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