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