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