modules: do not include gmodule-2.0 in static builds
[qemu/rayw.git] / target-alpha / translate.c
blob4c94bed70438ed6bc5fdd251b8a929b805a492c4
1 /*
2 * Alpha emulation cpu translation for qemu.
4 * Copyright (c) 2007 Jocelyn Mayer
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "cpu.h"
21 #include "disas/disas.h"
22 #include "qemu/host-utils.h"
23 #include "tcg-op.h"
25 #include "helper.h"
26 #define GEN_HELPER 1
27 #include "helper.h"
29 #undef ALPHA_DEBUG_DISAS
30 #define CONFIG_SOFTFLOAT_INLINE
32 #ifdef ALPHA_DEBUG_DISAS
33 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
34 #else
35 # define LOG_DISAS(...) do { } while (0)
36 #endif
38 typedef struct DisasContext DisasContext;
39 struct DisasContext {
40 struct TranslationBlock *tb;
41 uint64_t pc;
42 int mem_idx;
44 /* Current rounding mode for this TB. */
45 int tb_rm;
46 /* Current flush-to-zero setting for this TB. */
47 int tb_ftz;
49 /* implver value for this CPU. */
50 int implver;
52 bool singlestep_enabled;
55 /* Return values from translate_one, indicating the state of the TB.
56 Note that zero indicates that we are not exiting the TB. */
58 typedef enum {
59 NO_EXIT,
61 /* We have emitted one or more goto_tb. No fixup required. */
62 EXIT_GOTO_TB,
64 /* We are not using a goto_tb (for whatever reason), but have updated
65 the PC (for whatever reason), so there's no need to do it again on
66 exiting the TB. */
67 EXIT_PC_UPDATED,
69 /* We are exiting the TB, but have neither emitted a goto_tb, nor
70 updated the PC for the next instruction to be executed. */
71 EXIT_PC_STALE,
73 /* We are ending the TB with a noreturn function call, e.g. longjmp.
74 No following code will be executed. */
75 EXIT_NORETURN,
76 } ExitStatus;
78 /* global register indexes */
79 static TCGv_ptr cpu_env;
80 static TCGv cpu_ir[31];
81 static TCGv cpu_fir[31];
82 static TCGv cpu_pc;
83 static TCGv cpu_lock_addr;
84 static TCGv cpu_lock_st_addr;
85 static TCGv cpu_lock_value;
86 static TCGv cpu_unique;
87 #ifndef CONFIG_USER_ONLY
88 static TCGv cpu_sysval;
89 static TCGv cpu_usp;
90 #endif
92 /* register names */
93 static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
95 #include "exec/gen-icount.h"
97 void alpha_translate_init(void)
99 int i;
100 char *p;
101 static int done_init = 0;
103 if (done_init)
104 return;
106 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
108 p = cpu_reg_names;
109 for (i = 0; i < 31; i++) {
110 sprintf(p, "ir%d", i);
111 cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
112 offsetof(CPUAlphaState, ir[i]), p);
113 p += (i < 10) ? 4 : 5;
115 sprintf(p, "fir%d", i);
116 cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
117 offsetof(CPUAlphaState, fir[i]), p);
118 p += (i < 10) ? 5 : 6;
121 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
122 offsetof(CPUAlphaState, pc), "pc");
124 cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
125 offsetof(CPUAlphaState, lock_addr),
126 "lock_addr");
127 cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
128 offsetof(CPUAlphaState, lock_st_addr),
129 "lock_st_addr");
130 cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
131 offsetof(CPUAlphaState, lock_value),
132 "lock_value");
134 cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
135 offsetof(CPUAlphaState, unique), "unique");
136 #ifndef CONFIG_USER_ONLY
137 cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
138 offsetof(CPUAlphaState, sysval), "sysval");
139 cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
140 offsetof(CPUAlphaState, usp), "usp");
141 #endif
143 done_init = 1;
146 static void gen_excp_1(int exception, int error_code)
148 TCGv_i32 tmp1, tmp2;
150 tmp1 = tcg_const_i32(exception);
151 tmp2 = tcg_const_i32(error_code);
152 gen_helper_excp(cpu_env, tmp1, tmp2);
153 tcg_temp_free_i32(tmp2);
154 tcg_temp_free_i32(tmp1);
157 static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
159 tcg_gen_movi_i64(cpu_pc, ctx->pc);
160 gen_excp_1(exception, error_code);
161 return EXIT_NORETURN;
164 static inline ExitStatus gen_invalid(DisasContext *ctx)
166 return gen_excp(ctx, EXCP_OPCDEC, 0);
169 static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
171 TCGv_i32 tmp32 = tcg_temp_new_i32();
172 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
173 gen_helper_memory_to_f(t0, tmp32);
174 tcg_temp_free_i32(tmp32);
177 static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
179 TCGv tmp = tcg_temp_new();
180 tcg_gen_qemu_ld_i64(tmp, t1, flags, MO_LEQ);
181 gen_helper_memory_to_g(t0, tmp);
182 tcg_temp_free(tmp);
185 static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
187 TCGv_i32 tmp32 = tcg_temp_new_i32();
188 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
189 gen_helper_memory_to_s(t0, tmp32);
190 tcg_temp_free_i32(tmp32);
193 static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
195 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL);
196 tcg_gen_mov_i64(cpu_lock_addr, t1);
197 tcg_gen_mov_i64(cpu_lock_value, t0);
200 static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
202 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ);
203 tcg_gen_mov_i64(cpu_lock_addr, t1);
204 tcg_gen_mov_i64(cpu_lock_value, t0);
207 static inline void gen_load_mem(DisasContext *ctx,
208 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
209 int flags),
210 int ra, int rb, int32_t disp16, int fp,
211 int clear)
213 TCGv addr, va;
215 /* LDQ_U with ra $31 is UNOP. Other various loads are forms of
216 prefetches, which we can treat as nops. No worries about
217 missed exceptions here. */
218 if (unlikely(ra == 31)) {
219 return;
222 addr = tcg_temp_new();
223 if (rb != 31) {
224 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
225 if (clear) {
226 tcg_gen_andi_i64(addr, addr, ~0x7);
228 } else {
229 if (clear) {
230 disp16 &= ~0x7;
232 tcg_gen_movi_i64(addr, disp16);
235 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
236 tcg_gen_qemu_load(va, addr, ctx->mem_idx);
238 tcg_temp_free(addr);
241 static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
243 TCGv_i32 tmp32 = tcg_temp_new_i32();
244 gen_helper_f_to_memory(tmp32, t0);
245 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
246 tcg_temp_free_i32(tmp32);
249 static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
251 TCGv tmp = tcg_temp_new();
252 gen_helper_g_to_memory(tmp, t0);
253 tcg_gen_qemu_st_i64(tmp, t1, flags, MO_LEQ);
254 tcg_temp_free(tmp);
257 static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
259 TCGv_i32 tmp32 = tcg_temp_new_i32();
260 gen_helper_s_to_memory(tmp32, t0);
261 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
262 tcg_temp_free_i32(tmp32);
265 static inline void gen_store_mem(DisasContext *ctx,
266 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
267 int flags),
268 int ra, int rb, int32_t disp16, int fp,
269 int clear)
271 TCGv addr, va;
273 addr = tcg_temp_new();
274 if (rb != 31) {
275 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
276 if (clear) {
277 tcg_gen_andi_i64(addr, addr, ~0x7);
279 } else {
280 if (clear) {
281 disp16 &= ~0x7;
283 tcg_gen_movi_i64(addr, disp16);
286 if (ra == 31) {
287 va = tcg_const_i64(0);
288 } else {
289 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
291 tcg_gen_qemu_store(va, addr, ctx->mem_idx);
293 tcg_temp_free(addr);
294 if (ra == 31) {
295 tcg_temp_free(va);
299 static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
300 int32_t disp16, int quad)
302 TCGv addr;
304 if (ra == 31) {
305 /* ??? Don't bother storing anything. The user can't tell
306 the difference, since the zero register always reads zero. */
307 return NO_EXIT;
310 #if defined(CONFIG_USER_ONLY)
311 addr = cpu_lock_st_addr;
312 #else
313 addr = tcg_temp_local_new();
314 #endif
316 if (rb != 31) {
317 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
318 } else {
319 tcg_gen_movi_i64(addr, disp16);
322 #if defined(CONFIG_USER_ONLY)
323 /* ??? This is handled via a complicated version of compare-and-swap
324 in the cpu_loop. Hopefully one day we'll have a real CAS opcode
325 in TCG so that this isn't necessary. */
326 return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
327 #else
328 /* ??? In system mode we are never multi-threaded, so CAS can be
329 implemented via a non-atomic load-compare-store sequence. */
331 int lab_fail, lab_done;
332 TCGv val;
334 lab_fail = gen_new_label();
335 lab_done = gen_new_label();
336 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
338 val = tcg_temp_new();
339 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, quad ? MO_LEQ : MO_LESL);
340 tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
342 tcg_gen_qemu_st_i64(cpu_ir[ra], addr, ctx->mem_idx,
343 quad ? MO_LEQ : MO_LEUL);
344 tcg_gen_movi_i64(cpu_ir[ra], 1);
345 tcg_gen_br(lab_done);
347 gen_set_label(lab_fail);
348 tcg_gen_movi_i64(cpu_ir[ra], 0);
350 gen_set_label(lab_done);
351 tcg_gen_movi_i64(cpu_lock_addr, -1);
353 tcg_temp_free(addr);
354 return NO_EXIT;
356 #endif
359 static bool in_superpage(DisasContext *ctx, int64_t addr)
361 return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
362 && addr < 0
363 && ((addr >> 41) & 3) == 2
364 && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
367 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
369 /* Suppress goto_tb in the case of single-steping and IO. */
370 if (ctx->singlestep_enabled || (ctx->tb->cflags & CF_LAST_IO)) {
371 return false;
373 /* If the destination is in the superpage, the page perms can't change. */
374 if (in_superpage(ctx, dest)) {
375 return true;
377 /* Check for the dest on the same page as the start of the TB. */
378 return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
381 static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
383 uint64_t dest = ctx->pc + (disp << 2);
385 if (ra != 31) {
386 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
389 /* Notice branch-to-next; used to initialize RA with the PC. */
390 if (disp == 0) {
391 return 0;
392 } else if (use_goto_tb(ctx, dest)) {
393 tcg_gen_goto_tb(0);
394 tcg_gen_movi_i64(cpu_pc, dest);
395 tcg_gen_exit_tb((uintptr_t)ctx->tb);
396 return EXIT_GOTO_TB;
397 } else {
398 tcg_gen_movi_i64(cpu_pc, dest);
399 return EXIT_PC_UPDATED;
403 static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
404 TCGv cmp, int32_t disp)
406 uint64_t dest = ctx->pc + (disp << 2);
407 int lab_true = gen_new_label();
409 if (use_goto_tb(ctx, dest)) {
410 tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
412 tcg_gen_goto_tb(0);
413 tcg_gen_movi_i64(cpu_pc, ctx->pc);
414 tcg_gen_exit_tb((uintptr_t)ctx->tb);
416 gen_set_label(lab_true);
417 tcg_gen_goto_tb(1);
418 tcg_gen_movi_i64(cpu_pc, dest);
419 tcg_gen_exit_tb((uintptr_t)ctx->tb + 1);
421 return EXIT_GOTO_TB;
422 } else {
423 TCGv_i64 z = tcg_const_i64(0);
424 TCGv_i64 d = tcg_const_i64(dest);
425 TCGv_i64 p = tcg_const_i64(ctx->pc);
427 tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
429 tcg_temp_free_i64(z);
430 tcg_temp_free_i64(d);
431 tcg_temp_free_i64(p);
432 return EXIT_PC_UPDATED;
436 static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
437 int32_t disp, int mask)
439 TCGv cmp_tmp;
441 if (unlikely(ra == 31)) {
442 cmp_tmp = tcg_const_i64(0);
443 } else {
444 cmp_tmp = tcg_temp_new();
445 if (mask) {
446 tcg_gen_andi_i64(cmp_tmp, cpu_ir[ra], 1);
447 } else {
448 tcg_gen_mov_i64(cmp_tmp, cpu_ir[ra]);
452 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
455 /* Fold -0.0 for comparison with COND. */
457 static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
459 uint64_t mzero = 1ull << 63;
461 switch (cond) {
462 case TCG_COND_LE:
463 case TCG_COND_GT:
464 /* For <= or >, the -0.0 value directly compares the way we want. */
465 tcg_gen_mov_i64(dest, src);
466 break;
468 case TCG_COND_EQ:
469 case TCG_COND_NE:
470 /* For == or !=, we can simply mask off the sign bit and compare. */
471 tcg_gen_andi_i64(dest, src, mzero - 1);
472 break;
474 case TCG_COND_GE:
475 case TCG_COND_LT:
476 /* For >= or <, map -0.0 to +0.0 via comparison and mask. */
477 tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
478 tcg_gen_neg_i64(dest, dest);
479 tcg_gen_and_i64(dest, dest, src);
480 break;
482 default:
483 abort();
487 static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
488 int32_t disp)
490 TCGv cmp_tmp;
492 if (unlikely(ra == 31)) {
493 /* Very uncommon case, but easier to optimize it to an integer
494 comparison than continuing with the floating point comparison. */
495 return gen_bcond(ctx, cond, ra, disp, 0);
498 cmp_tmp = tcg_temp_new();
499 gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
500 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
503 static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
504 int islit, uint8_t lit, int mask)
506 TCGv_i64 c1, z, v1;
508 if (unlikely(rc == 31)) {
509 return;
512 if (ra == 31) {
513 /* Very uncommon case - Do not bother to optimize. */
514 c1 = tcg_const_i64(0);
515 } else if (mask) {
516 c1 = tcg_const_i64(1);
517 tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
518 } else {
519 c1 = cpu_ir[ra];
521 if (islit) {
522 v1 = tcg_const_i64(lit);
523 } else {
524 v1 = cpu_ir[rb];
526 z = tcg_const_i64(0);
528 tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
530 tcg_temp_free_i64(z);
531 if (ra == 31 || mask) {
532 tcg_temp_free_i64(c1);
534 if (islit) {
535 tcg_temp_free_i64(v1);
539 static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
541 TCGv_i64 c1, z, v1;
543 if (unlikely(rc == 31)) {
544 return;
547 c1 = tcg_temp_new_i64();
548 if (unlikely(ra == 31)) {
549 tcg_gen_movi_i64(c1, 0);
550 } else {
551 gen_fold_mzero(cond, c1, cpu_fir[ra]);
553 if (rb == 31) {
554 v1 = tcg_const_i64(0);
555 } else {
556 v1 = cpu_fir[rb];
558 z = tcg_const_i64(0);
560 tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
562 tcg_temp_free_i64(z);
563 tcg_temp_free_i64(c1);
564 if (rb == 31) {
565 tcg_temp_free_i64(v1);
569 #define QUAL_RM_N 0x080 /* Round mode nearest even */
570 #define QUAL_RM_C 0x000 /* Round mode chopped */
571 #define QUAL_RM_M 0x040 /* Round mode minus infinity */
572 #define QUAL_RM_D 0x0c0 /* Round mode dynamic */
573 #define QUAL_RM_MASK 0x0c0
575 #define QUAL_U 0x100 /* Underflow enable (fp output) */
576 #define QUAL_V 0x100 /* Overflow enable (int output) */
577 #define QUAL_S 0x400 /* Software completion enable */
578 #define QUAL_I 0x200 /* Inexact detection enable */
580 static void gen_qual_roundmode(DisasContext *ctx, int fn11)
582 TCGv_i32 tmp;
584 fn11 &= QUAL_RM_MASK;
585 if (fn11 == ctx->tb_rm) {
586 return;
588 ctx->tb_rm = fn11;
590 tmp = tcg_temp_new_i32();
591 switch (fn11) {
592 case QUAL_RM_N:
593 tcg_gen_movi_i32(tmp, float_round_nearest_even);
594 break;
595 case QUAL_RM_C:
596 tcg_gen_movi_i32(tmp, float_round_to_zero);
597 break;
598 case QUAL_RM_M:
599 tcg_gen_movi_i32(tmp, float_round_down);
600 break;
601 case QUAL_RM_D:
602 tcg_gen_ld8u_i32(tmp, cpu_env,
603 offsetof(CPUAlphaState, fpcr_dyn_round));
604 break;
607 #if defined(CONFIG_SOFTFLOAT_INLINE)
608 /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
609 With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
610 sets the one field. */
611 tcg_gen_st8_i32(tmp, cpu_env,
612 offsetof(CPUAlphaState, fp_status.float_rounding_mode));
613 #else
614 gen_helper_setroundmode(tmp);
615 #endif
617 tcg_temp_free_i32(tmp);
620 static void gen_qual_flushzero(DisasContext *ctx, int fn11)
622 TCGv_i32 tmp;
624 fn11 &= QUAL_U;
625 if (fn11 == ctx->tb_ftz) {
626 return;
628 ctx->tb_ftz = fn11;
630 tmp = tcg_temp_new_i32();
631 if (fn11) {
632 /* Underflow is enabled, use the FPCR setting. */
633 tcg_gen_ld8u_i32(tmp, cpu_env,
634 offsetof(CPUAlphaState, fpcr_flush_to_zero));
635 } else {
636 /* Underflow is disabled, force flush-to-zero. */
637 tcg_gen_movi_i32(tmp, 1);
640 #if defined(CONFIG_SOFTFLOAT_INLINE)
641 tcg_gen_st8_i32(tmp, cpu_env,
642 offsetof(CPUAlphaState, fp_status.flush_to_zero));
643 #else
644 gen_helper_setflushzero(tmp);
645 #endif
647 tcg_temp_free_i32(tmp);
650 static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
652 TCGv val;
653 if (reg == 31) {
654 val = tcg_const_i64(0);
655 } else {
656 if ((fn11 & QUAL_S) == 0) {
657 if (is_cmp) {
658 gen_helper_ieee_input_cmp(cpu_env, cpu_fir[reg]);
659 } else {
660 gen_helper_ieee_input(cpu_env, cpu_fir[reg]);
663 val = tcg_temp_new();
664 tcg_gen_mov_i64(val, cpu_fir[reg]);
666 return val;
669 static void gen_fp_exc_clear(void)
671 #if defined(CONFIG_SOFTFLOAT_INLINE)
672 TCGv_i32 zero = tcg_const_i32(0);
673 tcg_gen_st8_i32(zero, cpu_env,
674 offsetof(CPUAlphaState, fp_status.float_exception_flags));
675 tcg_temp_free_i32(zero);
676 #else
677 gen_helper_fp_exc_clear(cpu_env);
678 #endif
681 static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
683 /* ??? We ought to be able to do something with imprecise exceptions.
684 E.g. notice we're still in the trap shadow of something within the
685 TB and do not generate the code to signal the exception; end the TB
686 when an exception is forced to arrive, either by consumption of a
687 register value or TRAPB or EXCB. */
688 TCGv_i32 exc = tcg_temp_new_i32();
689 TCGv_i32 reg;
691 #if defined(CONFIG_SOFTFLOAT_INLINE)
692 tcg_gen_ld8u_i32(exc, cpu_env,
693 offsetof(CPUAlphaState, fp_status.float_exception_flags));
694 #else
695 gen_helper_fp_exc_get(exc, cpu_env);
696 #endif
698 if (ignore) {
699 tcg_gen_andi_i32(exc, exc, ~ignore);
702 /* ??? Pass in the regno of the destination so that the helper can
703 set EXC_MASK, which contains a bitmask of destination registers
704 that have caused arithmetic traps. A simple userspace emulation
705 does not require this. We do need it for a guest kernel's entArith,
706 or if we were to do something clever with imprecise exceptions. */
707 reg = tcg_const_i32(rc + 32);
709 if (fn11 & QUAL_S) {
710 gen_helper_fp_exc_raise_s(cpu_env, exc, reg);
711 } else {
712 gen_helper_fp_exc_raise(cpu_env, exc, reg);
715 tcg_temp_free_i32(reg);
716 tcg_temp_free_i32(exc);
719 static inline void gen_fp_exc_raise(int rc, int fn11)
721 gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
724 static void gen_fcvtlq(int rb, int rc)
726 if (unlikely(rc == 31)) {
727 return;
729 if (unlikely(rb == 31)) {
730 tcg_gen_movi_i64(cpu_fir[rc], 0);
731 } else {
732 TCGv tmp = tcg_temp_new();
734 /* The arithmetic right shift here, plus the sign-extended mask below
735 yields a sign-extended result without an explicit ext32s_i64. */
736 tcg_gen_sari_i64(tmp, cpu_fir[rb], 32);
737 tcg_gen_shri_i64(cpu_fir[rc], cpu_fir[rb], 29);
738 tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
739 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rc], 0x3fffffff);
740 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
742 tcg_temp_free(tmp);
746 static void gen_fcvtql(int rb, int rc)
748 if (unlikely(rc == 31)) {
749 return;
751 if (unlikely(rb == 31)) {
752 tcg_gen_movi_i64(cpu_fir[rc], 0);
753 } else {
754 TCGv tmp = tcg_temp_new();
756 tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
757 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
758 tcg_gen_shli_i64(tmp, tmp, 32);
759 tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
760 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
762 tcg_temp_free(tmp);
766 static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
768 if (rb != 31) {
769 int lab = gen_new_label();
770 TCGv tmp = tcg_temp_new();
772 tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
773 tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
774 gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
776 gen_set_label(lab);
778 gen_fcvtql(rb, rc);
781 #define FARITH2(name) \
782 static inline void glue(gen_f, name)(int rb, int rc) \
784 if (unlikely(rc == 31)) { \
785 return; \
787 if (rb != 31) { \
788 gen_helper_ ## name(cpu_fir[rc], cpu_env, cpu_fir[rb]); \
789 } else { \
790 TCGv tmp = tcg_const_i64(0); \
791 gen_helper_ ## name(cpu_fir[rc], cpu_env, tmp); \
792 tcg_temp_free(tmp); \
796 /* ??? VAX instruction qualifiers ignored. */
797 FARITH2(sqrtf)
798 FARITH2(sqrtg)
799 FARITH2(cvtgf)
800 FARITH2(cvtgq)
801 FARITH2(cvtqf)
802 FARITH2(cvtqg)
804 static void gen_ieee_arith2(DisasContext *ctx,
805 void (*helper)(TCGv, TCGv_ptr, TCGv),
806 int rb, int rc, int fn11)
808 TCGv vb;
810 /* ??? This is wrong: the instruction is not a nop, it still may
811 raise exceptions. */
812 if (unlikely(rc == 31)) {
813 return;
816 gen_qual_roundmode(ctx, fn11);
817 gen_qual_flushzero(ctx, fn11);
818 gen_fp_exc_clear();
820 vb = gen_ieee_input(rb, fn11, 0);
821 helper(cpu_fir[rc], cpu_env, vb);
822 tcg_temp_free(vb);
824 gen_fp_exc_raise(rc, fn11);
827 #define IEEE_ARITH2(name) \
828 static inline void glue(gen_f, name)(DisasContext *ctx, \
829 int rb, int rc, int fn11) \
831 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \
833 IEEE_ARITH2(sqrts)
834 IEEE_ARITH2(sqrtt)
835 IEEE_ARITH2(cvtst)
836 IEEE_ARITH2(cvtts)
838 static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
840 TCGv vb;
841 int ignore = 0;
843 /* ??? This is wrong: the instruction is not a nop, it still may
844 raise exceptions. */
845 if (unlikely(rc == 31)) {
846 return;
849 /* No need to set flushzero, since we have an integer output. */
850 gen_fp_exc_clear();
851 vb = gen_ieee_input(rb, fn11, 0);
853 /* Almost all integer conversions use cropped rounding, and most
854 also do not have integer overflow enabled. Special case that. */
855 switch (fn11) {
856 case QUAL_RM_C:
857 gen_helper_cvttq_c(cpu_fir[rc], cpu_env, vb);
858 break;
859 case QUAL_V | QUAL_RM_C:
860 case QUAL_S | QUAL_V | QUAL_RM_C:
861 ignore = float_flag_inexact;
862 /* FALLTHRU */
863 case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
864 gen_helper_cvttq_svic(cpu_fir[rc], cpu_env, vb);
865 break;
866 default:
867 gen_qual_roundmode(ctx, fn11);
868 gen_helper_cvttq(cpu_fir[rc], cpu_env, vb);
869 ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
870 ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
871 break;
873 tcg_temp_free(vb);
875 gen_fp_exc_raise_ignore(rc, fn11, ignore);
878 static void gen_ieee_intcvt(DisasContext *ctx,
879 void (*helper)(TCGv, TCGv_ptr, TCGv),
880 int rb, int rc, int fn11)
882 TCGv vb;
884 /* ??? This is wrong: the instruction is not a nop, it still may
885 raise exceptions. */
886 if (unlikely(rc == 31)) {
887 return;
890 gen_qual_roundmode(ctx, fn11);
892 if (rb == 31) {
893 vb = tcg_const_i64(0);
894 } else {
895 vb = cpu_fir[rb];
898 /* The only exception that can be raised by integer conversion
899 is inexact. Thus we only need to worry about exceptions when
900 inexact handling is requested. */
901 if (fn11 & QUAL_I) {
902 gen_fp_exc_clear();
903 helper(cpu_fir[rc], cpu_env, vb);
904 gen_fp_exc_raise(rc, fn11);
905 } else {
906 helper(cpu_fir[rc], cpu_env, vb);
909 if (rb == 31) {
910 tcg_temp_free(vb);
914 #define IEEE_INTCVT(name) \
915 static inline void glue(gen_f, name)(DisasContext *ctx, \
916 int rb, int rc, int fn11) \
918 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \
920 IEEE_INTCVT(cvtqs)
921 IEEE_INTCVT(cvtqt)
923 static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask)
925 TCGv va, vb, vmask;
926 int za = 0, zb = 0;
928 if (unlikely(rc == 31)) {
929 return;
932 vmask = tcg_const_i64(mask);
934 TCGV_UNUSED_I64(va);
935 if (ra == 31) {
936 if (inv_a) {
937 va = vmask;
938 } else {
939 za = 1;
941 } else {
942 va = tcg_temp_new_i64();
943 tcg_gen_mov_i64(va, cpu_fir[ra]);
944 if (inv_a) {
945 tcg_gen_andc_i64(va, vmask, va);
946 } else {
947 tcg_gen_and_i64(va, va, vmask);
951 TCGV_UNUSED_I64(vb);
952 if (rb == 31) {
953 zb = 1;
954 } else {
955 vb = tcg_temp_new_i64();
956 tcg_gen_andc_i64(vb, cpu_fir[rb], vmask);
959 switch (za << 1 | zb) {
960 case 0 | 0:
961 tcg_gen_or_i64(cpu_fir[rc], va, vb);
962 break;
963 case 0 | 1:
964 tcg_gen_mov_i64(cpu_fir[rc], va);
965 break;
966 case 2 | 0:
967 tcg_gen_mov_i64(cpu_fir[rc], vb);
968 break;
969 case 2 | 1:
970 tcg_gen_movi_i64(cpu_fir[rc], 0);
971 break;
974 tcg_temp_free(vmask);
975 if (ra != 31) {
976 tcg_temp_free(va);
978 if (rb != 31) {
979 tcg_temp_free(vb);
983 static inline void gen_fcpys(int ra, int rb, int rc)
985 gen_cpys_internal(ra, rb, rc, 0, 0x8000000000000000ULL);
988 static inline void gen_fcpysn(int ra, int rb, int rc)
990 gen_cpys_internal(ra, rb, rc, 1, 0x8000000000000000ULL);
993 static inline void gen_fcpyse(int ra, int rb, int rc)
995 gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
998 #define FARITH3(name) \
999 static inline void glue(gen_f, name)(int ra, int rb, int rc) \
1001 TCGv va, vb; \
1003 if (unlikely(rc == 31)) { \
1004 return; \
1006 if (ra == 31) { \
1007 va = tcg_const_i64(0); \
1008 } else { \
1009 va = cpu_fir[ra]; \
1011 if (rb == 31) { \
1012 vb = tcg_const_i64(0); \
1013 } else { \
1014 vb = cpu_fir[rb]; \
1017 gen_helper_ ## name(cpu_fir[rc], cpu_env, va, vb); \
1019 if (ra == 31) { \
1020 tcg_temp_free(va); \
1022 if (rb == 31) { \
1023 tcg_temp_free(vb); \
1027 /* ??? VAX instruction qualifiers ignored. */
1028 FARITH3(addf)
1029 FARITH3(subf)
1030 FARITH3(mulf)
1031 FARITH3(divf)
1032 FARITH3(addg)
1033 FARITH3(subg)
1034 FARITH3(mulg)
1035 FARITH3(divg)
1036 FARITH3(cmpgeq)
1037 FARITH3(cmpglt)
1038 FARITH3(cmpgle)
1040 static void gen_ieee_arith3(DisasContext *ctx,
1041 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
1042 int ra, int rb, int rc, int fn11)
1044 TCGv va, vb;
1046 /* ??? This is wrong: the instruction is not a nop, it still may
1047 raise exceptions. */
1048 if (unlikely(rc == 31)) {
1049 return;
1052 gen_qual_roundmode(ctx, fn11);
1053 gen_qual_flushzero(ctx, fn11);
1054 gen_fp_exc_clear();
1056 va = gen_ieee_input(ra, fn11, 0);
1057 vb = gen_ieee_input(rb, fn11, 0);
1058 helper(cpu_fir[rc], cpu_env, va, vb);
1059 tcg_temp_free(va);
1060 tcg_temp_free(vb);
1062 gen_fp_exc_raise(rc, fn11);
1065 #define IEEE_ARITH3(name) \
1066 static inline void glue(gen_f, name)(DisasContext *ctx, \
1067 int ra, int rb, int rc, int fn11) \
1069 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1071 IEEE_ARITH3(adds)
1072 IEEE_ARITH3(subs)
1073 IEEE_ARITH3(muls)
1074 IEEE_ARITH3(divs)
1075 IEEE_ARITH3(addt)
1076 IEEE_ARITH3(subt)
1077 IEEE_ARITH3(mult)
1078 IEEE_ARITH3(divt)
1080 static void gen_ieee_compare(DisasContext *ctx,
1081 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
1082 int ra, int rb, int rc, int fn11)
1084 TCGv va, vb;
1086 /* ??? This is wrong: the instruction is not a nop, it still may
1087 raise exceptions. */
1088 if (unlikely(rc == 31)) {
1089 return;
1092 gen_fp_exc_clear();
1094 va = gen_ieee_input(ra, fn11, 1);
1095 vb = gen_ieee_input(rb, fn11, 1);
1096 helper(cpu_fir[rc], cpu_env, va, vb);
1097 tcg_temp_free(va);
1098 tcg_temp_free(vb);
1100 gen_fp_exc_raise(rc, fn11);
1103 #define IEEE_CMP3(name) \
1104 static inline void glue(gen_f, name)(DisasContext *ctx, \
1105 int ra, int rb, int rc, int fn11) \
1107 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1109 IEEE_CMP3(cmptun)
1110 IEEE_CMP3(cmpteq)
1111 IEEE_CMP3(cmptlt)
1112 IEEE_CMP3(cmptle)
1114 static inline uint64_t zapnot_mask(uint8_t lit)
1116 uint64_t mask = 0;
1117 int i;
1119 for (i = 0; i < 8; ++i) {
1120 if ((lit >> i) & 1)
1121 mask |= 0xffull << (i * 8);
1123 return mask;
1126 /* Implement zapnot with an immediate operand, which expands to some
1127 form of immediate AND. This is a basic building block in the
1128 definition of many of the other byte manipulation instructions. */
1129 static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
1131 switch (lit) {
1132 case 0x00:
1133 tcg_gen_movi_i64(dest, 0);
1134 break;
1135 case 0x01:
1136 tcg_gen_ext8u_i64(dest, src);
1137 break;
1138 case 0x03:
1139 tcg_gen_ext16u_i64(dest, src);
1140 break;
1141 case 0x0f:
1142 tcg_gen_ext32u_i64(dest, src);
1143 break;
1144 case 0xff:
1145 tcg_gen_mov_i64(dest, src);
1146 break;
1147 default:
1148 tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
1149 break;
1153 static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
1155 if (unlikely(rc == 31))
1156 return;
1157 else if (unlikely(ra == 31))
1158 tcg_gen_movi_i64(cpu_ir[rc], 0);
1159 else if (islit)
1160 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
1161 else
1162 gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1165 static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
1167 if (unlikely(rc == 31))
1168 return;
1169 else if (unlikely(ra == 31))
1170 tcg_gen_movi_i64(cpu_ir[rc], 0);
1171 else if (islit)
1172 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
1173 else
1174 gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1178 /* EXTWH, EXTLH, EXTQH */
1179 static void gen_ext_h(int ra, int rb, int rc, int islit,
1180 uint8_t lit, uint8_t byte_mask)
1182 if (unlikely(rc == 31))
1183 return;
1184 else if (unlikely(ra == 31))
1185 tcg_gen_movi_i64(cpu_ir[rc], 0);
1186 else {
1187 if (islit) {
1188 lit = (64 - (lit & 7) * 8) & 0x3f;
1189 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1190 } else {
1191 TCGv tmp1 = tcg_temp_new();
1192 tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
1193 tcg_gen_shli_i64(tmp1, tmp1, 3);
1194 tcg_gen_neg_i64(tmp1, tmp1);
1195 tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1196 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
1197 tcg_temp_free(tmp1);
1199 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1203 /* EXTBL, EXTWL, EXTLL, EXTQL */
1204 static void gen_ext_l(int ra, int rb, int rc, int islit,
1205 uint8_t lit, uint8_t byte_mask)
1207 if (unlikely(rc == 31))
1208 return;
1209 else if (unlikely(ra == 31))
1210 tcg_gen_movi_i64(cpu_ir[rc], 0);
1211 else {
1212 if (islit) {
1213 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
1214 } else {
1215 TCGv tmp = tcg_temp_new();
1216 tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
1217 tcg_gen_shli_i64(tmp, tmp, 3);
1218 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
1219 tcg_temp_free(tmp);
1221 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1225 /* INSWH, INSLH, INSQH */
1226 static void gen_ins_h(int ra, int rb, int rc, int islit,
1227 uint8_t lit, uint8_t byte_mask)
1229 if (unlikely(rc == 31))
1230 return;
1231 else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
1232 tcg_gen_movi_i64(cpu_ir[rc], 0);
1233 else {
1234 TCGv tmp = tcg_temp_new();
1236 /* The instruction description has us left-shift the byte mask
1237 and extract bits <15:8> and apply that zap at the end. This
1238 is equivalent to simply performing the zap first and shifting
1239 afterward. */
1240 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1242 if (islit) {
1243 /* Note that we have handled the lit==0 case above. */
1244 tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
1245 } else {
1246 TCGv shift = tcg_temp_new();
1248 /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
1249 Do this portably by splitting the shift into two parts:
1250 shift_count-1 and 1. Arrange for the -1 by using
1251 ones-complement instead of twos-complement in the negation:
1252 ~((B & 7) * 8) & 63. */
1254 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1255 tcg_gen_shli_i64(shift, shift, 3);
1256 tcg_gen_not_i64(shift, shift);
1257 tcg_gen_andi_i64(shift, shift, 0x3f);
1259 tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
1260 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
1261 tcg_temp_free(shift);
1263 tcg_temp_free(tmp);
1267 /* INSBL, INSWL, INSLL, INSQL */
1268 static void gen_ins_l(int ra, int rb, int rc, int islit,
1269 uint8_t lit, uint8_t byte_mask)
1271 if (unlikely(rc == 31))
1272 return;
1273 else if (unlikely(ra == 31))
1274 tcg_gen_movi_i64(cpu_ir[rc], 0);
1275 else {
1276 TCGv tmp = tcg_temp_new();
1278 /* The instruction description has us left-shift the byte mask
1279 the same number of byte slots as the data and apply the zap
1280 at the end. This is equivalent to simply performing the zap
1281 first and shifting afterward. */
1282 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1284 if (islit) {
1285 tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
1286 } else {
1287 TCGv shift = tcg_temp_new();
1288 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1289 tcg_gen_shli_i64(shift, shift, 3);
1290 tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
1291 tcg_temp_free(shift);
1293 tcg_temp_free(tmp);
1297 /* MSKWH, MSKLH, MSKQH */
1298 static void gen_msk_h(int ra, int rb, int rc, int islit,
1299 uint8_t lit, uint8_t byte_mask)
1301 if (unlikely(rc == 31))
1302 return;
1303 else if (unlikely(ra == 31))
1304 tcg_gen_movi_i64(cpu_ir[rc], 0);
1305 else if (islit) {
1306 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
1307 } else {
1308 TCGv shift = tcg_temp_new();
1309 TCGv mask = tcg_temp_new();
1311 /* The instruction description is as above, where the byte_mask
1312 is shifted left, and then we extract bits <15:8>. This can be
1313 emulated with a right-shift on the expanded byte mask. This
1314 requires extra care because for an input <2:0> == 0 we need a
1315 shift of 64 bits in order to generate a zero. This is done by
1316 splitting the shift into two parts, the variable shift - 1
1317 followed by a constant 1 shift. The code we expand below is
1318 equivalent to ~((B & 7) * 8) & 63. */
1320 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1321 tcg_gen_shli_i64(shift, shift, 3);
1322 tcg_gen_not_i64(shift, shift);
1323 tcg_gen_andi_i64(shift, shift, 0x3f);
1324 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1325 tcg_gen_shr_i64(mask, mask, shift);
1326 tcg_gen_shri_i64(mask, mask, 1);
1328 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1330 tcg_temp_free(mask);
1331 tcg_temp_free(shift);
1335 /* MSKBL, MSKWL, MSKLL, MSKQL */
1336 static void gen_msk_l(int ra, int rb, int rc, int islit,
1337 uint8_t lit, uint8_t byte_mask)
1339 if (unlikely(rc == 31))
1340 return;
1341 else if (unlikely(ra == 31))
1342 tcg_gen_movi_i64(cpu_ir[rc], 0);
1343 else if (islit) {
1344 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
1345 } else {
1346 TCGv shift = tcg_temp_new();
1347 TCGv mask = tcg_temp_new();
1349 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1350 tcg_gen_shli_i64(shift, shift, 3);
1351 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1352 tcg_gen_shl_i64(mask, mask, shift);
1354 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1356 tcg_temp_free(mask);
1357 tcg_temp_free(shift);
1361 /* Code to call arith3 helpers */
1362 #define ARITH3(name) \
1363 static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
1364 uint8_t lit) \
1366 if (unlikely(rc == 31)) \
1367 return; \
1369 if (ra != 31) { \
1370 if (islit) { \
1371 TCGv tmp = tcg_const_i64(lit); \
1372 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
1373 tcg_temp_free(tmp); \
1374 } else \
1375 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1376 } else { \
1377 TCGv tmp1 = tcg_const_i64(0); \
1378 if (islit) { \
1379 TCGv tmp2 = tcg_const_i64(lit); \
1380 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
1381 tcg_temp_free(tmp2); \
1382 } else \
1383 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
1384 tcg_temp_free(tmp1); \
1387 ARITH3(cmpbge)
1388 ARITH3(minub8)
1389 ARITH3(minsb8)
1390 ARITH3(minuw4)
1391 ARITH3(minsw4)
1392 ARITH3(maxub8)
1393 ARITH3(maxsb8)
1394 ARITH3(maxuw4)
1395 ARITH3(maxsw4)
1396 ARITH3(perr)
1398 /* Code to call arith3 helpers */
1399 #define ARITH3_EX(name) \
1400 static inline void glue(gen_, name)(int ra, int rb, int rc, \
1401 int islit, uint8_t lit) \
1403 if (unlikely(rc == 31)) { \
1404 return; \
1406 if (ra != 31) { \
1407 if (islit) { \
1408 TCGv tmp = tcg_const_i64(lit); \
1409 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1410 cpu_ir[ra], tmp); \
1411 tcg_temp_free(tmp); \
1412 } else { \
1413 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1414 cpu_ir[ra], cpu_ir[rb]); \
1416 } else { \
1417 TCGv tmp1 = tcg_const_i64(0); \
1418 if (islit) { \
1419 TCGv tmp2 = tcg_const_i64(lit); \
1420 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2); \
1421 tcg_temp_free(tmp2); \
1422 } else { \
1423 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
1425 tcg_temp_free(tmp1); \
1428 ARITH3_EX(addlv)
1429 ARITH3_EX(sublv)
1430 ARITH3_EX(addqv)
1431 ARITH3_EX(subqv)
1432 ARITH3_EX(mullv)
1433 ARITH3_EX(mulqv)
1435 #define MVIOP2(name) \
1436 static inline void glue(gen_, name)(int rb, int rc) \
1438 if (unlikely(rc == 31)) \
1439 return; \
1440 if (unlikely(rb == 31)) \
1441 tcg_gen_movi_i64(cpu_ir[rc], 0); \
1442 else \
1443 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
1445 MVIOP2(pklb)
1446 MVIOP2(pkwb)
1447 MVIOP2(unpkbl)
1448 MVIOP2(unpkbw)
1450 static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
1451 int islit, uint8_t lit)
1453 TCGv va, vb;
1455 if (unlikely(rc == 31)) {
1456 return;
1459 if (ra == 31) {
1460 va = tcg_const_i64(0);
1461 } else {
1462 va = cpu_ir[ra];
1464 if (islit) {
1465 vb = tcg_const_i64(lit);
1466 } else {
1467 vb = cpu_ir[rb];
1470 tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
1472 if (ra == 31) {
1473 tcg_temp_free(va);
1475 if (islit) {
1476 tcg_temp_free(vb);
1480 static void gen_rx(int ra, int set)
1482 TCGv_i32 tmp;
1484 if (ra != 31) {
1485 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, offsetof(CPUAlphaState, intr_flag));
1488 tmp = tcg_const_i32(set);
1489 tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUAlphaState, intr_flag));
1490 tcg_temp_free_i32(tmp);
1493 static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1495 /* We're emulating OSF/1 PALcode. Many of these are trivial access
1496 to internal cpu registers. */
1498 /* Unprivileged PAL call */
1499 if (palcode >= 0x80 && palcode < 0xC0) {
1500 switch (palcode) {
1501 case 0x86:
1502 /* IMB */
1503 /* No-op inside QEMU. */
1504 break;
1505 case 0x9E:
1506 /* RDUNIQUE */
1507 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
1508 break;
1509 case 0x9F:
1510 /* WRUNIQUE */
1511 tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
1512 break;
1513 default:
1514 palcode &= 0xbf;
1515 goto do_call_pal;
1517 return NO_EXIT;
1520 #ifndef CONFIG_USER_ONLY
1521 /* Privileged PAL code */
1522 if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1523 switch (palcode) {
1524 case 0x01:
1525 /* CFLUSH */
1526 /* No-op inside QEMU. */
1527 break;
1528 case 0x02:
1529 /* DRAINA */
1530 /* No-op inside QEMU. */
1531 break;
1532 case 0x2D:
1533 /* WRVPTPTR */
1534 tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUAlphaState, vptptr));
1535 break;
1536 case 0x31:
1537 /* WRVAL */
1538 tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
1539 break;
1540 case 0x32:
1541 /* RDVAL */
1542 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
1543 break;
1545 case 0x35: {
1546 /* SWPIPL */
1547 TCGv tmp;
1549 /* Note that we already know we're in kernel mode, so we know
1550 that PS only contains the 3 IPL bits. */
1551 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
1553 /* But make sure and store only the 3 IPL bits from the user. */
1554 tmp = tcg_temp_new();
1555 tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
1556 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps));
1557 tcg_temp_free(tmp);
1558 break;
1561 case 0x36:
1562 /* RDPS */
1563 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
1564 break;
1565 case 0x38:
1566 /* WRUSP */
1567 tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
1568 break;
1569 case 0x3A:
1570 /* RDUSP */
1571 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
1572 break;
1573 case 0x3C:
1574 /* WHAMI */
1575 tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
1576 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1577 break;
1579 default:
1580 palcode &= 0x3f;
1581 goto do_call_pal;
1583 return NO_EXIT;
1585 #endif
1586 return gen_invalid(ctx);
1588 do_call_pal:
1589 #ifdef CONFIG_USER_ONLY
1590 return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1591 #else
1593 TCGv pc = tcg_const_i64(ctx->pc);
1594 TCGv entry = tcg_const_i64(palcode & 0x80
1595 ? 0x2000 + (palcode - 0x80) * 64
1596 : 0x1000 + palcode * 64);
1598 gen_helper_call_pal(cpu_env, pc, entry);
1600 tcg_temp_free(entry);
1601 tcg_temp_free(pc);
1603 /* Since the destination is running in PALmode, we don't really
1604 need the page permissions check. We'll see the existence of
1605 the page when we create the TB, and we'll flush all TBs if
1606 we change the PAL base register. */
1607 if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
1608 tcg_gen_goto_tb(0);
1609 tcg_gen_exit_tb((uintptr_t)ctx->tb);
1610 return EXIT_GOTO_TB;
1613 return EXIT_PC_UPDATED;
1615 #endif
1618 #ifndef CONFIG_USER_ONLY
1620 #define PR_BYTE 0x100000
1621 #define PR_LONG 0x200000
1623 static int cpu_pr_data(int pr)
1625 switch (pr) {
1626 case 0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
1627 case 1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
1628 case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1629 case 3: return offsetof(CPUAlphaState, trap_arg0);
1630 case 4: return offsetof(CPUAlphaState, trap_arg1);
1631 case 5: return offsetof(CPUAlphaState, trap_arg2);
1632 case 6: return offsetof(CPUAlphaState, exc_addr);
1633 case 7: return offsetof(CPUAlphaState, palbr);
1634 case 8: return offsetof(CPUAlphaState, ptbr);
1635 case 9: return offsetof(CPUAlphaState, vptptr);
1636 case 10: return offsetof(CPUAlphaState, unique);
1637 case 11: return offsetof(CPUAlphaState, sysval);
1638 case 12: return offsetof(CPUAlphaState, usp);
1640 case 32 ... 39:
1641 return offsetof(CPUAlphaState, shadow[pr - 32]);
1642 case 40 ... 63:
1643 return offsetof(CPUAlphaState, scratch[pr - 40]);
1645 case 251:
1646 return offsetof(CPUAlphaState, alarm_expire);
1648 return 0;
1651 static ExitStatus gen_mfpr(int ra, int regno)
1653 int data = cpu_pr_data(regno);
1655 /* In our emulated PALcode, these processor registers have no
1656 side effects from reading. */
1657 if (ra == 31) {
1658 return NO_EXIT;
1661 /* Special help for VMTIME and WALLTIME. */
1662 if (regno == 250 || regno == 249) {
1663 void (*helper)(TCGv) = gen_helper_get_walltime;
1664 if (regno == 249) {
1665 helper = gen_helper_get_vmtime;
1667 if (use_icount) {
1668 gen_io_start();
1669 helper(cpu_ir[ra]);
1670 gen_io_end();
1671 return EXIT_PC_STALE;
1672 } else {
1673 helper(cpu_ir[ra]);
1674 return NO_EXIT;
1678 /* The basic registers are data only, and unknown registers
1679 are read-zero, write-ignore. */
1680 if (data == 0) {
1681 tcg_gen_movi_i64(cpu_ir[ra], 0);
1682 } else if (data & PR_BYTE) {
1683 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
1684 } else if (data & PR_LONG) {
1685 tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
1686 } else {
1687 tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
1689 return NO_EXIT;
1692 static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
1694 TCGv tmp;
1695 int data;
1697 if (rb == 31) {
1698 tmp = tcg_const_i64(0);
1699 } else {
1700 tmp = cpu_ir[rb];
1703 switch (regno) {
1704 case 255:
1705 /* TBIA */
1706 gen_helper_tbia(cpu_env);
1707 break;
1709 case 254:
1710 /* TBIS */
1711 gen_helper_tbis(cpu_env, tmp);
1712 break;
1714 case 253:
1715 /* WAIT */
1716 tmp = tcg_const_i64(1);
1717 tcg_gen_st32_i64(tmp, cpu_env, -offsetof(AlphaCPU, env) +
1718 offsetof(CPUState, halted));
1719 return gen_excp(ctx, EXCP_HLT, 0);
1721 case 252:
1722 /* HALT */
1723 gen_helper_halt(tmp);
1724 return EXIT_PC_STALE;
1726 case 251:
1727 /* ALARM */
1728 gen_helper_set_alarm(cpu_env, tmp);
1729 break;
1731 case 7:
1732 /* PALBR */
1733 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, palbr));
1734 /* Changing the PAL base register implies un-chaining all of the TBs
1735 that ended with a CALL_PAL. Since the base register usually only
1736 changes during boot, flushing everything works well. */
1737 gen_helper_tb_flush(cpu_env);
1738 return EXIT_PC_STALE;
1740 default:
1741 /* The basic registers are data only, and unknown registers
1742 are read-zero, write-ignore. */
1743 data = cpu_pr_data(regno);
1744 if (data != 0) {
1745 if (data & PR_BYTE) {
1746 tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
1747 } else if (data & PR_LONG) {
1748 tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
1749 } else {
1750 tcg_gen_st_i64(tmp, cpu_env, data);
1753 break;
1756 if (rb == 31) {
1757 tcg_temp_free(tmp);
1760 return NO_EXIT;
1762 #endif /* !USER_ONLY*/
1764 static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1766 uint32_t palcode;
1767 int32_t disp21, disp16;
1768 #ifndef CONFIG_USER_ONLY
1769 int32_t disp12;
1770 #endif
1771 uint16_t fn11;
1772 uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit;
1773 uint8_t lit;
1774 ExitStatus ret;
1776 /* Decode all instruction fields */
1777 opc = insn >> 26;
1778 ra = (insn >> 21) & 0x1F;
1779 rb = (insn >> 16) & 0x1F;
1780 rc = insn & 0x1F;
1781 real_islit = islit = (insn >> 12) & 1;
1782 if (rb == 31 && !islit) {
1783 islit = 1;
1784 lit = 0;
1785 } else
1786 lit = (insn >> 13) & 0xFF;
1787 palcode = insn & 0x03FFFFFF;
1788 disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
1789 disp16 = (int16_t)(insn & 0x0000FFFF);
1790 #ifndef CONFIG_USER_ONLY
1791 disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
1792 #endif
1793 fn11 = (insn >> 5) & 0x000007FF;
1794 fpfn = fn11 & 0x3F;
1795 fn7 = (insn >> 5) & 0x0000007F;
1796 LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1797 opc, ra, rb, rc, disp16);
1799 ret = NO_EXIT;
1800 switch (opc) {
1801 case 0x00:
1802 /* CALL_PAL */
1803 ret = gen_call_pal(ctx, palcode);
1804 break;
1805 case 0x01:
1806 /* OPC01 */
1807 goto invalid_opc;
1808 case 0x02:
1809 /* OPC02 */
1810 goto invalid_opc;
1811 case 0x03:
1812 /* OPC03 */
1813 goto invalid_opc;
1814 case 0x04:
1815 /* OPC04 */
1816 goto invalid_opc;
1817 case 0x05:
1818 /* OPC05 */
1819 goto invalid_opc;
1820 case 0x06:
1821 /* OPC06 */
1822 goto invalid_opc;
1823 case 0x07:
1824 /* OPC07 */
1825 goto invalid_opc;
1826 case 0x08:
1827 /* LDA */
1828 if (likely(ra != 31)) {
1829 if (rb != 31)
1830 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
1831 else
1832 tcg_gen_movi_i64(cpu_ir[ra], disp16);
1834 break;
1835 case 0x09:
1836 /* LDAH */
1837 if (likely(ra != 31)) {
1838 if (rb != 31)
1839 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
1840 else
1841 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
1843 break;
1844 case 0x0A:
1845 /* LDBU */
1846 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1847 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1848 break;
1850 goto invalid_opc;
1851 case 0x0B:
1852 /* LDQ_U */
1853 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1854 break;
1855 case 0x0C:
1856 /* LDWU */
1857 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1858 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1859 break;
1861 goto invalid_opc;
1862 case 0x0D:
1863 /* STW */
1864 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1865 break;
1866 case 0x0E:
1867 /* STB */
1868 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1869 break;
1870 case 0x0F:
1871 /* STQ_U */
1872 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1873 break;
1874 case 0x10:
1875 switch (fn7) {
1876 case 0x00:
1877 /* ADDL */
1878 if (likely(rc != 31)) {
1879 if (ra != 31) {
1880 if (islit) {
1881 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1882 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1883 } else {
1884 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1885 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1887 } else {
1888 if (islit)
1889 tcg_gen_movi_i64(cpu_ir[rc], lit);
1890 else
1891 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1894 break;
1895 case 0x02:
1896 /* S4ADDL */
1897 if (likely(rc != 31)) {
1898 if (ra != 31) {
1899 TCGv tmp = tcg_temp_new();
1900 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1901 if (islit)
1902 tcg_gen_addi_i64(tmp, tmp, lit);
1903 else
1904 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1905 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1906 tcg_temp_free(tmp);
1907 } else {
1908 if (islit)
1909 tcg_gen_movi_i64(cpu_ir[rc], lit);
1910 else
1911 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1914 break;
1915 case 0x09:
1916 /* SUBL */
1917 if (likely(rc != 31)) {
1918 if (ra != 31) {
1919 if (islit)
1920 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1921 else
1922 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1923 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1924 } else {
1925 if (islit)
1926 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1927 else {
1928 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1929 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1932 break;
1933 case 0x0B:
1934 /* S4SUBL */
1935 if (likely(rc != 31)) {
1936 if (ra != 31) {
1937 TCGv tmp = tcg_temp_new();
1938 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1939 if (islit)
1940 tcg_gen_subi_i64(tmp, tmp, lit);
1941 else
1942 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1943 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1944 tcg_temp_free(tmp);
1945 } else {
1946 if (islit)
1947 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1948 else {
1949 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1950 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1954 break;
1955 case 0x0F:
1956 /* CMPBGE */
1957 gen_cmpbge(ra, rb, rc, islit, lit);
1958 break;
1959 case 0x12:
1960 /* S8ADDL */
1961 if (likely(rc != 31)) {
1962 if (ra != 31) {
1963 TCGv tmp = tcg_temp_new();
1964 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1965 if (islit)
1966 tcg_gen_addi_i64(tmp, tmp, lit);
1967 else
1968 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1969 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1970 tcg_temp_free(tmp);
1971 } else {
1972 if (islit)
1973 tcg_gen_movi_i64(cpu_ir[rc], lit);
1974 else
1975 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1978 break;
1979 case 0x1B:
1980 /* S8SUBL */
1981 if (likely(rc != 31)) {
1982 if (ra != 31) {
1983 TCGv tmp = tcg_temp_new();
1984 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1985 if (islit)
1986 tcg_gen_subi_i64(tmp, tmp, lit);
1987 else
1988 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1989 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1990 tcg_temp_free(tmp);
1991 } else {
1992 if (islit)
1993 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1994 else
1995 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1996 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2000 break;
2001 case 0x1D:
2002 /* CMPULT */
2003 gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
2004 break;
2005 case 0x20:
2006 /* ADDQ */
2007 if (likely(rc != 31)) {
2008 if (ra != 31) {
2009 if (islit)
2010 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2011 else
2012 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2013 } else {
2014 if (islit)
2015 tcg_gen_movi_i64(cpu_ir[rc], lit);
2016 else
2017 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2020 break;
2021 case 0x22:
2022 /* S4ADDQ */
2023 if (likely(rc != 31)) {
2024 if (ra != 31) {
2025 TCGv tmp = tcg_temp_new();
2026 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
2027 if (islit)
2028 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
2029 else
2030 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2031 tcg_temp_free(tmp);
2032 } else {
2033 if (islit)
2034 tcg_gen_movi_i64(cpu_ir[rc], lit);
2035 else
2036 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2039 break;
2040 case 0x29:
2041 /* SUBQ */
2042 if (likely(rc != 31)) {
2043 if (ra != 31) {
2044 if (islit)
2045 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2046 else
2047 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2048 } else {
2049 if (islit)
2050 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2051 else
2052 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2055 break;
2056 case 0x2B:
2057 /* S4SUBQ */
2058 if (likely(rc != 31)) {
2059 if (ra != 31) {
2060 TCGv tmp = tcg_temp_new();
2061 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
2062 if (islit)
2063 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
2064 else
2065 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2066 tcg_temp_free(tmp);
2067 } else {
2068 if (islit)
2069 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2070 else
2071 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2074 break;
2075 case 0x2D:
2076 /* CMPEQ */
2077 gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
2078 break;
2079 case 0x32:
2080 /* S8ADDQ */
2081 if (likely(rc != 31)) {
2082 if (ra != 31) {
2083 TCGv tmp = tcg_temp_new();
2084 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
2085 if (islit)
2086 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
2087 else
2088 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2089 tcg_temp_free(tmp);
2090 } else {
2091 if (islit)
2092 tcg_gen_movi_i64(cpu_ir[rc], lit);
2093 else
2094 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2097 break;
2098 case 0x3B:
2099 /* S8SUBQ */
2100 if (likely(rc != 31)) {
2101 if (ra != 31) {
2102 TCGv tmp = tcg_temp_new();
2103 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
2104 if (islit)
2105 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
2106 else
2107 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2108 tcg_temp_free(tmp);
2109 } else {
2110 if (islit)
2111 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2112 else
2113 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2116 break;
2117 case 0x3D:
2118 /* CMPULE */
2119 gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
2120 break;
2121 case 0x40:
2122 /* ADDL/V */
2123 gen_addlv(ra, rb, rc, islit, lit);
2124 break;
2125 case 0x49:
2126 /* SUBL/V */
2127 gen_sublv(ra, rb, rc, islit, lit);
2128 break;
2129 case 0x4D:
2130 /* CMPLT */
2131 gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
2132 break;
2133 case 0x60:
2134 /* ADDQ/V */
2135 gen_addqv(ra, rb, rc, islit, lit);
2136 break;
2137 case 0x69:
2138 /* SUBQ/V */
2139 gen_subqv(ra, rb, rc, islit, lit);
2140 break;
2141 case 0x6D:
2142 /* CMPLE */
2143 gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
2144 break;
2145 default:
2146 goto invalid_opc;
2148 break;
2149 case 0x11:
2150 switch (fn7) {
2151 case 0x00:
2152 /* AND */
2153 if (likely(rc != 31)) {
2154 if (ra == 31)
2155 tcg_gen_movi_i64(cpu_ir[rc], 0);
2156 else if (islit)
2157 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2158 else
2159 tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2161 break;
2162 case 0x08:
2163 /* BIC */
2164 if (likely(rc != 31)) {
2165 if (ra != 31) {
2166 if (islit)
2167 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2168 else
2169 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2170 } else
2171 tcg_gen_movi_i64(cpu_ir[rc], 0);
2173 break;
2174 case 0x14:
2175 /* CMOVLBS */
2176 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
2177 break;
2178 case 0x16:
2179 /* CMOVLBC */
2180 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
2181 break;
2182 case 0x20:
2183 /* BIS */
2184 if (likely(rc != 31)) {
2185 if (ra != 31) {
2186 if (islit)
2187 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2188 else
2189 tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2190 } else {
2191 if (islit)
2192 tcg_gen_movi_i64(cpu_ir[rc], lit);
2193 else
2194 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2197 break;
2198 case 0x24:
2199 /* CMOVEQ */
2200 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
2201 break;
2202 case 0x26:
2203 /* CMOVNE */
2204 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
2205 break;
2206 case 0x28:
2207 /* ORNOT */
2208 if (likely(rc != 31)) {
2209 if (ra != 31) {
2210 if (islit)
2211 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2212 else
2213 tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2214 } else {
2215 if (islit)
2216 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2217 else
2218 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2221 break;
2222 case 0x40:
2223 /* XOR */
2224 if (likely(rc != 31)) {
2225 if (ra != 31) {
2226 if (islit)
2227 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2228 else
2229 tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2230 } else {
2231 if (islit)
2232 tcg_gen_movi_i64(cpu_ir[rc], lit);
2233 else
2234 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2237 break;
2238 case 0x44:
2239 /* CMOVLT */
2240 gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
2241 break;
2242 case 0x46:
2243 /* CMOVGE */
2244 gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
2245 break;
2246 case 0x48:
2247 /* EQV */
2248 if (likely(rc != 31)) {
2249 if (ra != 31) {
2250 if (islit)
2251 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2252 else
2253 tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2254 } else {
2255 if (islit)
2256 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2257 else
2258 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2261 break;
2262 case 0x61:
2263 /* AMASK */
2264 if (likely(rc != 31)) {
2265 uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
2267 if (islit) {
2268 tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
2269 } else {
2270 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
2273 break;
2274 case 0x64:
2275 /* CMOVLE */
2276 gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
2277 break;
2278 case 0x66:
2279 /* CMOVGT */
2280 gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
2281 break;
2282 case 0x6C:
2283 /* IMPLVER */
2284 if (rc != 31) {
2285 tcg_gen_movi_i64(cpu_ir[rc], ctx->implver);
2287 break;
2288 default:
2289 goto invalid_opc;
2291 break;
2292 case 0x12:
2293 switch (fn7) {
2294 case 0x02:
2295 /* MSKBL */
2296 gen_msk_l(ra, rb, rc, islit, lit, 0x01);
2297 break;
2298 case 0x06:
2299 /* EXTBL */
2300 gen_ext_l(ra, rb, rc, islit, lit, 0x01);
2301 break;
2302 case 0x0B:
2303 /* INSBL */
2304 gen_ins_l(ra, rb, rc, islit, lit, 0x01);
2305 break;
2306 case 0x12:
2307 /* MSKWL */
2308 gen_msk_l(ra, rb, rc, islit, lit, 0x03);
2309 break;
2310 case 0x16:
2311 /* EXTWL */
2312 gen_ext_l(ra, rb, rc, islit, lit, 0x03);
2313 break;
2314 case 0x1B:
2315 /* INSWL */
2316 gen_ins_l(ra, rb, rc, islit, lit, 0x03);
2317 break;
2318 case 0x22:
2319 /* MSKLL */
2320 gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
2321 break;
2322 case 0x26:
2323 /* EXTLL */
2324 gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
2325 break;
2326 case 0x2B:
2327 /* INSLL */
2328 gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
2329 break;
2330 case 0x30:
2331 /* ZAP */
2332 gen_zap(ra, rb, rc, islit, lit);
2333 break;
2334 case 0x31:
2335 /* ZAPNOT */
2336 gen_zapnot(ra, rb, rc, islit, lit);
2337 break;
2338 case 0x32:
2339 /* MSKQL */
2340 gen_msk_l(ra, rb, rc, islit, lit, 0xff);
2341 break;
2342 case 0x34:
2343 /* SRL */
2344 if (likely(rc != 31)) {
2345 if (ra != 31) {
2346 if (islit)
2347 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2348 else {
2349 TCGv shift = tcg_temp_new();
2350 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2351 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
2352 tcg_temp_free(shift);
2354 } else
2355 tcg_gen_movi_i64(cpu_ir[rc], 0);
2357 break;
2358 case 0x36:
2359 /* EXTQL */
2360 gen_ext_l(ra, rb, rc, islit, lit, 0xff);
2361 break;
2362 case 0x39:
2363 /* SLL */
2364 if (likely(rc != 31)) {
2365 if (ra != 31) {
2366 if (islit)
2367 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2368 else {
2369 TCGv shift = tcg_temp_new();
2370 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2371 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
2372 tcg_temp_free(shift);
2374 } else
2375 tcg_gen_movi_i64(cpu_ir[rc], 0);
2377 break;
2378 case 0x3B:
2379 /* INSQL */
2380 gen_ins_l(ra, rb, rc, islit, lit, 0xff);
2381 break;
2382 case 0x3C:
2383 /* SRA */
2384 if (likely(rc != 31)) {
2385 if (ra != 31) {
2386 if (islit)
2387 tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2388 else {
2389 TCGv shift = tcg_temp_new();
2390 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2391 tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
2392 tcg_temp_free(shift);
2394 } else
2395 tcg_gen_movi_i64(cpu_ir[rc], 0);
2397 break;
2398 case 0x52:
2399 /* MSKWH */
2400 gen_msk_h(ra, rb, rc, islit, lit, 0x03);
2401 break;
2402 case 0x57:
2403 /* INSWH */
2404 gen_ins_h(ra, rb, rc, islit, lit, 0x03);
2405 break;
2406 case 0x5A:
2407 /* EXTWH */
2408 gen_ext_h(ra, rb, rc, islit, lit, 0x03);
2409 break;
2410 case 0x62:
2411 /* MSKLH */
2412 gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
2413 break;
2414 case 0x67:
2415 /* INSLH */
2416 gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
2417 break;
2418 case 0x6A:
2419 /* EXTLH */
2420 gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
2421 break;
2422 case 0x72:
2423 /* MSKQH */
2424 gen_msk_h(ra, rb, rc, islit, lit, 0xff);
2425 break;
2426 case 0x77:
2427 /* INSQH */
2428 gen_ins_h(ra, rb, rc, islit, lit, 0xff);
2429 break;
2430 case 0x7A:
2431 /* EXTQH */
2432 gen_ext_h(ra, rb, rc, islit, lit, 0xff);
2433 break;
2434 default:
2435 goto invalid_opc;
2437 break;
2438 case 0x13:
2439 switch (fn7) {
2440 case 0x00:
2441 /* MULL */
2442 if (likely(rc != 31)) {
2443 if (ra == 31)
2444 tcg_gen_movi_i64(cpu_ir[rc], 0);
2445 else {
2446 if (islit)
2447 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2448 else
2449 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2450 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2453 break;
2454 case 0x20:
2455 /* MULQ */
2456 if (likely(rc != 31)) {
2457 if (ra == 31)
2458 tcg_gen_movi_i64(cpu_ir[rc], 0);
2459 else if (islit)
2460 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2461 else
2462 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2464 break;
2465 case 0x30:
2466 /* UMULH */
2468 TCGv low;
2469 if (unlikely(rc == 31)){
2470 break;
2472 if (ra == 31) {
2473 tcg_gen_movi_i64(cpu_ir[rc], 0);
2474 break;
2476 low = tcg_temp_new();
2477 if (islit) {
2478 tcg_gen_movi_tl(low, lit);
2479 tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], low);
2480 } else {
2481 tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2483 tcg_temp_free(low);
2485 break;
2486 case 0x40:
2487 /* MULL/V */
2488 gen_mullv(ra, rb, rc, islit, lit);
2489 break;
2490 case 0x60:
2491 /* MULQ/V */
2492 gen_mulqv(ra, rb, rc, islit, lit);
2493 break;
2494 default:
2495 goto invalid_opc;
2497 break;
2498 case 0x14:
2499 switch (fpfn) { /* fn11 & 0x3F */
2500 case 0x04:
2501 /* ITOFS */
2502 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2503 goto invalid_opc;
2505 if (likely(rc != 31)) {
2506 if (ra != 31) {
2507 TCGv_i32 tmp = tcg_temp_new_i32();
2508 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2509 gen_helper_memory_to_s(cpu_fir[rc], tmp);
2510 tcg_temp_free_i32(tmp);
2511 } else
2512 tcg_gen_movi_i64(cpu_fir[rc], 0);
2514 break;
2515 case 0x0A:
2516 /* SQRTF */
2517 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2518 gen_fsqrtf(rb, rc);
2519 break;
2521 goto invalid_opc;
2522 case 0x0B:
2523 /* SQRTS */
2524 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2525 gen_fsqrts(ctx, rb, rc, fn11);
2526 break;
2528 goto invalid_opc;
2529 case 0x14:
2530 /* ITOFF */
2531 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2532 goto invalid_opc;
2534 if (likely(rc != 31)) {
2535 if (ra != 31) {
2536 TCGv_i32 tmp = tcg_temp_new_i32();
2537 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2538 gen_helper_memory_to_f(cpu_fir[rc], tmp);
2539 tcg_temp_free_i32(tmp);
2540 } else
2541 tcg_gen_movi_i64(cpu_fir[rc], 0);
2543 break;
2544 case 0x24:
2545 /* ITOFT */
2546 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2547 goto invalid_opc;
2549 if (likely(rc != 31)) {
2550 if (ra != 31)
2551 tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
2552 else
2553 tcg_gen_movi_i64(cpu_fir[rc], 0);
2555 break;
2556 case 0x2A:
2557 /* SQRTG */
2558 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2559 gen_fsqrtg(rb, rc);
2560 break;
2562 goto invalid_opc;
2563 case 0x02B:
2564 /* SQRTT */
2565 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2566 gen_fsqrtt(ctx, rb, rc, fn11);
2567 break;
2569 goto invalid_opc;
2570 default:
2571 goto invalid_opc;
2573 break;
2574 case 0x15:
2575 /* VAX floating point */
2576 /* XXX: rounding mode and trap are ignored (!) */
2577 switch (fpfn) { /* fn11 & 0x3F */
2578 case 0x00:
2579 /* ADDF */
2580 gen_faddf(ra, rb, rc);
2581 break;
2582 case 0x01:
2583 /* SUBF */
2584 gen_fsubf(ra, rb, rc);
2585 break;
2586 case 0x02:
2587 /* MULF */
2588 gen_fmulf(ra, rb, rc);
2589 break;
2590 case 0x03:
2591 /* DIVF */
2592 gen_fdivf(ra, rb, rc);
2593 break;
2594 case 0x1E:
2595 /* CVTDG */
2596 #if 0 // TODO
2597 gen_fcvtdg(rb, rc);
2598 #else
2599 goto invalid_opc;
2600 #endif
2601 break;
2602 case 0x20:
2603 /* ADDG */
2604 gen_faddg(ra, rb, rc);
2605 break;
2606 case 0x21:
2607 /* SUBG */
2608 gen_fsubg(ra, rb, rc);
2609 break;
2610 case 0x22:
2611 /* MULG */
2612 gen_fmulg(ra, rb, rc);
2613 break;
2614 case 0x23:
2615 /* DIVG */
2616 gen_fdivg(ra, rb, rc);
2617 break;
2618 case 0x25:
2619 /* CMPGEQ */
2620 gen_fcmpgeq(ra, rb, rc);
2621 break;
2622 case 0x26:
2623 /* CMPGLT */
2624 gen_fcmpglt(ra, rb, rc);
2625 break;
2626 case 0x27:
2627 /* CMPGLE */
2628 gen_fcmpgle(ra, rb, rc);
2629 break;
2630 case 0x2C:
2631 /* CVTGF */
2632 gen_fcvtgf(rb, rc);
2633 break;
2634 case 0x2D:
2635 /* CVTGD */
2636 #if 0 // TODO
2637 gen_fcvtgd(rb, rc);
2638 #else
2639 goto invalid_opc;
2640 #endif
2641 break;
2642 case 0x2F:
2643 /* CVTGQ */
2644 gen_fcvtgq(rb, rc);
2645 break;
2646 case 0x3C:
2647 /* CVTQF */
2648 gen_fcvtqf(rb, rc);
2649 break;
2650 case 0x3E:
2651 /* CVTQG */
2652 gen_fcvtqg(rb, rc);
2653 break;
2654 default:
2655 goto invalid_opc;
2657 break;
2658 case 0x16:
2659 /* IEEE floating-point */
2660 switch (fpfn) { /* fn11 & 0x3F */
2661 case 0x00:
2662 /* ADDS */
2663 gen_fadds(ctx, ra, rb, rc, fn11);
2664 break;
2665 case 0x01:
2666 /* SUBS */
2667 gen_fsubs(ctx, ra, rb, rc, fn11);
2668 break;
2669 case 0x02:
2670 /* MULS */
2671 gen_fmuls(ctx, ra, rb, rc, fn11);
2672 break;
2673 case 0x03:
2674 /* DIVS */
2675 gen_fdivs(ctx, ra, rb, rc, fn11);
2676 break;
2677 case 0x20:
2678 /* ADDT */
2679 gen_faddt(ctx, ra, rb, rc, fn11);
2680 break;
2681 case 0x21:
2682 /* SUBT */
2683 gen_fsubt(ctx, ra, rb, rc, fn11);
2684 break;
2685 case 0x22:
2686 /* MULT */
2687 gen_fmult(ctx, ra, rb, rc, fn11);
2688 break;
2689 case 0x23:
2690 /* DIVT */
2691 gen_fdivt(ctx, ra, rb, rc, fn11);
2692 break;
2693 case 0x24:
2694 /* CMPTUN */
2695 gen_fcmptun(ctx, ra, rb, rc, fn11);
2696 break;
2697 case 0x25:
2698 /* CMPTEQ */
2699 gen_fcmpteq(ctx, ra, rb, rc, fn11);
2700 break;
2701 case 0x26:
2702 /* CMPTLT */
2703 gen_fcmptlt(ctx, ra, rb, rc, fn11);
2704 break;
2705 case 0x27:
2706 /* CMPTLE */
2707 gen_fcmptle(ctx, ra, rb, rc, fn11);
2708 break;
2709 case 0x2C:
2710 if (fn11 == 0x2AC || fn11 == 0x6AC) {
2711 /* CVTST */
2712 gen_fcvtst(ctx, rb, rc, fn11);
2713 } else {
2714 /* CVTTS */
2715 gen_fcvtts(ctx, rb, rc, fn11);
2717 break;
2718 case 0x2F:
2719 /* CVTTQ */
2720 gen_fcvttq(ctx, rb, rc, fn11);
2721 break;
2722 case 0x3C:
2723 /* CVTQS */
2724 gen_fcvtqs(ctx, rb, rc, fn11);
2725 break;
2726 case 0x3E:
2727 /* CVTQT */
2728 gen_fcvtqt(ctx, rb, rc, fn11);
2729 break;
2730 default:
2731 goto invalid_opc;
2733 break;
2734 case 0x17:
2735 switch (fn11) {
2736 case 0x010:
2737 /* CVTLQ */
2738 gen_fcvtlq(rb, rc);
2739 break;
2740 case 0x020:
2741 if (likely(rc != 31)) {
2742 if (ra == rb) {
2743 /* FMOV */
2744 if (ra == 31)
2745 tcg_gen_movi_i64(cpu_fir[rc], 0);
2746 else
2747 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
2748 } else {
2749 /* CPYS */
2750 gen_fcpys(ra, rb, rc);
2753 break;
2754 case 0x021:
2755 /* CPYSN */
2756 gen_fcpysn(ra, rb, rc);
2757 break;
2758 case 0x022:
2759 /* CPYSE */
2760 gen_fcpyse(ra, rb, rc);
2761 break;
2762 case 0x024:
2763 /* MT_FPCR */
2764 if (likely(ra != 31))
2765 gen_helper_store_fpcr(cpu_env, cpu_fir[ra]);
2766 else {
2767 TCGv tmp = tcg_const_i64(0);
2768 gen_helper_store_fpcr(cpu_env, tmp);
2769 tcg_temp_free(tmp);
2771 break;
2772 case 0x025:
2773 /* MF_FPCR */
2774 if (likely(ra != 31))
2775 gen_helper_load_fpcr(cpu_fir[ra], cpu_env);
2776 break;
2777 case 0x02A:
2778 /* FCMOVEQ */
2779 gen_fcmov(TCG_COND_EQ, ra, rb, rc);
2780 break;
2781 case 0x02B:
2782 /* FCMOVNE */
2783 gen_fcmov(TCG_COND_NE, ra, rb, rc);
2784 break;
2785 case 0x02C:
2786 /* FCMOVLT */
2787 gen_fcmov(TCG_COND_LT, ra, rb, rc);
2788 break;
2789 case 0x02D:
2790 /* FCMOVGE */
2791 gen_fcmov(TCG_COND_GE, ra, rb, rc);
2792 break;
2793 case 0x02E:
2794 /* FCMOVLE */
2795 gen_fcmov(TCG_COND_LE, ra, rb, rc);
2796 break;
2797 case 0x02F:
2798 /* FCMOVGT */
2799 gen_fcmov(TCG_COND_GT, ra, rb, rc);
2800 break;
2801 case 0x030:
2802 /* CVTQL */
2803 gen_fcvtql(rb, rc);
2804 break;
2805 case 0x130:
2806 /* CVTQL/V */
2807 case 0x530:
2808 /* CVTQL/SV */
2809 /* ??? I'm pretty sure there's nothing that /sv needs to do that
2810 /v doesn't do. The only thing I can think is that /sv is a
2811 valid instruction merely for completeness in the ISA. */
2812 gen_fcvtql_v(ctx, rb, rc);
2813 break;
2814 default:
2815 goto invalid_opc;
2817 break;
2818 case 0x18:
2819 switch ((uint16_t)disp16) {
2820 case 0x0000:
2821 /* TRAPB */
2822 /* No-op. */
2823 break;
2824 case 0x0400:
2825 /* EXCB */
2826 /* No-op. */
2827 break;
2828 case 0x4000:
2829 /* MB */
2830 /* No-op */
2831 break;
2832 case 0x4400:
2833 /* WMB */
2834 /* No-op */
2835 break;
2836 case 0x8000:
2837 /* FETCH */
2838 /* No-op */
2839 break;
2840 case 0xA000:
2841 /* FETCH_M */
2842 /* No-op */
2843 break;
2844 case 0xC000:
2845 /* RPCC */
2846 if (ra != 31) {
2847 if (use_icount) {
2848 gen_io_start();
2849 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
2850 gen_io_end();
2851 ret = EXIT_PC_STALE;
2852 } else {
2853 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
2856 break;
2857 case 0xE000:
2858 /* RC */
2859 gen_rx(ra, 0);
2860 break;
2861 case 0xE800:
2862 /* ECB */
2863 break;
2864 case 0xF000:
2865 /* RS */
2866 gen_rx(ra, 1);
2867 break;
2868 case 0xF800:
2869 /* WH64 */
2870 /* No-op */
2871 break;
2872 default:
2873 goto invalid_opc;
2875 break;
2876 case 0x19:
2877 /* HW_MFPR (PALcode) */
2878 #ifndef CONFIG_USER_ONLY
2879 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2880 return gen_mfpr(ra, insn & 0xffff);
2882 #endif
2883 goto invalid_opc;
2884 case 0x1A:
2885 /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch
2886 prediction stack action, which of course we don't implement. */
2887 if (rb != 31) {
2888 tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
2889 } else {
2890 tcg_gen_movi_i64(cpu_pc, 0);
2892 if (ra != 31) {
2893 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2895 ret = EXIT_PC_UPDATED;
2896 break;
2897 case 0x1B:
2898 /* HW_LD (PALcode) */
2899 #ifndef CONFIG_USER_ONLY
2900 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2901 TCGv addr;
2903 if (ra == 31) {
2904 break;
2907 addr = tcg_temp_new();
2908 if (rb != 31)
2909 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2910 else
2911 tcg_gen_movi_i64(addr, disp12);
2912 switch ((insn >> 12) & 0xF) {
2913 case 0x0:
2914 /* Longword physical access (hw_ldl/p) */
2915 gen_helper_ldl_phys(cpu_ir[ra], cpu_env, addr);
2916 break;
2917 case 0x1:
2918 /* Quadword physical access (hw_ldq/p) */
2919 gen_helper_ldq_phys(cpu_ir[ra], cpu_env, addr);
2920 break;
2921 case 0x2:
2922 /* Longword physical access with lock (hw_ldl_l/p) */
2923 gen_helper_ldl_l_phys(cpu_ir[ra], cpu_env, addr);
2924 break;
2925 case 0x3:
2926 /* Quadword physical access with lock (hw_ldq_l/p) */
2927 gen_helper_ldq_l_phys(cpu_ir[ra], cpu_env, addr);
2928 break;
2929 case 0x4:
2930 /* Longword virtual PTE fetch (hw_ldl/v) */
2931 goto invalid_opc;
2932 case 0x5:
2933 /* Quadword virtual PTE fetch (hw_ldq/v) */
2934 goto invalid_opc;
2935 break;
2936 case 0x6:
2937 /* Incpu_ir[ra]id */
2938 goto invalid_opc;
2939 case 0x7:
2940 /* Incpu_ir[ra]id */
2941 goto invalid_opc;
2942 case 0x8:
2943 /* Longword virtual access (hw_ldl) */
2944 goto invalid_opc;
2945 case 0x9:
2946 /* Quadword virtual access (hw_ldq) */
2947 goto invalid_opc;
2948 case 0xA:
2949 /* Longword virtual access with protection check (hw_ldl/w) */
2950 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LESL);
2951 break;
2952 case 0xB:
2953 /* Quadword virtual access with protection check (hw_ldq/w) */
2954 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LEQ);
2955 break;
2956 case 0xC:
2957 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2958 goto invalid_opc;
2959 case 0xD:
2960 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2961 goto invalid_opc;
2962 case 0xE:
2963 /* Longword virtual access with alternate access mode and
2964 protection checks (hw_ldl/wa) */
2965 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LESL);
2966 break;
2967 case 0xF:
2968 /* Quadword virtual access with alternate access mode and
2969 protection checks (hw_ldq/wa) */
2970 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LEQ);
2971 break;
2973 tcg_temp_free(addr);
2974 break;
2976 #endif
2977 goto invalid_opc;
2978 case 0x1C:
2979 switch (fn7) {
2980 case 0x00:
2981 /* SEXTB */
2982 if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {
2983 goto invalid_opc;
2985 if (likely(rc != 31)) {
2986 if (islit)
2987 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
2988 else
2989 tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
2991 break;
2992 case 0x01:
2993 /* SEXTW */
2994 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
2995 if (likely(rc != 31)) {
2996 if (islit) {
2997 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
2998 } else {
2999 tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
3002 break;
3004 goto invalid_opc;
3005 case 0x30:
3006 /* CTPOP */
3007 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
3008 if (likely(rc != 31)) {
3009 if (islit) {
3010 tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
3011 } else {
3012 gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
3015 break;
3017 goto invalid_opc;
3018 case 0x31:
3019 /* PERR */
3020 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3021 gen_perr(ra, rb, rc, islit, lit);
3022 break;
3024 goto invalid_opc;
3025 case 0x32:
3026 /* CTLZ */
3027 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
3028 if (likely(rc != 31)) {
3029 if (islit) {
3030 tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
3031 } else {
3032 gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
3035 break;
3037 goto invalid_opc;
3038 case 0x33:
3039 /* CTTZ */
3040 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
3041 if (likely(rc != 31)) {
3042 if (islit) {
3043 tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
3044 } else {
3045 gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
3048 break;
3050 goto invalid_opc;
3051 case 0x34:
3052 /* UNPKBW */
3053 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3054 if (real_islit || ra != 31) {
3055 goto invalid_opc;
3057 gen_unpkbw(rb, rc);
3058 break;
3060 goto invalid_opc;
3061 case 0x35:
3062 /* UNPKBL */
3063 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3064 if (real_islit || ra != 31) {
3065 goto invalid_opc;
3067 gen_unpkbl(rb, rc);
3068 break;
3070 goto invalid_opc;
3071 case 0x36:
3072 /* PKWB */
3073 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3074 if (real_islit || ra != 31) {
3075 goto invalid_opc;
3077 gen_pkwb(rb, rc);
3078 break;
3080 goto invalid_opc;
3081 case 0x37:
3082 /* PKLB */
3083 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3084 if (real_islit || ra != 31) {
3085 goto invalid_opc;
3087 gen_pklb(rb, rc);
3088 break;
3090 goto invalid_opc;
3091 case 0x38:
3092 /* MINSB8 */
3093 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3094 gen_minsb8(ra, rb, rc, islit, lit);
3095 break;
3097 goto invalid_opc;
3098 case 0x39:
3099 /* MINSW4 */
3100 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3101 gen_minsw4(ra, rb, rc, islit, lit);
3102 break;
3104 goto invalid_opc;
3105 case 0x3A:
3106 /* MINUB8 */
3107 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3108 gen_minub8(ra, rb, rc, islit, lit);
3109 break;
3111 goto invalid_opc;
3112 case 0x3B:
3113 /* MINUW4 */
3114 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3115 gen_minuw4(ra, rb, rc, islit, lit);
3116 break;
3118 goto invalid_opc;
3119 case 0x3C:
3120 /* MAXUB8 */
3121 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3122 gen_maxub8(ra, rb, rc, islit, lit);
3123 break;
3125 goto invalid_opc;
3126 case 0x3D:
3127 /* MAXUW4 */
3128 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3129 gen_maxuw4(ra, rb, rc, islit, lit);
3130 break;
3132 goto invalid_opc;
3133 case 0x3E:
3134 /* MAXSB8 */
3135 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3136 gen_maxsb8(ra, rb, rc, islit, lit);
3137 break;
3139 goto invalid_opc;
3140 case 0x3F:
3141 /* MAXSW4 */
3142 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3143 gen_maxsw4(ra, rb, rc, islit, lit);
3144 break;
3146 goto invalid_opc;
3147 case 0x70:
3148 /* FTOIT */
3149 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3150 goto invalid_opc;
3152 if (likely(rc != 31)) {
3153 if (ra != 31)
3154 tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
3155 else
3156 tcg_gen_movi_i64(cpu_ir[rc], 0);
3158 break;
3159 case 0x78:
3160 /* FTOIS */
3161 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3162 goto invalid_opc;
3164 if (rc != 31) {
3165 TCGv_i32 tmp1 = tcg_temp_new_i32();
3166 if (ra != 31)
3167 gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
3168 else {
3169 TCGv tmp2 = tcg_const_i64(0);
3170 gen_helper_s_to_memory(tmp1, tmp2);
3171 tcg_temp_free(tmp2);
3173 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
3174 tcg_temp_free_i32(tmp1);
3176 break;
3177 default:
3178 goto invalid_opc;
3180 break;
3181 case 0x1D:
3182 /* HW_MTPR (PALcode) */
3183 #ifndef CONFIG_USER_ONLY
3184 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3185 return gen_mtpr(ctx, rb, insn & 0xffff);
3187 #endif
3188 goto invalid_opc;
3189 case 0x1E:
3190 /* HW_RET (PALcode) */
3191 #ifndef CONFIG_USER_ONLY
3192 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3193 if (rb == 31) {
3194 /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
3195 address from EXC_ADDR. This turns out to be useful for our
3196 emulation PALcode, so continue to accept it. */
3197 TCGv tmp = tcg_temp_new();
3198 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
3199 gen_helper_hw_ret(cpu_env, tmp);
3200 tcg_temp_free(tmp);
3201 } else {
3202 gen_helper_hw_ret(cpu_env, cpu_ir[rb]);
3204 ret = EXIT_PC_UPDATED;
3205 break;
3207 #endif
3208 goto invalid_opc;
3209 case 0x1F:
3210 /* HW_ST (PALcode) */
3211 #ifndef CONFIG_USER_ONLY
3212 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3213 TCGv addr, val;
3214 addr = tcg_temp_new();
3215 if (rb != 31)
3216 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
3217 else
3218 tcg_gen_movi_i64(addr, disp12);
3219 if (ra != 31)
3220 val = cpu_ir[ra];
3221 else {
3222 val = tcg_temp_new();
3223 tcg_gen_movi_i64(val, 0);
3225 switch ((insn >> 12) & 0xF) {
3226 case 0x0:
3227 /* Longword physical access */
3228 gen_helper_stl_phys(cpu_env, addr, val);
3229 break;
3230 case 0x1:
3231 /* Quadword physical access */
3232 gen_helper_stq_phys(cpu_env, addr, val);
3233 break;
3234 case 0x2:
3235 /* Longword physical access with lock */
3236 gen_helper_stl_c_phys(val, cpu_env, addr, val);
3237 break;
3238 case 0x3:
3239 /* Quadword physical access with lock */
3240 gen_helper_stq_c_phys(val, cpu_env, addr, val);
3241 break;
3242 case 0x4:
3243 /* Longword virtual access */
3244 goto invalid_opc;
3245 case 0x5:
3246 /* Quadword virtual access */
3247 goto invalid_opc;
3248 case 0x6:
3249 /* Invalid */
3250 goto invalid_opc;
3251 case 0x7:
3252 /* Invalid */
3253 goto invalid_opc;
3254 case 0x8:
3255 /* Invalid */
3256 goto invalid_opc;
3257 case 0x9:
3258 /* Invalid */
3259 goto invalid_opc;
3260 case 0xA:
3261 /* Invalid */
3262 goto invalid_opc;
3263 case 0xB:
3264 /* Invalid */
3265 goto invalid_opc;
3266 case 0xC:
3267 /* Longword virtual access with alternate access mode */
3268 goto invalid_opc;
3269 case 0xD:
3270 /* Quadword virtual access with alternate access mode */
3271 goto invalid_opc;
3272 case 0xE:
3273 /* Invalid */
3274 goto invalid_opc;
3275 case 0xF:
3276 /* Invalid */
3277 goto invalid_opc;
3279 if (ra == 31)
3280 tcg_temp_free(val);
3281 tcg_temp_free(addr);
3282 break;
3284 #endif
3285 goto invalid_opc;
3286 case 0x20:
3287 /* LDF */
3288 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
3289 break;
3290 case 0x21:
3291 /* LDG */
3292 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
3293 break;
3294 case 0x22:
3295 /* LDS */
3296 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
3297 break;
3298 case 0x23:
3299 /* LDT */
3300 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
3301 break;
3302 case 0x24:
3303 /* STF */
3304 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
3305 break;
3306 case 0x25:
3307 /* STG */
3308 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
3309 break;
3310 case 0x26:
3311 /* STS */
3312 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
3313 break;
3314 case 0x27:
3315 /* STT */
3316 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
3317 break;
3318 case 0x28:
3319 /* LDL */
3320 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
3321 break;
3322 case 0x29:
3323 /* LDQ */
3324 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
3325 break;
3326 case 0x2A:
3327 /* LDL_L */
3328 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
3329 break;
3330 case 0x2B:
3331 /* LDQ_L */
3332 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
3333 break;
3334 case 0x2C:
3335 /* STL */
3336 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
3337 break;
3338 case 0x2D:
3339 /* STQ */
3340 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
3341 break;
3342 case 0x2E:
3343 /* STL_C */
3344 ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
3345 break;
3346 case 0x2F:
3347 /* STQ_C */
3348 ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
3349 break;
3350 case 0x30:
3351 /* BR */
3352 ret = gen_bdirect(ctx, ra, disp21);
3353 break;
3354 case 0x31: /* FBEQ */
3355 ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
3356 break;
3357 case 0x32: /* FBLT */
3358 ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
3359 break;
3360 case 0x33: /* FBLE */
3361 ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
3362 break;
3363 case 0x34:
3364 /* BSR */
3365 ret = gen_bdirect(ctx, ra, disp21);
3366 break;
3367 case 0x35: /* FBNE */
3368 ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
3369 break;
3370 case 0x36: /* FBGE */
3371 ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
3372 break;
3373 case 0x37: /* FBGT */
3374 ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
3375 break;
3376 case 0x38:
3377 /* BLBC */
3378 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
3379 break;
3380 case 0x39:
3381 /* BEQ */
3382 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
3383 break;
3384 case 0x3A:
3385 /* BLT */
3386 ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
3387 break;
3388 case 0x3B:
3389 /* BLE */
3390 ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
3391 break;
3392 case 0x3C:
3393 /* BLBS */
3394 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
3395 break;
3396 case 0x3D:
3397 /* BNE */
3398 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
3399 break;
3400 case 0x3E:
3401 /* BGE */
3402 ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
3403 break;
3404 case 0x3F:
3405 /* BGT */
3406 ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
3407 break;
3408 invalid_opc:
3409 ret = gen_invalid(ctx);
3410 break;
3413 return ret;
3416 static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
3417 TranslationBlock *tb,
3418 bool search_pc)
3420 CPUState *cs = CPU(cpu);
3421 CPUAlphaState *env = &cpu->env;
3422 DisasContext ctx, *ctxp = &ctx;
3423 target_ulong pc_start;
3424 target_ulong pc_mask;
3425 uint32_t insn;
3426 uint16_t *gen_opc_end;
3427 CPUBreakpoint *bp;
3428 int j, lj = -1;
3429 ExitStatus ret;
3430 int num_insns;
3431 int max_insns;
3433 pc_start = tb->pc;
3434 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3436 ctx.tb = tb;
3437 ctx.pc = pc_start;
3438 ctx.mem_idx = cpu_mmu_index(env);
3439 ctx.implver = env->implver;
3440 ctx.singlestep_enabled = cs->singlestep_enabled;
3442 /* ??? Every TB begins with unset rounding mode, to be initialized on
3443 the first fp insn of the TB. Alternately we could define a proper
3444 default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
3445 to reset the FP_STATUS to that default at the end of any TB that
3446 changes the default. We could even (gasp) dynamiclly figure out
3447 what default would be most efficient given the running program. */
3448 ctx.tb_rm = -1;
3449 /* Similarly for flush-to-zero. */
3450 ctx.tb_ftz = -1;
3452 num_insns = 0;
3453 max_insns = tb->cflags & CF_COUNT_MASK;
3454 if (max_insns == 0) {
3455 max_insns = CF_COUNT_MASK;
3458 if (in_superpage(&ctx, pc_start)) {
3459 pc_mask = (1ULL << 41) - 1;
3460 } else {
3461 pc_mask = ~TARGET_PAGE_MASK;
3464 gen_tb_start();
3465 do {
3466 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3467 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3468 if (bp->pc == ctx.pc) {
3469 gen_excp(&ctx, EXCP_DEBUG, 0);
3470 break;
3474 if (search_pc) {
3475 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3476 if (lj < j) {
3477 lj++;
3478 while (lj < j)
3479 tcg_ctx.gen_opc_instr_start[lj++] = 0;
3481 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
3482 tcg_ctx.gen_opc_instr_start[lj] = 1;
3483 tcg_ctx.gen_opc_icount[lj] = num_insns;
3485 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3486 gen_io_start();
3487 insn = cpu_ldl_code(env, ctx.pc);
3488 num_insns++;
3490 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3491 tcg_gen_debug_insn_start(ctx.pc);
3494 ctx.pc += 4;
3495 ret = translate_one(ctxp, insn);
3497 /* If we reach a page boundary, are single stepping,
3498 or exhaust instruction count, stop generation. */
3499 if (ret == NO_EXIT
3500 && ((ctx.pc & pc_mask) == 0
3501 || tcg_ctx.gen_opc_ptr >= gen_opc_end
3502 || num_insns >= max_insns
3503 || singlestep
3504 || ctx.singlestep_enabled)) {
3505 ret = EXIT_PC_STALE;
3507 } while (ret == NO_EXIT);
3509 if (tb->cflags & CF_LAST_IO) {
3510 gen_io_end();
3513 switch (ret) {
3514 case EXIT_GOTO_TB:
3515 case EXIT_NORETURN:
3516 break;
3517 case EXIT_PC_STALE:
3518 tcg_gen_movi_i64(cpu_pc, ctx.pc);
3519 /* FALLTHRU */
3520 case EXIT_PC_UPDATED:
3521 if (ctx.singlestep_enabled) {
3522 gen_excp_1(EXCP_DEBUG, 0);
3523 } else {
3524 tcg_gen_exit_tb(0);
3526 break;
3527 default:
3528 abort();
3531 gen_tb_end(tb, num_insns);
3532 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3533 if (search_pc) {
3534 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3535 lj++;
3536 while (lj <= j)
3537 tcg_ctx.gen_opc_instr_start[lj++] = 0;
3538 } else {
3539 tb->size = ctx.pc - pc_start;
3540 tb->icount = num_insns;
3543 #ifdef DEBUG_DISAS
3544 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3545 qemu_log("IN: %s\n", lookup_symbol(pc_start));
3546 log_target_disas(env, pc_start, ctx.pc - pc_start, 1);
3547 qemu_log("\n");
3549 #endif
3552 void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb)
3554 gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, false);
3557 void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
3559 gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, true);
3562 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
3564 env->pc = tcg_ctx.gen_opc_pc[pc_pos];