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/>.
21 #include "disas/disas.h"
22 #include "qemu/host-utils.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__)
35 # define LOG_DISAS(...) do { } while (0)
38 typedef struct DisasContext DisasContext
;
40 struct TranslationBlock
*tb
;
44 /* Current rounding mode for this TB. */
46 /* Current flush-to-zero setting for this TB. */
49 /* implver value for this CPU. */
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. */
61 /* We have emitted one or more goto_tb. No fixup required. */
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
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. */
73 /* We are ending the TB with a noreturn function call, e.g. longjmp.
74 No following code will be executed. */
78 /* global register indexes */
79 static TCGv_ptr cpu_env
;
80 static TCGv cpu_ir
[31];
81 static TCGv cpu_fir
[31];
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
;
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)
101 static int done_init
= 0;
106 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
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
),
127 cpu_lock_st_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
128 offsetof(CPUAlphaState
, lock_st_addr
),
130 cpu_lock_value
= tcg_global_mem_new_i64(TCG_AREG0
,
131 offsetof(CPUAlphaState
, 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");
146 static void gen_excp_1(int exception
, int error_code
)
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
);
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
,
210 int ra
, int rb
, int32_t disp16
, int fp
,
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)) {
222 addr
= tcg_temp_new();
224 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp16
);
226 tcg_gen_andi_i64(addr
, addr
, ~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
);
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
);
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
,
268 int ra
, int rb
, int32_t disp16
, int fp
,
273 addr
= tcg_temp_new();
275 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp16
);
277 tcg_gen_andi_i64(addr
, addr
, ~0x7);
283 tcg_gen_movi_i64(addr
, disp16
);
287 va
= tcg_const_i64(0);
289 va
= (fp
? cpu_fir
[ra
] : cpu_ir
[ra
]);
291 tcg_gen_qemu_store(va
, addr
, ctx
->mem_idx
);
299 static ExitStatus
gen_store_conditional(DisasContext
*ctx
, int ra
, int rb
,
300 int32_t disp16
, int quad
)
305 /* ??? Don't bother storing anything. The user can't tell
306 the difference, since the zero register always reads zero. */
310 #if defined(CONFIG_USER_ONLY)
311 addr
= cpu_lock_st_addr
;
313 addr
= tcg_temp_local_new();
317 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp16
);
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
);
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
;
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);
359 static bool in_superpage(DisasContext
*ctx
, int64_t addr
)
361 return ((ctx
->tb
->flags
& TB_FLAGS_USER_MODE
) == 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
)) {
373 /* If the destination is in the superpage, the page perms can't change. */
374 if (in_superpage(ctx
, dest
)) {
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);
386 tcg_gen_movi_i64(cpu_ir
[ra
], ctx
->pc
);
389 /* Notice branch-to-next; used to initialize RA with the PC. */
392 } else if (use_goto_tb(ctx
, dest
)) {
394 tcg_gen_movi_i64(cpu_pc
, dest
);
395 tcg_gen_exit_tb((uintptr_t)ctx
->tb
);
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
);
413 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
);
414 tcg_gen_exit_tb((uintptr_t)ctx
->tb
);
416 gen_set_label(lab_true
);
418 tcg_gen_movi_i64(cpu_pc
, dest
);
419 tcg_gen_exit_tb((uintptr_t)ctx
->tb
+ 1);
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
)
441 if (unlikely(ra
== 31)) {
442 cmp_tmp
= tcg_const_i64(0);
444 cmp_tmp
= tcg_temp_new();
446 tcg_gen_andi_i64(cmp_tmp
, cpu_ir
[ra
], 1);
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;
464 /* For <= or >, the -0.0 value directly compares the way we want. */
465 tcg_gen_mov_i64(dest
, src
);
470 /* For == or !=, we can simply mask off the sign bit and compare. */
471 tcg_gen_andi_i64(dest
, src
, mzero
- 1);
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
);
487 static ExitStatus
gen_fbcond(DisasContext
*ctx
, TCGCond cond
, int ra
,
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
)
508 if (unlikely(rc
== 31)) {
513 /* Very uncommon case - Do not bother to optimize. */
514 c1
= tcg_const_i64(0);
516 c1
= tcg_const_i64(1);
517 tcg_gen_and_i64(c1
, c1
, cpu_ir
[ra
]);
522 v1
= tcg_const_i64(lit
);
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
);
535 tcg_temp_free_i64(v1
);
539 static void gen_fcmov(TCGCond cond
, int ra
, int rb
, int rc
)
543 if (unlikely(rc
== 31)) {
547 c1
= tcg_temp_new_i64();
548 if (unlikely(ra
== 31)) {
549 tcg_gen_movi_i64(c1
, 0);
551 gen_fold_mzero(cond
, c1
, cpu_fir
[ra
]);
554 v1
= tcg_const_i64(0);
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
);
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
)
584 fn11
&= QUAL_RM_MASK
;
585 if (fn11
== ctx
->tb_rm
) {
590 tmp
= tcg_temp_new_i32();
593 tcg_gen_movi_i32(tmp
, float_round_nearest_even
);
596 tcg_gen_movi_i32(tmp
, float_round_to_zero
);
599 tcg_gen_movi_i32(tmp
, float_round_down
);
602 tcg_gen_ld8u_i32(tmp
, cpu_env
,
603 offsetof(CPUAlphaState
, fpcr_dyn_round
));
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
));
614 gen_helper_setroundmode(tmp
);
617 tcg_temp_free_i32(tmp
);
620 static void gen_qual_flushzero(DisasContext
*ctx
, int fn11
)
625 if (fn11
== ctx
->tb_ftz
) {
630 tmp
= tcg_temp_new_i32();
632 /* Underflow is enabled, use the FPCR setting. */
633 tcg_gen_ld8u_i32(tmp
, cpu_env
,
634 offsetof(CPUAlphaState
, fpcr_flush_to_zero
));
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
));
644 gen_helper_setflushzero(tmp
);
647 tcg_temp_free_i32(tmp
);
650 static TCGv
gen_ieee_input(int reg
, int fn11
, int is_cmp
)
654 val
= tcg_const_i64(0);
656 if ((fn11
& QUAL_S
) == 0) {
658 gen_helper_ieee_input_cmp(cpu_env
, cpu_fir
[reg
]);
660 gen_helper_ieee_input(cpu_env
, cpu_fir
[reg
]);
663 val
= tcg_temp_new();
664 tcg_gen_mov_i64(val
, cpu_fir
[reg
]);
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
);
677 gen_helper_fp_exc_clear(cpu_env
);
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();
691 #if defined(CONFIG_SOFTFLOAT_INLINE)
692 tcg_gen_ld8u_i32(exc
, cpu_env
,
693 offsetof(CPUAlphaState
, fp_status
.float_exception_flags
));
695 gen_helper_fp_exc_get(exc
, cpu_env
);
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);
710 gen_helper_fp_exc_raise_s(cpu_env
, exc
, reg
);
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)) {
729 if (unlikely(rb
== 31)) {
730 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
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
);
746 static void gen_fcvtql(int rb
, int rc
)
748 if (unlikely(rc
== 31)) {
751 if (unlikely(rb
== 31)) {
752 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
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
);
766 static void gen_fcvtql_v(DisasContext
*ctx
, int rb
, int rc
)
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
);
781 #define FARITH2(name) \
782 static inline void glue(gen_f, name)(int rb, int rc) \
784 if (unlikely(rc == 31)) { \
788 gen_helper_ ## name(cpu_fir[rc], cpu_env, cpu_fir[rb]); \
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. */
804 static void gen_ieee_arith2(DisasContext
*ctx
,
805 void (*helper
)(TCGv
, TCGv_ptr
, TCGv
),
806 int rb
, int rc
, int fn11
)
810 /* ??? This is wrong: the instruction is not a nop, it still may
812 if (unlikely(rc
== 31)) {
816 gen_qual_roundmode(ctx
, fn11
);
817 gen_qual_flushzero(ctx
, fn11
);
820 vb
= gen_ieee_input(rb
, fn11
, 0);
821 helper(cpu_fir
[rc
], cpu_env
, 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); \
838 static void gen_fcvttq(DisasContext
*ctx
, int rb
, int rc
, int fn11
)
843 /* ??? This is wrong: the instruction is not a nop, it still may
845 if (unlikely(rc
== 31)) {
849 /* No need to set flushzero, since we have an integer output. */
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. */
857 gen_helper_cvttq_c(cpu_fir
[rc
], cpu_env
, vb
);
859 case QUAL_V
| QUAL_RM_C
:
860 case QUAL_S
| QUAL_V
| QUAL_RM_C
:
861 ignore
= float_flag_inexact
;
863 case QUAL_S
| QUAL_V
| QUAL_I
| QUAL_RM_C
:
864 gen_helper_cvttq_svic(cpu_fir
[rc
], cpu_env
, vb
);
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
);
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
)
884 /* ??? This is wrong: the instruction is not a nop, it still may
886 if (unlikely(rc
== 31)) {
890 gen_qual_roundmode(ctx
, fn11
);
893 vb
= tcg_const_i64(0);
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. */
903 helper(cpu_fir
[rc
], cpu_env
, vb
);
904 gen_fp_exc_raise(rc
, fn11
);
906 helper(cpu_fir
[rc
], cpu_env
, 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); \
923 static void gen_cpys_internal(int ra
, int rb
, int rc
, int inv_a
, uint64_t mask
)
928 if (unlikely(rc
== 31)) {
932 vmask
= tcg_const_i64(mask
);
942 va
= tcg_temp_new_i64();
943 tcg_gen_mov_i64(va
, cpu_fir
[ra
]);
945 tcg_gen_andc_i64(va
, vmask
, va
);
947 tcg_gen_and_i64(va
, va
, vmask
);
955 vb
= tcg_temp_new_i64();
956 tcg_gen_andc_i64(vb
, cpu_fir
[rb
], vmask
);
959 switch (za
<< 1 | zb
) {
961 tcg_gen_or_i64(cpu_fir
[rc
], va
, vb
);
964 tcg_gen_mov_i64(cpu_fir
[rc
], va
);
967 tcg_gen_mov_i64(cpu_fir
[rc
], vb
);
970 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
974 tcg_temp_free(vmask
);
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) \
1003 if (unlikely(rc == 31)) { \
1007 va = tcg_const_i64(0); \
1012 vb = tcg_const_i64(0); \
1017 gen_helper_ ## name(cpu_fir[rc], cpu_env, va, vb); \
1020 tcg_temp_free(va); \
1023 tcg_temp_free(vb); \
1027 /* ??? VAX instruction qualifiers ignored. */
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
)
1046 /* ??? This is wrong: the instruction is not a nop, it still may
1047 raise exceptions. */
1048 if (unlikely(rc
== 31)) {
1052 gen_qual_roundmode(ctx
, fn11
);
1053 gen_qual_flushzero(ctx
, fn11
);
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
);
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); \
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
)
1086 /* ??? This is wrong: the instruction is not a nop, it still may
1087 raise exceptions. */
1088 if (unlikely(rc
== 31)) {
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
);
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); \
1114 static inline uint64_t zapnot_mask(uint8_t lit
)
1119 for (i
= 0; i
< 8; ++i
) {
1121 mask
|= 0xffull
<< (i
* 8);
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
)
1133 tcg_gen_movi_i64(dest
, 0);
1136 tcg_gen_ext8u_i64(dest
, src
);
1139 tcg_gen_ext16u_i64(dest
, src
);
1142 tcg_gen_ext32u_i64(dest
, src
);
1145 tcg_gen_mov_i64(dest
, src
);
1148 tcg_gen_andi_i64 (dest
, src
, zapnot_mask (lit
));
1153 static inline void gen_zapnot(int ra
, int rb
, int rc
, int islit
, uint8_t lit
)
1155 if (unlikely(rc
== 31))
1157 else if (unlikely(ra
== 31))
1158 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1160 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
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))
1169 else if (unlikely(ra
== 31))
1170 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1172 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
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))
1184 else if (unlikely(ra
== 31))
1185 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1188 lit
= (64 - (lit
& 7) * 8) & 0x3f;
1189 tcg_gen_shli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
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))
1209 else if (unlikely(ra
== 31))
1210 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1213 tcg_gen_shri_i64(cpu_ir
[rc
], cpu_ir
[ra
], (lit
& 7) * 8);
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
);
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))
1231 else if (unlikely(ra
== 31) || (islit
&& (lit
& 7) == 0))
1232 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
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
1240 gen_zapnoti (tmp
, cpu_ir
[ra
], byte_mask
);
1243 /* Note that we have handled the lit==0 case above. */
1244 tcg_gen_shri_i64 (cpu_ir
[rc
], tmp
, 64 - (lit
& 7) * 8);
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
);
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))
1273 else if (unlikely(ra
== 31))
1274 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
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
);
1285 tcg_gen_shli_i64(cpu_ir
[rc
], tmp
, (lit
& 7) * 8);
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
);
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))
1303 else if (unlikely(ra
== 31))
1304 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1306 gen_zapnoti (cpu_ir
[rc
], cpu_ir
[ra
], ~((byte_mask
<< (lit
& 7)) >> 8));
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))
1341 else if (unlikely(ra
== 31))
1342 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1344 gen_zapnoti (cpu_ir
[rc
], cpu_ir
[ra
], ~(byte_mask
<< (lit
& 7)));
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,\
1366 if (unlikely(rc == 31)) \
1371 TCGv tmp = tcg_const_i64(lit); \
1372 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
1373 tcg_temp_free(tmp); \
1375 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1377 TCGv tmp1 = tcg_const_i64(0); \
1379 TCGv tmp2 = tcg_const_i64(lit); \
1380 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
1381 tcg_temp_free(tmp2); \
1383 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
1384 tcg_temp_free(tmp1); \
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)) { \
1408 TCGv tmp = tcg_const_i64(lit); \
1409 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1411 tcg_temp_free(tmp); \
1413 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1414 cpu_ir[ra], cpu_ir[rb]); \
1417 TCGv tmp1 = tcg_const_i64(0); \
1419 TCGv tmp2 = tcg_const_i64(lit); \
1420 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2); \
1421 tcg_temp_free(tmp2); \
1423 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
1425 tcg_temp_free(tmp1); \
1435 #define MVIOP2(name) \
1436 static inline void glue(gen_, name)(int rb, int rc) \
1438 if (unlikely(rc == 31)) \
1440 if (unlikely(rb == 31)) \
1441 tcg_gen_movi_i64(cpu_ir[rc], 0); \
1443 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
1450 static void gen_cmp(TCGCond cond
, int ra
, int rb
, int rc
,
1451 int islit
, uint8_t lit
)
1455 if (unlikely(rc
== 31)) {
1460 va
= tcg_const_i64(0);
1465 vb
= tcg_const_i64(lit
);
1470 tcg_gen_setcond_i64(cond
, cpu_ir
[rc
], va
, vb
);
1480 static void gen_rx(int ra
, int set
)
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) {
1503 /* No-op inside QEMU. */
1507 tcg_gen_mov_i64(cpu_ir
[IR_V0
], cpu_unique
);
1511 tcg_gen_mov_i64(cpu_unique
, cpu_ir
[IR_A0
]);
1520 #ifndef CONFIG_USER_ONLY
1521 /* Privileged PAL code */
1522 if (palcode
< 0x40 && (ctx
->tb
->flags
& TB_FLAGS_USER_MODE
) == 0) {
1526 /* No-op inside QEMU. */
1530 /* No-op inside QEMU. */
1534 tcg_gen_st_i64(cpu_ir
[IR_A0
], cpu_env
, offsetof(CPUAlphaState
, vptptr
));
1538 tcg_gen_mov_i64(cpu_sysval
, cpu_ir
[IR_A0
]);
1542 tcg_gen_mov_i64(cpu_ir
[IR_V0
], cpu_sysval
);
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
));
1563 tcg_gen_ld8u_i64(cpu_ir
[IR_V0
], cpu_env
, offsetof(CPUAlphaState
, ps
));
1567 tcg_gen_mov_i64(cpu_usp
, cpu_ir
[IR_A0
]);
1571 tcg_gen_mov_i64(cpu_ir
[IR_V0
], cpu_usp
);
1575 tcg_gen_ld32s_i64(cpu_ir
[IR_V0
], cpu_env
,
1576 -offsetof(AlphaCPU
, env
) + offsetof(CPUState
, cpu_index
));
1586 return gen_invalid(ctx
);
1589 #ifdef CONFIG_USER_ONLY
1590 return gen_excp(ctx
, EXCP_CALL_PAL
, palcode
);
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
);
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
)) {
1609 tcg_gen_exit_tb((uintptr_t)ctx
->tb
);
1610 return EXIT_GOTO_TB
;
1613 return EXIT_PC_UPDATED
;
1618 #ifndef CONFIG_USER_ONLY
1620 #define PR_BYTE 0x100000
1621 #define PR_LONG 0x200000
1623 static int cpu_pr_data(int 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
);
1641 return offsetof(CPUAlphaState
, shadow
[pr
- 32]);
1643 return offsetof(CPUAlphaState
, scratch
[pr
- 40]);
1646 return offsetof(CPUAlphaState
, alarm_expire
);
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. */
1661 /* Special help for VMTIME and WALLTIME. */
1662 if (regno
== 250 || regno
== 249) {
1663 void (*helper
)(TCGv
) = gen_helper_get_walltime
;
1665 helper
= gen_helper_get_vmtime
;
1671 return EXIT_PC_STALE
;
1678 /* The basic registers are data only, and unknown registers
1679 are read-zero, write-ignore. */
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
);
1687 tcg_gen_ld_i64(cpu_ir
[ra
], cpu_env
, data
);
1692 static ExitStatus
gen_mtpr(DisasContext
*ctx
, int rb
, int regno
)
1698 tmp
= tcg_const_i64(0);
1706 gen_helper_tbia(cpu_env
);
1711 gen_helper_tbis(cpu_env
, tmp
);
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);
1723 gen_helper_halt(tmp
);
1724 return EXIT_PC_STALE
;
1728 gen_helper_set_alarm(cpu_env
, tmp
);
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
;
1741 /* The basic registers are data only, and unknown registers
1742 are read-zero, write-ignore. */
1743 data
= cpu_pr_data(regno
);
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
);
1750 tcg_gen_st_i64(tmp
, cpu_env
, data
);
1762 #endif /* !USER_ONLY*/
1764 static ExitStatus
translate_one(DisasContext
*ctx
, uint32_t insn
)
1767 int32_t disp21
, disp16
;
1768 #ifndef CONFIG_USER_ONLY
1772 uint8_t opc
, ra
, rb
, rc
, fpfn
, fn7
, islit
, real_islit
;
1776 /* Decode all instruction fields */
1778 ra
= (insn
>> 21) & 0x1F;
1779 rb
= (insn
>> 16) & 0x1F;
1781 real_islit
= islit
= (insn
>> 12) & 1;
1782 if (rb
== 31 && !islit
) {
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;
1793 fn11
= (insn
>> 5) & 0x000007FF;
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
);
1803 ret
= gen_call_pal(ctx
, palcode
);
1828 if (likely(ra
!= 31)) {
1830 tcg_gen_addi_i64(cpu_ir
[ra
], cpu_ir
[rb
], disp16
);
1832 tcg_gen_movi_i64(cpu_ir
[ra
], disp16
);
1837 if (likely(ra
!= 31)) {
1839 tcg_gen_addi_i64(cpu_ir
[ra
], cpu_ir
[rb
], disp16
<< 16);
1841 tcg_gen_movi_i64(cpu_ir
[ra
], disp16
<< 16);
1846 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_BWX
) {
1847 gen_load_mem(ctx
, &tcg_gen_qemu_ld8u
, ra
, rb
, disp16
, 0, 0);
1853 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 0, 1);
1857 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_BWX
) {
1858 gen_load_mem(ctx
, &tcg_gen_qemu_ld16u
, ra
, rb
, disp16
, 0, 0);
1864 gen_store_mem(ctx
, &tcg_gen_qemu_st16
, ra
, rb
, disp16
, 0, 0);
1868 gen_store_mem(ctx
, &tcg_gen_qemu_st8
, ra
, rb
, disp16
, 0, 0);
1872 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 0, 1);
1878 if (likely(rc
!= 31)) {
1881 tcg_gen_addi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1882 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
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
]);
1889 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1891 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1897 if (likely(rc
!= 31)) {
1899 TCGv tmp
= tcg_temp_new();
1900 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1902 tcg_gen_addi_i64(tmp
, tmp
, lit
);
1904 tcg_gen_add_i64(tmp
, tmp
, cpu_ir
[rb
]);
1905 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1909 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1911 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1917 if (likely(rc
!= 31)) {
1920 tcg_gen_subi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
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
]);
1926 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1928 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1929 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1935 if (likely(rc
!= 31)) {
1937 TCGv tmp
= tcg_temp_new();
1938 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1940 tcg_gen_subi_i64(tmp
, tmp
, lit
);
1942 tcg_gen_sub_i64(tmp
, tmp
, cpu_ir
[rb
]);
1943 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1947 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1949 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1950 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1957 gen_cmpbge(ra
, rb
, rc
, islit
, lit
);
1961 if (likely(rc
!= 31)) {
1963 TCGv tmp
= tcg_temp_new();
1964 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1966 tcg_gen_addi_i64(tmp
, tmp
, lit
);
1968 tcg_gen_add_i64(tmp
, tmp
, cpu_ir
[rb
]);
1969 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1973 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1975 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1981 if (likely(rc
!= 31)) {
1983 TCGv tmp
= tcg_temp_new();
1984 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1986 tcg_gen_subi_i64(tmp
, tmp
, lit
);
1988 tcg_gen_sub_i64(tmp
, tmp
, cpu_ir
[rb
]);
1989 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1993 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1995 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1996 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
2003 gen_cmp(TCG_COND_LTU
, ra
, rb
, rc
, islit
, lit
);
2007 if (likely(rc
!= 31)) {
2010 tcg_gen_addi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2012 tcg_gen_add_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2015 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
2017 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2023 if (likely(rc
!= 31)) {
2025 TCGv tmp
= tcg_temp_new();
2026 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
2028 tcg_gen_addi_i64(cpu_ir
[rc
], tmp
, lit
);
2030 tcg_gen_add_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
2034 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
2036 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2042 if (likely(rc
!= 31)) {
2045 tcg_gen_subi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2047 tcg_gen_sub_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2050 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
2052 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2058 if (likely(rc
!= 31)) {
2060 TCGv tmp
= tcg_temp_new();
2061 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
2063 tcg_gen_subi_i64(cpu_ir
[rc
], tmp
, lit
);
2065 tcg_gen_sub_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
2069 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
2071 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2077 gen_cmp(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
);
2081 if (likely(rc
!= 31)) {
2083 TCGv tmp
= tcg_temp_new();
2084 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
2086 tcg_gen_addi_i64(cpu_ir
[rc
], tmp
, lit
);
2088 tcg_gen_add_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
2092 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
2094 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2100 if (likely(rc
!= 31)) {
2102 TCGv tmp
= tcg_temp_new();
2103 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
2105 tcg_gen_subi_i64(cpu_ir
[rc
], tmp
, lit
);
2107 tcg_gen_sub_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
2111 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
2113 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2119 gen_cmp(TCG_COND_LEU
, ra
, rb
, rc
, islit
, lit
);
2123 gen_addlv(ra
, rb
, rc
, islit
, lit
);
2127 gen_sublv(ra
, rb
, rc
, islit
, lit
);
2131 gen_cmp(TCG_COND_LT
, ra
, rb
, rc
, islit
, lit
);
2135 gen_addqv(ra
, rb
, rc
, islit
, lit
);
2139 gen_subqv(ra
, rb
, rc
, islit
, lit
);
2143 gen_cmp(TCG_COND_LE
, ra
, rb
, rc
, islit
, lit
);
2153 if (likely(rc
!= 31)) {
2155 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2157 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2159 tcg_gen_and_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2164 if (likely(rc
!= 31)) {
2167 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
2169 tcg_gen_andc_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2171 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2176 gen_cmov(TCG_COND_NE
, ra
, rb
, rc
, islit
, lit
, 1);
2180 gen_cmov(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
, 1);
2184 if (likely(rc
!= 31)) {
2187 tcg_gen_ori_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2189 tcg_gen_or_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2192 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
2194 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2200 gen_cmov(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
, 0);
2204 gen_cmov(TCG_COND_NE
, ra
, rb
, rc
, islit
, lit
, 0);
2208 if (likely(rc
!= 31)) {
2211 tcg_gen_ori_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
2213 tcg_gen_orc_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2216 tcg_gen_movi_i64(cpu_ir
[rc
], ~lit
);
2218 tcg_gen_not_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2224 if (likely(rc
!= 31)) {
2227 tcg_gen_xori_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2229 tcg_gen_xor_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2232 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
2234 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2240 gen_cmov(TCG_COND_LT
, ra
, rb
, rc
, islit
, lit
, 0);
2244 gen_cmov(TCG_COND_GE
, ra
, rb
, rc
, islit
, lit
, 0);
2248 if (likely(rc
!= 31)) {
2251 tcg_gen_xori_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
2253 tcg_gen_eqv_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2256 tcg_gen_movi_i64(cpu_ir
[rc
], ~lit
);
2258 tcg_gen_not_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2264 if (likely(rc
!= 31)) {
2265 uint64_t amask
= ctx
->tb
->flags
>> TB_FLAGS_AMASK_SHIFT
;
2268 tcg_gen_movi_i64(cpu_ir
[rc
], lit
& ~amask
);
2270 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[rb
], ~amask
);
2276 gen_cmov(TCG_COND_LE
, ra
, rb
, rc
, islit
, lit
, 0);
2280 gen_cmov(TCG_COND_GT
, ra
, rb
, rc
, islit
, lit
, 0);
2285 tcg_gen_movi_i64(cpu_ir
[rc
], ctx
->implver
);
2296 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x01);
2300 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x01);
2304 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x01);
2308 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x03);
2312 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x03);
2316 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x03);
2320 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
2324 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
2328 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
2332 gen_zap(ra
, rb
, rc
, islit
, lit
);
2336 gen_zapnot(ra
, rb
, rc
, islit
, lit
);
2340 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0xff);
2344 if (likely(rc
!= 31)) {
2347 tcg_gen_shri_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
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
);
2355 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2360 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0xff);
2364 if (likely(rc
!= 31)) {
2367 tcg_gen_shli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
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
);
2375 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2380 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0xff);
2384 if (likely(rc
!= 31)) {
2387 tcg_gen_sari_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
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
);
2395 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2400 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0x03);
2404 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0x03);
2408 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0x03);
2412 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
2416 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
2420 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
2424 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0xff);
2428 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0xff);
2432 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0xff);
2442 if (likely(rc
!= 31)) {
2444 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2447 tcg_gen_muli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
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
]);
2456 if (likely(rc
!= 31)) {
2458 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2460 tcg_gen_muli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
2462 tcg_gen_mul_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2469 if (unlikely(rc
== 31)){
2473 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2476 low
= tcg_temp_new();
2478 tcg_gen_movi_tl(low
, lit
);
2479 tcg_gen_mulu2_i64(low
, cpu_ir
[rc
], cpu_ir
[ra
], low
);
2481 tcg_gen_mulu2_i64(low
, cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
2488 gen_mullv(ra
, rb
, rc
, islit
, lit
);
2492 gen_mulqv(ra
, rb
, rc
, islit
, lit
);
2499 switch (fpfn
) { /* fn11 & 0x3F */
2502 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) == 0) {
2505 if (likely(rc
!= 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
);
2512 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2517 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) {
2524 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) {
2525 gen_fsqrts(ctx
, rb
, rc
, fn11
);
2531 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) == 0) {
2534 if (likely(rc
!= 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
);
2541 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2546 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) == 0) {
2549 if (likely(rc
!= 31)) {
2551 tcg_gen_mov_i64(cpu_fir
[rc
], cpu_ir
[ra
]);
2553 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2558 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) {
2565 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) {
2566 gen_fsqrtt(ctx
, rb
, rc
, fn11
);
2575 /* VAX floating point */
2576 /* XXX: rounding mode and trap are ignored (!) */
2577 switch (fpfn
) { /* fn11 & 0x3F */
2580 gen_faddf(ra
, rb
, rc
);
2584 gen_fsubf(ra
, rb
, rc
);
2588 gen_fmulf(ra
, rb
, rc
);
2592 gen_fdivf(ra
, rb
, rc
);
2604 gen_faddg(ra
, rb
, rc
);
2608 gen_fsubg(ra
, rb
, rc
);
2612 gen_fmulg(ra
, rb
, rc
);
2616 gen_fdivg(ra
, rb
, rc
);
2620 gen_fcmpgeq(ra
, rb
, rc
);
2624 gen_fcmpglt(ra
, rb
, rc
);
2628 gen_fcmpgle(ra
, rb
, rc
);
2659 /* IEEE floating-point */
2660 switch (fpfn
) { /* fn11 & 0x3F */
2663 gen_fadds(ctx
, ra
, rb
, rc
, fn11
);
2667 gen_fsubs(ctx
, ra
, rb
, rc
, fn11
);
2671 gen_fmuls(ctx
, ra
, rb
, rc
, fn11
);
2675 gen_fdivs(ctx
, ra
, rb
, rc
, fn11
);
2679 gen_faddt(ctx
, ra
, rb
, rc
, fn11
);
2683 gen_fsubt(ctx
, ra
, rb
, rc
, fn11
);
2687 gen_fmult(ctx
, ra
, rb
, rc
, fn11
);
2691 gen_fdivt(ctx
, ra
, rb
, rc
, fn11
);
2695 gen_fcmptun(ctx
, ra
, rb
, rc
, fn11
);
2699 gen_fcmpteq(ctx
, ra
, rb
, rc
, fn11
);
2703 gen_fcmptlt(ctx
, ra
, rb
, rc
, fn11
);
2707 gen_fcmptle(ctx
, ra
, rb
, rc
, fn11
);
2710 if (fn11
== 0x2AC || fn11
== 0x6AC) {
2712 gen_fcvtst(ctx
, rb
, rc
, fn11
);
2715 gen_fcvtts(ctx
, rb
, rc
, fn11
);
2720 gen_fcvttq(ctx
, rb
, rc
, fn11
);
2724 gen_fcvtqs(ctx
, rb
, rc
, fn11
);
2728 gen_fcvtqt(ctx
, rb
, rc
, fn11
);
2741 if (likely(rc
!= 31)) {
2745 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2747 tcg_gen_mov_i64(cpu_fir
[rc
], cpu_fir
[ra
]);
2750 gen_fcpys(ra
, rb
, rc
);
2756 gen_fcpysn(ra
, rb
, rc
);
2760 gen_fcpyse(ra
, rb
, rc
);
2764 if (likely(ra
!= 31))
2765 gen_helper_store_fpcr(cpu_env
, cpu_fir
[ra
]);
2767 TCGv tmp
= tcg_const_i64(0);
2768 gen_helper_store_fpcr(cpu_env
, tmp
);
2774 if (likely(ra
!= 31))
2775 gen_helper_load_fpcr(cpu_fir
[ra
], cpu_env
);
2779 gen_fcmov(TCG_COND_EQ
, ra
, rb
, rc
);
2783 gen_fcmov(TCG_COND_NE
, ra
, rb
, rc
);
2787 gen_fcmov(TCG_COND_LT
, ra
, rb
, rc
);
2791 gen_fcmov(TCG_COND_GE
, ra
, rb
, rc
);
2795 gen_fcmov(TCG_COND_LE
, ra
, rb
, rc
);
2799 gen_fcmov(TCG_COND_GT
, ra
, rb
, rc
);
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
);
2819 switch ((uint16_t)disp16
) {
2849 gen_helper_load_pcc(cpu_ir
[ra
], cpu_env
);
2851 ret
= EXIT_PC_STALE
;
2853 gen_helper_load_pcc(cpu_ir
[ra
], cpu_env
);
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);
2885 /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch
2886 prediction stack action, which of course we don't implement. */
2888 tcg_gen_andi_i64(cpu_pc
, cpu_ir
[rb
], ~3);
2890 tcg_gen_movi_i64(cpu_pc
, 0);
2893 tcg_gen_movi_i64(cpu_ir
[ra
], ctx
->pc
);
2895 ret
= EXIT_PC_UPDATED
;
2898 /* HW_LD (PALcode) */
2899 #ifndef CONFIG_USER_ONLY
2900 if (ctx
->tb
->flags
& TB_FLAGS_PAL_MODE
) {
2907 addr
= tcg_temp_new();
2909 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp12
);
2911 tcg_gen_movi_i64(addr
, disp12
);
2912 switch ((insn
>> 12) & 0xF) {
2914 /* Longword physical access (hw_ldl/p) */
2915 gen_helper_ldl_phys(cpu_ir
[ra
], cpu_env
, addr
);
2918 /* Quadword physical access (hw_ldq/p) */
2919 gen_helper_ldq_phys(cpu_ir
[ra
], cpu_env
, addr
);
2922 /* Longword physical access with lock (hw_ldl_l/p) */
2923 gen_helper_ldl_l_phys(cpu_ir
[ra
], cpu_env
, addr
);
2926 /* Quadword physical access with lock (hw_ldq_l/p) */
2927 gen_helper_ldq_l_phys(cpu_ir
[ra
], cpu_env
, addr
);
2930 /* Longword virtual PTE fetch (hw_ldl/v) */
2933 /* Quadword virtual PTE fetch (hw_ldq/v) */
2937 /* Incpu_ir[ra]id */
2940 /* Incpu_ir[ra]id */
2943 /* Longword virtual access (hw_ldl) */
2946 /* Quadword virtual access (hw_ldq) */
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
);
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
);
2957 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2960 /* Quadword virtual access with alt access mode (hw_ldq/a) */
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
);
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
);
2973 tcg_temp_free(addr
);
2982 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_BWX
) == 0) {
2985 if (likely(rc
!= 31)) {
2987 tcg_gen_movi_i64(cpu_ir
[rc
], (int64_t)((int8_t)lit
));
2989 tcg_gen_ext8s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2994 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_BWX
) {
2995 if (likely(rc
!= 31)) {
2997 tcg_gen_movi_i64(cpu_ir
[rc
], (int64_t)((int16_t)lit
));
2999 tcg_gen_ext16s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
3007 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_CIX
) {
3008 if (likely(rc
!= 31)) {
3010 tcg_gen_movi_i64(cpu_ir
[rc
], ctpop64(lit
));
3012 gen_helper_ctpop(cpu_ir
[rc
], cpu_ir
[rb
]);
3020 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3021 gen_perr(ra
, rb
, rc
, islit
, lit
);
3027 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_CIX
) {
3028 if (likely(rc
!= 31)) {
3030 tcg_gen_movi_i64(cpu_ir
[rc
], clz64(lit
));
3032 gen_helper_ctlz(cpu_ir
[rc
], cpu_ir
[rb
]);
3040 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_CIX
) {
3041 if (likely(rc
!= 31)) {
3043 tcg_gen_movi_i64(cpu_ir
[rc
], ctz64(lit
));
3045 gen_helper_cttz(cpu_ir
[rc
], cpu_ir
[rb
]);
3053 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3054 if (real_islit
|| ra
!= 31) {
3063 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3064 if (real_islit
|| ra
!= 31) {
3073 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3074 if (real_islit
|| ra
!= 31) {
3083 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3084 if (real_islit
|| ra
!= 31) {
3093 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3094 gen_minsb8(ra
, rb
, rc
, islit
, lit
);
3100 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3101 gen_minsw4(ra
, rb
, rc
, islit
, lit
);
3107 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3108 gen_minub8(ra
, rb
, rc
, islit
, lit
);
3114 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3115 gen_minuw4(ra
, rb
, rc
, islit
, lit
);
3121 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3122 gen_maxub8(ra
, rb
, rc
, islit
, lit
);
3128 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3129 gen_maxuw4(ra
, rb
, rc
, islit
, lit
);
3135 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3136 gen_maxsb8(ra
, rb
, rc
, islit
, lit
);
3142 if (ctx
->tb
->flags
& TB_FLAGS_AMASK_MVI
) {
3143 gen_maxsw4(ra
, rb
, rc
, islit
, lit
);
3149 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) == 0) {
3152 if (likely(rc
!= 31)) {
3154 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_fir
[ra
]);
3156 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
3161 if ((ctx
->tb
->flags
& TB_FLAGS_AMASK_FIX
) == 0) {
3165 TCGv_i32 tmp1
= tcg_temp_new_i32();
3167 gen_helper_s_to_memory(tmp1
, cpu_fir
[ra
]);
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
);
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);
3190 /* HW_RET (PALcode) */
3191 #ifndef CONFIG_USER_ONLY
3192 if (ctx
->tb
->flags
& TB_FLAGS_PAL_MODE
) {
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
);
3202 gen_helper_hw_ret(cpu_env
, cpu_ir
[rb
]);
3204 ret
= EXIT_PC_UPDATED
;
3210 /* HW_ST (PALcode) */
3211 #ifndef CONFIG_USER_ONLY
3212 if (ctx
->tb
->flags
& TB_FLAGS_PAL_MODE
) {
3214 addr
= tcg_temp_new();
3216 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp12
);
3218 tcg_gen_movi_i64(addr
, disp12
);
3222 val
= tcg_temp_new();
3223 tcg_gen_movi_i64(val
, 0);
3225 switch ((insn
>> 12) & 0xF) {
3227 /* Longword physical access */
3228 gen_helper_stl_phys(cpu_env
, addr
, val
);
3231 /* Quadword physical access */
3232 gen_helper_stq_phys(cpu_env
, addr
, val
);
3235 /* Longword physical access with lock */
3236 gen_helper_stl_c_phys(val
, cpu_env
, addr
, val
);
3239 /* Quadword physical access with lock */
3240 gen_helper_stq_c_phys(val
, cpu_env
, addr
, val
);
3243 /* Longword virtual access */
3246 /* Quadword virtual access */
3267 /* Longword virtual access with alternate access mode */
3270 /* Quadword virtual access with alternate access mode */
3281 tcg_temp_free(addr
);
3288 gen_load_mem(ctx
, &gen_qemu_ldf
, ra
, rb
, disp16
, 1, 0);
3292 gen_load_mem(ctx
, &gen_qemu_ldg
, ra
, rb
, disp16
, 1, 0);
3296 gen_load_mem(ctx
, &gen_qemu_lds
, ra
, rb
, disp16
, 1, 0);
3300 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 1, 0);
3304 gen_store_mem(ctx
, &gen_qemu_stf
, ra
, rb
, disp16
, 1, 0);
3308 gen_store_mem(ctx
, &gen_qemu_stg
, ra
, rb
, disp16
, 1, 0);
3312 gen_store_mem(ctx
, &gen_qemu_sts
, ra
, rb
, disp16
, 1, 0);
3316 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 1, 0);
3320 gen_load_mem(ctx
, &tcg_gen_qemu_ld32s
, ra
, rb
, disp16
, 0, 0);
3324 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 0, 0);
3328 gen_load_mem(ctx
, &gen_qemu_ldl_l
, ra
, rb
, disp16
, 0, 0);
3332 gen_load_mem(ctx
, &gen_qemu_ldq_l
, ra
, rb
, disp16
, 0, 0);
3336 gen_store_mem(ctx
, &tcg_gen_qemu_st32
, ra
, rb
, disp16
, 0, 0);
3340 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 0, 0);
3344 ret
= gen_store_conditional(ctx
, ra
, rb
, disp16
, 0);
3348 ret
= gen_store_conditional(ctx
, ra
, rb
, disp16
, 1);
3352 ret
= gen_bdirect(ctx
, ra
, disp21
);
3354 case 0x31: /* FBEQ */
3355 ret
= gen_fbcond(ctx
, TCG_COND_EQ
, ra
, disp21
);
3357 case 0x32: /* FBLT */
3358 ret
= gen_fbcond(ctx
, TCG_COND_LT
, ra
, disp21
);
3360 case 0x33: /* FBLE */
3361 ret
= gen_fbcond(ctx
, TCG_COND_LE
, ra
, disp21
);
3365 ret
= gen_bdirect(ctx
, ra
, disp21
);
3367 case 0x35: /* FBNE */
3368 ret
= gen_fbcond(ctx
, TCG_COND_NE
, ra
, disp21
);
3370 case 0x36: /* FBGE */
3371 ret
= gen_fbcond(ctx
, TCG_COND_GE
, ra
, disp21
);
3373 case 0x37: /* FBGT */
3374 ret
= gen_fbcond(ctx
, TCG_COND_GT
, ra
, disp21
);
3378 ret
= gen_bcond(ctx
, TCG_COND_EQ
, ra
, disp21
, 1);
3382 ret
= gen_bcond(ctx
, TCG_COND_EQ
, ra
, disp21
, 0);
3386 ret
= gen_bcond(ctx
, TCG_COND_LT
, ra
, disp21
, 0);
3390 ret
= gen_bcond(ctx
, TCG_COND_LE
, ra
, disp21
, 0);
3394 ret
= gen_bcond(ctx
, TCG_COND_NE
, ra
, disp21
, 1);
3398 ret
= gen_bcond(ctx
, TCG_COND_NE
, ra
, disp21
, 0);
3402 ret
= gen_bcond(ctx
, TCG_COND_GE
, ra
, disp21
, 0);
3406 ret
= gen_bcond(ctx
, TCG_COND_GT
, ra
, disp21
, 0);
3409 ret
= gen_invalid(ctx
);
3416 static inline void gen_intermediate_code_internal(AlphaCPU
*cpu
,
3417 TranslationBlock
*tb
,
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
;
3426 uint16_t *gen_opc_end
;
3434 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
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. */
3449 /* Similarly for flush-to-zero. */
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;
3461 pc_mask
= ~TARGET_PAGE_MASK
;
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);
3475 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
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
))
3487 insn
= cpu_ldl_code(env
, ctx
.pc
);
3490 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
3491 tcg_gen_debug_insn_start(ctx
.pc
);
3495 ret
= translate_one(ctxp
, insn
);
3497 /* If we reach a page boundary, are single stepping,
3498 or exhaust instruction count, stop generation. */
3500 && ((ctx
.pc
& pc_mask
) == 0
3501 || tcg_ctx
.gen_opc_ptr
>= gen_opc_end
3502 || num_insns
>= max_insns
3504 || ctx
.singlestep_enabled
)) {
3505 ret
= EXIT_PC_STALE
;
3507 } while (ret
== NO_EXIT
);
3509 if (tb
->cflags
& CF_LAST_IO
) {
3518 tcg_gen_movi_i64(cpu_pc
, ctx
.pc
);
3520 case EXIT_PC_UPDATED
:
3521 if (ctx
.singlestep_enabled
) {
3522 gen_excp_1(EXCP_DEBUG
, 0);
3531 gen_tb_end(tb
, num_insns
);
3532 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
3534 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
3537 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
3539 tb
->size
= ctx
.pc
- pc_start
;
3540 tb
->icount
= num_insns
;
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);
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
];