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