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