OSDN Git Service

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