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/>.
27 #include "host-utils.h"
29 #include "qemu-common.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
;
48 #if !defined (CONFIG_USER_ONLY)
54 /* Current rounding mode for this TB. */
56 /* Current flush-to-zero setting for this TB. */
60 /* global register indexes */
61 static TCGv_ptr cpu_env
;
62 static TCGv cpu_ir
[31];
63 static TCGv cpu_fir
[31];
66 #ifdef CONFIG_USER_ONLY
71 static char cpu_reg_names
[10*4+21*5 + 10*5+21*6];
73 #include "gen-icount.h"
75 static void alpha_translate_init(void)
79 static int done_init
= 0;
84 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
87 for (i
= 0; i
< 31; i
++) {
88 sprintf(p
, "ir%d", i
);
89 cpu_ir
[i
] = tcg_global_mem_new_i64(TCG_AREG0
,
90 offsetof(CPUState
, ir
[i
]), p
);
91 p
+= (i
< 10) ? 4 : 5;
93 sprintf(p
, "fir%d", i
);
94 cpu_fir
[i
] = tcg_global_mem_new_i64(TCG_AREG0
,
95 offsetof(CPUState
, fir
[i
]), p
);
96 p
+= (i
< 10) ? 5 : 6;
99 cpu_pc
= tcg_global_mem_new_i64(TCG_AREG0
,
100 offsetof(CPUState
, pc
), "pc");
102 cpu_lock
= tcg_global_mem_new_i64(TCG_AREG0
,
103 offsetof(CPUState
, lock
), "lock");
105 #ifdef CONFIG_USER_ONLY
106 cpu_uniq
= tcg_global_mem_new_i64(TCG_AREG0
,
107 offsetof(CPUState
, unique
), "uniq");
110 /* register helpers */
117 static inline void gen_excp(DisasContext
*ctx
, int exception
, int error_code
)
121 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
);
122 tmp1
= tcg_const_i32(exception
);
123 tmp2
= tcg_const_i32(error_code
);
124 gen_helper_excp(tmp1
, tmp2
);
125 tcg_temp_free_i32(tmp2
);
126 tcg_temp_free_i32(tmp1
);
129 static inline void gen_invalid(DisasContext
*ctx
)
131 gen_excp(ctx
, EXCP_OPCDEC
, 0);
134 static inline void gen_qemu_ldf(TCGv t0
, TCGv t1
, int flags
)
136 TCGv tmp
= tcg_temp_new();
137 TCGv_i32 tmp32
= tcg_temp_new_i32();
138 tcg_gen_qemu_ld32u(tmp
, t1
, flags
);
139 tcg_gen_trunc_i64_i32(tmp32
, tmp
);
140 gen_helper_memory_to_f(t0
, tmp32
);
141 tcg_temp_free_i32(tmp32
);
145 static inline void gen_qemu_ldg(TCGv t0
, TCGv t1
, int flags
)
147 TCGv tmp
= tcg_temp_new();
148 tcg_gen_qemu_ld64(tmp
, t1
, flags
);
149 gen_helper_memory_to_g(t0
, tmp
);
153 static inline void gen_qemu_lds(TCGv t0
, TCGv t1
, int flags
)
155 TCGv tmp
= tcg_temp_new();
156 TCGv_i32 tmp32
= tcg_temp_new_i32();
157 tcg_gen_qemu_ld32u(tmp
, t1
, flags
);
158 tcg_gen_trunc_i64_i32(tmp32
, tmp
);
159 gen_helper_memory_to_s(t0
, tmp32
);
160 tcg_temp_free_i32(tmp32
);
164 static inline void gen_qemu_ldl_l(TCGv t0
, TCGv t1
, int flags
)
166 tcg_gen_mov_i64(cpu_lock
, t1
);
167 tcg_gen_qemu_ld32s(t0
, t1
, flags
);
170 static inline void gen_qemu_ldq_l(TCGv t0
, TCGv t1
, int flags
)
172 tcg_gen_mov_i64(cpu_lock
, t1
);
173 tcg_gen_qemu_ld64(t0
, t1
, flags
);
176 static inline void gen_load_mem(DisasContext
*ctx
,
177 void (*tcg_gen_qemu_load
)(TCGv t0
, TCGv t1
,
179 int ra
, int rb
, int32_t disp16
, int fp
,
184 if (unlikely(ra
== 31))
187 addr
= tcg_temp_new();
189 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp16
);
191 tcg_gen_andi_i64(addr
, addr
, ~0x7);
195 tcg_gen_movi_i64(addr
, disp16
);
198 tcg_gen_qemu_load(cpu_fir
[ra
], addr
, ctx
->mem_idx
);
200 tcg_gen_qemu_load(cpu_ir
[ra
], addr
, ctx
->mem_idx
);
204 static inline void gen_qemu_stf(TCGv t0
, TCGv t1
, int flags
)
206 TCGv_i32 tmp32
= tcg_temp_new_i32();
207 TCGv tmp
= tcg_temp_new();
208 gen_helper_f_to_memory(tmp32
, t0
);
209 tcg_gen_extu_i32_i64(tmp
, tmp32
);
210 tcg_gen_qemu_st32(tmp
, t1
, flags
);
212 tcg_temp_free_i32(tmp32
);
215 static inline void gen_qemu_stg(TCGv t0
, TCGv t1
, int flags
)
217 TCGv tmp
= tcg_temp_new();
218 gen_helper_g_to_memory(tmp
, t0
);
219 tcg_gen_qemu_st64(tmp
, t1
, flags
);
223 static inline void gen_qemu_sts(TCGv t0
, TCGv t1
, int flags
)
225 TCGv_i32 tmp32
= tcg_temp_new_i32();
226 TCGv tmp
= tcg_temp_new();
227 gen_helper_s_to_memory(tmp32
, t0
);
228 tcg_gen_extu_i32_i64(tmp
, tmp32
);
229 tcg_gen_qemu_st32(tmp
, t1
, flags
);
231 tcg_temp_free_i32(tmp32
);
234 static inline void gen_qemu_stl_c(TCGv t0
, TCGv t1
, int flags
)
238 l1
= gen_new_label();
239 l2
= gen_new_label();
240 tcg_gen_brcond_i64(TCG_COND_NE
, cpu_lock
, t1
, l1
);
241 tcg_gen_qemu_st32(t0
, t1
, flags
);
242 tcg_gen_movi_i64(t0
, 1);
245 tcg_gen_movi_i64(t0
, 0);
247 tcg_gen_movi_i64(cpu_lock
, -1);
250 static inline void gen_qemu_stq_c(TCGv t0
, TCGv t1
, int flags
)
254 l1
= gen_new_label();
255 l2
= gen_new_label();
256 tcg_gen_brcond_i64(TCG_COND_NE
, cpu_lock
, t1
, l1
);
257 tcg_gen_qemu_st64(t0
, t1
, flags
);
258 tcg_gen_movi_i64(t0
, 1);
261 tcg_gen_movi_i64(t0
, 0);
263 tcg_gen_movi_i64(cpu_lock
, -1);
266 static inline void gen_store_mem(DisasContext
*ctx
,
267 void (*tcg_gen_qemu_store
)(TCGv t0
, TCGv t1
,
269 int ra
, int rb
, int32_t disp16
, int fp
,
270 int clear
, int local
)
274 addr
= tcg_temp_local_new();
276 addr
= tcg_temp_new();
278 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp16
);
280 tcg_gen_andi_i64(addr
, addr
, ~0x7);
284 tcg_gen_movi_i64(addr
, disp16
);
288 tcg_gen_qemu_store(cpu_fir
[ra
], addr
, ctx
->mem_idx
);
290 tcg_gen_qemu_store(cpu_ir
[ra
], addr
, ctx
->mem_idx
);
294 zero
= tcg_const_local_i64(0);
296 zero
= tcg_const_i64(0);
297 tcg_gen_qemu_store(zero
, addr
, ctx
->mem_idx
);
303 static void gen_bcond_pcload(DisasContext
*ctx
, int32_t disp
, int lab_true
)
305 int lab_over
= gen_new_label();
307 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
);
308 tcg_gen_br(lab_over
);
309 gen_set_label(lab_true
);
310 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
+ (int64_t)(disp
<< 2));
311 gen_set_label(lab_over
);
314 static void gen_bcond(DisasContext
*ctx
, TCGCond cond
, int ra
,
315 int32_t disp
, int mask
)
317 int lab_true
= gen_new_label();
319 if (likely(ra
!= 31)) {
321 TCGv tmp
= tcg_temp_new();
322 tcg_gen_andi_i64(tmp
, cpu_ir
[ra
], 1);
323 tcg_gen_brcondi_i64(cond
, tmp
, 0, lab_true
);
326 tcg_gen_brcondi_i64(cond
, cpu_ir
[ra
], 0, lab_true
);
329 /* Very uncommon case - Do not bother to optimize. */
330 TCGv tmp
= tcg_const_i64(0);
331 tcg_gen_brcondi_i64(cond
, tmp
, 0, lab_true
);
334 gen_bcond_pcload(ctx
, disp
, lab_true
);
337 /* Generate a forward TCG branch to LAB_TRUE if RA cmp 0.0.
338 This is complicated by the fact that -0.0 compares the same as +0.0. */
340 static void gen_fbcond_internal(TCGCond cond
, TCGv src
, int lab_true
)
343 uint64_t mzero
= 1ull << 63;
349 /* For <= or >, the -0.0 value directly compares the way we want. */
350 tcg_gen_brcondi_i64(cond
, src
, 0, lab_true
);
355 /* For == or !=, we can simply mask off the sign bit and compare. */
356 /* ??? Assume that the temporary is reclaimed at the branch. */
357 tmp
= tcg_temp_new();
358 tcg_gen_andi_i64(tmp
, src
, mzero
- 1);
359 tcg_gen_brcondi_i64(cond
, tmp
, 0, lab_true
);
363 /* For >=, emit two branches to the destination. */
364 tcg_gen_brcondi_i64(cond
, src
, 0, lab_true
);
365 tcg_gen_brcondi_i64(TCG_COND_EQ
, src
, mzero
, lab_true
);
369 /* For <, first filter out -0.0 to what will be the fallthru. */
370 lab_false
= gen_new_label();
371 tcg_gen_brcondi_i64(TCG_COND_EQ
, src
, mzero
, lab_false
);
372 tcg_gen_brcondi_i64(cond
, src
, 0, lab_true
);
373 gen_set_label(lab_false
);
381 static void gen_fbcond(DisasContext
*ctx
, TCGCond cond
, int ra
, int32_t disp
)
385 if (unlikely(ra
== 31)) {
386 /* Very uncommon case, but easier to optimize it to an integer
387 comparison than continuing with the floating point comparison. */
388 gen_bcond(ctx
, cond
, ra
, disp
, 0);
392 lab_true
= gen_new_label();
393 gen_fbcond_internal(cond
, cpu_fir
[ra
], lab_true
);
394 gen_bcond_pcload(ctx
, disp
, lab_true
);
397 static void gen_cmov(TCGCond cond
, int ra
, int rb
, int rc
,
398 int islit
, uint8_t lit
, int mask
)
400 TCGCond inv_cond
= tcg_invert_cond(cond
);
403 if (unlikely(rc
== 31))
406 l1
= gen_new_label();
410 TCGv tmp
= tcg_temp_new();
411 tcg_gen_andi_i64(tmp
, cpu_ir
[ra
], 1);
412 tcg_gen_brcondi_i64(inv_cond
, tmp
, 0, l1
);
415 tcg_gen_brcondi_i64(inv_cond
, cpu_ir
[ra
], 0, l1
);
417 /* Very uncommon case - Do not bother to optimize. */
418 TCGv tmp
= tcg_const_i64(0);
419 tcg_gen_brcondi_i64(inv_cond
, tmp
, 0, l1
);
424 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
426 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
430 static void gen_fcmov(TCGCond cond
, int ra
, int rb
, int rc
)
432 TCGv va
= cpu_fir
[ra
];
435 if (unlikely(rc
== 31))
437 if (unlikely(ra
== 31)) {
438 /* ??? Assume that the temporary is reclaimed at the branch. */
439 va
= tcg_const_i64(0);
442 l1
= gen_new_label();
443 gen_fbcond_internal(tcg_invert_cond(cond
), va
, l1
);
446 tcg_gen_mov_i64(cpu_fir
[rc
], cpu_fir
[rb
]);
448 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
452 #define QUAL_RM_N 0x080 /* Round mode nearest even */
453 #define QUAL_RM_C 0x000 /* Round mode chopped */
454 #define QUAL_RM_M 0x040 /* Round mode minus infinity */
455 #define QUAL_RM_D 0x0c0 /* Round mode dynamic */
456 #define QUAL_RM_MASK 0x0c0
458 #define QUAL_U 0x100 /* Underflow enable (fp output) */
459 #define QUAL_V 0x100 /* Overflow enable (int output) */
460 #define QUAL_S 0x400 /* Software completion enable */
461 #define QUAL_I 0x200 /* Inexact detection enable */
463 static void gen_qual_roundmode(DisasContext
*ctx
, int fn11
)
467 fn11
&= QUAL_RM_MASK
;
468 if (fn11
== ctx
->tb_rm
) {
473 tmp
= tcg_temp_new_i32();
476 tcg_gen_movi_i32(tmp
, float_round_nearest_even
);
479 tcg_gen_movi_i32(tmp
, float_round_to_zero
);
482 tcg_gen_movi_i32(tmp
, float_round_down
);
485 tcg_gen_ld8u_i32(tmp
, cpu_env
, offsetof(CPUState
, fpcr_dyn_round
));
489 #if defined(CONFIG_SOFTFLOAT_INLINE)
490 /* ??? The "softfloat.h" interface is to call set_float_rounding_mode.
491 With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
492 sets the one field. */
493 tcg_gen_st8_i32(tmp
, cpu_env
,
494 offsetof(CPUState
, fp_status
.float_rounding_mode
));
496 gen_helper_setroundmode(tmp
);
499 tcg_temp_free_i32(tmp
);
502 static void gen_qual_flushzero(DisasContext
*ctx
, int fn11
)
507 if (fn11
== ctx
->tb_ftz
) {
512 tmp
= tcg_temp_new_i32();
514 /* Underflow is enabled, use the FPCR setting. */
515 tcg_gen_ld8u_i32(tmp
, cpu_env
, offsetof(CPUState
, fpcr_flush_to_zero
));
517 /* Underflow is disabled, force flush-to-zero. */
518 tcg_gen_movi_i32(tmp
, 1);
521 #if defined(CONFIG_SOFTFLOAT_INLINE)
522 tcg_gen_st8_i32(tmp
, cpu_env
,
523 offsetof(CPUState
, fp_status
.flush_to_zero
));
525 gen_helper_setflushzero(tmp
);
528 tcg_temp_free_i32(tmp
);
531 static TCGv
gen_ieee_input(int reg
, int fn11
, int is_cmp
)
533 TCGv val
= tcg_temp_new();
535 tcg_gen_movi_i64(val
, 0);
536 } else if (fn11
& QUAL_S
) {
537 gen_helper_ieee_input_s(val
, cpu_fir
[reg
]);
539 gen_helper_ieee_input_cmp(val
, cpu_fir
[reg
]);
541 gen_helper_ieee_input(val
, cpu_fir
[reg
]);
546 static void gen_fp_exc_clear(void)
548 #if defined(CONFIG_SOFTFLOAT_INLINE)
549 TCGv_i32 zero
= tcg_const_i32(0);
550 tcg_gen_st8_i32(zero
, cpu_env
,
551 offsetof(CPUState
, fp_status
.float_exception_flags
));
552 tcg_temp_free_i32(zero
);
554 gen_helper_fp_exc_clear();
558 static void gen_fp_exc_raise_ignore(int rc
, int fn11
, int ignore
)
560 /* ??? We ought to be able to do something with imprecise exceptions.
561 E.g. notice we're still in the trap shadow of something within the
562 TB and do not generate the code to signal the exception; end the TB
563 when an exception is forced to arrive, either by consumption of a
564 register value or TRAPB or EXCB. */
565 TCGv_i32 exc
= tcg_temp_new_i32();
568 #if defined(CONFIG_SOFTFLOAT_INLINE)
569 tcg_gen_ld8u_i32(exc
, cpu_env
,
570 offsetof(CPUState
, fp_status
.float_exception_flags
));
572 gen_helper_fp_exc_get(exc
);
576 tcg_gen_andi_i32(exc
, exc
, ~ignore
);
579 /* ??? Pass in the regno of the destination so that the helper can
580 set EXC_MASK, which contains a bitmask of destination registers
581 that have caused arithmetic traps. A simple userspace emulation
582 does not require this. We do need it for a guest kernel's entArith,
583 or if we were to do something clever with imprecise exceptions. */
584 reg
= tcg_const_i32(rc
+ 32);
587 gen_helper_fp_exc_raise_s(exc
, reg
);
589 gen_helper_fp_exc_raise(exc
, reg
);
592 tcg_temp_free_i32(reg
);
593 tcg_temp_free_i32(exc
);
596 static inline void gen_fp_exc_raise(int rc
, int fn11
)
598 gen_fp_exc_raise_ignore(rc
, fn11
, fn11
& QUAL_I
? 0 : float_flag_inexact
);
601 static void gen_fcvtql(int rb
, int rc
)
603 if (unlikely(rc
== 31)) {
606 if (unlikely(rb
== 31)) {
607 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
609 TCGv tmp
= tcg_temp_new();
611 tcg_gen_andi_i64(tmp
, cpu_fir
[rb
], 0xC0000000);
612 tcg_gen_andi_i64(cpu_fir
[rc
], cpu_fir
[rb
], 0x3FFFFFFF);
613 tcg_gen_shli_i64(tmp
, tmp
, 32);
614 tcg_gen_shli_i64(cpu_fir
[rc
], cpu_fir
[rc
], 29);
615 tcg_gen_or_i64(cpu_fir
[rc
], cpu_fir
[rc
], tmp
);
621 static void gen_fcvtql_v(DisasContext
*ctx
, int rb
, int rc
)
624 int lab
= gen_new_label();
625 TCGv tmp
= tcg_temp_new();
627 tcg_gen_ext32s_i64(tmp
, cpu_fir
[rb
]);
628 tcg_gen_brcond_i64(TCG_COND_EQ
, tmp
, cpu_fir
[rb
], lab
);
629 gen_excp(ctx
, EXCP_ARITH
, EXC_M_IOV
);
636 #define FARITH2(name) \
637 static inline void glue(gen_f, name)(int rb, int rc) \
639 if (unlikely(rc == 31)) { \
643 gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
645 TCGv tmp = tcg_const_i64(0); \
646 gen_helper_ ## name (cpu_fir[rc], tmp); \
647 tcg_temp_free(tmp); \
652 /* ??? VAX instruction qualifiers ignored. */
660 static void gen_ieee_arith2(DisasContext
*ctx
, void (*helper
)(TCGv
, TCGv
),
661 int rb
, int rc
, int fn11
)
665 /* ??? This is wrong: the instruction is not a nop, it still may
667 if (unlikely(rc
== 31)) {
671 gen_qual_roundmode(ctx
, fn11
);
672 gen_qual_flushzero(ctx
, fn11
);
675 vb
= gen_ieee_input(rb
, fn11
, 0);
676 helper(cpu_fir
[rc
], vb
);
679 gen_fp_exc_raise(rc
, fn11
);
682 #define IEEE_ARITH2(name) \
683 static inline void glue(gen_f, name)(DisasContext *ctx, \
684 int rb, int rc, int fn11) \
686 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \
693 static void gen_fcvttq(DisasContext
*ctx
, int rb
, int rc
, int fn11
)
698 /* ??? This is wrong: the instruction is not a nop, it still may
700 if (unlikely(rc
== 31)) {
704 /* No need to set flushzero, since we have an integer output. */
706 vb
= gen_ieee_input(rb
, fn11
, 0);
708 /* Almost all integer conversions use cropped rounding, and most
709 also do not have integer overflow enabled. Special case that. */
712 gen_helper_cvttq_c(cpu_fir
[rc
], vb
);
714 case QUAL_V
| QUAL_RM_C
:
715 case QUAL_S
| QUAL_V
| QUAL_RM_C
:
716 ignore
= float_flag_inexact
;
718 case QUAL_S
| QUAL_V
| QUAL_I
| QUAL_RM_C
:
719 gen_helper_cvttq_svic(cpu_fir
[rc
], vb
);
722 gen_qual_roundmode(ctx
, fn11
);
723 gen_helper_cvttq(cpu_fir
[rc
], vb
);
724 ignore
|= (fn11
& QUAL_V
? 0 : float_flag_overflow
);
725 ignore
|= (fn11
& QUAL_I
? 0 : float_flag_inexact
);
730 gen_fp_exc_raise_ignore(rc
, fn11
, ignore
);
733 static void gen_ieee_intcvt(DisasContext
*ctx
, void (*helper
)(TCGv
, TCGv
),
734 int rb
, int rc
, int fn11
)
738 /* ??? This is wrong: the instruction is not a nop, it still may
740 if (unlikely(rc
== 31)) {
744 gen_qual_roundmode(ctx
, fn11
);
747 vb
= tcg_const_i64(0);
752 /* The only exception that can be raised by integer conversion
753 is inexact. Thus we only need to worry about exceptions when
754 inexact handling is requested. */
757 helper(cpu_fir
[rc
], vb
);
758 gen_fp_exc_raise(rc
, fn11
);
760 helper(cpu_fir
[rc
], vb
);
768 #define IEEE_INTCVT(name) \
769 static inline void glue(gen_f, name)(DisasContext *ctx, \
770 int rb, int rc, int fn11) \
772 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \
777 #define FARITH3(name) \
778 static inline void glue(gen_f, name)(int ra, int rb, int rc) \
782 if (unlikely(rc == 31)) { \
786 va = tcg_const_i64(0); \
791 vb = tcg_const_i64(0); \
796 gen_helper_ ## name (cpu_fir[rc], va, vb); \
805 /* ??? Ought to expand these inline; simple masking operations. */
810 /* ??? VAX instruction qualifiers ignored. */
823 static void gen_ieee_arith3(DisasContext
*ctx
,
824 void (*helper
)(TCGv
, TCGv
, TCGv
),
825 int ra
, int rb
, int rc
, int fn11
)
829 /* ??? This is wrong: the instruction is not a nop, it still may
831 if (unlikely(rc
== 31)) {
835 gen_qual_roundmode(ctx
, fn11
);
836 gen_qual_flushzero(ctx
, fn11
);
839 va
= gen_ieee_input(ra
, fn11
, 0);
840 vb
= gen_ieee_input(rb
, fn11
, 0);
841 helper(cpu_fir
[rc
], va
, vb
);
845 gen_fp_exc_raise(rc
, fn11
);
848 #define IEEE_ARITH3(name) \
849 static inline void glue(gen_f, name)(DisasContext *ctx, \
850 int ra, int rb, int rc, int fn11) \
852 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \
863 static void gen_ieee_compare(DisasContext
*ctx
,
864 void (*helper
)(TCGv
, TCGv
, TCGv
),
865 int ra
, int rb
, int rc
, int fn11
)
869 /* ??? This is wrong: the instruction is not a nop, it still may
871 if (unlikely(rc
== 31)) {
877 va
= gen_ieee_input(ra
, fn11
, 1);
878 vb
= gen_ieee_input(rb
, fn11
, 1);
879 helper(cpu_fir
[rc
], va
, vb
);
883 gen_fp_exc_raise(rc
, fn11
);
886 #define IEEE_CMP3(name) \
887 static inline void glue(gen_f, name)(DisasContext *ctx, \
888 int ra, int rb, int rc, int fn11) \
890 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \
897 static inline uint64_t zapnot_mask(uint8_t lit
)
902 for (i
= 0; i
< 8; ++i
) {
904 mask
|= 0xffull
<< (i
* 8);
909 /* Implement zapnot with an immediate operand, which expands to some
910 form of immediate AND. This is a basic building block in the
911 definition of many of the other byte manipulation instructions. */
912 static void gen_zapnoti(TCGv dest
, TCGv src
, uint8_t lit
)
916 tcg_gen_movi_i64(dest
, 0);
919 tcg_gen_ext8u_i64(dest
, src
);
922 tcg_gen_ext16u_i64(dest
, src
);
925 tcg_gen_ext32u_i64(dest
, src
);
928 tcg_gen_mov_i64(dest
, src
);
931 tcg_gen_andi_i64 (dest
, src
, zapnot_mask (lit
));
936 static inline void gen_zapnot(int ra
, int rb
, int rc
, int islit
, uint8_t lit
)
938 if (unlikely(rc
== 31))
940 else if (unlikely(ra
== 31))
941 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
943 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
945 gen_helper_zapnot (cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
948 static inline void gen_zap(int ra
, int rb
, int rc
, int islit
, uint8_t lit
)
950 if (unlikely(rc
== 31))
952 else if (unlikely(ra
== 31))
953 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
955 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
957 gen_helper_zap (cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
961 /* EXTWH, EXTLH, EXTQH */
962 static void gen_ext_h(int ra
, int rb
, int rc
, int islit
,
963 uint8_t lit
, uint8_t byte_mask
)
965 if (unlikely(rc
== 31))
967 else if (unlikely(ra
== 31))
968 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
971 lit
= (64 - (lit
& 7) * 8) & 0x3f;
972 tcg_gen_shli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
974 TCGv tmp1
= tcg_temp_new();
975 tcg_gen_andi_i64(tmp1
, cpu_ir
[rb
], 7);
976 tcg_gen_shli_i64(tmp1
, tmp1
, 3);
977 tcg_gen_neg_i64(tmp1
, tmp1
);
978 tcg_gen_andi_i64(tmp1
, tmp1
, 0x3f);
979 tcg_gen_shl_i64(cpu_ir
[rc
], cpu_ir
[ra
], tmp1
);
982 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[rc
], byte_mask
);
986 /* EXTBL, EXTWL, EXTLL, EXTQL */
987 static void gen_ext_l(int ra
, int rb
, int rc
, int islit
,
988 uint8_t lit
, uint8_t byte_mask
)
990 if (unlikely(rc
== 31))
992 else if (unlikely(ra
== 31))
993 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
996 tcg_gen_shri_i64(cpu_ir
[rc
], cpu_ir
[ra
], (lit
& 7) * 8);
998 TCGv tmp
= tcg_temp_new();
999 tcg_gen_andi_i64(tmp
, cpu_ir
[rb
], 7);
1000 tcg_gen_shli_i64(tmp
, tmp
, 3);
1001 tcg_gen_shr_i64(cpu_ir
[rc
], cpu_ir
[ra
], tmp
);
1004 gen_zapnoti(cpu_ir
[rc
], cpu_ir
[rc
], byte_mask
);
1008 /* INSWH, INSLH, INSQH */
1009 static void gen_ins_h(int ra
, int rb
, int rc
, int islit
,
1010 uint8_t lit
, uint8_t byte_mask
)
1012 if (unlikely(rc
== 31))
1014 else if (unlikely(ra
== 31) || (islit
&& (lit
& 7) == 0))
1015 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1017 TCGv tmp
= tcg_temp_new();
1019 /* The instruction description has us left-shift the byte mask
1020 and extract bits <15:8> and apply that zap at the end. This
1021 is equivalent to simply performing the zap first and shifting
1023 gen_zapnoti (tmp
, cpu_ir
[ra
], byte_mask
);
1026 /* Note that we have handled the lit==0 case above. */
1027 tcg_gen_shri_i64 (cpu_ir
[rc
], tmp
, 64 - (lit
& 7) * 8);
1029 TCGv shift
= tcg_temp_new();
1031 /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
1032 Do this portably by splitting the shift into two parts:
1033 shift_count-1 and 1. Arrange for the -1 by using
1034 ones-complement instead of twos-complement in the negation:
1035 ~((B & 7) * 8) & 63. */
1037 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 7);
1038 tcg_gen_shli_i64(shift
, shift
, 3);
1039 tcg_gen_not_i64(shift
, shift
);
1040 tcg_gen_andi_i64(shift
, shift
, 0x3f);
1042 tcg_gen_shr_i64(cpu_ir
[rc
], tmp
, shift
);
1043 tcg_gen_shri_i64(cpu_ir
[rc
], cpu_ir
[rc
], 1);
1044 tcg_temp_free(shift
);
1050 /* INSBL, INSWL, INSLL, INSQL */
1051 static void gen_ins_l(int ra
, int rb
, int rc
, int islit
,
1052 uint8_t lit
, uint8_t byte_mask
)
1054 if (unlikely(rc
== 31))
1056 else if (unlikely(ra
== 31))
1057 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1059 TCGv tmp
= tcg_temp_new();
1061 /* The instruction description has us left-shift the byte mask
1062 the same number of byte slots as the data and apply the zap
1063 at the end. This is equivalent to simply performing the zap
1064 first and shifting afterward. */
1065 gen_zapnoti (tmp
, cpu_ir
[ra
], byte_mask
);
1068 tcg_gen_shli_i64(cpu_ir
[rc
], tmp
, (lit
& 7) * 8);
1070 TCGv shift
= tcg_temp_new();
1071 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 7);
1072 tcg_gen_shli_i64(shift
, shift
, 3);
1073 tcg_gen_shl_i64(cpu_ir
[rc
], tmp
, shift
);
1074 tcg_temp_free(shift
);
1080 /* MSKWH, MSKLH, MSKQH */
1081 static void gen_msk_h(int ra
, int rb
, int rc
, int islit
,
1082 uint8_t lit
, uint8_t byte_mask
)
1084 if (unlikely(rc
== 31))
1086 else if (unlikely(ra
== 31))
1087 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1089 gen_zapnoti (cpu_ir
[rc
], cpu_ir
[ra
], ~((byte_mask
<< (lit
& 7)) >> 8));
1091 TCGv shift
= tcg_temp_new();
1092 TCGv mask
= tcg_temp_new();
1094 /* The instruction description is as above, where the byte_mask
1095 is shifted left, and then we extract bits <15:8>. This can be
1096 emulated with a right-shift on the expanded byte mask. This
1097 requires extra care because for an input <2:0> == 0 we need a
1098 shift of 64 bits in order to generate a zero. This is done by
1099 splitting the shift into two parts, the variable shift - 1
1100 followed by a constant 1 shift. The code we expand below is
1101 equivalent to ~((B & 7) * 8) & 63. */
1103 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 7);
1104 tcg_gen_shli_i64(shift
, shift
, 3);
1105 tcg_gen_not_i64(shift
, shift
);
1106 tcg_gen_andi_i64(shift
, shift
, 0x3f);
1107 tcg_gen_movi_i64(mask
, zapnot_mask (byte_mask
));
1108 tcg_gen_shr_i64(mask
, mask
, shift
);
1109 tcg_gen_shri_i64(mask
, mask
, 1);
1111 tcg_gen_andc_i64(cpu_ir
[rc
], cpu_ir
[ra
], mask
);
1113 tcg_temp_free(mask
);
1114 tcg_temp_free(shift
);
1118 /* MSKBL, MSKWL, MSKLL, MSKQL */
1119 static void gen_msk_l(int ra
, int rb
, int rc
, int islit
,
1120 uint8_t lit
, uint8_t byte_mask
)
1122 if (unlikely(rc
== 31))
1124 else if (unlikely(ra
== 31))
1125 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1127 gen_zapnoti (cpu_ir
[rc
], cpu_ir
[ra
], ~(byte_mask
<< (lit
& 7)));
1129 TCGv shift
= tcg_temp_new();
1130 TCGv mask
= tcg_temp_new();
1132 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 7);
1133 tcg_gen_shli_i64(shift
, shift
, 3);
1134 tcg_gen_movi_i64(mask
, zapnot_mask (byte_mask
));
1135 tcg_gen_shl_i64(mask
, mask
, shift
);
1137 tcg_gen_andc_i64(cpu_ir
[rc
], cpu_ir
[ra
], mask
);
1139 tcg_temp_free(mask
);
1140 tcg_temp_free(shift
);
1144 /* Code to call arith3 helpers */
1145 #define ARITH3(name) \
1146 static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
1149 if (unlikely(rc == 31)) \
1154 TCGv tmp = tcg_const_i64(lit); \
1155 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
1156 tcg_temp_free(tmp); \
1158 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1160 TCGv tmp1 = tcg_const_i64(0); \
1162 TCGv tmp2 = tcg_const_i64(lit); \
1163 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
1164 tcg_temp_free(tmp2); \
1166 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
1167 tcg_temp_free(tmp1); \
1188 #define MVIOP2(name) \
1189 static inline void glue(gen_, name)(int rb, int rc) \
1191 if (unlikely(rc == 31)) \
1193 if (unlikely(rb == 31)) \
1194 tcg_gen_movi_i64(cpu_ir[rc], 0); \
1196 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
1203 static void gen_cmp(TCGCond cond
, int ra
, int rb
, int rc
,
1204 int islit
, uint8_t lit
)
1208 if (unlikely(rc
== 31)) {
1213 va
= tcg_const_i64(0);
1218 vb
= tcg_const_i64(lit
);
1223 tcg_gen_setcond_i64(cond
, cpu_ir
[rc
], va
, vb
);
1233 static inline int translate_one(DisasContext
*ctx
, uint32_t insn
)
1236 int32_t disp21
, disp16
, disp12
;
1238 uint8_t opc
, ra
, rb
, rc
, fpfn
, fn7
, fn2
, islit
, real_islit
;
1242 /* Decode all instruction fields */
1244 ra
= (insn
>> 21) & 0x1F;
1245 rb
= (insn
>> 16) & 0x1F;
1247 real_islit
= islit
= (insn
>> 12) & 1;
1248 if (rb
== 31 && !islit
) {
1252 lit
= (insn
>> 13) & 0xFF;
1253 palcode
= insn
& 0x03FFFFFF;
1254 disp21
= ((int32_t)((insn
& 0x001FFFFF) << 11)) >> 11;
1255 disp16
= (int16_t)(insn
& 0x0000FFFF);
1256 disp12
= (int32_t)((insn
& 0x00000FFF) << 20) >> 20;
1257 fn11
= (insn
>> 5) & 0x000007FF;
1259 fn7
= (insn
>> 5) & 0x0000007F;
1260 fn2
= (insn
>> 5) & 0x00000003;
1262 LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1263 opc
, ra
, rb
, rc
, disp16
);
1268 #ifdef CONFIG_USER_ONLY
1269 if (palcode
== 0x9E) {
1271 tcg_gen_mov_i64(cpu_ir
[IR_V0
], cpu_uniq
);
1273 } else if (palcode
== 0x9F) {
1275 tcg_gen_mov_i64(cpu_uniq
, cpu_ir
[IR_A0
]);
1279 if (palcode
>= 0x80 && palcode
< 0xC0) {
1280 /* Unprivileged PAL call */
1281 gen_excp(ctx
, EXCP_CALL_PAL
+ ((palcode
& 0x3F) << 6), 0);
1285 #ifndef CONFIG_USER_ONLY
1286 if (palcode
< 0x40) {
1287 /* Privileged PAL code */
1288 if (ctx
->mem_idx
& 1)
1290 gen_excp(ctx
, EXCP_CALL_PALP
+ ((palcode
& 0x3F) << 6), 0);
1293 /* Invalid PAL call */
1318 if (likely(ra
!= 31)) {
1320 tcg_gen_addi_i64(cpu_ir
[ra
], cpu_ir
[rb
], disp16
);
1322 tcg_gen_movi_i64(cpu_ir
[ra
], disp16
);
1327 if (likely(ra
!= 31)) {
1329 tcg_gen_addi_i64(cpu_ir
[ra
], cpu_ir
[rb
], disp16
<< 16);
1331 tcg_gen_movi_i64(cpu_ir
[ra
], disp16
<< 16);
1336 if (!(ctx
->amask
& AMASK_BWX
))
1338 gen_load_mem(ctx
, &tcg_gen_qemu_ld8u
, ra
, rb
, disp16
, 0, 0);
1342 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 0, 1);
1346 if (!(ctx
->amask
& AMASK_BWX
))
1348 gen_load_mem(ctx
, &tcg_gen_qemu_ld16u
, ra
, rb
, disp16
, 0, 0);
1352 gen_store_mem(ctx
, &tcg_gen_qemu_st16
, ra
, rb
, disp16
, 0, 0, 0);
1356 gen_store_mem(ctx
, &tcg_gen_qemu_st8
, ra
, rb
, disp16
, 0, 0, 0);
1360 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 0, 1, 0);
1366 if (likely(rc
!= 31)) {
1369 tcg_gen_addi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1370 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1372 tcg_gen_add_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1373 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1377 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1379 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1385 if (likely(rc
!= 31)) {
1387 TCGv tmp
= tcg_temp_new();
1388 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1390 tcg_gen_addi_i64(tmp
, tmp
, lit
);
1392 tcg_gen_add_i64(tmp
, tmp
, cpu_ir
[rb
]);
1393 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1397 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1399 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1405 if (likely(rc
!= 31)) {
1408 tcg_gen_subi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1410 tcg_gen_sub_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1411 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1414 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1416 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1417 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1423 if (likely(rc
!= 31)) {
1425 TCGv tmp
= tcg_temp_new();
1426 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1428 tcg_gen_subi_i64(tmp
, tmp
, lit
);
1430 tcg_gen_sub_i64(tmp
, tmp
, cpu_ir
[rb
]);
1431 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1435 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1437 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1438 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1445 gen_cmpbge(ra
, rb
, rc
, islit
, lit
);
1449 if (likely(rc
!= 31)) {
1451 TCGv tmp
= tcg_temp_new();
1452 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1454 tcg_gen_addi_i64(tmp
, tmp
, lit
);
1456 tcg_gen_add_i64(tmp
, tmp
, cpu_ir
[rb
]);
1457 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1461 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1463 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1469 if (likely(rc
!= 31)) {
1471 TCGv tmp
= tcg_temp_new();
1472 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1474 tcg_gen_subi_i64(tmp
, tmp
, lit
);
1476 tcg_gen_sub_i64(tmp
, tmp
, cpu_ir
[rb
]);
1477 tcg_gen_ext32s_i64(cpu_ir
[rc
], tmp
);
1481 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1483 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1484 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1491 gen_cmp(TCG_COND_LTU
, ra
, rb
, rc
, islit
, lit
);
1495 if (likely(rc
!= 31)) {
1498 tcg_gen_addi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1500 tcg_gen_add_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1503 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1505 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1511 if (likely(rc
!= 31)) {
1513 TCGv tmp
= tcg_temp_new();
1514 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1516 tcg_gen_addi_i64(cpu_ir
[rc
], tmp
, lit
);
1518 tcg_gen_add_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
1522 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1524 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1530 if (likely(rc
!= 31)) {
1533 tcg_gen_subi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1535 tcg_gen_sub_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1538 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1540 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1546 if (likely(rc
!= 31)) {
1548 TCGv tmp
= tcg_temp_new();
1549 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 2);
1551 tcg_gen_subi_i64(cpu_ir
[rc
], tmp
, lit
);
1553 tcg_gen_sub_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
1557 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1559 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1565 gen_cmp(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
);
1569 if (likely(rc
!= 31)) {
1571 TCGv tmp
= tcg_temp_new();
1572 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1574 tcg_gen_addi_i64(cpu_ir
[rc
], tmp
, lit
);
1576 tcg_gen_add_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
1580 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1582 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1588 if (likely(rc
!= 31)) {
1590 TCGv tmp
= tcg_temp_new();
1591 tcg_gen_shli_i64(tmp
, cpu_ir
[ra
], 3);
1593 tcg_gen_subi_i64(cpu_ir
[rc
], tmp
, lit
);
1595 tcg_gen_sub_i64(cpu_ir
[rc
], tmp
, cpu_ir
[rb
]);
1599 tcg_gen_movi_i64(cpu_ir
[rc
], -lit
);
1601 tcg_gen_neg_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1607 gen_cmp(TCG_COND_LEU
, ra
, rb
, rc
, islit
, lit
);
1611 gen_addlv(ra
, rb
, rc
, islit
, lit
);
1615 gen_sublv(ra
, rb
, rc
, islit
, lit
);
1619 gen_cmp(TCG_COND_LT
, ra
, rb
, rc
, islit
, lit
);
1623 gen_addqv(ra
, rb
, rc
, islit
, lit
);
1627 gen_subqv(ra
, rb
, rc
, islit
, lit
);
1631 gen_cmp(TCG_COND_LE
, ra
, rb
, rc
, islit
, lit
);
1641 if (likely(rc
!= 31)) {
1643 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1645 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1647 tcg_gen_and_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1652 if (likely(rc
!= 31)) {
1655 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
1657 tcg_gen_andc_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1659 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1664 gen_cmov(TCG_COND_NE
, ra
, rb
, rc
, islit
, lit
, 1);
1668 gen_cmov(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
, 1);
1672 if (likely(rc
!= 31)) {
1675 tcg_gen_ori_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1677 tcg_gen_or_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1680 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1682 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1688 gen_cmov(TCG_COND_EQ
, ra
, rb
, rc
, islit
, lit
, 0);
1692 gen_cmov(TCG_COND_NE
, ra
, rb
, rc
, islit
, lit
, 0);
1696 if (likely(rc
!= 31)) {
1699 tcg_gen_ori_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
1701 tcg_gen_orc_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1704 tcg_gen_movi_i64(cpu_ir
[rc
], ~lit
);
1706 tcg_gen_not_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1712 if (likely(rc
!= 31)) {
1715 tcg_gen_xori_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1717 tcg_gen_xor_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1720 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1722 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1728 gen_cmov(TCG_COND_LT
, ra
, rb
, rc
, islit
, lit
, 0);
1732 gen_cmov(TCG_COND_GE
, ra
, rb
, rc
, islit
, lit
, 0);
1736 if (likely(rc
!= 31)) {
1739 tcg_gen_xori_i64(cpu_ir
[rc
], cpu_ir
[ra
], ~lit
);
1741 tcg_gen_eqv_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1744 tcg_gen_movi_i64(cpu_ir
[rc
], ~lit
);
1746 tcg_gen_not_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1752 if (likely(rc
!= 31)) {
1754 tcg_gen_movi_i64(cpu_ir
[rc
], lit
);
1756 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
1757 switch (ctx
->env
->implver
) {
1759 /* EV4, EV45, LCA, LCA45 & EV5 */
1764 tcg_gen_andi_i64(cpu_ir
[rc
], cpu_ir
[rc
],
1765 ~(uint64_t)ctx
->amask
);
1772 gen_cmov(TCG_COND_LE
, ra
, rb
, rc
, islit
, lit
, 0);
1776 gen_cmov(TCG_COND_GT
, ra
, rb
, rc
, islit
, lit
, 0);
1781 tcg_gen_movi_i64(cpu_ir
[rc
], ctx
->env
->implver
);
1791 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x01);
1795 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x01);
1799 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x01);
1803 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x03);
1807 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x03);
1811 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x03);
1815 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
1819 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
1823 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0x0f);
1827 gen_zap(ra
, rb
, rc
, islit
, lit
);
1831 gen_zapnot(ra
, rb
, rc
, islit
, lit
);
1835 gen_msk_l(ra
, rb
, rc
, islit
, lit
, 0xff);
1839 if (likely(rc
!= 31)) {
1842 tcg_gen_shri_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
1844 TCGv shift
= tcg_temp_new();
1845 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 0x3f);
1846 tcg_gen_shr_i64(cpu_ir
[rc
], cpu_ir
[ra
], shift
);
1847 tcg_temp_free(shift
);
1850 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1855 gen_ext_l(ra
, rb
, rc
, islit
, lit
, 0xff);
1859 if (likely(rc
!= 31)) {
1862 tcg_gen_shli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
1864 TCGv shift
= tcg_temp_new();
1865 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 0x3f);
1866 tcg_gen_shl_i64(cpu_ir
[rc
], cpu_ir
[ra
], shift
);
1867 tcg_temp_free(shift
);
1870 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1875 gen_ins_l(ra
, rb
, rc
, islit
, lit
, 0xff);
1879 if (likely(rc
!= 31)) {
1882 tcg_gen_sari_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
& 0x3f);
1884 TCGv shift
= tcg_temp_new();
1885 tcg_gen_andi_i64(shift
, cpu_ir
[rb
], 0x3f);
1886 tcg_gen_sar_i64(cpu_ir
[rc
], cpu_ir
[ra
], shift
);
1887 tcg_temp_free(shift
);
1890 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1895 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0x03);
1899 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0x03);
1903 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0x03);
1907 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
1911 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
1915 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0x0f);
1919 gen_msk_h(ra
, rb
, rc
, islit
, lit
, 0xff);
1923 gen_ins_h(ra
, rb
, rc
, islit
, lit
, 0xff);
1927 gen_ext_h(ra
, rb
, rc
, islit
, lit
, 0xff);
1937 if (likely(rc
!= 31)) {
1939 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1942 tcg_gen_muli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1944 tcg_gen_mul_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1945 tcg_gen_ext32s_i64(cpu_ir
[rc
], cpu_ir
[rc
]);
1951 if (likely(rc
!= 31)) {
1953 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
1955 tcg_gen_muli_i64(cpu_ir
[rc
], cpu_ir
[ra
], lit
);
1957 tcg_gen_mul_i64(cpu_ir
[rc
], cpu_ir
[ra
], cpu_ir
[rb
]);
1962 gen_umulh(ra
, rb
, rc
, islit
, lit
);
1966 gen_mullv(ra
, rb
, rc
, islit
, lit
);
1970 gen_mulqv(ra
, rb
, rc
, islit
, lit
);
1977 switch (fpfn
) { /* fn11 & 0x3F */
1980 if (!(ctx
->amask
& AMASK_FIX
))
1982 if (likely(rc
!= 31)) {
1984 TCGv_i32 tmp
= tcg_temp_new_i32();
1985 tcg_gen_trunc_i64_i32(tmp
, cpu_ir
[ra
]);
1986 gen_helper_memory_to_s(cpu_fir
[rc
], tmp
);
1987 tcg_temp_free_i32(tmp
);
1989 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
1994 if (!(ctx
->amask
& AMASK_FIX
))
2000 if (!(ctx
->amask
& AMASK_FIX
))
2002 gen_fsqrts(ctx
, rb
, rc
, fn11
);
2006 if (!(ctx
->amask
& AMASK_FIX
))
2008 if (likely(rc
!= 31)) {
2010 TCGv_i32 tmp
= tcg_temp_new_i32();
2011 tcg_gen_trunc_i64_i32(tmp
, cpu_ir
[ra
]);
2012 gen_helper_memory_to_f(cpu_fir
[rc
], tmp
);
2013 tcg_temp_free_i32(tmp
);
2015 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2020 if (!(ctx
->amask
& AMASK_FIX
))
2022 if (likely(rc
!= 31)) {
2024 tcg_gen_mov_i64(cpu_fir
[rc
], cpu_ir
[ra
]);
2026 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2031 if (!(ctx
->amask
& AMASK_FIX
))
2037 if (!(ctx
->amask
& AMASK_FIX
))
2039 gen_fsqrtt(ctx
, rb
, rc
, fn11
);
2046 /* VAX floating point */
2047 /* XXX: rounding mode and trap are ignored (!) */
2048 switch (fpfn
) { /* fn11 & 0x3F */
2051 gen_faddf(ra
, rb
, rc
);
2055 gen_fsubf(ra
, rb
, rc
);
2059 gen_fmulf(ra
, rb
, rc
);
2063 gen_fdivf(ra
, rb
, rc
);
2075 gen_faddg(ra
, rb
, rc
);
2079 gen_fsubg(ra
, rb
, rc
);
2083 gen_fmulg(ra
, rb
, rc
);
2087 gen_fdivg(ra
, rb
, rc
);
2091 gen_fcmpgeq(ra
, rb
, rc
);
2095 gen_fcmpglt(ra
, rb
, rc
);
2099 gen_fcmpgle(ra
, rb
, rc
);
2130 /* IEEE floating-point */
2131 switch (fpfn
) { /* fn11 & 0x3F */
2134 gen_fadds(ctx
, ra
, rb
, rc
, fn11
);
2138 gen_fsubs(ctx
, ra
, rb
, rc
, fn11
);
2142 gen_fmuls(ctx
, ra
, rb
, rc
, fn11
);
2146 gen_fdivs(ctx
, ra
, rb
, rc
, fn11
);
2150 gen_faddt(ctx
, ra
, rb
, rc
, fn11
);
2154 gen_fsubt(ctx
, ra
, rb
, rc
, fn11
);
2158 gen_fmult(ctx
, ra
, rb
, rc
, fn11
);
2162 gen_fdivt(ctx
, ra
, rb
, rc
, fn11
);
2166 gen_fcmptun(ctx
, ra
, rb
, rc
, fn11
);
2170 gen_fcmpteq(ctx
, ra
, rb
, rc
, fn11
);
2174 gen_fcmptlt(ctx
, ra
, rb
, rc
, fn11
);
2178 gen_fcmptle(ctx
, ra
, rb
, rc
, fn11
);
2181 if (fn11
== 0x2AC || fn11
== 0x6AC) {
2183 gen_fcvtst(ctx
, rb
, rc
, fn11
);
2186 gen_fcvtts(ctx
, rb
, rc
, fn11
);
2191 gen_fcvttq(ctx
, rb
, rc
, fn11
);
2195 gen_fcvtqs(ctx
, rb
, rc
, fn11
);
2199 gen_fcvtqt(ctx
, rb
, rc
, fn11
);
2212 if (likely(rc
!= 31)) {
2216 tcg_gen_movi_i64(cpu_fir
[rc
], 0);
2218 tcg_gen_mov_i64(cpu_fir
[rc
], cpu_fir
[ra
]);
2221 gen_fcpys(ra
, rb
, rc
);
2227 gen_fcpysn(ra
, rb
, rc
);
2231 gen_fcpyse(ra
, rb
, rc
);
2235 if (likely(ra
!= 31))
2236 gen_helper_store_fpcr(cpu_fir
[ra
]);
2238 TCGv tmp
= tcg_const_i64(0);
2239 gen_helper_store_fpcr(tmp
);
2245 if (likely(ra
!= 31))
2246 gen_helper_load_fpcr(cpu_fir
[ra
]);
2250 gen_fcmov(TCG_COND_EQ
, ra
, rb
, rc
);
2254 gen_fcmov(TCG_COND_NE
, ra
, rb
, rc
);
2258 gen_fcmov(TCG_COND_LT
, ra
, rb
, rc
);
2262 gen_fcmov(TCG_COND_GE
, ra
, rb
, rc
);
2266 gen_fcmov(TCG_COND_LE
, ra
, rb
, rc
);
2270 gen_fcmov(TCG_COND_GT
, ra
, rb
, rc
);
2280 /* ??? I'm pretty sure there's nothing that /sv needs to do that
2281 /v doesn't do. The only thing I can think is that /sv is a
2282 valid instruction merely for completeness in the ISA. */
2283 gen_fcvtql_v(ctx
, rb
, rc
);
2290 switch ((uint16_t)disp16
) {
2293 /* No-op. Just exit from the current tb */
2298 /* No-op. Just exit from the current tb */
2320 gen_helper_load_pcc(cpu_ir
[ra
]);
2325 gen_helper_rc(cpu_ir
[ra
]);
2333 gen_helper_rs(cpu_ir
[ra
]);
2344 /* HW_MFPR (PALcode) */
2345 #if defined (CONFIG_USER_ONLY)
2351 TCGv tmp
= tcg_const_i32(insn
& 0xFF);
2352 gen_helper_mfpr(cpu_ir
[ra
], tmp
, cpu_ir
[ra
]);
2359 tcg_gen_andi_i64(cpu_pc
, cpu_ir
[rb
], ~3);
2361 tcg_gen_movi_i64(cpu_pc
, 0);
2363 tcg_gen_movi_i64(cpu_ir
[ra
], ctx
->pc
);
2364 /* Those four jumps only differ by the branch prediction hint */
2382 /* HW_LD (PALcode) */
2383 #if defined (CONFIG_USER_ONLY)
2389 TCGv addr
= tcg_temp_new();
2391 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp12
);
2393 tcg_gen_movi_i64(addr
, disp12
);
2394 switch ((insn
>> 12) & 0xF) {
2396 /* Longword physical access (hw_ldl/p) */
2397 gen_helper_ldl_raw(cpu_ir
[ra
], addr
);
2400 /* Quadword physical access (hw_ldq/p) */
2401 gen_helper_ldq_raw(cpu_ir
[ra
], addr
);
2404 /* Longword physical access with lock (hw_ldl_l/p) */
2405 gen_helper_ldl_l_raw(cpu_ir
[ra
], addr
);
2408 /* Quadword physical access with lock (hw_ldq_l/p) */
2409 gen_helper_ldq_l_raw(cpu_ir
[ra
], addr
);
2412 /* Longword virtual PTE fetch (hw_ldl/v) */
2413 tcg_gen_qemu_ld32s(cpu_ir
[ra
], addr
, 0);
2416 /* Quadword virtual PTE fetch (hw_ldq/v) */
2417 tcg_gen_qemu_ld64(cpu_ir
[ra
], addr
, 0);
2420 /* Incpu_ir[ra]id */
2423 /* Incpu_ir[ra]id */
2426 /* Longword virtual access (hw_ldl) */
2427 gen_helper_st_virt_to_phys(addr
, addr
);
2428 gen_helper_ldl_raw(cpu_ir
[ra
], addr
);
2431 /* Quadword virtual access (hw_ldq) */
2432 gen_helper_st_virt_to_phys(addr
, addr
);
2433 gen_helper_ldq_raw(cpu_ir
[ra
], addr
);
2436 /* Longword virtual access with protection check (hw_ldl/w) */
2437 tcg_gen_qemu_ld32s(cpu_ir
[ra
], addr
, 0);
2440 /* Quadword virtual access with protection check (hw_ldq/w) */
2441 tcg_gen_qemu_ld64(cpu_ir
[ra
], addr
, 0);
2444 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2445 gen_helper_set_alt_mode();
2446 gen_helper_st_virt_to_phys(addr
, addr
);
2447 gen_helper_ldl_raw(cpu_ir
[ra
], addr
);
2448 gen_helper_restore_mode();
2451 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2452 gen_helper_set_alt_mode();
2453 gen_helper_st_virt_to_phys(addr
, addr
);
2454 gen_helper_ldq_raw(cpu_ir
[ra
], addr
);
2455 gen_helper_restore_mode();
2458 /* Longword virtual access with alternate access mode and
2459 * protection checks (hw_ldl/wa)
2461 gen_helper_set_alt_mode();
2462 gen_helper_ldl_data(cpu_ir
[ra
], addr
);
2463 gen_helper_restore_mode();
2466 /* Quadword virtual access with alternate access mode and
2467 * protection checks (hw_ldq/wa)
2469 gen_helper_set_alt_mode();
2470 gen_helper_ldq_data(cpu_ir
[ra
], addr
);
2471 gen_helper_restore_mode();
2474 tcg_temp_free(addr
);
2482 if (!(ctx
->amask
& AMASK_BWX
))
2484 if (likely(rc
!= 31)) {
2486 tcg_gen_movi_i64(cpu_ir
[rc
], (int64_t)((int8_t)lit
));
2488 tcg_gen_ext8s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2493 if (!(ctx
->amask
& AMASK_BWX
))
2495 if (likely(rc
!= 31)) {
2497 tcg_gen_movi_i64(cpu_ir
[rc
], (int64_t)((int16_t)lit
));
2499 tcg_gen_ext16s_i64(cpu_ir
[rc
], cpu_ir
[rb
]);
2504 if (!(ctx
->amask
& AMASK_CIX
))
2506 if (likely(rc
!= 31)) {
2508 tcg_gen_movi_i64(cpu_ir
[rc
], ctpop64(lit
));
2510 gen_helper_ctpop(cpu_ir
[rc
], cpu_ir
[rb
]);
2515 if (!(ctx
->amask
& AMASK_MVI
))
2517 gen_perr(ra
, rb
, rc
, islit
, lit
);
2521 if (!(ctx
->amask
& AMASK_CIX
))
2523 if (likely(rc
!= 31)) {
2525 tcg_gen_movi_i64(cpu_ir
[rc
], clz64(lit
));
2527 gen_helper_ctlz(cpu_ir
[rc
], cpu_ir
[rb
]);
2532 if (!(ctx
->amask
& AMASK_CIX
))
2534 if (likely(rc
!= 31)) {
2536 tcg_gen_movi_i64(cpu_ir
[rc
], ctz64(lit
));
2538 gen_helper_cttz(cpu_ir
[rc
], cpu_ir
[rb
]);
2543 if (!(ctx
->amask
& AMASK_MVI
))
2545 if (real_islit
|| ra
!= 31)
2547 gen_unpkbw (rb
, rc
);
2551 if (!(ctx
->amask
& AMASK_MVI
))
2553 if (real_islit
|| ra
!= 31)
2555 gen_unpkbl (rb
, rc
);
2559 if (!(ctx
->amask
& AMASK_MVI
))
2561 if (real_islit
|| ra
!= 31)
2567 if (!(ctx
->amask
& AMASK_MVI
))
2569 if (real_islit
|| ra
!= 31)
2575 if (!(ctx
->amask
& AMASK_MVI
))
2577 gen_minsb8 (ra
, rb
, rc
, islit
, lit
);
2581 if (!(ctx
->amask
& AMASK_MVI
))
2583 gen_minsw4 (ra
, rb
, rc
, islit
, lit
);
2587 if (!(ctx
->amask
& AMASK_MVI
))
2589 gen_minub8 (ra
, rb
, rc
, islit
, lit
);
2593 if (!(ctx
->amask
& AMASK_MVI
))
2595 gen_minuw4 (ra
, rb
, rc
, islit
, lit
);
2599 if (!(ctx
->amask
& AMASK_MVI
))
2601 gen_maxub8 (ra
, rb
, rc
, islit
, lit
);
2605 if (!(ctx
->amask
& AMASK_MVI
))
2607 gen_maxuw4 (ra
, rb
, rc
, islit
, lit
);
2611 if (!(ctx
->amask
& AMASK_MVI
))
2613 gen_maxsb8 (ra
, rb
, rc
, islit
, lit
);
2617 if (!(ctx
->amask
& AMASK_MVI
))
2619 gen_maxsw4 (ra
, rb
, rc
, islit
, lit
);
2623 if (!(ctx
->amask
& AMASK_FIX
))
2625 if (likely(rc
!= 31)) {
2627 tcg_gen_mov_i64(cpu_ir
[rc
], cpu_fir
[ra
]);
2629 tcg_gen_movi_i64(cpu_ir
[rc
], 0);
2634 if (!(ctx
->amask
& AMASK_FIX
))
2637 TCGv_i32 tmp1
= tcg_temp_new_i32();
2639 gen_helper_s_to_memory(tmp1
, cpu_fir
[ra
]);
2641 TCGv tmp2
= tcg_const_i64(0);
2642 gen_helper_s_to_memory(tmp1
, tmp2
);
2643 tcg_temp_free(tmp2
);
2645 tcg_gen_ext_i32_i64(cpu_ir
[rc
], tmp1
);
2646 tcg_temp_free_i32(tmp1
);
2654 /* HW_MTPR (PALcode) */
2655 #if defined (CONFIG_USER_ONLY)
2661 TCGv tmp1
= tcg_const_i32(insn
& 0xFF);
2663 gen_helper_mtpr(tmp1
, cpu_ir
[ra
]);
2665 TCGv tmp2
= tcg_const_i64(0);
2666 gen_helper_mtpr(tmp1
, tmp2
);
2667 tcg_temp_free(tmp2
);
2669 tcg_temp_free(tmp1
);
2675 /* HW_REI (PALcode) */
2676 #if defined (CONFIG_USER_ONLY)
2683 gen_helper_hw_rei();
2688 tmp
= tcg_temp_new();
2689 tcg_gen_addi_i64(tmp
, cpu_ir
[rb
], (((int64_t)insn
<< 51) >> 51));
2691 tmp
= tcg_const_i64(((int64_t)insn
<< 51) >> 51);
2692 gen_helper_hw_ret(tmp
);
2699 /* HW_ST (PALcode) */
2700 #if defined (CONFIG_USER_ONLY)
2707 addr
= tcg_temp_new();
2709 tcg_gen_addi_i64(addr
, cpu_ir
[rb
], disp12
);
2711 tcg_gen_movi_i64(addr
, disp12
);
2715 val
= tcg_temp_new();
2716 tcg_gen_movi_i64(val
, 0);
2718 switch ((insn
>> 12) & 0xF) {
2720 /* Longword physical access */
2721 gen_helper_stl_raw(val
, addr
);
2724 /* Quadword physical access */
2725 gen_helper_stq_raw(val
, addr
);
2728 /* Longword physical access with lock */
2729 gen_helper_stl_c_raw(val
, val
, addr
);
2732 /* Quadword physical access with lock */
2733 gen_helper_stq_c_raw(val
, val
, addr
);
2736 /* Longword virtual access */
2737 gen_helper_st_virt_to_phys(addr
, addr
);
2738 gen_helper_stl_raw(val
, addr
);
2741 /* Quadword virtual access */
2742 gen_helper_st_virt_to_phys(addr
, addr
);
2743 gen_helper_stq_raw(val
, addr
);
2764 /* Longword virtual access with alternate access mode */
2765 gen_helper_set_alt_mode();
2766 gen_helper_st_virt_to_phys(addr
, addr
);
2767 gen_helper_stl_raw(val
, addr
);
2768 gen_helper_restore_mode();
2771 /* Quadword virtual access with alternate access mode */
2772 gen_helper_set_alt_mode();
2773 gen_helper_st_virt_to_phys(addr
, addr
);
2774 gen_helper_stl_raw(val
, addr
);
2775 gen_helper_restore_mode();
2786 tcg_temp_free(addr
);
2792 gen_load_mem(ctx
, &gen_qemu_ldf
, ra
, rb
, disp16
, 1, 0);
2796 gen_load_mem(ctx
, &gen_qemu_ldg
, ra
, rb
, disp16
, 1, 0);
2800 gen_load_mem(ctx
, &gen_qemu_lds
, ra
, rb
, disp16
, 1, 0);
2804 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 1, 0);
2808 gen_store_mem(ctx
, &gen_qemu_stf
, ra
, rb
, disp16
, 1, 0, 0);
2812 gen_store_mem(ctx
, &gen_qemu_stg
, ra
, rb
, disp16
, 1, 0, 0);
2816 gen_store_mem(ctx
, &gen_qemu_sts
, ra
, rb
, disp16
, 1, 0, 0);
2820 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 1, 0, 0);
2824 gen_load_mem(ctx
, &tcg_gen_qemu_ld32s
, ra
, rb
, disp16
, 0, 0);
2828 gen_load_mem(ctx
, &tcg_gen_qemu_ld64
, ra
, rb
, disp16
, 0, 0);
2832 gen_load_mem(ctx
, &gen_qemu_ldl_l
, ra
, rb
, disp16
, 0, 0);
2836 gen_load_mem(ctx
, &gen_qemu_ldq_l
, ra
, rb
, disp16
, 0, 0);
2840 gen_store_mem(ctx
, &tcg_gen_qemu_st32
, ra
, rb
, disp16
, 0, 0, 0);
2844 gen_store_mem(ctx
, &tcg_gen_qemu_st64
, ra
, rb
, disp16
, 0, 0, 0);
2848 gen_store_mem(ctx
, &gen_qemu_stl_c
, ra
, rb
, disp16
, 0, 0, 1);
2852 gen_store_mem(ctx
, &gen_qemu_stq_c
, ra
, rb
, disp16
, 0, 0, 1);
2857 tcg_gen_movi_i64(cpu_ir
[ra
], ctx
->pc
);
2858 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
+ (int64_t)(disp21
<< 2));
2861 case 0x31: /* FBEQ */
2862 gen_fbcond(ctx
, TCG_COND_EQ
, ra
, disp21
);
2865 case 0x32: /* FBLT */
2866 gen_fbcond(ctx
, TCG_COND_LT
, ra
, disp21
);
2869 case 0x33: /* FBLE */
2870 gen_fbcond(ctx
, TCG_COND_LE
, ra
, disp21
);
2876 tcg_gen_movi_i64(cpu_ir
[ra
], ctx
->pc
);
2877 tcg_gen_movi_i64(cpu_pc
, ctx
->pc
+ (int64_t)(disp21
<< 2));
2880 case 0x35: /* FBNE */
2881 gen_fbcond(ctx
, TCG_COND_NE
, ra
, disp21
);
2884 case 0x36: /* FBGE */
2885 gen_fbcond(ctx
, TCG_COND_GE
, ra
, disp21
);
2888 case 0x37: /* FBGT */
2889 gen_fbcond(ctx
, TCG_COND_GT
, ra
, disp21
);
2894 gen_bcond(ctx
, TCG_COND_EQ
, ra
, disp21
, 1);
2899 gen_bcond(ctx
, TCG_COND_EQ
, ra
, disp21
, 0);
2904 gen_bcond(ctx
, TCG_COND_LT
, ra
, disp21
, 0);
2909 gen_bcond(ctx
, TCG_COND_LE
, ra
, disp21
, 0);
2914 gen_bcond(ctx
, TCG_COND_NE
, ra
, disp21
, 1);
2919 gen_bcond(ctx
, TCG_COND_NE
, ra
, disp21
, 0);
2924 gen_bcond(ctx
, TCG_COND_GE
, ra
, disp21
, 0);
2929 gen_bcond(ctx
, TCG_COND_GT
, ra
, disp21
, 0);
2941 static inline void gen_intermediate_code_internal(CPUState
*env
,
2942 TranslationBlock
*tb
,
2945 DisasContext ctx
, *ctxp
= &ctx
;
2946 target_ulong pc_start
;
2948 uint16_t *gen_opc_end
;
2956 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
2958 ctx
.amask
= env
->amask
;
2960 #if defined (CONFIG_USER_ONLY)
2963 ctx
.mem_idx
= ((env
->ps
>> 3) & 3);
2964 ctx
.pal_mode
= env
->ipr
[IPR_EXC_ADDR
] & 1;
2967 /* ??? Every TB begins with unset rounding mode, to be initialized on
2968 the first fp insn of the TB. Alternately we could define a proper
2969 default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
2970 to reset the FP_STATUS to that default at the end of any TB that
2971 changes the default. We could even (gasp) dynamiclly figure out
2972 what default would be most efficient given the running program. */
2974 /* Similarly for flush-to-zero. */
2978 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
2980 max_insns
= CF_COUNT_MASK
;
2983 for (ret
= 0; ret
== 0;) {
2984 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
2985 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
2986 if (bp
->pc
== ctx
.pc
) {
2987 gen_excp(&ctx
, EXCP_DEBUG
, 0);
2993 j
= gen_opc_ptr
- gen_opc_buf
;
2997 gen_opc_instr_start
[lj
++] = 0;
2999 gen_opc_pc
[lj
] = ctx
.pc
;
3000 gen_opc_instr_start
[lj
] = 1;
3001 gen_opc_icount
[lj
] = num_insns
;
3003 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
3005 insn
= ldl_code(ctx
.pc
);
3008 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
3009 tcg_gen_debug_insn_start(ctx
.pc
);
3013 ret
= translate_one(ctxp
, insn
);
3016 /* if we reach a page boundary or are single stepping, stop
3019 if (env
->singlestep_enabled
) {
3020 gen_excp(&ctx
, EXCP_DEBUG
, 0);
3024 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
3027 if (gen_opc_ptr
>= gen_opc_end
)
3030 if (num_insns
>= max_insns
)
3037 if (ret
!= 1 && ret
!= 3) {
3038 tcg_gen_movi_i64(cpu_pc
, ctx
.pc
);
3040 if (tb
->cflags
& CF_LAST_IO
)
3042 /* Generate the return instruction */
3044 gen_icount_end(tb
, num_insns
);
3045 *gen_opc_ptr
= INDEX_op_end
;
3047 j
= gen_opc_ptr
- gen_opc_buf
;
3050 gen_opc_instr_start
[lj
++] = 0;
3052 tb
->size
= ctx
.pc
- pc_start
;
3053 tb
->icount
= num_insns
;
3056 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
3057 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
3058 log_target_disas(pc_start
, ctx
.pc
- pc_start
, 1);
3064 void gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
3066 gen_intermediate_code_internal(env
, tb
, 0);
3069 void gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
3071 gen_intermediate_code_internal(env
, tb
, 1);
3079 static const struct cpu_def_t cpu_defs
[] = {
3080 { "ev4", IMPLVER_2106x
, 0 },
3081 { "ev5", IMPLVER_21164
, 0 },
3082 { "ev56", IMPLVER_21164
, AMASK_BWX
},
3083 { "pca56", IMPLVER_21164
, AMASK_BWX
| AMASK_MVI
},
3084 { "ev6", IMPLVER_21264
, AMASK_BWX
| AMASK_FIX
| AMASK_MVI
| AMASK_TRAP
},
3085 { "ev67", IMPLVER_21264
, (AMASK_BWX
| AMASK_FIX
| AMASK_CIX
3086 | AMASK_MVI
| AMASK_TRAP
| AMASK_PREFETCH
), },
3087 { "ev68", IMPLVER_21264
, (AMASK_BWX
| AMASK_FIX
| AMASK_CIX
3088 | AMASK_MVI
| AMASK_TRAP
| AMASK_PREFETCH
), },
3089 { "21064", IMPLVER_2106x
, 0 },
3090 { "21164", IMPLVER_21164
, 0 },
3091 { "21164a", IMPLVER_21164
, AMASK_BWX
},
3092 { "21164pc", IMPLVER_21164
, AMASK_BWX
| AMASK_MVI
},
3093 { "21264", IMPLVER_21264
, AMASK_BWX
| AMASK_FIX
| AMASK_MVI
| AMASK_TRAP
},
3094 { "21264a", IMPLVER_21264
, (AMASK_BWX
| AMASK_FIX
| AMASK_CIX
3095 | AMASK_MVI
| AMASK_TRAP
| AMASK_PREFETCH
), }
3098 CPUAlphaState
* cpu_alpha_init (const char *cpu_model
)
3101 int implver
, amask
, i
, max
;
3103 env
= qemu_mallocz(sizeof(CPUAlphaState
));
3105 alpha_translate_init();
3108 /* Default to ev67; no reason not to emulate insns by default. */
3109 implver
= IMPLVER_21264
;
3110 amask
= (AMASK_BWX
| AMASK_FIX
| AMASK_CIX
| AMASK_MVI
3111 | AMASK_TRAP
| AMASK_PREFETCH
);
3113 max
= ARRAY_SIZE(cpu_defs
);
3114 for (i
= 0; i
< max
; i
++) {
3115 if (strcmp (cpu_model
, cpu_defs
[i
].name
) == 0) {
3116 implver
= cpu_defs
[i
].implver
;
3117 amask
= cpu_defs
[i
].amask
;
3121 env
->implver
= implver
;
3125 #if defined (CONFIG_USER_ONLY)
3127 cpu_alpha_store_fpcr(env
, (FPCR_INVD
| FPCR_DZED
| FPCR_OVFD
3128 | FPCR_UNFD
| FPCR_INED
| FPCR_DNOD
));
3133 /* Initialize IPR */
3134 #if defined (CONFIG_USER_ONLY)
3135 env
->ipr
[IPR_EXC_ADDR
] = 0;
3136 env
->ipr
[IPR_EXC_SUM
] = 0;
3137 env
->ipr
[IPR_EXC_MASK
] = 0;
3141 // hwpcb = env->ipr[IPR_PCBB];
3142 env
->ipr
[IPR_ASN
] = 0;
3143 env
->ipr
[IPR_ASTEN
] = 0;
3144 env
->ipr
[IPR_ASTSR
] = 0;
3145 env
->ipr
[IPR_DATFX
] = 0;
3147 // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
3148 // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
3149 // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
3150 // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
3151 env
->ipr
[IPR_FEN
] = 0;
3152 env
->ipr
[IPR_IPL
] = 31;
3153 env
->ipr
[IPR_MCES
] = 0;
3154 env
->ipr
[IPR_PERFMON
] = 0; /* Implementation specific */
3155 // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
3156 env
->ipr
[IPR_SISR
] = 0;
3157 env
->ipr
[IPR_VIRBND
] = -1ULL;
3161 qemu_init_vcpu(env
);
3165 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
3166 unsigned long searched_pc
, int pc_pos
, void *puc
)
3168 env
->pc
= gen_opc_pc
[pc_pos
];