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