]>
git.proxmox.com Git - qemu.git/blob - target-cris/translate.c
2 * CRIS emulation for qemu: main translation routines.
4 * Copyright (c) 2008 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "crisv32-decode.h"
35 #include "qemu-common.h"
51 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52 #define BUG_ON(x) ({if (x) BUG();})
56 /* Used by the decoder. */
57 #define EXTRACT_FIELD(src, start, end) \
58 (((src) >> start) & ((1 << (end - start + 1)) - 1))
60 #define CC_MASK_NZ 0xc
61 #define CC_MASK_NZV 0xe
62 #define CC_MASK_NZVC 0xf
63 #define CC_MASK_RNZV 0x10e
76 /* This is the state at translation time. */
77 typedef struct DisasContext
{
79 target_ulong pc
, insn_pc
;
86 unsigned int zsize
, zzsize
;
97 uint32_t tb_entry_flags
;
99 int memidx
; /* user or kernel mode. */
108 struct TranslationBlock
*tb
;
109 int singlestep_enabled
;
112 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
);
113 static void gen_BUG(DisasContext
*dc
, char *file
, int line
)
115 printf ("BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
116 fprintf (logfile
, "BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
117 cpu_dump_state (dc
->env
, stdout
, fprintf
, 0);
119 cris_prepare_jmp (dc
, 0x70000000 + line
);
122 #ifdef CONFIG_USER_ONLY
123 #define GEN_OP_LD(width, reg) \
124 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
125 gen_op_ld##width##_T0_##reg##_raw(); \
127 #define GEN_OP_ST(width, reg) \
128 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
129 gen_op_st##width##_##reg##_T1_raw(); \
132 #define GEN_OP_LD(width, reg) \
133 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
134 if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
135 else gen_op_ld##width##_T0_##reg##_user();\
137 #define GEN_OP_ST(width, reg) \
138 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
139 if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
140 else gen_op_st##width##_##reg##_T1_user();\
153 const char *regnames
[] =
155 "$r0", "$r1", "$r2", "$r3",
156 "$r4", "$r5", "$r6", "$r7",
157 "$r8", "$r9", "$r10", "$r11",
158 "$r12", "$r13", "$sp", "$acr",
160 const char *pregnames
[] =
162 "$bz", "$vr", "$pid", "$srs",
163 "$wz", "$exs", "$eda", "$mof",
164 "$dz", "$ebp", "$erp", "$srp",
165 "$nrp", "$ccs", "$usp", "$spc",
168 /* We need this table to handle preg-moves with implicit width. */
180 #define t_gen_mov_TN_env(tn, member) \
181 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
182 #define t_gen_mov_env_TN(member, tn) \
183 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
185 #define t_gen_mov_TN_reg(tn, regno) \
186 tcg_gen_mov_tl(tn, cpu_R[regno])
187 #define t_gen_mov_reg_TN(regno, tn) \
188 tcg_gen_mov_tl(cpu_R[regno], tn)
190 static inline void _t_gen_mov_TN_env(TCGv tn
, int offset
)
192 tcg_gen_ld_tl(tn
, cpu_env
, offset
);
194 static inline void _t_gen_mov_env_TN(int offset
, TCGv tn
)
196 tcg_gen_st_tl(tn
, cpu_env
, offset
);
199 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
201 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
202 tcg_gen_mov_tl(tn
, tcg_const_tl(0));
204 tcg_gen_mov_tl(tn
, tcg_const_tl(32));
206 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
208 static inline void t_gen_mov_preg_TN(int r
, TCGv tn
)
210 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
213 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
216 static inline void t_gen_mov_TN_im(TCGv tn
, int32_t val
)
218 tcg_gen_movi_tl(tn
, val
);
221 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
225 l1
= gen_new_label();
226 /* Speculative shift. */
227 tcg_gen_shl_tl(d
, a
, b
);
228 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
229 /* Clear dst if shift operands were to large. */
230 tcg_gen_movi_tl(d
, 0);
234 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
238 l1
= gen_new_label();
239 /* Speculative shift. */
240 tcg_gen_shr_tl(d
, a
, b
);
241 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
242 /* Clear dst if shift operands were to large. */
243 tcg_gen_movi_tl(d
, 0);
247 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
251 l1
= gen_new_label();
252 /* Speculative shift. */
253 tcg_gen_sar_tl(d
, a
, b
);
254 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
255 /* Clear dst if shift operands were to large. */
256 tcg_gen_movi_tl(d
, 0);
257 tcg_gen_brcond_tl(TCG_COND_LT
, b
, tcg_const_tl(0x80000000), l1
);
258 tcg_gen_movi_tl(d
, 0xffffffff);
262 /* 64-bit signed mul, lower result in d and upper in d2. */
263 static void t_gen_muls(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
267 t0
= tcg_temp_new(TCG_TYPE_I64
);
268 t1
= tcg_temp_new(TCG_TYPE_I64
);
270 tcg_gen_ext32s_i64(t0
, a
);
271 tcg_gen_ext32s_i64(t1
, b
);
272 tcg_gen_mul_i64(t0
, t0
, t1
);
274 tcg_gen_trunc_i64_i32(d
, t0
);
275 tcg_gen_shri_i64(t0
, t0
, 32);
276 tcg_gen_trunc_i64_i32(d2
, t0
);
279 /* 64-bit unsigned muls, lower result in d and upper in d2. */
280 static void t_gen_mulu(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
284 t0
= tcg_temp_new(TCG_TYPE_I64
);
285 t1
= tcg_temp_new(TCG_TYPE_I64
);
287 tcg_gen_extu_i32_i64(t0
, a
);
288 tcg_gen_extu_i32_i64(t1
, b
);
289 tcg_gen_mul_i64(t0
, t0
, t1
);
291 tcg_gen_trunc_i64_i32(d
, t0
);
292 tcg_gen_shri_i64(t0
, t0
, 32);
293 tcg_gen_trunc_i64_i32(d2
, t0
);
296 /* Extended arithmetics on CRIS. */
297 static inline void t_gen_add_flag(TCGv d
, int flag
)
301 c
= tcg_temp_new(TCG_TYPE_TL
);
302 t_gen_mov_TN_preg(c
, PR_CCS
);
303 /* Propagate carry into d. */
304 tcg_gen_andi_tl(c
, c
, 1 << flag
);
306 tcg_gen_shri_tl(c
, c
, flag
);
307 tcg_gen_add_tl(d
, d
, c
);
310 static inline void t_gen_addx_carry(TCGv d
)
314 x
= tcg_temp_new(TCG_TYPE_TL
);
315 c
= tcg_temp_new(TCG_TYPE_TL
);
316 t_gen_mov_TN_preg(x
, PR_CCS
);
317 tcg_gen_mov_tl(c
, x
);
319 /* Propagate carry into d if X is set. Branch free. */
320 tcg_gen_andi_tl(c
, c
, C_FLAG
);
321 tcg_gen_andi_tl(x
, x
, X_FLAG
);
322 tcg_gen_shri_tl(x
, x
, 4);
324 tcg_gen_and_tl(x
, x
, c
);
325 tcg_gen_add_tl(d
, d
, x
);
328 static inline void t_gen_subx_carry(TCGv d
)
332 x
= tcg_temp_new(TCG_TYPE_TL
);
333 c
= tcg_temp_new(TCG_TYPE_TL
);
334 t_gen_mov_TN_preg(x
, PR_CCS
);
335 tcg_gen_mov_tl(c
, x
);
337 /* Propagate carry into d if X is set. Branch free. */
338 tcg_gen_andi_tl(c
, c
, C_FLAG
);
339 tcg_gen_andi_tl(x
, x
, X_FLAG
);
340 tcg_gen_shri_tl(x
, x
, 4);
342 tcg_gen_and_tl(x
, x
, c
);
343 tcg_gen_sub_tl(d
, d
, x
);
346 /* Swap the two bytes within each half word of the s operand.
347 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
348 static inline void t_gen_swapb(TCGv d
, TCGv s
)
352 t
= tcg_temp_new(TCG_TYPE_TL
);
353 org_s
= tcg_temp_new(TCG_TYPE_TL
);
355 /* d and s may refer to the same object. */
356 tcg_gen_mov_tl(org_s
, s
);
357 tcg_gen_shli_tl(t
, org_s
, 8);
358 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
359 tcg_gen_shri_tl(t
, org_s
, 8);
360 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
361 tcg_gen_or_tl(d
, d
, t
);
364 /* Swap the halfwords of the s operand. */
365 static inline void t_gen_swapw(TCGv d
, TCGv s
)
368 /* d and s refer the same object. */
369 t
= tcg_temp_new(TCG_TYPE_TL
);
370 tcg_gen_mov_tl(t
, s
);
371 tcg_gen_shli_tl(d
, t
, 16);
372 tcg_gen_shri_tl(t
, t
, 16);
373 tcg_gen_or_tl(d
, d
, t
);
376 /* Reverse the within each byte.
377 T0 = (((T0 << 7) & 0x80808080) |
378 ((T0 << 5) & 0x40404040) |
379 ((T0 << 3) & 0x20202020) |
380 ((T0 << 1) & 0x10101010) |
381 ((T0 >> 1) & 0x08080808) |
382 ((T0 >> 3) & 0x04040404) |
383 ((T0 >> 5) & 0x02020202) |
384 ((T0 >> 7) & 0x01010101));
386 static inline void t_gen_swapr(TCGv d
, TCGv s
)
389 int shift
; /* LSL when positive, LSR when negative. */
404 /* d and s refer the same object. */
405 t
= tcg_temp_new(TCG_TYPE_TL
);
406 org_s
= tcg_temp_new(TCG_TYPE_TL
);
407 tcg_gen_mov_tl(org_s
, s
);
409 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
410 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
411 for (i
= 1; i
< sizeof bitrev
/ sizeof bitrev
[0]; i
++) {
412 if (bitrev
[i
].shift
>= 0) {
413 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
415 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
417 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
418 tcg_gen_or_tl(d
, d
, t
);
422 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
424 TranslationBlock
*tb
;
426 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
428 tcg_gen_movi_tl(cpu_T
[0], dest
);
429 t_gen_mov_env_TN(pc
, cpu_T
[0]);
430 tcg_gen_exit_tb((long)tb
+ n
);
432 t_gen_mov_env_TN(pc
, cpu_T
[0]);
437 /* Sign extend at translation time. */
438 static int sign_extend(unsigned int val
, unsigned int width
)
450 static inline void cris_clear_x_flag(DisasContext
*dc
)
452 if (!dc
->flagx_live
|| dc
->cc_op
!= CC_OP_FLAGS
) {
453 t_gen_mov_TN_preg(cpu_T
[0], PR_CCS
);
454 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], ~X_FLAG
);
455 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
461 static void cris_evaluate_flags(DisasContext
*dc
)
463 if (!dc
->flags_live
) {
467 gen_op_evaluate_flags_mcp ();
470 gen_op_evaluate_flags_muls ();
473 gen_op_evaluate_flags_mulu ();
479 gen_op_evaluate_flags_move_4();
482 gen_op_evaluate_flags_move_2();
485 gen_op_evaluate_flags ();
495 gen_op_evaluate_flags_alu_4 ();
498 gen_op_evaluate_flags ();
508 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
512 /* Check if we need to evaluate the condition codes due to
514 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
516 /* TODO: optimize this case. It trigs all the time. */
517 cris_evaluate_flags (dc
);
528 static void cris_update_cc_op(DisasContext
*dc
, int op
)
532 tcg_gen_movi_tl(cc_op
, op
);
534 static void cris_update_cc_size(DisasContext
*dc
, int size
)
537 tcg_gen_movi_tl(cc_size
, size
);
540 /* op is the operation.
541 T0, T1 are the operands.
542 dst is the destination reg.
544 static void crisv32_alu_op(DisasContext
*dc
, int op
, int rd
, int size
)
548 cris_update_cc_op(dc
, op
);
549 cris_update_cc_size(dc
, size
);
550 tcg_gen_mov_tl(cc_dest
, cpu_T
[0]);
551 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
553 /* FIXME: This shouldn't be needed. But we don't pass the
554 tests without it. Investigate. */
555 t_gen_mov_env_TN(cc_x_live
, tcg_const_tl(dc
->flagx_live
));
556 t_gen_mov_env_TN(cc_x
, tcg_const_tl(dc
->flags_x
));
559 /* Emit the ALU insns. */
563 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
564 /* Extended arithmetics. */
565 t_gen_addx_carry(cpu_T
[0]);
568 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
569 t_gen_add_flag(cpu_T
[0], 0); /* C_FLAG. */
572 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
573 t_gen_add_flag(cpu_T
[0], 8); /* R_FLAG. */
576 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
577 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
578 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
579 /* CRIS flag evaluation needs ~src. */
580 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
582 /* Extended arithmetics. */
583 t_gen_subx_carry(cpu_T
[0]);
586 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
589 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
592 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
595 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
598 t_gen_lsl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
601 t_gen_lsr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
604 t_gen_asr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
607 /* Hopefully the TCG backend recognizes this pattern
608 and makes a real neg out of it. */
609 tcg_gen_sub_tl(cpu_T
[0], tcg_const_tl(0), cpu_T
[1]);
610 /* Extended arithmetics. */
611 t_gen_subx_carry(cpu_T
[0]);
623 mof
= tcg_temp_new(TCG_TYPE_TL
);
624 t_gen_muls(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
625 t_gen_mov_preg_TN(PR_MOF
, mof
);
631 mof
= tcg_temp_new(TCG_TYPE_TL
);
632 t_gen_mulu(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
633 t_gen_mov_preg_TN(PR_MOF
, mof
);
637 gen_op_dstep_T0_T1();
642 l1
= gen_new_label();
643 tcg_gen_brcond_tl(TCG_COND_LEU
,
644 cpu_T
[0], cpu_T
[1], l1
);
645 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
650 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
651 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
652 /* CRIS flag evaluation needs ~src. */
653 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
654 /* CRIS flag evaluation needs ~src. */
655 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
657 /* Extended arithmetics. */
658 t_gen_subx_carry(cpu_T
[0]);
662 fprintf (logfile
, "illegal ALU op.\n");
668 tcg_gen_mov_tl(cc_src
, cpu_T
[1]);
671 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
673 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
678 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
680 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
681 t_gen_mov_TN_reg(cpu_T
[0], rd
);
683 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xff);
685 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xffff);
686 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
687 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
688 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
692 tcg_gen_mov_tl(cc_result
, cpu_T
[0]);
695 /* TODO: Optimize this. */
697 cris_evaluate_flags(dc
);
701 static int arith_cc(DisasContext
*dc
)
705 case CC_OP_ADD
: return 1;
706 case CC_OP_SUB
: return 1;
707 case CC_OP_LSL
: return 1;
708 case CC_OP_LSR
: return 1;
709 case CC_OP_ASR
: return 1;
710 case CC_OP_CMP
: return 1;
718 static void gen_tst_cc (DisasContext
*dc
, int cond
)
722 /* TODO: optimize more condition codes. */
723 arith_opt
= arith_cc(dc
) && !dc
->flags_live
;
727 gen_op_tst_cc_eq_fast ();
729 cris_evaluate_flags(dc
);
735 gen_op_tst_cc_ne_fast ();
737 cris_evaluate_flags(dc
);
742 cris_evaluate_flags(dc
);
746 cris_evaluate_flags(dc
);
750 cris_evaluate_flags(dc
);
754 cris_evaluate_flags(dc
);
759 gen_op_tst_cc_pl_fast ();
761 cris_evaluate_flags(dc
);
767 gen_op_tst_cc_mi_fast ();
769 cris_evaluate_flags(dc
);
774 cris_evaluate_flags(dc
);
778 cris_evaluate_flags(dc
);
782 cris_evaluate_flags(dc
);
786 cris_evaluate_flags(dc
);
790 cris_evaluate_flags(dc
);
794 cris_evaluate_flags(dc
);
798 cris_evaluate_flags(dc
);
802 cris_evaluate_flags(dc
);
803 gen_op_movl_T0_im (1);
811 static void cris_prepare_cc_branch (DisasContext
*dc
, int offset
, int cond
)
813 /* This helps us re-schedule the micro-code to insns in delay-slots
814 before the actual jump. */
815 dc
->delayed_branch
= 2;
816 dc
->delayed_pc
= dc
->pc
+ offset
;
820 gen_tst_cc (dc
, cond
);
821 gen_op_evaluate_bcc ();
823 tcg_gen_movi_tl(cpu_T
[0], dc
->delayed_pc
);
824 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
827 /* Dynamic jumps, when the dest is in a live reg for example. */
828 void cris_prepare_dyn_jmp (DisasContext
*dc
)
830 /* This helps us re-schedule the micro-code to insns in delay-slots
831 before the actual jump. */
832 dc
->delayed_branch
= 2;
837 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
)
839 /* This helps us re-schedule the micro-code to insns in delay-slots
840 before the actual jump. */
841 dc
->delayed_branch
= 2;
842 dc
->delayed_pc
= dst
;
847 void gen_load_T0_T0 (DisasContext
*dc
, unsigned int size
, int sign
)
851 gen_op_ldb_T0_T0(dc
);
853 gen_op_ldub_T0_T0(dc
);
855 else if (size
== 2) {
857 gen_op_ldw_T0_T0(dc
);
859 gen_op_lduw_T0_T0(dc
);
862 gen_op_ldl_T0_T0(dc
);
866 void gen_store_T0_T1 (DisasContext
*dc
, unsigned int size
)
868 /* Remember, operands are flipped. CRIS has reversed order. */
870 gen_op_stb_T0_T1(dc
);
872 else if (size
== 2) {
873 gen_op_stw_T0_T1(dc
);
876 gen_op_stl_T0_T1(dc
);
879 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
882 tcg_gen_ext8s_i32(d
, s
);
884 tcg_gen_ext16s_i32(d
, s
);
887 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
889 /* TCG-FIXME: this is not optimal. Many archs have fast zext insns. */
891 tcg_gen_andi_i32(d
, s
, 0xff);
893 tcg_gen_andi_i32(d
, s
, 0xffff);
897 static char memsize_char(int size
)
901 case 1: return 'b'; break;
902 case 2: return 'w'; break;
903 case 4: return 'd'; break;
911 static unsigned int memsize_z(DisasContext
*dc
)
913 return dc
->zsize
+ 1;
916 static unsigned int memsize_zz(DisasContext
*dc
)
927 static void do_postinc (DisasContext
*dc
, int size
)
931 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
932 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], size
);
933 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
937 static void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
940 t_gen_mov_TN_reg(cpu_T
[1], rs
);
942 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
944 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
947 /* Prepare T0 and T1 for a register alu operation.
948 s_ext decides if the operand1 should be sign-extended or zero-extended when
950 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
953 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
);
955 t_gen_mov_TN_reg(cpu_T
[0], rd
);
957 t_gen_sext(cpu_T
[0], cpu_T
[0], size
);
959 t_gen_zext(cpu_T
[0], cpu_T
[0], size
);
962 /* Prepare T0 and T1 for a memory + alu operation.
963 s_ext decides if the operand1 should be sign-extended or zero-extended when
965 static int dec_prep_alu_m(DisasContext
*dc
, int s_ext
, int memsize
)
974 is_imm
= rs
== 15 && dc
->postinc
;
976 /* Load [$rs] onto T1. */
978 insn_len
= 2 + memsize
;
982 imm
= ldl_code(dc
->pc
+ 2);
985 imm
= sign_extend(imm
, (memsize
* 8) - 1);
993 DIS(fprintf (logfile
, "imm=%x rd=%d sext=%d ms=%d\n",
994 imm
, rd
, s_ext
, memsize
));
995 tcg_gen_movi_tl(cpu_T
[1], imm
);
998 t_gen_mov_TN_reg(cpu_T
[0], rs
);
999 gen_load_T0_T0(dc
, memsize
, 0);
1000 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1002 t_gen_sext(cpu_T
[1], cpu_T
[1], memsize
);
1004 t_gen_zext(cpu_T
[1], cpu_T
[1], memsize
);
1007 /* put dest in T0. */
1008 t_gen_mov_TN_reg(cpu_T
[0], rd
);
1013 static const char *cc_name(int cc
)
1015 static char *cc_names
[16] = {
1016 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1017 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1020 return cc_names
[cc
];
1024 static unsigned int dec_bccq(DisasContext
*dc
)
1028 uint32_t cond
= dc
->op2
;
1031 offset
= EXTRACT_FIELD (dc
->ir
, 1, 7);
1032 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1035 offset
|= sign
<< 8;
1037 offset
= sign_extend(offset
, 8);
1039 /* op2 holds the condition-code. */
1040 cris_cc_mask(dc
, 0);
1041 cris_prepare_cc_branch (dc
, offset
, cond
);
1044 static unsigned int dec_addoq(DisasContext
*dc
)
1048 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1049 imm
= sign_extend(dc
->op1
, 7);
1051 DIS(fprintf (logfile
, "addoq %d, $r%u\n", imm
, dc
->op2
));
1052 cris_cc_mask(dc
, 0);
1053 /* Fetch register operand, */
1054 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1055 tcg_gen_movi_tl(cpu_T
[1], imm
);
1056 crisv32_alu_op(dc
, CC_OP_ADD
, R_ACR
, 4);
1059 static unsigned int dec_addq(DisasContext
*dc
)
1061 DIS(fprintf (logfile
, "addq %u, $r%u\n", dc
->op1
, dc
->op2
));
1063 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1065 cris_cc_mask(dc
, CC_MASK_NZVC
);
1066 /* Fetch register operand, */
1067 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1068 tcg_gen_movi_tl(cpu_T
[1], dc
->op1
);
1069 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1072 static unsigned int dec_moveq(DisasContext
*dc
)
1076 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1077 imm
= sign_extend(dc
->op1
, 5);
1078 DIS(fprintf (logfile
, "moveq %d, $r%u\n", imm
, dc
->op2
));
1080 t_gen_mov_reg_TN(dc
->op2
, tcg_const_tl(imm
));
1083 static unsigned int dec_subq(DisasContext
*dc
)
1085 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1087 DIS(fprintf (logfile
, "subq %u, $r%u\n", dc
->op1
, dc
->op2
));
1089 cris_cc_mask(dc
, CC_MASK_NZVC
);
1090 /* Fetch register operand, */
1091 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1092 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1093 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1096 static unsigned int dec_cmpq(DisasContext
*dc
)
1099 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1100 imm
= sign_extend(dc
->op1
, 5);
1102 DIS(fprintf (logfile
, "cmpq %d, $r%d\n", imm
, dc
->op2
));
1103 cris_cc_mask(dc
, CC_MASK_NZVC
);
1104 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1105 t_gen_mov_TN_im(cpu_T
[1], imm
);
1106 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1109 static unsigned int dec_andq(DisasContext
*dc
)
1112 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1113 imm
= sign_extend(dc
->op1
, 5);
1115 DIS(fprintf (logfile
, "andq %d, $r%d\n", imm
, dc
->op2
));
1116 cris_cc_mask(dc
, CC_MASK_NZ
);
1117 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1118 t_gen_mov_TN_im(cpu_T
[1], imm
);
1119 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, 4);
1122 static unsigned int dec_orq(DisasContext
*dc
)
1125 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1126 imm
= sign_extend(dc
->op1
, 5);
1127 DIS(fprintf (logfile
, "orq %d, $r%d\n", imm
, dc
->op2
));
1128 cris_cc_mask(dc
, CC_MASK_NZ
);
1129 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1130 t_gen_mov_TN_im(cpu_T
[1], imm
);
1131 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, 4);
1134 static unsigned int dec_btstq(DisasContext
*dc
)
1136 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1137 DIS(fprintf (logfile
, "btstq %u, $r%d\n", dc
->op1
, dc
->op2
));
1138 cris_cc_mask(dc
, CC_MASK_NZ
);
1139 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1140 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1141 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1143 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1144 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1148 static unsigned int dec_asrq(DisasContext
*dc
)
1150 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1151 DIS(fprintf (logfile
, "asrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1152 cris_cc_mask(dc
, CC_MASK_NZ
);
1153 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1154 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1155 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, 4);
1158 static unsigned int dec_lslq(DisasContext
*dc
)
1160 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1161 DIS(fprintf (logfile
, "lslq %u, $r%d\n", dc
->op1
, dc
->op2
));
1163 cris_cc_mask(dc
, CC_MASK_NZ
);
1164 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1165 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1166 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, 4);
1169 static unsigned int dec_lsrq(DisasContext
*dc
)
1171 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1172 DIS(fprintf (logfile
, "lsrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1174 cris_cc_mask(dc
, CC_MASK_NZ
);
1175 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1176 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1177 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, 4);
1181 static unsigned int dec_move_r(DisasContext
*dc
)
1183 int size
= memsize_zz(dc
);
1185 DIS(fprintf (logfile
, "move.%c $r%u, $r%u\n",
1186 memsize_char(size
), dc
->op1
, dc
->op2
));
1188 cris_cc_mask(dc
, CC_MASK_NZ
);
1189 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1190 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, size
);
1194 static unsigned int dec_scc_r(DisasContext
*dc
)
1198 DIS(fprintf (logfile
, "s%s $r%u\n",
1199 cc_name(cond
), dc
->op1
));
1203 gen_tst_cc (dc
, cond
);
1204 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1207 tcg_gen_movi_tl(cpu_T
[1], 1);
1209 cris_cc_mask(dc
, 0);
1210 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1214 static unsigned int dec_and_r(DisasContext
*dc
)
1216 int size
= memsize_zz(dc
);
1218 DIS(fprintf (logfile
, "and.%c $r%u, $r%u\n",
1219 memsize_char(size
), dc
->op1
, dc
->op2
));
1220 cris_cc_mask(dc
, CC_MASK_NZ
);
1221 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1222 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, size
);
1226 static unsigned int dec_lz_r(DisasContext
*dc
)
1228 DIS(fprintf (logfile
, "lz $r%u, $r%u\n",
1230 cris_cc_mask(dc
, CC_MASK_NZ
);
1231 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1232 crisv32_alu_op(dc
, CC_OP_LZ
, dc
->op2
, 4);
1236 static unsigned int dec_lsl_r(DisasContext
*dc
)
1238 int size
= memsize_zz(dc
);
1240 DIS(fprintf (logfile
, "lsl.%c $r%u, $r%u\n",
1241 memsize_char(size
), dc
->op1
, dc
->op2
));
1242 cris_cc_mask(dc
, CC_MASK_NZ
);
1243 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1244 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1245 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, size
);
1249 static unsigned int dec_lsr_r(DisasContext
*dc
)
1251 int size
= memsize_zz(dc
);
1253 DIS(fprintf (logfile
, "lsr.%c $r%u, $r%u\n",
1254 memsize_char(size
), dc
->op1
, dc
->op2
));
1255 cris_cc_mask(dc
, CC_MASK_NZ
);
1256 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1257 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1258 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, size
);
1262 static unsigned int dec_asr_r(DisasContext
*dc
)
1264 int size
= memsize_zz(dc
);
1266 DIS(fprintf (logfile
, "asr.%c $r%u, $r%u\n",
1267 memsize_char(size
), dc
->op1
, dc
->op2
));
1268 cris_cc_mask(dc
, CC_MASK_NZ
);
1269 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1270 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1271 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, size
);
1275 static unsigned int dec_muls_r(DisasContext
*dc
)
1277 int size
= memsize_zz(dc
);
1279 DIS(fprintf (logfile
, "muls.%c $r%u, $r%u\n",
1280 memsize_char(size
), dc
->op1
, dc
->op2
));
1281 cris_cc_mask(dc
, CC_MASK_NZV
);
1282 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1283 t_gen_sext(cpu_T
[0], cpu_T
[0], size
);
1284 crisv32_alu_op(dc
, CC_OP_MULS
, dc
->op2
, 4);
1288 static unsigned int dec_mulu_r(DisasContext
*dc
)
1290 int size
= memsize_zz(dc
);
1292 DIS(fprintf (logfile
, "mulu.%c $r%u, $r%u\n",
1293 memsize_char(size
), dc
->op1
, dc
->op2
));
1294 cris_cc_mask(dc
, CC_MASK_NZV
);
1295 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1296 t_gen_zext(cpu_T
[0], cpu_T
[0], size
);
1297 crisv32_alu_op(dc
, CC_OP_MULU
, dc
->op2
, 4);
1302 static unsigned int dec_dstep_r(DisasContext
*dc
)
1304 DIS(fprintf (logfile
, "dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
));
1305 cris_cc_mask(dc
, CC_MASK_NZ
);
1306 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1307 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1308 crisv32_alu_op(dc
, CC_OP_DSTEP
, dc
->op2
, 4);
1312 static unsigned int dec_xor_r(DisasContext
*dc
)
1314 int size
= memsize_zz(dc
);
1315 DIS(fprintf (logfile
, "xor.%c $r%u, $r%u\n",
1316 memsize_char(size
), dc
->op1
, dc
->op2
));
1317 BUG_ON(size
!= 4); /* xor is dword. */
1318 cris_cc_mask(dc
, CC_MASK_NZ
);
1319 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1320 crisv32_alu_op(dc
, CC_OP_XOR
, dc
->op2
, 4);
1324 static unsigned int dec_bound_r(DisasContext
*dc
)
1326 int size
= memsize_zz(dc
);
1327 DIS(fprintf (logfile
, "bound.%c $r%u, $r%u\n",
1328 memsize_char(size
), dc
->op1
, dc
->op2
));
1329 cris_cc_mask(dc
, CC_MASK_NZ
);
1330 /* TODO: needs optmimization. */
1331 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1332 /* rd should be 4. */
1333 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1334 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1338 static unsigned int dec_cmp_r(DisasContext
*dc
)
1340 int size
= memsize_zz(dc
);
1341 DIS(fprintf (logfile
, "cmp.%c $r%u, $r%u\n",
1342 memsize_char(size
), dc
->op1
, dc
->op2
));
1343 cris_cc_mask(dc
, CC_MASK_NZVC
);
1344 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1345 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, size
);
1349 static unsigned int dec_abs_r(DisasContext
*dc
)
1353 DIS(fprintf (logfile
, "abs $r%u, $r%u\n",
1355 cris_cc_mask(dc
, CC_MASK_NZ
);
1356 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1358 /* TODO: consider a branch free approach. */
1359 l1
= gen_new_label();
1360 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_T
[1], tcg_const_tl(0), l1
);
1361 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
1363 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1367 static unsigned int dec_add_r(DisasContext
*dc
)
1369 int size
= memsize_zz(dc
);
1370 DIS(fprintf (logfile
, "add.%c $r%u, $r%u\n",
1371 memsize_char(size
), dc
->op1
, dc
->op2
));
1372 cris_cc_mask(dc
, CC_MASK_NZVC
);
1373 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1374 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, size
);
1378 static unsigned int dec_addc_r(DisasContext
*dc
)
1380 DIS(fprintf (logfile
, "addc $r%u, $r%u\n",
1382 cris_evaluate_flags(dc
);
1383 cris_cc_mask(dc
, CC_MASK_NZVC
);
1384 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1385 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1389 static unsigned int dec_mcp_r(DisasContext
*dc
)
1391 DIS(fprintf (logfile
, "mcp $p%u, $r%u\n",
1393 cris_evaluate_flags(dc
);
1394 cris_cc_mask(dc
, CC_MASK_RNZV
);
1395 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1396 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1397 crisv32_alu_op(dc
, CC_OP_MCP
, dc
->op1
, 4);
1402 static char * swapmode_name(int mode
, char *modename
) {
1405 modename
[i
++] = 'n';
1407 modename
[i
++] = 'w';
1409 modename
[i
++] = 'b';
1411 modename
[i
++] = 'r';
1417 static unsigned int dec_swap_r(DisasContext
*dc
)
1419 DIS(char modename
[4]);
1420 DIS(fprintf (logfile
, "swap%s $r%u\n",
1421 swapmode_name(dc
->op2
, modename
), dc
->op1
));
1423 cris_cc_mask(dc
, CC_MASK_NZ
);
1424 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1426 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], -1);
1428 t_gen_swapw(cpu_T
[0], cpu_T
[0]);
1430 t_gen_swapb(cpu_T
[0], cpu_T
[0]);
1432 t_gen_swapr(cpu_T
[0], cpu_T
[0]);
1433 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1434 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1438 static unsigned int dec_or_r(DisasContext
*dc
)
1440 int size
= memsize_zz(dc
);
1441 DIS(fprintf (logfile
, "or.%c $r%u, $r%u\n",
1442 memsize_char(size
), dc
->op1
, dc
->op2
));
1443 cris_cc_mask(dc
, CC_MASK_NZ
);
1444 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1445 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, size
);
1449 static unsigned int dec_addi_r(DisasContext
*dc
)
1451 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u\n",
1452 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1453 cris_cc_mask(dc
, 0);
1454 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1455 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1456 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1457 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
1461 static unsigned int dec_addi_acr(DisasContext
*dc
)
1463 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u, $acr\n",
1464 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1465 cris_cc_mask(dc
, 0);
1466 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1467 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1469 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1470 t_gen_mov_reg_TN(R_ACR
, cpu_T
[0]);
1474 static unsigned int dec_neg_r(DisasContext
*dc
)
1476 int size
= memsize_zz(dc
);
1477 DIS(fprintf (logfile
, "neg.%c $r%u, $r%u\n",
1478 memsize_char(size
), dc
->op1
, dc
->op2
));
1479 cris_cc_mask(dc
, CC_MASK_NZVC
);
1480 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1481 crisv32_alu_op(dc
, CC_OP_NEG
, dc
->op2
, size
);
1485 static unsigned int dec_btst_r(DisasContext
*dc
)
1487 DIS(fprintf (logfile
, "btst $r%u, $r%u\n",
1489 cris_cc_mask(dc
, CC_MASK_NZ
);
1490 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1491 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1493 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1494 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1499 static unsigned int dec_sub_r(DisasContext
*dc
)
1501 int size
= memsize_zz(dc
);
1502 DIS(fprintf (logfile
, "sub.%c $r%u, $r%u\n",
1503 memsize_char(size
), dc
->op1
, dc
->op2
));
1504 cris_cc_mask(dc
, CC_MASK_NZVC
);
1505 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1506 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, size
);
1510 /* Zero extension. From size to dword. */
1511 static unsigned int dec_movu_r(DisasContext
*dc
)
1513 int size
= memsize_z(dc
);
1514 DIS(fprintf (logfile
, "movu.%c $r%u, $r%u\n",
1518 cris_cc_mask(dc
, CC_MASK_NZ
);
1519 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1520 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1524 /* Sign extension. From size to dword. */
1525 static unsigned int dec_movs_r(DisasContext
*dc
)
1527 int size
= memsize_z(dc
);
1528 DIS(fprintf (logfile
, "movs.%c $r%u, $r%u\n",
1532 cris_cc_mask(dc
, CC_MASK_NZ
);
1533 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1534 /* Size can only be qi or hi. */
1535 t_gen_sext(cpu_T
[1], cpu_T
[0], size
);
1536 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1540 /* zero extension. From size to dword. */
1541 static unsigned int dec_addu_r(DisasContext
*dc
)
1543 int size
= memsize_z(dc
);
1544 DIS(fprintf (logfile
, "addu.%c $r%u, $r%u\n",
1548 cris_cc_mask(dc
, CC_MASK_NZVC
);
1549 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1550 /* Size can only be qi or hi. */
1551 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1552 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1553 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1557 /* Sign extension. From size to dword. */
1558 static unsigned int dec_adds_r(DisasContext
*dc
)
1560 int size
= memsize_z(dc
);
1561 DIS(fprintf (logfile
, "adds.%c $r%u, $r%u\n",
1565 cris_cc_mask(dc
, CC_MASK_NZVC
);
1566 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1567 /* Size can only be qi or hi. */
1568 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1569 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1571 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1575 /* Zero extension. From size to dword. */
1576 static unsigned int dec_subu_r(DisasContext
*dc
)
1578 int size
= memsize_z(dc
);
1579 DIS(fprintf (logfile
, "subu.%c $r%u, $r%u\n",
1583 cris_cc_mask(dc
, CC_MASK_NZVC
);
1584 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1585 /* Size can only be qi or hi. */
1586 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1587 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1588 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1592 /* Sign extension. From size to dword. */
1593 static unsigned int dec_subs_r(DisasContext
*dc
)
1595 int size
= memsize_z(dc
);
1596 DIS(fprintf (logfile
, "subs.%c $r%u, $r%u\n",
1600 cris_cc_mask(dc
, CC_MASK_NZVC
);
1601 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1602 /* Size can only be qi or hi. */
1603 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1604 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1605 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1609 static unsigned int dec_setclrf(DisasContext
*dc
)
1612 int set
= (~dc
->opcode
>> 2) & 1;
1614 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1615 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1616 DIS(fprintf (logfile
, "set=%d flags=%x\n", set
, flags
));
1617 if (set
&& flags
== 0)
1618 DIS(fprintf (logfile
, "nop\n"));
1619 else if (!set
&& (flags
& 0x20))
1620 DIS(fprintf (logfile
, "di\n"));
1622 DIS(fprintf (logfile
, "%sf %x\n",
1623 set
? "set" : "clr",
1626 if (set
&& (flags
& X_FLAG
)) {
1631 /* Simply decode the flags. */
1632 cris_evaluate_flags (dc
);
1633 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1642 static unsigned int dec_move_rs(DisasContext
*dc
)
1644 DIS(fprintf (logfile
, "move $r%u, $s%u\n", dc
->op1
, dc
->op2
));
1645 cris_cc_mask(dc
, 0);
1646 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1647 gen_op_movl_sreg_T0(dc
->op2
);
1649 #if !defined(CONFIG_USER_ONLY)
1651 gen_op_movl_tlb_hi_T0();
1652 else if (dc
->op2
== 5) { /* srs is checked at runtime. */
1653 tcg_gen_helper_0_1(helper_tlb_update
, cpu_T
[0]);
1654 gen_op_movl_tlb_lo_T0();
1659 static unsigned int dec_move_sr(DisasContext
*dc
)
1661 DIS(fprintf (logfile
, "move $s%u, $r%u\n", dc
->op2
, dc
->op1
));
1662 cris_cc_mask(dc
, 0);
1663 gen_op_movl_T0_sreg(dc
->op2
);
1664 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1665 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1668 static unsigned int dec_move_rp(DisasContext
*dc
)
1670 DIS(fprintf (logfile
, "move $r%u, $p%u\n", dc
->op1
, dc
->op2
));
1671 cris_cc_mask(dc
, 0);
1672 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1673 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
1676 static unsigned int dec_move_pr(DisasContext
*dc
)
1678 DIS(fprintf (logfile
, "move $p%u, $r%u\n", dc
->op1
, dc
->op2
));
1679 cris_cc_mask(dc
, 0);
1680 /* Support register 0 is hardwired to zero.
1681 Treat it specially. */
1683 tcg_gen_movi_tl(cpu_T
[1], 0);
1685 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1686 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, preg_sizes
[dc
->op2
]);
1690 static unsigned int dec_move_mr(DisasContext
*dc
)
1692 int memsize
= memsize_zz(dc
);
1694 DIS(fprintf (logfile
, "move.%c [$r%u%s, $r%u\n",
1695 memsize_char(memsize
),
1696 dc
->op1
, dc
->postinc
? "+]" : "]",
1699 cris_cc_mask(dc
, CC_MASK_NZ
);
1700 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1701 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, memsize
);
1702 do_postinc(dc
, memsize
);
1706 static unsigned int dec_movs_m(DisasContext
*dc
)
1708 int memsize
= memsize_z(dc
);
1710 DIS(fprintf (logfile
, "movs.%c [$r%u%s, $r%u\n",
1711 memsize_char(memsize
),
1712 dc
->op1
, dc
->postinc
? "+]" : "]",
1716 cris_cc_mask(dc
, CC_MASK_NZ
);
1717 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1718 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1719 do_postinc(dc
, memsize
);
1723 static unsigned int dec_addu_m(DisasContext
*dc
)
1725 int memsize
= memsize_z(dc
);
1727 DIS(fprintf (logfile
, "addu.%c [$r%u%s, $r%u\n",
1728 memsize_char(memsize
),
1729 dc
->op1
, dc
->postinc
? "+]" : "]",
1733 cris_cc_mask(dc
, CC_MASK_NZVC
);
1734 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1735 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1736 do_postinc(dc
, memsize
);
1740 static unsigned int dec_adds_m(DisasContext
*dc
)
1742 int memsize
= memsize_z(dc
);
1744 DIS(fprintf (logfile
, "adds.%c [$r%u%s, $r%u\n",
1745 memsize_char(memsize
),
1746 dc
->op1
, dc
->postinc
? "+]" : "]",
1750 cris_cc_mask(dc
, CC_MASK_NZVC
);
1751 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1752 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1753 do_postinc(dc
, memsize
);
1757 static unsigned int dec_subu_m(DisasContext
*dc
)
1759 int memsize
= memsize_z(dc
);
1761 DIS(fprintf (logfile
, "subu.%c [$r%u%s, $r%u\n",
1762 memsize_char(memsize
),
1763 dc
->op1
, dc
->postinc
? "+]" : "]",
1767 cris_cc_mask(dc
, CC_MASK_NZVC
);
1768 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1769 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1770 do_postinc(dc
, memsize
);
1774 static unsigned int dec_subs_m(DisasContext
*dc
)
1776 int memsize
= memsize_z(dc
);
1778 DIS(fprintf (logfile
, "subs.%c [$r%u%s, $r%u\n",
1779 memsize_char(memsize
),
1780 dc
->op1
, dc
->postinc
? "+]" : "]",
1784 cris_cc_mask(dc
, CC_MASK_NZVC
);
1785 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1786 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1787 do_postinc(dc
, memsize
);
1791 static unsigned int dec_movu_m(DisasContext
*dc
)
1793 int memsize
= memsize_z(dc
);
1796 DIS(fprintf (logfile
, "movu.%c [$r%u%s, $r%u\n",
1797 memsize_char(memsize
),
1798 dc
->op1
, dc
->postinc
? "+]" : "]",
1801 cris_cc_mask(dc
, CC_MASK_NZ
);
1802 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1803 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1804 do_postinc(dc
, memsize
);
1808 static unsigned int dec_cmpu_m(DisasContext
*dc
)
1810 int memsize
= memsize_z(dc
);
1812 DIS(fprintf (logfile
, "cmpu.%c [$r%u%s, $r%u\n",
1813 memsize_char(memsize
),
1814 dc
->op1
, dc
->postinc
? "+]" : "]",
1817 cris_cc_mask(dc
, CC_MASK_NZVC
);
1818 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1819 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1820 do_postinc(dc
, memsize
);
1824 static unsigned int dec_cmps_m(DisasContext
*dc
)
1826 int memsize
= memsize_z(dc
);
1828 DIS(fprintf (logfile
, "cmps.%c [$r%u%s, $r%u\n",
1829 memsize_char(memsize
),
1830 dc
->op1
, dc
->postinc
? "+]" : "]",
1833 cris_cc_mask(dc
, CC_MASK_NZVC
);
1834 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1835 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1836 do_postinc(dc
, memsize
);
1840 static unsigned int dec_cmp_m(DisasContext
*dc
)
1842 int memsize
= memsize_zz(dc
);
1844 DIS(fprintf (logfile
, "cmp.%c [$r%u%s, $r%u\n",
1845 memsize_char(memsize
),
1846 dc
->op1
, dc
->postinc
? "+]" : "]",
1849 cris_cc_mask(dc
, CC_MASK_NZVC
);
1850 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1851 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1852 do_postinc(dc
, memsize
);
1856 static unsigned int dec_test_m(DisasContext
*dc
)
1858 int memsize
= memsize_zz(dc
);
1860 DIS(fprintf (logfile
, "test.%d [$r%u%s] op2=%x\n",
1861 memsize_char(memsize
),
1862 dc
->op1
, dc
->postinc
? "+]" : "]",
1865 cris_cc_mask(dc
, CC_MASK_NZ
);
1867 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1868 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
1869 tcg_gen_movi_tl(cpu_T
[1], 0);
1870 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1871 do_postinc(dc
, memsize
);
1875 static unsigned int dec_and_m(DisasContext
*dc
)
1877 int memsize
= memsize_zz(dc
);
1879 DIS(fprintf (logfile
, "and.%d [$r%u%s, $r%u\n",
1880 memsize_char(memsize
),
1881 dc
->op1
, dc
->postinc
? "+]" : "]",
1884 cris_cc_mask(dc
, CC_MASK_NZ
);
1885 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1886 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, memsize_zz(dc
));
1887 do_postinc(dc
, memsize
);
1891 static unsigned int dec_add_m(DisasContext
*dc
)
1893 int memsize
= memsize_zz(dc
);
1895 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1896 memsize_char(memsize
),
1897 dc
->op1
, dc
->postinc
? "+]" : "]",
1900 cris_cc_mask(dc
, CC_MASK_NZVC
);
1901 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1902 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, memsize_zz(dc
));
1903 do_postinc(dc
, memsize
);
1907 static unsigned int dec_addo_m(DisasContext
*dc
)
1909 int memsize
= memsize_zz(dc
);
1911 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1912 memsize_char(memsize
),
1913 dc
->op1
, dc
->postinc
? "+]" : "]",
1916 cris_cc_mask(dc
, 0);
1917 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1918 crisv32_alu_op(dc
, CC_OP_ADD
, R_ACR
, 4);
1919 do_postinc(dc
, memsize
);
1923 static unsigned int dec_bound_m(DisasContext
*dc
)
1925 int memsize
= memsize_zz(dc
);
1927 DIS(fprintf (logfile
, "bound.%d [$r%u%s, $r%u\n",
1928 memsize_char(memsize
),
1929 dc
->op1
, dc
->postinc
? "+]" : "]",
1932 cris_cc_mask(dc
, CC_MASK_NZ
);
1933 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1934 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1935 do_postinc(dc
, memsize
);
1939 static unsigned int dec_addc_mr(DisasContext
*dc
)
1942 DIS(fprintf (logfile
, "addc [$r%u%s, $r%u\n",
1943 dc
->op1
, dc
->postinc
? "+]" : "]",
1946 cris_evaluate_flags(dc
);
1947 cris_cc_mask(dc
, CC_MASK_NZVC
);
1948 insn_len
= dec_prep_alu_m(dc
, 0, 4);
1949 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1954 static unsigned int dec_sub_m(DisasContext
*dc
)
1956 int memsize
= memsize_zz(dc
);
1958 DIS(fprintf (logfile
, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1959 memsize_char(memsize
),
1960 dc
->op1
, dc
->postinc
? "+]" : "]",
1961 dc
->op2
, dc
->ir
, dc
->zzsize
));
1963 cris_cc_mask(dc
, CC_MASK_NZVC
);
1964 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1965 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, memsize
);
1966 do_postinc(dc
, memsize
);
1970 static unsigned int dec_or_m(DisasContext
*dc
)
1972 int memsize
= memsize_zz(dc
);
1974 DIS(fprintf (logfile
, "or.%d [$r%u%s, $r%u pc=%x\n",
1975 memsize_char(memsize
),
1976 dc
->op1
, dc
->postinc
? "+]" : "]",
1979 cris_cc_mask(dc
, CC_MASK_NZ
);
1980 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1981 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, memsize_zz(dc
));
1982 do_postinc(dc
, memsize
);
1986 static unsigned int dec_move_mp(DisasContext
*dc
)
1988 int memsize
= memsize_zz(dc
);
1991 DIS(fprintf (logfile
, "move.%c [$r%u%s, $p%u\n",
1992 memsize_char(memsize
),
1994 dc
->postinc
? "+]" : "]",
1997 cris_cc_mask(dc
, 0);
1998 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1999 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[1]);
2001 do_postinc(dc
, memsize
);
2005 static unsigned int dec_move_pm(DisasContext
*dc
)
2009 memsize
= preg_sizes
[dc
->op2
];
2011 DIS(fprintf (logfile
, "move.%c $p%u, [$r%u%s\n",
2012 memsize_char(memsize
),
2013 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]"));
2015 cris_cc_mask(dc
, 0);
2016 /* prepare store. Address in T0, value in T1. */
2017 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
2018 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2019 gen_store_T0_T1(dc
, memsize
);
2022 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2023 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2028 static unsigned int dec_movem_mr(DisasContext
*dc
)
2032 DIS(fprintf (logfile
, "movem [$r%u%s, $r%u\n", dc
->op1
,
2033 dc
->postinc
? "+]" : "]", dc
->op2
));
2035 cris_cc_mask(dc
, 0);
2036 /* fetch the address into T0 and T1. */
2037 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
2038 for (i
= 0; i
<= dc
->op2
; i
++) {
2039 /* Perform the load onto regnum i. Always dword wide. */
2040 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
2041 gen_load_T0_T0(dc
, 4, 0);
2042 t_gen_mov_reg_TN(i
, cpu_T
[0]);
2043 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 4);
2045 /* writeback the updated pointer value. */
2047 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[1]);
2051 static unsigned int dec_movem_rm(DisasContext
*dc
)
2055 DIS(fprintf (logfile
, "movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2056 dc
->postinc
? "+]" : "]"));
2058 cris_cc_mask(dc
, 0);
2059 for (i
= 0; i
<= dc
->op2
; i
++) {
2060 /* Fetch register i into T1. */
2061 t_gen_mov_TN_reg(cpu_T
[1], i
);
2062 /* Fetch the address into T0. */
2063 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2065 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], i
* 4);
2066 /* Perform the store. */
2067 gen_store_T0_T1(dc
, 4);
2070 /* T0 should point to the last written addr, advance one more
2072 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 4);
2073 /* writeback the updated pointer value. */
2074 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2079 static unsigned int dec_move_rm(DisasContext
*dc
)
2083 memsize
= memsize_zz(dc
);
2085 DIS(fprintf (logfile
, "move.%d $r%u, [$r%u]\n",
2086 memsize
, dc
->op2
, dc
->op1
));
2088 cris_cc_mask(dc
, 0);
2089 /* prepare store. */
2090 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2091 t_gen_mov_TN_reg(cpu_T
[1], dc
->op2
);
2092 gen_store_T0_T1(dc
, memsize
);
2095 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2096 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2101 static unsigned int dec_lapcq(DisasContext
*dc
)
2103 DIS(fprintf (logfile
, "lapcq %x, $r%u\n",
2104 dc
->pc
+ dc
->op1
*2, dc
->op2
));
2105 cris_cc_mask(dc
, 0);
2106 tcg_gen_movi_tl(cpu_T
[1], dc
->pc
+ dc
->op1
* 2);
2107 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
2111 static unsigned int dec_lapc_im(DisasContext
*dc
)
2118 cris_cc_mask(dc
, 0);
2119 imm
= ldl_code(dc
->pc
+ 2);
2120 DIS(fprintf (logfile
, "lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
));
2121 t_gen_mov_reg_TN(rd
, tcg_const_tl(dc
->pc
+ imm
));
2125 /* Jump to special reg. */
2126 static unsigned int dec_jump_p(DisasContext
*dc
)
2128 DIS(fprintf (logfile
, "jump $p%u\n", dc
->op2
));
2129 cris_cc_mask(dc
, 0);
2130 /* Store the return address in Pd. */
2131 t_gen_mov_TN_preg(cpu_T
[0], dc
->op2
);
2132 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2133 cris_prepare_dyn_jmp(dc
);
2137 /* Jump and save. */
2138 static unsigned int dec_jas_r(DisasContext
*dc
)
2140 DIS(fprintf (logfile
, "jas $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2141 cris_cc_mask(dc
, 0);
2142 /* Stor the return address in Pd. */
2143 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2144 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2145 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 4);
2146 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2147 cris_prepare_dyn_jmp(dc
);
2151 static unsigned int dec_jas_im(DisasContext
*dc
)
2155 imm
= ldl_code(dc
->pc
+ 2);
2157 DIS(fprintf (logfile
, "jas 0x%x\n", imm
));
2158 cris_cc_mask(dc
, 0);
2159 /* Stor the return address in Pd. */
2160 t_gen_mov_env_TN(btarget
, tcg_const_tl(imm
));
2161 t_gen_mov_preg_TN(dc
->op2
, tcg_const_tl(dc
->pc
+ 8));
2162 cris_prepare_dyn_jmp(dc
);
2166 static unsigned int dec_jasc_im(DisasContext
*dc
)
2170 imm
= ldl_code(dc
->pc
+ 2);
2172 DIS(fprintf (logfile
, "jasc 0x%x\n", imm
));
2173 cris_cc_mask(dc
, 0);
2174 /* Stor the return address in Pd. */
2175 tcg_gen_movi_tl(cpu_T
[0], imm
);
2176 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2177 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8 + 4);
2178 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2179 cris_prepare_dyn_jmp(dc
);
2183 static unsigned int dec_jasc_r(DisasContext
*dc
)
2185 DIS(fprintf (logfile
, "jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2186 cris_cc_mask(dc
, 0);
2187 /* Stor the return address in Pd. */
2188 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2189 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2190 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 4 + 4);
2191 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2192 cris_prepare_dyn_jmp(dc
);
2196 static unsigned int dec_bcc_im(DisasContext
*dc
)
2199 uint32_t cond
= dc
->op2
;
2201 offset
= ldl_code(dc
->pc
+ 2);
2202 offset
= sign_extend(offset
, 15);
2204 DIS(fprintf (logfile
, "b%s %d pc=%x dst=%x\n",
2205 cc_name(cond
), offset
,
2206 dc
->pc
, dc
->pc
+ offset
));
2208 cris_cc_mask(dc
, 0);
2209 /* op2 holds the condition-code. */
2210 cris_prepare_cc_branch (dc
, offset
, cond
);
2214 static unsigned int dec_bas_im(DisasContext
*dc
)
2219 simm
= ldl_code(dc
->pc
+ 2);
2221 DIS(fprintf (logfile
, "bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2222 cris_cc_mask(dc
, 0);
2223 /* Stor the return address in Pd. */
2224 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2225 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2226 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8);
2227 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2228 cris_prepare_dyn_jmp(dc
);
2232 static unsigned int dec_basc_im(DisasContext
*dc
)
2235 simm
= ldl_code(dc
->pc
+ 2);
2237 DIS(fprintf (logfile
, "basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2238 cris_cc_mask(dc
, 0);
2239 /* Stor the return address in Pd. */
2240 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2241 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2242 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 12);
2243 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2244 cris_prepare_dyn_jmp(dc
);
2248 static unsigned int dec_rfe_etc(DisasContext
*dc
)
2250 DIS(fprintf (logfile
, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2251 dc
->opcode
, dc
->pc
, dc
->op1
, dc
->op2
));
2253 cris_cc_mask(dc
, 0);
2255 if (dc
->op2
== 15) /* ignore halt. */
2258 switch (dc
->op2
& 7) {
2261 cris_evaluate_flags(dc
);
2262 gen_op_ccs_rshift();
2270 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2271 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2272 /* Breaks start at 16 in the exception vector. */
2273 gen_op_break_im(dc
->op1
+ 16);
2274 dc
->is_jmp
= DISAS_SWI
;
2277 printf ("op2=%x\n", dc
->op2
);
2285 static unsigned int dec_ftag_fidx_d_m(DisasContext
*dc
)
2287 /* Ignore D-cache flushes. */
2291 static unsigned int dec_ftag_fidx_i_m(DisasContext
*dc
)
2293 /* Ignore I-cache flushes. */
2297 static unsigned int dec_null(DisasContext
*dc
)
2299 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2300 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2306 struct decoder_info
{
2311 unsigned int (*dec
)(DisasContext
*dc
);
2313 /* Order matters here. */
2314 {DEC_MOVEQ
, dec_moveq
},
2315 {DEC_BTSTQ
, dec_btstq
},
2316 {DEC_CMPQ
, dec_cmpq
},
2317 {DEC_ADDOQ
, dec_addoq
},
2318 {DEC_ADDQ
, dec_addq
},
2319 {DEC_SUBQ
, dec_subq
},
2320 {DEC_ANDQ
, dec_andq
},
2322 {DEC_ASRQ
, dec_asrq
},
2323 {DEC_LSLQ
, dec_lslq
},
2324 {DEC_LSRQ
, dec_lsrq
},
2325 {DEC_BCCQ
, dec_bccq
},
2327 {DEC_BCC_IM
, dec_bcc_im
},
2328 {DEC_JAS_IM
, dec_jas_im
},
2329 {DEC_JAS_R
, dec_jas_r
},
2330 {DEC_JASC_IM
, dec_jasc_im
},
2331 {DEC_JASC_R
, dec_jasc_r
},
2332 {DEC_BAS_IM
, dec_bas_im
},
2333 {DEC_BASC_IM
, dec_basc_im
},
2334 {DEC_JUMP_P
, dec_jump_p
},
2335 {DEC_LAPC_IM
, dec_lapc_im
},
2336 {DEC_LAPCQ
, dec_lapcq
},
2338 {DEC_RFE_ETC
, dec_rfe_etc
},
2339 {DEC_ADDC_MR
, dec_addc_mr
},
2341 {DEC_MOVE_MP
, dec_move_mp
},
2342 {DEC_MOVE_PM
, dec_move_pm
},
2343 {DEC_MOVEM_MR
, dec_movem_mr
},
2344 {DEC_MOVEM_RM
, dec_movem_rm
},
2345 {DEC_MOVE_PR
, dec_move_pr
},
2346 {DEC_SCC_R
, dec_scc_r
},
2347 {DEC_SETF
, dec_setclrf
},
2348 {DEC_CLEARF
, dec_setclrf
},
2350 {DEC_MOVE_SR
, dec_move_sr
},
2351 {DEC_MOVE_RP
, dec_move_rp
},
2352 {DEC_SWAP_R
, dec_swap_r
},
2353 {DEC_ABS_R
, dec_abs_r
},
2354 {DEC_LZ_R
, dec_lz_r
},
2355 {DEC_MOVE_RS
, dec_move_rs
},
2356 {DEC_BTST_R
, dec_btst_r
},
2357 {DEC_ADDC_R
, dec_addc_r
},
2359 {DEC_DSTEP_R
, dec_dstep_r
},
2360 {DEC_XOR_R
, dec_xor_r
},
2361 {DEC_MCP_R
, dec_mcp_r
},
2362 {DEC_CMP_R
, dec_cmp_r
},
2364 {DEC_ADDI_R
, dec_addi_r
},
2365 {DEC_ADDI_ACR
, dec_addi_acr
},
2367 {DEC_ADD_R
, dec_add_r
},
2368 {DEC_SUB_R
, dec_sub_r
},
2370 {DEC_ADDU_R
, dec_addu_r
},
2371 {DEC_ADDS_R
, dec_adds_r
},
2372 {DEC_SUBU_R
, dec_subu_r
},
2373 {DEC_SUBS_R
, dec_subs_r
},
2374 {DEC_LSL_R
, dec_lsl_r
},
2376 {DEC_AND_R
, dec_and_r
},
2377 {DEC_OR_R
, dec_or_r
},
2378 {DEC_BOUND_R
, dec_bound_r
},
2379 {DEC_ASR_R
, dec_asr_r
},
2380 {DEC_LSR_R
, dec_lsr_r
},
2382 {DEC_MOVU_R
, dec_movu_r
},
2383 {DEC_MOVS_R
, dec_movs_r
},
2384 {DEC_NEG_R
, dec_neg_r
},
2385 {DEC_MOVE_R
, dec_move_r
},
2387 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2388 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2390 {DEC_MULS_R
, dec_muls_r
},
2391 {DEC_MULU_R
, dec_mulu_r
},
2393 {DEC_ADDU_M
, dec_addu_m
},
2394 {DEC_ADDS_M
, dec_adds_m
},
2395 {DEC_SUBU_M
, dec_subu_m
},
2396 {DEC_SUBS_M
, dec_subs_m
},
2398 {DEC_CMPU_M
, dec_cmpu_m
},
2399 {DEC_CMPS_M
, dec_cmps_m
},
2400 {DEC_MOVU_M
, dec_movu_m
},
2401 {DEC_MOVS_M
, dec_movs_m
},
2403 {DEC_CMP_M
, dec_cmp_m
},
2404 {DEC_ADDO_M
, dec_addo_m
},
2405 {DEC_BOUND_M
, dec_bound_m
},
2406 {DEC_ADD_M
, dec_add_m
},
2407 {DEC_SUB_M
, dec_sub_m
},
2408 {DEC_AND_M
, dec_and_m
},
2409 {DEC_OR_M
, dec_or_m
},
2410 {DEC_MOVE_RM
, dec_move_rm
},
2411 {DEC_TEST_M
, dec_test_m
},
2412 {DEC_MOVE_MR
, dec_move_mr
},
2417 static inline unsigned int
2418 cris_decoder(DisasContext
*dc
)
2420 unsigned int insn_len
= 2;
2424 /* Load a halfword onto the instruction register. */
2425 tmp
= ldl_code(dc
->pc
);
2426 dc
->ir
= tmp
& 0xffff;
2428 /* Now decode it. */
2429 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2430 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2431 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2432 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2433 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2434 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2436 /* Large switch for all insns. */
2437 for (i
= 0; i
< sizeof decinfo
/ sizeof decinfo
[0]; i
++) {
2438 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
)
2440 insn_len
= decinfo
[i
].dec(dc
);
2448 static void check_breakpoint(CPUState
*env
, DisasContext
*dc
)
2451 if (env
->nb_breakpoints
> 0) {
2452 for(j
= 0; j
< env
->nb_breakpoints
; j
++) {
2453 if (env
->breakpoints
[j
] == dc
->pc
) {
2454 cris_evaluate_flags (dc
);
2455 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2456 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2458 dc
->is_jmp
= DISAS_UPDATE
;
2464 /* generate intermediate code for basic block 'tb'. */
2465 struct DisasContext ctx
;
2467 gen_intermediate_code_internal(CPUState
*env
, TranslationBlock
*tb
,
2470 uint16_t *gen_opc_end
;
2472 unsigned int insn_len
;
2474 struct DisasContext
*dc
= &ctx
;
2475 uint32_t next_page_start
;
2484 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
2486 dc
->is_jmp
= DISAS_NEXT
;
2488 dc
->singlestep_enabled
= env
->singlestep_enabled
;
2492 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
2496 check_breakpoint(env
, dc
);
2497 if (dc
->is_jmp
== DISAS_JUMP
2498 || dc
->is_jmp
== DISAS_SWI
)
2502 j
= gen_opc_ptr
- gen_opc_buf
;
2506 gen_opc_instr_start
[lj
++] = 0;
2508 gen_opc_pc
[lj
] = dc
->pc
;
2509 gen_opc_instr_start
[lj
] = 1;
2512 insn_len
= cris_decoder(dc
);
2513 STATS(gen_op_exec_insn());
2515 cris_clear_x_flag(dc
);
2517 /* Check for delayed branches here. If we do it before
2518 actually genereating any host code, the simulator will just
2519 loop doing nothing for on this program location. */
2520 if (dc
->delayed_branch
) {
2521 dc
->delayed_branch
--;
2522 if (dc
->delayed_branch
== 0)
2524 if (dc
->bcc
== CC_A
) {
2526 dc
->is_jmp
= DISAS_UPDATE
;
2529 /* Conditional jmp. */
2530 gen_op_cc_jmp (dc
->delayed_pc
, dc
->pc
);
2531 dc
->is_jmp
= DISAS_UPDATE
;
2536 if (env
->singlestep_enabled
)
2538 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
2539 && dc
->pc
< next_page_start
);
2542 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2543 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2546 cris_evaluate_flags (dc
);
2548 if (__builtin_expect(env
->singlestep_enabled
, 0)) {
2551 switch(dc
->is_jmp
) {
2553 gen_goto_tb(dc
, 1, dc
->pc
);
2558 /* indicate that the hash table must be used
2559 to find the next TB */
2564 /* nothing more to generate */
2568 *gen_opc_ptr
= INDEX_op_end
;
2570 j
= gen_opc_ptr
- gen_opc_buf
;
2573 gen_opc_instr_start
[lj
++] = 0;
2575 tb
->size
= dc
->pc
- pc_start
;
2579 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
2580 fprintf(logfile
, "--------------\n");
2581 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
2582 target_disas(logfile
, pc_start
, dc
->pc
+ 4 - pc_start
, 0);
2583 fprintf(logfile
, "\n");
2589 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
2591 return gen_intermediate_code_internal(env
, tb
, 0);
2594 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
2596 return gen_intermediate_code_internal(env
, tb
, 1);
2599 void cpu_dump_state (CPUState
*env
, FILE *f
,
2600 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
2609 cpu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2610 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2612 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
2614 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
,
2615 env
->debug1
, env
->debug2
, env
->debug3
);
2617 for (i
= 0; i
< 16; i
++) {
2618 cpu_fprintf(f
, "r%2.2d=%8.8x ", i
, env
->regs
[i
]);
2619 if ((i
+ 1) % 4 == 0)
2620 cpu_fprintf(f
, "\n");
2622 cpu_fprintf(f
, "\nspecial regs:\n");
2623 for (i
= 0; i
< 16; i
++) {
2624 cpu_fprintf(f
, "p%2.2d=%8.8x ", i
, env
->pregs
[i
]);
2625 if ((i
+ 1) % 4 == 0)
2626 cpu_fprintf(f
, "\n");
2628 srs
= env
->pregs
[PR_SRS
];
2629 cpu_fprintf(f
, "\nsupport function regs bank %d:\n", srs
);
2631 for (i
= 0; i
< 16; i
++) {
2632 cpu_fprintf(f
, "s%2.2d=%8.8x ",
2633 i
, env
->sregs
[srs
][i
]);
2634 if ((i
+ 1) % 4 == 0)
2635 cpu_fprintf(f
, "\n");
2638 cpu_fprintf(f
, "\n\n");
2642 static void tcg_macro_func(TCGContext
*s
, int macro_id
, const int *dead_args
)
2646 CPUCRISState
*cpu_cris_init (const char *cpu_model
)
2651 env
= qemu_mallocz(sizeof(CPUCRISState
));
2656 tcg_set_macro_func(&tcg_ctx
, tcg_macro_func
);
2657 cpu_env
= tcg_global_reg_new(TCG_TYPE_PTR
, TCG_AREG0
, "env");
2658 #if TARGET_LONG_BITS > HOST_LONG_BITS
2659 cpu_T
[0] = tcg_global_mem_new(TCG_TYPE_TL
,
2660 TCG_AREG0
, offsetof(CPUState
, t0
), "T0");
2661 cpu_T
[1] = tcg_global_mem_new(TCG_TYPE_TL
,
2662 TCG_AREG0
, offsetof(CPUState
, t1
), "T1");
2664 cpu_T
[0] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG1
, "T0");
2665 cpu_T
[1] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG2
, "T1");
2668 cc_src
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2669 offsetof(CPUState
, cc_src
), "cc_src");
2670 cc_dest
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2671 offsetof(CPUState
, cc_dest
),
2673 cc_result
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2674 offsetof(CPUState
, cc_result
),
2676 cc_op
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2677 offsetof(CPUState
, cc_op
), "cc_op");
2678 cc_size
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2679 offsetof(CPUState
, cc_size
),
2681 cc_mask
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2682 offsetof(CPUState
, cc_mask
),
2685 for (i
= 0; i
< 16; i
++) {
2686 cpu_R
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2687 offsetof(CPUState
, regs
[i
]),
2690 for (i
= 0; i
< 16; i
++) {
2691 cpu_PR
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2692 offsetof(CPUState
, pregs
[i
]),
2700 void cpu_reset (CPUCRISState
*env
)
2702 memset(env
, 0, offsetof(CPUCRISState
, breakpoints
));