]> git.proxmox.com Git - mirror_qemu.git/blob - target-alpha/translate.c
find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[mirror_qemu.git] / target-alpha / translate.c
1 /*
2 * Alpha emulation cpu translation for qemu.
3 *
4 * Copyright (c) 2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, 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##_user, /* executive */ \
194 &gen_op_ld##width##_data, /* supervisor */ \
195 &gen_op_ld##width##_data, /* 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##_user, /* executive */ \
201 &gen_op_st##width##_data, /* supervisor */ \
202 &gen_op_st##width##_data, /* 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 }