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