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