]> git.proxmox.com Git - qemu.git/blame - target-alpha/translate.c
Proper target format for qOffsets.
[qemu.git] / target-alpha / translate.c
CommitLineData
4c9649a9
JM
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
34typedef struct DisasContext DisasContext;
35struct 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
50enum {
51#define DEF(s, n, copy_size) INDEX_op_ ## s,
52#include "opc.h"
53#undef DEF
54 NB_OPS,
55};
56
57static uint16_t *gen_opc_ptr;
58static uint32_t *gen_opparam_ptr;
59
60#include "gen-op.h"
61
62static 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) \
70static GenOpFunc *NAME ## _table [32] = { \
71NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
72NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
73NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
74NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
75NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
76NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
77NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
78NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
79}; \
80static 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
94GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir);
95GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir);
96GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir);
97GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir);
98GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir);
99GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir);
100GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
101
102static 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
117static 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
141GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir);
142GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir);
143GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir);
144GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir);
145GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir);
146GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir);
147GEN32(gen_op_cmov_fir, gen_op_cmov_fir);
148
149static 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
164static 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) \
182static GenOpFunc *gen_op_ld##width[] = { \
183 &gen_op_ld##width##_raw, \
184}
185#define OP_ST_TABLE(width) \
186static GenOpFunc *gen_op_st##width[] = { \
187 &gen_op_st##width##_raw, \
188}
189#else
190#define OP_LD_TABLE(width) \
191static GenOpFunc *gen_op_ld##width[] = { \
192 &gen_op_ld##width##_kernel, \
193 &gen_op_ld##width##_user, /* executive */ \
194 &gen_op_ld##width##_data, /* supervisor */ \
195 &gen_op_ld##width##_data, /* user */ \
196}
197#define OP_ST_TABLE(width) \
198static GenOpFunc *gen_op_st##width[] = { \
199 &gen_op_st##width##_kernel, \
200 &gen_op_st##width##_user, /* executive */ \
201 &gen_op_st##width##_data, /* supervisor */ \
202 &gen_op_st##width##_data, /* user */ \
203}
204#endif
205
206#define GEN_LD(width) \
207OP_LD_TABLE(width); \
208static void gen_ld##width (DisasContext *ctx) \
209{ \
210 (*gen_op_ld##width[ctx->mem_idx])(); \
211}
212
213#define GEN_ST(width) \
214OP_ST_TABLE(width); \
215static void gen_st##width (DisasContext *ctx) \
216{ \
217 (*gen_op_st##width[ctx->mem_idx])(); \
218}
219
220GEN_LD(bu);
221GEN_ST(b);
222GEN_LD(wu);
223GEN_ST(w);
224GEN_LD(l);
225GEN_ST(l);
226GEN_LD(q);
227GEN_ST(q);
228GEN_LD(q_u);
229GEN_ST(q_u);
230GEN_LD(l_l);
231GEN_ST(l_c);
232GEN_LD(q_l);
233GEN_ST(q_c);
234
235GEN_LD(f);
236GEN_ST(f);
237GEN_LD(g);
238GEN_ST(g);
239GEN_LD(s);
240GEN_ST(s);
241GEN_LD(t);
242GEN_ST(t);
243
244#if defined(__i386__) || defined(__x86_64__)
245static inline void gen_op_set_s16_T0 (int16_t imm)
246{
247 gen_op_set_s32_T0((int32_t)imm);
248}
249
250static inline void gen_op_set_s16_T1 (int16_t imm)
251{
252 gen_op_set_s32_T1((int32_t)imm);
253}
254
255static inline void gen_op_set_u16_T0 (uint16_t imm)
256{
257 gen_op_set_s32_T0((uint32_t)imm);
258}
259
260static inline void gen_op_set_u16_T1 (uint16_t imm)
261{
262 gen_op_set_s32_T1((uint32_t)imm);
263}
264#endif
265
266static inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
267{
268 int32_t imm32;
269 int16_t imm16;
270
271 imm32 = imm;
272 if (imm32 == imm) {
273 imm16 = imm;
274 if (imm16 == imm) {
275 if (imm == 0) {
276 gen_op_reset_T0();
277 } else {
278 gen_op_set_s16_T0(imm16);
279 }
280 } else {
281 gen_op_set_s32_T0(imm32);
282 }
283 } else {
284#if 0 // Qemu does not know how to do this...
285 gen_op_set_64_T0(imm);
286#else
287 gen_op_set_64_T0(imm >> 32, imm);
288#endif
289 }
290}
291
292static inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
293{
294 int32_t imm32;
295 int16_t imm16;
296
297 imm32 = imm;
298 if (imm32 == imm) {
299 imm16 = imm;
300 if (imm16 == imm) {
301 if (imm == 0) {
302 gen_op_reset_T1();
303 } else {
304 gen_op_set_s16_T1(imm16);
305 }
306 } else {
307 gen_op_set_s32_T1(imm32);
308 }
309 } else {
310#if 0 // Qemu does not know how to do this...
311 gen_op_set_64_T1(imm);
312#else
313 gen_op_set_64_T1(imm >> 32, imm);
314#endif
315 }
316}
317
318static inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm)
319{
320 if (!(imm >> 32)) {
321 if ((!imm >> 16)) {
322 if (imm == 0)
323 gen_op_reset_T0();
324 else
325 gen_op_set_u16_T0(imm);
326 } else {
327 gen_op_set_u32_T0(imm);
328 }
329 } else {
330#if 0 // Qemu does not know how to do this...
331 gen_op_set_64_T0(imm);
332#else
333 gen_op_set_64_T0(imm >> 32, imm);
334#endif
335 }
336}
337
338static inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm)
339{
340 if (!(imm >> 32)) {
341 if ((!imm >> 16)) {
342 if (imm == 0)
343 gen_op_reset_T1();
344 else
345 gen_op_set_u16_T1(imm);
346 } else {
347 gen_op_set_u32_T1(imm);
348 }
349 } else {
350#if 0 // Qemu does not know how to do this...
351 gen_op_set_64_T1(imm);
352#else
353 gen_op_set_64_T1(imm >> 32, imm);
354#endif
355 }
356}
357
358static inline void gen_update_pc (DisasContext *ctx)
359{
360 if (!(ctx->pc >> 32)) {
361 gen_op_update_pc32(ctx->pc);
362 } else {
363#if 0 // Qemu does not know how to do this...
364 gen_op_update_pc(ctx->pc);
365#else
366 gen_op_update_pc(ctx->pc >> 32, ctx->pc);
367#endif
368 }
369}
370
371static inline void _gen_op_bcond (DisasContext *ctx)
372{
373#if 0 // Qemu does not know how to do this...
374 gen_op_bcond(ctx->pc);
375#else
376 gen_op_bcond(ctx->pc >> 32, ctx->pc);
377#endif
378}
379
380static inline void gen_excp (DisasContext *ctx, int exception, int error_code)
381{
382 gen_update_pc(ctx);
383 gen_op_excp(exception, error_code);
384}
385
386static inline void gen_invalid (DisasContext *ctx)
387{
388 gen_excp(ctx, EXCP_OPCDEC, 0);
389}
390
391static void gen_load_mem (DisasContext *ctx,
392 void (*gen_load_op)(DisasContext *ctx),
393 int ra, int rb, int32_t disp16, int clear)
394{
395 if (ra == 31 && disp16 == 0) {
396 /* UNOP */
397 gen_op_nop();
398 } else {
399 gen_load_ir(ctx, rb, 0);
400 if (disp16 != 0) {
401 gen_set_sT1(ctx, disp16);
402 gen_op_addq();
403 }
404 if (clear)
405 gen_op_n7();
406 (*gen_load_op)(ctx);
407 gen_store_ir(ctx, ra, 1);
408 }
409}
410
411static void gen_store_mem (DisasContext *ctx,
412 void (*gen_store_op)(DisasContext *ctx),
413 int ra, int rb, int32_t disp16, int clear)
414{
415 gen_load_ir(ctx, rb, 0);
416 if (disp16 != 0) {
417 gen_set_sT1(ctx, disp16);
418 gen_op_addq();
419 }
420 if (clear)
421 gen_op_n7();
422 gen_load_ir(ctx, ra, 1);
423 (*gen_store_op)(ctx);
424}
425
426static void gen_load_fmem (DisasContext *ctx,
427 void (*gen_load_fop)(DisasContext *ctx),
428 int ra, int rb, int32_t disp16)
429{
430 gen_load_ir(ctx, rb, 0);
431 if (disp16 != 0) {
432 gen_set_sT1(ctx, disp16);
433 gen_op_addq();
434 }
435 (*gen_load_fop)(ctx);
436 gen_store_fir(ctx, ra, 1);
437}
438
439static void gen_store_fmem (DisasContext *ctx,
440 void (*gen_store_fop)(DisasContext *ctx),
441 int ra, int rb, int32_t disp16)
442{
443 gen_load_ir(ctx, rb, 0);
444 if (disp16 != 0) {
445 gen_set_sT1(ctx, disp16);
446 gen_op_addq();
447 }
448 gen_load_fir(ctx, ra, 1);
449 (*gen_store_fop)(ctx);
450}
451
452static void gen_bcond (DisasContext *ctx, void (*gen_test_op)(void),
453 int ra, int32_t disp16)
454{
455 if (disp16 != 0) {
456 gen_set_uT0(ctx, ctx->pc);
457 gen_set_sT1(ctx, disp16 << 2);
458 gen_op_addq1();
459 } else {
460 gen_set_uT1(ctx, ctx->pc);
461 }
462 gen_load_ir(ctx, ra, 0);
463 (*gen_test_op)();
464 _gen_op_bcond(ctx);
465}
466
467static void gen_fbcond (DisasContext *ctx, void (*gen_test_op)(void),
468 int ra, int32_t disp16)
469{
470 if (disp16 != 0) {
471 gen_set_uT0(ctx, ctx->pc);
472 gen_set_sT1(ctx, disp16 << 2);
473 gen_op_addq1();
474 } else {
475 gen_set_uT1(ctx, ctx->pc);
476 }
477 gen_load_fir(ctx, ra, 0);
478 (*gen_test_op)();
479 _gen_op_bcond(ctx);
480}
481
482static void gen_arith2 (DisasContext *ctx, void (*gen_arith_op)(void),
483 int rb, int rc, int islit, int8_t lit)
484{
485 if (islit)
486 gen_set_sT0(ctx, lit);
487 else
488 gen_load_ir(ctx, rb, 0);
489 (*gen_arith_op)();
490 gen_store_ir(ctx, rc, 0);
491}
492
493static void gen_arith3 (DisasContext *ctx, void (*gen_arith_op)(void),
494 int ra, int rb, int rc, int islit, int8_t lit)
495{
496 gen_load_ir(ctx, ra, 0);
497 if (islit)
498 gen_set_sT1(ctx, lit);
499 else
500 gen_load_ir(ctx, rb, 1);
501 (*gen_arith_op)();
502 gen_store_ir(ctx, rc, 0);
503}
504
505static void gen_cmov (DisasContext *ctx, void (*gen_test_op)(void),
506 int ra, int rb, int rc, int islit, int8_t lit)
507{
508 gen_load_ir(ctx, ra, 1);
509 if (islit)
510 gen_set_sT0(ctx, lit);
511 else
512 gen_load_ir(ctx, rb, 0);
513 (*gen_test_op)();
514 gen_op_cmov_ir(rc);
515}
516
517static void gen_farith2 (DisasContext *ctx, void (*gen_arith_fop)(void),
518 int rb, int rc)
519{
520 gen_load_fir(ctx, rb, 0);
521 (*gen_arith_fop)();
522 gen_store_fir(ctx, rc, 0);
523}
524
525static void gen_farith3 (DisasContext *ctx, void (*gen_arith_fop)(void),
526 int ra, int rb, int rc)
527{
528 gen_load_fir(ctx, ra, 0);
529 gen_load_fir(ctx, rb, 1);
530 (*gen_arith_fop)();
531 gen_store_fir(ctx, rc, 0);
532}
533
534static void gen_fcmov (DisasContext *ctx, void (*gen_test_fop)(void),
535 int ra, int rb, int rc)
536{
537 gen_load_fir(ctx, ra, 0);
538 gen_load_fir(ctx, rb, 1);
539 (*gen_test_fop)();
540 gen_op_cmov_fir(rc);
541}
542
543static void gen_fti (DisasContext *ctx, void (*gen_move_fop)(void),
544 int ra, int rc)
545{
546 gen_load_fir(ctx, rc, 0);
547 (*gen_move_fop)();
548 gen_store_ir(ctx, ra, 0);
549}
550
551static void gen_itf (DisasContext *ctx, void (*gen_move_fop)(void),
552 int ra, int rc)
553{
554 gen_load_ir(ctx, ra, 0);
555 (*gen_move_fop)();
556 gen_store_fir(ctx, rc, 0);
557}
558
559static void gen_s4addl (void)
560{
561 gen_op_s4();
562 gen_op_addl();
563}
564
565static void gen_s4subl (void)
566{
567 gen_op_s4();
568 gen_op_subl();
569}
570
571static void gen_s8addl (void)
572{
573 gen_op_s8();
574 gen_op_addl();
575}
576
577static void gen_s8subl (void)
578{
579 gen_op_s8();
580 gen_op_subl();
581}
582
583static void gen_s4addq (void)
584{
585 gen_op_s4();
586 gen_op_addq();
587}
588
589static void gen_s4subq (void)
590{
591 gen_op_s4();
592 gen_op_subq();
593}
594
595static void gen_s8addq (void)
596{
597 gen_op_s8();
598 gen_op_addq();
599}
600
601static void gen_s8subq (void)
602{
603 gen_op_s8();
604 gen_op_subq();
605}
606
607static void gen_amask (void)
608{
609 gen_op_load_amask();
610 gen_op_bic();
611}
612
613static int translate_one (DisasContext *ctx, uint32_t insn)
614{
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;
621
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);
644 }
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;
663 }
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;
825 }
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);
855 }
856 } else {
857 gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
858 }
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;
907 }
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;
1017 }
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;
1043 }
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;
1095 }
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;
1179 }
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);
1241 }
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;
1257 }
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);
1275 }
1276 } else {
1277 gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
1278 }
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;
1336 }
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;
1398 }
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);
1416 }
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;
1432 }
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
1511 */
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
1519 */
1520 gen_op_set_alt_mode();
1521 gen_op_ldq_data();
1522 gen_op_restore_mode();
1523 break;
1524 }
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;
1665 }
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();
1694 }
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;
1774 }
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();
1865 }
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();
1891 }
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;
1954 }
1955
1956 return ret;
1957}
1958
1959int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
1960 int search_pc)
1961{
1962#if defined ALPHA_DEBUG_DISAS
1963 static int insn_count;
1964#endif
1965 DisasContext ctx, *ctxp = &ctx;
1966 target_ulong pc_start;
1967 uint32_t insn;
1968 uint16_t *gen_opc_end;
1969 int j, lj = -1;
1970 int ret;
1971
1972 pc_start = tb->pc;
1973 gen_opc_ptr = gen_opc_buf;
1974 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1975 gen_opparam_ptr = gen_opparam_buf;
1976 nb_gen_labels = 0;
1977 ctx.pc = pc_start;
1978 ctx.amask = env->amask;
1979#if defined (CONFIG_USER_ONLY)
1980 ctx.mem_idx = 0;
1981#else
1982 ctx.mem_idx = ((env->ps >> 3) & 3);
1983 ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
1984#endif
1985 for (ret = 0; ret == 0;) {
1986 if (env->nb_breakpoints > 0) {
1987 for(j = 0; j < env->nb_breakpoints; j++) {
1988 if (env->breakpoints[j] == ctx.pc) {
1989 gen_excp(&ctx, EXCP_DEBUG, 0);
1990 break;
1991 }
1992 }
1993 }
1994 if (search_pc) {
1995 j = gen_opc_ptr - gen_opc_buf;
1996 if (lj < j) {
1997 lj++;
1998 while (lj < j)
1999 gen_opc_instr_start[lj++] = 0;
2000 gen_opc_pc[lj] = ctx.pc;
2001 gen_opc_instr_start[lj] = 1;
2002 }
2003 }
2004#if defined ALPHA_DEBUG_DISAS
2005 insn_count++;
2006 if (logfile != NULL) {
e96efcfc
JM
2007 fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2008 ctx.pc, ctx.mem_idx);
4c9649a9
JM
2009 }
2010#endif
2011 insn = ldl_code(ctx.pc);
2012#if defined ALPHA_DEBUG_DISAS
2013 insn_count++;
2014 if (logfile != NULL) {
2015 fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2016 }
2017#endif
2018 ctx.pc += 4;
2019 ret = translate_one(ctxp, insn);
2020 if (ret != 0)
2021 break;
2022 /* if we reach a page boundary or are single stepping, stop
2023 * generation
2024 */
2025 if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2026 (env->singlestep_enabled)) {
2027 break;
2028 }
2029#if defined (DO_SINGLE_STEP)
2030 break;
2031#endif
2032 }
2033 if (ret != 1 && ret != 3) {
2034 gen_update_pc(&ctx);
2035 }
2036 gen_op_reset_T0();
2037#if defined (DO_TB_FLUSH)
2038 gen_op_tb_flush();
2039#endif
2040 /* Generate the return instruction */
2041 gen_op_exit_tb();
2042 *gen_opc_ptr = INDEX_op_end;
2043 if (search_pc) {
2044 j = gen_opc_ptr - gen_opc_buf;
2045 lj++;
2046 while (lj <= j)
2047 gen_opc_instr_start[lj++] = 0;
2048 tb->size = 0;
2049 } else {
2050 tb->size = ctx.pc - pc_start;
2051 }
2052#if defined ALPHA_DEBUG_DISAS
2053 if (loglevel & CPU_LOG_TB_CPU) {
2054 cpu_dump_state(env, logfile, fprintf, 0);
2055 }
2056 if (loglevel & CPU_LOG_TB_IN_ASM) {
2057 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2058 target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2059 fprintf(logfile, "\n");
2060 }
2061 if (loglevel & CPU_LOG_TB_OP) {
2062 fprintf(logfile, "OP:\n");
2063 dump_ops(gen_opc_buf, gen_opparam_buf);
2064 fprintf(logfile, "\n");
2065 }
2066#endif
2067
2068 return 0;
2069}
2070
2071int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2072{
2073 return gen_intermediate_code_internal(env, tb, 0);
2074}
2075
2076int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2077{
2078 return gen_intermediate_code_internal(env, tb, 1);
2079}
2080
2081CPUAlphaState * cpu_alpha_init (void)
2082{
2083 CPUAlphaState *env;
2084 uint64_t hwpcb;
2085
2086 env = qemu_mallocz(sizeof(CPUAlphaState));
2087 if (!env)
2088 return NULL;
2089 cpu_exec_init(env);
2090 tlb_flush(env, 1);
2091 /* XXX: should not be hardcoded */
2092 env->implver = IMPLVER_2106x;
2093 env->ps = 0x1F00;
2094#if defined (CONFIG_USER_ONLY)
2095 env->ps |= 1 << 3;
2096#endif
2097 pal_init(env);
2098 /* Initialize IPR */
2099 hwpcb = env->ipr[IPR_PCBB];
2100 env->ipr[IPR_ASN] = 0;
2101 env->ipr[IPR_ASTEN] = 0;
2102 env->ipr[IPR_ASTSR] = 0;
2103 env->ipr[IPR_DATFX] = 0;
2104 /* XXX: fix this */
2105 // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2106 // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2107 // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2108 // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2109 env->ipr[IPR_FEN] = 0;
2110 env->ipr[IPR_IPL] = 31;
2111 env->ipr[IPR_MCES] = 0;
2112 env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2113 // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2114 env->ipr[IPR_SISR] = 0;
2115 env->ipr[IPR_VIRBND] = -1ULL;
2116
2117 return env;
2118}