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