Factorize code in translate.c
[qemu] / 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24
25 #include "cpu.h"
26 #include "exec-all.h"
27 #include "disas.h"
28 #include "tcg-op.h"
29 #include "qemu-common.h"
30
31 #define DO_SINGLE_STEP
32 #define GENERATE_NOP
33 #define ALPHA_DEBUG_DISAS
34 #define DO_TB_FLUSH
35
36 typedef struct DisasContext DisasContext;
37 struct DisasContext {
38     uint64_t pc;
39     int mem_idx;
40 #if !defined (CONFIG_USER_ONLY)
41     int pal_mode;
42 #endif
43     uint32_t amask;
44 };
45
46 static always_inline void gen_op_nop (void)
47 {
48 #if defined(GENERATE_NOP)
49     gen_op_no_op();
50 #endif
51 }
52
53 #define GEN32(func, NAME) \
54 static GenOpFunc *NAME ## _table [32] = {                                     \
55 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
56 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
57 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
58 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
59 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
60 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
61 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
62 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
63 };                                                                            \
64 static always_inline void func (int n)                                        \
65 {                                                                             \
66     NAME ## _table[n]();                                                      \
67 }
68
69 /* IR moves */
70 /* Special hacks for ir31 */
71 #define gen_op_load_T0_ir31 gen_op_reset_T0
72 #define gen_op_load_T1_ir31 gen_op_reset_T1
73 #define gen_op_load_T2_ir31 gen_op_reset_T2
74 #define gen_op_store_T0_ir31 gen_op_nop
75 #define gen_op_store_T1_ir31 gen_op_nop
76 #define gen_op_store_T2_ir31 gen_op_nop
77 #define gen_op_cmov_ir31 gen_op_nop
78 GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir);
79 GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir);
80 GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir);
81 GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir);
82 GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir);
83 GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir);
84 GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
85
86 static always_inline void gen_load_ir (DisasContext *ctx, int irn, int Tn)
87 {
88     switch (Tn) {
89     case 0:
90         gen_op_load_T0_ir(irn);
91         break;
92     case 1:
93         gen_op_load_T1_ir(irn);
94         break;
95     case 2:
96         gen_op_load_T2_ir(irn);
97         break;
98     }
99 }
100
101 static always_inline void gen_store_ir (DisasContext *ctx, int irn, int Tn)
102 {
103     switch (Tn) {
104     case 0:
105         gen_op_store_T0_ir(irn);
106         break;
107     case 1:
108         gen_op_store_T1_ir(irn);
109         break;
110     case 2:
111         gen_op_store_T2_ir(irn);
112         break;
113     }
114 }
115
116 /* FIR moves */
117 /* Special hacks for fir31 */
118 #define gen_op_load_FT0_fir31 gen_op_reset_FT0
119 #define gen_op_load_FT1_fir31 gen_op_reset_FT1
120 #define gen_op_load_FT2_fir31 gen_op_reset_FT2
121 #define gen_op_store_FT0_fir31 gen_op_nop
122 #define gen_op_store_FT1_fir31 gen_op_nop
123 #define gen_op_store_FT2_fir31 gen_op_nop
124 #define gen_op_cmov_fir31 gen_op_nop
125 GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir);
126 GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir);
127 GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir);
128 GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir);
129 GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir);
130 GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir);
131 GEN32(gen_op_cmov_fir, gen_op_cmov_fir);
132
133 static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn)
134 {
135     switch (Tn) {
136     case 0:
137         gen_op_load_FT0_fir(firn);
138         break;
139     case 1:
140         gen_op_load_FT1_fir(firn);
141         break;
142     case 2:
143         gen_op_load_FT2_fir(firn);
144         break;
145     }
146 }
147
148 static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn)
149 {
150     switch (Tn) {
151     case 0:
152         gen_op_store_FT0_fir(firn);
153         break;
154     case 1:
155         gen_op_store_FT1_fir(firn);
156         break;
157     case 2:
158         gen_op_store_FT2_fir(firn);
159         break;
160     }
161 }
162
163 /* Memory moves */
164 #if defined(CONFIG_USER_ONLY)
165 #define OP_LD_TABLE(width)                                                    \
166 static GenOpFunc *gen_op_ld##width[] = {                                      \
167     &gen_op_ld##width##_raw,                                                  \
168 }
169 #define OP_ST_TABLE(width)                                                    \
170 static GenOpFunc *gen_op_st##width[] = {                                      \
171     &gen_op_st##width##_raw,                                                  \
172 }
173 #else
174 #define OP_LD_TABLE(width)                                                    \
175 static GenOpFunc *gen_op_ld##width[] = {                                      \
176     &gen_op_ld##width##_kernel,                                               \
177     &gen_op_ld##width##_executive,                                            \
178     &gen_op_ld##width##_supervisor,                                           \
179     &gen_op_ld##width##_user,                                                 \
180 }
181 #define OP_ST_TABLE(width)                                                    \
182 static GenOpFunc *gen_op_st##width[] = {                                      \
183     &gen_op_st##width##_kernel,                                               \
184     &gen_op_st##width##_executive,                                            \
185     &gen_op_st##width##_supervisor,                                           \
186     &gen_op_st##width##_user,                                                 \
187 }
188 #endif
189
190 #define GEN_LD(width)                                                         \
191 OP_LD_TABLE(width);                                                           \
192 static always_inline void gen_ld##width (DisasContext *ctx)                   \
193 {                                                                             \
194     (*gen_op_ld##width[ctx->mem_idx])();                                      \
195 }
196
197 #define GEN_ST(width)                                                         \
198 OP_ST_TABLE(width);                                                           \
199 static always_inline void gen_st##width (DisasContext *ctx)                   \
200 {                                                                             \
201     (*gen_op_st##width[ctx->mem_idx])();                                      \
202 }
203
204 GEN_LD(bu);
205 GEN_ST(b);
206 GEN_LD(wu);
207 GEN_ST(w);
208 GEN_LD(l);
209 GEN_ST(l);
210 GEN_LD(q);
211 GEN_ST(q);
212 GEN_LD(q_u);
213 GEN_ST(q_u);
214 GEN_LD(l_l);
215 GEN_ST(l_c);
216 GEN_LD(q_l);
217 GEN_ST(q_c);
218
219 #if 0 /* currently unused */
220 GEN_LD(f);
221 GEN_ST(f);
222 GEN_LD(g);
223 GEN_ST(g);
224 #endif /* 0 */
225 GEN_LD(s);
226 GEN_ST(s);
227 GEN_LD(t);
228 GEN_ST(t);
229
230 #if defined(__i386__) || defined(__x86_64__)
231 static always_inline void gen_op_set_s16_T0 (int16_t imm)
232 {
233     gen_op_set_s32_T0((int32_t)imm);
234 }
235
236 static always_inline void gen_op_set_s16_T1 (int16_t imm)
237 {
238     gen_op_set_s32_T1((int32_t)imm);
239 }
240
241 static always_inline void gen_op_set_u16_T0 (uint16_t imm)
242 {
243     gen_op_set_s32_T0((uint32_t)imm);
244 }
245
246 static always_inline void gen_op_set_u16_T1 (uint16_t imm)
247 {
248     gen_op_set_s32_T1((uint32_t)imm);
249 }
250 #endif
251
252 static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
253 {
254     int32_t imm32;
255     int16_t imm16;
256
257     imm32 = imm;
258     if (imm32 == imm) {
259         imm16 = imm;
260         if (imm16 == imm) {
261             if (imm == 0) {
262                 gen_op_reset_T0();
263             } else {
264                 gen_op_set_s16_T0(imm16);
265             }
266         } else {
267             gen_op_set_s32_T0(imm32);
268         }
269     } else {
270 #if 0 // Qemu does not know how to do this...
271         gen_op_set_64_T0(imm);
272 #else
273         gen_op_set_64_T0(imm >> 32, imm);
274 #endif
275     }
276 }
277
278 static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
279 {
280     int32_t imm32;
281     int16_t imm16;
282
283     imm32 = imm;
284     if (imm32 == imm) {
285         imm16 = imm;
286         if (imm16 == imm) {
287             if (imm == 0) {
288                 gen_op_reset_T1();
289             } else {
290                 gen_op_set_s16_T1(imm16);
291             }
292         } else {
293             gen_op_set_s32_T1(imm32);
294         }
295     } else {
296 #if 0 // Qemu does not know how to do this...
297         gen_op_set_64_T1(imm);
298 #else
299         gen_op_set_64_T1(imm >> 32, imm);
300 #endif
301     }
302 }
303
304 static always_inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm)
305 {
306     if (!(imm >> 32)) {
307         if ((!imm >> 16)) {
308             if (imm == 0)
309                 gen_op_reset_T0();
310             else
311                 gen_op_set_u16_T0(imm);
312         } else {
313             gen_op_set_u32_T0(imm);
314         }
315     } else {
316 #if 0 // Qemu does not know how to do this...
317         gen_op_set_64_T0(imm);
318 #else
319         gen_op_set_64_T0(imm >> 32, imm);
320 #endif
321     }
322 }
323
324 static always_inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm)
325 {
326     if (!(imm >> 32)) {
327         if ((!imm >> 16)) {
328             if (imm == 0)
329                 gen_op_reset_T1();
330             else
331                 gen_op_set_u16_T1(imm);
332         } else {
333             gen_op_set_u32_T1(imm);
334         }
335     } else {
336 #if 0 // Qemu does not know how to do this...
337         gen_op_set_64_T1(imm);
338 #else
339         gen_op_set_64_T1(imm >> 32, imm);
340 #endif
341     }
342 }
343
344 static always_inline void gen_update_pc (DisasContext *ctx)
345 {
346     if (!(ctx->pc >> 32)) {
347         gen_op_update_pc32(ctx->pc);
348     } else {
349 #if 0 // Qemu does not know how to do this...
350         gen_op_update_pc(ctx->pc);
351 #else
352         gen_op_update_pc(ctx->pc >> 32, ctx->pc);
353 #endif
354     }
355 }
356
357 static always_inline void _gen_op_bcond (DisasContext *ctx)
358 {
359 #if 0 // Qemu does not know how to do this...
360     gen_op_bcond(ctx->pc);
361 #else
362     gen_op_bcond(ctx->pc >> 32, ctx->pc);
363 #endif
364 }
365
366 static always_inline void gen_excp (DisasContext *ctx,
367                                     int exception, int error_code)
368 {
369     gen_update_pc(ctx);
370     gen_op_excp(exception, error_code);
371 }
372
373 static always_inline void gen_invalid (DisasContext *ctx)
374 {
375     gen_excp(ctx, EXCP_OPCDEC, 0);
376 }
377
378 static always_inline void gen_load_mem (DisasContext *ctx,
379                                         void (*gen_load_op)(DisasContext *ctx),
380                                         int ra, int rb, int32_t disp16,
381                                         int clear)
382 {
383     if (ra == 31 && disp16 == 0) {
384         /* UNOP */
385         gen_op_nop();
386     } else {
387         gen_load_ir(ctx, rb, 0);
388         if (disp16 != 0) {
389             gen_set_sT1(ctx, disp16);
390             gen_op_addq();
391         }
392         if (clear)
393             gen_op_n7();
394         (*gen_load_op)(ctx);
395         gen_store_ir(ctx, ra, 1);
396     }
397 }
398
399 static always_inline void gen_store_mem (DisasContext *ctx,
400                                          void (*gen_store_op)(DisasContext *ctx),
401                                          int ra, int rb, int32_t disp16,
402                                          int clear)
403 {
404     gen_load_ir(ctx, rb, 0);
405     if (disp16 != 0) {
406         gen_set_sT1(ctx, disp16);
407         gen_op_addq();
408     }
409     if (clear)
410         gen_op_n7();
411     gen_load_ir(ctx, ra, 1);
412     (*gen_store_op)(ctx);
413 }
414
415 static always_inline void gen_load_fmem (DisasContext *ctx,
416                                          void (*gen_load_fop)(DisasContext *ctx),
417                                          int ra, int rb, int32_t disp16)
418 {
419     gen_load_ir(ctx, rb, 0);
420     if (disp16 != 0) {
421         gen_set_sT1(ctx, disp16);
422         gen_op_addq();
423     }
424     (*gen_load_fop)(ctx);
425     gen_store_fir(ctx, ra, 1);
426 }
427
428 static always_inline void gen_store_fmem (DisasContext *ctx,
429                                           void (*gen_store_fop)(DisasContext *ctx),
430                                           int ra, int rb, int32_t disp16)
431 {
432     gen_load_ir(ctx, rb, 0);
433     if (disp16 != 0) {
434         gen_set_sT1(ctx, disp16);
435         gen_op_addq();
436     }
437     gen_load_fir(ctx, ra, 1);
438     (*gen_store_fop)(ctx);
439 }
440
441 static always_inline void gen_bcond (DisasContext *ctx,
442                                      void (*gen_test_op)(void),
443                                      int ra, int32_t disp16)
444 {
445     if (disp16 != 0) {
446         gen_set_uT0(ctx, ctx->pc);
447         gen_set_sT1(ctx, disp16 << 2);
448         gen_op_addq1();
449     } else {
450         gen_set_uT1(ctx, ctx->pc);
451     }
452     gen_load_ir(ctx, ra, 0);
453     (*gen_test_op)();
454     _gen_op_bcond(ctx);
455 }
456
457 static always_inline void gen_fbcond (DisasContext *ctx,
458                                       void (*gen_test_op)(void),
459                                       int ra, int32_t disp16)
460 {
461     if (disp16 != 0) {
462         gen_set_uT0(ctx, ctx->pc);
463         gen_set_sT1(ctx, disp16 << 2);
464         gen_op_addq1();
465     } else {
466         gen_set_uT1(ctx, ctx->pc);
467     }
468     gen_load_fir(ctx, ra, 0);
469     (*gen_test_op)();
470     _gen_op_bcond(ctx);
471 }
472
473 static always_inline void gen_arith2 (DisasContext *ctx,
474                                       void (*gen_arith_op)(void),
475                                       int rb, int rc, int islit, int8_t lit)
476 {
477     if (islit)
478         gen_set_sT0(ctx, lit);
479     else
480         gen_load_ir(ctx, rb, 0);
481     (*gen_arith_op)();
482     gen_store_ir(ctx, rc, 0);
483 }
484
485 static always_inline void gen_arith3 (DisasContext *ctx,
486                                       void (*gen_arith_op)(void),
487                                       int ra, int rb, int rc,
488                                       int islit, int8_t lit)
489 {
490     gen_load_ir(ctx, ra, 0);
491     if (islit)
492         gen_set_sT1(ctx, lit);
493     else
494         gen_load_ir(ctx, rb, 1);
495     (*gen_arith_op)();
496     gen_store_ir(ctx, rc, 0);
497 }
498
499 static always_inline void gen_cmov (DisasContext *ctx,
500                                     void (*gen_test_op)(void),
501                                     int ra, int rb, int rc,
502                                     int islit, int8_t lit)
503 {
504     gen_load_ir(ctx, ra, 1);
505     if (islit)
506         gen_set_sT0(ctx, lit);
507     else
508         gen_load_ir(ctx, rb, 0);
509     (*gen_test_op)();
510     gen_op_cmov_ir(rc);
511 }
512
513 static always_inline void gen_farith2 (DisasContext *ctx,
514                                        void (*gen_arith_fop)(void),
515                                        int rb, int rc)
516 {
517     gen_load_fir(ctx, rb, 0);
518     (*gen_arith_fop)();
519     gen_store_fir(ctx, rc, 0);
520 }
521
522 static always_inline void gen_farith3 (DisasContext *ctx,
523                                        void (*gen_arith_fop)(void),
524                                        int ra, int rb, int rc)
525 {
526     gen_load_fir(ctx, ra, 0);
527     gen_load_fir(ctx, rb, 1);
528     (*gen_arith_fop)();
529     gen_store_fir(ctx, rc, 0);
530 }
531
532 static always_inline void gen_fcmov (DisasContext *ctx,
533                                      void (*gen_test_fop)(void),
534                                      int ra, int rb, int rc)
535 {
536     gen_load_fir(ctx, ra, 0);
537     gen_load_fir(ctx, rb, 1);
538     (*gen_test_fop)();
539     gen_op_cmov_fir(rc);
540 }
541
542 static always_inline void gen_fti (DisasContext *ctx,
543                                    void (*gen_move_fop)(void),
544                                    int ra, int rc)
545 {
546     gen_load_fir(ctx, rc, 0);
547     (*gen_move_fop)();
548     gen_store_ir(ctx, ra, 0);
549 }
550
551 static always_inline void gen_itf (DisasContext *ctx,
552                                    void (*gen_move_fop)(void),
553                                    int ra, int rc)
554 {
555     gen_load_ir(ctx, ra, 0);
556     (*gen_move_fop)();
557     gen_store_fir(ctx, rc, 0);
558 }
559
560 static always_inline void gen_s4addl (void)
561 {
562     gen_op_s4();
563     gen_op_addl();
564 }
565
566 static always_inline void gen_s4subl (void)
567 {
568     gen_op_s4();
569     gen_op_subl();
570 }
571
572 static always_inline void gen_s8addl (void)
573 {
574     gen_op_s8();
575     gen_op_addl();
576 }
577
578 static always_inline void gen_s8subl (void)
579 {
580     gen_op_s8();
581     gen_op_subl();
582 }
583
584 static always_inline void gen_s4addq (void)
585 {
586     gen_op_s4();
587     gen_op_addq();
588 }
589
590 static always_inline void gen_s4subq (void)
591 {
592     gen_op_s4();
593     gen_op_subq();
594 }
595
596 static always_inline void gen_s8addq (void)
597 {
598     gen_op_s8();
599     gen_op_addq();
600 }
601
602 static always_inline void gen_s8subq (void)
603 {
604     gen_op_s8();
605     gen_op_subq();
606 }
607
608 static always_inline void gen_amask (void)
609 {
610     gen_op_load_amask();
611     gen_op_bic();
612 }
613
614 static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
615 {
616     uint32_t palcode;
617     int32_t disp21, disp16, disp12;
618     uint16_t fn11, fn16;
619     uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
620     int8_t lit;
621     int ret;
622
623     /* Decode all instruction fields */
624     opc = insn >> 26;
625     ra = (insn >> 21) & 0x1F;
626     rb = (insn >> 16) & 0x1F;
627     rc = insn & 0x1F;
628     sbz = (insn >> 13) & 0x07;
629     islit = (insn >> 12) & 1;
630     lit = (insn >> 13) & 0xFF;
631     palcode = insn & 0x03FFFFFF;
632     disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
633     disp16 = (int16_t)(insn & 0x0000FFFF);
634     disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
635     fn16 = insn & 0x0000FFFF;
636     fn11 = (insn >> 5) & 0x000007FF;
637     fpfn = fn11 & 0x3F;
638     fn7 = (insn >> 5) & 0x0000007F;
639     fn2 = (insn >> 5) & 0x00000003;
640     ret = 0;
641 #if defined ALPHA_DEBUG_DISAS
642     if (logfile != NULL) {
643         fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
644                 opc, ra, rb, rc, disp16);
645     }
646 #endif
647     switch (opc) {
648     case 0x00:
649         /* CALL_PAL */
650         if (palcode >= 0x80 && palcode < 0xC0) {
651             /* Unprivileged PAL call */
652             gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
653 #if !defined (CONFIG_USER_ONLY)
654         } else if (palcode < 0x40) {
655             /* Privileged PAL code */
656             if (ctx->mem_idx & 1)
657                 goto invalid_opc;
658             else
659                 gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
660 #endif
661         } else {
662             /* Invalid PAL call */
663             goto invalid_opc;
664         }
665         ret = 3;
666         break;
667     case 0x01:
668         /* OPC01 */
669         goto invalid_opc;
670     case 0x02:
671         /* OPC02 */
672         goto invalid_opc;
673     case 0x03:
674         /* OPC03 */
675         goto invalid_opc;
676     case 0x04:
677         /* OPC04 */
678         goto invalid_opc;
679     case 0x05:
680         /* OPC05 */
681         goto invalid_opc;
682     case 0x06:
683         /* OPC06 */
684         goto invalid_opc;
685     case 0x07:
686         /* OPC07 */
687         goto invalid_opc;
688     case 0x08:
689         /* LDA */
690         gen_load_ir(ctx, rb, 0);
691         gen_set_sT1(ctx, disp16);
692         gen_op_addq();
693         gen_store_ir(ctx, ra, 0);
694         break;
695     case 0x09:
696         /* LDAH */
697         gen_load_ir(ctx, rb, 0);
698         gen_set_sT1(ctx, disp16 << 16);
699         gen_op_addq();
700         gen_store_ir(ctx, ra, 0);
701         break;
702     case 0x0A:
703         /* LDBU */
704         if (!(ctx->amask & AMASK_BWX))
705             goto invalid_opc;
706         gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0);
707         break;
708     case 0x0B:
709         /* LDQ_U */
710         gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1);
711         break;
712     case 0x0C:
713         /* LDWU */
714         if (!(ctx->amask & AMASK_BWX))
715             goto invalid_opc;
716         gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0);
717         break;
718     case 0x0D:
719         /* STW */
720         if (!(ctx->amask & AMASK_BWX))
721             goto invalid_opc;
722         gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0);
723         break;
724     case 0x0E:
725         /* STB */
726         if (!(ctx->amask & AMASK_BWX))
727             goto invalid_opc;
728         gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0);
729         break;
730     case 0x0F:
731         /* STQ_U */
732         gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1);
733         break;
734     case 0x10:
735         switch (fn7) {
736         case 0x00:
737             /* ADDL */
738             gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
739             break;
740         case 0x02:
741             /* S4ADDL */
742             gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
743             break;
744         case 0x09:
745             /* SUBL */
746             gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
747             break;
748         case 0x0B:
749             /* S4SUBL */
750             gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
751             break;
752         case 0x0F:
753             /* CMPBGE */
754             gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit);
755             break;
756         case 0x12:
757             /* S8ADDL */
758             gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
759             break;
760         case 0x1B:
761             /* S8SUBL */
762             gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
763             break;
764         case 0x1D:
765             /* CMPULT */
766             gen_arith3(ctx, &gen_op_cmpult, ra, rb, rc, islit, lit);
767             break;
768         case 0x20:
769             /* ADDQ */
770             gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
771             break;
772         case 0x22:
773             /* S4ADDQ */
774             gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
775             break;
776         case 0x29:
777             /* SUBQ */
778             gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
779             break;
780         case 0x2B:
781             /* S4SUBQ */
782             gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
783             break;
784         case 0x2D:
785             /* CMPEQ */
786             gen_arith3(ctx, &gen_op_cmpeq, ra, rb, rc, islit, lit);
787             break;
788         case 0x32:
789             /* S8ADDQ */
790             gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
791             break;
792         case 0x3B:
793             /* S8SUBQ */
794             gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
795             break;
796         case 0x3D:
797             /* CMPULE */
798             gen_arith3(ctx, &gen_op_cmpule, ra, rb, rc, islit, lit);
799             break;
800         case 0x40:
801             /* ADDL/V */
802             gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit);
803             break;
804         case 0x49:
805             /* SUBL/V */
806             gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit);
807             break;
808         case 0x4D:
809             /* CMPLT */
810             gen_arith3(ctx, &gen_op_cmplt, ra, rb, rc, islit, lit);
811             break;
812         case 0x60:
813             /* ADDQ/V */
814             gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit);
815             break;
816         case 0x69:
817             /* SUBQ/V */
818             gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit);
819             break;
820         case 0x6D:
821             /* CMPLE */
822             gen_arith3(ctx, &gen_op_cmple, ra, rb, rc, islit, lit);
823             break;
824         default:
825             goto invalid_opc;
826         }
827         break;
828     case 0x11:
829         switch (fn7) {
830         case 0x00:
831             /* AND */
832             gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
833             break;
834         case 0x08:
835             /* BIC */
836             gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
837             break;
838         case 0x14:
839             /* CMOVLBS */
840             gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit);
841             break;
842         case 0x16:
843             /* CMOVLBC */
844             gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit);
845             break;
846         case 0x20:
847             /* BIS */
848             if (ra == rb || ra == 31 || rb == 31) {
849                 if (ra == 31 && rc == 31) {
850                     /* NOP */
851                     gen_op_nop();
852                 } else {
853                     /* MOV */
854                     gen_load_ir(ctx, rb, 0);
855                     gen_store_ir(ctx, rc, 0);
856                 }
857             } else {
858                 gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
859             }
860             break;
861         case 0x24:
862             /* CMOVEQ */
863             gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit);
864             break;
865         case 0x26:
866             /* CMOVNE */
867             gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit);
868             break;
869         case 0x28:
870             /* ORNOT */
871             gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
872             break;
873         case 0x40:
874             /* XOR */
875             gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
876             break;
877         case 0x44:
878             /* CMOVLT */
879             gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit);
880             break;
881         case 0x46:
882             /* CMOVGE */
883             gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit);
884             break;
885         case 0x48:
886             /* EQV */
887             gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
888             break;
889         case 0x61:
890             /* AMASK */
891             gen_arith2(ctx, &gen_amask, rb, rc, islit, lit);
892             break;
893         case 0x64:
894             /* CMOVLE */
895             gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit);
896             break;
897         case 0x66:
898             /* CMOVGT */
899             gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit);
900             break;
901         case 0x6C:
902             /* IMPLVER */
903             gen_op_load_implver();
904             gen_store_ir(ctx, rc, 0);
905             break;
906         default:
907             goto invalid_opc;
908         }
909         break;
910     case 0x12:
911         switch (fn7) {
912         case 0x02:
913             /* MSKBL */
914             gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit);
915             break;
916         case 0x06:
917             /* EXTBL */
918             gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit);
919             break;
920         case 0x0B:
921             /* INSBL */
922             gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit);
923             break;
924         case 0x12:
925             /* MSKWL */
926             gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit);
927             break;
928         case 0x16:
929             /* EXTWL */
930             gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit);
931             break;
932         case 0x1B:
933             /* INSWL */
934             gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit);
935             break;
936         case 0x22:
937             /* MSKLL */
938             gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit);
939             break;
940         case 0x26:
941             /* EXTLL */
942             gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit);
943             break;
944         case 0x2B:
945             /* INSLL */
946             gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit);
947             break;
948         case 0x30:
949             /* ZAP */
950             gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit);
951             break;
952         case 0x31:
953             /* ZAPNOT */
954             gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit);
955             break;
956         case 0x32:
957             /* MSKQL */
958             gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit);
959             break;
960         case 0x34:
961             /* SRL */
962             gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
963             break;
964         case 0x36:
965             /* EXTQL */
966             gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit);
967             break;
968         case 0x39:
969             /* SLL */
970             gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
971             break;
972         case 0x3B:
973             /* INSQL */
974             gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit);
975             break;
976         case 0x3C:
977             /* SRA */
978             gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
979             break;
980         case 0x52:
981             /* MSKWH */
982             gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit);
983             break;
984         case 0x57:
985             /* INSWH */
986             gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit);
987             break;
988         case 0x5A:
989             /* EXTWH */
990             gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit);
991             break;
992         case 0x62:
993             /* MSKLH */
994             gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit);
995             break;
996         case 0x67:
997             /* INSLH */
998             gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit);
999             break;
1000         case 0x6A:
1001             /* EXTLH */
1002             gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit);
1003             break;
1004         case 0x72:
1005             /* MSKQH */
1006             gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit);
1007             break;
1008         case 0x77:
1009             /* INSQH */
1010             gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit);
1011             break;
1012         case 0x7A:
1013             /* EXTQH */
1014             gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit);
1015             break;
1016         default:
1017             goto invalid_opc;
1018         }
1019         break;
1020     case 0x13:
1021         switch (fn7) {
1022         case 0x00:
1023             /* MULL */
1024             gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
1025             break;
1026         case 0x20:
1027             /* MULQ */
1028             gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
1029             break;
1030         case 0x30:
1031             /* UMULH */
1032             gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit);
1033             break;
1034         case 0x40:
1035             /* MULL/V */
1036             gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit);
1037             break;
1038         case 0x60:
1039             /* MULQ/V */
1040             gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit);
1041             break;
1042         default:
1043             goto invalid_opc;
1044         }
1045         break;
1046     case 0x14:
1047         switch (fpfn) { /* f11 & 0x3F */
1048         case 0x04:
1049             /* ITOFS */
1050             if (!(ctx->amask & AMASK_FIX))
1051                 goto invalid_opc;
1052             gen_itf(ctx, &gen_op_itofs, ra, rc);
1053             break;
1054         case 0x0A:
1055             /* SQRTF */
1056             if (!(ctx->amask & AMASK_FIX))
1057                 goto invalid_opc;
1058             gen_farith2(ctx, &gen_op_sqrtf, rb, rc);
1059             break;
1060         case 0x0B:
1061             /* SQRTS */
1062             if (!(ctx->amask & AMASK_FIX))
1063                 goto invalid_opc;
1064             gen_farith2(ctx, &gen_op_sqrts, rb, rc);
1065             break;
1066         case 0x14:
1067             /* ITOFF */
1068             if (!(ctx->amask & AMASK_FIX))
1069                 goto invalid_opc;
1070 #if 0 // TODO
1071             gen_itf(ctx, &gen_op_itoff, ra, rc);
1072 #else
1073             goto invalid_opc;
1074 #endif
1075             break;
1076         case 0x24:
1077             /* ITOFT */
1078             if (!(ctx->amask & AMASK_FIX))
1079                 goto invalid_opc;
1080             gen_itf(ctx, &gen_op_itoft, ra, rc);
1081             break;
1082         case 0x2A:
1083             /* SQRTG */
1084             if (!(ctx->amask & AMASK_FIX))
1085                 goto invalid_opc;
1086             gen_farith2(ctx, &gen_op_sqrtg, rb, rc);
1087             break;
1088         case 0x02B:
1089             /* SQRTT */
1090             if (!(ctx->amask & AMASK_FIX))
1091                 goto invalid_opc;
1092             gen_farith2(ctx, &gen_op_sqrtt, rb, rc);
1093             break;
1094         default:
1095             goto invalid_opc;
1096         }
1097         break;
1098     case 0x15:
1099         /* VAX floating point */
1100         /* XXX: rounding mode and trap are ignored (!) */
1101         switch (fpfn) { /* f11 & 0x3F */
1102         case 0x00:
1103             /* ADDF */
1104             gen_farith3(ctx, &gen_op_addf, ra, rb, rc);
1105             break;
1106         case 0x01:
1107             /* SUBF */
1108             gen_farith3(ctx, &gen_op_subf, ra, rb, rc);
1109             break;
1110         case 0x02:
1111             /* MULF */
1112             gen_farith3(ctx, &gen_op_mulf, ra, rb, rc);
1113             break;
1114         case 0x03:
1115             /* DIVF */
1116             gen_farith3(ctx, &gen_op_divf, ra, rb, rc);
1117             break;
1118         case 0x1E:
1119             /* CVTDG */
1120 #if 0 // TODO
1121             gen_farith2(ctx, &gen_op_cvtdg, rb, rc);
1122 #else
1123             goto invalid_opc;
1124 #endif
1125             break;
1126         case 0x20:
1127             /* ADDG */
1128             gen_farith3(ctx, &gen_op_addg, ra, rb, rc);
1129             break;
1130         case 0x21:
1131             /* SUBG */
1132             gen_farith3(ctx, &gen_op_subg, ra, rb, rc);
1133             break;
1134         case 0x22:
1135             /* MULG */
1136             gen_farith3(ctx, &gen_op_mulg, ra, rb, rc);
1137             break;
1138         case 0x23:
1139             /* DIVG */
1140             gen_farith3(ctx, &gen_op_divg, ra, rb, rc);
1141             break;
1142         case 0x25:
1143             /* CMPGEQ */
1144             gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc);
1145             break;
1146         case 0x26:
1147             /* CMPGLT */
1148             gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc);
1149             break;
1150         case 0x27:
1151             /* CMPGLE */
1152             gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc);
1153             break;
1154         case 0x2C:
1155             /* CVTGF */
1156             gen_farith2(ctx, &gen_op_cvtgf, rb, rc);
1157             break;
1158         case 0x2D:
1159             /* CVTGD */
1160 #if 0 // TODO
1161             gen_farith2(ctx, &gen_op_cvtgd, rb, rc);
1162 #else
1163             goto invalid_opc;
1164 #endif
1165             break;
1166         case 0x2F:
1167             /* CVTGQ */
1168             gen_farith2(ctx, &gen_op_cvtgq, rb, rc);
1169             break;
1170         case 0x3C:
1171             /* CVTQF */
1172             gen_farith2(ctx, &gen_op_cvtqf, rb, rc);
1173             break;
1174         case 0x3E:
1175             /* CVTQG */
1176             gen_farith2(ctx, &gen_op_cvtqg, rb, rc);
1177             break;
1178         default:
1179             goto invalid_opc;
1180         }
1181         break;
1182     case 0x16:
1183         /* IEEE floating-point */
1184         /* XXX: rounding mode and traps are ignored (!) */
1185         switch (fpfn) { /* f11 & 0x3F */
1186         case 0x00:
1187             /* ADDS */
1188             gen_farith3(ctx, &gen_op_adds, ra, rb, rc);
1189             break;
1190         case 0x01:
1191             /* SUBS */
1192             gen_farith3(ctx, &gen_op_subs, ra, rb, rc);
1193             break;
1194         case 0x02:
1195             /* MULS */
1196             gen_farith3(ctx, &gen_op_muls, ra, rb, rc);
1197             break;
1198         case 0x03:
1199             /* DIVS */
1200             gen_farith3(ctx, &gen_op_divs, ra, rb, rc);
1201             break;
1202         case 0x20:
1203             /* ADDT */
1204             gen_farith3(ctx, &gen_op_addt, ra, rb, rc);
1205             break;
1206         case 0x21:
1207             /* SUBT */
1208             gen_farith3(ctx, &gen_op_subt, ra, rb, rc);
1209             break;
1210         case 0x22:
1211             /* MULT */
1212             gen_farith3(ctx, &gen_op_mult, ra, rb, rc);
1213             break;
1214         case 0x23:
1215             /* DIVT */
1216             gen_farith3(ctx, &gen_op_divt, ra, rb, rc);
1217             break;
1218         case 0x24:
1219             /* CMPTUN */
1220             gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc);
1221             break;
1222         case 0x25:
1223             /* CMPTEQ */
1224             gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc);
1225             break;
1226         case 0x26:
1227             /* CMPTLT */
1228             gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc);
1229             break;
1230         case 0x27:
1231             /* CMPTLE */
1232             gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc);
1233             break;
1234         case 0x2C:
1235             /* XXX: incorrect */
1236             if (fn11 == 0x2AC) {
1237                 /* CVTST */
1238                 gen_farith2(ctx, &gen_op_cvtst, rb, rc);
1239             } else {
1240                 /* CVTTS */
1241                 gen_farith2(ctx, &gen_op_cvtts, rb, rc);
1242             }
1243             break;
1244         case 0x2F:
1245             /* CVTTQ */
1246             gen_farith2(ctx, &gen_op_cvttq, rb, rc);
1247             break;
1248         case 0x3C:
1249             /* CVTQS */
1250             gen_farith2(ctx, &gen_op_cvtqs, rb, rc);
1251             break;
1252         case 0x3E:
1253             /* CVTQT */
1254             gen_farith2(ctx, &gen_op_cvtqt, rb, rc);
1255             break;
1256         default:
1257             goto invalid_opc;
1258         }
1259         break;
1260     case 0x17:
1261         switch (fn11) {
1262         case 0x010:
1263             /* CVTLQ */
1264             gen_farith2(ctx, &gen_op_cvtlq, rb, rc);
1265             break;
1266         case 0x020:
1267             /* CPYS */
1268             if (ra == rb) {
1269                 if (ra == 31 && rc == 31) {
1270                     /* FNOP */
1271                     gen_op_nop();
1272                 } else {
1273                     /* FMOV */
1274                     gen_load_fir(ctx, rb, 0);
1275                     gen_store_fir(ctx, rc, 0);
1276                 }
1277             } else {
1278                 gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
1279             }
1280             break;
1281         case 0x021:
1282             /* CPYSN */
1283             gen_farith2(ctx, &gen_op_cpysn, rb, rc);
1284             break;
1285         case 0x022:
1286             /* CPYSE */
1287             gen_farith2(ctx, &gen_op_cpyse, rb, rc);
1288             break;
1289         case 0x024:
1290             /* MT_FPCR */
1291             gen_load_fir(ctx, ra, 0);
1292             gen_op_store_fpcr();
1293             break;
1294         case 0x025:
1295             /* MF_FPCR */
1296             gen_op_load_fpcr();
1297             gen_store_fir(ctx, ra, 0);
1298             break;
1299         case 0x02A:
1300             /* FCMOVEQ */
1301             gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc);
1302             break;
1303         case 0x02B:
1304             /* FCMOVNE */
1305             gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc);
1306             break;
1307         case 0x02C:
1308             /* FCMOVLT */
1309             gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc);
1310             break;
1311         case 0x02D:
1312             /* FCMOVGE */
1313             gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc);
1314             break;
1315         case 0x02E:
1316             /* FCMOVLE */
1317             gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc);
1318             break;
1319         case 0x02F:
1320             /* FCMOVGT */
1321             gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc);
1322             break;
1323         case 0x030:
1324             /* CVTQL */
1325             gen_farith2(ctx, &gen_op_cvtql, rb, rc);
1326             break;
1327         case 0x130:
1328             /* CVTQL/V */
1329             gen_farith2(ctx, &gen_op_cvtqlv, rb, rc);
1330             break;
1331         case 0x530:
1332             /* CVTQL/SV */
1333             gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc);
1334             break;
1335         default:
1336             goto invalid_opc;
1337         }
1338         break;
1339     case 0x18:
1340         switch ((uint16_t)disp16) {
1341         case 0x0000:
1342             /* TRAPB */
1343             /* No-op. Just exit from the current tb */
1344             ret = 2;
1345             break;
1346         case 0x0400:
1347             /* EXCB */
1348             /* No-op. Just exit from the current tb */
1349             ret = 2;
1350             break;
1351         case 0x4000:
1352             /* MB */
1353             /* No-op */
1354             break;
1355         case 0x4400:
1356             /* WMB */
1357             /* No-op */
1358             break;
1359         case 0x8000:
1360             /* FETCH */
1361             /* No-op */
1362             break;
1363         case 0xA000:
1364             /* FETCH_M */
1365             /* No-op */
1366             break;
1367         case 0xC000:
1368             /* RPCC */
1369             gen_op_load_pcc();
1370             gen_store_ir(ctx, ra, 0);
1371             break;
1372         case 0xE000:
1373             /* RC */
1374             gen_op_load_irf();
1375             gen_store_ir(ctx, ra, 0);
1376             gen_op_clear_irf();
1377             break;
1378         case 0xE800:
1379             /* ECB */
1380             /* XXX: TODO: evict tb cache at address rb */
1381 #if 0
1382             ret = 2;
1383 #else
1384             goto invalid_opc;
1385 #endif
1386             break;
1387         case 0xF000:
1388             /* RS */
1389             gen_op_load_irf();
1390             gen_store_ir(ctx, ra, 0);
1391             gen_op_set_irf();
1392             break;
1393         case 0xF800:
1394             /* WH64 */
1395             /* No-op */
1396             break;
1397         default:
1398             goto invalid_opc;
1399         }
1400         break;
1401     case 0x19:
1402         /* HW_MFPR (PALcode) */
1403 #if defined (CONFIG_USER_ONLY)
1404         goto invalid_opc;
1405 #else
1406         if (!ctx->pal_mode)
1407             goto invalid_opc;
1408         gen_op_mfpr(insn & 0xFF);
1409         gen_store_ir(ctx, ra, 0);
1410         break;
1411 #endif
1412     case 0x1A:
1413         gen_load_ir(ctx, rb, 0);
1414         if (ra != 31) {
1415             gen_set_uT1(ctx, ctx->pc);
1416             gen_store_ir(ctx, ra, 1);
1417         }
1418         gen_op_branch();
1419         /* Those four jumps only differ by the branch prediction hint */
1420         switch (fn2) {
1421         case 0x0:
1422             /* JMP */
1423             break;
1424         case 0x1:
1425             /* JSR */
1426             break;
1427         case 0x2:
1428             /* RET */
1429             break;
1430         case 0x3:
1431             /* JSR_COROUTINE */
1432             break;
1433         }
1434         ret = 1;
1435         break;
1436     case 0x1B:
1437         /* HW_LD (PALcode) */
1438 #if defined (CONFIG_USER_ONLY)
1439         goto invalid_opc;
1440 #else
1441         if (!ctx->pal_mode)
1442             goto invalid_opc;
1443         gen_load_ir(ctx, rb, 0);
1444         gen_set_sT1(ctx, disp12);
1445         gen_op_addq();
1446         switch ((insn >> 12) & 0xF) {
1447         case 0x0:
1448             /* Longword physical access */
1449             gen_op_ldl_raw();
1450             break;
1451         case 0x1:
1452             /* Quadword physical access */
1453             gen_op_ldq_raw();
1454             break;
1455         case 0x2:
1456             /* Longword physical access with lock */
1457             gen_op_ldl_l_raw();
1458             break;
1459         case 0x3:
1460             /* Quadword physical access with lock */
1461             gen_op_ldq_l_raw();
1462             break;
1463         case 0x4:
1464             /* Longword virtual PTE fetch */
1465             gen_op_ldl_kernel();
1466             break;
1467         case 0x5:
1468             /* Quadword virtual PTE fetch */
1469             gen_op_ldq_kernel();
1470             break;
1471         case 0x6:
1472             /* Invalid */
1473             goto invalid_opc;
1474         case 0x7:
1475             /* Invalid */
1476             goto invalid_opc;
1477         case 0x8:
1478             /* Longword virtual access */
1479             gen_op_ld_phys_to_virt();
1480             gen_op_ldl_raw();
1481             break;
1482         case 0x9:
1483             /* Quadword virtual access */
1484             gen_op_ld_phys_to_virt();
1485             gen_op_ldq_raw();
1486             break;
1487         case 0xA:
1488             /* Longword virtual access with protection check */
1489             gen_ldl(ctx);
1490             break;
1491         case 0xB:
1492             /* Quadword virtual access with protection check */
1493             gen_ldq(ctx);
1494             break;
1495         case 0xC:
1496             /* Longword virtual access with altenate access mode */
1497             gen_op_set_alt_mode();
1498             gen_op_ld_phys_to_virt();
1499             gen_op_ldl_raw();
1500             gen_op_restore_mode();
1501             break;
1502         case 0xD:
1503             /* Quadword virtual access with altenate access mode */
1504             gen_op_set_alt_mode();
1505             gen_op_ld_phys_to_virt();
1506             gen_op_ldq_raw();
1507             gen_op_restore_mode();
1508             break;
1509         case 0xE:
1510             /* Longword virtual access with alternate access mode and
1511              * protection checks
1512              */
1513             gen_op_set_alt_mode();
1514             gen_op_ldl_data();
1515             gen_op_restore_mode();
1516             break;
1517         case 0xF:
1518             /* Quadword virtual access with alternate access mode and
1519              * protection checks
1520              */
1521             gen_op_set_alt_mode();
1522             gen_op_ldq_data();
1523             gen_op_restore_mode();
1524             break;
1525         }
1526         gen_store_ir(ctx, ra, 1);
1527         break;
1528 #endif
1529     case 0x1C:
1530         switch (fn7) {
1531         case 0x00:
1532             /* SEXTB */
1533             if (!(ctx->amask & AMASK_BWX))
1534                 goto invalid_opc;
1535             gen_arith2(ctx, &gen_op_sextb, rb, rc, islit, lit);
1536             break;
1537         case 0x01:
1538             /* SEXTW */
1539             if (!(ctx->amask & AMASK_BWX))
1540                 goto invalid_opc;
1541             gen_arith2(ctx, &gen_op_sextw, rb, rc, islit, lit);
1542             break;
1543         case 0x30:
1544             /* CTPOP */
1545             if (!(ctx->amask & AMASK_CIX))
1546                 goto invalid_opc;
1547             gen_arith2(ctx, &gen_op_ctpop, rb, rc, 0, 0);
1548             break;
1549         case 0x31:
1550             /* PERR */
1551             if (!(ctx->amask & AMASK_MVI))
1552                 goto invalid_opc;
1553             /* XXX: TODO */
1554             goto invalid_opc;
1555             break;
1556         case 0x32:
1557             /* CTLZ */
1558             if (!(ctx->amask & AMASK_CIX))
1559                 goto invalid_opc;
1560             gen_arith2(ctx, &gen_op_ctlz, rb, rc, 0, 0);
1561             break;
1562         case 0x33:
1563             /* CTTZ */
1564             if (!(ctx->amask & AMASK_CIX))
1565                 goto invalid_opc;
1566             gen_arith2(ctx, &gen_op_cttz, rb, rc, 0, 0);
1567             break;
1568         case 0x34:
1569             /* UNPKBW */
1570             if (!(ctx->amask & AMASK_MVI))
1571                 goto invalid_opc;
1572             /* XXX: TODO */
1573             goto invalid_opc;
1574             break;
1575         case 0x35:
1576             /* UNPKWL */
1577             if (!(ctx->amask & AMASK_MVI))
1578                 goto invalid_opc;
1579             /* XXX: TODO */
1580             goto invalid_opc;
1581             break;
1582         case 0x36:
1583             /* PKWB */
1584             if (!(ctx->amask & AMASK_MVI))
1585                 goto invalid_opc;
1586             /* XXX: TODO */
1587             goto invalid_opc;
1588             break;
1589         case 0x37:
1590             /* PKLB */
1591             if (!(ctx->amask & AMASK_MVI))
1592                 goto invalid_opc;
1593             /* XXX: TODO */
1594             goto invalid_opc;
1595             break;
1596         case 0x38:
1597             /* MINSB8 */
1598             if (!(ctx->amask & AMASK_MVI))
1599                 goto invalid_opc;
1600             /* XXX: TODO */
1601             goto invalid_opc;
1602             break;
1603         case 0x39:
1604             /* MINSW4 */
1605             if (!(ctx->amask & AMASK_MVI))
1606                 goto invalid_opc;
1607             /* XXX: TODO */
1608             goto invalid_opc;
1609             break;
1610         case 0x3A:
1611             /* MINUB8 */
1612             if (!(ctx->amask & AMASK_MVI))
1613                 goto invalid_opc;
1614             /* XXX: TODO */
1615             goto invalid_opc;
1616             break;
1617         case 0x3B:
1618             /* MINUW4 */
1619             if (!(ctx->amask & AMASK_MVI))
1620                 goto invalid_opc;
1621             /* XXX: TODO */
1622             goto invalid_opc;
1623             break;
1624         case 0x3C:
1625             /* MAXUB8 */
1626             if (!(ctx->amask & AMASK_MVI))
1627                 goto invalid_opc;
1628             /* XXX: TODO */
1629             goto invalid_opc;
1630             break;
1631         case 0x3D:
1632             /* MAXUW4 */
1633             if (!(ctx->amask & AMASK_MVI))
1634                 goto invalid_opc;
1635             /* XXX: TODO */
1636             goto invalid_opc;
1637             break;
1638         case 0x3E:
1639             /* MAXSB8 */
1640             if (!(ctx->amask & AMASK_MVI))
1641                 goto invalid_opc;
1642             /* XXX: TODO */
1643             goto invalid_opc;
1644             break;
1645         case 0x3F:
1646             /* MAXSW4 */
1647             if (!(ctx->amask & AMASK_MVI))
1648                 goto invalid_opc;
1649             /* XXX: TODO */
1650             goto invalid_opc;
1651             break;
1652         case 0x70:
1653             /* FTOIT */
1654             if (!(ctx->amask & AMASK_FIX))
1655                 goto invalid_opc;
1656             gen_fti(ctx, &gen_op_ftoit, ra, rb);
1657             break;
1658         case 0x78:
1659             /* FTOIS */
1660             if (!(ctx->amask & AMASK_FIX))
1661                 goto invalid_opc;
1662             gen_fti(ctx, &gen_op_ftois, ra, rb);
1663             break;
1664         default:
1665             goto invalid_opc;
1666         }
1667         break;
1668     case 0x1D:
1669         /* HW_MTPR (PALcode) */
1670 #if defined (CONFIG_USER_ONLY)
1671         goto invalid_opc;
1672 #else
1673         if (!ctx->pal_mode)
1674             goto invalid_opc;
1675         gen_load_ir(ctx, ra, 0);
1676         gen_op_mtpr(insn & 0xFF);
1677         ret = 2;
1678         break;
1679 #endif
1680     case 0x1E:
1681         /* HW_REI (PALcode) */
1682 #if defined (CONFIG_USER_ONLY)
1683         goto invalid_opc;
1684 #else
1685         if (!ctx->pal_mode)
1686             goto invalid_opc;
1687         if (rb == 31) {
1688             /* "Old" alpha */
1689             gen_op_hw_rei();
1690         } else {
1691             gen_load_ir(ctx, rb, 0);
1692             gen_set_uT1(ctx, (((int64_t)insn << 51) >> 51));
1693             gen_op_addq();
1694             gen_op_hw_ret();
1695         }
1696         ret = 2;
1697         break;
1698 #endif
1699     case 0x1F:
1700         /* HW_ST (PALcode) */
1701 #if defined (CONFIG_USER_ONLY)
1702         goto invalid_opc;
1703 #else
1704         if (!ctx->pal_mode)
1705             goto invalid_opc;
1706         gen_load_ir(ctx, rb, 0);
1707         gen_set_sT1(ctx, disp12);
1708         gen_op_addq();
1709         gen_load_ir(ctx, ra, 1);
1710         switch ((insn >> 12) & 0xF) {
1711         case 0x0:
1712             /* Longword physical access */
1713             gen_op_stl_raw();
1714             break;
1715         case 0x1:
1716             /* Quadword physical access */
1717             gen_op_stq_raw();
1718             break;
1719         case 0x2:
1720             /* Longword physical access with lock */
1721             gen_op_stl_c_raw();
1722             break;
1723         case 0x3:
1724             /* Quadword physical access with lock */
1725             gen_op_stq_c_raw();
1726             break;
1727         case 0x4:
1728             /* Longword virtual access */
1729             gen_op_st_phys_to_virt();
1730             gen_op_stl_raw();
1731             break;
1732         case 0x5:
1733             /* Quadword virtual access */
1734             gen_op_st_phys_to_virt();
1735             gen_op_stq_raw();
1736             break;
1737         case 0x6:
1738             /* Invalid */
1739             goto invalid_opc;
1740         case 0x7:
1741             /* Invalid */
1742             goto invalid_opc;
1743         case 0x8:
1744             /* Invalid */
1745             goto invalid_opc;
1746         case 0x9:
1747             /* Invalid */
1748             goto invalid_opc;
1749         case 0xA:
1750             /* Invalid */
1751             goto invalid_opc;
1752         case 0xB:
1753             /* Invalid */
1754             goto invalid_opc;
1755         case 0xC:
1756             /* Longword virtual access with alternate access mode */
1757             gen_op_set_alt_mode();
1758             gen_op_st_phys_to_virt();
1759             gen_op_ldl_raw();
1760             gen_op_restore_mode();
1761             break;
1762         case 0xD:
1763             /* Quadword virtual access with alternate access mode */
1764             gen_op_set_alt_mode();
1765             gen_op_st_phys_to_virt();
1766             gen_op_ldq_raw();
1767             gen_op_restore_mode();
1768             break;
1769         case 0xE:
1770             /* Invalid */
1771             goto invalid_opc;
1772         case 0xF:
1773             /* Invalid */
1774             goto invalid_opc;
1775         }
1776         ret = 2;
1777         break;
1778 #endif
1779     case 0x20:
1780         /* LDF */
1781 #if 0 // TODO
1782         gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16);
1783 #else
1784         goto invalid_opc;
1785 #endif
1786         break;
1787     case 0x21:
1788         /* LDG */
1789 #if 0 // TODO
1790         gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16);
1791 #else
1792         goto invalid_opc;
1793 #endif
1794         break;
1795     case 0x22:
1796         /* LDS */
1797         gen_load_fmem(ctx, &gen_lds, ra, rb, disp16);
1798         break;
1799     case 0x23:
1800         /* LDT */
1801         gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16);
1802         break;
1803     case 0x24:
1804         /* STF */
1805 #if 0 // TODO
1806         gen_store_fmem(ctx, &gen_stf, ra, rb, disp16);
1807 #else
1808         goto invalid_opc;
1809 #endif
1810         break;
1811     case 0x25:
1812         /* STG */
1813 #if 0 // TODO
1814         gen_store_fmem(ctx, &gen_stg, ra, rb, disp16);
1815 #else
1816         goto invalid_opc;
1817 #endif
1818         break;
1819     case 0x26:
1820         /* STS */
1821         gen_store_fmem(ctx, &gen_sts, ra, rb, disp16);
1822         break;
1823     case 0x27:
1824         /* STT */
1825         gen_store_fmem(ctx, &gen_stt, ra, rb, disp16);
1826         break;
1827     case 0x28:
1828         /* LDL */
1829         gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0);
1830         break;
1831     case 0x29:
1832         /* LDQ */
1833         gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0);
1834         break;
1835     case 0x2A:
1836         /* LDL_L */
1837         gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0);
1838         break;
1839     case 0x2B:
1840         /* LDQ_L */
1841         gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0);
1842         break;
1843     case 0x2C:
1844         /* STL */
1845         gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0);
1846         break;
1847     case 0x2D:
1848         /* STQ */
1849         gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0);
1850         break;
1851     case 0x2E:
1852         /* STL_C */
1853         gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0);
1854         break;
1855     case 0x2F:
1856         /* STQ_C */
1857         gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0);
1858         break;
1859     case 0x30:
1860         /* BR */
1861         gen_set_uT0(ctx, ctx->pc);
1862         gen_store_ir(ctx, ra, 0);
1863         if (disp21 != 0) {
1864             gen_set_sT1(ctx, disp21 << 2);
1865             gen_op_addq();
1866         }
1867         gen_op_branch();
1868         ret = 1;
1869         break;
1870     case 0x31:
1871         /* FBEQ */
1872         gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16);
1873         ret = 1;
1874         break;
1875     case 0x32:
1876         /* FBLT */
1877         gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16);
1878         ret = 1;
1879         break;
1880     case 0x33:
1881         /* FBLE */
1882         gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16);
1883         ret = 1;
1884         break;
1885     case 0x34:
1886         /* BSR */
1887         gen_set_uT0(ctx, ctx->pc);
1888         gen_store_ir(ctx, ra, 0);
1889         if (disp21 != 0) {
1890             gen_set_sT1(ctx, disp21 << 2);
1891             gen_op_addq();
1892         }
1893         gen_op_branch();
1894         ret = 1;
1895         break;
1896     case 0x35:
1897         /* FBNE */
1898         gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16);
1899         ret = 1;
1900         break;
1901     case 0x36:
1902         /* FBGE */
1903         gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16);
1904         ret = 1;
1905         break;
1906     case 0x37:
1907         /* FBGT */
1908         gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16);
1909         ret = 1;
1910         break;
1911     case 0x38:
1912         /* BLBC */
1913         gen_bcond(ctx, &gen_op_cmplbc, ra, disp16);
1914         ret = 1;
1915         break;
1916     case 0x39:
1917         /* BEQ */
1918         gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16);
1919         ret = 1;
1920         break;
1921     case 0x3A:
1922         /* BLT */
1923         gen_bcond(ctx, &gen_op_cmpltz, ra, disp16);
1924         ret = 1;
1925         break;
1926     case 0x3B:
1927         /* BLE */
1928         gen_bcond(ctx, &gen_op_cmplez, ra, disp16);
1929         ret = 1;
1930         break;
1931     case 0x3C:
1932         /* BLBS */
1933         gen_bcond(ctx, &gen_op_cmplbs, ra, disp16);
1934         ret = 1;
1935         break;
1936     case 0x3D:
1937         /* BNE */
1938         gen_bcond(ctx, &gen_op_cmpnez, ra, disp16);
1939         ret = 1;
1940         break;
1941     case 0x3E:
1942         /* BGE */
1943         gen_bcond(ctx, &gen_op_cmpgez, ra, disp16);
1944         ret = 1;
1945         break;
1946     case 0x3F:
1947         /* BGT */
1948         gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16);
1949         ret = 1;
1950         break;
1951     invalid_opc:
1952         gen_invalid(ctx);
1953         ret = 3;
1954         break;
1955     }
1956
1957     return ret;
1958 }
1959
1960 static always_inline int gen_intermediate_code_internal (CPUState *env,
1961                                                          TranslationBlock *tb,
1962                                                          int search_pc)
1963 {
1964 #if defined ALPHA_DEBUG_DISAS
1965     static int insn_count;
1966 #endif
1967     DisasContext ctx, *ctxp = &ctx;
1968     target_ulong pc_start;
1969     uint32_t insn;
1970     uint16_t *gen_opc_end;
1971     int j, lj = -1;
1972     int ret;
1973
1974     pc_start = tb->pc;
1975     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1976     ctx.pc = pc_start;
1977     ctx.amask = env->amask;
1978 #if defined (CONFIG_USER_ONLY)
1979     ctx.mem_idx = 0;
1980 #else
1981     ctx.mem_idx = ((env->ps >> 3) & 3);
1982     ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
1983 #endif
1984     for (ret = 0; ret == 0;) {
1985         if (env->nb_breakpoints > 0) {
1986             for(j = 0; j < env->nb_breakpoints; j++) {
1987                 if (env->breakpoints[j] == ctx.pc) {
1988                     gen_excp(&ctx, EXCP_DEBUG, 0);
1989                     break;
1990                 }
1991             }
1992         }
1993         if (search_pc) {
1994             j = gen_opc_ptr - gen_opc_buf;
1995             if (lj < j) {
1996                 lj++;
1997                 while (lj < j)
1998                     gen_opc_instr_start[lj++] = 0;
1999                 gen_opc_pc[lj] = ctx.pc;
2000                 gen_opc_instr_start[lj] = 1;
2001             }
2002         }
2003 #if defined ALPHA_DEBUG_DISAS
2004         insn_count++;
2005         if (logfile != NULL) {
2006             fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2007                     ctx.pc, ctx.mem_idx);
2008         }
2009 #endif
2010         insn = ldl_code(ctx.pc);
2011 #if defined ALPHA_DEBUG_DISAS
2012         insn_count++;
2013         if (logfile != NULL) {
2014             fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2015         }
2016 #endif
2017         ctx.pc += 4;
2018         ret = translate_one(ctxp, insn);
2019         if (ret != 0)
2020             break;
2021         /* if we reach a page boundary or are single stepping, stop
2022          * generation
2023          */
2024         if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2025             (env->singlestep_enabled)) {
2026             break;
2027         }
2028 #if defined (DO_SINGLE_STEP)
2029         break;
2030 #endif
2031     }
2032     if (ret != 1 && ret != 3) {
2033         gen_update_pc(&ctx);
2034     }
2035 #if defined (DO_TB_FLUSH)
2036     gen_op_tb_flush();
2037 #endif
2038     /* Generate the return instruction */
2039     tcg_gen_exit_tb(0);
2040     *gen_opc_ptr = INDEX_op_end;
2041     if (search_pc) {
2042         j = gen_opc_ptr - gen_opc_buf;
2043         lj++;
2044         while (lj <= j)
2045             gen_opc_instr_start[lj++] = 0;
2046     } else {
2047         tb->size = ctx.pc - pc_start;
2048     }
2049 #if defined ALPHA_DEBUG_DISAS
2050     if (loglevel & CPU_LOG_TB_CPU) {
2051         cpu_dump_state(env, logfile, fprintf, 0);
2052     }
2053     if (loglevel & CPU_LOG_TB_IN_ASM) {
2054         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2055         target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2056         fprintf(logfile, "\n");
2057     }
2058 #endif
2059
2060     return 0;
2061 }
2062
2063 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2064 {
2065     return gen_intermediate_code_internal(env, tb, 0);
2066 }
2067
2068 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2069 {
2070     return gen_intermediate_code_internal(env, tb, 1);
2071 }
2072
2073 CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2074 {
2075     CPUAlphaState *env;
2076     uint64_t hwpcb;
2077
2078     env = qemu_mallocz(sizeof(CPUAlphaState));
2079     if (!env)
2080         return NULL;
2081     cpu_exec_init(env);
2082     tlb_flush(env, 1);
2083     /* XXX: should not be hardcoded */
2084     env->implver = IMPLVER_2106x;
2085     env->ps = 0x1F00;
2086 #if defined (CONFIG_USER_ONLY)
2087     env->ps |= 1 << 3;
2088 #endif
2089     pal_init(env);
2090     /* Initialize IPR */
2091     hwpcb = env->ipr[IPR_PCBB];
2092     env->ipr[IPR_ASN] = 0;
2093     env->ipr[IPR_ASTEN] = 0;
2094     env->ipr[IPR_ASTSR] = 0;
2095     env->ipr[IPR_DATFX] = 0;
2096     /* XXX: fix this */
2097     //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2098     //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2099     //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2100     //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2101     env->ipr[IPR_FEN] = 0;
2102     env->ipr[IPR_IPL] = 31;
2103     env->ipr[IPR_MCES] = 0;
2104     env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2105     //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2106     env->ipr[IPR_SISR] = 0;
2107     env->ipr[IPR_VIRBND] = -1ULL;
2108
2109     return env;
2110 }
2111
2112 void gen_pc_load(CPUState *env, TranslationBlock *tb,
2113                 unsigned long searched_pc, int pc_pos, void *puc)
2114 {
2115     env->pc = gen_opc_pc[pc_pos];
2116 }