xref: /openbmc/qemu/target/alpha/translate.c (revision b14df228)
1 /*
2  *  Alpha emulation cpu translation for qemu.
3  *
4  *  Copyright (c) 2007 Jocelyn Mayer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "sysemu/cpus.h"
23 #include "disas/disas.h"
24 #include "qemu/host-utils.h"
25 #include "exec/exec-all.h"
26 #include "tcg/tcg-op.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30 #include "exec/translator.h"
31 #include "exec/log.h"
32 
33 
34 #undef ALPHA_DEBUG_DISAS
35 #define CONFIG_SOFTFLOAT_INLINE
36 
37 #ifdef ALPHA_DEBUG_DISAS
38 #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
39 #else
40 #  define LOG_DISAS(...) do { } while (0)
41 #endif
42 
43 typedef struct DisasContext DisasContext;
44 struct DisasContext {
45     DisasContextBase base;
46 
47 #ifdef CONFIG_USER_ONLY
48     MemOp unalign;
49 #else
50     uint64_t palbr;
51 #endif
52     uint32_t tbflags;
53     int mem_idx;
54 
55     /* implver and amask values for this CPU.  */
56     int implver;
57     int amask;
58 
59     /* Current rounding mode for this TB.  */
60     int tb_rm;
61     /* Current flush-to-zero setting for this TB.  */
62     int tb_ftz;
63 
64     /* The set of registers active in the current context.  */
65     TCGv *ir;
66 
67     /* Temporaries for $31 and $f31 as source and destination.  */
68     TCGv zero;
69     TCGv sink;
70 };
71 
72 #ifdef CONFIG_USER_ONLY
73 #define UNALIGN(C)  (C)->unalign
74 #else
75 #define UNALIGN(C)  0
76 #endif
77 
78 /* Target-specific return values from translate_one, indicating the
79    state of the TB.  Note that DISAS_NEXT indicates that we are not
80    exiting the TB.  */
81 #define DISAS_PC_UPDATED_NOCHAIN  DISAS_TARGET_0
82 #define DISAS_PC_UPDATED          DISAS_TARGET_1
83 #define DISAS_PC_STALE            DISAS_TARGET_2
84 
85 /* global register indexes */
86 static TCGv cpu_std_ir[31];
87 static TCGv cpu_fir[31];
88 static TCGv cpu_pc;
89 static TCGv cpu_lock_addr;
90 static TCGv cpu_lock_value;
91 
92 #ifndef CONFIG_USER_ONLY
93 static TCGv cpu_pal_ir[31];
94 #endif
95 
96 #include "exec/gen-icount.h"
97 
98 void alpha_translate_init(void)
99 {
100 #define DEF_VAR(V)  { &cpu_##V, #V, offsetof(CPUAlphaState, V) }
101 
102     typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar;
103     static const GlobalVar vars[] = {
104         DEF_VAR(pc),
105         DEF_VAR(lock_addr),
106         DEF_VAR(lock_value),
107     };
108 
109 #undef DEF_VAR
110 
111     /* Use the symbolic register names that match the disassembler.  */
112     static const char greg_names[31][4] = {
113         "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
114         "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
115         "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
116         "t10", "t11", "ra", "t12", "at", "gp", "sp"
117     };
118     static const char freg_names[31][4] = {
119         "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
120         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
121         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
122         "f24", "f25", "f26", "f27", "f28", "f29", "f30"
123     };
124 #ifndef CONFIG_USER_ONLY
125     static const char shadow_names[8][8] = {
126         "pal_t7", "pal_s0", "pal_s1", "pal_s2",
127         "pal_s3", "pal_s4", "pal_s5", "pal_t11"
128     };
129 #endif
130 
131     int i;
132 
133     for (i = 0; i < 31; i++) {
134         cpu_std_ir[i] = tcg_global_mem_new_i64(cpu_env,
135                                                offsetof(CPUAlphaState, ir[i]),
136                                                greg_names[i]);
137     }
138 
139     for (i = 0; i < 31; i++) {
140         cpu_fir[i] = tcg_global_mem_new_i64(cpu_env,
141                                             offsetof(CPUAlphaState, fir[i]),
142                                             freg_names[i]);
143     }
144 
145 #ifndef CONFIG_USER_ONLY
146     memcpy(cpu_pal_ir, cpu_std_ir, sizeof(cpu_pal_ir));
147     for (i = 0; i < 8; i++) {
148         int r = (i == 7 ? 25 : i + 8);
149         cpu_pal_ir[r] = tcg_global_mem_new_i64(cpu_env,
150                                                offsetof(CPUAlphaState,
151                                                         shadow[i]),
152                                                shadow_names[i]);
153     }
154 #endif
155 
156     for (i = 0; i < ARRAY_SIZE(vars); ++i) {
157         const GlobalVar *v = &vars[i];
158         *v->var = tcg_global_mem_new_i64(cpu_env, v->ofs, v->name);
159     }
160 }
161 
162 static TCGv load_zero(DisasContext *ctx)
163 {
164     if (!ctx->zero) {
165         ctx->zero = tcg_constant_i64(0);
166     }
167     return ctx->zero;
168 }
169 
170 static TCGv dest_sink(DisasContext *ctx)
171 {
172     if (!ctx->sink) {
173         ctx->sink = tcg_temp_new();
174     }
175     return ctx->sink;
176 }
177 
178 static void free_context_temps(DisasContext *ctx)
179 {
180     if (ctx->sink) {
181         tcg_gen_discard_i64(ctx->sink);
182         tcg_temp_free(ctx->sink);
183         ctx->sink = NULL;
184     }
185 }
186 
187 static TCGv load_gpr(DisasContext *ctx, unsigned reg)
188 {
189     if (likely(reg < 31)) {
190         return ctx->ir[reg];
191     } else {
192         return load_zero(ctx);
193     }
194 }
195 
196 static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
197                          uint8_t lit, bool islit)
198 {
199     if (islit) {
200         return tcg_constant_i64(lit);
201     } else if (likely(reg < 31)) {
202         return ctx->ir[reg];
203     } else {
204         return load_zero(ctx);
205     }
206 }
207 
208 static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
209 {
210     if (likely(reg < 31)) {
211         return ctx->ir[reg];
212     } else {
213         return dest_sink(ctx);
214     }
215 }
216 
217 static TCGv load_fpr(DisasContext *ctx, unsigned reg)
218 {
219     if (likely(reg < 31)) {
220         return cpu_fir[reg];
221     } else {
222         return load_zero(ctx);
223     }
224 }
225 
226 static TCGv dest_fpr(DisasContext *ctx, unsigned reg)
227 {
228     if (likely(reg < 31)) {
229         return cpu_fir[reg];
230     } else {
231         return dest_sink(ctx);
232     }
233 }
234 
235 static int get_flag_ofs(unsigned shift)
236 {
237     int ofs = offsetof(CPUAlphaState, flags);
238 #if HOST_BIG_ENDIAN
239     ofs += 3 - (shift / 8);
240 #else
241     ofs += shift / 8;
242 #endif
243     return ofs;
244 }
245 
246 static void ld_flag_byte(TCGv val, unsigned shift)
247 {
248     tcg_gen_ld8u_i64(val, cpu_env, get_flag_ofs(shift));
249 }
250 
251 static void st_flag_byte(TCGv val, unsigned shift)
252 {
253     tcg_gen_st8_i64(val, cpu_env, get_flag_ofs(shift));
254 }
255 
256 static void gen_excp_1(int exception, int error_code)
257 {
258     TCGv_i32 tmp1, tmp2;
259 
260     tmp1 = tcg_constant_i32(exception);
261     tmp2 = tcg_constant_i32(error_code);
262     gen_helper_excp(cpu_env, tmp1, tmp2);
263 }
264 
265 static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code)
266 {
267     tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
268     gen_excp_1(exception, error_code);
269     return DISAS_NORETURN;
270 }
271 
272 static inline DisasJumpType gen_invalid(DisasContext *ctx)
273 {
274     return gen_excp(ctx, EXCP_OPCDEC, 0);
275 }
276 
277 static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr)
278 {
279     TCGv_i32 tmp32 = tcg_temp_new_i32();
280     tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
281     gen_helper_memory_to_f(dest, tmp32);
282     tcg_temp_free_i32(tmp32);
283 }
284 
285 static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr)
286 {
287     TCGv tmp = tcg_temp_new();
288     tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
289     gen_helper_memory_to_g(dest, tmp);
290     tcg_temp_free(tmp);
291 }
292 
293 static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr)
294 {
295     TCGv_i32 tmp32 = tcg_temp_new_i32();
296     tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
297     gen_helper_memory_to_s(dest, tmp32);
298     tcg_temp_free_i32(tmp32);
299 }
300 
301 static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr)
302 {
303     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
304 }
305 
306 static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
307                         void (*func)(DisasContext *, TCGv, TCGv))
308 {
309     /* Loads to $f31 are prefetches, which we can treat as nops. */
310     if (likely(ra != 31)) {
311         TCGv addr = tcg_temp_new();
312         tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
313         func(ctx, cpu_fir[ra], addr);
314         tcg_temp_free(addr);
315     }
316 }
317 
318 static void gen_load_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
319                          MemOp op, bool clear, bool locked)
320 {
321     TCGv addr, dest;
322 
323     /* LDQ_U with ra $31 is UNOP.  Other various loads are forms of
324        prefetches, which we can treat as nops.  No worries about
325        missed exceptions here.  */
326     if (unlikely(ra == 31)) {
327         return;
328     }
329 
330     addr = tcg_temp_new();
331     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
332     if (clear) {
333         tcg_gen_andi_i64(addr, addr, ~0x7);
334     } else if (!locked) {
335         op |= UNALIGN(ctx);
336     }
337 
338     dest = ctx->ir[ra];
339     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, op);
340 
341     if (locked) {
342         tcg_gen_mov_i64(cpu_lock_addr, addr);
343         tcg_gen_mov_i64(cpu_lock_value, dest);
344     }
345     tcg_temp_free(addr);
346 }
347 
348 static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr)
349 {
350     TCGv_i32 tmp32 = tcg_temp_new_i32();
351     gen_helper_f_to_memory(tmp32, addr);
352     tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
353     tcg_temp_free_i32(tmp32);
354 }
355 
356 static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr)
357 {
358     TCGv tmp = tcg_temp_new();
359     gen_helper_g_to_memory(tmp, src);
360     tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
361     tcg_temp_free(tmp);
362 }
363 
364 static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr)
365 {
366     TCGv_i32 tmp32 = tcg_temp_new_i32();
367     gen_helper_s_to_memory(tmp32, src);
368     tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
369     tcg_temp_free_i32(tmp32);
370 }
371 
372 static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr)
373 {
374     tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
375 }
376 
377 static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
378                          void (*func)(DisasContext *, TCGv, TCGv))
379 {
380     TCGv addr = tcg_temp_new();
381     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
382     func(ctx, load_fpr(ctx, ra), addr);
383     tcg_temp_free(addr);
384 }
385 
386 static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
387                           MemOp op, bool clear)
388 {
389     TCGv addr, src;
390 
391     addr = tcg_temp_new();
392     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
393     if (clear) {
394         tcg_gen_andi_i64(addr, addr, ~0x7);
395     } else {
396         op |= UNALIGN(ctx);
397     }
398 
399     src = load_gpr(ctx, ra);
400     tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, op);
401 
402     tcg_temp_free(addr);
403 }
404 
405 static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
406                                            int32_t disp16, int mem_idx,
407                                            MemOp op)
408 {
409     TCGLabel *lab_fail, *lab_done;
410     TCGv addr, val;
411 
412     addr = tcg_temp_new_i64();
413     tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
414     free_context_temps(ctx);
415 
416     lab_fail = gen_new_label();
417     lab_done = gen_new_label();
418     tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
419     tcg_temp_free_i64(addr);
420 
421     val = tcg_temp_new_i64();
422     tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value,
423                                load_gpr(ctx, ra), mem_idx, op);
424     free_context_temps(ctx);
425 
426     if (ra != 31) {
427         tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value);
428     }
429     tcg_temp_free_i64(val);
430     tcg_gen_br(lab_done);
431 
432     gen_set_label(lab_fail);
433     if (ra != 31) {
434         tcg_gen_movi_i64(ctx->ir[ra], 0);
435     }
436 
437     gen_set_label(lab_done);
438     tcg_gen_movi_i64(cpu_lock_addr, -1);
439     return DISAS_NEXT;
440 }
441 
442 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
443 {
444     return translator_use_goto_tb(&ctx->base, dest);
445 }
446 
447 static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
448 {
449     uint64_t dest = ctx->base.pc_next + (disp << 2);
450 
451     if (ra != 31) {
452         tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
453     }
454 
455     /* Notice branch-to-next; used to initialize RA with the PC.  */
456     if (disp == 0) {
457         return 0;
458     } else if (use_goto_tb(ctx, dest)) {
459         tcg_gen_goto_tb(0);
460         tcg_gen_movi_i64(cpu_pc, dest);
461         tcg_gen_exit_tb(ctx->base.tb, 0);
462         return DISAS_NORETURN;
463     } else {
464         tcg_gen_movi_i64(cpu_pc, dest);
465         return DISAS_PC_UPDATED;
466     }
467 }
468 
469 static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
470                                         TCGv cmp, int32_t disp)
471 {
472     uint64_t dest = ctx->base.pc_next + (disp << 2);
473     TCGLabel *lab_true = gen_new_label();
474 
475     if (use_goto_tb(ctx, dest)) {
476         tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
477 
478         tcg_gen_goto_tb(0);
479         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
480         tcg_gen_exit_tb(ctx->base.tb, 0);
481 
482         gen_set_label(lab_true);
483         tcg_gen_goto_tb(1);
484         tcg_gen_movi_i64(cpu_pc, dest);
485         tcg_gen_exit_tb(ctx->base.tb, 1);
486 
487         return DISAS_NORETURN;
488     } else {
489         TCGv_i64 z = load_zero(ctx);
490         TCGv_i64 d = tcg_constant_i64(dest);
491         TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
492 
493         tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
494         return DISAS_PC_UPDATED;
495     }
496 }
497 
498 static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
499                                int32_t disp, int mask)
500 {
501     if (mask) {
502         TCGv tmp = tcg_temp_new();
503         DisasJumpType ret;
504 
505         tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
506         ret = gen_bcond_internal(ctx, cond, tmp, disp);
507         tcg_temp_free(tmp);
508         return ret;
509     }
510     return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
511 }
512 
513 /* Fold -0.0 for comparison with COND.  */
514 
515 static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
516 {
517     uint64_t mzero = 1ull << 63;
518 
519     switch (cond) {
520     case TCG_COND_LE:
521     case TCG_COND_GT:
522         /* For <= or >, the -0.0 value directly compares the way we want.  */
523         tcg_gen_mov_i64(dest, src);
524         break;
525 
526     case TCG_COND_EQ:
527     case TCG_COND_NE:
528         /* For == or !=, we can simply mask off the sign bit and compare.  */
529         tcg_gen_andi_i64(dest, src, mzero - 1);
530         break;
531 
532     case TCG_COND_GE:
533     case TCG_COND_LT:
534         /* For >= or <, map -0.0 to +0.0 via comparison and mask.  */
535         tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
536         tcg_gen_neg_i64(dest, dest);
537         tcg_gen_and_i64(dest, dest, src);
538         break;
539 
540     default:
541         abort();
542     }
543 }
544 
545 static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
546                                 int32_t disp)
547 {
548     TCGv cmp_tmp = tcg_temp_new();
549     DisasJumpType ret;
550 
551     gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
552     ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
553     tcg_temp_free(cmp_tmp);
554     return ret;
555 }
556 
557 static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
558 {
559     TCGv_i64 va, vb, z;
560 
561     z = load_zero(ctx);
562     vb = load_fpr(ctx, rb);
563     va = tcg_temp_new();
564     gen_fold_mzero(cond, va, load_fpr(ctx, ra));
565 
566     tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
567 
568     tcg_temp_free(va);
569 }
570 
571 #define QUAL_RM_N       0x080   /* Round mode nearest even */
572 #define QUAL_RM_C       0x000   /* Round mode chopped */
573 #define QUAL_RM_M       0x040   /* Round mode minus infinity */
574 #define QUAL_RM_D       0x0c0   /* Round mode dynamic */
575 #define QUAL_RM_MASK    0x0c0
576 
577 #define QUAL_U          0x100   /* Underflow enable (fp output) */
578 #define QUAL_V          0x100   /* Overflow enable (int output) */
579 #define QUAL_S          0x400   /* Software completion enable */
580 #define QUAL_I          0x200   /* Inexact detection enable */
581 
582 static void gen_qual_roundmode(DisasContext *ctx, int fn11)
583 {
584     TCGv_i32 tmp;
585 
586     fn11 &= QUAL_RM_MASK;
587     if (fn11 == ctx->tb_rm) {
588         return;
589     }
590     ctx->tb_rm = fn11;
591 
592     tmp = tcg_temp_new_i32();
593     switch (fn11) {
594     case QUAL_RM_N:
595         tcg_gen_movi_i32(tmp, float_round_nearest_even);
596         break;
597     case QUAL_RM_C:
598         tcg_gen_movi_i32(tmp, float_round_to_zero);
599         break;
600     case QUAL_RM_M:
601         tcg_gen_movi_i32(tmp, float_round_down);
602         break;
603     case QUAL_RM_D:
604         tcg_gen_ld8u_i32(tmp, cpu_env,
605                          offsetof(CPUAlphaState, fpcr_dyn_round));
606         break;
607     }
608 
609 #if defined(CONFIG_SOFTFLOAT_INLINE)
610     /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
611        With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
612        sets the one field.  */
613     tcg_gen_st8_i32(tmp, cpu_env,
614                     offsetof(CPUAlphaState, fp_status.float_rounding_mode));
615 #else
616     gen_helper_setroundmode(tmp);
617 #endif
618 
619     tcg_temp_free_i32(tmp);
620 }
621 
622 static void gen_qual_flushzero(DisasContext *ctx, int fn11)
623 {
624     TCGv_i32 tmp;
625 
626     fn11 &= QUAL_U;
627     if (fn11 == ctx->tb_ftz) {
628         return;
629     }
630     ctx->tb_ftz = fn11;
631 
632     tmp = tcg_temp_new_i32();
633     if (fn11) {
634         /* Underflow is enabled, use the FPCR setting.  */
635         tcg_gen_ld8u_i32(tmp, cpu_env,
636                          offsetof(CPUAlphaState, fpcr_flush_to_zero));
637     } else {
638         /* Underflow is disabled, force flush-to-zero.  */
639         tcg_gen_movi_i32(tmp, 1);
640     }
641 
642 #if defined(CONFIG_SOFTFLOAT_INLINE)
643     tcg_gen_st8_i32(tmp, cpu_env,
644                     offsetof(CPUAlphaState, fp_status.flush_to_zero));
645 #else
646     gen_helper_setflushzero(tmp);
647 #endif
648 
649     tcg_temp_free_i32(tmp);
650 }
651 
652 static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp)
653 {
654     TCGv val;
655 
656     if (unlikely(reg == 31)) {
657         val = load_zero(ctx);
658     } else {
659         val = cpu_fir[reg];
660         if ((fn11 & QUAL_S) == 0) {
661             if (is_cmp) {
662                 gen_helper_ieee_input_cmp(cpu_env, val);
663             } else {
664                 gen_helper_ieee_input(cpu_env, val);
665             }
666         } else {
667 #ifndef CONFIG_USER_ONLY
668             /* In system mode, raise exceptions for denormals like real
669                hardware.  In user mode, proceed as if the OS completion
670                handler is handling the denormal as per spec.  */
671             gen_helper_ieee_input_s(cpu_env, val);
672 #endif
673         }
674     }
675     return val;
676 }
677 
678 static void gen_fp_exc_raise(int rc, int fn11)
679 {
680     /* ??? We ought to be able to do something with imprecise exceptions.
681        E.g. notice we're still in the trap shadow of something within the
682        TB and do not generate the code to signal the exception; end the TB
683        when an exception is forced to arrive, either by consumption of a
684        register value or TRAPB or EXCB.  */
685     TCGv_i32 reg, ign;
686     uint32_t ignore = 0;
687 
688     if (!(fn11 & QUAL_U)) {
689         /* Note that QUAL_U == QUAL_V, so ignore either.  */
690         ignore |= FPCR_UNF | FPCR_IOV;
691     }
692     if (!(fn11 & QUAL_I)) {
693         ignore |= FPCR_INE;
694     }
695     ign = tcg_constant_i32(ignore);
696 
697     /* ??? Pass in the regno of the destination so that the helper can
698        set EXC_MASK, which contains a bitmask of destination registers
699        that have caused arithmetic traps.  A simple userspace emulation
700        does not require this.  We do need it for a guest kernel's entArith,
701        or if we were to do something clever with imprecise exceptions.  */
702     reg = tcg_constant_i32(rc + 32);
703     if (fn11 & QUAL_S) {
704         gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
705     } else {
706         gen_helper_fp_exc_raise(cpu_env, ign, reg);
707     }
708 }
709 
710 static void gen_cvtlq(TCGv vc, TCGv vb)
711 {
712     TCGv tmp = tcg_temp_new();
713 
714     /* The arithmetic right shift here, plus the sign-extended mask below
715        yields a sign-extended result without an explicit ext32s_i64.  */
716     tcg_gen_shri_i64(tmp, vb, 29);
717     tcg_gen_sari_i64(vc, vb, 32);
718     tcg_gen_deposit_i64(vc, vc, tmp, 0, 30);
719 
720     tcg_temp_free(tmp);
721 }
722 
723 static void gen_ieee_arith2(DisasContext *ctx,
724                             void (*helper)(TCGv, TCGv_ptr, TCGv),
725                             int rb, int rc, int fn11)
726 {
727     TCGv vb;
728 
729     gen_qual_roundmode(ctx, fn11);
730     gen_qual_flushzero(ctx, fn11);
731 
732     vb = gen_ieee_input(ctx, rb, fn11, 0);
733     helper(dest_fpr(ctx, rc), cpu_env, vb);
734 
735     gen_fp_exc_raise(rc, fn11);
736 }
737 
738 #define IEEE_ARITH2(name)                                       \
739 static inline void glue(gen_, name)(DisasContext *ctx,          \
740                                     int rb, int rc, int fn11)   \
741 {                                                               \
742     gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11);      \
743 }
744 IEEE_ARITH2(sqrts)
745 IEEE_ARITH2(sqrtt)
746 IEEE_ARITH2(cvtst)
747 IEEE_ARITH2(cvtts)
748 
749 static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11)
750 {
751     TCGv vb, vc;
752 
753     /* No need to set flushzero, since we have an integer output.  */
754     vb = gen_ieee_input(ctx, rb, fn11, 0);
755     vc = dest_fpr(ctx, rc);
756 
757     /* Almost all integer conversions use cropped rounding;
758        special case that.  */
759     if ((fn11 & QUAL_RM_MASK) == QUAL_RM_C) {
760         gen_helper_cvttq_c(vc, cpu_env, vb);
761     } else {
762         gen_qual_roundmode(ctx, fn11);
763         gen_helper_cvttq(vc, cpu_env, vb);
764     }
765     gen_fp_exc_raise(rc, fn11);
766 }
767 
768 static void gen_ieee_intcvt(DisasContext *ctx,
769                             void (*helper)(TCGv, TCGv_ptr, TCGv),
770                             int rb, int rc, int fn11)
771 {
772     TCGv vb, vc;
773 
774     gen_qual_roundmode(ctx, fn11);
775     vb = load_fpr(ctx, rb);
776     vc = dest_fpr(ctx, rc);
777 
778     /* The only exception that can be raised by integer conversion
779        is inexact.  Thus we only need to worry about exceptions when
780        inexact handling is requested.  */
781     if (fn11 & QUAL_I) {
782         helper(vc, cpu_env, vb);
783         gen_fp_exc_raise(rc, fn11);
784     } else {
785         helper(vc, cpu_env, vb);
786     }
787 }
788 
789 #define IEEE_INTCVT(name)                                       \
790 static inline void glue(gen_, name)(DisasContext *ctx,          \
791                                     int rb, int rc, int fn11)   \
792 {                                                               \
793     gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11);      \
794 }
795 IEEE_INTCVT(cvtqs)
796 IEEE_INTCVT(cvtqt)
797 
798 static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
799 {
800     TCGv vmask = tcg_constant_i64(mask);
801     TCGv tmp = tcg_temp_new_i64();
802 
803     if (inv_a) {
804         tcg_gen_andc_i64(tmp, vmask, va);
805     } else {
806         tcg_gen_and_i64(tmp, va, vmask);
807     }
808 
809     tcg_gen_andc_i64(vc, vb, vmask);
810     tcg_gen_or_i64(vc, vc, tmp);
811 
812     tcg_temp_free(tmp);
813 }
814 
815 static void gen_ieee_arith3(DisasContext *ctx,
816                             void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
817                             int ra, int rb, int rc, int fn11)
818 {
819     TCGv va, vb, vc;
820 
821     gen_qual_roundmode(ctx, fn11);
822     gen_qual_flushzero(ctx, fn11);
823 
824     va = gen_ieee_input(ctx, ra, fn11, 0);
825     vb = gen_ieee_input(ctx, rb, fn11, 0);
826     vc = dest_fpr(ctx, rc);
827     helper(vc, cpu_env, va, vb);
828 
829     gen_fp_exc_raise(rc, fn11);
830 }
831 
832 #define IEEE_ARITH3(name)                                               \
833 static inline void glue(gen_, name)(DisasContext *ctx,                  \
834                                     int ra, int rb, int rc, int fn11)   \
835 {                                                                       \
836     gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11);          \
837 }
838 IEEE_ARITH3(adds)
839 IEEE_ARITH3(subs)
840 IEEE_ARITH3(muls)
841 IEEE_ARITH3(divs)
842 IEEE_ARITH3(addt)
843 IEEE_ARITH3(subt)
844 IEEE_ARITH3(mult)
845 IEEE_ARITH3(divt)
846 
847 static void gen_ieee_compare(DisasContext *ctx,
848                              void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
849                              int ra, int rb, int rc, int fn11)
850 {
851     TCGv va, vb, vc;
852 
853     va = gen_ieee_input(ctx, ra, fn11, 1);
854     vb = gen_ieee_input(ctx, rb, fn11, 1);
855     vc = dest_fpr(ctx, rc);
856     helper(vc, cpu_env, va, vb);
857 
858     gen_fp_exc_raise(rc, fn11);
859 }
860 
861 #define IEEE_CMP3(name)                                                 \
862 static inline void glue(gen_, name)(DisasContext *ctx,                  \
863                                     int ra, int rb, int rc, int fn11)   \
864 {                                                                       \
865     gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11);         \
866 }
867 IEEE_CMP3(cmptun)
868 IEEE_CMP3(cmpteq)
869 IEEE_CMP3(cmptlt)
870 IEEE_CMP3(cmptle)
871 
872 static inline uint64_t zapnot_mask(uint8_t lit)
873 {
874     uint64_t mask = 0;
875     int i;
876 
877     for (i = 0; i < 8; ++i) {
878         if ((lit >> i) & 1) {
879             mask |= 0xffull << (i * 8);
880         }
881     }
882     return mask;
883 }
884 
885 /* Implement zapnot with an immediate operand, which expands to some
886    form of immediate AND.  This is a basic building block in the
887    definition of many of the other byte manipulation instructions.  */
888 static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
889 {
890     switch (lit) {
891     case 0x00:
892         tcg_gen_movi_i64(dest, 0);
893         break;
894     case 0x01:
895         tcg_gen_ext8u_i64(dest, src);
896         break;
897     case 0x03:
898         tcg_gen_ext16u_i64(dest, src);
899         break;
900     case 0x0f:
901         tcg_gen_ext32u_i64(dest, src);
902         break;
903     case 0xff:
904         tcg_gen_mov_i64(dest, src);
905         break;
906     default:
907         tcg_gen_andi_i64(dest, src, zapnot_mask(lit));
908         break;
909     }
910 }
911 
912 /* EXTWH, EXTLH, EXTQH */
913 static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
914                       uint8_t lit, uint8_t byte_mask)
915 {
916     if (islit) {
917         int pos = (64 - lit * 8) & 0x3f;
918         int len = cto32(byte_mask) * 8;
919         if (pos < len) {
920             tcg_gen_deposit_z_i64(vc, va, pos, len - pos);
921         } else {
922             tcg_gen_movi_i64(vc, 0);
923         }
924     } else {
925         TCGv tmp = tcg_temp_new();
926         tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
927         tcg_gen_neg_i64(tmp, tmp);
928         tcg_gen_andi_i64(tmp, tmp, 0x3f);
929         tcg_gen_shl_i64(vc, va, tmp);
930         tcg_temp_free(tmp);
931     }
932     gen_zapnoti(vc, vc, byte_mask);
933 }
934 
935 /* EXTBL, EXTWL, EXTLL, EXTQL */
936 static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
937                       uint8_t lit, uint8_t byte_mask)
938 {
939     if (islit) {
940         int pos = (lit & 7) * 8;
941         int len = cto32(byte_mask) * 8;
942         if (pos + len >= 64) {
943             len = 64 - pos;
944         }
945         tcg_gen_extract_i64(vc, va, pos, len);
946     } else {
947         TCGv tmp = tcg_temp_new();
948         tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
949         tcg_gen_shli_i64(tmp, tmp, 3);
950         tcg_gen_shr_i64(vc, va, tmp);
951         tcg_temp_free(tmp);
952         gen_zapnoti(vc, vc, byte_mask);
953     }
954 }
955 
956 /* INSWH, INSLH, INSQH */
957 static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
958                       uint8_t lit, uint8_t byte_mask)
959 {
960     if (islit) {
961         int pos = 64 - (lit & 7) * 8;
962         int len = cto32(byte_mask) * 8;
963         if (pos < len) {
964             tcg_gen_extract_i64(vc, va, pos, len - pos);
965         } else {
966             tcg_gen_movi_i64(vc, 0);
967         }
968     } else {
969         TCGv tmp = tcg_temp_new();
970         TCGv shift = tcg_temp_new();
971 
972         /* The instruction description has us left-shift the byte mask
973            and extract bits <15:8> and apply that zap at the end.  This
974            is equivalent to simply performing the zap first and shifting
975            afterward.  */
976         gen_zapnoti(tmp, va, byte_mask);
977 
978         /* If (B & 7) == 0, we need to shift by 64 and leave a zero.  Do this
979            portably by splitting the shift into two parts: shift_count-1 and 1.
980            Arrange for the -1 by using ones-complement instead of
981            twos-complement in the negation: ~(B * 8) & 63.  */
982 
983         tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
984         tcg_gen_not_i64(shift, shift);
985         tcg_gen_andi_i64(shift, shift, 0x3f);
986 
987         tcg_gen_shr_i64(vc, tmp, shift);
988         tcg_gen_shri_i64(vc, vc, 1);
989         tcg_temp_free(shift);
990         tcg_temp_free(tmp);
991     }
992 }
993 
994 /* INSBL, INSWL, INSLL, INSQL */
995 static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
996                       uint8_t lit, uint8_t byte_mask)
997 {
998     if (islit) {
999         int pos = (lit & 7) * 8;
1000         int len = cto32(byte_mask) * 8;
1001         if (pos + len > 64) {
1002             len = 64 - pos;
1003         }
1004         tcg_gen_deposit_z_i64(vc, va, pos, len);
1005     } else {
1006         TCGv tmp = tcg_temp_new();
1007         TCGv shift = tcg_temp_new();
1008 
1009         /* The instruction description has us left-shift the byte mask
1010            and extract bits <15:8> and apply that zap at the end.  This
1011            is equivalent to simply performing the zap first and shifting
1012            afterward.  */
1013         gen_zapnoti(tmp, va, byte_mask);
1014 
1015         tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1016         tcg_gen_shli_i64(shift, shift, 3);
1017         tcg_gen_shl_i64(vc, tmp, shift);
1018         tcg_temp_free(shift);
1019         tcg_temp_free(tmp);
1020     }
1021 }
1022 
1023 /* MSKWH, MSKLH, MSKQH */
1024 static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1025                       uint8_t lit, uint8_t byte_mask)
1026 {
1027     if (islit) {
1028         gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8));
1029     } else {
1030         TCGv shift = tcg_temp_new();
1031         TCGv mask = tcg_temp_new();
1032 
1033         /* The instruction description is as above, where the byte_mask
1034            is shifted left, and then we extract bits <15:8>.  This can be
1035            emulated with a right-shift on the expanded byte mask.  This
1036            requires extra care because for an input <2:0> == 0 we need a
1037            shift of 64 bits in order to generate a zero.  This is done by
1038            splitting the shift into two parts, the variable shift - 1
1039            followed by a constant 1 shift.  The code we expand below is
1040            equivalent to ~(B * 8) & 63.  */
1041 
1042         tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1043         tcg_gen_not_i64(shift, shift);
1044         tcg_gen_andi_i64(shift, shift, 0x3f);
1045         tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1046         tcg_gen_shr_i64(mask, mask, shift);
1047         tcg_gen_shri_i64(mask, mask, 1);
1048 
1049         tcg_gen_andc_i64(vc, va, mask);
1050 
1051         tcg_temp_free(mask);
1052         tcg_temp_free(shift);
1053     }
1054 }
1055 
1056 /* MSKBL, MSKWL, MSKLL, MSKQL */
1057 static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1058                       uint8_t lit, uint8_t byte_mask)
1059 {
1060     if (islit) {
1061         gen_zapnoti(vc, va, ~(byte_mask << (lit & 7)));
1062     } else {
1063         TCGv shift = tcg_temp_new();
1064         TCGv mask = tcg_temp_new();
1065 
1066         tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1067         tcg_gen_shli_i64(shift, shift, 3);
1068         tcg_gen_movi_i64(mask, zapnot_mask(byte_mask));
1069         tcg_gen_shl_i64(mask, mask, shift);
1070 
1071         tcg_gen_andc_i64(vc, va, mask);
1072 
1073         tcg_temp_free(mask);
1074         tcg_temp_free(shift);
1075     }
1076 }
1077 
1078 static void gen_rx(DisasContext *ctx, int ra, int set)
1079 {
1080     if (ra != 31) {
1081         ld_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
1082     }
1083 
1084     st_flag_byte(tcg_constant_i64(set), ENV_FLAG_RX_SHIFT);
1085 }
1086 
1087 static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
1088 {
1089     /* We're emulating OSF/1 PALcode.  Many of these are trivial access
1090        to internal cpu registers.  */
1091 
1092     /* Unprivileged PAL call */
1093     if (palcode >= 0x80 && palcode < 0xC0) {
1094         switch (palcode) {
1095         case 0x86:
1096             /* IMB */
1097             /* No-op inside QEMU.  */
1098             break;
1099         case 0x9E:
1100             /* RDUNIQUE */
1101             tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1102                            offsetof(CPUAlphaState, unique));
1103             break;
1104         case 0x9F:
1105             /* WRUNIQUE */
1106             tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1107                            offsetof(CPUAlphaState, unique));
1108             break;
1109         default:
1110             palcode &= 0xbf;
1111             goto do_call_pal;
1112         }
1113         return DISAS_NEXT;
1114     }
1115 
1116 #ifndef CONFIG_USER_ONLY
1117     /* Privileged PAL code */
1118     if (palcode < 0x40 && (ctx->tbflags & ENV_FLAG_PS_USER) == 0) {
1119         switch (palcode) {
1120         case 0x01:
1121             /* CFLUSH */
1122             /* No-op inside QEMU.  */
1123             break;
1124         case 0x02:
1125             /* DRAINA */
1126             /* No-op inside QEMU.  */
1127             break;
1128         case 0x2D:
1129             /* WRVPTPTR */
1130             tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1131                            offsetof(CPUAlphaState, vptptr));
1132             break;
1133         case 0x31:
1134             /* WRVAL */
1135             tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1136                            offsetof(CPUAlphaState, sysval));
1137             break;
1138         case 0x32:
1139             /* RDVAL */
1140             tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1141                            offsetof(CPUAlphaState, sysval));
1142             break;
1143 
1144         case 0x35:
1145             /* SWPIPL */
1146             /* Note that we already know we're in kernel mode, so we know
1147                that PS only contains the 3 IPL bits.  */
1148             ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1149 
1150             /* But make sure and store only the 3 IPL bits from the user.  */
1151             {
1152                 TCGv tmp = tcg_temp_new();
1153                 tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK);
1154                 st_flag_byte(tmp, ENV_FLAG_PS_SHIFT);
1155                 tcg_temp_free(tmp);
1156             }
1157 
1158             /* Allow interrupts to be recognized right away.  */
1159             tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
1160             return DISAS_PC_UPDATED_NOCHAIN;
1161 
1162         case 0x36:
1163             /* RDPS */
1164             ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1165             break;
1166 
1167         case 0x38:
1168             /* WRUSP */
1169             tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1170                            offsetof(CPUAlphaState, usp));
1171             break;
1172         case 0x3A:
1173             /* RDUSP */
1174             tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1175                            offsetof(CPUAlphaState, usp));
1176             break;
1177         case 0x3C:
1178             /* WHAMI */
1179             tcg_gen_ld32s_i64(ctx->ir[IR_V0], cpu_env,
1180                 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1181             break;
1182 
1183         case 0x3E:
1184             /* WTINT */
1185             tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
1186                            -offsetof(AlphaCPU, env) +
1187                            offsetof(CPUState, halted));
1188             tcg_gen_movi_i64(ctx->ir[IR_V0], 0);
1189             return gen_excp(ctx, EXCP_HALTED, 0);
1190 
1191         default:
1192             palcode &= 0x3f;
1193             goto do_call_pal;
1194         }
1195         return DISAS_NEXT;
1196     }
1197 #endif
1198     return gen_invalid(ctx);
1199 
1200  do_call_pal:
1201 #ifdef CONFIG_USER_ONLY
1202     return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1203 #else
1204     {
1205         TCGv tmp = tcg_temp_new();
1206         uint64_t exc_addr = ctx->base.pc_next;
1207         uint64_t entry = ctx->palbr;
1208 
1209         if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
1210             exc_addr |= 1;
1211         } else {
1212             tcg_gen_movi_i64(tmp, 1);
1213             st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
1214         }
1215 
1216         tcg_gen_movi_i64(tmp, exc_addr);
1217         tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
1218         tcg_temp_free(tmp);
1219 
1220         entry += (palcode & 0x80
1221                   ? 0x2000 + (palcode - 0x80) * 64
1222                   : 0x1000 + palcode * 64);
1223 
1224         tcg_gen_movi_i64(cpu_pc, entry);
1225         return DISAS_PC_UPDATED;
1226     }
1227 #endif
1228 }
1229 
1230 #ifndef CONFIG_USER_ONLY
1231 
1232 #define PR_LONG         0x200000
1233 
1234 static int cpu_pr_data(int pr)
1235 {
1236     switch (pr) {
1237     case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1238     case  3: return offsetof(CPUAlphaState, trap_arg0);
1239     case  4: return offsetof(CPUAlphaState, trap_arg1);
1240     case  5: return offsetof(CPUAlphaState, trap_arg2);
1241     case  6: return offsetof(CPUAlphaState, exc_addr);
1242     case  7: return offsetof(CPUAlphaState, palbr);
1243     case  8: return offsetof(CPUAlphaState, ptbr);
1244     case  9: return offsetof(CPUAlphaState, vptptr);
1245     case 10: return offsetof(CPUAlphaState, unique);
1246     case 11: return offsetof(CPUAlphaState, sysval);
1247     case 12: return offsetof(CPUAlphaState, usp);
1248 
1249     case 40 ... 63:
1250         return offsetof(CPUAlphaState, scratch[pr - 40]);
1251 
1252     case 251:
1253         return offsetof(CPUAlphaState, alarm_expire);
1254     }
1255     return 0;
1256 }
1257 
1258 static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
1259 {
1260     void (*helper)(TCGv);
1261     int data;
1262 
1263     switch (regno) {
1264     case 32 ... 39:
1265         /* Accessing the "non-shadow" general registers.  */
1266         regno = regno == 39 ? 25 : regno - 32 + 8;
1267         tcg_gen_mov_i64(va, cpu_std_ir[regno]);
1268         break;
1269 
1270     case 250: /* WALLTIME */
1271         helper = gen_helper_get_walltime;
1272         goto do_helper;
1273     case 249: /* VMTIME */
1274         helper = gen_helper_get_vmtime;
1275     do_helper:
1276         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1277             gen_io_start();
1278             helper(va);
1279             return DISAS_PC_STALE;
1280         } else {
1281             helper(va);
1282         }
1283         break;
1284 
1285     case 0: /* PS */
1286         ld_flag_byte(va, ENV_FLAG_PS_SHIFT);
1287         break;
1288     case 1: /* FEN */
1289         ld_flag_byte(va, ENV_FLAG_FEN_SHIFT);
1290         break;
1291 
1292     default:
1293         /* The basic registers are data only, and unknown registers
1294            are read-zero, write-ignore.  */
1295         data = cpu_pr_data(regno);
1296         if (data == 0) {
1297             tcg_gen_movi_i64(va, 0);
1298         } else if (data & PR_LONG) {
1299             tcg_gen_ld32s_i64(va, cpu_env, data & ~PR_LONG);
1300         } else {
1301             tcg_gen_ld_i64(va, cpu_env, data);
1302         }
1303         break;
1304     }
1305 
1306     return DISAS_NEXT;
1307 }
1308 
1309 static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
1310 {
1311     int data;
1312     DisasJumpType ret = DISAS_NEXT;
1313 
1314     switch (regno) {
1315     case 255:
1316         /* TBIA */
1317         gen_helper_tbia(cpu_env);
1318         break;
1319 
1320     case 254:
1321         /* TBIS */
1322         gen_helper_tbis(cpu_env, vb);
1323         break;
1324 
1325     case 253:
1326         /* WAIT */
1327         tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
1328                        -offsetof(AlphaCPU, env) + offsetof(CPUState, halted));
1329         return gen_excp(ctx, EXCP_HALTED, 0);
1330 
1331     case 252:
1332         /* HALT */
1333         gen_helper_halt(vb);
1334         return DISAS_PC_STALE;
1335 
1336     case 251:
1337         /* ALARM */
1338         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1339             gen_io_start();
1340             ret = DISAS_PC_STALE;
1341         }
1342         gen_helper_set_alarm(cpu_env, vb);
1343         break;
1344 
1345     case 7:
1346         /* PALBR */
1347         tcg_gen_st_i64(vb, cpu_env, offsetof(CPUAlphaState, palbr));
1348         /* Changing the PAL base register implies un-chaining all of the TBs
1349            that ended with a CALL_PAL.  Since the base register usually only
1350            changes during boot, flushing everything works well.  */
1351         gen_helper_tb_flush(cpu_env);
1352         return DISAS_PC_STALE;
1353 
1354     case 32 ... 39:
1355         /* Accessing the "non-shadow" general registers.  */
1356         regno = regno == 39 ? 25 : regno - 32 + 8;
1357         tcg_gen_mov_i64(cpu_std_ir[regno], vb);
1358         break;
1359 
1360     case 0: /* PS */
1361         st_flag_byte(vb, ENV_FLAG_PS_SHIFT);
1362         break;
1363     case 1: /* FEN */
1364         st_flag_byte(vb, ENV_FLAG_FEN_SHIFT);
1365         break;
1366 
1367     default:
1368         /* The basic registers are data only, and unknown registers
1369            are read-zero, write-ignore.  */
1370         data = cpu_pr_data(regno);
1371         if (data != 0) {
1372             if (data & PR_LONG) {
1373                 tcg_gen_st32_i64(vb, cpu_env, data & ~PR_LONG);
1374             } else {
1375                 tcg_gen_st_i64(vb, cpu_env, data);
1376             }
1377         }
1378         break;
1379     }
1380 
1381     return ret;
1382 }
1383 #endif /* !USER_ONLY*/
1384 
1385 #define REQUIRE_NO_LIT                          \
1386     do {                                        \
1387         if (real_islit) {                       \
1388             goto invalid_opc;                   \
1389         }                                       \
1390     } while (0)
1391 
1392 #define REQUIRE_AMASK(FLAG)                     \
1393     do {                                        \
1394         if ((ctx->amask & AMASK_##FLAG) == 0) { \
1395             goto invalid_opc;                   \
1396         }                                       \
1397     } while (0)
1398 
1399 #define REQUIRE_TB_FLAG(FLAG)                   \
1400     do {                                        \
1401         if ((ctx->tbflags & (FLAG)) == 0) {     \
1402             goto invalid_opc;                   \
1403         }                                       \
1404     } while (0)
1405 
1406 #define REQUIRE_REG_31(WHICH)                   \
1407     do {                                        \
1408         if (WHICH != 31) {                      \
1409             goto invalid_opc;                   \
1410         }                                       \
1411     } while (0)
1412 
1413 #define REQUIRE_FEN                             \
1414     do {                                        \
1415         if (!(ctx->tbflags & ENV_FLAG_FEN)) {   \
1416             goto raise_fen;                     \
1417         }                                       \
1418     } while (0)
1419 
1420 static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
1421 {
1422     int32_t disp21, disp16, disp12 __attribute__((unused));
1423     uint16_t fn11;
1424     uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
1425     bool islit, real_islit;
1426     TCGv va, vb, vc, tmp, tmp2;
1427     TCGv_i32 t32;
1428     DisasJumpType ret;
1429 
1430     /* Decode all instruction fields */
1431     opc = extract32(insn, 26, 6);
1432     ra = extract32(insn, 21, 5);
1433     rb = extract32(insn, 16, 5);
1434     rc = extract32(insn, 0, 5);
1435     real_islit = islit = extract32(insn, 12, 1);
1436     lit = extract32(insn, 13, 8);
1437 
1438     disp21 = sextract32(insn, 0, 21);
1439     disp16 = sextract32(insn, 0, 16);
1440     disp12 = sextract32(insn, 0, 12);
1441 
1442     fn11 = extract32(insn, 5, 11);
1443     fpfn = extract32(insn, 5, 6);
1444     fn7 = extract32(insn, 5, 7);
1445 
1446     if (rb == 31 && !islit) {
1447         islit = true;
1448         lit = 0;
1449     }
1450 
1451     ret = DISAS_NEXT;
1452     switch (opc) {
1453     case 0x00:
1454         /* CALL_PAL */
1455         ret = gen_call_pal(ctx, insn & 0x03ffffff);
1456         break;
1457     case 0x01:
1458         /* OPC01 */
1459         goto invalid_opc;
1460     case 0x02:
1461         /* OPC02 */
1462         goto invalid_opc;
1463     case 0x03:
1464         /* OPC03 */
1465         goto invalid_opc;
1466     case 0x04:
1467         /* OPC04 */
1468         goto invalid_opc;
1469     case 0x05:
1470         /* OPC05 */
1471         goto invalid_opc;
1472     case 0x06:
1473         /* OPC06 */
1474         goto invalid_opc;
1475     case 0x07:
1476         /* OPC07 */
1477         goto invalid_opc;
1478 
1479     case 0x09:
1480         /* LDAH */
1481         disp16 = (uint32_t)disp16 << 16;
1482         /* fall through */
1483     case 0x08:
1484         /* LDA */
1485         va = dest_gpr(ctx, ra);
1486         /* It's worth special-casing immediate loads.  */
1487         if (rb == 31) {
1488             tcg_gen_movi_i64(va, disp16);
1489         } else {
1490             tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);
1491         }
1492         break;
1493 
1494     case 0x0A:
1495         /* LDBU */
1496         REQUIRE_AMASK(BWX);
1497         gen_load_int(ctx, ra, rb, disp16, MO_UB, 0, 0);
1498         break;
1499     case 0x0B:
1500         /* LDQ_U */
1501         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 1, 0);
1502         break;
1503     case 0x0C:
1504         /* LDWU */
1505         REQUIRE_AMASK(BWX);
1506         gen_load_int(ctx, ra, rb, disp16, MO_LEUW, 0, 0);
1507         break;
1508     case 0x0D:
1509         /* STW */
1510         REQUIRE_AMASK(BWX);
1511         gen_store_int(ctx, ra, rb, disp16, MO_LEUW, 0);
1512         break;
1513     case 0x0E:
1514         /* STB */
1515         REQUIRE_AMASK(BWX);
1516         gen_store_int(ctx, ra, rb, disp16, MO_UB, 0);
1517         break;
1518     case 0x0F:
1519         /* STQ_U */
1520         gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 1);
1521         break;
1522 
1523     case 0x10:
1524         vc = dest_gpr(ctx, rc);
1525         vb = load_gpr_lit(ctx, rb, lit, islit);
1526 
1527         if (ra == 31) {
1528             if (fn7 == 0x00) {
1529                 /* Special case ADDL as SEXTL.  */
1530                 tcg_gen_ext32s_i64(vc, vb);
1531                 break;
1532             }
1533             if (fn7 == 0x29) {
1534                 /* Special case SUBQ as NEGQ.  */
1535                 tcg_gen_neg_i64(vc, vb);
1536                 break;
1537             }
1538         }
1539 
1540         va = load_gpr(ctx, ra);
1541         switch (fn7) {
1542         case 0x00:
1543             /* ADDL */
1544             tcg_gen_add_i64(vc, va, vb);
1545             tcg_gen_ext32s_i64(vc, vc);
1546             break;
1547         case 0x02:
1548             /* S4ADDL */
1549             tmp = tcg_temp_new();
1550             tcg_gen_shli_i64(tmp, va, 2);
1551             tcg_gen_add_i64(tmp, tmp, vb);
1552             tcg_gen_ext32s_i64(vc, tmp);
1553             tcg_temp_free(tmp);
1554             break;
1555         case 0x09:
1556             /* SUBL */
1557             tcg_gen_sub_i64(vc, va, vb);
1558             tcg_gen_ext32s_i64(vc, vc);
1559             break;
1560         case 0x0B:
1561             /* S4SUBL */
1562             tmp = tcg_temp_new();
1563             tcg_gen_shli_i64(tmp, va, 2);
1564             tcg_gen_sub_i64(tmp, tmp, vb);
1565             tcg_gen_ext32s_i64(vc, tmp);
1566             tcg_temp_free(tmp);
1567             break;
1568         case 0x0F:
1569             /* CMPBGE */
1570             if (ra == 31) {
1571                 /* Special case 0 >= X as X == 0.  */
1572                 gen_helper_cmpbe0(vc, vb);
1573             } else {
1574                 gen_helper_cmpbge(vc, va, vb);
1575             }
1576             break;
1577         case 0x12:
1578             /* S8ADDL */
1579             tmp = tcg_temp_new();
1580             tcg_gen_shli_i64(tmp, va, 3);
1581             tcg_gen_add_i64(tmp, tmp, vb);
1582             tcg_gen_ext32s_i64(vc, tmp);
1583             tcg_temp_free(tmp);
1584             break;
1585         case 0x1B:
1586             /* S8SUBL */
1587             tmp = tcg_temp_new();
1588             tcg_gen_shli_i64(tmp, va, 3);
1589             tcg_gen_sub_i64(tmp, tmp, vb);
1590             tcg_gen_ext32s_i64(vc, tmp);
1591             tcg_temp_free(tmp);
1592             break;
1593         case 0x1D:
1594             /* CMPULT */
1595             tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb);
1596             break;
1597         case 0x20:
1598             /* ADDQ */
1599             tcg_gen_add_i64(vc, va, vb);
1600             break;
1601         case 0x22:
1602             /* S4ADDQ */
1603             tmp = tcg_temp_new();
1604             tcg_gen_shli_i64(tmp, va, 2);
1605             tcg_gen_add_i64(vc, tmp, vb);
1606             tcg_temp_free(tmp);
1607             break;
1608         case 0x29:
1609             /* SUBQ */
1610             tcg_gen_sub_i64(vc, va, vb);
1611             break;
1612         case 0x2B:
1613             /* S4SUBQ */
1614             tmp = tcg_temp_new();
1615             tcg_gen_shli_i64(tmp, va, 2);
1616             tcg_gen_sub_i64(vc, tmp, vb);
1617             tcg_temp_free(tmp);
1618             break;
1619         case 0x2D:
1620             /* CMPEQ */
1621             tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb);
1622             break;
1623         case 0x32:
1624             /* S8ADDQ */
1625             tmp = tcg_temp_new();
1626             tcg_gen_shli_i64(tmp, va, 3);
1627             tcg_gen_add_i64(vc, tmp, vb);
1628             tcg_temp_free(tmp);
1629             break;
1630         case 0x3B:
1631             /* S8SUBQ */
1632             tmp = tcg_temp_new();
1633             tcg_gen_shli_i64(tmp, va, 3);
1634             tcg_gen_sub_i64(vc, tmp, vb);
1635             tcg_temp_free(tmp);
1636             break;
1637         case 0x3D:
1638             /* CMPULE */
1639             tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb);
1640             break;
1641         case 0x40:
1642             /* ADDL/V */
1643             tmp = tcg_temp_new();
1644             tcg_gen_ext32s_i64(tmp, va);
1645             tcg_gen_ext32s_i64(vc, vb);
1646             tcg_gen_add_i64(tmp, tmp, vc);
1647             tcg_gen_ext32s_i64(vc, tmp);
1648             gen_helper_check_overflow(cpu_env, vc, tmp);
1649             tcg_temp_free(tmp);
1650             break;
1651         case 0x49:
1652             /* SUBL/V */
1653             tmp = tcg_temp_new();
1654             tcg_gen_ext32s_i64(tmp, va);
1655             tcg_gen_ext32s_i64(vc, vb);
1656             tcg_gen_sub_i64(tmp, tmp, vc);
1657             tcg_gen_ext32s_i64(vc, tmp);
1658             gen_helper_check_overflow(cpu_env, vc, tmp);
1659             tcg_temp_free(tmp);
1660             break;
1661         case 0x4D:
1662             /* CMPLT */
1663             tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb);
1664             break;
1665         case 0x60:
1666             /* ADDQ/V */
1667             tmp = tcg_temp_new();
1668             tmp2 = tcg_temp_new();
1669             tcg_gen_eqv_i64(tmp, va, vb);
1670             tcg_gen_mov_i64(tmp2, va);
1671             tcg_gen_add_i64(vc, va, vb);
1672             tcg_gen_xor_i64(tmp2, tmp2, vc);
1673             tcg_gen_and_i64(tmp, tmp, tmp2);
1674             tcg_gen_shri_i64(tmp, tmp, 63);
1675             tcg_gen_movi_i64(tmp2, 0);
1676             gen_helper_check_overflow(cpu_env, tmp, tmp2);
1677             tcg_temp_free(tmp);
1678             tcg_temp_free(tmp2);
1679             break;
1680         case 0x69:
1681             /* SUBQ/V */
1682             tmp = tcg_temp_new();
1683             tmp2 = tcg_temp_new();
1684             tcg_gen_xor_i64(tmp, va, vb);
1685             tcg_gen_mov_i64(tmp2, va);
1686             tcg_gen_sub_i64(vc, va, vb);
1687             tcg_gen_xor_i64(tmp2, tmp2, vc);
1688             tcg_gen_and_i64(tmp, tmp, tmp2);
1689             tcg_gen_shri_i64(tmp, tmp, 63);
1690             tcg_gen_movi_i64(tmp2, 0);
1691             gen_helper_check_overflow(cpu_env, tmp, tmp2);
1692             tcg_temp_free(tmp);
1693             tcg_temp_free(tmp2);
1694             break;
1695         case 0x6D:
1696             /* CMPLE */
1697             tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb);
1698             break;
1699         default:
1700             goto invalid_opc;
1701         }
1702         break;
1703 
1704     case 0x11:
1705         if (fn7 == 0x20) {
1706             if (rc == 31) {
1707                 /* Special case BIS as NOP.  */
1708                 break;
1709             }
1710             if (ra == 31) {
1711                 /* Special case BIS as MOV.  */
1712                 vc = dest_gpr(ctx, rc);
1713                 if (islit) {
1714                     tcg_gen_movi_i64(vc, lit);
1715                 } else {
1716                     tcg_gen_mov_i64(vc, load_gpr(ctx, rb));
1717                 }
1718                 break;
1719             }
1720         }
1721 
1722         vc = dest_gpr(ctx, rc);
1723         vb = load_gpr_lit(ctx, rb, lit, islit);
1724 
1725         if (fn7 == 0x28 && ra == 31) {
1726             /* Special case ORNOT as NOT.  */
1727             tcg_gen_not_i64(vc, vb);
1728             break;
1729         }
1730 
1731         va = load_gpr(ctx, ra);
1732         switch (fn7) {
1733         case 0x00:
1734             /* AND */
1735             tcg_gen_and_i64(vc, va, vb);
1736             break;
1737         case 0x08:
1738             /* BIC */
1739             tcg_gen_andc_i64(vc, va, vb);
1740             break;
1741         case 0x14:
1742             /* CMOVLBS */
1743             tmp = tcg_temp_new();
1744             tcg_gen_andi_i64(tmp, va, 1);
1745             tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
1746                                 vb, load_gpr(ctx, rc));
1747             tcg_temp_free(tmp);
1748             break;
1749         case 0x16:
1750             /* CMOVLBC */
1751             tmp = tcg_temp_new();
1752             tcg_gen_andi_i64(tmp, va, 1);
1753             tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
1754                                 vb, load_gpr(ctx, rc));
1755             tcg_temp_free(tmp);
1756             break;
1757         case 0x20:
1758             /* BIS */
1759             tcg_gen_or_i64(vc, va, vb);
1760             break;
1761         case 0x24:
1762             /* CMOVEQ */
1763             tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx),
1764                                 vb, load_gpr(ctx, rc));
1765             break;
1766         case 0x26:
1767             /* CMOVNE */
1768             tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx),
1769                                 vb, load_gpr(ctx, rc));
1770             break;
1771         case 0x28:
1772             /* ORNOT */
1773             tcg_gen_orc_i64(vc, va, vb);
1774             break;
1775         case 0x40:
1776             /* XOR */
1777             tcg_gen_xor_i64(vc, va, vb);
1778             break;
1779         case 0x44:
1780             /* CMOVLT */
1781             tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx),
1782                                 vb, load_gpr(ctx, rc));
1783             break;
1784         case 0x46:
1785             /* CMOVGE */
1786             tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx),
1787                                 vb, load_gpr(ctx, rc));
1788             break;
1789         case 0x48:
1790             /* EQV */
1791             tcg_gen_eqv_i64(vc, va, vb);
1792             break;
1793         case 0x61:
1794             /* AMASK */
1795             REQUIRE_REG_31(ra);
1796             tcg_gen_andi_i64(vc, vb, ~ctx->amask);
1797             break;
1798         case 0x64:
1799             /* CMOVLE */
1800             tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx),
1801                                 vb, load_gpr(ctx, rc));
1802             break;
1803         case 0x66:
1804             /* CMOVGT */
1805             tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx),
1806                                 vb, load_gpr(ctx, rc));
1807             break;
1808         case 0x6C:
1809             /* IMPLVER */
1810             REQUIRE_REG_31(ra);
1811             tcg_gen_movi_i64(vc, ctx->implver);
1812             break;
1813         default:
1814             goto invalid_opc;
1815         }
1816         break;
1817 
1818     case 0x12:
1819         vc = dest_gpr(ctx, rc);
1820         va = load_gpr(ctx, ra);
1821         switch (fn7) {
1822         case 0x02:
1823             /* MSKBL */
1824             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01);
1825             break;
1826         case 0x06:
1827             /* EXTBL */
1828             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01);
1829             break;
1830         case 0x0B:
1831             /* INSBL */
1832             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01);
1833             break;
1834         case 0x12:
1835             /* MSKWL */
1836             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03);
1837             break;
1838         case 0x16:
1839             /* EXTWL */
1840             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03);
1841             break;
1842         case 0x1B:
1843             /* INSWL */
1844             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03);
1845             break;
1846         case 0x22:
1847             /* MSKLL */
1848             gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f);
1849             break;
1850         case 0x26:
1851             /* EXTLL */
1852             gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f);
1853             break;
1854         case 0x2B:
1855             /* INSLL */
1856             gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f);
1857             break;
1858         case 0x30:
1859             /* ZAP */
1860             if (islit) {
1861                 gen_zapnoti(vc, va, ~lit);
1862             } else {
1863                 gen_helper_zap(vc, va, load_gpr(ctx, rb));
1864             }
1865             break;
1866         case 0x31:
1867             /* ZAPNOT */
1868             if (islit) {
1869                 gen_zapnoti(vc, va, lit);
1870             } else {
1871                 gen_helper_zapnot(vc, va, load_gpr(ctx, rb));
1872             }
1873             break;
1874         case 0x32:
1875             /* MSKQL */
1876             gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff);
1877             break;
1878         case 0x34:
1879             /* SRL */
1880             if (islit) {
1881                 tcg_gen_shri_i64(vc, va, lit & 0x3f);
1882             } else {
1883                 tmp = tcg_temp_new();
1884                 vb = load_gpr(ctx, rb);
1885                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1886                 tcg_gen_shr_i64(vc, va, tmp);
1887                 tcg_temp_free(tmp);
1888             }
1889             break;
1890         case 0x36:
1891             /* EXTQL */
1892             gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff);
1893             break;
1894         case 0x39:
1895             /* SLL */
1896             if (islit) {
1897                 tcg_gen_shli_i64(vc, va, lit & 0x3f);
1898             } else {
1899                 tmp = tcg_temp_new();
1900                 vb = load_gpr(ctx, rb);
1901                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1902                 tcg_gen_shl_i64(vc, va, tmp);
1903                 tcg_temp_free(tmp);
1904             }
1905             break;
1906         case 0x3B:
1907             /* INSQL */
1908             gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff);
1909             break;
1910         case 0x3C:
1911             /* SRA */
1912             if (islit) {
1913                 tcg_gen_sari_i64(vc, va, lit & 0x3f);
1914             } else {
1915                 tmp = tcg_temp_new();
1916                 vb = load_gpr(ctx, rb);
1917                 tcg_gen_andi_i64(tmp, vb, 0x3f);
1918                 tcg_gen_sar_i64(vc, va, tmp);
1919                 tcg_temp_free(tmp);
1920             }
1921             break;
1922         case 0x52:
1923             /* MSKWH */
1924             gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03);
1925             break;
1926         case 0x57:
1927             /* INSWH */
1928             gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03);
1929             break;
1930         case 0x5A:
1931             /* EXTWH */
1932             gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03);
1933             break;
1934         case 0x62:
1935             /* MSKLH */
1936             gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f);
1937             break;
1938         case 0x67:
1939             /* INSLH */
1940             gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f);
1941             break;
1942         case 0x6A:
1943             /* EXTLH */
1944             gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f);
1945             break;
1946         case 0x72:
1947             /* MSKQH */
1948             gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff);
1949             break;
1950         case 0x77:
1951             /* INSQH */
1952             gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff);
1953             break;
1954         case 0x7A:
1955             /* EXTQH */
1956             gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff);
1957             break;
1958         default:
1959             goto invalid_opc;
1960         }
1961         break;
1962 
1963     case 0x13:
1964         vc = dest_gpr(ctx, rc);
1965         vb = load_gpr_lit(ctx, rb, lit, islit);
1966         va = load_gpr(ctx, ra);
1967         switch (fn7) {
1968         case 0x00:
1969             /* MULL */
1970             tcg_gen_mul_i64(vc, va, vb);
1971             tcg_gen_ext32s_i64(vc, vc);
1972             break;
1973         case 0x20:
1974             /* MULQ */
1975             tcg_gen_mul_i64(vc, va, vb);
1976             break;
1977         case 0x30:
1978             /* UMULH */
1979             tmp = tcg_temp_new();
1980             tcg_gen_mulu2_i64(tmp, vc, va, vb);
1981             tcg_temp_free(tmp);
1982             break;
1983         case 0x40:
1984             /* MULL/V */
1985             tmp = tcg_temp_new();
1986             tcg_gen_ext32s_i64(tmp, va);
1987             tcg_gen_ext32s_i64(vc, vb);
1988             tcg_gen_mul_i64(tmp, tmp, vc);
1989             tcg_gen_ext32s_i64(vc, tmp);
1990             gen_helper_check_overflow(cpu_env, vc, tmp);
1991             tcg_temp_free(tmp);
1992             break;
1993         case 0x60:
1994             /* MULQ/V */
1995             tmp = tcg_temp_new();
1996             tmp2 = tcg_temp_new();
1997             tcg_gen_muls2_i64(vc, tmp, va, vb);
1998             tcg_gen_sari_i64(tmp2, vc, 63);
1999             gen_helper_check_overflow(cpu_env, tmp, tmp2);
2000             tcg_temp_free(tmp);
2001             tcg_temp_free(tmp2);
2002             break;
2003         default:
2004             goto invalid_opc;
2005         }
2006         break;
2007 
2008     case 0x14:
2009         REQUIRE_AMASK(FIX);
2010         vc = dest_fpr(ctx, rc);
2011         switch (fpfn) { /* fn11 & 0x3F */
2012         case 0x04:
2013             /* ITOFS */
2014             REQUIRE_REG_31(rb);
2015             REQUIRE_FEN;
2016             t32 = tcg_temp_new_i32();
2017             va = load_gpr(ctx, ra);
2018             tcg_gen_extrl_i64_i32(t32, va);
2019             gen_helper_memory_to_s(vc, t32);
2020             tcg_temp_free_i32(t32);
2021             break;
2022         case 0x0A:
2023             /* SQRTF */
2024             REQUIRE_REG_31(ra);
2025             REQUIRE_FEN;
2026             vb = load_fpr(ctx, rb);
2027             gen_helper_sqrtf(vc, cpu_env, vb);
2028             break;
2029         case 0x0B:
2030             /* SQRTS */
2031             REQUIRE_REG_31(ra);
2032             REQUIRE_FEN;
2033             gen_sqrts(ctx, rb, rc, fn11);
2034             break;
2035         case 0x14:
2036             /* ITOFF */
2037             REQUIRE_REG_31(rb);
2038             REQUIRE_FEN;
2039             t32 = tcg_temp_new_i32();
2040             va = load_gpr(ctx, ra);
2041             tcg_gen_extrl_i64_i32(t32, va);
2042             gen_helper_memory_to_f(vc, t32);
2043             tcg_temp_free_i32(t32);
2044             break;
2045         case 0x24:
2046             /* ITOFT */
2047             REQUIRE_REG_31(rb);
2048             REQUIRE_FEN;
2049             va = load_gpr(ctx, ra);
2050             tcg_gen_mov_i64(vc, va);
2051             break;
2052         case 0x2A:
2053             /* SQRTG */
2054             REQUIRE_REG_31(ra);
2055             REQUIRE_FEN;
2056             vb = load_fpr(ctx, rb);
2057             gen_helper_sqrtg(vc, cpu_env, vb);
2058             break;
2059         case 0x02B:
2060             /* SQRTT */
2061             REQUIRE_REG_31(ra);
2062             REQUIRE_FEN;
2063             gen_sqrtt(ctx, rb, rc, fn11);
2064             break;
2065         default:
2066             goto invalid_opc;
2067         }
2068         break;
2069 
2070     case 0x15:
2071         /* VAX floating point */
2072         /* XXX: rounding mode and trap are ignored (!) */
2073         vc = dest_fpr(ctx, rc);
2074         vb = load_fpr(ctx, rb);
2075         va = load_fpr(ctx, ra);
2076         switch (fpfn) { /* fn11 & 0x3F */
2077         case 0x00:
2078             /* ADDF */
2079             REQUIRE_FEN;
2080             gen_helper_addf(vc, cpu_env, va, vb);
2081             break;
2082         case 0x01:
2083             /* SUBF */
2084             REQUIRE_FEN;
2085             gen_helper_subf(vc, cpu_env, va, vb);
2086             break;
2087         case 0x02:
2088             /* MULF */
2089             REQUIRE_FEN;
2090             gen_helper_mulf(vc, cpu_env, va, vb);
2091             break;
2092         case 0x03:
2093             /* DIVF */
2094             REQUIRE_FEN;
2095             gen_helper_divf(vc, cpu_env, va, vb);
2096             break;
2097         case 0x1E:
2098             /* CVTDG -- TODO */
2099             REQUIRE_REG_31(ra);
2100             goto invalid_opc;
2101         case 0x20:
2102             /* ADDG */
2103             REQUIRE_FEN;
2104             gen_helper_addg(vc, cpu_env, va, vb);
2105             break;
2106         case 0x21:
2107             /* SUBG */
2108             REQUIRE_FEN;
2109             gen_helper_subg(vc, cpu_env, va, vb);
2110             break;
2111         case 0x22:
2112             /* MULG */
2113             REQUIRE_FEN;
2114             gen_helper_mulg(vc, cpu_env, va, vb);
2115             break;
2116         case 0x23:
2117             /* DIVG */
2118             REQUIRE_FEN;
2119             gen_helper_divg(vc, cpu_env, va, vb);
2120             break;
2121         case 0x25:
2122             /* CMPGEQ */
2123             REQUIRE_FEN;
2124             gen_helper_cmpgeq(vc, cpu_env, va, vb);
2125             break;
2126         case 0x26:
2127             /* CMPGLT */
2128             REQUIRE_FEN;
2129             gen_helper_cmpglt(vc, cpu_env, va, vb);
2130             break;
2131         case 0x27:
2132             /* CMPGLE */
2133             REQUIRE_FEN;
2134             gen_helper_cmpgle(vc, cpu_env, va, vb);
2135             break;
2136         case 0x2C:
2137             /* CVTGF */
2138             REQUIRE_REG_31(ra);
2139             REQUIRE_FEN;
2140             gen_helper_cvtgf(vc, cpu_env, vb);
2141             break;
2142         case 0x2D:
2143             /* CVTGD -- TODO */
2144             REQUIRE_REG_31(ra);
2145             goto invalid_opc;
2146         case 0x2F:
2147             /* CVTGQ */
2148             REQUIRE_REG_31(ra);
2149             REQUIRE_FEN;
2150             gen_helper_cvtgq(vc, cpu_env, vb);
2151             break;
2152         case 0x3C:
2153             /* CVTQF */
2154             REQUIRE_REG_31(ra);
2155             REQUIRE_FEN;
2156             gen_helper_cvtqf(vc, cpu_env, vb);
2157             break;
2158         case 0x3E:
2159             /* CVTQG */
2160             REQUIRE_REG_31(ra);
2161             REQUIRE_FEN;
2162             gen_helper_cvtqg(vc, cpu_env, vb);
2163             break;
2164         default:
2165             goto invalid_opc;
2166         }
2167         break;
2168 
2169     case 0x16:
2170         /* IEEE floating-point */
2171         switch (fpfn) { /* fn11 & 0x3F */
2172         case 0x00:
2173             /* ADDS */
2174             REQUIRE_FEN;
2175             gen_adds(ctx, ra, rb, rc, fn11);
2176             break;
2177         case 0x01:
2178             /* SUBS */
2179             REQUIRE_FEN;
2180             gen_subs(ctx, ra, rb, rc, fn11);
2181             break;
2182         case 0x02:
2183             /* MULS */
2184             REQUIRE_FEN;
2185             gen_muls(ctx, ra, rb, rc, fn11);
2186             break;
2187         case 0x03:
2188             /* DIVS */
2189             REQUIRE_FEN;
2190             gen_divs(ctx, ra, rb, rc, fn11);
2191             break;
2192         case 0x20:
2193             /* ADDT */
2194             REQUIRE_FEN;
2195             gen_addt(ctx, ra, rb, rc, fn11);
2196             break;
2197         case 0x21:
2198             /* SUBT */
2199             REQUIRE_FEN;
2200             gen_subt(ctx, ra, rb, rc, fn11);
2201             break;
2202         case 0x22:
2203             /* MULT */
2204             REQUIRE_FEN;
2205             gen_mult(ctx, ra, rb, rc, fn11);
2206             break;
2207         case 0x23:
2208             /* DIVT */
2209             REQUIRE_FEN;
2210             gen_divt(ctx, ra, rb, rc, fn11);
2211             break;
2212         case 0x24:
2213             /* CMPTUN */
2214             REQUIRE_FEN;
2215             gen_cmptun(ctx, ra, rb, rc, fn11);
2216             break;
2217         case 0x25:
2218             /* CMPTEQ */
2219             REQUIRE_FEN;
2220             gen_cmpteq(ctx, ra, rb, rc, fn11);
2221             break;
2222         case 0x26:
2223             /* CMPTLT */
2224             REQUIRE_FEN;
2225             gen_cmptlt(ctx, ra, rb, rc, fn11);
2226             break;
2227         case 0x27:
2228             /* CMPTLE */
2229             REQUIRE_FEN;
2230             gen_cmptle(ctx, ra, rb, rc, fn11);
2231             break;
2232         case 0x2C:
2233             REQUIRE_REG_31(ra);
2234             REQUIRE_FEN;
2235             if (fn11 == 0x2AC || fn11 == 0x6AC) {
2236                 /* CVTST */
2237                 gen_cvtst(ctx, rb, rc, fn11);
2238             } else {
2239                 /* CVTTS */
2240                 gen_cvtts(ctx, rb, rc, fn11);
2241             }
2242             break;
2243         case 0x2F:
2244             /* CVTTQ */
2245             REQUIRE_REG_31(ra);
2246             REQUIRE_FEN;
2247             gen_cvttq(ctx, rb, rc, fn11);
2248             break;
2249         case 0x3C:
2250             /* CVTQS */
2251             REQUIRE_REG_31(ra);
2252             REQUIRE_FEN;
2253             gen_cvtqs(ctx, rb, rc, fn11);
2254             break;
2255         case 0x3E:
2256             /* CVTQT */
2257             REQUIRE_REG_31(ra);
2258             REQUIRE_FEN;
2259             gen_cvtqt(ctx, rb, rc, fn11);
2260             break;
2261         default:
2262             goto invalid_opc;
2263         }
2264         break;
2265 
2266     case 0x17:
2267         switch (fn11) {
2268         case 0x010:
2269             /* CVTLQ */
2270             REQUIRE_REG_31(ra);
2271             REQUIRE_FEN;
2272             vc = dest_fpr(ctx, rc);
2273             vb = load_fpr(ctx, rb);
2274             gen_cvtlq(vc, vb);
2275             break;
2276         case 0x020:
2277             /* CPYS */
2278             REQUIRE_FEN;
2279             if (rc == 31) {
2280                 /* Special case CPYS as FNOP.  */
2281             } else {
2282                 vc = dest_fpr(ctx, rc);
2283                 va = load_fpr(ctx, ra);
2284                 if (ra == rb) {
2285                     /* Special case CPYS as FMOV.  */
2286                     tcg_gen_mov_i64(vc, va);
2287                 } else {
2288                     vb = load_fpr(ctx, rb);
2289                     gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL);
2290                 }
2291             }
2292             break;
2293         case 0x021:
2294             /* CPYSN */
2295             REQUIRE_FEN;
2296             vc = dest_fpr(ctx, rc);
2297             vb = load_fpr(ctx, rb);
2298             va = load_fpr(ctx, ra);
2299             gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL);
2300             break;
2301         case 0x022:
2302             /* CPYSE */
2303             REQUIRE_FEN;
2304             vc = dest_fpr(ctx, rc);
2305             vb = load_fpr(ctx, rb);
2306             va = load_fpr(ctx, ra);
2307             gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL);
2308             break;
2309         case 0x024:
2310             /* MT_FPCR */
2311             REQUIRE_FEN;
2312             va = load_fpr(ctx, ra);
2313             gen_helper_store_fpcr(cpu_env, va);
2314             if (ctx->tb_rm == QUAL_RM_D) {
2315                 /* Re-do the copy of the rounding mode to fp_status
2316                    the next time we use dynamic rounding.  */
2317                 ctx->tb_rm = -1;
2318             }
2319             break;
2320         case 0x025:
2321             /* MF_FPCR */
2322             REQUIRE_FEN;
2323             va = dest_fpr(ctx, ra);
2324             gen_helper_load_fpcr(va, cpu_env);
2325             break;
2326         case 0x02A:
2327             /* FCMOVEQ */
2328             REQUIRE_FEN;
2329             gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc);
2330             break;
2331         case 0x02B:
2332             /* FCMOVNE */
2333             REQUIRE_FEN;
2334             gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc);
2335             break;
2336         case 0x02C:
2337             /* FCMOVLT */
2338             REQUIRE_FEN;
2339             gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc);
2340             break;
2341         case 0x02D:
2342             /* FCMOVGE */
2343             REQUIRE_FEN;
2344             gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc);
2345             break;
2346         case 0x02E:
2347             /* FCMOVLE */
2348             REQUIRE_FEN;
2349             gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc);
2350             break;
2351         case 0x02F:
2352             /* FCMOVGT */
2353             REQUIRE_FEN;
2354             gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);
2355             break;
2356         case 0x030: /* CVTQL */
2357         case 0x130: /* CVTQL/V */
2358         case 0x530: /* CVTQL/SV */
2359             REQUIRE_REG_31(ra);
2360             REQUIRE_FEN;
2361             vc = dest_fpr(ctx, rc);
2362             vb = load_fpr(ctx, rb);
2363             gen_helper_cvtql(vc, cpu_env, vb);
2364             gen_fp_exc_raise(rc, fn11);
2365             break;
2366         default:
2367             goto invalid_opc;
2368         }
2369         break;
2370 
2371     case 0x18:
2372         switch ((uint16_t)disp16) {
2373         case 0x0000:
2374             /* TRAPB */
2375             /* No-op.  */
2376             break;
2377         case 0x0400:
2378             /* EXCB */
2379             /* No-op.  */
2380             break;
2381         case 0x4000:
2382             /* MB */
2383             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
2384             break;
2385         case 0x4400:
2386             /* WMB */
2387             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
2388             break;
2389         case 0x8000:
2390             /* FETCH */
2391             /* No-op */
2392             break;
2393         case 0xA000:
2394             /* FETCH_M */
2395             /* No-op */
2396             break;
2397         case 0xC000:
2398             /* RPCC */
2399             va = dest_gpr(ctx, ra);
2400             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2401                 gen_io_start();
2402                 gen_helper_load_pcc(va, cpu_env);
2403                 ret = DISAS_PC_STALE;
2404             } else {
2405                 gen_helper_load_pcc(va, cpu_env);
2406             }
2407             break;
2408         case 0xE000:
2409             /* RC */
2410             gen_rx(ctx, ra, 0);
2411             break;
2412         case 0xE800:
2413             /* ECB */
2414             break;
2415         case 0xF000:
2416             /* RS */
2417             gen_rx(ctx, ra, 1);
2418             break;
2419         case 0xF800:
2420             /* WH64 */
2421             /* No-op */
2422             break;
2423         case 0xFC00:
2424             /* WH64EN */
2425             /* No-op */
2426             break;
2427         default:
2428             goto invalid_opc;
2429         }
2430         break;
2431 
2432     case 0x19:
2433         /* HW_MFPR (PALcode) */
2434 #ifndef CONFIG_USER_ONLY
2435         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2436         va = dest_gpr(ctx, ra);
2437         ret = gen_mfpr(ctx, va, insn & 0xffff);
2438         break;
2439 #else
2440         goto invalid_opc;
2441 #endif
2442 
2443     case 0x1A:
2444         /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
2445            prediction stack action, which of course we don't implement.  */
2446         vb = load_gpr(ctx, rb);
2447         tcg_gen_andi_i64(cpu_pc, vb, ~3);
2448         if (ra != 31) {
2449             tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
2450         }
2451         ret = DISAS_PC_UPDATED;
2452         break;
2453 
2454     case 0x1B:
2455         /* HW_LD (PALcode) */
2456 #ifndef CONFIG_USER_ONLY
2457         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2458         {
2459             TCGv addr = tcg_temp_new();
2460             vb = load_gpr(ctx, rb);
2461             va = dest_gpr(ctx, ra);
2462 
2463             tcg_gen_addi_i64(addr, vb, disp12);
2464             switch ((insn >> 12) & 0xF) {
2465             case 0x0:
2466                 /* Longword physical access (hw_ldl/p) */
2467                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL);
2468                 break;
2469             case 0x1:
2470                 /* Quadword physical access (hw_ldq/p) */
2471                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ);
2472                 break;
2473             case 0x2:
2474                 /* Longword physical access with lock (hw_ldl_l/p) */
2475                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL);
2476                 tcg_gen_mov_i64(cpu_lock_addr, addr);
2477                 tcg_gen_mov_i64(cpu_lock_value, va);
2478                 break;
2479             case 0x3:
2480                 /* Quadword physical access with lock (hw_ldq_l/p) */
2481                 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ);
2482                 tcg_gen_mov_i64(cpu_lock_addr, addr);
2483                 tcg_gen_mov_i64(cpu_lock_value, va);
2484                 break;
2485             case 0x4:
2486                 /* Longword virtual PTE fetch (hw_ldl/v) */
2487                 goto invalid_opc;
2488             case 0x5:
2489                 /* Quadword virtual PTE fetch (hw_ldq/v) */
2490                 goto invalid_opc;
2491                 break;
2492             case 0x6:
2493                 /* Invalid */
2494                 goto invalid_opc;
2495             case 0x7:
2496                 /* Invaliid */
2497                 goto invalid_opc;
2498             case 0x8:
2499                 /* Longword virtual access (hw_ldl) */
2500                 goto invalid_opc;
2501             case 0x9:
2502                 /* Quadword virtual access (hw_ldq) */
2503                 goto invalid_opc;
2504             case 0xA:
2505                 /* Longword virtual access with protection check (hw_ldl/w) */
2506                 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LESL);
2507                 break;
2508             case 0xB:
2509                 /* Quadword virtual access with protection check (hw_ldq/w) */
2510                 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEUQ);
2511                 break;
2512             case 0xC:
2513                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2514                 goto invalid_opc;
2515             case 0xD:
2516                 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2517                 goto invalid_opc;
2518             case 0xE:
2519                 /* Longword virtual access with alternate access mode and
2520                    protection checks (hw_ldl/wa) */
2521                 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LESL);
2522                 break;
2523             case 0xF:
2524                 /* Quadword virtual access with alternate access mode and
2525                    protection checks (hw_ldq/wa) */
2526                 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEUQ);
2527                 break;
2528             }
2529             tcg_temp_free(addr);
2530             break;
2531         }
2532 #else
2533         goto invalid_opc;
2534 #endif
2535 
2536     case 0x1C:
2537         vc = dest_gpr(ctx, rc);
2538         if (fn7 == 0x70) {
2539             /* FTOIT */
2540             REQUIRE_AMASK(FIX);
2541             REQUIRE_REG_31(rb);
2542             va = load_fpr(ctx, ra);
2543             tcg_gen_mov_i64(vc, va);
2544             break;
2545         } else if (fn7 == 0x78) {
2546             /* FTOIS */
2547             REQUIRE_AMASK(FIX);
2548             REQUIRE_REG_31(rb);
2549             t32 = tcg_temp_new_i32();
2550             va = load_fpr(ctx, ra);
2551             gen_helper_s_to_memory(t32, va);
2552             tcg_gen_ext_i32_i64(vc, t32);
2553             tcg_temp_free_i32(t32);
2554             break;
2555         }
2556 
2557         vb = load_gpr_lit(ctx, rb, lit, islit);
2558         switch (fn7) {
2559         case 0x00:
2560             /* SEXTB */
2561             REQUIRE_AMASK(BWX);
2562             REQUIRE_REG_31(ra);
2563             tcg_gen_ext8s_i64(vc, vb);
2564             break;
2565         case 0x01:
2566             /* SEXTW */
2567             REQUIRE_AMASK(BWX);
2568             REQUIRE_REG_31(ra);
2569             tcg_gen_ext16s_i64(vc, vb);
2570             break;
2571         case 0x30:
2572             /* CTPOP */
2573             REQUIRE_AMASK(CIX);
2574             REQUIRE_REG_31(ra);
2575             REQUIRE_NO_LIT;
2576             tcg_gen_ctpop_i64(vc, vb);
2577             break;
2578         case 0x31:
2579             /* PERR */
2580             REQUIRE_AMASK(MVI);
2581             REQUIRE_NO_LIT;
2582             va = load_gpr(ctx, ra);
2583             gen_helper_perr(vc, va, vb);
2584             break;
2585         case 0x32:
2586             /* CTLZ */
2587             REQUIRE_AMASK(CIX);
2588             REQUIRE_REG_31(ra);
2589             REQUIRE_NO_LIT;
2590             tcg_gen_clzi_i64(vc, vb, 64);
2591             break;
2592         case 0x33:
2593             /* CTTZ */
2594             REQUIRE_AMASK(CIX);
2595             REQUIRE_REG_31(ra);
2596             REQUIRE_NO_LIT;
2597             tcg_gen_ctzi_i64(vc, vb, 64);
2598             break;
2599         case 0x34:
2600             /* UNPKBW */
2601             REQUIRE_AMASK(MVI);
2602             REQUIRE_REG_31(ra);
2603             REQUIRE_NO_LIT;
2604             gen_helper_unpkbw(vc, vb);
2605             break;
2606         case 0x35:
2607             /* UNPKBL */
2608             REQUIRE_AMASK(MVI);
2609             REQUIRE_REG_31(ra);
2610             REQUIRE_NO_LIT;
2611             gen_helper_unpkbl(vc, vb);
2612             break;
2613         case 0x36:
2614             /* PKWB */
2615             REQUIRE_AMASK(MVI);
2616             REQUIRE_REG_31(ra);
2617             REQUIRE_NO_LIT;
2618             gen_helper_pkwb(vc, vb);
2619             break;
2620         case 0x37:
2621             /* PKLB */
2622             REQUIRE_AMASK(MVI);
2623             REQUIRE_REG_31(ra);
2624             REQUIRE_NO_LIT;
2625             gen_helper_pklb(vc, vb);
2626             break;
2627         case 0x38:
2628             /* MINSB8 */
2629             REQUIRE_AMASK(MVI);
2630             va = load_gpr(ctx, ra);
2631             gen_helper_minsb8(vc, va, vb);
2632             break;
2633         case 0x39:
2634             /* MINSW4 */
2635             REQUIRE_AMASK(MVI);
2636             va = load_gpr(ctx, ra);
2637             gen_helper_minsw4(vc, va, vb);
2638             break;
2639         case 0x3A:
2640             /* MINUB8 */
2641             REQUIRE_AMASK(MVI);
2642             va = load_gpr(ctx, ra);
2643             gen_helper_minub8(vc, va, vb);
2644             break;
2645         case 0x3B:
2646             /* MINUW4 */
2647             REQUIRE_AMASK(MVI);
2648             va = load_gpr(ctx, ra);
2649             gen_helper_minuw4(vc, va, vb);
2650             break;
2651         case 0x3C:
2652             /* MAXUB8 */
2653             REQUIRE_AMASK(MVI);
2654             va = load_gpr(ctx, ra);
2655             gen_helper_maxub8(vc, va, vb);
2656             break;
2657         case 0x3D:
2658             /* MAXUW4 */
2659             REQUIRE_AMASK(MVI);
2660             va = load_gpr(ctx, ra);
2661             gen_helper_maxuw4(vc, va, vb);
2662             break;
2663         case 0x3E:
2664             /* MAXSB8 */
2665             REQUIRE_AMASK(MVI);
2666             va = load_gpr(ctx, ra);
2667             gen_helper_maxsb8(vc, va, vb);
2668             break;
2669         case 0x3F:
2670             /* MAXSW4 */
2671             REQUIRE_AMASK(MVI);
2672             va = load_gpr(ctx, ra);
2673             gen_helper_maxsw4(vc, va, vb);
2674             break;
2675         default:
2676             goto invalid_opc;
2677         }
2678         break;
2679 
2680     case 0x1D:
2681         /* HW_MTPR (PALcode) */
2682 #ifndef CONFIG_USER_ONLY
2683         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2684         vb = load_gpr(ctx, rb);
2685         ret = gen_mtpr(ctx, vb, insn & 0xffff);
2686         break;
2687 #else
2688         goto invalid_opc;
2689 #endif
2690 
2691     case 0x1E:
2692         /* HW_RET (PALcode) */
2693 #ifndef CONFIG_USER_ONLY
2694         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2695         if (rb == 31) {
2696             /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
2697                address from EXC_ADDR.  This turns out to be useful for our
2698                emulation PALcode, so continue to accept it.  */
2699             vb = dest_sink(ctx);
2700             tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr));
2701         } else {
2702             vb = load_gpr(ctx, rb);
2703         }
2704         tcg_gen_movi_i64(cpu_lock_addr, -1);
2705         st_flag_byte(load_zero(ctx), ENV_FLAG_RX_SHIFT);
2706         tmp = tcg_temp_new();
2707         tcg_gen_andi_i64(tmp, vb, 1);
2708         st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
2709         tcg_temp_free(tmp);
2710         tcg_gen_andi_i64(cpu_pc, vb, ~3);
2711         /* Allow interrupts to be recognized right away.  */
2712         ret = DISAS_PC_UPDATED_NOCHAIN;
2713         break;
2714 #else
2715         goto invalid_opc;
2716 #endif
2717 
2718     case 0x1F:
2719         /* HW_ST (PALcode) */
2720 #ifndef CONFIG_USER_ONLY
2721         REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2722         {
2723             switch ((insn >> 12) & 0xF) {
2724             case 0x0:
2725                 /* Longword physical access */
2726                 va = load_gpr(ctx, ra);
2727                 vb = load_gpr(ctx, rb);
2728                 tmp = tcg_temp_new();
2729                 tcg_gen_addi_i64(tmp, vb, disp12);
2730                 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL);
2731                 tcg_temp_free(tmp);
2732                 break;
2733             case 0x1:
2734                 /* Quadword physical access */
2735                 va = load_gpr(ctx, ra);
2736                 vb = load_gpr(ctx, rb);
2737                 tmp = tcg_temp_new();
2738                 tcg_gen_addi_i64(tmp, vb, disp12);
2739                 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEUQ);
2740                 tcg_temp_free(tmp);
2741                 break;
2742             case 0x2:
2743                 /* Longword physical access with lock */
2744                 ret = gen_store_conditional(ctx, ra, rb, disp12,
2745                                             MMU_PHYS_IDX, MO_LESL);
2746                 break;
2747             case 0x3:
2748                 /* Quadword physical access with lock */
2749                 ret = gen_store_conditional(ctx, ra, rb, disp12,
2750                                             MMU_PHYS_IDX, MO_LEUQ);
2751                 break;
2752             case 0x4:
2753                 /* Longword virtual access */
2754                 goto invalid_opc;
2755             case 0x5:
2756                 /* Quadword virtual access */
2757                 goto invalid_opc;
2758             case 0x6:
2759                 /* Invalid */
2760                 goto invalid_opc;
2761             case 0x7:
2762                 /* Invalid */
2763                 goto invalid_opc;
2764             case 0x8:
2765                 /* Invalid */
2766                 goto invalid_opc;
2767             case 0x9:
2768                 /* Invalid */
2769                 goto invalid_opc;
2770             case 0xA:
2771                 /* Invalid */
2772                 goto invalid_opc;
2773             case 0xB:
2774                 /* Invalid */
2775                 goto invalid_opc;
2776             case 0xC:
2777                 /* Longword virtual access with alternate access mode */
2778                 goto invalid_opc;
2779             case 0xD:
2780                 /* Quadword virtual access with alternate access mode */
2781                 goto invalid_opc;
2782             case 0xE:
2783                 /* Invalid */
2784                 goto invalid_opc;
2785             case 0xF:
2786                 /* Invalid */
2787                 goto invalid_opc;
2788             }
2789             break;
2790         }
2791 #else
2792         goto invalid_opc;
2793 #endif
2794     case 0x20:
2795         /* LDF */
2796         REQUIRE_FEN;
2797         gen_load_fp(ctx, ra, rb, disp16, gen_ldf);
2798         break;
2799     case 0x21:
2800         /* LDG */
2801         REQUIRE_FEN;
2802         gen_load_fp(ctx, ra, rb, disp16, gen_ldg);
2803         break;
2804     case 0x22:
2805         /* LDS */
2806         REQUIRE_FEN;
2807         gen_load_fp(ctx, ra, rb, disp16, gen_lds);
2808         break;
2809     case 0x23:
2810         /* LDT */
2811         REQUIRE_FEN;
2812         gen_load_fp(ctx, ra, rb, disp16, gen_ldt);
2813         break;
2814     case 0x24:
2815         /* STF */
2816         REQUIRE_FEN;
2817         gen_store_fp(ctx, ra, rb, disp16, gen_stf);
2818         break;
2819     case 0x25:
2820         /* STG */
2821         REQUIRE_FEN;
2822         gen_store_fp(ctx, ra, rb, disp16, gen_stg);
2823         break;
2824     case 0x26:
2825         /* STS */
2826         REQUIRE_FEN;
2827         gen_store_fp(ctx, ra, rb, disp16, gen_sts);
2828         break;
2829     case 0x27:
2830         /* STT */
2831         REQUIRE_FEN;
2832         gen_store_fp(ctx, ra, rb, disp16, gen_stt);
2833         break;
2834     case 0x28:
2835         /* LDL */
2836         gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 0);
2837         break;
2838     case 0x29:
2839         /* LDQ */
2840         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 0);
2841         break;
2842     case 0x2A:
2843         /* LDL_L */
2844         gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 1);
2845         break;
2846     case 0x2B:
2847         /* LDQ_L */
2848         gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 1);
2849         break;
2850     case 0x2C:
2851         /* STL */
2852         gen_store_int(ctx, ra, rb, disp16, MO_LEUL, 0);
2853         break;
2854     case 0x2D:
2855         /* STQ */
2856         gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 0);
2857         break;
2858     case 0x2E:
2859         /* STL_C */
2860         ret = gen_store_conditional(ctx, ra, rb, disp16,
2861                                     ctx->mem_idx, MO_LESL);
2862         break;
2863     case 0x2F:
2864         /* STQ_C */
2865         ret = gen_store_conditional(ctx, ra, rb, disp16,
2866                                     ctx->mem_idx, MO_LEUQ);
2867         break;
2868     case 0x30:
2869         /* BR */
2870         ret = gen_bdirect(ctx, ra, disp21);
2871         break;
2872     case 0x31: /* FBEQ */
2873         REQUIRE_FEN;
2874         ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
2875         break;
2876     case 0x32: /* FBLT */
2877         REQUIRE_FEN;
2878         ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
2879         break;
2880     case 0x33: /* FBLE */
2881         REQUIRE_FEN;
2882         ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
2883         break;
2884     case 0x34:
2885         /* BSR */
2886         ret = gen_bdirect(ctx, ra, disp21);
2887         break;
2888     case 0x35: /* FBNE */
2889         REQUIRE_FEN;
2890         ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
2891         break;
2892     case 0x36: /* FBGE */
2893         REQUIRE_FEN;
2894         ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
2895         break;
2896     case 0x37: /* FBGT */
2897         REQUIRE_FEN;
2898         ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
2899         break;
2900     case 0x38:
2901         /* BLBC */
2902         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
2903         break;
2904     case 0x39:
2905         /* BEQ */
2906         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
2907         break;
2908     case 0x3A:
2909         /* BLT */
2910         ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
2911         break;
2912     case 0x3B:
2913         /* BLE */
2914         ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
2915         break;
2916     case 0x3C:
2917         /* BLBS */
2918         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
2919         break;
2920     case 0x3D:
2921         /* BNE */
2922         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
2923         break;
2924     case 0x3E:
2925         /* BGE */
2926         ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
2927         break;
2928     case 0x3F:
2929         /* BGT */
2930         ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
2931         break;
2932     invalid_opc:
2933         ret = gen_invalid(ctx);
2934         break;
2935     raise_fen:
2936         ret = gen_excp(ctx, EXCP_FEN, 0);
2937         break;
2938     }
2939 
2940     return ret;
2941 }
2942 
2943 static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
2944 {
2945     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2946     CPUAlphaState *env = cpu->env_ptr;
2947     int64_t bound;
2948 
2949     ctx->tbflags = ctx->base.tb->flags;
2950     ctx->mem_idx = cpu_mmu_index(env, false);
2951     ctx->implver = env->implver;
2952     ctx->amask = env->amask;
2953 
2954 #ifdef CONFIG_USER_ONLY
2955     ctx->ir = cpu_std_ir;
2956     ctx->unalign = (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
2957 #else
2958     ctx->palbr = env->palbr;
2959     ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
2960 #endif
2961 
2962     /* ??? Every TB begins with unset rounding mode, to be initialized on
2963        the first fp insn of the TB.  Alternately we could define a proper
2964        default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
2965        to reset the FP_STATUS to that default at the end of any TB that
2966        changes the default.  We could even (gasp) dynamiclly figure out
2967        what default would be most efficient given the running program.  */
2968     ctx->tb_rm = -1;
2969     /* Similarly for flush-to-zero.  */
2970     ctx->tb_ftz = -1;
2971 
2972     ctx->zero = NULL;
2973     ctx->sink = NULL;
2974 
2975     /* Bound the number of insns to execute to those left on the page.  */
2976     bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
2977     ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2978 }
2979 
2980 static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu)
2981 {
2982 }
2983 
2984 static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
2985 {
2986     tcg_gen_insn_start(dcbase->pc_next);
2987 }
2988 
2989 static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
2990 {
2991     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2992     CPUAlphaState *env = cpu->env_ptr;
2993     uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
2994 
2995     ctx->base.pc_next += 4;
2996     ctx->base.is_jmp = translate_one(ctx, insn);
2997 
2998     free_context_temps(ctx);
2999     translator_loop_temp_check(&ctx->base);
3000 }
3001 
3002 static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
3003 {
3004     DisasContext *ctx = container_of(dcbase, DisasContext, base);
3005 
3006     switch (ctx->base.is_jmp) {
3007     case DISAS_NORETURN:
3008         break;
3009     case DISAS_TOO_MANY:
3010         if (use_goto_tb(ctx, ctx->base.pc_next)) {
3011             tcg_gen_goto_tb(0);
3012             tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
3013             tcg_gen_exit_tb(ctx->base.tb, 0);
3014         }
3015         /* FALLTHRU */
3016     case DISAS_PC_STALE:
3017         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
3018         /* FALLTHRU */
3019     case DISAS_PC_UPDATED:
3020         tcg_gen_lookup_and_goto_ptr();
3021         break;
3022     case DISAS_PC_UPDATED_NOCHAIN:
3023         tcg_gen_exit_tb(NULL, 0);
3024         break;
3025     default:
3026         g_assert_not_reached();
3027     }
3028 }
3029 
3030 static void alpha_tr_disas_log(const DisasContextBase *dcbase,
3031                                CPUState *cpu, FILE *logfile)
3032 {
3033     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
3034     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
3035 }
3036 
3037 static const TranslatorOps alpha_tr_ops = {
3038     .init_disas_context = alpha_tr_init_disas_context,
3039     .tb_start           = alpha_tr_tb_start,
3040     .insn_start         = alpha_tr_insn_start,
3041     .translate_insn     = alpha_tr_translate_insn,
3042     .tb_stop            = alpha_tr_tb_stop,
3043     .disas_log          = alpha_tr_disas_log,
3044 };
3045 
3046 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
3047 {
3048     DisasContext dc;
3049     translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
3050 }
3051 
3052 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
3053                           target_ulong *data)
3054 {
3055     env->pc = data[0];
3056 }
3057