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