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