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