qemu/target/hppa/translate.c
<<
>>
Prefs
   1/*
   2 * HPPA emulation cpu translation for qemu.
   3 *
   4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "cpu.h"
  22#include "disas/disas.h"
  23#include "qemu/host-utils.h"
  24#include "exec/exec-all.h"
  25#include "tcg-op.h"
  26#include "exec/cpu_ldst.h"
  27#include "exec/helper-proto.h"
  28#include "exec/helper-gen.h"
  29#include "exec/translator.h"
  30#include "trace-tcg.h"
  31#include "exec/log.h"
  32
  33/* Since we have a distinction between register size and address size,
  34   we need to redefine all of these.  */
  35
  36#undef TCGv
  37#undef tcg_temp_new
  38#undef tcg_global_reg_new
  39#undef tcg_global_mem_new
  40#undef tcg_temp_local_new
  41#undef tcg_temp_free
  42
  43#if TARGET_LONG_BITS == 64
  44#define TCGv_tl              TCGv_i64
  45#define tcg_temp_new_tl      tcg_temp_new_i64
  46#define tcg_temp_free_tl     tcg_temp_free_i64
  47#if TARGET_REGISTER_BITS == 64
  48#define tcg_gen_extu_reg_tl  tcg_gen_mov_i64
  49#else
  50#define tcg_gen_extu_reg_tl  tcg_gen_extu_i32_i64
  51#endif
  52#else
  53#define TCGv_tl              TCGv_i32
  54#define tcg_temp_new_tl      tcg_temp_new_i32
  55#define tcg_temp_free_tl     tcg_temp_free_i32
  56#define tcg_gen_extu_reg_tl  tcg_gen_mov_i32
  57#endif
  58
  59#if TARGET_REGISTER_BITS == 64
  60#define TCGv_reg             TCGv_i64
  61
  62#define tcg_temp_new         tcg_temp_new_i64
  63#define tcg_global_reg_new   tcg_global_reg_new_i64
  64#define tcg_global_mem_new   tcg_global_mem_new_i64
  65#define tcg_temp_local_new   tcg_temp_local_new_i64
  66#define tcg_temp_free        tcg_temp_free_i64
  67
  68#define tcg_gen_movi_reg     tcg_gen_movi_i64
  69#define tcg_gen_mov_reg      tcg_gen_mov_i64
  70#define tcg_gen_ld8u_reg     tcg_gen_ld8u_i64
  71#define tcg_gen_ld8s_reg     tcg_gen_ld8s_i64
  72#define tcg_gen_ld16u_reg    tcg_gen_ld16u_i64
  73#define tcg_gen_ld16s_reg    tcg_gen_ld16s_i64
  74#define tcg_gen_ld32u_reg    tcg_gen_ld32u_i64
  75#define tcg_gen_ld32s_reg    tcg_gen_ld32s_i64
  76#define tcg_gen_ld_reg       tcg_gen_ld_i64
  77#define tcg_gen_st8_reg      tcg_gen_st8_i64
  78#define tcg_gen_st16_reg     tcg_gen_st16_i64
  79#define tcg_gen_st32_reg     tcg_gen_st32_i64
  80#define tcg_gen_st_reg       tcg_gen_st_i64
  81#define tcg_gen_add_reg      tcg_gen_add_i64
  82#define tcg_gen_addi_reg     tcg_gen_addi_i64
  83#define tcg_gen_sub_reg      tcg_gen_sub_i64
  84#define tcg_gen_neg_reg      tcg_gen_neg_i64
  85#define tcg_gen_subfi_reg    tcg_gen_subfi_i64
  86#define tcg_gen_subi_reg     tcg_gen_subi_i64
  87#define tcg_gen_and_reg      tcg_gen_and_i64
  88#define tcg_gen_andi_reg     tcg_gen_andi_i64
  89#define tcg_gen_or_reg       tcg_gen_or_i64
  90#define tcg_gen_ori_reg      tcg_gen_ori_i64
  91#define tcg_gen_xor_reg      tcg_gen_xor_i64
  92#define tcg_gen_xori_reg     tcg_gen_xori_i64
  93#define tcg_gen_not_reg      tcg_gen_not_i64
  94#define tcg_gen_shl_reg      tcg_gen_shl_i64
  95#define tcg_gen_shli_reg     tcg_gen_shli_i64
  96#define tcg_gen_shr_reg      tcg_gen_shr_i64
  97#define tcg_gen_shri_reg     tcg_gen_shri_i64
  98#define tcg_gen_sar_reg      tcg_gen_sar_i64
  99#define tcg_gen_sari_reg     tcg_gen_sari_i64
 100#define tcg_gen_brcond_reg   tcg_gen_brcond_i64
 101#define tcg_gen_brcondi_reg  tcg_gen_brcondi_i64
 102#define tcg_gen_setcond_reg  tcg_gen_setcond_i64
 103#define tcg_gen_setcondi_reg tcg_gen_setcondi_i64
 104#define tcg_gen_mul_reg      tcg_gen_mul_i64
 105#define tcg_gen_muli_reg     tcg_gen_muli_i64
 106#define tcg_gen_div_reg      tcg_gen_div_i64
 107#define tcg_gen_rem_reg      tcg_gen_rem_i64
 108#define tcg_gen_divu_reg     tcg_gen_divu_i64
 109#define tcg_gen_remu_reg     tcg_gen_remu_i64
 110#define tcg_gen_discard_reg  tcg_gen_discard_i64
 111#define tcg_gen_trunc_reg_i32 tcg_gen_extrl_i64_i32
 112#define tcg_gen_trunc_i64_reg tcg_gen_mov_i64
 113#define tcg_gen_extu_i32_reg tcg_gen_extu_i32_i64
 114#define tcg_gen_ext_i32_reg  tcg_gen_ext_i32_i64
 115#define tcg_gen_extu_reg_i64 tcg_gen_mov_i64
 116#define tcg_gen_ext_reg_i64  tcg_gen_mov_i64
 117#define tcg_gen_ext8u_reg    tcg_gen_ext8u_i64
 118#define tcg_gen_ext8s_reg    tcg_gen_ext8s_i64
 119#define tcg_gen_ext16u_reg   tcg_gen_ext16u_i64
 120#define tcg_gen_ext16s_reg   tcg_gen_ext16s_i64
 121#define tcg_gen_ext32u_reg   tcg_gen_ext32u_i64
 122#define tcg_gen_ext32s_reg   tcg_gen_ext32s_i64
 123#define tcg_gen_bswap16_reg  tcg_gen_bswap16_i64
 124#define tcg_gen_bswap32_reg  tcg_gen_bswap32_i64
 125#define tcg_gen_bswap64_reg  tcg_gen_bswap64_i64
 126#define tcg_gen_concat_reg_i64 tcg_gen_concat32_i64
 127#define tcg_gen_andc_reg     tcg_gen_andc_i64
 128#define tcg_gen_eqv_reg      tcg_gen_eqv_i64
 129#define tcg_gen_nand_reg     tcg_gen_nand_i64
 130#define tcg_gen_nor_reg      tcg_gen_nor_i64
 131#define tcg_gen_orc_reg      tcg_gen_orc_i64
 132#define tcg_gen_clz_reg      tcg_gen_clz_i64
 133#define tcg_gen_ctz_reg      tcg_gen_ctz_i64
 134#define tcg_gen_clzi_reg     tcg_gen_clzi_i64
 135#define tcg_gen_ctzi_reg     tcg_gen_ctzi_i64
 136#define tcg_gen_clrsb_reg    tcg_gen_clrsb_i64
 137#define tcg_gen_ctpop_reg    tcg_gen_ctpop_i64
 138#define tcg_gen_rotl_reg     tcg_gen_rotl_i64
 139#define tcg_gen_rotli_reg    tcg_gen_rotli_i64
 140#define tcg_gen_rotr_reg     tcg_gen_rotr_i64
 141#define tcg_gen_rotri_reg    tcg_gen_rotri_i64
 142#define tcg_gen_deposit_reg  tcg_gen_deposit_i64
 143#define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i64
 144#define tcg_gen_extract_reg  tcg_gen_extract_i64
 145#define tcg_gen_sextract_reg tcg_gen_sextract_i64
 146#define tcg_const_reg        tcg_const_i64
 147#define tcg_const_local_reg  tcg_const_local_i64
 148#define tcg_gen_movcond_reg  tcg_gen_movcond_i64
 149#define tcg_gen_add2_reg     tcg_gen_add2_i64
 150#define tcg_gen_sub2_reg     tcg_gen_sub2_i64
 151#define tcg_gen_qemu_ld_reg  tcg_gen_qemu_ld_i64
 152#define tcg_gen_qemu_st_reg  tcg_gen_qemu_st_i64
 153#define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i64
 154#define tcg_gen_trunc_reg_ptr   tcg_gen_trunc_i64_ptr
 155#else
 156#define TCGv_reg             TCGv_i32
 157#define tcg_temp_new         tcg_temp_new_i32
 158#define tcg_global_reg_new   tcg_global_reg_new_i32
 159#define tcg_global_mem_new   tcg_global_mem_new_i32
 160#define tcg_temp_local_new   tcg_temp_local_new_i32
 161#define tcg_temp_free        tcg_temp_free_i32
 162
 163#define tcg_gen_movi_reg     tcg_gen_movi_i32
 164#define tcg_gen_mov_reg      tcg_gen_mov_i32
 165#define tcg_gen_ld8u_reg     tcg_gen_ld8u_i32
 166#define tcg_gen_ld8s_reg     tcg_gen_ld8s_i32
 167#define tcg_gen_ld16u_reg    tcg_gen_ld16u_i32
 168#define tcg_gen_ld16s_reg    tcg_gen_ld16s_i32
 169#define tcg_gen_ld32u_reg    tcg_gen_ld_i32
 170#define tcg_gen_ld32s_reg    tcg_gen_ld_i32
 171#define tcg_gen_ld_reg       tcg_gen_ld_i32
 172#define tcg_gen_st8_reg      tcg_gen_st8_i32
 173#define tcg_gen_st16_reg     tcg_gen_st16_i32
 174#define tcg_gen_st32_reg     tcg_gen_st32_i32
 175#define tcg_gen_st_reg       tcg_gen_st_i32
 176#define tcg_gen_add_reg      tcg_gen_add_i32
 177#define tcg_gen_addi_reg     tcg_gen_addi_i32
 178#define tcg_gen_sub_reg      tcg_gen_sub_i32
 179#define tcg_gen_neg_reg      tcg_gen_neg_i32
 180#define tcg_gen_subfi_reg    tcg_gen_subfi_i32
 181#define tcg_gen_subi_reg     tcg_gen_subi_i32
 182#define tcg_gen_and_reg      tcg_gen_and_i32
 183#define tcg_gen_andi_reg     tcg_gen_andi_i32
 184#define tcg_gen_or_reg       tcg_gen_or_i32
 185#define tcg_gen_ori_reg      tcg_gen_ori_i32
 186#define tcg_gen_xor_reg      tcg_gen_xor_i32
 187#define tcg_gen_xori_reg     tcg_gen_xori_i32
 188#define tcg_gen_not_reg      tcg_gen_not_i32
 189#define tcg_gen_shl_reg      tcg_gen_shl_i32
 190#define tcg_gen_shli_reg     tcg_gen_shli_i32
 191#define tcg_gen_shr_reg      tcg_gen_shr_i32
 192#define tcg_gen_shri_reg     tcg_gen_shri_i32
 193#define tcg_gen_sar_reg      tcg_gen_sar_i32
 194#define tcg_gen_sari_reg     tcg_gen_sari_i32
 195#define tcg_gen_brcond_reg   tcg_gen_brcond_i32
 196#define tcg_gen_brcondi_reg  tcg_gen_brcondi_i32
 197#define tcg_gen_setcond_reg  tcg_gen_setcond_i32
 198#define tcg_gen_setcondi_reg tcg_gen_setcondi_i32
 199#define tcg_gen_mul_reg      tcg_gen_mul_i32
 200#define tcg_gen_muli_reg     tcg_gen_muli_i32
 201#define tcg_gen_div_reg      tcg_gen_div_i32
 202#define tcg_gen_rem_reg      tcg_gen_rem_i32
 203#define tcg_gen_divu_reg     tcg_gen_divu_i32
 204#define tcg_gen_remu_reg     tcg_gen_remu_i32
 205#define tcg_gen_discard_reg  tcg_gen_discard_i32
 206#define tcg_gen_trunc_reg_i32 tcg_gen_mov_i32
 207#define tcg_gen_trunc_i64_reg tcg_gen_extrl_i64_i32
 208#define tcg_gen_extu_i32_reg tcg_gen_mov_i32
 209#define tcg_gen_ext_i32_reg  tcg_gen_mov_i32
 210#define tcg_gen_extu_reg_i64 tcg_gen_extu_i32_i64
 211#define tcg_gen_ext_reg_i64  tcg_gen_ext_i32_i64
 212#define tcg_gen_ext8u_reg    tcg_gen_ext8u_i32
 213#define tcg_gen_ext8s_reg    tcg_gen_ext8s_i32
 214#define tcg_gen_ext16u_reg   tcg_gen_ext16u_i32
 215#define tcg_gen_ext16s_reg   tcg_gen_ext16s_i32
 216#define tcg_gen_ext32u_reg   tcg_gen_mov_i32
 217#define tcg_gen_ext32s_reg   tcg_gen_mov_i32
 218#define tcg_gen_bswap16_reg  tcg_gen_bswap16_i32
 219#define tcg_gen_bswap32_reg  tcg_gen_bswap32_i32
 220#define tcg_gen_concat_reg_i64 tcg_gen_concat_i32_i64
 221#define tcg_gen_andc_reg     tcg_gen_andc_i32
 222#define tcg_gen_eqv_reg      tcg_gen_eqv_i32
 223#define tcg_gen_nand_reg     tcg_gen_nand_i32
 224#define tcg_gen_nor_reg      tcg_gen_nor_i32
 225#define tcg_gen_orc_reg      tcg_gen_orc_i32
 226#define tcg_gen_clz_reg      tcg_gen_clz_i32
 227#define tcg_gen_ctz_reg      tcg_gen_ctz_i32
 228#define tcg_gen_clzi_reg     tcg_gen_clzi_i32
 229#define tcg_gen_ctzi_reg     tcg_gen_ctzi_i32
 230#define tcg_gen_clrsb_reg    tcg_gen_clrsb_i32
 231#define tcg_gen_ctpop_reg    tcg_gen_ctpop_i32
 232#define tcg_gen_rotl_reg     tcg_gen_rotl_i32
 233#define tcg_gen_rotli_reg    tcg_gen_rotli_i32
 234#define tcg_gen_rotr_reg     tcg_gen_rotr_i32
 235#define tcg_gen_rotri_reg    tcg_gen_rotri_i32
 236#define tcg_gen_deposit_reg  tcg_gen_deposit_i32
 237#define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i32
 238#define tcg_gen_extract_reg  tcg_gen_extract_i32
 239#define tcg_gen_sextract_reg tcg_gen_sextract_i32
 240#define tcg_const_reg        tcg_const_i32
 241#define tcg_const_local_reg  tcg_const_local_i32
 242#define tcg_gen_movcond_reg  tcg_gen_movcond_i32
 243#define tcg_gen_add2_reg     tcg_gen_add2_i32
 244#define tcg_gen_sub2_reg     tcg_gen_sub2_i32
 245#define tcg_gen_qemu_ld_reg  tcg_gen_qemu_ld_i32
 246#define tcg_gen_qemu_st_reg  tcg_gen_qemu_st_i32
 247#define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i32
 248#define tcg_gen_trunc_reg_ptr   tcg_gen_ext_i32_ptr
 249#endif /* TARGET_REGISTER_BITS */
 250
 251typedef struct DisasCond {
 252    TCGCond c;
 253    TCGv_reg a0, a1;
 254    bool a0_is_n;
 255    bool a1_is_0;
 256} DisasCond;
 257
 258typedef struct DisasContext {
 259    DisasContextBase base;
 260    CPUState *cs;
 261
 262    target_ureg iaoq_f;
 263    target_ureg iaoq_b;
 264    target_ureg iaoq_n;
 265    TCGv_reg iaoq_n_var;
 266
 267    int ntempr, ntempl;
 268    TCGv_reg tempr[8];
 269    TCGv_tl  templ[4];
 270
 271    DisasCond null_cond;
 272    TCGLabel *null_lab;
 273
 274    uint32_t insn;
 275    uint32_t tb_flags;
 276    int mmu_idx;
 277    int privilege;
 278    bool psw_n_nonzero;
 279} DisasContext;
 280
 281/* Note that ssm/rsm instructions number PSW_W and PSW_E differently.  */
 282static int expand_sm_imm(DisasContext *ctx, int val)
 283{
 284    if (val & PSW_SM_E) {
 285        val = (val & ~PSW_SM_E) | PSW_E;
 286    }
 287    if (val & PSW_SM_W) {
 288        val = (val & ~PSW_SM_W) | PSW_W;
 289    }
 290    return val;
 291}
 292
 293/* Inverted space register indicates 0 means sr0 not inferred from base.  */
 294static int expand_sr3x(DisasContext *ctx, int val)
 295{
 296    return ~val;
 297}
 298
 299/* Convert the M:A bits within a memory insn to the tri-state value
 300   we use for the final M.  */
 301static int ma_to_m(DisasContext *ctx, int val)
 302{
 303    return val & 2 ? (val & 1 ? -1 : 1) : 0;
 304}
 305
 306/* Convert the sign of the displacement to a pre or post-modify.  */
 307static int pos_to_m(DisasContext *ctx, int val)
 308{
 309    return val ? 1 : -1;
 310}
 311
 312static int neg_to_m(DisasContext *ctx, int val)
 313{
 314    return val ? -1 : 1;
 315}
 316
 317/* Used for branch targets and fp memory ops.  */
 318static int expand_shl2(DisasContext *ctx, int val)
 319{
 320    return val << 2;
 321}
 322
 323/* Used for fp memory ops.  */
 324static int expand_shl3(DisasContext *ctx, int val)
 325{
 326    return val << 3;
 327}
 328
 329/* Used for assemble_21.  */
 330static int expand_shl11(DisasContext *ctx, int val)
 331{
 332    return val << 11;
 333}
 334
 335
 336/* Include the auto-generated decoder.  */
 337#include "decode.inc.c"
 338
 339/* We are not using a goto_tb (for whatever reason), but have updated
 340   the iaq (for whatever reason), so don't do it again on exit.  */
 341#define DISAS_IAQ_N_UPDATED  DISAS_TARGET_0
 342
 343/* We are exiting the TB, but have neither emitted a goto_tb, nor
 344   updated the iaq for the next instruction to be executed.  */
 345#define DISAS_IAQ_N_STALE    DISAS_TARGET_1
 346
 347/* Similarly, but we want to return to the main loop immediately
 348   to recognize unmasked interrupts.  */
 349#define DISAS_IAQ_N_STALE_EXIT      DISAS_TARGET_2
 350#define DISAS_EXIT                  DISAS_TARGET_3
 351
 352/* global register indexes */
 353static TCGv_reg cpu_gr[32];
 354static TCGv_i64 cpu_sr[4];
 355static TCGv_i64 cpu_srH;
 356static TCGv_reg cpu_iaoq_f;
 357static TCGv_reg cpu_iaoq_b;
 358static TCGv_i64 cpu_iasq_f;
 359static TCGv_i64 cpu_iasq_b;
 360static TCGv_reg cpu_sar;
 361static TCGv_reg cpu_psw_n;
 362static TCGv_reg cpu_psw_v;
 363static TCGv_reg cpu_psw_cb;
 364static TCGv_reg cpu_psw_cb_msb;
 365
 366#include "exec/gen-icount.h"
 367
 368void hppa_translate_init(void)
 369{
 370#define DEF_VAR(V)  { &cpu_##V, #V, offsetof(CPUHPPAState, V) }
 371
 372    typedef struct { TCGv_reg *var; const char *name; int ofs; } GlobalVar;
 373    static const GlobalVar vars[] = {
 374        { &cpu_sar, "sar", offsetof(CPUHPPAState, cr[CR_SAR]) },
 375        DEF_VAR(psw_n),
 376        DEF_VAR(psw_v),
 377        DEF_VAR(psw_cb),
 378        DEF_VAR(psw_cb_msb),
 379        DEF_VAR(iaoq_f),
 380        DEF_VAR(iaoq_b),
 381    };
 382
 383#undef DEF_VAR
 384
 385    /* Use the symbolic register names that match the disassembler.  */
 386    static const char gr_names[32][4] = {
 387        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
 388        "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
 389        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
 390        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
 391    };
 392    /* SR[4-7] are not global registers so that we can index them.  */
 393    static const char sr_names[5][4] = {
 394        "sr0", "sr1", "sr2", "sr3", "srH"
 395    };
 396
 397    int i;
 398
 399    cpu_gr[0] = NULL;
 400    for (i = 1; i < 32; i++) {
 401        cpu_gr[i] = tcg_global_mem_new(cpu_env,
 402                                       offsetof(CPUHPPAState, gr[i]),
 403                                       gr_names[i]);
 404    }
 405    for (i = 0; i < 4; i++) {
 406        cpu_sr[i] = tcg_global_mem_new_i64(cpu_env,
 407                                           offsetof(CPUHPPAState, sr[i]),
 408                                           sr_names[i]);
 409    }
 410    cpu_srH = tcg_global_mem_new_i64(cpu_env,
 411                                     offsetof(CPUHPPAState, sr[4]),
 412                                     sr_names[4]);
 413
 414    for (i = 0; i < ARRAY_SIZE(vars); ++i) {
 415        const GlobalVar *v = &vars[i];
 416        *v->var = tcg_global_mem_new(cpu_env, v->ofs, v->name);
 417    }
 418
 419    cpu_iasq_f = tcg_global_mem_new_i64(cpu_env,
 420                                        offsetof(CPUHPPAState, iasq_f),
 421                                        "iasq_f");
 422    cpu_iasq_b = tcg_global_mem_new_i64(cpu_env,
 423                                        offsetof(CPUHPPAState, iasq_b),
 424                                        "iasq_b");
 425}
 426
 427static DisasCond cond_make_f(void)
 428{
 429    return (DisasCond){
 430        .c = TCG_COND_NEVER,
 431        .a0 = NULL,
 432        .a1 = NULL,
 433    };
 434}
 435
 436static DisasCond cond_make_t(void)
 437{
 438    return (DisasCond){
 439        .c = TCG_COND_ALWAYS,
 440        .a0 = NULL,
 441        .a1 = NULL,
 442    };
 443}
 444
 445static DisasCond cond_make_n(void)
 446{
 447    return (DisasCond){
 448        .c = TCG_COND_NE,
 449        .a0 = cpu_psw_n,
 450        .a0_is_n = true,
 451        .a1 = NULL,
 452        .a1_is_0 = true
 453    };
 454}
 455
 456static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
 457{
 458    assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
 459    return (DisasCond){
 460        .c = c, .a0 = a0, .a1_is_0 = true
 461    };
 462}
 463
 464static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
 465{
 466    TCGv_reg tmp = tcg_temp_new();
 467    tcg_gen_mov_reg(tmp, a0);
 468    return cond_make_0_tmp(c, tmp);
 469}
 470
 471static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1)
 472{
 473    DisasCond r = { .c = c };
 474
 475    assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
 476    r.a0 = tcg_temp_new();
 477    tcg_gen_mov_reg(r.a0, a0);
 478    r.a1 = tcg_temp_new();
 479    tcg_gen_mov_reg(r.a1, a1);
 480
 481    return r;
 482}
 483
 484static void cond_prep(DisasCond *cond)
 485{
 486    if (cond->a1_is_0) {
 487        cond->a1_is_0 = false;
 488        cond->a1 = tcg_const_reg(0);
 489    }
 490}
 491
 492static void cond_free(DisasCond *cond)
 493{
 494    switch (cond->c) {
 495    default:
 496        if (!cond->a0_is_n) {
 497            tcg_temp_free(cond->a0);
 498        }
 499        if (!cond->a1_is_0) {
 500            tcg_temp_free(cond->a1);
 501        }
 502        cond->a0_is_n = false;
 503        cond->a1_is_0 = false;
 504        cond->a0 = NULL;
 505        cond->a1 = NULL;
 506        /* fallthru */
 507    case TCG_COND_ALWAYS:
 508        cond->c = TCG_COND_NEVER;
 509        break;
 510    case TCG_COND_NEVER:
 511        break;
 512    }
 513}
 514
 515static TCGv_reg get_temp(DisasContext *ctx)
 516{
 517    unsigned i = ctx->ntempr++;
 518    g_assert(i < ARRAY_SIZE(ctx->tempr));
 519    return ctx->tempr[i] = tcg_temp_new();
 520}
 521
 522#ifndef CONFIG_USER_ONLY
 523static TCGv_tl get_temp_tl(DisasContext *ctx)
 524{
 525    unsigned i = ctx->ntempl++;
 526    g_assert(i < ARRAY_SIZE(ctx->templ));
 527    return ctx->templ[i] = tcg_temp_new_tl();
 528}
 529#endif
 530
 531static TCGv_reg load_const(DisasContext *ctx, target_sreg v)
 532{
 533    TCGv_reg t = get_temp(ctx);
 534    tcg_gen_movi_reg(t, v);
 535    return t;
 536}
 537
 538static TCGv_reg load_gpr(DisasContext *ctx, unsigned reg)
 539{
 540    if (reg == 0) {
 541        TCGv_reg t = get_temp(ctx);
 542        tcg_gen_movi_reg(t, 0);
 543        return t;
 544    } else {
 545        return cpu_gr[reg];
 546    }
 547}
 548
 549static TCGv_reg dest_gpr(DisasContext *ctx, unsigned reg)
 550{
 551    if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) {
 552        return get_temp(ctx);
 553    } else {
 554        return cpu_gr[reg];
 555    }
 556}
 557
 558static void save_or_nullify(DisasContext *ctx, TCGv_reg dest, TCGv_reg t)
 559{
 560    if (ctx->null_cond.c != TCG_COND_NEVER) {
 561        cond_prep(&ctx->null_cond);
 562        tcg_gen_movcond_reg(ctx->null_cond.c, dest, ctx->null_cond.a0,
 563                           ctx->null_cond.a1, dest, t);
 564    } else {
 565        tcg_gen_mov_reg(dest, t);
 566    }
 567}
 568
 569static void save_gpr(DisasContext *ctx, unsigned reg, TCGv_reg t)
 570{
 571    if (reg != 0) {
 572        save_or_nullify(ctx, cpu_gr[reg], t);
 573    }
 574}
 575
 576#ifdef HOST_WORDS_BIGENDIAN
 577# define HI_OFS  0
 578# define LO_OFS  4
 579#else
 580# define HI_OFS  4
 581# define LO_OFS  0
 582#endif
 583
 584static TCGv_i32 load_frw_i32(unsigned rt)
 585{
 586    TCGv_i32 ret = tcg_temp_new_i32();
 587    tcg_gen_ld_i32(ret, cpu_env,
 588                   offsetof(CPUHPPAState, fr[rt & 31])
 589                   + (rt & 32 ? LO_OFS : HI_OFS));
 590    return ret;
 591}
 592
 593static TCGv_i32 load_frw0_i32(unsigned rt)
 594{
 595    if (rt == 0) {
 596        return tcg_const_i32(0);
 597    } else {
 598        return load_frw_i32(rt);
 599    }
 600}
 601
 602static TCGv_i64 load_frw0_i64(unsigned rt)
 603{
 604    if (rt == 0) {
 605        return tcg_const_i64(0);
 606    } else {
 607        TCGv_i64 ret = tcg_temp_new_i64();
 608        tcg_gen_ld32u_i64(ret, cpu_env,
 609                          offsetof(CPUHPPAState, fr[rt & 31])
 610                          + (rt & 32 ? LO_OFS : HI_OFS));
 611        return ret;
 612    }
 613}
 614
 615static void save_frw_i32(unsigned rt, TCGv_i32 val)
 616{
 617    tcg_gen_st_i32(val, cpu_env,
 618                   offsetof(CPUHPPAState, fr[rt & 31])
 619                   + (rt & 32 ? LO_OFS : HI_OFS));
 620}
 621
 622#undef HI_OFS
 623#undef LO_OFS
 624
 625static TCGv_i64 load_frd(unsigned rt)
 626{
 627    TCGv_i64 ret = tcg_temp_new_i64();
 628    tcg_gen_ld_i64(ret, cpu_env, offsetof(CPUHPPAState, fr[rt]));
 629    return ret;
 630}
 631
 632static TCGv_i64 load_frd0(unsigned rt)
 633{
 634    if (rt == 0) {
 635        return tcg_const_i64(0);
 636    } else {
 637        return load_frd(rt);
 638    }
 639}
 640
 641static void save_frd(unsigned rt, TCGv_i64 val)
 642{
 643    tcg_gen_st_i64(val, cpu_env, offsetof(CPUHPPAState, fr[rt]));
 644}
 645
 646static void load_spr(DisasContext *ctx, TCGv_i64 dest, unsigned reg)
 647{
 648#ifdef CONFIG_USER_ONLY
 649    tcg_gen_movi_i64(dest, 0);
 650#else
 651    if (reg < 4) {
 652        tcg_gen_mov_i64(dest, cpu_sr[reg]);
 653    } else if (ctx->tb_flags & TB_FLAG_SR_SAME) {
 654        tcg_gen_mov_i64(dest, cpu_srH);
 655    } else {
 656        tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUHPPAState, sr[reg]));
 657    }
 658#endif
 659}
 660
 661/* Skip over the implementation of an insn that has been nullified.
 662   Use this when the insn is too complex for a conditional move.  */
 663static void nullify_over(DisasContext *ctx)
 664{
 665    if (ctx->null_cond.c != TCG_COND_NEVER) {
 666        /* The always condition should have been handled in the main loop.  */
 667        assert(ctx->null_cond.c != TCG_COND_ALWAYS);
 668
 669        ctx->null_lab = gen_new_label();
 670        cond_prep(&ctx->null_cond);
 671
 672        /* If we're using PSW[N], copy it to a temp because... */
 673        if (ctx->null_cond.a0_is_n) {
 674            ctx->null_cond.a0_is_n = false;
 675            ctx->null_cond.a0 = tcg_temp_new();
 676            tcg_gen_mov_reg(ctx->null_cond.a0, cpu_psw_n);
 677        }
 678        /* ... we clear it before branching over the implementation,
 679           so that (1) it's clear after nullifying this insn and
 680           (2) if this insn nullifies the next, PSW[N] is valid.  */
 681        if (ctx->psw_n_nonzero) {
 682            ctx->psw_n_nonzero = false;
 683            tcg_gen_movi_reg(cpu_psw_n, 0);
 684        }
 685
 686        tcg_gen_brcond_reg(ctx->null_cond.c, ctx->null_cond.a0,
 687                          ctx->null_cond.a1, ctx->null_lab);
 688        cond_free(&ctx->null_cond);
 689    }
 690}
 691
 692/* Save the current nullification state to PSW[N].  */
 693static void nullify_save(DisasContext *ctx)
 694{
 695    if (ctx->null_cond.c == TCG_COND_NEVER) {
 696        if (ctx->psw_n_nonzero) {
 697            tcg_gen_movi_reg(cpu_psw_n, 0);
 698        }
 699        return;
 700    }
 701    if (!ctx->null_cond.a0_is_n) {
 702        cond_prep(&ctx->null_cond);
 703        tcg_gen_setcond_reg(ctx->null_cond.c, cpu_psw_n,
 704                           ctx->null_cond.a0, ctx->null_cond.a1);
 705        ctx->psw_n_nonzero = true;
 706    }
 707    cond_free(&ctx->null_cond);
 708}
 709
 710/* Set a PSW[N] to X.  The intention is that this is used immediately
 711   before a goto_tb/exit_tb, so that there is no fallthru path to other
 712   code within the TB.  Therefore we do not update psw_n_nonzero.  */
 713static void nullify_set(DisasContext *ctx, bool x)
 714{
 715    if (ctx->psw_n_nonzero || x) {
 716        tcg_gen_movi_reg(cpu_psw_n, x);
 717    }
 718}
 719
 720/* Mark the end of an instruction that may have been nullified.
 721   This is the pair to nullify_over.  Always returns true so that
 722   it may be tail-called from a translate function.  */
 723static bool nullify_end(DisasContext *ctx)
 724{
 725    TCGLabel *null_lab = ctx->null_lab;
 726    DisasJumpType status = ctx->base.is_jmp;
 727
 728    /* For NEXT, NORETURN, STALE, we can easily continue (or exit).
 729       For UPDATED, we cannot update on the nullified path.  */
 730    assert(status != DISAS_IAQ_N_UPDATED);
 731
 732    if (likely(null_lab == NULL)) {
 733        /* The current insn wasn't conditional or handled the condition
 734           applied to it without a branch, so the (new) setting of
 735           NULL_COND can be applied directly to the next insn.  */
 736        return true;
 737    }
 738    ctx->null_lab = NULL;
 739
 740    if (likely(ctx->null_cond.c == TCG_COND_NEVER)) {
 741        /* The next instruction will be unconditional,
 742           and NULL_COND already reflects that.  */
 743        gen_set_label(null_lab);
 744    } else {
 745        /* The insn that we just executed is itself nullifying the next
 746           instruction.  Store the condition in the PSW[N] global.
 747           We asserted PSW[N] = 0 in nullify_over, so that after the
 748           label we have the proper value in place.  */
 749        nullify_save(ctx);
 750        gen_set_label(null_lab);
 751        ctx->null_cond = cond_make_n();
 752    }
 753    if (status == DISAS_NORETURN) {
 754        ctx->base.is_jmp = DISAS_NEXT;
 755    }
 756    return true;
 757}
 758
 759static void copy_iaoq_entry(TCGv_reg dest, target_ureg ival, TCGv_reg vval)
 760{
 761    if (unlikely(ival == -1)) {
 762        tcg_gen_mov_reg(dest, vval);
 763    } else {
 764        tcg_gen_movi_reg(dest, ival);
 765    }
 766}
 767
 768static inline target_ureg iaoq_dest(DisasContext *ctx, target_sreg disp)
 769{
 770    return ctx->iaoq_f + disp + 8;
 771}
 772
 773static void gen_excp_1(int exception)
 774{
 775    TCGv_i32 t = tcg_const_i32(exception);
 776    gen_helper_excp(cpu_env, t);
 777    tcg_temp_free_i32(t);
 778}
 779
 780static void gen_excp(DisasContext *ctx, int exception)
 781{
 782    copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
 783    copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
 784    nullify_save(ctx);
 785    gen_excp_1(exception);
 786    ctx->base.is_jmp = DISAS_NORETURN;
 787}
 788
 789static bool gen_excp_iir(DisasContext *ctx, int exc)
 790{
 791    TCGv_reg tmp;
 792
 793    nullify_over(ctx);
 794    tmp = tcg_const_reg(ctx->insn);
 795    tcg_gen_st_reg(tmp, cpu_env, offsetof(CPUHPPAState, cr[CR_IIR]));
 796    tcg_temp_free(tmp);
 797    gen_excp(ctx, exc);
 798    return nullify_end(ctx);
 799}
 800
 801static bool gen_illegal(DisasContext *ctx)
 802{
 803    return gen_excp_iir(ctx, EXCP_ILL);
 804}
 805
 806#ifdef CONFIG_USER_ONLY
 807#define CHECK_MOST_PRIVILEGED(EXCP) \
 808    return gen_excp_iir(ctx, EXCP)
 809#else
 810#define CHECK_MOST_PRIVILEGED(EXCP) \
 811    do {                                     \
 812        if (ctx->privilege != 0) {           \
 813            return gen_excp_iir(ctx, EXCP);  \
 814        }                                    \
 815    } while (0)
 816#endif
 817
 818static bool use_goto_tb(DisasContext *ctx, target_ureg dest)
 819{
 820    /* Suppress goto_tb for page crossing, IO, or single-steping.  */
 821    return !(((ctx->base.pc_first ^ dest) & TARGET_PAGE_MASK)
 822             || (tb_cflags(ctx->base.tb) & CF_LAST_IO)
 823             || ctx->base.singlestep_enabled);
 824}
 825
 826/* If the next insn is to be nullified, and it's on the same page,
 827   and we're not attempting to set a breakpoint on it, then we can
 828   totally skip the nullified insn.  This avoids creating and
 829   executing a TB that merely branches to the next TB.  */
 830static bool use_nullify_skip(DisasContext *ctx)
 831{
 832    return (((ctx->iaoq_b ^ ctx->iaoq_f) & TARGET_PAGE_MASK) == 0
 833            && !cpu_breakpoint_test(ctx->cs, ctx->iaoq_b, BP_ANY));
 834}
 835
 836static void gen_goto_tb(DisasContext *ctx, int which,
 837                        target_ureg f, target_ureg b)
 838{
 839    if (f != -1 && b != -1 && use_goto_tb(ctx, f)) {
 840        tcg_gen_goto_tb(which);
 841        tcg_gen_movi_reg(cpu_iaoq_f, f);
 842        tcg_gen_movi_reg(cpu_iaoq_b, b);
 843        tcg_gen_exit_tb(ctx->base.tb, which);
 844    } else {
 845        copy_iaoq_entry(cpu_iaoq_f, f, cpu_iaoq_b);
 846        copy_iaoq_entry(cpu_iaoq_b, b, ctx->iaoq_n_var);
 847        if (ctx->base.singlestep_enabled) {
 848            gen_excp_1(EXCP_DEBUG);
 849        } else {
 850            tcg_gen_lookup_and_goto_ptr();
 851        }
 852    }
 853}
 854
 855static bool cond_need_sv(int c)
 856{
 857    return c == 2 || c == 3 || c == 6;
 858}
 859
 860static bool cond_need_cb(int c)
 861{
 862    return c == 4 || c == 5;
 863}
 864
 865/*
 866 * Compute conditional for arithmetic.  See Page 5-3, Table 5-1, of
 867 * the Parisc 1.1 Architecture Reference Manual for details.
 868 */
 869
 870static DisasCond do_cond(unsigned cf, TCGv_reg res,
 871                         TCGv_reg cb_msb, TCGv_reg sv)
 872{
 873    DisasCond cond;
 874    TCGv_reg tmp;
 875
 876    switch (cf >> 1) {
 877    case 0: /* Never / TR    (0 / 1) */
 878        cond = cond_make_f();
 879        break;
 880    case 1: /* = / <>        (Z / !Z) */
 881        cond = cond_make_0(TCG_COND_EQ, res);
 882        break;
 883    case 2: /* < / >=        (N ^ V / !(N ^ V) */
 884        tmp = tcg_temp_new();
 885        tcg_gen_xor_reg(tmp, res, sv);
 886        cond = cond_make_0_tmp(TCG_COND_LT, tmp);
 887        break;
 888    case 3: /* <= / >        (N ^ V) | Z / !((N ^ V) | Z) */
 889        /*
 890         * Simplify:
 891         *   (N ^ V) | Z
 892         *   ((res < 0) ^ (sv < 0)) | !res
 893         *   ((res ^ sv) < 0) | !res
 894         *   (~(res ^ sv) >= 0) | !res
 895         *   !(~(res ^ sv) >> 31) | !res
 896         *   !(~(res ^ sv) >> 31 & res)
 897         */
 898        tmp = tcg_temp_new();
 899        tcg_gen_eqv_reg(tmp, res, sv);
 900        tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
 901        tcg_gen_and_reg(tmp, tmp, res);
 902        cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
 903        break;
 904    case 4: /* NUV / UV      (!C / C) */
 905        cond = cond_make_0(TCG_COND_EQ, cb_msb);
 906        break;
 907    case 5: /* ZNV / VNZ     (!C | Z / C & !Z) */
 908        tmp = tcg_temp_new();
 909        tcg_gen_neg_reg(tmp, cb_msb);
 910        tcg_gen_and_reg(tmp, tmp, res);
 911        cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
 912        break;
 913    case 6: /* SV / NSV      (V / !V) */
 914        cond = cond_make_0(TCG_COND_LT, sv);
 915        break;
 916    case 7: /* OD / EV */
 917        tmp = tcg_temp_new();
 918        tcg_gen_andi_reg(tmp, res, 1);
 919        cond = cond_make_0_tmp(TCG_COND_NE, tmp);
 920        break;
 921    default:
 922        g_assert_not_reached();
 923    }
 924    if (cf & 1) {
 925        cond.c = tcg_invert_cond(cond.c);
 926    }
 927
 928    return cond;
 929}
 930
 931/* Similar, but for the special case of subtraction without borrow, we
 932   can use the inputs directly.  This can allow other computation to be
 933   deleted as unused.  */
 934
 935static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
 936                             TCGv_reg in1, TCGv_reg in2, TCGv_reg sv)
 937{
 938    DisasCond cond;
 939
 940    switch (cf >> 1) {
 941    case 1: /* = / <> */
 942        cond = cond_make(TCG_COND_EQ, in1, in2);
 943        break;
 944    case 2: /* < / >= */
 945        cond = cond_make(TCG_COND_LT, in1, in2);
 946        break;
 947    case 3: /* <= / > */
 948        cond = cond_make(TCG_COND_LE, in1, in2);
 949        break;
 950    case 4: /* << / >>= */
 951        cond = cond_make(TCG_COND_LTU, in1, in2);
 952        break;
 953    case 5: /* <<= / >> */
 954        cond = cond_make(TCG_COND_LEU, in1, in2);
 955        break;
 956    default:
 957        return do_cond(cf, res, NULL, sv);
 958    }
 959    if (cf & 1) {
 960        cond.c = tcg_invert_cond(cond.c);
 961    }
 962
 963    return cond;
 964}
 965
 966/*
 967 * Similar, but for logicals, where the carry and overflow bits are not
 968 * computed, and use of them is undefined.
 969 *
 970 * Undefined or not, hardware does not trap.  It seems reasonable to
 971 * assume hardware treats cases c={4,5,6} as if C=0 & V=0, since that's
 972 * how cases c={2,3} are treated.
 973 */
 974
 975static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
 976{
 977    switch (cf) {
 978    case 0:  /* never */
 979    case 9:  /* undef, C */
 980    case 11: /* undef, C & !Z */
 981    case 12: /* undef, V */
 982        return cond_make_f();
 983
 984    case 1:  /* true */
 985    case 8:  /* undef, !C */
 986    case 10: /* undef, !C | Z */
 987    case 13: /* undef, !V */
 988        return cond_make_t();
 989
 990    case 2:  /* == */
 991        return cond_make_0(TCG_COND_EQ, res);
 992    case 3:  /* <> */
 993        return cond_make_0(TCG_COND_NE, res);
 994    case 4:  /* < */
 995        return cond_make_0(TCG_COND_LT, res);
 996    case 5:  /* >= */
 997        return cond_make_0(TCG_COND_GE, res);
 998    case 6:  /* <= */
 999        return cond_make_0(TCG_COND_LE, res);
1000    case 7:  /* > */
1001        return cond_make_0(TCG_COND_GT, res);
1002
1003    case 14: /* OD */
1004    case 15: /* EV */
1005        return do_cond(cf, res, NULL, NULL);
1006
1007    default:
1008        g_assert_not_reached();
1009    }
1010}
1011
1012/* Similar, but for shift/extract/deposit conditions.  */
1013
1014static DisasCond do_sed_cond(unsigned orig, TCGv_reg res)
1015{
1016    unsigned c, f;
1017
1018    /* Convert the compressed condition codes to standard.
1019       0-2 are the same as logicals (nv,<,<=), while 3 is OD.
1020       4-7 are the reverse of 0-3.  */
1021    c = orig & 3;
1022    if (c == 3) {
1023        c = 7;
1024    }
1025    f = (orig & 4) / 4;
1026
1027    return do_log_cond(c * 2 + f, res);
1028}
1029
1030/* Similar, but for unit conditions.  */
1031
1032static DisasCond do_unit_cond(unsigned cf, TCGv_reg res,
1033                              TCGv_reg in1, TCGv_reg in2)
1034{
1035    DisasCond cond;
1036    TCGv_reg tmp, cb = NULL;
1037
1038    if (cf & 8) {
1039        /* Since we want to test lots of carry-out bits all at once, do not
1040         * do our normal thing and compute carry-in of bit B+1 since that
1041         * leaves us with carry bits spread across two words.
1042         */
1043        cb = tcg_temp_new();
1044        tmp = tcg_temp_new();
1045        tcg_gen_or_reg(cb, in1, in2);
1046        tcg_gen_and_reg(tmp, in1, in2);
1047        tcg_gen_andc_reg(cb, cb, res);
1048        tcg_gen_or_reg(cb, cb, tmp);
1049        tcg_temp_free(tmp);
1050    }
1051
1052    switch (cf >> 1) {
1053    case 0: /* never / TR */
1054    case 1: /* undefined */
1055    case 5: /* undefined */
1056        cond = cond_make_f();
1057        break;
1058
1059    case 2: /* SBZ / NBZ */
1060        /* See hasless(v,1) from
1061         * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
1062         */
1063        tmp = tcg_temp_new();
1064        tcg_gen_subi_reg(tmp, res, 0x01010101u);
1065        tcg_gen_andc_reg(tmp, tmp, res);
1066        tcg_gen_andi_reg(tmp, tmp, 0x80808080u);
1067        cond = cond_make_0(TCG_COND_NE, tmp);
1068        tcg_temp_free(tmp);
1069        break;
1070
1071    case 3: /* SHZ / NHZ */
1072        tmp = tcg_temp_new();
1073        tcg_gen_subi_reg(tmp, res, 0x00010001u);
1074        tcg_gen_andc_reg(tmp, tmp, res);
1075        tcg_gen_andi_reg(tmp, tmp, 0x80008000u);
1076        cond = cond_make_0(TCG_COND_NE, tmp);
1077        tcg_temp_free(tmp);
1078        break;
1079
1080    case 4: /* SDC / NDC */
1081        tcg_gen_andi_reg(cb, cb, 0x88888888u);
1082        cond = cond_make_0(TCG_COND_NE, cb);
1083        break;
1084
1085    case 6: /* SBC / NBC */
1086        tcg_gen_andi_reg(cb, cb, 0x80808080u);
1087        cond = cond_make_0(TCG_COND_NE, cb);
1088        break;
1089
1090    case 7: /* SHC / NHC */
1091        tcg_gen_andi_reg(cb, cb, 0x80008000u);
1092        cond = cond_make_0(TCG_COND_NE, cb);
1093        break;
1094
1095    default:
1096        g_assert_not_reached();
1097    }
1098    if (cf & 8) {
1099        tcg_temp_free(cb);
1100    }
1101    if (cf & 1) {
1102        cond.c = tcg_invert_cond(cond.c);
1103    }
1104
1105    return cond;
1106}
1107
1108/* Compute signed overflow for addition.  */
1109static TCGv_reg do_add_sv(DisasContext *ctx, TCGv_reg res,
1110                          TCGv_reg in1, TCGv_reg in2)
1111{
1112    TCGv_reg sv = get_temp(ctx);
1113    TCGv_reg tmp = tcg_temp_new();
1114
1115    tcg_gen_xor_reg(sv, res, in1);
1116    tcg_gen_xor_reg(tmp, in1, in2);
1117    tcg_gen_andc_reg(sv, sv, tmp);
1118    tcg_temp_free(tmp);
1119
1120    return sv;
1121}
1122
1123/* Compute signed overflow for subtraction.  */
1124static TCGv_reg do_sub_sv(DisasContext *ctx, TCGv_reg res,
1125                          TCGv_reg in1, TCGv_reg in2)
1126{
1127    TCGv_reg sv = get_temp(ctx);
1128    TCGv_reg tmp = tcg_temp_new();
1129
1130    tcg_gen_xor_reg(sv, res, in1);
1131    tcg_gen_xor_reg(tmp, in1, in2);
1132    tcg_gen_and_reg(sv, sv, tmp);
1133    tcg_temp_free(tmp);
1134
1135    return sv;
1136}
1137
1138static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
1139                   TCGv_reg in2, unsigned shift, bool is_l,
1140                   bool is_tsv, bool is_tc, bool is_c, unsigned cf)
1141{
1142    TCGv_reg dest, cb, cb_msb, sv, tmp;
1143    unsigned c = cf >> 1;
1144    DisasCond cond;
1145
1146    dest = tcg_temp_new();
1147    cb = NULL;
1148    cb_msb = NULL;
1149
1150    if (shift) {
1151        tmp = get_temp(ctx);
1152        tcg_gen_shli_reg(tmp, in1, shift);
1153        in1 = tmp;
1154    }
1155
1156    if (!is_l || cond_need_cb(c)) {
1157        TCGv_reg zero = tcg_const_reg(0);
1158        cb_msb = get_temp(ctx);
1159        tcg_gen_add2_reg(dest, cb_msb, in1, zero, in2, zero);
1160        if (is_c) {
1161            tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cpu_psw_cb_msb, zero);
1162        }
1163        tcg_temp_free(zero);
1164        if (!is_l) {
1165            cb = get_temp(ctx);
1166            tcg_gen_xor_reg(cb, in1, in2);
1167            tcg_gen_xor_reg(cb, cb, dest);
1168        }
1169    } else {
1170        tcg_gen_add_reg(dest, in1, in2);
1171        if (is_c) {
1172            tcg_gen_add_reg(dest, dest, cpu_psw_cb_msb);
1173        }
1174    }
1175
1176    /* Compute signed overflow if required.  */
1177    sv = NULL;
1178    if (is_tsv || cond_need_sv(c)) {
1179        sv = do_add_sv(ctx, dest, in1, in2);
1180        if (is_tsv) {
1181            /* ??? Need to include overflow from shift.  */
1182            gen_helper_tsv(cpu_env, sv);
1183        }
1184    }
1185
1186    /* Emit any conditional trap before any writeback.  */
1187    cond = do_cond(cf, dest, cb_msb, sv);
1188    if (is_tc) {
1189        cond_prep(&cond);
1190        tmp = tcg_temp_new();
1191        tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
1192        gen_helper_tcond(cpu_env, tmp);
1193        tcg_temp_free(tmp);
1194    }
1195
1196    /* Write back the result.  */
1197    if (!is_l) {
1198        save_or_nullify(ctx, cpu_psw_cb, cb);
1199        save_or_nullify(ctx, cpu_psw_cb_msb, cb_msb);
1200    }
1201    save_gpr(ctx, rt, dest);
1202    tcg_temp_free(dest);
1203
1204    /* Install the new nullification.  */
1205    cond_free(&ctx->null_cond);
1206    ctx->null_cond = cond;
1207}
1208
1209static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a,
1210                       bool is_l, bool is_tsv, bool is_tc, bool is_c)
1211{
1212    TCGv_reg tcg_r1, tcg_r2;
1213
1214    if (a->cf) {
1215        nullify_over(ctx);
1216    }
1217    tcg_r1 = load_gpr(ctx, a->r1);
1218    tcg_r2 = load_gpr(ctx, a->r2);
1219    do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l, is_tsv, is_tc, is_c, a->cf);
1220    return nullify_end(ctx);
1221}
1222
1223static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
1224                       bool is_tsv, bool is_tc)
1225{
1226    TCGv_reg tcg_im, tcg_r2;
1227
1228    if (a->cf) {
1229        nullify_over(ctx);
1230    }
1231    tcg_im = load_const(ctx, a->i);
1232    tcg_r2 = load_gpr(ctx, a->r);
1233    do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf);
1234    return nullify_end(ctx);
1235}
1236
1237static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
1238                   TCGv_reg in2, bool is_tsv, bool is_b,
1239                   bool is_tc, unsigned cf)
1240{
1241    TCGv_reg dest, sv, cb, cb_msb, zero, tmp;
1242    unsigned c = cf >> 1;
1243    DisasCond cond;
1244
1245    dest = tcg_temp_new();
1246    cb = tcg_temp_new();
1247    cb_msb = tcg_temp_new();
1248
1249    zero = tcg_const_reg(0);
1250    if (is_b) {
1251        /* DEST,C = IN1 + ~IN2 + C.  */
1252        tcg_gen_not_reg(cb, in2);
1253        tcg_gen_add2_reg(dest, cb_msb, in1, zero, cpu_psw_cb_msb, zero);
1254        tcg_gen_add2_reg(dest, cb_msb, dest, cb_msb, cb, zero);
1255        tcg_gen_xor_reg(cb, cb, in1);
1256        tcg_gen_xor_reg(cb, cb, dest);
1257    } else {
1258        /* DEST,C = IN1 + ~IN2 + 1.  We can produce the same result in fewer
1259           operations by seeding the high word with 1 and subtracting.  */
1260        tcg_gen_movi_reg(cb_msb, 1);
1261        tcg_gen_sub2_reg(dest, cb_msb, in1, cb_msb, in2, zero);
1262        tcg_gen_eqv_reg(cb, in1, in2);
1263        tcg_gen_xor_reg(cb, cb, dest);
1264    }
1265    tcg_temp_free(zero);
1266
1267    /* Compute signed overflow if required.  */
1268    sv = NULL;
1269    if (is_tsv || cond_need_sv(c)) {
1270        sv = do_sub_sv(ctx, dest, in1, in2);
1271        if (is_tsv) {
1272            gen_helper_tsv(cpu_env, sv);
1273        }
1274    }
1275
1276    /* Compute the condition.  We cannot use the special case for borrow.  */
1277    if (!is_b) {
1278        cond = do_sub_cond(cf, dest, in1, in2, sv);
1279    } else {
1280        cond = do_cond(cf, dest, cb_msb, sv);
1281    }
1282
1283    /* Emit any conditional trap before any writeback.  */
1284    if (is_tc) {
1285        cond_prep(&cond);
1286        tmp = tcg_temp_new();
1287        tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
1288        gen_helper_tcond(cpu_env, tmp);
1289        tcg_temp_free(tmp);
1290    }
1291
1292    /* Write back the result.  */
1293    save_or_nullify(ctx, cpu_psw_cb, cb);
1294    save_or_nullify(ctx, cpu_psw_cb_msb, cb_msb);
1295    save_gpr(ctx, rt, dest);
1296    tcg_temp_free(dest);
1297
1298    /* Install the new nullification.  */
1299    cond_free(&ctx->null_cond);
1300    ctx->null_cond = cond;
1301}
1302
1303static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a,
1304                       bool is_tsv, bool is_b, bool is_tc)
1305{
1306    TCGv_reg tcg_r1, tcg_r2;
1307
1308    if (a->cf) {
1309        nullify_over(ctx);
1310    }
1311    tcg_r1 = load_gpr(ctx, a->r1);
1312    tcg_r2 = load_gpr(ctx, a->r2);
1313    do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf);
1314    return nullify_end(ctx);
1315}
1316
1317static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv)
1318{
1319    TCGv_reg tcg_im, tcg_r2;
1320
1321    if (a->cf) {
1322        nullify_over(ctx);
1323    }
1324    tcg_im = load_const(ctx, a->i);
1325    tcg_r2 = load_gpr(ctx, a->r);
1326    do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf);
1327    return nullify_end(ctx);
1328}
1329
1330static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
1331                      TCGv_reg in2, unsigned cf)
1332{
1333    TCGv_reg dest, sv;
1334    DisasCond cond;
1335
1336    dest = tcg_temp_new();
1337    tcg_gen_sub_reg(dest, in1, in2);
1338
1339    /* Compute signed overflow if required.  */
1340    sv = NULL;
1341    if (cond_need_sv(cf >> 1)) {
1342        sv = do_sub_sv(ctx, dest, in1, in2);
1343    }
1344
1345    /* Form the condition for the compare.  */
1346    cond = do_sub_cond(cf, dest, in1, in2, sv);
1347
1348    /* Clear.  */
1349    tcg_gen_movi_reg(dest, 0);
1350    save_gpr(ctx, rt, dest);
1351    tcg_temp_free(dest);
1352
1353    /* Install the new nullification.  */
1354    cond_free(&ctx->null_cond);
1355    ctx->null_cond = cond;
1356}
1357
1358static void do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
1359                   TCGv_reg in2, unsigned cf,
1360                   void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
1361{
1362    TCGv_reg dest = dest_gpr(ctx, rt);
1363
1364    /* Perform the operation, and writeback.  */
1365    fn(dest, in1, in2);
1366    save_gpr(ctx, rt, dest);
1367
1368    /* Install the new nullification.  */
1369    cond_free(&ctx->null_cond);
1370    if (cf) {
1371        ctx->null_cond = do_log_cond(cf, dest);
1372    }
1373}
1374
1375static bool do_log_reg(DisasContext *ctx, arg_rrr_cf *a,
1376                       void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
1377{
1378    TCGv_reg tcg_r1, tcg_r2;
1379
1380    if (a->cf) {
1381        nullify_over(ctx);
1382    }
1383    tcg_r1 = load_gpr(ctx, a->r1);
1384    tcg_r2 = load_gpr(ctx, a->r2);
1385    do_log(ctx, a->t, tcg_r1, tcg_r2, a->cf, fn);
1386    return nullify_end(ctx);
1387}
1388
1389static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
1390                    TCGv_reg in2, unsigned cf, bool is_tc,
1391                    void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
1392{
1393    TCGv_reg dest;
1394    DisasCond cond;
1395
1396    if (cf == 0) {
1397        dest = dest_gpr(ctx, rt);
1398        fn(dest, in1, in2);
1399        save_gpr(ctx, rt, dest);
1400        cond_free(&ctx->null_cond);
1401    } else {
1402        dest = tcg_temp_new();
1403        fn(dest, in1, in2);
1404
1405        cond = do_unit_cond(cf, dest, in1, in2);
1406
1407        if (is_tc) {
1408            TCGv_reg tmp = tcg_temp_new();
1409            cond_prep(&cond);
1410            tcg_gen_setcond_reg(cond.c, tmp, cond.a0, cond.a1);
1411            gen_helper_tcond(cpu_env, tmp);
1412            tcg_temp_free(tmp);
1413        }
1414        save_gpr(ctx, rt, dest);
1415
1416        cond_free(&ctx->null_cond);
1417        ctx->null_cond = cond;
1418    }
1419}
1420
1421#ifndef CONFIG_USER_ONLY
1422/* The "normal" usage is SP >= 0, wherein SP == 0 selects the space
1423   from the top 2 bits of the base register.  There are a few system
1424   instructions that have a 3-bit space specifier, for which SR0 is
1425   not special.  To handle this, pass ~SP.  */
1426static TCGv_i64 space_select(DisasContext *ctx, int sp, TCGv_reg base)
1427{
1428    TCGv_ptr ptr;
1429    TCGv_reg tmp;
1430    TCGv_i64 spc;
1431
1432    if (sp != 0) {
1433        if (sp < 0) {
1434            sp = ~sp;
1435        }
1436        spc = get_temp_tl(ctx);
1437        load_spr(ctx, spc, sp);
1438        return spc;
1439    }
1440    if (ctx->tb_flags & TB_FLAG_SR_SAME) {
1441        return cpu_srH;
1442    }
1443
1444    ptr = tcg_temp_new_ptr();
1445    tmp = tcg_temp_new();
1446    spc = get_temp_tl(ctx);
1447
1448    tcg_gen_shri_reg(tmp, base, TARGET_REGISTER_BITS - 5);
1449    tcg_gen_andi_reg(tmp, tmp, 030);
1450    tcg_gen_trunc_reg_ptr(ptr, tmp);
1451    tcg_temp_free(tmp);
1452
1453    tcg_gen_add_ptr(ptr, ptr, cpu_env);
1454    tcg_gen_ld_i64(spc, ptr, offsetof(CPUHPPAState, sr[4]));
1455    tcg_temp_free_ptr(ptr);
1456
1457    return spc;
1458}
1459#endif
1460
1461static void form_gva(DisasContext *ctx, TCGv_tl *pgva, TCGv_reg *pofs,
1462                     unsigned rb, unsigned rx, int scale, target_sreg disp,
1463                     unsigned sp, int modify, bool is_phys)
1464{
1465    TCGv_reg base = load_gpr(ctx, rb);
1466    TCGv_reg ofs;
1467
1468    /* Note that RX is mutually exclusive with DISP.  */
1469    if (rx) {
1470        ofs = get_temp(ctx);
1471        tcg_gen_shli_reg(ofs, cpu_gr[rx], scale);
1472        tcg_gen_add_reg(ofs, ofs, base);
1473    } else if (disp || modify) {
1474        ofs = get_temp(ctx);
1475        tcg_gen_addi_reg(ofs, base, disp);
1476    } else {
1477        ofs = base;
1478    }
1479
1480    *pofs = ofs;
1481#ifdef CONFIG_USER_ONLY
1482    *pgva = (modify <= 0 ? ofs : base);
1483#else
1484    TCGv_tl addr = get_temp_tl(ctx);
1485    tcg_gen_extu_reg_tl(addr, modify <= 0 ? ofs : base);
1486    if (ctx->tb_flags & PSW_W) {
1487        tcg_gen_andi_tl(addr, addr, 0x3fffffffffffffffull);
1488    }
1489    if (!is_phys) {
1490        tcg_gen_or_tl(addr, addr, space_select(ctx, sp, base));
1491    }
1492    *pgva = addr;
1493#endif
1494}
1495
1496/* Emit a memory load.  The modify parameter should be
1497 * < 0 for pre-modify,
1498 * > 0 for post-modify,
1499 * = 0 for no base register update.
1500 */
1501static void do_load_32(DisasContext *ctx, TCGv_i32 dest, unsigned rb,
1502                       unsigned rx, int scale, target_sreg disp,
1503                       unsigned sp, int modify, MemOp mop)
1504{
1505    TCGv_reg ofs;
1506    TCGv_tl addr;
1507
1508    /* Caller uses nullify_over/nullify_end.  */
1509    assert(ctx->null_cond.c == TCG_COND_NEVER);
1510
1511    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
1512             ctx->mmu_idx == MMU_PHYS_IDX);
1513    tcg_gen_qemu_ld_reg(dest, addr, ctx->mmu_idx, mop);
1514    if (modify) {
1515        save_gpr(ctx, rb, ofs);
1516    }
1517}
1518
1519static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb,
1520                       unsigned rx, int scale, target_sreg disp,
1521                       unsigned sp, int modify, MemOp mop)
1522{
1523    TCGv_reg ofs;
1524    TCGv_tl addr;
1525
1526    /* Caller uses nullify_over/nullify_end.  */
1527    assert(ctx->null_cond.c == TCG_COND_NEVER);
1528
1529    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
1530             ctx->mmu_idx == MMU_PHYS_IDX);
1531    tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop);
1532    if (modify) {
1533        save_gpr(ctx, rb, ofs);
1534    }
1535}
1536
1537static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb,
1538                        unsigned rx, int scale, target_sreg disp,
1539                        unsigned sp, int modify, MemOp mop)
1540{
1541    TCGv_reg ofs;
1542    TCGv_tl addr;
1543
1544    /* Caller uses nullify_over/nullify_end.  */
1545    assert(ctx->null_cond.c == TCG_COND_NEVER);
1546
1547    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
1548             ctx->mmu_idx == MMU_PHYS_IDX);
1549    tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop);
1550    if (modify) {
1551        save_gpr(ctx, rb, ofs);
1552    }
1553}
1554
1555static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
1556                        unsigned rx, int scale, target_sreg disp,
1557                        unsigned sp, int modify, MemOp mop)
1558{
1559    TCGv_reg ofs;
1560    TCGv_tl addr;
1561
1562    /* Caller uses nullify_over/nullify_end.  */
1563    assert(ctx->null_cond.c == TCG_COND_NEVER);
1564
1565    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
1566             ctx->mmu_idx == MMU_PHYS_IDX);
1567    tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop);
1568    if (modify) {
1569        save_gpr(ctx, rb, ofs);
1570    }
1571}
1572
1573#if TARGET_REGISTER_BITS == 64
1574#define do_load_reg   do_load_64
1575#define do_store_reg  do_store_64
1576#else
1577#define do_load_reg   do_load_32
1578#define do_store_reg  do_store_32
1579#endif
1580
1581static bool do_load(DisasContext *ctx, unsigned rt, unsigned rb,
1582                    unsigned rx, int scale, target_sreg disp,
1583                    unsigned sp, int modify, MemOp mop)
1584{
1585    TCGv_reg dest;
1586
1587    nullify_over(ctx);
1588
1589    if (modify == 0) {
1590        /* No base register update.  */
1591        dest = dest_gpr(ctx, rt);
1592    } else {
1593        /* Make sure if RT == RB, we see the result of the load.  */
1594        dest = get_temp(ctx);
1595    }
1596    do_load_reg(ctx, dest, rb, rx, scale, disp, sp, modify, mop);
1597    save_gpr(ctx, rt, dest);
1598
1599    return nullify_end(ctx);
1600}
1601
1602static bool do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
1603                      unsigned rx, int scale, target_sreg disp,
1604                      unsigned sp, int modify)
1605{
1606    TCGv_i32 tmp;
1607
1608    nullify_over(ctx);
1609
1610    tmp = tcg_temp_new_i32();
1611    do_load_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
1612    save_frw_i32(rt, tmp);
1613    tcg_temp_free_i32(tmp);
1614
1615    if (rt == 0) {
1616        gen_helper_loaded_fr0(cpu_env);
1617    }
1618
1619    return nullify_end(ctx);
1620}
1621
1622static bool trans_fldw(DisasContext *ctx, arg_ldst *a)
1623{
1624    return do_floadw(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
1625                     a->disp, a->sp, a->m);
1626}
1627
1628static bool do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
1629                      unsigned rx, int scale, target_sreg disp,
1630                      unsigned sp, int modify)
1631{
1632    TCGv_i64 tmp;
1633
1634    nullify_over(ctx);
1635
1636    tmp = tcg_temp_new_i64();
1637    do_load_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
1638    save_frd(rt, tmp);
1639    tcg_temp_free_i64(tmp);
1640
1641    if (rt == 0) {
1642        gen_helper_loaded_fr0(cpu_env);
1643    }
1644
1645    return nullify_end(ctx);
1646}
1647
1648static bool trans_fldd(DisasContext *ctx, arg_ldst *a)
1649{
1650    return do_floadd(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
1651                     a->disp, a->sp, a->m);
1652}
1653
1654static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
1655                     target_sreg disp, unsigned sp,
1656                     int modify, MemOp mop)
1657{
1658    nullify_over(ctx);
1659    do_store_reg(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, sp, modify, mop);
1660    return nullify_end(ctx);
1661}
1662
1663static bool do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
1664                       unsigned rx, int scale, target_sreg disp,
1665                       unsigned sp, int modify)
1666{
1667    TCGv_i32 tmp;
1668
1669    nullify_over(ctx);
1670
1671    tmp = load_frw_i32(rt);
1672    do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
1673    tcg_temp_free_i32(tmp);
1674
1675    return nullify_end(ctx);
1676}
1677
1678static bool trans_fstw(DisasContext *ctx, arg_ldst *a)
1679{
1680    return do_fstorew(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
1681                      a->disp, a->sp, a->m);
1682}
1683
1684static bool do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
1685                       unsigned rx, int scale, target_sreg disp,
1686                       unsigned sp, int modify)
1687{
1688    TCGv_i64 tmp;
1689
1690    nullify_over(ctx);
1691
1692    tmp = load_frd(rt);
1693    do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
1694    tcg_temp_free_i64(tmp);
1695
1696    return nullify_end(ctx);
1697}
1698
1699static bool trans_fstd(DisasContext *ctx, arg_ldst *a)
1700{
1701    return do_fstored(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
1702                      a->disp, a->sp, a->m);
1703}
1704
1705static bool do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
1706                       void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
1707{
1708    TCGv_i32 tmp;
1709
1710    nullify_over(ctx);
1711    tmp = load_frw0_i32(ra);
1712
1713    func(tmp, cpu_env, tmp);
1714
1715    save_frw_i32(rt, tmp);
1716    tcg_temp_free_i32(tmp);
1717    return nullify_end(ctx);
1718}
1719
1720static bool do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
1721                       void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
1722{
1723    TCGv_i32 dst;
1724    TCGv_i64 src;
1725
1726    nullify_over(ctx);
1727    src = load_frd(ra);
1728    dst = tcg_temp_new_i32();
1729
1730    func(dst, cpu_env, src);
1731
1732    tcg_temp_free_i64(src);
1733    save_frw_i32(rt, dst);
1734    tcg_temp_free_i32(dst);
1735    return nullify_end(ctx);
1736}
1737
1738static bool do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
1739                       void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
1740{
1741    TCGv_i64 tmp;
1742
1743    nullify_over(ctx);
1744    tmp = load_frd0(ra);
1745
1746    func(tmp, cpu_env, tmp);
1747
1748    save_frd(rt, tmp);
1749    tcg_temp_free_i64(tmp);
1750    return nullify_end(ctx);
1751}
1752
1753static bool do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
1754                       void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
1755{
1756    TCGv_i32 src;
1757    TCGv_i64 dst;
1758
1759    nullify_over(ctx);
1760    src = load_frw0_i32(ra);
1761    dst = tcg_temp_new_i64();
1762
1763    func(dst, cpu_env, src);
1764
1765    tcg_temp_free_i32(src);
1766    save_frd(rt, dst);
1767    tcg_temp_free_i64(dst);
1768    return nullify_end(ctx);
1769}
1770
1771static bool do_fop_weww(DisasContext *ctx, unsigned rt,
1772                        unsigned ra, unsigned rb,
1773                        void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
1774{
1775    TCGv_i32 a, b;
1776
1777    nullify_over(ctx);
1778    a = load_frw0_i32(ra);
1779    b = load_frw0_i32(rb);
1780
1781    func(a, cpu_env, a, b);
1782
1783    tcg_temp_free_i32(b);
1784    save_frw_i32(rt, a);
1785    tcg_temp_free_i32(a);
1786    return nullify_end(ctx);
1787}
1788
1789static bool do_fop_dedd(DisasContext *ctx, unsigned rt,
1790                        unsigned ra, unsigned rb,
1791                        void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
1792{
1793    TCGv_i64 a, b;
1794
1795    nullify_over(ctx);
1796    a = load_frd0(ra);
1797    b = load_frd0(rb);
1798
1799    func(a, cpu_env, a, b);
1800
1801    tcg_temp_free_i64(b);
1802    save_frd(rt, a);
1803    tcg_temp_free_i64(a);
1804    return nullify_end(ctx);
1805}
1806
1807/* Emit an unconditional branch to a direct target, which may or may not
1808   have already had nullification handled.  */
1809static bool do_dbranch(DisasContext *ctx, target_ureg dest,
1810                       unsigned link, bool is_n)
1811{
1812    if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
1813        if (link != 0) {
1814            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
1815        }
1816        ctx->iaoq_n = dest;
1817        if (is_n) {
1818            ctx->null_cond.c = TCG_COND_ALWAYS;
1819        }
1820    } else {
1821        nullify_over(ctx);
1822
1823        if (link != 0) {
1824            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
1825        }
1826
1827        if (is_n && use_nullify_skip(ctx)) {
1828            nullify_set(ctx, 0);
1829            gen_goto_tb(ctx, 0, dest, dest + 4);
1830        } else {
1831            nullify_set(ctx, is_n);
1832            gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
1833        }
1834
1835        nullify_end(ctx);
1836
1837        nullify_set(ctx, 0);
1838        gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
1839        ctx->base.is_jmp = DISAS_NORETURN;
1840    }
1841    return true;
1842}
1843
1844/* Emit a conditional branch to a direct target.  If the branch itself
1845   is nullified, we should have already used nullify_over.  */
1846static bool do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
1847                       DisasCond *cond)
1848{
1849    target_ureg dest = iaoq_dest(ctx, disp);
1850    TCGLabel *taken = NULL;
1851    TCGCond c = cond->c;
1852    bool n;
1853
1854    assert(ctx->null_cond.c == TCG_COND_NEVER);
1855
1856    /* Handle TRUE and NEVER as direct branches.  */
1857    if (c == TCG_COND_ALWAYS) {
1858        return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
1859    }
1860    if (c == TCG_COND_NEVER) {
1861        return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
1862    }
1863
1864    taken = gen_new_label();
1865    cond_prep(cond);
1866    tcg_gen_brcond_reg(c, cond->a0, cond->a1, taken);
1867    cond_free(cond);
1868
1869    /* Not taken: Condition not satisfied; nullify on backward branches. */
1870    n = is_n && disp < 0;
1871    if (n && use_nullify_skip(ctx)) {
1872        nullify_set(ctx, 0);
1873        gen_goto_tb(ctx, 0, ctx->iaoq_n, ctx->iaoq_n + 4);
1874    } else {
1875        if (!n && ctx->null_lab) {
1876            gen_set_label(ctx->null_lab);
1877            ctx->null_lab = NULL;
1878        }
1879        nullify_set(ctx, n);
1880        if (ctx->iaoq_n == -1) {
1881            /* The temporary iaoq_n_var died at the branch above.
1882               Regenerate it here instead of saving it.  */
1883            tcg_gen_addi_reg(ctx->iaoq_n_var, cpu_iaoq_b, 4);
1884        }
1885        gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
1886    }
1887
1888    gen_set_label(taken);
1889
1890    /* Taken: Condition satisfied; nullify on forward branches.  */
1891    n = is_n && disp >= 0;
1892    if (n && use_nullify_skip(ctx)) {
1893        nullify_set(ctx, 0);
1894        gen_goto_tb(ctx, 1, dest, dest + 4);
1895    } else {
1896        nullify_set(ctx, n);
1897        gen_goto_tb(ctx, 1, ctx->iaoq_b, dest);
1898    }
1899
1900    /* Not taken: the branch itself was nullified.  */
1901    if (ctx->null_lab) {
1902        gen_set_label(ctx->null_lab);
1903        ctx->null_lab = NULL;
1904        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
1905    } else {
1906        ctx->base.is_jmp = DISAS_NORETURN;
1907    }
1908    return true;
1909}
1910
1911/* Emit an unconditional branch to an indirect target.  This handles
1912   nullification of the branch itself.  */
1913static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
1914                       unsigned link, bool is_n)
1915{
1916    TCGv_reg a0, a1, next, tmp;
1917    TCGCond c;
1918
1919    assert(ctx->null_lab == NULL);
1920
1921    if (ctx->null_cond.c == TCG_COND_NEVER) {
1922        if (link != 0) {
1923            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
1924        }
1925        next = get_temp(ctx);
1926        tcg_gen_mov_reg(next, dest);
1927        if (is_n) {
1928            if (use_nullify_skip(ctx)) {
1929                tcg_gen_mov_reg(cpu_iaoq_f, next);
1930                tcg_gen_addi_reg(cpu_iaoq_b, next, 4);
1931                nullify_set(ctx, 0);
1932                ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
1933                return true;
1934            }
1935            ctx->null_cond.c = TCG_COND_ALWAYS;
1936        }
1937        ctx->iaoq_n = -1;
1938        ctx->iaoq_n_var = next;
1939    } else if (is_n && use_nullify_skip(ctx)) {
1940        /* The (conditional) branch, B, nullifies the next insn, N,
1941           and we're allowed to skip execution N (no single-step or
1942           tracepoint in effect).  Since the goto_ptr that we must use
1943           for the indirect branch consumes no special resources, we
1944           can (conditionally) skip B and continue execution.  */
1945        /* The use_nullify_skip test implies we have a known control path.  */
1946        tcg_debug_assert(ctx->iaoq_b != -1);
1947        tcg_debug_assert(ctx->iaoq_n != -1);
1948
1949        /* We do have to handle the non-local temporary, DEST, before
1950           branching.  Since IOAQ_F is not really live at this point, we
1951           can simply store DEST optimistically.  Similarly with IAOQ_B.  */
1952        tcg_gen_mov_reg(cpu_iaoq_f, dest);
1953        tcg_gen_addi_reg(cpu_iaoq_b, dest, 4);
1954
1955        nullify_over(ctx);
1956        if (link != 0) {
1957            tcg_gen_movi_reg(cpu_gr[link], ctx->iaoq_n);
1958        }
1959        tcg_gen_lookup_and_goto_ptr();
1960        return nullify_end(ctx);
1961    } else {
1962        cond_prep(&ctx->null_cond);
1963        c = ctx->null_cond.c;
1964        a0 = ctx->null_cond.a0;
1965        a1 = ctx->null_cond.a1;
1966
1967        tmp = tcg_temp_new();
1968        next = get_temp(ctx);
1969
1970        copy_iaoq_entry(tmp, ctx->iaoq_n, ctx->iaoq_n_var);
1971        tcg_gen_movcond_reg(c, next, a0, a1, tmp, dest);
1972        ctx->iaoq_n = -1;
1973        ctx->iaoq_n_var = next;
1974
1975        if (link != 0) {
1976            tcg_gen_movcond_reg(c, cpu_gr[link], a0, a1, cpu_gr[link], tmp);
1977        }
1978
1979        if (is_n) {
1980            /* The branch nullifies the next insn, which means the state of N
1981               after the branch is the inverse of the state of N that applied
1982               to the branch.  */
1983            tcg_gen_setcond_reg(tcg_invert_cond(c), cpu_psw_n, a0, a1);
1984            cond_free(&ctx->null_cond);
1985            ctx->null_cond = cond_make_n();
1986            ctx->psw_n_nonzero = true;
1987        } else {
1988            cond_free(&ctx->null_cond);
1989        }
1990    }
1991    return true;
1992}
1993
1994/* Implement
1995 *    if (IAOQ_Front{30..31} < GR[b]{30..31})
1996 *      IAOQ_Next{30..31} ← GR[b]{30..31};
1997 *    else
1998 *      IAOQ_Next{30..31} ← IAOQ_Front{30..31};
1999 * which keeps the privilege level from being increased.
2000 */
2001static TCGv_reg do_ibranch_priv(DisasContext *ctx, TCGv_reg offset)
2002{
2003    TCGv_reg dest;
2004    switch (ctx->privilege) {
2005    case 0:
2006        /* Privilege 0 is maximum and is allowed to decrease.  */
2007        return offset;
2008    case 3:
2009        /* Privilege 3 is minimum and is never allowed to increase.  */
2010        dest = get_temp(ctx);
2011        tcg_gen_ori_reg(dest, offset, 3);
2012        break;
2013    default:
2014        dest = get_temp(ctx);
2015        tcg_gen_andi_reg(dest, offset, -4);
2016        tcg_gen_ori_reg(dest, dest, ctx->privilege);
2017        tcg_gen_movcond_reg(TCG_COND_GTU, dest, dest, offset, dest, offset);
2018        break;
2019    }
2020    return dest;
2021}
2022
2023#ifdef CONFIG_USER_ONLY
2024/* On Linux, page zero is normally marked execute only + gateway.
2025   Therefore normal read or write is supposed to fail, but specific
2026   offsets have kernel code mapped to raise permissions to implement
2027   system calls.  Handling this via an explicit check here, rather
2028   in than the "be disp(sr2,r0)" instruction that probably sent us
2029   here, is the easiest way to handle the branch delay slot on the
2030   aforementioned BE.  */
2031static void do_page_zero(DisasContext *ctx)
2032{
2033    /* If by some means we get here with PSW[N]=1, that implies that
2034       the B,GATE instruction would be skipped, and we'd fault on the
2035       next insn within the privilaged page.  */
2036    switch (ctx->null_cond.c) {
2037    case TCG_COND_NEVER:
2038        break;
2039    case TCG_COND_ALWAYS:
2040        tcg_gen_movi_reg(cpu_psw_n, 0);
2041        goto do_sigill;
2042    default:
2043        /* Since this is always the first (and only) insn within the
2044           TB, we should know the state of PSW[N] from TB->FLAGS.  */
2045        g_assert_not_reached();
2046    }
2047
2048    /* Check that we didn't arrive here via some means that allowed
2049       non-sequential instruction execution.  Normally the PSW[B] bit
2050       detects this by disallowing the B,GATE instruction to execute
2051       under such conditions.  */
2052    if (ctx->iaoq_b != ctx->iaoq_f + 4) {
2053        goto do_sigill;
2054    }
2055
2056    switch (ctx->iaoq_f & -4) {
2057    case 0x00: /* Null pointer call */
2058        gen_excp_1(EXCP_IMP);
2059        ctx->base.is_jmp = DISAS_NORETURN;
2060        break;
2061
2062    case 0xb0: /* LWS */
2063        gen_excp_1(EXCP_SYSCALL_LWS);
2064        ctx->base.is_jmp = DISAS_NORETURN;
2065        break;
2066
2067    case 0xe0: /* SET_THREAD_POINTER */
2068        tcg_gen_st_reg(cpu_gr[26], cpu_env, offsetof(CPUHPPAState, cr[27]));
2069        tcg_gen_ori_reg(cpu_iaoq_f, cpu_gr[31], 3);
2070        tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
2071        ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
2072        break;
2073
2074    case 0x100: /* SYSCALL */
2075        gen_excp_1(EXCP_SYSCALL);
2076        ctx->base.is_jmp = DISAS_NORETURN;
2077        break;
2078
2079    default:
2080    do_sigill:
2081        gen_excp_1(EXCP_ILL);
2082        ctx->base.is_jmp = DISAS_NORETURN;
2083        break;
2084    }
2085}
2086#endif
2087
2088static bool trans_nop(DisasContext *ctx, arg_nop *a)
2089{
2090    cond_free(&ctx->null_cond);
2091    return true;
2092}
2093
2094static bool trans_break(DisasContext *ctx, arg_break *a)
2095{
2096    return gen_excp_iir(ctx, EXCP_BREAK);
2097}
2098
2099static bool trans_sync(DisasContext *ctx, arg_sync *a)
2100{
2101    /* No point in nullifying the memory barrier.  */
2102    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
2103
2104    cond_free(&ctx->null_cond);
2105    return true;
2106}
2107
2108static bool trans_mfia(DisasContext *ctx, arg_mfia *a)
2109{
2110    unsigned rt = a->t;
2111    TCGv_reg tmp = dest_gpr(ctx, rt);
2112    tcg_gen_movi_reg(tmp, ctx->iaoq_f);
2113    save_gpr(ctx, rt, tmp);
2114
2115    cond_free(&ctx->null_cond);
2116    return true;
2117}
2118
2119static bool trans_mfsp(DisasContext *ctx, arg_mfsp *a)
2120{
2121    unsigned rt = a->t;
2122    unsigned rs = a->sp;
2123    TCGv_i64 t0 = tcg_temp_new_i64();
2124    TCGv_reg t1 = tcg_temp_new();
2125
2126    load_spr(ctx, t0, rs);
2127    tcg_gen_shri_i64(t0, t0, 32);
2128    tcg_gen_trunc_i64_reg(t1, t0);
2129
2130    save_gpr(ctx, rt, t1);
2131    tcg_temp_free(t1);
2132    tcg_temp_free_i64(t0);
2133
2134    cond_free(&ctx->null_cond);
2135    return true;
2136}
2137
2138static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
2139{
2140    unsigned rt = a->t;
2141    unsigned ctl = a->r;
2142    TCGv_reg tmp;
2143
2144    switch (ctl) {
2145    case CR_SAR:
2146#ifdef TARGET_HPPA64
2147        if (a->e == 0) {
2148            /* MFSAR without ,W masks low 5 bits.  */
2149            tmp = dest_gpr(ctx, rt);
2150            tcg_gen_andi_reg(tmp, cpu_sar, 31);
2151            save_gpr(ctx, rt, tmp);
2152            goto done;
2153        }
2154#endif
2155        save_gpr(ctx, rt, cpu_sar);
2156        goto done;
2157    case CR_IT: /* Interval Timer */
2158        /* FIXME: Respect PSW_S bit.  */
2159        nullify_over(ctx);
2160        tmp = dest_gpr(ctx, rt);
2161        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2162            gen_io_start();
2163            gen_helper_read_interval_timer(tmp);
2164            ctx->base.is_jmp = DISAS_IAQ_N_STALE;
2165        } else {
2166            gen_helper_read_interval_timer(tmp);
2167        }
2168        save_gpr(ctx, rt, tmp);
2169        return nullify_end(ctx);
2170    case 26:
2171    case 27:
2172        break;
2173    default:
2174        /* All other control registers are privileged.  */
2175        CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
2176        break;
2177    }
2178
2179    tmp = get_temp(ctx);
2180    tcg_gen_ld_reg(tmp, cpu_env, offsetof(CPUHPPAState, cr[ctl]));
2181    save_gpr(ctx, rt, tmp);
2182
2183 done:
2184    cond_free(&ctx->null_cond);
2185    return true;
2186}
2187
2188static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a)
2189{
2190    unsigned rr = a->r;
2191    unsigned rs = a->sp;
2192    TCGv_i64 t64;
2193
2194    if (rs >= 5) {
2195        CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
2196    }
2197    nullify_over(ctx);
2198
2199    t64 = tcg_temp_new_i64();
2200    tcg_gen_extu_reg_i64(t64, load_gpr(ctx, rr));
2201    tcg_gen_shli_i64(t64, t64, 32);
2202
2203    if (rs >= 4) {
2204        tcg_gen_st_i64(t64, cpu_env, offsetof(CPUHPPAState, sr[rs]));
2205        ctx->tb_flags &= ~TB_FLAG_SR_SAME;
2206    } else {
2207        tcg_gen_mov_i64(cpu_sr[rs], t64);
2208    }
2209    tcg_temp_free_i64(t64);
2210
2211    return nullify_end(ctx);
2212}
2213
2214static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
2215{
2216    unsigned ctl = a->t;
2217    TCGv_reg reg;
2218    TCGv_reg tmp;
2219
2220    if (ctl == CR_SAR) {
2221        reg = load_gpr(ctx, a->r);
2222        tmp = tcg_temp_new();
2223        tcg_gen_andi_reg(tmp, reg, TARGET_REGISTER_BITS - 1);
2224        save_or_nullify(ctx, cpu_sar, tmp);
2225        tcg_temp_free(tmp);
2226
2227        cond_free(&ctx->null_cond);
2228        return true;
2229    }
2230
2231    /* All other control registers are privileged or read-only.  */
2232    CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
2233
2234#ifndef CONFIG_USER_ONLY
2235    nullify_over(ctx);
2236    reg = load_gpr(ctx, a->r);
2237
2238    switch (ctl) {
2239    case CR_IT:
2240        gen_helper_write_interval_timer(cpu_env, reg);
2241        break;
2242    case CR_EIRR:
2243        gen_helper_write_eirr(cpu_env, reg);
2244        break;
2245    case CR_EIEM:
2246        gen_helper_write_eiem(cpu_env, reg);
2247        ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
2248        break;
2249
2250    case CR_IIASQ:
2251    case CR_IIAOQ:
2252        /* FIXME: Respect PSW_Q bit */
2253        /* The write advances the queue and stores to the back element.  */
2254        tmp = get_temp(ctx);
2255        tcg_gen_ld_reg(tmp, cpu_env,
2256                       offsetof(CPUHPPAState, cr_back[ctl - CR_IIASQ]));
2257        tcg_gen_st_reg(tmp, cpu_env, offsetof(CPUHPPAState, cr[ctl]));
2258        tcg_gen_st_reg(reg, cpu_env,
2259                       offsetof(CPUHPPAState, cr_back[ctl - CR_IIASQ]));
2260        break;
2261
2262    case CR_PID1:
2263    case CR_PID2:
2264    case CR_PID3:
2265    case CR_PID4:
2266        tcg_gen_st_reg(reg, cpu_env, offsetof(CPUHPPAState, cr[ctl]));
2267#ifndef CONFIG_USER_ONLY
2268        gen_helper_change_prot_id(cpu_env);
2269#endif
2270        break;
2271
2272    default:
2273        tcg_gen_st_reg(reg, cpu_env, offsetof(CPUHPPAState, cr[ctl]));
2274        break;
2275    }
2276    return nullify_end(ctx);
2277#endif
2278}
2279
2280static bool trans_mtsarcm(DisasContext *ctx, arg_mtsarcm *a)
2281{
2282    TCGv_reg tmp = tcg_temp_new();
2283
2284    tcg_gen_not_reg(tmp, load_gpr(ctx, a->r));
2285    tcg_gen_andi_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
2286    save_or_nullify(ctx, cpu_sar, tmp);
2287    tcg_temp_free(tmp);
2288
2289    cond_free(&ctx->null_cond);
2290    return true;
2291}
2292
2293static bool trans_ldsid(DisasContext *ctx, arg_ldsid *a)
2294{
2295    TCGv_reg dest = dest_gpr(ctx, a->t);
2296
2297#ifdef CONFIG_USER_ONLY
2298    /* We don't implement space registers in user mode. */
2299    tcg_gen_movi_reg(dest, 0);
2300#else
2301    TCGv_i64 t0 = tcg_temp_new_i64();
2302
2303    tcg_gen_mov_i64(t0, space_select(ctx, a->sp, load_gpr(ctx, a->b)));
2304    tcg_gen_shri_i64(t0, t0, 32);
2305    tcg_gen_trunc_i64_reg(dest, t0);
2306
2307    tcg_temp_free_i64(t0);
2308#endif
2309    save_gpr(ctx, a->t, dest);
2310
2311    cond_free(&ctx->null_cond);
2312    return true;
2313}
2314
2315static bool trans_rsm(DisasContext *ctx, arg_rsm *a)
2316{
2317    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2318#ifndef CONFIG_USER_ONLY
2319    TCGv_reg tmp;
2320
2321    nullify_over(ctx);
2322
2323    tmp = get_temp(ctx);
2324    tcg_gen_ld_reg(tmp, cpu_env, offsetof(CPUHPPAState, psw));
2325    tcg_gen_andi_reg(tmp, tmp, ~a->i);
2326    gen_helper_swap_system_mask(tmp, cpu_env, tmp);
2327    save_gpr(ctx, a->t, tmp);
2328
2329    /* Exit the TB to recognize new interrupts, e.g. PSW_M.  */
2330    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
2331    return nullify_end(ctx);
2332#endif
2333}
2334
2335static bool trans_ssm(DisasContext *ctx, arg_ssm *a)
2336{
2337    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2338#ifndef CONFIG_USER_ONLY
2339    TCGv_reg tmp;
2340
2341    nullify_over(ctx);
2342
2343    tmp = get_temp(ctx);
2344    tcg_gen_ld_reg(tmp, cpu_env, offsetof(CPUHPPAState, psw));
2345    tcg_gen_ori_reg(tmp, tmp, a->i);
2346    gen_helper_swap_system_mask(tmp, cpu_env, tmp);
2347    save_gpr(ctx, a->t, tmp);
2348
2349    /* Exit the TB to recognize new interrupts, e.g. PSW_I.  */
2350    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
2351    return nullify_end(ctx);
2352#endif
2353}
2354
2355static bool trans_mtsm(DisasContext *ctx, arg_mtsm *a)
2356{
2357    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2358#ifndef CONFIG_USER_ONLY
2359    TCGv_reg tmp, reg;
2360    nullify_over(ctx);
2361
2362    reg = load_gpr(ctx, a->r);
2363    tmp = get_temp(ctx);
2364    gen_helper_swap_system_mask(tmp, cpu_env, reg);
2365
2366    /* Exit the TB to recognize new interrupts.  */
2367    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
2368    return nullify_end(ctx);
2369#endif
2370}
2371
2372static bool do_rfi(DisasContext *ctx, bool rfi_r)
2373{
2374    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2375#ifndef CONFIG_USER_ONLY
2376    nullify_over(ctx);
2377
2378    if (rfi_r) {
2379        gen_helper_rfi_r(cpu_env);
2380    } else {
2381        gen_helper_rfi(cpu_env);
2382    }
2383    /* Exit the TB to recognize new interrupts.  */
2384    if (ctx->base.singlestep_enabled) {
2385        gen_excp_1(EXCP_DEBUG);
2386    } else {
2387        tcg_gen_exit_tb(NULL, 0);
2388    }
2389    ctx->base.is_jmp = DISAS_NORETURN;
2390
2391    return nullify_end(ctx);
2392#endif
2393}
2394
2395static bool trans_rfi(DisasContext *ctx, arg_rfi *a)
2396{
2397    return do_rfi(ctx, false);
2398}
2399
2400static bool trans_rfi_r(DisasContext *ctx, arg_rfi_r *a)
2401{
2402    return do_rfi(ctx, true);
2403}
2404
2405static bool trans_halt(DisasContext *ctx, arg_halt *a)
2406{
2407    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2408#ifndef CONFIG_USER_ONLY
2409    nullify_over(ctx);
2410    gen_helper_halt(cpu_env);
2411    ctx->base.is_jmp = DISAS_NORETURN;
2412    return nullify_end(ctx);
2413#endif
2414}
2415
2416static bool trans_reset(DisasContext *ctx, arg_reset *a)
2417{
2418    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2419#ifndef CONFIG_USER_ONLY
2420    nullify_over(ctx);
2421    gen_helper_reset(cpu_env);
2422    ctx->base.is_jmp = DISAS_NORETURN;
2423    return nullify_end(ctx);
2424#endif
2425}
2426
2427static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
2428{
2429    if (a->m) {
2430        TCGv_reg dest = dest_gpr(ctx, a->b);
2431        TCGv_reg src1 = load_gpr(ctx, a->b);
2432        TCGv_reg src2 = load_gpr(ctx, a->x);
2433
2434        /* The only thing we need to do is the base register modification.  */
2435        tcg_gen_add_reg(dest, src1, src2);
2436        save_gpr(ctx, a->b, dest);
2437    }
2438    cond_free(&ctx->null_cond);
2439    return true;
2440}
2441
2442static bool trans_probe(DisasContext *ctx, arg_probe *a)
2443{
2444    TCGv_reg dest, ofs;
2445    TCGv_i32 level, want;
2446    TCGv_tl addr;
2447
2448    nullify_over(ctx);
2449
2450    dest = dest_gpr(ctx, a->t);
2451    form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
2452
2453    if (a->imm) {
2454        level = tcg_const_i32(a->ri);
2455    } else {
2456        level = tcg_temp_new_i32();
2457        tcg_gen_trunc_reg_i32(level, load_gpr(ctx, a->ri));
2458        tcg_gen_andi_i32(level, level, 3);
2459    }
2460    want = tcg_const_i32(a->write ? PAGE_WRITE : PAGE_READ);
2461
2462    gen_helper_probe(dest, cpu_env, addr, level, want);
2463
2464    tcg_temp_free_i32(want);
2465    tcg_temp_free_i32(level);
2466
2467    save_gpr(ctx, a->t, dest);
2468    return nullify_end(ctx);
2469}
2470
2471static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a)
2472{
2473    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2474#ifndef CONFIG_USER_ONLY
2475    TCGv_tl addr;
2476    TCGv_reg ofs, reg;
2477
2478    nullify_over(ctx);
2479
2480    form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
2481    reg = load_gpr(ctx, a->r);
2482    if (a->addr) {
2483        gen_helper_itlba(cpu_env, addr, reg);
2484    } else {
2485        gen_helper_itlbp(cpu_env, addr, reg);
2486    }
2487
2488    /* Exit TB for TLB change if mmu is enabled.  */
2489    if (ctx->tb_flags & PSW_C) {
2490        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
2491    }
2492    return nullify_end(ctx);
2493#endif
2494}
2495
2496static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a)
2497{
2498    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2499#ifndef CONFIG_USER_ONLY
2500    TCGv_tl addr;
2501    TCGv_reg ofs;
2502
2503    nullify_over(ctx);
2504
2505    form_gva(ctx, &addr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);
2506    if (a->m) {
2507        save_gpr(ctx, a->b, ofs);
2508    }
2509    if (a->local) {
2510        gen_helper_ptlbe(cpu_env);
2511    } else {
2512        gen_helper_ptlb(cpu_env, addr);
2513    }
2514
2515    /* Exit TB for TLB change if mmu is enabled.  */
2516    if (ctx->tb_flags & PSW_C) {
2517        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
2518    }
2519    return nullify_end(ctx);
2520#endif
2521}
2522
2523/*
2524 * Implement the pcxl and pcxl2 Fast TLB Insert instructions.
2525 * See
2526 *     https://parisc.wiki.kernel.org/images-parisc/a/a9/Pcxl2_ers.pdf
2527 *     page 13-9 (195/206)
2528 */
2529static bool trans_ixtlbxf(DisasContext *ctx, arg_ixtlbxf *a)
2530{
2531    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2532#ifndef CONFIG_USER_ONLY
2533    TCGv_tl addr, atl, stl;
2534    TCGv_reg reg;
2535
2536    nullify_over(ctx);
2537
2538    /*
2539     * FIXME:
2540     *  if (not (pcxl or pcxl2))
2541     *    return gen_illegal(ctx);
2542     *
2543     * Note for future: these are 32-bit systems; no hppa64.
2544     */
2545
2546    atl = tcg_temp_new_tl();
2547    stl = tcg_temp_new_tl();
2548    addr = tcg_temp_new_tl();
2549
2550    tcg_gen_ld32u_i64(stl, cpu_env,
2551                      a->data ? offsetof(CPUHPPAState, cr[CR_ISR])
2552                      : offsetof(CPUHPPAState, cr[CR_IIASQ]));
2553    tcg_gen_ld32u_i64(atl, cpu_env,
2554                      a->data ? offsetof(CPUHPPAState, cr[CR_IOR])
2555                      : offsetof(CPUHPPAState, cr[CR_IIAOQ]));
2556    tcg_gen_shli_i64(stl, stl, 32);
2557    tcg_gen_or_tl(addr, atl, stl);
2558    tcg_temp_free_tl(atl);
2559    tcg_temp_free_tl(stl);
2560
2561    reg = load_gpr(ctx, a->r);
2562    if (a->addr) {
2563        gen_helper_itlba(cpu_env, addr, reg);
2564    } else {
2565        gen_helper_itlbp(cpu_env, addr, reg);
2566    }
2567    tcg_temp_free_tl(addr);
2568
2569    /* Exit TB for TLB change if mmu is enabled.  */
2570    if (ctx->tb_flags & PSW_C) {
2571        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
2572    }
2573    return nullify_end(ctx);
2574#endif
2575}
2576
2577static bool trans_lpa(DisasContext *ctx, arg_ldst *a)
2578{
2579    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2580#ifndef CONFIG_USER_ONLY
2581    TCGv_tl vaddr;
2582    TCGv_reg ofs, paddr;
2583
2584    nullify_over(ctx);
2585
2586    form_gva(ctx, &vaddr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);
2587
2588    paddr = tcg_temp_new();
2589    gen_helper_lpa(paddr, cpu_env, vaddr);
2590
2591    /* Note that physical address result overrides base modification.  */
2592    if (a->m) {
2593        save_gpr(ctx, a->b, ofs);
2594    }
2595    save_gpr(ctx, a->t, paddr);
2596    tcg_temp_free(paddr);
2597
2598    return nullify_end(ctx);
2599#endif
2600}
2601
2602static bool trans_lci(DisasContext *ctx, arg_lci *a)
2603{
2604    TCGv_reg ci;
2605
2606    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
2607
2608    /* The Coherence Index is an implementation-defined function of the
2609       physical address.  Two addresses with the same CI have a coherent
2610       view of the cache.  Our implementation is to return 0 for all,
2611       since the entire address space is coherent.  */
2612    ci = tcg_const_reg(0);
2613    save_gpr(ctx, a->t, ci);
2614    tcg_temp_free(ci);
2615
2616    cond_free(&ctx->null_cond);
2617    return true;
2618}
2619
2620static bool trans_add(DisasContext *ctx, arg_rrr_cf_sh *a)
2621{
2622    return do_add_reg(ctx, a, false, false, false, false);
2623}
2624
2625static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_sh *a)
2626{
2627    return do_add_reg(ctx, a, true, false, false, false);
2628}
2629
2630static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
2631{
2632    return do_add_reg(ctx, a, false, true, false, false);
2633}
2634
2635static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_sh *a)
2636{
2637    return do_add_reg(ctx, a, false, false, false, true);
2638}
2639
2640static bool trans_add_c_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
2641{
2642    return do_add_reg(ctx, a, false, true, false, true);
2643}
2644
2645static bool trans_sub(DisasContext *ctx, arg_rrr_cf *a)
2646{
2647    return do_sub_reg(ctx, a, false, false, false);
2648}
2649
2650static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf *a)
2651{
2652    return do_sub_reg(ctx, a, true, false, false);
2653}
2654
2655static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf *a)
2656{
2657    return do_sub_reg(ctx, a, false, false, true);
2658}
2659
2660static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf *a)
2661{
2662    return do_sub_reg(ctx, a, true, false, true);
2663}
2664
2665static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf *a)
2666{
2667    return do_sub_reg(ctx, a, false, true, false);
2668}
2669
2670static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf *a)
2671{
2672    return do_sub_reg(ctx, a, true, true, false);
2673}
2674
2675static bool trans_andcm(DisasContext *ctx, arg_rrr_cf *a)
2676{
2677    return do_log_reg(ctx, a, tcg_gen_andc_reg);
2678}
2679
2680static bool trans_and(DisasContext *ctx, arg_rrr_cf *a)
2681{
2682    return do_log_reg(ctx, a, tcg_gen_and_reg);
2683}
2684
2685static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
2686{
2687    if (a->cf == 0) {
2688        unsigned r2 = a->r2;
2689        unsigned r1 = a->r1;
2690        unsigned rt = a->t;
2691
2692        if (rt == 0) { /* NOP */
2693            cond_free(&ctx->null_cond);
2694            return true;
2695        }
2696        if (r2 == 0) { /* COPY */
2697            if (r1 == 0) {
2698                TCGv_reg dest = dest_gpr(ctx, rt);
2699                tcg_gen_movi_reg(dest, 0);
2700                save_gpr(ctx, rt, dest);
2701            } else {
2702                save_gpr(ctx, rt, cpu_gr[r1]);
2703            }
2704            cond_free(&ctx->null_cond);
2705            return true;
2706        }
2707#ifndef CONFIG_USER_ONLY
2708        /* These are QEMU extensions and are nops in the real architecture:
2709         *
2710         * or %r10,%r10,%r10 -- idle loop; wait for interrupt
2711         * or %r31,%r31,%r31 -- death loop; offline cpu
2712         *                      currently implemented as idle.
2713         */
2714        if ((rt == 10 || rt == 31) && r1 == rt && r2 == rt) { /* PAUSE */
2715            TCGv_i32 tmp;
2716
2717            /* No need to check for supervisor, as userland can only pause
2718               until the next timer interrupt.  */
2719            nullify_over(ctx);
2720
2721            /* Advance the instruction queue.  */
2722            copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
2723            copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
2724            nullify_set(ctx, 0);
2725
2726            /* Tell the qemu main loop to halt until this cpu has work.  */
2727            tmp = tcg_const_i32(1);
2728            tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
2729                                         offsetof(CPUState, halted));
2730            tcg_temp_free_i32(tmp);
2731            gen_excp_1(EXCP_HALTED);
2732            ctx->base.is_jmp = DISAS_NORETURN;
2733
2734            return nullify_end(ctx);
2735        }
2736#endif
2737    }
2738    return do_log_reg(ctx, a, tcg_gen_or_reg);
2739}
2740
2741static bool trans_xor(DisasContext *ctx, arg_rrr_cf *a)
2742{
2743    return do_log_reg(ctx, a, tcg_gen_xor_reg);
2744}
2745
2746static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a)
2747{
2748    TCGv_reg tcg_r1, tcg_r2;
2749
2750    if (a->cf) {
2751        nullify_over(ctx);
2752    }
2753    tcg_r1 = load_gpr(ctx, a->r1);
2754    tcg_r2 = load_gpr(ctx, a->r2);
2755    do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf);
2756    return nullify_end(ctx);
2757}
2758
2759static bool trans_uxor(DisasContext *ctx, arg_rrr_cf *a)
2760{
2761    TCGv_reg tcg_r1, tcg_r2;
2762
2763    if (a->cf) {
2764        nullify_over(ctx);
2765    }
2766    tcg_r1 = load_gpr(ctx, a->r1);
2767    tcg_r2 = load_gpr(ctx, a->r2);
2768    do_unit(ctx, a->t, tcg_r1, tcg_r2, a->cf, false, tcg_gen_xor_reg);
2769    return nullify_end(ctx);
2770}
2771
2772static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf *a, bool is_tc)
2773{
2774    TCGv_reg tcg_r1, tcg_r2, tmp;
2775
2776    if (a->cf) {
2777        nullify_over(ctx);
2778    }
2779    tcg_r1 = load_gpr(ctx, a->r1);
2780    tcg_r2 = load_gpr(ctx, a->r2);
2781    tmp = get_temp(ctx);
2782    tcg_gen_not_reg(tmp, tcg_r2);
2783    do_unit(ctx, a->t, tcg_r1, tmp, a->cf, is_tc, tcg_gen_add_reg);
2784    return nullify_end(ctx);
2785}
2786
2787static bool trans_uaddcm(DisasContext *ctx, arg_rrr_cf *a)
2788{
2789    return do_uaddcm(ctx, a, false);
2790}
2791
2792static bool trans_uaddcm_tc(DisasContext *ctx, arg_rrr_cf *a)
2793{
2794    return do_uaddcm(ctx, a, true);
2795}
2796
2797static bool do_dcor(DisasContext *ctx, arg_rr_cf *a, bool is_i)
2798{
2799    TCGv_reg tmp;
2800
2801    nullify_over(ctx);
2802
2803    tmp = get_temp(ctx);
2804    tcg_gen_shri_reg(tmp, cpu_psw_cb, 3);
2805    if (!is_i) {
2806        tcg_gen_not_reg(tmp, tmp);
2807    }
2808    tcg_gen_andi_reg(tmp, tmp, 0x11111111);
2809    tcg_gen_muli_reg(tmp, tmp, 6);
2810    do_unit(ctx, a->t, load_gpr(ctx, a->r), tmp, a->cf, false,
2811            is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
2812    return nullify_end(ctx);
2813}
2814
2815static bool trans_dcor(DisasContext *ctx, arg_rr_cf *a)
2816{
2817    return do_dcor(ctx, a, false);
2818}
2819
2820static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf *a)
2821{
2822    return do_dcor(ctx, a, true);
2823}
2824
2825static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
2826{
2827    TCGv_reg dest, add1, add2, addc, zero, in1, in2;
2828
2829    nullify_over(ctx);
2830
2831    in1 = load_gpr(ctx, a->r1);
2832    in2 = load_gpr(ctx, a->r2);
2833
2834    add1 = tcg_temp_new();
2835    add2 = tcg_temp_new();
2836    addc = tcg_temp_new();
2837    dest = tcg_temp_new();
2838    zero = tcg_const_reg(0);
2839
2840    /* Form R1 << 1 | PSW[CB]{8}.  */
2841    tcg_gen_add_reg(add1, in1, in1);
2842    tcg_gen_add_reg(add1, add1, cpu_psw_cb_msb);
2843
2844    /* Add or subtract R2, depending on PSW[V].  Proper computation of
2845       carry{8} requires that we subtract via + ~R2 + 1, as described in
2846       the manual.  By extracting and masking V, we can produce the
2847       proper inputs to the addition without movcond.  */
2848    tcg_gen_sari_reg(addc, cpu_psw_v, TARGET_REGISTER_BITS - 1);
2849    tcg_gen_xor_reg(add2, in2, addc);
2850    tcg_gen_andi_reg(addc, addc, 1);
2851    /* ??? This is only correct for 32-bit.  */
2852    tcg_gen_add2_i32(dest, cpu_psw_cb_msb, add1, zero, add2, zero);
2853    tcg_gen_add2_i32(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);
2854
2855    tcg_temp_free(addc);
2856    tcg_temp_free(zero);
2857
2858    /* Write back the result register.  */
2859    save_gpr(ctx, a->t, dest);
2860
2861    /* Write back PSW[CB].  */
2862    tcg_gen_xor_reg(cpu_psw_cb, add1, add2);
2863    tcg_gen_xor_reg(cpu_psw_cb, cpu_psw_cb, dest);
2864
2865    /* Write back PSW[V] for the division step.  */
2866    tcg_gen_neg_reg(cpu_psw_v, cpu_psw_cb_msb);
2867    tcg_gen_xor_reg(cpu_psw_v, cpu_psw_v, in2);
2868
2869    /* Install the new nullification.  */
2870    if (a->cf) {
2871        TCGv_reg sv = NULL;
2872        if (cond_need_sv(a->cf >> 1)) {
2873            /* ??? The lshift is supposed to contribute to overflow.  */
2874            sv = do_add_sv(ctx, dest, add1, add2);
2875        }
2876        ctx->null_cond = do_cond(a->cf, dest, cpu_psw_cb_msb, sv);
2877    }
2878
2879    tcg_temp_free(add1);
2880    tcg_temp_free(add2);
2881    tcg_temp_free(dest);
2882
2883    return nullify_end(ctx);
2884}
2885
2886static bool trans_addi(DisasContext *ctx, arg_rri_cf *a)
2887{
2888    return do_add_imm(ctx, a, false, false);
2889}
2890
2891static bool trans_addi_tsv(DisasContext *ctx, arg_rri_cf *a)
2892{
2893    return do_add_imm(ctx, a, true, false);
2894}
2895
2896static bool trans_addi_tc(DisasContext *ctx, arg_rri_cf *a)
2897{
2898    return do_add_imm(ctx, a, false, true);
2899}
2900
2901static bool trans_addi_tc_tsv(DisasContext *ctx, arg_rri_cf *a)
2902{
2903    return do_add_imm(ctx, a, true, true);
2904}
2905
2906static bool trans_subi(DisasContext *ctx, arg_rri_cf *a)
2907{
2908    return do_sub_imm(ctx, a, false);
2909}
2910
2911static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf *a)
2912{
2913    return do_sub_imm(ctx, a, true);
2914}
2915
2916static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a)
2917{
2918    TCGv_reg tcg_im, tcg_r2;
2919
2920    if (a->cf) {
2921        nullify_over(ctx);
2922    }
2923
2924    tcg_im = load_const(ctx, a->i);
2925    tcg_r2 = load_gpr(ctx, a->r);
2926    do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf);
2927
2928    return nullify_end(ctx);
2929}
2930
2931static bool trans_ld(DisasContext *ctx, arg_ldst *a)
2932{
2933    return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0,
2934                   a->disp, a->sp, a->m, a->size | MO_TE);
2935}
2936
2937static bool trans_st(DisasContext *ctx, arg_ldst *a)
2938{
2939    assert(a->x == 0 && a->scale == 0);
2940    return do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size | MO_TE);
2941}
2942
2943static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
2944{
2945    MemOp mop = MO_TEUL | MO_ALIGN_16 | a->size;
2946    TCGv_reg zero, dest, ofs;
2947    TCGv_tl addr;
2948
2949    nullify_over(ctx);
2950
2951    if (a->m) {
2952        /* Base register modification.  Make sure if RT == RB,
2953           we see the result of the load.  */
2954        dest = get_temp(ctx);
2955    } else {
2956        dest = dest_gpr(ctx, a->t);
2957    }
2958
2959    form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? a->size : 0,
2960             a->disp, a->sp, a->m, ctx->mmu_idx == MMU_PHYS_IDX);
2961    zero = tcg_const_reg(0);
2962    tcg_gen_atomic_xchg_reg(dest, addr, zero, ctx->mmu_idx, mop);
2963    if (a->m) {
2964        save_gpr(ctx, a->b, ofs);
2965    }
2966    save_gpr(ctx, a->t, dest);
2967
2968    return nullify_end(ctx);
2969}
2970
2971static bool trans_stby(DisasContext *ctx, arg_stby *a)
2972{
2973    TCGv_reg ofs, val;
2974    TCGv_tl addr;
2975
2976    nullify_over(ctx);
2977
2978    form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m,
2979             ctx->mmu_idx == MMU_PHYS_IDX);
2980    val = load_gpr(ctx, a->r);
2981    if (a->a) {
2982        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
2983            gen_helper_stby_e_parallel(cpu_env, addr, val);
2984        } else {
2985            gen_helper_stby_e(cpu_env, addr, val);
2986        }
2987    } else {
2988        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
2989            gen_helper_stby_b_parallel(cpu_env, addr, val);
2990        } else {
2991            gen_helper_stby_b(cpu_env, addr, val);
2992        }
2993    }
2994    if (a->m) {
2995        tcg_gen_andi_reg(ofs, ofs, ~3);
2996        save_gpr(ctx, a->b, ofs);
2997    }
2998
2999    return nullify_end(ctx);
3000}
3001
3002static bool trans_lda(DisasContext *ctx, arg_ldst *a)
3003{
3004    int hold_mmu_idx = ctx->mmu_idx;
3005
3006    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
3007    ctx->mmu_idx = MMU_PHYS_IDX;
3008    trans_ld(ctx, a);
3009    ctx->mmu_idx = hold_mmu_idx;
3010    return true;
3011}
3012
3013static bool trans_sta(DisasContext *ctx, arg_ldst *a)
3014{
3015    int hold_mmu_idx = ctx->mmu_idx;
3016
3017    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
3018    ctx->mmu_idx = MMU_PHYS_IDX;
3019    trans_st(ctx, a);
3020    ctx->mmu_idx = hold_mmu_idx;
3021    return true;
3022}
3023
3024static bool trans_ldil(DisasContext *ctx, arg_ldil *a)
3025{
3026    TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
3027
3028    tcg_gen_movi_reg(tcg_rt, a->i);
3029    save_gpr(ctx, a->t, tcg_rt);
3030    cond_free(&ctx->null_cond);
3031    return true;
3032}
3033
3034static bool trans_addil(DisasContext *ctx, arg_addil *a)
3035{
3036    TCGv_reg tcg_rt = load_gpr(ctx, a->r);
3037    TCGv_reg tcg_r1 = dest_gpr(ctx, 1);
3038
3039    tcg_gen_addi_reg(tcg_r1, tcg_rt, a->i);
3040    save_gpr(ctx, 1, tcg_r1);
3041    cond_free(&ctx->null_cond);
3042    return true;
3043}
3044
3045static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
3046{
3047    TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
3048
3049    /* Special case rb == 0, for the LDI pseudo-op.
3050       The COPY pseudo-op is handled for free within tcg_gen_addi_tl.  */
3051    if (a->b == 0) {
3052        tcg_gen_movi_reg(tcg_rt, a->i);
3053    } else {
3054        tcg_gen_addi_reg(tcg_rt, cpu_gr[a->b], a->i);
3055    }
3056    save_gpr(ctx, a->t, tcg_rt);
3057    cond_free(&ctx->null_cond);
3058    return true;
3059}
3060
3061static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
3062                    unsigned c, unsigned f, unsigned n, int disp)
3063{
3064    TCGv_reg dest, in2, sv;
3065    DisasCond cond;
3066
3067    in2 = load_gpr(ctx, r);
3068    dest = get_temp(ctx);
3069
3070    tcg_gen_sub_reg(dest, in1, in2);
3071
3072    sv = NULL;
3073    if (cond_need_sv(c)) {
3074        sv = do_sub_sv(ctx, dest, in1, in2);
3075    }
3076
3077    cond = do_sub_cond(c * 2 + f, dest, in1, in2, sv);
3078    return do_cbranch(ctx, disp, n, &cond);
3079}
3080
3081static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a)
3082{
3083    nullify_over(ctx);
3084    return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp);
3085}
3086
3087static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
3088{
3089    nullify_over(ctx);
3090    return do_cmpb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp);
3091}
3092
3093static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
3094                    unsigned c, unsigned f, unsigned n, int disp)
3095{
3096    TCGv_reg dest, in2, sv, cb_msb;
3097    DisasCond cond;
3098
3099    in2 = load_gpr(ctx, r);
3100    dest = tcg_temp_new();
3101    sv = NULL;
3102    cb_msb = NULL;
3103
3104    if (cond_need_cb(c)) {
3105        cb_msb = get_temp(ctx);
3106        tcg_gen_movi_reg(cb_msb, 0);
3107        tcg_gen_add2_reg(dest, cb_msb, in1, cb_msb, in2, cb_msb);
3108    } else {
3109        tcg_gen_add_reg(dest, in1, in2);
3110    }
3111    if (cond_need_sv(c)) {
3112        sv = do_add_sv(ctx, dest, in1, in2);
3113    }
3114
3115    cond = do_cond(c * 2 + f, dest, cb_msb, sv);
3116    save_gpr(ctx, r, dest);
3117    tcg_temp_free(dest);
3118    return do_cbranch(ctx, disp, n, &cond);
3119}
3120
3121static bool trans_addb(DisasContext *ctx, arg_addb *a)
3122{
3123    nullify_over(ctx);
3124    return do_addb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp);
3125}
3126
3127static bool trans_addbi(DisasContext *ctx, arg_addbi *a)
3128{
3129    nullify_over(ctx);
3130    return do_addb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp);
3131}
3132
3133static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a)
3134{
3135    TCGv_reg tmp, tcg_r;
3136    DisasCond cond;
3137
3138    nullify_over(ctx);
3139
3140    tmp = tcg_temp_new();
3141    tcg_r = load_gpr(ctx, a->r);
3142    tcg_gen_shl_reg(tmp, tcg_r, cpu_sar);
3143
3144    cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
3145    tcg_temp_free(tmp);
3146    return do_cbranch(ctx, a->disp, a->n, &cond);
3147}
3148
3149static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm *a)
3150{
3151    TCGv_reg tmp, tcg_r;
3152    DisasCond cond;
3153
3154    nullify_over(ctx);
3155
3156    tmp = tcg_temp_new();
3157    tcg_r = load_gpr(ctx, a->r);
3158    tcg_gen_shli_reg(tmp, tcg_r, a->p);
3159
3160    cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
3161    tcg_temp_free(tmp);
3162    return do_cbranch(ctx, a->disp, a->n, &cond);
3163}
3164
3165static bool trans_movb(DisasContext *ctx, arg_movb *a)
3166{
3167    TCGv_reg dest;
3168    DisasCond cond;
3169
3170    nullify_over(ctx);
3171
3172    dest = dest_gpr(ctx, a->r2);
3173    if (a->r1 == 0) {
3174        tcg_gen_movi_reg(dest, 0);
3175    } else {
3176        tcg_gen_mov_reg(dest, cpu_gr[a->r1]);
3177    }
3178
3179    cond = do_sed_cond(a->c, dest);
3180    return do_cbranch(ctx, a->disp, a->n, &cond);
3181}
3182
3183static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
3184{
3185    TCGv_reg dest;
3186    DisasCond cond;
3187
3188    nullify_over(ctx);
3189
3190    dest = dest_gpr(ctx, a->r);
3191    tcg_gen_movi_reg(dest, a->i);
3192
3193    cond = do_sed_cond(a->c, dest);
3194    return do_cbranch(ctx, a->disp, a->n, &cond);
3195}
3196
3197static bool trans_shrpw_sar(DisasContext *ctx, arg_shrpw_sar *a)
3198{
3199    TCGv_reg dest;
3200
3201    if (a->c) {
3202        nullify_over(ctx);
3203    }
3204
3205    dest = dest_gpr(ctx, a->t);
3206    if (a->r1 == 0) {
3207        tcg_gen_ext32u_reg(dest, load_gpr(ctx, a->r2));
3208        tcg_gen_shr_reg(dest, dest, cpu_sar);
3209    } else if (a->r1 == a->r2) {
3210        TCGv_i32 t32 = tcg_temp_new_i32();
3211        tcg_gen_trunc_reg_i32(t32, load_gpr(ctx, a->r2));
3212        tcg_gen_rotr_i32(t32, t32, cpu_sar);
3213        tcg_gen_extu_i32_reg(dest, t32);
3214        tcg_temp_free_i32(t32);
3215    } else {
3216        TCGv_i64 t = tcg_temp_new_i64();
3217        TCGv_i64 s = tcg_temp_new_i64();
3218
3219        tcg_gen_concat_reg_i64(t, load_gpr(ctx, a->r2), load_gpr(ctx, a->r1));
3220        tcg_gen_extu_reg_i64(s, cpu_sar);
3221        tcg_gen_shr_i64(t, t, s);
3222        tcg_gen_trunc_i64_reg(dest, t);
3223
3224        tcg_temp_free_i64(t);
3225        tcg_temp_free_i64(s);
3226    }
3227    save_gpr(ctx, a->t, dest);
3228
3229    /* Install the new nullification.  */
3230    cond_free(&ctx->null_cond);
3231    if (a->c) {
3232        ctx->null_cond = do_sed_cond(a->c, dest);
3233    }
3234    return nullify_end(ctx);
3235}
3236
3237static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a)
3238{
3239    unsigned sa = 31 - a->cpos;
3240    TCGv_reg dest, t2;
3241
3242    if (a->c) {
3243        nullify_over(ctx);
3244    }
3245
3246    dest = dest_gpr(ctx, a->t);
3247    t2 = load_gpr(ctx, a->r2);
3248    if (a->r1 == a->r2) {
3249        TCGv_i32 t32 = tcg_temp_new_i32();
3250        tcg_gen_trunc_reg_i32(t32, t2);
3251        tcg_gen_rotri_i32(t32, t32, sa);
3252        tcg_gen_extu_i32_reg(dest, t32);
3253        tcg_temp_free_i32(t32);
3254    } else if (a->r1 == 0) {
3255        tcg_gen_extract_reg(dest, t2, sa, 32 - sa);
3256    } else {
3257        TCGv_reg t0 = tcg_temp_new();
3258        tcg_gen_extract_reg(t0, t2, sa, 32 - sa);
3259        tcg_gen_deposit_reg(dest, t0, cpu_gr[a->r1], 32 - sa, sa);
3260        tcg_temp_free(t0);
3261    }
3262    save_gpr(ctx, a->t, dest);
3263
3264    /* Install the new nullification.  */
3265    cond_free(&ctx->null_cond);
3266    if (a->c) {
3267        ctx->null_cond = do_sed_cond(a->c, dest);
3268    }
3269    return nullify_end(ctx);
3270}
3271
3272static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a)
3273{
3274    unsigned len = 32 - a->clen;
3275    TCGv_reg dest, src, tmp;
3276
3277    if (a->c) {
3278        nullify_over(ctx);
3279    }
3280
3281    dest = dest_gpr(ctx, a->t);
3282    src = load_gpr(ctx, a->r);
3283    tmp = tcg_temp_new();
3284
3285    /* Recall that SAR is using big-endian bit numbering.  */
3286    tcg_gen_xori_reg(tmp, cpu_sar, TARGET_REGISTER_BITS - 1);
3287    if (a->se) {
3288        tcg_gen_sar_reg(dest, src, tmp);
3289        tcg_gen_sextract_reg(dest, dest, 0, len);
3290    } else {
3291        tcg_gen_shr_reg(dest, src, tmp);
3292        tcg_gen_extract_reg(dest, dest, 0, len);
3293    }
3294    tcg_temp_free(tmp);
3295    save_gpr(ctx, a->t, dest);
3296
3297    /* Install the new nullification.  */
3298    cond_free(&ctx->null_cond);
3299    if (a->c) {
3300        ctx->null_cond = do_sed_cond(a->c, dest);
3301    }
3302    return nullify_end(ctx);
3303}
3304
3305static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a)
3306{
3307    unsigned len = 32 - a->clen;
3308    unsigned cpos = 31 - a->pos;
3309    TCGv_reg dest, src;
3310
3311    if (a->c) {
3312        nullify_over(ctx);
3313    }
3314
3315    dest = dest_gpr(ctx, a->t);
3316    src = load_gpr(ctx, a->r);
3317    if (a->se) {
3318        tcg_gen_sextract_reg(dest, src, cpos, len);
3319    } else {
3320        tcg_gen_extract_reg(dest, src, cpos, len);
3321    }
3322    save_gpr(ctx, a->t, dest);
3323
3324    /* Install the new nullification.  */
3325    cond_free(&ctx->null_cond);
3326    if (a->c) {
3327        ctx->null_cond = do_sed_cond(a->c, dest);
3328    }
3329    return nullify_end(ctx);
3330}
3331
3332static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_imm *a)
3333{
3334    unsigned len = 32 - a->clen;
3335    target_sreg mask0, mask1;
3336    TCGv_reg dest;
3337
3338    if (a->c) {
3339        nullify_over(ctx);
3340    }
3341    if (a->cpos + len > 32) {
3342        len = 32 - a->cpos;
3343    }
3344
3345    dest = dest_gpr(ctx, a->t);
3346    mask0 = deposit64(0, a->cpos, len, a->i);
3347    mask1 = deposit64(-1, a->cpos, len, a->i);
3348
3349    if (a->nz) {
3350        TCGv_reg src = load_gpr(ctx, a->t);
3351        if (mask1 != -1) {
3352            tcg_gen_andi_reg(dest, src, mask1);
3353            src = dest;
3354        }
3355        tcg_gen_ori_reg(dest, src, mask0);
3356    } else {
3357        tcg_gen_movi_reg(dest, mask0);
3358    }
3359    save_gpr(ctx, a->t, dest);
3360
3361    /* Install the new nullification.  */
3362    cond_free(&ctx->null_cond);
3363    if (a->c) {
3364        ctx->null_cond = do_sed_cond(a->c, dest);
3365    }
3366    return nullify_end(ctx);
3367}
3368
3369static bool trans_depw_imm(DisasContext *ctx, arg_depw_imm *a)
3370{
3371    unsigned rs = a->nz ? a->t : 0;
3372    unsigned len = 32 - a->clen;
3373    TCGv_reg dest, val;
3374
3375    if (a->c) {
3376        nullify_over(ctx);
3377    }
3378    if (a->cpos + len > 32) {
3379        len = 32 - a->cpos;
3380    }
3381
3382    dest = dest_gpr(ctx, a->t);
3383    val = load_gpr(ctx, a->r);
3384    if (rs == 0) {
3385        tcg_gen_deposit_z_reg(dest, val, a->cpos, len);
3386    } else {
3387        tcg_gen_deposit_reg(dest, cpu_gr[rs], val, a->cpos, len);
3388    }
3389    save_gpr(ctx, a->t, dest);
3390
3391    /* Install the new nullification.  */
3392    cond_free(&ctx->null_cond);
3393    if (a->c) {
3394        ctx->null_cond = do_sed_cond(a->c, dest);
3395    }
3396    return nullify_end(ctx);
3397}
3398
3399static bool do_depw_sar(DisasContext *ctx, unsigned rt, unsigned c,
3400                        unsigned nz, unsigned clen, TCGv_reg val)
3401{
3402    unsigned rs = nz ? rt : 0;
3403    unsigned len = 32 - clen;
3404    TCGv_reg mask, tmp, shift, dest;
3405    unsigned msb = 1U << (len - 1);
3406
3407    dest = dest_gpr(ctx, rt);
3408    shift = tcg_temp_new();
3409    tmp = tcg_temp_new();
3410
3411    /* Convert big-endian bit numbering in SAR to left-shift.  */
3412    tcg_gen_xori_reg(shift, cpu_sar, TARGET_REGISTER_BITS - 1);
3413
3414    mask = tcg_const_reg(msb + (msb - 1));
3415    tcg_gen_and_reg(tmp, val, mask);
3416    if (rs) {
3417        tcg_gen_shl_reg(mask, mask, shift);
3418        tcg_gen_shl_reg(tmp, tmp, shift);
3419        tcg_gen_andc_reg(dest, cpu_gr[rs], mask);
3420        tcg_gen_or_reg(dest, dest, tmp);
3421    } else {
3422        tcg_gen_shl_reg(dest, tmp, shift);
3423    }
3424    tcg_temp_free(shift);
3425    tcg_temp_free(mask);
3426    tcg_temp_free(tmp);
3427    save_gpr(ctx, rt, dest);
3428
3429    /* Install the new nullification.  */
3430    cond_free(&ctx->null_cond);
3431    if (c) {
3432        ctx->null_cond = do_sed_cond(c, dest);
3433    }
3434    return nullify_end(ctx);
3435}
3436
3437static bool trans_depw_sar(DisasContext *ctx, arg_depw_sar *a)
3438{
3439    if (a->c) {
3440        nullify_over(ctx);
3441    }
3442    return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_gpr(ctx, a->r));
3443}
3444
3445static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
3446{
3447    if (a->c) {
3448        nullify_over(ctx);
3449    }
3450    return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, a->i));
3451}
3452
3453static bool trans_be(DisasContext *ctx, arg_be *a)
3454{
3455    TCGv_reg tmp;
3456
3457#ifdef CONFIG_USER_ONLY
3458    /* ??? It seems like there should be a good way of using
3459       "be disp(sr2, r0)", the canonical gateway entry mechanism
3460       to our advantage.  But that appears to be inconvenient to
3461       manage along side branch delay slots.  Therefore we handle
3462       entry into the gateway page via absolute address.  */
3463    /* Since we don't implement spaces, just branch.  Do notice the special
3464       case of "be disp(*,r0)" using a direct branch to disp, so that we can
3465       goto_tb to the TB containing the syscall.  */
3466    if (a->b == 0) {
3467        return do_dbranch(ctx, a->disp, a->l, a->n);
3468    }
3469#else
3470    nullify_over(ctx);
3471#endif
3472
3473    tmp = get_temp(ctx);
3474    tcg_gen_addi_reg(tmp, load_gpr(ctx, a->b), a->disp);
3475    tmp = do_ibranch_priv(ctx, tmp);
3476
3477#ifdef CONFIG_USER_ONLY
3478    return do_ibranch(ctx, tmp, a->l, a->n);
3479#else
3480    TCGv_i64 new_spc = tcg_temp_new_i64();
3481
3482    load_spr(ctx, new_spc, a->sp);
3483    if (a->l) {
3484        copy_iaoq_entry(cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
3485        tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_f);
3486    }
3487    if (a->n && use_nullify_skip(ctx)) {
3488        tcg_gen_mov_reg(cpu_iaoq_f, tmp);
3489        tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
3490        tcg_gen_mov_i64(cpu_iasq_f, new_spc);
3491        tcg_gen_mov_i64(cpu_iasq_b, cpu_iasq_f);
3492    } else {
3493        copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
3494        if (ctx->iaoq_b == -1) {
3495            tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
3496        }
3497        tcg_gen_mov_reg(cpu_iaoq_b, tmp);
3498        tcg_gen_mov_i64(cpu_iasq_b, new_spc);
3499        nullify_set(ctx, a->n);
3500    }
3501    tcg_temp_free_i64(new_spc);
3502    tcg_gen_lookup_and_goto_ptr();
3503    ctx->base.is_jmp = DISAS_NORETURN;
3504    return nullify_end(ctx);
3505#endif
3506}
3507
3508static bool trans_bl(DisasContext *ctx, arg_bl *a)
3509{
3510    return do_dbranch(ctx, iaoq_dest(ctx, a->disp), a->l, a->n);
3511}
3512
3513static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
3514{
3515    target_ureg dest = iaoq_dest(ctx, a->disp);
3516
3517    nullify_over(ctx);
3518
3519    /* Make sure the caller hasn't done something weird with the queue.
3520     * ??? This is not quite the same as the PSW[B] bit, which would be
3521     * expensive to track.  Real hardware will trap for
3522     *    b  gateway
3523     *    b  gateway+4  (in delay slot of first branch)
3524     * However, checking for a non-sequential instruction queue *will*
3525     * diagnose the security hole
3526     *    b  gateway
3527     *    b  evil
3528     * in which instructions at evil would run with increased privs.
3529     */
3530    if (ctx->iaoq_b == -1 || ctx->iaoq_b != ctx->iaoq_f + 4) {
3531        return gen_illegal(ctx);
3532    }
3533
3534#ifndef CONFIG_USER_ONLY
3535    if (ctx->tb_flags & PSW_C) {
3536        CPUHPPAState *env = ctx->cs->env_ptr;
3537        int type = hppa_artype_for_page(env, ctx->base.pc_next);
3538        /* If we could not find a TLB entry, then we need to generate an
3539           ITLB miss exception so the kernel will provide it.
3540           The resulting TLB fill operation will invalidate this TB and
3541           we will re-translate, at which point we *will* be able to find
3542           the TLB entry and determine if this is in fact a gateway page.  */
3543        if (type < 0) {
3544            gen_excp(ctx, EXCP_ITLB_MISS);
3545            return true;
3546        }
3547        /* No change for non-gateway pages or for priv decrease.  */
3548        if (type >= 4 && type - 4 < ctx->privilege) {
3549            dest = deposit32(dest, 0, 2, type - 4);
3550        }
3551    } else {
3552        dest &= -4;  /* priv = 0 */
3553    }
3554#endif
3555
3556    if (a->l) {
3557        TCGv_reg tmp = dest_gpr(ctx, a->l);
3558        if (ctx->privilege < 3) {
3559            tcg_gen_andi_reg(tmp, tmp, -4);
3560        }
3561        tcg_gen_ori_reg(tmp, tmp, ctx->privilege);
3562        save_gpr(ctx, a->l, tmp);
3563    }
3564
3565    return do_dbranch(ctx, dest, 0, a->n);
3566}
3567
3568static bool trans_blr(DisasContext *ctx, arg_blr *a)
3569{
3570    if (a->x) {
3571        TCGv_reg tmp = get_temp(ctx);
3572        tcg_gen_shli_reg(tmp, load_gpr(ctx, a->x), 3);
3573        tcg_gen_addi_reg(tmp, tmp, ctx->iaoq_f + 8);
3574        /* The computation here never changes privilege level.  */
3575        return do_ibranch(ctx, tmp, a->l, a->n);
3576    } else {
3577        /* BLR R0,RX is a good way to load PC+8 into RX.  */
3578        return do_dbranch(ctx, ctx->iaoq_f + 8, a->l, a->n);
3579    }
3580}
3581
3582static bool trans_bv(DisasContext *ctx, arg_bv *a)
3583{
3584    TCGv_reg dest;
3585
3586    if (a->x == 0) {
3587        dest = load_gpr(ctx, a->b);
3588    } else {
3589        dest = get_temp(ctx);
3590        tcg_gen_shli_reg(dest, load_gpr(ctx, a->x), 3);
3591        tcg_gen_add_reg(dest, dest, load_gpr(ctx, a->b));
3592    }
3593    dest = do_ibranch_priv(ctx, dest);
3594    return do_ibranch(ctx, dest, 0, a->n);
3595}
3596
3597static bool trans_bve(DisasContext *ctx, arg_bve *a)
3598{
3599    TCGv_reg dest;
3600
3601#ifdef CONFIG_USER_ONLY
3602    dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
3603    return do_ibranch(ctx, dest, a->l, a->n);
3604#else
3605    nullify_over(ctx);
3606    dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
3607
3608    copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
3609    if (ctx->iaoq_b == -1) {
3610        tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
3611    }
3612    copy_iaoq_entry(cpu_iaoq_b, -1, dest);
3613    tcg_gen_mov_i64(cpu_iasq_b, space_select(ctx, 0, dest));
3614    if (a->l) {
3615        copy_iaoq_entry(cpu_gr[a->l], ctx->iaoq_n, ctx->iaoq_n_var);
3616    }
3617    nullify_set(ctx, a->n);
3618    tcg_gen_lookup_and_goto_ptr();
3619    ctx->base.is_jmp = DISAS_NORETURN;
3620    return nullify_end(ctx);
3621#endif
3622}
3623
3624/*
3625 * Float class 0
3626 */
3627
3628static void gen_fcpy_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
3629{
3630    tcg_gen_mov_i32(dst, src);
3631}
3632
3633static bool trans_fcpy_f(DisasContext *ctx, arg_fclass01 *a)
3634{
3635    return do_fop_wew(ctx, a->t, a->r, gen_fcpy_f);
3636}
3637
3638static void gen_fcpy_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
3639{
3640    tcg_gen_mov_i64(dst, src);
3641}
3642
3643static bool trans_fcpy_d(DisasContext *ctx, arg_fclass01 *a)
3644{
3645    return do_fop_ded(ctx, a->t, a->r, gen_fcpy_d);
3646}
3647
3648static void gen_fabs_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
3649{
3650    tcg_gen_andi_i32(dst, src, INT32_MAX);
3651}
3652
3653static bool trans_fabs_f(DisasContext *ctx, arg_fclass01 *a)
3654{
3655    return do_fop_wew(ctx, a->t, a->r, gen_fabs_f);
3656}
3657
3658static void gen_fabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
3659{
3660    tcg_gen_andi_i64(dst, src, INT64_MAX);
3661}
3662
3663static bool trans_fabs_d(DisasContext *ctx, arg_fclass01 *a)
3664{
3665    return do_fop_ded(ctx, a->t, a->r, gen_fabs_d);
3666}
3667
3668static bool trans_fsqrt_f(DisasContext *ctx, arg_fclass01 *a)
3669{
3670    return do_fop_wew(ctx, a->t, a->r, gen_helper_fsqrt_s);
3671}
3672
3673static bool trans_fsqrt_d(DisasContext *ctx, arg_fclass01 *a)
3674{
3675    return do_fop_ded(ctx, a->t, a->r, gen_helper_fsqrt_d);
3676}
3677
3678static bool trans_frnd_f(DisasContext *ctx, arg_fclass01 *a)
3679{
3680    return do_fop_wew(ctx, a->t, a->r, gen_helper_frnd_s);
3681}
3682
3683static bool trans_frnd_d(DisasContext *ctx, arg_fclass01 *a)
3684{
3685    return do_fop_ded(ctx, a->t, a->r, gen_helper_frnd_d);
3686}
3687
3688static void gen_fneg_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
3689{
3690    tcg_gen_xori_i32(dst, src, INT32_MIN);
3691}
3692
3693static bool trans_fneg_f(DisasContext *ctx, arg_fclass01 *a)
3694{
3695    return do_fop_wew(ctx, a->t, a->r, gen_fneg_f);
3696}
3697
3698static void gen_fneg_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
3699{
3700    tcg_gen_xori_i64(dst, src, INT64_MIN);
3701}
3702
3703static bool trans_fneg_d(DisasContext *ctx, arg_fclass01 *a)
3704{
3705    return do_fop_ded(ctx, a->t, a->r, gen_fneg_d);
3706}
3707
3708static void gen_fnegabs_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
3709{
3710    tcg_gen_ori_i32(dst, src, INT32_MIN);
3711}
3712
3713static bool trans_fnegabs_f(DisasContext *ctx, arg_fclass01 *a)
3714{
3715    return do_fop_wew(ctx, a->t, a->r, gen_fnegabs_f);
3716}
3717
3718static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
3719{
3720    tcg_gen_ori_i64(dst, src, INT64_MIN);
3721}
3722
3723static bool trans_fnegabs_d(DisasContext *ctx, arg_fclass01 *a)
3724{
3725    return do_fop_ded(ctx, a->t, a->r, gen_fnegabs_d);
3726}
3727
3728/*
3729 * Float class 1
3730 */
3731
3732static bool trans_fcnv_d_f(DisasContext *ctx, arg_fclass01 *a)
3733{
3734    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_s);
3735}
3736
3737static bool trans_fcnv_f_d(DisasContext *ctx, arg_fclass01 *a)
3738{
3739    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_d);
3740}
3741
3742static bool trans_fcnv_w_f(DisasContext *ctx, arg_fclass01 *a)
3743{
3744    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_w_s);
3745}
3746
3747static bool trans_fcnv_q_f(DisasContext *ctx, arg_fclass01 *a)
3748{
3749    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_dw_s);
3750}
3751
3752static bool trans_fcnv_w_d(DisasContext *ctx, arg_fclass01 *a)
3753{
3754    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_w_d);
3755}
3756
3757static bool trans_fcnv_q_d(DisasContext *ctx, arg_fclass01 *a)
3758{
3759    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_dw_d);
3760}
3761
3762static bool trans_fcnv_f_w(DisasContext *ctx, arg_fclass01 *a)
3763{
3764    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_w);
3765}
3766
3767static bool trans_fcnv_d_w(DisasContext *ctx, arg_fclass01 *a)
3768{
3769    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_w);
3770}
3771
3772static bool trans_fcnv_f_q(DisasContext *ctx, arg_fclass01 *a)
3773{
3774    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_dw);
3775}
3776
3777static bool trans_fcnv_d_q(DisasContext *ctx, arg_fclass01 *a)
3778{
3779    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_dw);
3780}
3781
3782static bool trans_fcnv_t_f_w(DisasContext *ctx, arg_fclass01 *a)
3783{
3784    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_w);
3785}
3786
3787static bool trans_fcnv_t_d_w(DisasContext *ctx, arg_fclass01 *a)
3788{
3789    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_w);
3790}
3791
3792static bool trans_fcnv_t_f_q(DisasContext *ctx, arg_fclass01 *a)
3793{
3794    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_dw);
3795}
3796
3797static bool trans_fcnv_t_d_q(DisasContext *ctx, arg_fclass01 *a)
3798{
3799    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_dw);
3800}
3801
3802static bool trans_fcnv_uw_f(DisasContext *ctx, arg_fclass01 *a)
3803{
3804    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_uw_s);
3805}
3806
3807static bool trans_fcnv_uq_f(DisasContext *ctx, arg_fclass01 *a)
3808{
3809    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_udw_s);
3810}
3811
3812static bool trans_fcnv_uw_d(DisasContext *ctx, arg_fclass01 *a)
3813{
3814    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_uw_d);
3815}
3816
3817static bool trans_fcnv_uq_d(DisasContext *ctx, arg_fclass01 *a)
3818{
3819    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_udw_d);
3820}
3821
3822static bool trans_fcnv_f_uw(DisasContext *ctx, arg_fclass01 *a)
3823{
3824    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_uw);
3825}
3826
3827static bool trans_fcnv_d_uw(DisasContext *ctx, arg_fclass01 *a)
3828{
3829    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_uw);
3830}
3831
3832static bool trans_fcnv_f_uq(DisasContext *ctx, arg_fclass01 *a)
3833{
3834    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_udw);
3835}
3836
3837static bool trans_fcnv_d_uq(DisasContext *ctx, arg_fclass01 *a)
3838{
3839    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_udw);
3840}
3841
3842static bool trans_fcnv_t_f_uw(DisasContext *ctx, arg_fclass01 *a)
3843{
3844    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_uw);
3845}
3846
3847static bool trans_fcnv_t_d_uw(DisasContext *ctx, arg_fclass01 *a)
3848{
3849    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_uw);
3850}
3851
3852static bool trans_fcnv_t_f_uq(DisasContext *ctx, arg_fclass01 *a)
3853{
3854    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_udw);
3855}
3856
3857static bool trans_fcnv_t_d_uq(DisasContext *ctx, arg_fclass01 *a)
3858{
3859    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_udw);
3860}
3861
3862/*
3863 * Float class 2
3864 */
3865
3866static bool trans_fcmp_f(DisasContext *ctx, arg_fclass2 *a)
3867{
3868    TCGv_i32 ta, tb, tc, ty;
3869
3870    nullify_over(ctx);
3871
3872    ta = load_frw0_i32(a->r1);
3873    tb = load_frw0_i32(a->r2);
3874    ty = tcg_const_i32(a->y);
3875    tc = tcg_const_i32(a->c);
3876
3877    gen_helper_fcmp_s(cpu_env, ta, tb, ty, tc);
3878
3879    tcg_temp_free_i32(ta);
3880    tcg_temp_free_i32(tb);
3881    tcg_temp_free_i32(ty);
3882    tcg_temp_free_i32(tc);
3883
3884    return nullify_end(ctx);
3885}
3886
3887static bool trans_fcmp_d(DisasContext *ctx, arg_fclass2 *a)
3888{
3889    TCGv_i64 ta, tb;
3890    TCGv_i32 tc, ty;
3891
3892    nullify_over(ctx);
3893
3894    ta = load_frd0(a->r1);
3895    tb = load_frd0(a->r2);
3896    ty = tcg_const_i32(a->y);
3897    tc = tcg_const_i32(a->c);
3898
3899    gen_helper_fcmp_d(cpu_env, ta, tb, ty, tc);
3900
3901    tcg_temp_free_i64(ta);
3902    tcg_temp_free_i64(tb);
3903    tcg_temp_free_i32(ty);
3904    tcg_temp_free_i32(tc);
3905
3906    return nullify_end(ctx);
3907}
3908
3909static bool trans_ftest(DisasContext *ctx, arg_ftest *a)
3910{
3911    TCGv_reg t;
3912
3913    nullify_over(ctx);
3914
3915    t = get_temp(ctx);
3916    tcg_gen_ld32u_reg(t, cpu_env, offsetof(CPUHPPAState, fr0_shadow));
3917
3918    if (a->y == 1) {
3919        int mask;
3920        bool inv = false;
3921
3922        switch (a->c) {
3923        case 0: /* simple */
3924            tcg_gen_andi_reg(t, t, 0x4000000);
3925            ctx->null_cond = cond_make_0(TCG_COND_NE, t);
3926            goto done;
3927        case 2: /* rej */
3928            inv = true;
3929            /* fallthru */
3930        case 1: /* acc */
3931            mask = 0x43ff800;
3932            break;
3933        case 6: /* rej8 */
3934            inv = true;
3935            /* fallthru */
3936        case 5: /* acc8 */
3937            mask = 0x43f8000;
3938            break;
3939        case 9: /* acc6 */
3940            mask = 0x43e0000;
3941            break;
3942        case 13: /* acc4 */
3943            mask = 0x4380000;
3944            break;
3945        case 17: /* acc2 */
3946            mask = 0x4200000;
3947            break;
3948        default:
3949            gen_illegal(ctx);
3950            return true;
3951        }
3952        if (inv) {
3953            TCGv_reg c = load_const(ctx, mask);
3954            tcg_gen_or_reg(t, t, c);
3955            ctx->null_cond = cond_make(TCG_COND_EQ, t, c);
3956        } else {
3957            tcg_gen_andi_reg(t, t, mask);
3958            ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
3959        }
3960    } else {
3961        unsigned cbit = (a->y ^ 1) - 1;
3962
3963        tcg_gen_extract_reg(t, t, 21 - cbit, 1);
3964        ctx->null_cond = cond_make_0(TCG_COND_NE, t);
3965        tcg_temp_free(t);
3966    }
3967
3968 done:
3969    return nullify_end(ctx);
3970}
3971
3972/*
3973 * Float class 2
3974 */
3975
3976static bool trans_fadd_f(DisasContext *ctx, arg_fclass3 *a)
3977{
3978    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fadd_s);
3979}
3980
3981static bool trans_fadd_d(DisasContext *ctx, arg_fclass3 *a)
3982{
3983    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fadd_d);
3984}
3985
3986static bool trans_fsub_f(DisasContext *ctx, arg_fclass3 *a)
3987{
3988    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fsub_s);
3989}
3990
3991static bool trans_fsub_d(DisasContext *ctx, arg_fclass3 *a)
3992{
3993    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fsub_d);
3994}
3995
3996static bool trans_fmpy_f(DisasContext *ctx, arg_fclass3 *a)
3997{
3998    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_s);
3999}
4000
4001static bool trans_fmpy_d(DisasContext *ctx, arg_fclass3 *a)
4002{
4003    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_d);
4004}
4005
4006static bool trans_fdiv_f(DisasContext *ctx, arg_fclass3 *a)
4007{
4008    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_s);
4009}
4010
4011static bool trans_fdiv_d(DisasContext *ctx, arg_fclass3 *a)
4012{
4013    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_d);
4014}
4015
4016static bool trans_xmpyu(DisasContext *ctx, arg_xmpyu *a)
4017{
4018    TCGv_i64 x, y;
4019
4020    nullify_over(ctx);
4021
4022    x = load_frw0_i64(a->r1);
4023    y = load_frw0_i64(a->r2);
4024    tcg_gen_mul_i64(x, x, y);
4025    save_frd(a->t, x);
4026    tcg_temp_free_i64(x);
4027    tcg_temp_free_i64(y);
4028
4029    return nullify_end(ctx);
4030}
4031
4032/* Convert the fmpyadd single-precision register encodings to standard.  */
4033static inline int fmpyadd_s_reg(unsigned r)
4034{
4035    return (r & 16) * 2 + 16 + (r & 15);
4036}
4037
4038static bool do_fmpyadd_s(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
4039{
4040    int tm = fmpyadd_s_reg(a->tm);
4041    int ra = fmpyadd_s_reg(a->ra);
4042    int ta = fmpyadd_s_reg(a->ta);
4043    int rm2 = fmpyadd_s_reg(a->rm2);
4044    int rm1 = fmpyadd_s_reg(a->rm1);
4045
4046    nullify_over(ctx);
4047
4048    do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
4049    do_fop_weww(ctx, ta, ta, ra,
4050                is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
4051
4052    return nullify_end(ctx);
4053}
4054
4055static bool trans_fmpyadd_f(DisasContext *ctx, arg_mpyadd *a)
4056{
4057    return do_fmpyadd_s(ctx, a, false);
4058}
4059
4060static bool trans_fmpysub_f(DisasContext *ctx, arg_mpyadd *a)
4061{
4062    return do_fmpyadd_s(ctx, a, true);
4063}
4064
4065static bool do_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
4066{
4067    nullify_over(ctx);
4068
4069    do_fop_dedd(ctx, a->tm, a->rm1, a->rm2, gen_helper_fmpy_d);
4070    do_fop_dedd(ctx, a->ta, a->ta, a->ra,
4071                is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
4072
4073    return nullify_end(ctx);
4074}
4075
4076static bool trans_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a)
4077{
4078    return do_fmpyadd_d(ctx, a, false);
4079}
4080
4081static bool trans_fmpysub_d(DisasContext *ctx, arg_mpyadd *a)
4082{
4083    return do_fmpyadd_d(ctx, a, true);
4084}
4085
4086static bool trans_fmpyfadd_f(DisasContext *ctx, arg_fmpyfadd_f *a)
4087{
4088    TCGv_i32 x, y, z;
4089
4090    nullify_over(ctx);
4091    x = load_frw0_i32(a->rm1);
4092    y = load_frw0_i32(a->rm2);
4093    z = load_frw0_i32(a->ra3);
4094
4095    if (a->neg) {
4096        gen_helper_fmpynfadd_s(x, cpu_env, x, y, z);
4097    } else {
4098        gen_helper_fmpyfadd_s(x, cpu_env, x, y, z);
4099    }
4100
4101    tcg_temp_free_i32(y);
4102    tcg_temp_free_i32(z);
4103    save_frw_i32(a->t, x);
4104    tcg_temp_free_i32(x);
4105    return nullify_end(ctx);
4106}
4107
4108static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
4109{
4110    TCGv_i64 x, y, z;
4111
4112    nullify_over(ctx);
4113    x = load_frd0(a->rm1);
4114    y = load_frd0(a->rm2);
4115    z = load_frd0(a->ra3);
4116
4117    if (a->neg) {
4118        gen_helper_fmpynfadd_d(x, cpu_env, x, y, z);
4119    } else {
4120        gen_helper_fmpyfadd_d(x, cpu_env, x, y, z);
4121    }
4122
4123    tcg_temp_free_i64(y);
4124    tcg_temp_free_i64(z);
4125    save_frd(a->t, x);
4126    tcg_temp_free_i64(x);
4127    return nullify_end(ctx);
4128}
4129
4130static bool trans_diag(DisasContext *ctx, arg_diag *a)
4131{
4132    qemu_log_mask(LOG_UNIMP, "DIAG opcode ignored\n");
4133    cond_free(&ctx->null_cond);
4134    return true;
4135}
4136
4137static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
4138{
4139    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4140    int bound;
4141
4142    ctx->cs = cs;
4143    ctx->tb_flags = ctx->base.tb->flags;
4144
4145#ifdef CONFIG_USER_ONLY
4146    ctx->privilege = MMU_USER_IDX;
4147    ctx->mmu_idx = MMU_USER_IDX;
4148    ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX;
4149    ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX;
4150#else
4151    ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
4152    ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX);
4153
4154    /* Recover the IAOQ values from the GVA + PRIV.  */
4155    uint64_t cs_base = ctx->base.tb->cs_base;
4156    uint64_t iasq_f = cs_base & ~0xffffffffull;
4157    int32_t diff = cs_base;
4158
4159    ctx->iaoq_f = (ctx->base.pc_first & ~iasq_f) + ctx->privilege;
4160    ctx->iaoq_b = (diff ? ctx->iaoq_f + diff : -1);
4161#endif
4162    ctx->iaoq_n = -1;
4163    ctx->iaoq_n_var = NULL;
4164
4165    /* Bound the number of instructions by those left on the page.  */
4166    bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
4167    ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
4168
4169    ctx->ntempr = 0;
4170    ctx->ntempl = 0;
4171    memset(ctx->tempr, 0, sizeof(ctx->tempr));
4172    memset(ctx->templ, 0, sizeof(ctx->templ));
4173}
4174
4175static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
4176{
4177    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4178
4179    /* Seed the nullification status from PSW[N], as saved in TB->FLAGS.  */
4180    ctx->null_cond = cond_make_f();
4181    ctx->psw_n_nonzero = false;
4182    if (ctx->tb_flags & PSW_N) {
4183        ctx->null_cond.c = TCG_COND_ALWAYS;
4184        ctx->psw_n_nonzero = true;
4185    }
4186    ctx->null_lab = NULL;
4187}
4188
4189static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
4190{
4191    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4192
4193    tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b);
4194}
4195
4196static bool hppa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
4197                                      const CPUBreakpoint *bp)
4198{
4199    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4200
4201    gen_excp(ctx, EXCP_DEBUG);
4202    ctx->base.pc_next += 4;
4203    return true;
4204}
4205
4206static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
4207{
4208    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4209    CPUHPPAState *env = cs->env_ptr;
4210    DisasJumpType ret;
4211    int i, n;
4212
4213    /* Execute one insn.  */
4214#ifdef CONFIG_USER_ONLY
4215    if (ctx->base.pc_next < TARGET_PAGE_SIZE) {
4216        do_page_zero(ctx);
4217        ret = ctx->base.is_jmp;
4218        assert(ret != DISAS_NEXT);
4219    } else
4220#endif
4221    {
4222        /* Always fetch the insn, even if nullified, so that we check
4223           the page permissions for execute.  */
4224        uint32_t insn = translator_ldl(env, ctx->base.pc_next);
4225
4226        /* Set up the IA queue for the next insn.
4227           This will be overwritten by a branch.  */
4228        if (ctx->iaoq_b == -1) {
4229            ctx->iaoq_n = -1;
4230            ctx->iaoq_n_var = get_temp(ctx);
4231            tcg_gen_addi_reg(ctx->iaoq_n_var, cpu_iaoq_b, 4);
4232        } else {
4233            ctx->iaoq_n = ctx->iaoq_b + 4;
4234            ctx->iaoq_n_var = NULL;
4235        }
4236
4237        if (unlikely(ctx->null_cond.c == TCG_COND_ALWAYS)) {
4238            ctx->null_cond.c = TCG_COND_NEVER;
4239            ret = DISAS_NEXT;
4240        } else {
4241            ctx->insn = insn;
4242            if (!decode(ctx, insn)) {
4243                gen_illegal(ctx);
4244            }
4245            ret = ctx->base.is_jmp;
4246            assert(ctx->null_lab == NULL);
4247        }
4248    }
4249
4250    /* Free any temporaries allocated.  */
4251    for (i = 0, n = ctx->ntempr; i < n; ++i) {
4252        tcg_temp_free(ctx->tempr[i]);
4253        ctx->tempr[i] = NULL;
4254    }
4255    for (i = 0, n = ctx->ntempl; i < n; ++i) {
4256        tcg_temp_free_tl(ctx->templ[i]);
4257        ctx->templ[i] = NULL;
4258    }
4259    ctx->ntempr = 0;
4260    ctx->ntempl = 0;
4261
4262    /* Advance the insn queue.  Note that this check also detects
4263       a priority change within the instruction queue.  */
4264    if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
4265        if (ctx->iaoq_b != -1 && ctx->iaoq_n != -1
4266            && use_goto_tb(ctx, ctx->iaoq_b)
4267            && (ctx->null_cond.c == TCG_COND_NEVER
4268                || ctx->null_cond.c == TCG_COND_ALWAYS)) {
4269            nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
4270            gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
4271            ctx->base.is_jmp = ret = DISAS_NORETURN;
4272        } else {
4273            ctx->base.is_jmp = ret = DISAS_IAQ_N_STALE;
4274        }
4275    }
4276    ctx->iaoq_f = ctx->iaoq_b;
4277    ctx->iaoq_b = ctx->iaoq_n;
4278    ctx->base.pc_next += 4;
4279
4280    switch (ret) {
4281    case DISAS_NORETURN:
4282    case DISAS_IAQ_N_UPDATED:
4283        break;
4284
4285    case DISAS_NEXT:
4286    case DISAS_IAQ_N_STALE:
4287    case DISAS_IAQ_N_STALE_EXIT:
4288        if (ctx->iaoq_f == -1) {
4289            tcg_gen_mov_reg(cpu_iaoq_f, cpu_iaoq_b);
4290            copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
4291#ifndef CONFIG_USER_ONLY
4292            tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
4293#endif
4294            nullify_save(ctx);
4295            ctx->base.is_jmp = (ret == DISAS_IAQ_N_STALE_EXIT
4296                                ? DISAS_EXIT
4297                                : DISAS_IAQ_N_UPDATED);
4298        } else if (ctx->iaoq_b == -1) {
4299            tcg_gen_mov_reg(cpu_iaoq_b, ctx->iaoq_n_var);
4300        }
4301        break;
4302
4303    default:
4304        g_assert_not_reached();
4305    }
4306}
4307
4308static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
4309{
4310    DisasContext *ctx = container_of(dcbase, DisasContext, base);
4311    DisasJumpType is_jmp = ctx->base.is_jmp;
4312
4313    switch (is_jmp) {
4314    case DISAS_NORETURN:
4315        break;
4316    case DISAS_TOO_MANY:
4317    case DISAS_IAQ_N_STALE:
4318    case DISAS_IAQ_N_STALE_EXIT:
4319        copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
4320        copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
4321        nullify_save(ctx);
4322        /* FALLTHRU */
4323    case DISAS_IAQ_N_UPDATED:
4324        if (ctx->base.singlestep_enabled) {
4325            gen_excp_1(EXCP_DEBUG);
4326        } else if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
4327            tcg_gen_lookup_and_goto_ptr();
4328        }
4329        /* FALLTHRU */
4330    case DISAS_EXIT:
4331        tcg_gen_exit_tb(NULL, 0);
4332        break;
4333    default:
4334        g_assert_not_reached();
4335    }
4336}
4337
4338static void hppa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
4339{
4340    target_ulong pc = dcbase->pc_first;
4341
4342#ifdef CONFIG_USER_ONLY
4343    switch (pc) {
4344    case 0x00:
4345        qemu_log("IN:\n0x00000000:  (null)\n");
4346        return;
4347    case 0xb0:
4348        qemu_log("IN:\n0x000000b0:  light-weight-syscall\n");
4349        return;
4350    case 0xe0:
4351        qemu_log("IN:\n0x000000e0:  set-thread-pointer-syscall\n");
4352        return;
4353    case 0x100:
4354        qemu_log("IN:\n0x00000100:  syscall\n");
4355        return;
4356    }
4357#endif
4358
4359    qemu_log("IN: %s\n", lookup_symbol(pc));
4360    log_target_disas(cs, pc, dcbase->tb->size);
4361}
4362
4363static const TranslatorOps hppa_tr_ops = {
4364    .init_disas_context = hppa_tr_init_disas_context,
4365    .tb_start           = hppa_tr_tb_start,
4366    .insn_start         = hppa_tr_insn_start,
4367    .breakpoint_check   = hppa_tr_breakpoint_check,
4368    .translate_insn     = hppa_tr_translate_insn,
4369    .tb_stop            = hppa_tr_tb_stop,
4370    .disas_log          = hppa_tr_disas_log,
4371};
4372
4373void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
4374{
4375    DisasContext ctx;
4376    translator_loop(&hppa_tr_ops, &ctx.base, cs, tb, max_insns);
4377}
4378
4379void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
4380                          target_ulong *data)
4381{
4382    env->iaoq_f = data[0];
4383    if (data[1] != (target_ureg)-1) {
4384        env->iaoq_b = data[1];
4385    }
4386    /* Since we were executing the instruction at IAOQ_F, and took some
4387       sort of action that provoked the cpu_restore_state, we can infer
4388       that the instruction was not nullified.  */
4389    env->psw_n = 0;
4390}
4391