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