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 "qemu/osdep.h"
22 #include "disas/disas.h"
23 #include "qemu/host-utils.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #include "trace-tcg.h"
35 #undef ALPHA_DEBUG_DISAS
36 #define CONFIG_SOFTFLOAT_INLINE
38 #ifdef ALPHA_DEBUG_DISAS
39 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
41 # define LOG_DISAS(...) do { } while (0)
44 typedef struct DisasContext DisasContext;
46 struct TranslationBlock *tb;
48 #ifndef CONFIG_USER_ONLY
53 /* Current rounding mode for this TB. */
55 /* Current flush-to-zero setting for this TB. */
58 /* implver value for this CPU. */
61 /* The set of registers active in the current context. */
64 /* Temporaries for $31 and $f31 as source and destination. */
67 /* Temporary for immediate constants. */
70 bool singlestep_enabled;
73 /* Return values from translate_one, indicating the state of the TB.
74 Note that zero indicates that we are not exiting the TB. */
79 /* We have emitted one or more goto_tb. No fixup required. */
82 /* We are not using a goto_tb (for whatever reason), but have updated
83 the PC (for whatever reason), so there's no need to do it again on
87 /* We are exiting the TB, but have neither emitted a goto_tb, nor
88 updated the PC for the next instruction to be executed. */
91 /* We are ending the TB with a noreturn function call, e.g. longjmp.
92 No following code will be executed. */
96 /* global register indexes */
97 static TCGv_env cpu_env;
98 static TCGv cpu_std_ir[31];
99 static TCGv cpu_fir[31];
101 static TCGv cpu_lock_addr;
102 static TCGv cpu_lock_st_addr;
103 static TCGv cpu_lock_value;
105 #ifndef CONFIG_USER_ONLY
106 static TCGv cpu_pal_ir[31];
109 #include "exec/gen-icount.h"
111 void alpha_translate_init(void)
113 #define DEF_VAR(V) { &cpu_##V, #V, offsetof(CPUAlphaState, V) }
115 typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar;
116 static const GlobalVar vars[] = {
119 DEF_VAR(lock_st_addr),
125 /* Use the symbolic register names that match the disassembler. */
126 static const char greg_names[31][4] = {
127 "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
128 "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
129 "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
130 "t10", "t11", "ra", "t12", "at", "gp", "sp"
132 static const char freg_names[31][4] = {
133 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
134 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
135 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
136 "f24", "f25", "f26", "f27", "f28", "f29", "f30"
138 #ifndef CONFIG_USER_ONLY
139 static const char shadow_names[8][8] = {
140 "pal_t7", "pal_s0", "pal_s1", "pal_s2",
141 "pal_s3", "pal_s4", "pal_s5", "pal_t11"
145 static bool done_init = 0;
153 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
154 tcg_ctx.tcg_env = cpu_env;
156 for (i = 0; i < 31; i++) {
157 cpu_std_ir[i] = tcg_global_mem_new_i64(cpu_env,
158 offsetof(CPUAlphaState, ir[i]),
162 for (i = 0; i < 31; i++) {
163 cpu_fir[i] = tcg_global_mem_new_i64(cpu_env,
164 offsetof(CPUAlphaState, fir[i]),
168 #ifndef CONFIG_USER_ONLY
169 memcpy(cpu_pal_ir, cpu_std_ir, sizeof(cpu_pal_ir));
170 for (i = 0; i < 8; i++) {
171 int r = (i == 7 ? 25 : i + 8);
172 cpu_pal_ir[r] = tcg_global_mem_new_i64(cpu_env,
173 offsetof(CPUAlphaState,
179 for (i = 0; i < ARRAY_SIZE(vars); ++i) {
180 const GlobalVar *v = &vars[i];
181 *v->var = tcg_global_mem_new_i64(cpu_env, v->ofs, v->name);
185 static TCGv load_zero(DisasContext *ctx)
187 if (TCGV_IS_UNUSED_I64(ctx->zero)) {
188 ctx->zero = tcg_const_i64(0);
193 static TCGv dest_sink(DisasContext *ctx)
195 if (TCGV_IS_UNUSED_I64(ctx->sink)) {
196 ctx->sink = tcg_temp_new();
201 static TCGv load_gpr(DisasContext *ctx, unsigned reg)
203 if (likely(reg < 31)) {
206 return load_zero(ctx);
210 static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
211 uint8_t lit, bool islit)
214 ctx->lit = tcg_const_i64(lit);
216 } else if (likely(reg < 31)) {
219 return load_zero(ctx);
223 static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
225 if (likely(reg < 31)) {
228 return dest_sink(ctx);
232 static TCGv load_fpr(DisasContext *ctx, unsigned reg)
234 if (likely(reg < 31)) {
237 return load_zero(ctx);
241 static TCGv dest_fpr(DisasContext *ctx, unsigned reg)
243 if (likely(reg < 31)) {
246 return dest_sink(ctx);
250 static void gen_excp_1(int exception, int error_code)
254 tmp1 = tcg_const_i32(exception);
255 tmp2 = tcg_const_i32(error_code);
256 gen_helper_excp(cpu_env, tmp1, tmp2);
257 tcg_temp_free_i32(tmp2);
258 tcg_temp_free_i32(tmp1);
261 static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
263 tcg_gen_movi_i64(cpu_pc, ctx->pc);
264 gen_excp_1(exception, error_code);
265 return EXIT_NORETURN;
268 static inline ExitStatus gen_invalid(DisasContext *ctx)
270 return gen_excp(ctx, EXCP_OPCDEC, 0);
273 static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
275 TCGv_i32 tmp32 = tcg_temp_new_i32();
276 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
277 gen_helper_memory_to_f(t0, tmp32);
278 tcg_temp_free_i32(tmp32);
281 static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
283 TCGv tmp = tcg_temp_new();
284 tcg_gen_qemu_ld_i64(tmp, t1, flags, MO_LEQ);
285 gen_helper_memory_to_g(t0, tmp);
289 static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
291 TCGv_i32 tmp32 = tcg_temp_new_i32();
292 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
293 gen_helper_memory_to_s(t0, tmp32);
294 tcg_temp_free_i32(tmp32);
297 static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
299 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL);
300 tcg_gen_mov_i64(cpu_lock_addr, t1);
301 tcg_gen_mov_i64(cpu_lock_value, t0);
304 static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
306 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ);
307 tcg_gen_mov_i64(cpu_lock_addr, t1);
308 tcg_gen_mov_i64(cpu_lock_value, t0);
311 static inline void gen_load_mem(DisasContext *ctx,
312 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
314 int ra, int rb, int32_t disp16, bool fp,
319 /* LDQ_U with ra $31 is UNOP. Other various loads are forms of
320 prefetches, which we can treat as nops. No worries about
321 missed exceptions here. */
322 if (unlikely(ra == 31)) {
326 tmp = tcg_temp_new();
327 addr = load_gpr(ctx, rb);
330 tcg_gen_addi_i64(tmp, addr, disp16);
334 tcg_gen_andi_i64(tmp, addr, ~0x7);
338 va = (fp ? cpu_fir[ra] : ctx->ir[ra]);
339 tcg_gen_qemu_load(va, addr, ctx->mem_idx);
344 static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
346 TCGv_i32 tmp32 = tcg_temp_new_i32();
347 gen_helper_f_to_memory(tmp32, t0);
348 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
349 tcg_temp_free_i32(tmp32);
352 static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
354 TCGv tmp = tcg_temp_new();
355 gen_helper_g_to_memory(tmp, t0);
356 tcg_gen_qemu_st_i64(tmp, t1, flags, MO_LEQ);
360 static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
362 TCGv_i32 tmp32 = tcg_temp_new_i32();
363 gen_helper_s_to_memory(tmp32, t0);
364 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
365 tcg_temp_free_i32(tmp32);
368 static inline void gen_store_mem(DisasContext *ctx,
369 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
371 int ra, int rb, int32_t disp16, bool fp,
376 tmp = tcg_temp_new();
377 addr = load_gpr(ctx, rb);
380 tcg_gen_addi_i64(tmp, addr, disp16);
384 tcg_gen_andi_i64(tmp, addr, ~0x7);
388 va = (fp ? load_fpr(ctx, ra) : load_gpr(ctx, ra));
389 tcg_gen_qemu_store(va, addr, ctx->mem_idx);
394 static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
395 int32_t disp16, int quad)
400 /* ??? Don't bother storing anything. The user can't tell
401 the difference, since the zero register always reads zero. */
405 #if defined(CONFIG_USER_ONLY)
406 addr = cpu_lock_st_addr;
408 addr = tcg_temp_local_new();
411 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
413 #if defined(CONFIG_USER_ONLY)
414 /* ??? This is handled via a complicated version of compare-and-swap
415 in the cpu_loop. Hopefully one day we'll have a real CAS opcode
416 in TCG so that this isn't necessary. */
417 return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
419 /* ??? In system mode we are never multi-threaded, so CAS can be
420 implemented via a non-atomic load-compare-store sequence. */
422 TCGLabel *lab_fail, *lab_done;
425 lab_fail = gen_new_label();
426 lab_done = gen_new_label();
427 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
429 val = tcg_temp_new();
430 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, quad ? MO_LEQ : MO_LESL);
431 tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
433 tcg_gen_qemu_st_i64(ctx->ir[ra], addr, ctx->mem_idx,
434 quad ? MO_LEQ : MO_LEUL);
435 tcg_gen_movi_i64(ctx->ir[ra], 1);
436 tcg_gen_br(lab_done);
438 gen_set_label(lab_fail);
439 tcg_gen_movi_i64(ctx->ir[ra], 0);
441 gen_set_label(lab_done);
442 tcg_gen_movi_i64(cpu_lock_addr, -1);
450 static bool in_superpage(DisasContext *ctx, int64_t addr)
452 return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
454 && ((addr >> 41) & 3) == 2
455 && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
458 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
460 /* Suppress goto_tb in the case of single-steping and IO. */
461 if ((ctx->tb->cflags & CF_LAST_IO)
462 || ctx->singlestep_enabled || singlestep) {
465 #ifndef CONFIG_USER_ONLY
466 /* If the destination is in the superpage, the page perms can't change. */
467 if (in_superpage(ctx, dest)) {
470 /* Check for the dest on the same page as the start of the TB. */
471 return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
477 static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
479 uint64_t dest = ctx->pc + (disp << 2);
482 tcg_gen_movi_i64(ctx->ir[ra], ctx->pc);
485 /* Notice branch-to-next; used to initialize RA with the PC. */
488 } else if (use_goto_tb(ctx, dest)) {
490 tcg_gen_movi_i64(cpu_pc, dest);
491 tcg_gen_exit_tb((uintptr_t)ctx->tb);
494 tcg_gen_movi_i64(cpu_pc, dest);
495 return EXIT_PC_UPDATED;
499 static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
500 TCGv cmp, int32_t disp)
502 uint64_t dest = ctx->pc + (disp << 2);
503 TCGLabel *lab_true = gen_new_label();
505 if (use_goto_tb(ctx, dest)) {
506 tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
509 tcg_gen_movi_i64(cpu_pc, ctx->pc);
510 tcg_gen_exit_tb((uintptr_t)ctx->tb);
512 gen_set_label(lab_true);
514 tcg_gen_movi_i64(cpu_pc, dest);
515 tcg_gen_exit_tb((uintptr_t)ctx->tb + 1);
519 TCGv_i64 z = tcg_const_i64(0);
520 TCGv_i64 d = tcg_const_i64(dest);
521 TCGv_i64 p = tcg_const_i64(ctx->pc);
523 tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
525 tcg_temp_free_i64(z);
526 tcg_temp_free_i64(d);
527 tcg_temp_free_i64(p);
528 return EXIT_PC_UPDATED;
532 static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
533 int32_t disp, int mask)
538 cmp_tmp = tcg_temp_new();
539 tcg_gen_andi_i64(cmp_tmp, load_gpr(ctx, ra), 1);
541 cmp_tmp = load_gpr(ctx, ra);
544 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
547 /* Fold -0.0 for comparison with COND. */
549 static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
551 uint64_t mzero = 1ull << 63;
556 /* For <= or >, the -0.0 value directly compares the way we want. */
557 tcg_gen_mov_i64(dest, src);
562 /* For == or !=, we can simply mask off the sign bit and compare. */
563 tcg_gen_andi_i64(dest, src, mzero - 1);
568 /* For >= or <, map -0.0 to +0.0 via comparison and mask. */
569 tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
570 tcg_gen_neg_i64(dest, dest);
571 tcg_gen_and_i64(dest, dest, src);
579 static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
582 TCGv cmp_tmp = tcg_temp_new();
583 gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
584 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
587 static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
592 vb = load_fpr(ctx, rb);
594 gen_fold_mzero(cond, va, load_fpr(ctx, ra));
596 tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
601 #define QUAL_RM_N 0x080 /* Round mode nearest even */
602 #define QUAL_RM_C 0x000 /* Round mode chopped */
603 #define QUAL_RM_M 0x040 /* Round mode minus infinity */
604 #define QUAL_RM_D 0x0c0 /* Round mode dynamic */
605 #define QUAL_RM_MASK 0x0c0
607 #define QUAL_U 0x100 /* Underflow enable (fp output) */
608 #define QUAL_V 0x100 /* Overflow enable (int output) */
609 #define QUAL_S 0x400 /* Software completion enable */
610 #define QUAL_I 0x200 /* Inexact detection enable */
612 static void gen_qual_roundmode(DisasContext *ctx, int fn11)
616 fn11 &= QUAL_RM_MASK;
617 if (fn11 == ctx->tb_rm) {
622 tmp = tcg_temp_new_i32();
625 tcg_gen_movi_i32(tmp, float_round_nearest_even);
628 tcg_gen_movi_i32(tmp, float_round_to_zero);
631 tcg_gen_movi_i32(tmp, float_round_down);
634 tcg_gen_ld8u_i32(tmp, cpu_env,
635 offsetof(CPUAlphaState, fpcr_dyn_round));
639 #if defined(CONFIG_SOFTFLOAT_INLINE)
640 /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
641 With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
642 sets the one field. */
643 tcg_gen_st8_i32(tmp, cpu_env,
644 offsetof(CPUAlphaState, fp_status.float_rounding_mode));
646 gen_helper_setroundmode(tmp);
649 tcg_temp_free_i32(tmp);
652 static void gen_qual_flushzero(DisasContext *ctx, int fn11)
657 if (fn11 == ctx->tb_ftz) {
662 tmp = tcg_temp_new_i32();
664 /* Underflow is enabled, use the FPCR setting. */
665 tcg_gen_ld8u_i32(tmp, cpu_env,
666 offsetof(CPUAlphaState, fpcr_flush_to_zero));
668 /* Underflow is disabled, force flush-to-zero. */
669 tcg_gen_movi_i32(tmp, 1);
672 #if defined(CONFIG_SOFTFLOAT_INLINE)
673 tcg_gen_st8_i32(tmp, cpu_env,
674 offsetof(CPUAlphaState, fp_status.flush_to_zero));
676 gen_helper_setflushzero(tmp);
679 tcg_temp_free_i32(tmp);
682 static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp)
686 if (unlikely(reg == 31)) {
687 val = load_zero(ctx);
690 if ((fn11 & QUAL_S) == 0) {
692 gen_helper_ieee_input_cmp(cpu_env, val);
694 gen_helper_ieee_input(cpu_env, val);
697 #ifndef CONFIG_USER_ONLY
698 /* In system mode, raise exceptions for denormals like real
699 hardware. In user mode, proceed as if the OS completion
700 handler is handling the denormal as per spec. */
701 gen_helper_ieee_input_s(cpu_env, val);
708 static void gen_fp_exc_raise(int rc, int fn11)
710 /* ??? We ought to be able to do something with imprecise exceptions.
711 E.g. notice we're still in the trap shadow of something within the
712 TB and do not generate the code to signal the exception; end the TB
713 when an exception is forced to arrive, either by consumption of a
714 register value or TRAPB or EXCB. */
718 if (!(fn11 & QUAL_U)) {
719 /* Note that QUAL_U == QUAL_V, so ignore either. */
720 ignore |= FPCR_UNF | FPCR_IOV;
722 if (!(fn11 & QUAL_I)) {
725 ign = tcg_const_i32(ignore);
727 /* ??? Pass in the regno of the destination so that the helper can
728 set EXC_MASK, which contains a bitmask of destination registers
729 that have caused arithmetic traps. A simple userspace emulation
730 does not require this. We do need it for a guest kernel's entArith,
731 or if we were to do something clever with imprecise exceptions. */
732 reg = tcg_const_i32(rc + 32);
734 gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
736 gen_helper_fp_exc_raise(cpu_env, ign, reg);
739 tcg_temp_free_i32(reg);
740 tcg_temp_free_i32(ign);
743 static void gen_cvtlq(TCGv vc, TCGv vb)
745 TCGv tmp = tcg_temp_new();
747 /* The arithmetic right shift here, plus the sign-extended mask below
748 yields a sign-extended result without an explicit ext32s_i64. */
749 tcg_gen_sari_i64(tmp, vb, 32);
750 tcg_gen_shri_i64(vc, vb, 29);
751 tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
752 tcg_gen_andi_i64(vc, vc, 0x3fffffff);
753 tcg_gen_or_i64(vc, vc, tmp);
758 static void gen_ieee_arith2(DisasContext *ctx,
759 void (*helper)(TCGv, TCGv_ptr, TCGv),
760 int rb, int rc, int fn11)
764 gen_qual_roundmode(ctx, fn11);
765 gen_qual_flushzero(ctx, fn11);
767 vb = gen_ieee_input(ctx, rb, fn11, 0);
768 helper(dest_fpr(ctx, rc), cpu_env, vb);
770 gen_fp_exc_raise(rc, fn11);
773 #define IEEE_ARITH2(name) \
774 static inline void glue(gen_, name)(DisasContext *ctx, \
775 int rb, int rc, int fn11) \
777 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \
784 static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11)
788 /* No need to set flushzero, since we have an integer output. */
789 vb = gen_ieee_input(ctx, rb, fn11, 0);
790 vc = dest_fpr(ctx, rc);
792 /* Almost all integer conversions use cropped rounding;
793 special case that. */
794 if ((fn11 & QUAL_RM_MASK) == QUAL_RM_C) {
795 gen_helper_cvttq_c(vc, cpu_env, vb);
797 gen_qual_roundmode(ctx, fn11);
798 gen_helper_cvttq(vc, cpu_env, vb);
800 gen_fp_exc_raise(rc, fn11);
803 static void gen_ieee_intcvt(DisasContext *ctx,
804 void (*helper)(TCGv, TCGv_ptr, TCGv),
805 int rb, int rc, int fn11)
809 gen_qual_roundmode(ctx, fn11);
810 vb = load_fpr(ctx, rb);
811 vc = dest_fpr(ctx, rc);
813 /* The only exception that can be raised by integer conversion
814 is inexact. Thus we only need to worry about exceptions when
815 inexact handling is requested. */
817 helper(vc, cpu_env, vb);
818 gen_fp_exc_raise(rc, fn11);
820 helper(vc, cpu_env, vb);
824 #define IEEE_INTCVT(name) \
825 static inline void glue(gen_, name)(DisasContext *ctx, \
826 int rb, int rc, int fn11) \
828 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \
833 static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
835 TCGv vmask = tcg_const_i64(mask);
836 TCGv tmp = tcg_temp_new_i64();
839 tcg_gen_andc_i64(tmp, vmask, va);
841 tcg_gen_and_i64(tmp, va, vmask);
844 tcg_gen_andc_i64(vc, vb, vmask);
845 tcg_gen_or_i64(vc, vc, tmp);
847 tcg_temp_free(vmask);
851 static void gen_ieee_arith3(DisasContext *ctx,
852 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
853 int ra, int rb, int rc, int fn11)
857 gen_qual_roundmode(ctx, fn11);
858 gen_qual_flushzero(ctx, fn11);
860 va = gen_ieee_input(ctx, ra, fn11, 0);
861 vb = gen_ieee_input(ctx, rb, fn11, 0);
862 vc = dest_fpr(ctx, rc);
863 helper(vc, cpu_env, va, vb);
865 gen_fp_exc_raise(rc, fn11);
868 #define IEEE_ARITH3(name) \
869 static inline void glue(gen_, name)(DisasContext *ctx, \
870 int ra, int rb, int rc, int fn11) \
872 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \
883 static void gen_ieee_compare(DisasContext *ctx,
884 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
885 int ra, int rb, int rc, int fn11)
889 va = gen_ieee_input(ctx, ra, fn11, 1);
890 vb = gen_ieee_input(ctx, rb, fn11, 1);
891 vc = dest_fpr(ctx, rc);
892 helper(vc, cpu_env, va, vb);
894 gen_fp_exc_raise(rc, fn11);
897 #define IEEE_CMP3(name) \
898 static inline void glue(gen_, name)(DisasContext *ctx, \
899 int ra, int rb, int rc, int fn11) \
901 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \
908 static inline uint64_t zapnot_mask(uint8_t lit)
913 for (i = 0; i < 8; ++i) {
914 if ((lit >> i) & 1) {
915 mask |= 0xffull << (i * 8);
921 /* Implement zapnot with an immediate operand, which expands to some
922 form of immediate AND. This is a basic building block in the
923 definition of many of the other byte manipulation instructions. */
924 static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
928 tcg_gen_movi_i64(dest, 0);
931 tcg_gen_ext8u_i64(dest, src);
934 tcg_gen_ext16u_i64(dest, src);
937 tcg_gen_ext32u_i64(dest, src);
940 tcg_gen_mov_i64(dest, src);
943 tcg_gen_andi_i64(dest, src, zapnot_mask(lit));
948 /* EXTWH, EXTLH, EXTQH */
949 static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
950 uint8_t lit, uint8_t byte_mask)
953 tcg_gen_shli_i64(vc, va, (64 - lit * 8) & 0x3f);
955 TCGv tmp = tcg_temp_new();
956 tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
957 tcg_gen_neg_i64(tmp, tmp);
958 tcg_gen_andi_i64(tmp, tmp, 0x3f);
959 tcg_gen_shl_i64(vc, va, tmp);
962 gen_zapnoti(vc, vc, byte_mask);
965 /* EXTBL, EXTWL, EXTLL, EXTQL */
966 static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
967 uint8_t lit, uint8_t byte_mask)
970 tcg_gen_shri_i64(vc, va, (lit & 7) * 8);
972 TCGv tmp = tcg_temp_new();
973 tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
974 tcg_gen_shli_i64(tmp, tmp, 3);
975 tcg_gen_shr_i64(vc, va, tmp);
978 gen_zapnoti(vc, vc, byte_mask);
981 /* INSWH, INSLH, INSQH */
982 static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
983 uint8_t lit, uint8_t byte_mask)
985 TCGv tmp = tcg_temp_new();
987 /* The instruction description has us left-shift the byte mask and extract
988 bits <15:8> and apply that zap at the end. This is equivalent to simply
989 performing the zap first and shifting afterward. */
990 gen_zapnoti(tmp, va, byte_mask);
994 if (unlikely(lit == 0)) {
995 tcg_gen_movi_i64(vc, 0);
997 tcg_gen_shri_i64(vc, tmp, 64 - lit * 8);
1000 TCGv shift = tcg_temp_new();
1002 /* If (B & 7) == 0, we need to shift by 64 and leave a zero. Do this
1003 portably by splitting the shift into two parts: shift_count-1 and 1.
1004 Arrange for the -1 by using ones-complement instead of
1005 twos-complement in the negation: ~(B * 8) & 63. */
1007 tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1008 tcg_gen_not_i64(shift, shift);
1009 tcg_gen_andi_i64(shift, shift, 0x3f);
1011 tcg_gen_shr_i64(vc, tmp, shift);
1012 tcg_gen_shri_i64(vc, vc, 1);
1013 tcg_temp_free(shift);
1018 /* INSBL, INSWL, INSLL, INSQL */
1019 static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1020 uint8_t lit, uint8_t byte_mask)
1022 TCGv tmp = tcg_temp_new();
1024 /* The instruction description has us left-shift the byte mask
1025 the same number of byte slots as the data and apply the zap
1026 at the end. This is equivalent to simply performing the zap
1027 first and shifting afterward. */
1028 gen_zapnoti(tmp, va, byte_mask);
1031 tcg_gen_shli_i64(vc, tmp, (lit & 7) * 8);
1033 TCGv shift = tcg_temp_new();
1034 tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1035 tcg_gen_shli_i64(shift, shift, 3);
1036 tcg_gen_shl_i64(vc, tmp, shift);
1037 tcg_temp_free(shift);
1042 /* MSKWH, MSKLH, MSKQH */
1043 static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1044 uint8_t lit, uint8_t byte_mask)
1047 gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8));
1049 TCGv shift = tcg_temp_new();
1050 TCGv mask = tcg_temp_new();
1052 /* The instruction description is as above, where the byte_mask
1053 is shifted left, and then we extract bits <15:8>. This can be
1054 emulated with a right-shift on the expanded byte mask. This
1055 requires extra care because for an input <2:0> == 0 we need a
1056 shift of 64 bits in order to generate a zero. This is done by
1057 splitting the shift into two parts, the variable shift - 1
1058 followed by a constant 1 shift. The code we expand below is
1059 equivalent to ~(B * 8) & 63. */
1061 tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1062 tcg_gen_not_i64(shift, shift);
1063 tcg_gen_andi_i64(shift, shift, 0x3f);
1064 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1065 tcg_gen_shr_i64(mask, mask, shift);
1066 tcg_gen_shri_i64(mask, mask, 1);
1068 tcg_gen_andc_i64(vc, va, mask);
1070 tcg_temp_free(mask);
1071 tcg_temp_free(shift);
1075 /* MSKBL, MSKWL, MSKLL, MSKQL */
1076 static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1077 uint8_t lit, uint8_t byte_mask)
1080 gen_zapnoti(vc, va, ~(byte_mask << (lit & 7)));
1082 TCGv shift = tcg_temp_new();
1083 TCGv mask = tcg_temp_new();
1085 tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1086 tcg_gen_shli_i64(shift, shift, 3);
1087 tcg_gen_movi_i64(mask, zapnot_mask(byte_mask));
1088 tcg_gen_shl_i64(mask, mask, shift);
1090 tcg_gen_andc_i64(vc, va, mask);
1092 tcg_temp_free(mask);
1093 tcg_temp_free(shift);
1097 static void gen_rx(DisasContext *ctx, int ra, int set)
1102 tcg_gen_ld8u_i64(ctx->ir[ra], cpu_env,
1103 offsetof(CPUAlphaState, intr_flag));
1106 tmp = tcg_const_i32(set);
1107 tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUAlphaState, intr_flag));
1108 tcg_temp_free_i32(tmp);
1111 static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1113 /* We're emulating OSF/1 PALcode. Many of these are trivial access
1114 to internal cpu registers. */
1116 /* Unprivileged PAL call */
1117 if (palcode >= 0x80 && palcode < 0xC0) {
1121 /* No-op inside QEMU. */
1125 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1126 offsetof(CPUAlphaState, unique));
1130 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1131 offsetof(CPUAlphaState, unique));
1140 #ifndef CONFIG_USER_ONLY
1141 /* Privileged PAL code */
1142 if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1146 /* No-op inside QEMU. */
1150 /* No-op inside QEMU. */
1154 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1155 offsetof(CPUAlphaState, vptptr));
1159 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1160 offsetof(CPUAlphaState, sysval));
1164 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1165 offsetof(CPUAlphaState, sysval));
1172 /* Note that we already know we're in kernel mode, so we know
1173 that PS only contains the 3 IPL bits. */
1174 tcg_gen_ld8u_i64(ctx->ir[IR_V0], cpu_env,
1175 offsetof(CPUAlphaState, ps));
1177 /* But make sure and store only the 3 IPL bits from the user. */
1178 tmp = tcg_temp_new();
1179 tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK);
1180 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps));
1187 tcg_gen_ld8u_i64(ctx->ir[IR_V0], cpu_env,
1188 offsetof(CPUAlphaState, ps));
1192 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1193 offsetof(CPUAlphaState, usp));
1197 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1198 offsetof(CPUAlphaState, usp));
1202 tcg_gen_ld32s_i64(ctx->ir[IR_V0], cpu_env,
1203 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1213 return gen_invalid(ctx);
1216 #ifdef CONFIG_USER_ONLY
1217 return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1220 TCGv tmp = tcg_temp_new();
1221 uint64_t exc_addr = ctx->pc;
1222 uint64_t entry = ctx->palbr;
1224 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
1227 tcg_gen_movi_i64(tmp, 1);
1228 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, pal_mode));
1231 tcg_gen_movi_i64(tmp, exc_addr);
1232 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
1235 entry += (palcode & 0x80
1236 ? 0x2000 + (palcode - 0x80) * 64
1237 : 0x1000 + palcode * 64);
1239 /* Since the destination is running in PALmode, we don't really
1240 need the page permissions check. We'll see the existence of
1241 the page when we create the TB, and we'll flush all TBs if
1242 we change the PAL base register. */
1243 if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
1245 tcg_gen_movi_i64(cpu_pc, entry);
1246 tcg_gen_exit_tb((uintptr_t)ctx->tb);
1247 return EXIT_GOTO_TB;
1249 tcg_gen_movi_i64(cpu_pc, entry);
1250 return EXIT_PC_UPDATED;
1256 #ifndef CONFIG_USER_ONLY
1258 #define PR_BYTE 0x100000
1259 #define PR_LONG 0x200000
1261 static int cpu_pr_data(int pr)
1264 case 0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
1265 case 1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
1266 case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1267 case 3: return offsetof(CPUAlphaState, trap_arg0);
1268 case 4: return offsetof(CPUAlphaState, trap_arg1);
1269 case 5: return offsetof(CPUAlphaState, trap_arg2);
1270 case 6: return offsetof(CPUAlphaState, exc_addr);
1271 case 7: return offsetof(CPUAlphaState, palbr);
1272 case 8: return offsetof(CPUAlphaState, ptbr);
1273 case 9: return offsetof(CPUAlphaState, vptptr);
1274 case 10: return offsetof(CPUAlphaState, unique);
1275 case 11: return offsetof(CPUAlphaState, sysval);
1276 case 12: return offsetof(CPUAlphaState, usp);
1279 return offsetof(CPUAlphaState, scratch[pr - 40]);
1282 return offsetof(CPUAlphaState, alarm_expire);
1287 static ExitStatus gen_mfpr(DisasContext *ctx, TCGv va, int regno)
1289 void (*helper)(TCGv);
1294 /* Accessing the "non-shadow" general registers. */
1295 regno = regno == 39 ? 25 : regno - 32 + 8;
1296 tcg_gen_mov_i64(va, cpu_std_ir[regno]);
1299 case 250: /* WALLTIME */
1300 helper = gen_helper_get_walltime;
1302 case 249: /* VMTIME */
1303 helper = gen_helper_get_vmtime;
1309 return EXIT_PC_STALE;
1316 /* The basic registers are data only, and unknown registers
1317 are read-zero, write-ignore. */
1318 data = cpu_pr_data(regno);
1320 tcg_gen_movi_i64(va, 0);
1321 } else if (data & PR_BYTE) {
1322 tcg_gen_ld8u_i64(va, cpu_env, data & ~PR_BYTE);
1323 } else if (data & PR_LONG) {
1324 tcg_gen_ld32s_i64(va, cpu_env, data & ~PR_LONG);
1326 tcg_gen_ld_i64(va, cpu_env, data);
1334 static ExitStatus gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
1342 gen_helper_tbia(cpu_env);
1347 gen_helper_tbis(cpu_env, vb);
1352 tmp = tcg_const_i64(1);
1353 tcg_gen_st32_i64(tmp, cpu_env, -offsetof(AlphaCPU, env) +
1354 offsetof(CPUState, halted));
1355 return gen_excp(ctx, EXCP_HLT, 0);
1359 gen_helper_halt(vb);
1360 return EXIT_PC_STALE;
1364 gen_helper_set_alarm(cpu_env, vb);
1369 tcg_gen_st_i64(vb, cpu_env, offsetof(CPUAlphaState, palbr));
1370 /* Changing the PAL base register implies un-chaining all of the TBs
1371 that ended with a CALL_PAL. Since the base register usually only
1372 changes during boot, flushing everything works well. */
1373 gen_helper_tb_flush(cpu_env);
1374 return EXIT_PC_STALE;
1377 /* Accessing the "non-shadow" general registers. */
1378 regno = regno == 39 ? 25 : regno - 32 + 8;
1379 tcg_gen_mov_i64(cpu_std_ir[regno], vb);
1383 /* The basic registers are data only, and unknown registers
1384 are read-zero, write-ignore. */
1385 data = cpu_pr_data(regno);
1387 if (data & PR_BYTE) {
1388 tcg_gen_st8_i64(vb, cpu_env, data & ~PR_BYTE);
1389 } else if (data & PR_LONG) {
1390 tcg_gen_st32_i64(vb, cpu_env, data & ~PR_LONG);
1392 tcg_gen_st_i64(vb, cpu_env, data);
1400 #endif /* !USER_ONLY*/
1402 #define REQUIRE_NO_LIT \
1409 #define REQUIRE_TB_FLAG(FLAG) \
1411 if ((ctx->tb->flags & (FLAG)) == 0) { \
1416 #define REQUIRE_REG_31(WHICH) \
1418 if (WHICH != 31) { \
1423 static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1425 int32_t disp21, disp16, disp12 __attribute__((unused));
1427 uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
1428 bool islit, real_islit;
1429 TCGv va, vb, vc, tmp, tmp2;
1433 /* Decode all instruction fields */
1434 opc = extract32(insn, 26, 6);
1435 ra = extract32(insn, 21, 5);
1436 rb = extract32(insn, 16, 5);
1437 rc = extract32(insn, 0, 5);
1438 real_islit = islit = extract32(insn, 12, 1);
1439 lit = extract32(insn, 13, 8);
1441 disp21 = sextract32(insn, 0, 21);
1442 disp16 = sextract32(insn, 0, 16);
1443 disp12 = sextract32(insn, 0, 12);
1445 fn11 = extract32(insn, 5, 11);
1446 fpfn = extract32(insn, 5, 6);
1447 fn7 = extract32(insn, 5, 7);
1449 if (rb == 31 && !islit) {
1458 ret = gen_call_pal(ctx, insn & 0x03ffffff);
1484 disp16 = (uint32_t)disp16 << 16;
1488 va = dest_gpr(ctx, ra);
1489 /* It's worth special-casing immediate loads. */
1491 tcg_gen_movi_i64(va, disp16);
1493 tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);
1499 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1500 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1504 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1508 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1509 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1513 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1514 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1518 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1519 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1523 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1527 vc = dest_gpr(ctx, rc);
1528 vb = load_gpr_lit(ctx, rb, lit, islit);
1532 /* Special case ADDL as SEXTL. */
1533 tcg_gen_ext32s_i64(vc, vb);
1537 /* Special case SUBQ as NEGQ. */
1538 tcg_gen_neg_i64(vc, vb);
1543 va = load_gpr(ctx, ra);
1547 tcg_gen_add_i64(vc, va, vb);
1548 tcg_gen_ext32s_i64(vc, vc);
1552 tmp = tcg_temp_new();
1553 tcg_gen_shli_i64(tmp, va, 2);
1554 tcg_gen_add_i64(tmp, tmp, vb);
1555 tcg_gen_ext32s_i64(vc, tmp);
1560 tcg_gen_sub_i64(vc, va, vb);
1561 tcg_gen_ext32s_i64(vc, vc);
1565 tmp = tcg_temp_new();
1566 tcg_gen_shli_i64(tmp, va, 2);
1567 tcg_gen_sub_i64(tmp, tmp, vb);
1568 tcg_gen_ext32s_i64(vc, tmp);
1574 /* Special case 0 >= X as X == 0. */
1575 gen_helper_cmpbe0(vc, vb);
1577 gen_helper_cmpbge(vc, va, vb);
1582 tmp = tcg_temp_new();
1583 tcg_gen_shli_i64(tmp, va, 3);
1584 tcg_gen_add_i64(tmp, tmp, vb);
1585 tcg_gen_ext32s_i64(vc, tmp);
1590 tmp = tcg_temp_new();
1591 tcg_gen_shli_i64(tmp, va, 3);
1592 tcg_gen_sub_i64(tmp, tmp, vb);
1593 tcg_gen_ext32s_i64(vc, tmp);
1598 tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb);
1602 tcg_gen_add_i64(vc, va, vb);
1606 tmp = tcg_temp_new();
1607 tcg_gen_shli_i64(tmp, va, 2);
1608 tcg_gen_add_i64(vc, tmp, vb);
1613 tcg_gen_sub_i64(vc, va, vb);
1617 tmp = tcg_temp_new();
1618 tcg_gen_shli_i64(tmp, va, 2);
1619 tcg_gen_sub_i64(vc, tmp, vb);
1624 tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb);
1628 tmp = tcg_temp_new();
1629 tcg_gen_shli_i64(tmp, va, 3);
1630 tcg_gen_add_i64(vc, tmp, vb);
1635 tmp = tcg_temp_new();
1636 tcg_gen_shli_i64(tmp, va, 3);
1637 tcg_gen_sub_i64(vc, tmp, vb);
1642 tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb);
1646 tmp = tcg_temp_new();
1647 tcg_gen_ext32s_i64(tmp, va);
1648 tcg_gen_ext32s_i64(vc, vb);
1649 tcg_gen_add_i64(tmp, tmp, vc);
1650 tcg_gen_ext32s_i64(vc, tmp);
1651 gen_helper_check_overflow(cpu_env, vc, tmp);
1656 tmp = tcg_temp_new();
1657 tcg_gen_ext32s_i64(tmp, va);
1658 tcg_gen_ext32s_i64(vc, vb);
1659 tcg_gen_sub_i64(tmp, tmp, vc);
1660 tcg_gen_ext32s_i64(vc, tmp);
1661 gen_helper_check_overflow(cpu_env, vc, tmp);
1666 tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb);
1670 tmp = tcg_temp_new();
1671 tmp2 = tcg_temp_new();
1672 tcg_gen_eqv_i64(tmp, va, vb);
1673 tcg_gen_mov_i64(tmp2, va);
1674 tcg_gen_add_i64(vc, va, vb);
1675 tcg_gen_xor_i64(tmp2, tmp2, vc);
1676 tcg_gen_and_i64(tmp, tmp, tmp2);
1677 tcg_gen_shri_i64(tmp, tmp, 63);
1678 tcg_gen_movi_i64(tmp2, 0);
1679 gen_helper_check_overflow(cpu_env, tmp, tmp2);
1681 tcg_temp_free(tmp2);
1685 tmp = tcg_temp_new();
1686 tmp2 = tcg_temp_new();
1687 tcg_gen_xor_i64(tmp, va, vb);
1688 tcg_gen_mov_i64(tmp2, va);
1689 tcg_gen_sub_i64(vc, va, vb);
1690 tcg_gen_xor_i64(tmp2, tmp2, vc);
1691 tcg_gen_and_i64(tmp, tmp, tmp2);
1692 tcg_gen_shri_i64(tmp, tmp, 63);
1693 tcg_gen_movi_i64(tmp2, 0);
1694 gen_helper_check_overflow(cpu_env, tmp, tmp2);
1696 tcg_temp_free(tmp2);
1700 tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb);
1710 /* Special case BIS as NOP. */
1714 /* Special case BIS as MOV. */
1715 vc = dest_gpr(ctx, rc);
1717 tcg_gen_movi_i64(vc, lit);
1719 tcg_gen_mov_i64(vc, load_gpr(ctx, rb));
1725 vc = dest_gpr(ctx, rc);
1726 vb = load_gpr_lit(ctx, rb, lit, islit);
1728 if (fn7 == 0x28 && ra == 31) {
1729 /* Special case ORNOT as NOT. */
1730 tcg_gen_not_i64(vc, vb);
1734 va = load_gpr(ctx, ra);
1738 tcg_gen_and_i64(vc, va, vb);
1742 tcg_gen_andc_i64(vc, va, vb);
1746 tmp = tcg_temp_new();
1747 tcg_gen_andi_i64(tmp, va, 1);
1748 tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
1749 vb, load_gpr(ctx, rc));
1754 tmp = tcg_temp_new();
1755 tcg_gen_andi_i64(tmp, va, 1);
1756 tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
1757 vb, load_gpr(ctx, rc));
1762 tcg_gen_or_i64(vc, va, vb);
1766 tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx),
1767 vb, load_gpr(ctx, rc));
1771 tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx),
1772 vb, load_gpr(ctx, rc));
1776 tcg_gen_orc_i64(vc, va, vb);
1780 tcg_gen_xor_i64(vc, va, vb);
1784 tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx),
1785 vb, load_gpr(ctx, rc));
1789 tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx),
1790 vb, load_gpr(ctx, rc));
1794 tcg_gen_eqv_i64(vc, va, vb);
1800 uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
1801 tcg_gen_andi_i64(vc, vb, ~amask);
1806 tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx),
1807 vb, load_gpr(ctx, rc));
1811 tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx),
1812 vb, load_gpr(ctx, rc));
1817 tcg_gen_movi_i64(vc, ctx->implver);
1825 vc = dest_gpr(ctx, rc);
1826 va = load_gpr(ctx, ra);
1830 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01);
1834 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01);
1838 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01);
1842 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03);
1846 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03);
1850 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03);
1854 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f);
1858 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f);
1862 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f);
1867 gen_zapnoti(vc, va, ~lit);
1869 gen_helper_zap(vc, va, load_gpr(ctx, rb));
1875 gen_zapnoti(vc, va, lit);
1877 gen_helper_zapnot(vc, va, load_gpr(ctx, rb));
1882 gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff);
1887 tcg_gen_shri_i64(vc, va, lit & 0x3f);
1889 tmp = tcg_temp_new();
1890 vb = load_gpr(ctx, rb);
1891 tcg_gen_andi_i64(tmp, vb, 0x3f);
1892 tcg_gen_shr_i64(vc, va, tmp);
1898 gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff);
1903 tcg_gen_shli_i64(vc, va, lit & 0x3f);
1905 tmp = tcg_temp_new();
1906 vb = load_gpr(ctx, rb);
1907 tcg_gen_andi_i64(tmp, vb, 0x3f);
1908 tcg_gen_shl_i64(vc, va, tmp);
1914 gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff);
1919 tcg_gen_sari_i64(vc, va, lit & 0x3f);
1921 tmp = tcg_temp_new();
1922 vb = load_gpr(ctx, rb);
1923 tcg_gen_andi_i64(tmp, vb, 0x3f);
1924 tcg_gen_sar_i64(vc, va, tmp);
1930 gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03);
1934 gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03);
1938 gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03);
1942 gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f);
1946 gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f);
1950 gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f);
1954 gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff);
1958 gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff);
1962 gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff);
1970 vc = dest_gpr(ctx, rc);
1971 vb = load_gpr_lit(ctx, rb, lit, islit);
1972 va = load_gpr(ctx, ra);
1976 tcg_gen_mul_i64(vc, va, vb);
1977 tcg_gen_ext32s_i64(vc, vc);
1981 tcg_gen_mul_i64(vc, va, vb);
1985 tmp = tcg_temp_new();
1986 tcg_gen_mulu2_i64(tmp, vc, va, vb);
1991 tmp = tcg_temp_new();
1992 tcg_gen_ext32s_i64(tmp, va);
1993 tcg_gen_ext32s_i64(vc, vb);
1994 tcg_gen_mul_i64(tmp, tmp, vc);
1995 tcg_gen_ext32s_i64(vc, tmp);
1996 gen_helper_check_overflow(cpu_env, vc, tmp);
2001 tmp = tcg_temp_new();
2002 tmp2 = tcg_temp_new();
2003 tcg_gen_muls2_i64(vc, tmp, va, vb);
2004 tcg_gen_sari_i64(tmp2, vc, 63);
2005 gen_helper_check_overflow(cpu_env, tmp, tmp2);
2007 tcg_temp_free(tmp2);
2015 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
2016 vc = dest_fpr(ctx, rc);
2017 switch (fpfn) { /* fn11 & 0x3F */
2021 t32 = tcg_temp_new_i32();
2022 va = load_gpr(ctx, ra);
2023 tcg_gen_extrl_i64_i32(t32, va);
2024 gen_helper_memory_to_s(vc, t32);
2025 tcg_temp_free_i32(t32);
2030 vb = load_fpr(ctx, rb);
2031 gen_helper_sqrtf(vc, cpu_env, vb);
2036 gen_sqrts(ctx, rb, rc, fn11);
2041 t32 = tcg_temp_new_i32();
2042 va = load_gpr(ctx, ra);
2043 tcg_gen_extrl_i64_i32(t32, va);
2044 gen_helper_memory_to_f(vc, t32);
2045 tcg_temp_free_i32(t32);
2050 va = load_gpr(ctx, ra);
2051 tcg_gen_mov_i64(vc, va);
2056 vb = load_fpr(ctx, rb);
2057 gen_helper_sqrtg(vc, cpu_env, vb);
2062 gen_sqrtt(ctx, rb, rc, fn11);
2070 /* VAX floating point */
2071 /* XXX: rounding mode and trap are ignored (!) */
2072 vc = dest_fpr(ctx, rc);
2073 vb = load_fpr(ctx, rb);
2074 va = load_fpr(ctx, ra);
2075 switch (fpfn) { /* fn11 & 0x3F */
2078 gen_helper_addf(vc, cpu_env, va, vb);
2082 gen_helper_subf(vc, cpu_env, va, vb);
2086 gen_helper_mulf(vc, cpu_env, va, vb);
2090 gen_helper_divf(vc, cpu_env, va, vb);
2098 gen_helper_addg(vc, cpu_env, va, vb);
2102 gen_helper_subg(vc, cpu_env, va, vb);
2106 gen_helper_mulg(vc, cpu_env, va, vb);
2110 gen_helper_divg(vc, cpu_env, va, vb);
2114 gen_helper_cmpgeq(vc, cpu_env, va, vb);
2118 gen_helper_cmpglt(vc, cpu_env, va, vb);
2122 gen_helper_cmpgle(vc, cpu_env, va, vb);
2127 gen_helper_cvtgf(vc, cpu_env, vb);
2136 gen_helper_cvtgq(vc, cpu_env, vb);
2141 gen_helper_cvtqf(vc, cpu_env, vb);
2146 gen_helper_cvtqg(vc, cpu_env, vb);
2154 /* IEEE floating-point */
2155 switch (fpfn) { /* fn11 & 0x3F */
2158 gen_adds(ctx, ra, rb, rc, fn11);
2162 gen_subs(ctx, ra, rb, rc, fn11);
2166 gen_muls(ctx, ra, rb, rc, fn11);
2170 gen_divs(ctx, ra, rb, rc, fn11);
2174 gen_addt(ctx, ra, rb, rc, fn11);
2178 gen_subt(ctx, ra, rb, rc, fn11);
2182 gen_mult(ctx, ra, rb, rc, fn11);
2186 gen_divt(ctx, ra, rb, rc, fn11);
2190 gen_cmptun(ctx, ra, rb, rc, fn11);
2194 gen_cmpteq(ctx, ra, rb, rc, fn11);
2198 gen_cmptlt(ctx, ra, rb, rc, fn11);
2202 gen_cmptle(ctx, ra, rb, rc, fn11);
2206 if (fn11 == 0x2AC || fn11 == 0x6AC) {
2208 gen_cvtst(ctx, rb, rc, fn11);
2211 gen_cvtts(ctx, rb, rc, fn11);
2217 gen_cvttq(ctx, rb, rc, fn11);
2222 gen_cvtqs(ctx, rb, rc, fn11);
2227 gen_cvtqt(ctx, rb, rc, fn11);
2239 vc = dest_fpr(ctx, rc);
2240 vb = load_fpr(ctx, rb);
2246 /* Special case CPYS as FNOP. */
2248 vc = dest_fpr(ctx, rc);
2249 va = load_fpr(ctx, ra);
2251 /* Special case CPYS as FMOV. */
2252 tcg_gen_mov_i64(vc, va);
2254 vb = load_fpr(ctx, rb);
2255 gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL);
2261 vc = dest_fpr(ctx, rc);
2262 vb = load_fpr(ctx, rb);
2263 va = load_fpr(ctx, ra);
2264 gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL);
2268 vc = dest_fpr(ctx, rc);
2269 vb = load_fpr(ctx, rb);
2270 va = load_fpr(ctx, ra);
2271 gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL);
2275 va = load_fpr(ctx, ra);
2276 gen_helper_store_fpcr(cpu_env, va);
2277 if (ctx->tb_rm == QUAL_RM_D) {
2278 /* Re-do the copy of the rounding mode to fp_status
2279 the next time we use dynamic rounding. */
2285 va = dest_fpr(ctx, ra);
2286 gen_helper_load_fpcr(va, cpu_env);
2290 gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc);
2294 gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc);
2298 gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc);
2302 gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc);
2306 gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc);
2310 gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);
2312 case 0x030: /* CVTQL */
2313 case 0x130: /* CVTQL/V */
2314 case 0x530: /* CVTQL/SV */
2316 vc = dest_fpr(ctx, rc);
2317 vb = load_fpr(ctx, rb);
2318 gen_helper_cvtql(vc, cpu_env, vb);
2319 gen_fp_exc_raise(rc, fn11);
2327 switch ((uint16_t)disp16) {
2354 va = dest_gpr(ctx, ra);
2355 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2357 gen_helper_load_pcc(va, cpu_env);
2359 ret = EXIT_PC_STALE;
2361 gen_helper_load_pcc(va, cpu_env);
2389 /* HW_MFPR (PALcode) */
2390 #ifndef CONFIG_USER_ONLY
2391 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2392 va = dest_gpr(ctx, ra);
2393 ret = gen_mfpr(ctx, va, insn & 0xffff);
2400 /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch
2401 prediction stack action, which of course we don't implement. */
2402 vb = load_gpr(ctx, rb);
2403 tcg_gen_andi_i64(cpu_pc, vb, ~3);
2405 tcg_gen_movi_i64(ctx->ir[ra], ctx->pc);
2407 ret = EXIT_PC_UPDATED;
2411 /* HW_LD (PALcode) */
2412 #ifndef CONFIG_USER_ONLY
2413 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2415 TCGv addr = tcg_temp_new();
2416 vb = load_gpr(ctx, rb);
2417 va = dest_gpr(ctx, ra);
2419 tcg_gen_addi_i64(addr, vb, disp12);
2420 switch ((insn >> 12) & 0xF) {
2422 /* Longword physical access (hw_ldl/p) */
2423 gen_helper_ldl_phys(va, cpu_env, addr);
2426 /* Quadword physical access (hw_ldq/p) */
2427 gen_helper_ldq_phys(va, cpu_env, addr);
2430 /* Longword physical access with lock (hw_ldl_l/p) */
2431 gen_helper_ldl_l_phys(va, cpu_env, addr);
2434 /* Quadword physical access with lock (hw_ldq_l/p) */
2435 gen_helper_ldq_l_phys(va, cpu_env, addr);
2438 /* Longword virtual PTE fetch (hw_ldl/v) */
2441 /* Quadword virtual PTE fetch (hw_ldq/v) */
2451 /* Longword virtual access (hw_ldl) */
2454 /* Quadword virtual access (hw_ldq) */
2457 /* Longword virtual access with protection check (hw_ldl/w) */
2458 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LESL);
2461 /* Quadword virtual access with protection check (hw_ldq/w) */
2462 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEQ);
2465 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2468 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2471 /* Longword virtual access with alternate access mode and
2472 protection checks (hw_ldl/wa) */
2473 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LESL);
2476 /* Quadword virtual access with alternate access mode and
2477 protection checks (hw_ldq/wa) */
2478 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEQ);
2481 tcg_temp_free(addr);
2489 vc = dest_gpr(ctx, rc);
2492 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
2494 va = load_fpr(ctx, ra);
2495 tcg_gen_mov_i64(vc, va);
2497 } else if (fn7 == 0x78) {
2499 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
2501 t32 = tcg_temp_new_i32();
2502 va = load_fpr(ctx, ra);
2503 gen_helper_s_to_memory(t32, va);
2504 tcg_gen_ext_i32_i64(vc, t32);
2505 tcg_temp_free_i32(t32);
2509 vb = load_gpr_lit(ctx, rb, lit, islit);
2513 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
2515 tcg_gen_ext8s_i64(vc, vb);
2519 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
2521 tcg_gen_ext16s_i64(vc, vb);
2525 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
2528 gen_helper_ctpop(vc, vb);
2532 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2534 va = load_gpr(ctx, ra);
2535 gen_helper_perr(vc, va, vb);
2539 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
2542 gen_helper_ctlz(vc, vb);
2546 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
2549 gen_helper_cttz(vc, vb);
2553 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2556 gen_helper_unpkbw(vc, vb);
2560 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2563 gen_helper_unpkbl(vc, vb);
2567 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2570 gen_helper_pkwb(vc, vb);
2574 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2577 gen_helper_pklb(vc, vb);
2581 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2582 va = load_gpr(ctx, ra);
2583 gen_helper_minsb8(vc, va, vb);
2587 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2588 va = load_gpr(ctx, ra);
2589 gen_helper_minsw4(vc, va, vb);
2593 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2594 va = load_gpr(ctx, ra);
2595 gen_helper_minub8(vc, va, vb);
2599 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2600 va = load_gpr(ctx, ra);
2601 gen_helper_minuw4(vc, va, vb);
2605 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2606 va = load_gpr(ctx, ra);
2607 gen_helper_maxub8(vc, va, vb);
2611 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2612 va = load_gpr(ctx, ra);
2613 gen_helper_maxuw4(vc, va, vb);
2617 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2618 va = load_gpr(ctx, ra);
2619 gen_helper_maxsb8(vc, va, vb);
2623 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2624 va = load_gpr(ctx, ra);
2625 gen_helper_maxsw4(vc, va, vb);
2633 /* HW_MTPR (PALcode) */
2634 #ifndef CONFIG_USER_ONLY
2635 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2636 vb = load_gpr(ctx, rb);
2637 ret = gen_mtpr(ctx, vb, insn & 0xffff);
2644 /* HW_RET (PALcode) */
2645 #ifndef CONFIG_USER_ONLY
2646 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2648 /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
2649 address from EXC_ADDR. This turns out to be useful for our
2650 emulation PALcode, so continue to accept it. */
2651 ctx->lit = vb = tcg_temp_new();
2652 tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr));
2654 vb = load_gpr(ctx, rb);
2656 tmp = tcg_temp_new();
2657 tcg_gen_movi_i64(tmp, 0);
2658 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, intr_flag));
2659 tcg_gen_movi_i64(cpu_lock_addr, -1);
2660 tcg_gen_andi_i64(tmp, vb, 1);
2661 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, pal_mode));
2662 tcg_gen_andi_i64(cpu_pc, vb, ~3);
2663 ret = EXIT_PC_UPDATED;
2670 /* HW_ST (PALcode) */
2671 #ifndef CONFIG_USER_ONLY
2672 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2674 TCGv addr = tcg_temp_new();
2675 va = load_gpr(ctx, ra);
2676 vb = load_gpr(ctx, rb);
2678 tcg_gen_addi_i64(addr, vb, disp12);
2679 switch ((insn >> 12) & 0xF) {
2681 /* Longword physical access */
2682 gen_helper_stl_phys(cpu_env, addr, va);
2685 /* Quadword physical access */
2686 gen_helper_stq_phys(cpu_env, addr, va);
2689 /* Longword physical access with lock */
2690 gen_helper_stl_c_phys(dest_gpr(ctx, ra), cpu_env, addr, va);
2693 /* Quadword physical access with lock */
2694 gen_helper_stq_c_phys(dest_gpr(ctx, ra), cpu_env, addr, va);
2697 /* Longword virtual access */
2700 /* Quadword virtual access */
2721 /* Longword virtual access with alternate access mode */
2724 /* Quadword virtual access with alternate access mode */
2733 tcg_temp_free(addr);
2741 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
2745 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
2749 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
2753 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
2757 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
2761 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
2765 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
2769 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
2773 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
2777 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
2781 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
2785 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
2789 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
2793 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
2797 ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
2801 ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
2805 ret = gen_bdirect(ctx, ra, disp21);
2807 case 0x31: /* FBEQ */
2808 ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
2810 case 0x32: /* FBLT */
2811 ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
2813 case 0x33: /* FBLE */
2814 ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
2818 ret = gen_bdirect(ctx, ra, disp21);
2820 case 0x35: /* FBNE */
2821 ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
2823 case 0x36: /* FBGE */
2824 ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
2826 case 0x37: /* FBGT */
2827 ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
2831 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
2835 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
2839 ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
2843 ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
2847 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
2851 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
2855 ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
2859 ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
2862 ret = gen_invalid(ctx);
2869 void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
2871 AlphaCPU *cpu = alpha_env_get_cpu(env);
2872 CPUState *cs = CPU(cpu);
2873 DisasContext ctx, *ctxp = &ctx;
2874 target_ulong pc_start;
2875 target_ulong pc_mask;
2885 ctx.mem_idx = cpu_mmu_index(env, false);
2886 ctx.implver = env->implver;
2887 ctx.singlestep_enabled = cs->singlestep_enabled;
2889 #ifdef CONFIG_USER_ONLY
2890 ctx.ir = cpu_std_ir;
2892 ctx.palbr = env->palbr;
2893 ctx.ir = (tb->flags & TB_FLAGS_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
2896 /* ??? Every TB begins with unset rounding mode, to be initialized on
2897 the first fp insn of the TB. Alternately we could define a proper
2898 default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
2899 to reset the FP_STATUS to that default at the end of any TB that
2900 changes the default. We could even (gasp) dynamiclly figure out
2901 what default would be most efficient given the running program. */
2903 /* Similarly for flush-to-zero. */
2907 max_insns = tb->cflags & CF_COUNT_MASK;
2908 if (max_insns == 0) {
2909 max_insns = CF_COUNT_MASK;
2911 if (max_insns > TCG_MAX_INSNS) {
2912 max_insns = TCG_MAX_INSNS;
2915 if (in_superpage(&ctx, pc_start)) {
2916 pc_mask = (1ULL << 41) - 1;
2918 pc_mask = ~TARGET_PAGE_MASK;
2923 tcg_gen_insn_start(ctx.pc);
2926 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
2927 ret = gen_excp(&ctx, EXCP_DEBUG, 0);
2928 /* The address covered by the breakpoint must be included in
2929 [tb->pc, tb->pc + tb->size) in order to for it to be
2930 properly cleared -- thus we increment the PC here so that
2931 the logic setting tb->size below does the right thing. */
2935 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2938 insn = cpu_ldl_code(env, ctx.pc);
2940 TCGV_UNUSED_I64(ctx.zero);
2941 TCGV_UNUSED_I64(ctx.sink);
2942 TCGV_UNUSED_I64(ctx.lit);
2945 ret = translate_one(ctxp, insn);
2947 if (!TCGV_IS_UNUSED_I64(ctx.sink)) {
2948 tcg_gen_discard_i64(ctx.sink);
2949 tcg_temp_free(ctx.sink);
2951 if (!TCGV_IS_UNUSED_I64(ctx.zero)) {
2952 tcg_temp_free(ctx.zero);
2954 if (!TCGV_IS_UNUSED_I64(ctx.lit)) {
2955 tcg_temp_free(ctx.lit);
2958 /* If we reach a page boundary, are single stepping,
2959 or exhaust instruction count, stop generation. */
2961 && ((ctx.pc & pc_mask) == 0
2962 || tcg_op_buf_full()
2963 || num_insns >= max_insns
2965 || ctx.singlestep_enabled)) {
2966 ret = EXIT_PC_STALE;
2968 } while (ret == NO_EXIT);
2970 if (tb->cflags & CF_LAST_IO) {
2979 tcg_gen_movi_i64(cpu_pc, ctx.pc);
2981 case EXIT_PC_UPDATED:
2982 if (ctx.singlestep_enabled) {
2983 gen_excp_1(EXCP_DEBUG, 0);
2992 gen_tb_end(tb, num_insns);
2994 tb->size = ctx.pc - pc_start;
2995 tb->icount = num_insns;
2998 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
2999 && qemu_log_in_addr_range(pc_start)) {
3000 qemu_log("IN: %s\n", lookup_symbol(pc_start));
3001 log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
3007 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,