]>
git.proxmox.com Git - qemu.git/blob - target-cris/translate.c
5769175ab0cf286d046391e00d6db7df9a64309a
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"
50 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
51 #define BUG_ON(x) ({if (x) BUG();})
55 /* Used by the decoder. */
56 #define EXTRACT_FIELD(src, start, end) \
57 (((src) >> start) & ((1 << (end - start + 1)) - 1))
59 #define CC_MASK_NZ 0xc
60 #define CC_MASK_NZV 0xe
61 #define CC_MASK_NZVC 0xf
62 #define CC_MASK_RNZV 0x10e
75 /* This is the state at translation time. */
76 typedef struct DisasContext
{
78 target_ulong pc
, insn_pc
;
85 unsigned int zsize
, zzsize
;
96 uint32_t tb_entry_flags
;
98 int memidx
; /* user or kernel mode. */
107 struct TranslationBlock
*tb
;
108 int singlestep_enabled
;
111 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
);
112 static void gen_BUG(DisasContext
*dc
, char *file
, int line
)
114 printf ("BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
115 fprintf (logfile
, "BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
116 cpu_dump_state (dc
->env
, stdout
, fprintf
, 0);
118 cris_prepare_jmp (dc
, 0x70000000 + line
);
121 #ifdef CONFIG_USER_ONLY
122 #define GEN_OP_LD(width, reg) \
123 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
124 gen_op_ld##width##_T0_##reg##_raw(); \
126 #define GEN_OP_ST(width, reg) \
127 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
128 gen_op_st##width##_##reg##_T1_raw(); \
131 #define GEN_OP_LD(width, reg) \
132 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
133 if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
134 else gen_op_ld##width##_T0_##reg##_user();\
136 #define GEN_OP_ST(width, reg) \
137 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
138 if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
139 else gen_op_st##width##_##reg##_T1_user();\
152 const char *regnames
[] =
154 "$r0", "$r1", "$r2", "$r3",
155 "$r4", "$r5", "$r6", "$r7",
156 "$r8", "$r9", "$r10", "$r11",
157 "$r12", "$r13", "$sp", "$acr",
159 const char *pregnames
[] =
161 "$bz", "$vr", "$pid", "$srs",
162 "$wz", "$exs", "$eda", "$mof",
163 "$dz", "$ebp", "$erp", "$srp",
164 "$nrp", "$ccs", "$usp", "$spc",
167 /* We need this table to handle preg-moves with implicit width. */
179 #define t_gen_mov_TN_env(tn, member) \
180 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
181 #define t_gen_mov_env_TN(member, tn) \
182 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
184 #define t_gen_mov_TN_reg(tn, regno) \
185 tcg_gen_mov_tl(tn, cpu_R[regno])
186 #define t_gen_mov_reg_TN(regno, tn) \
187 tcg_gen_mov_tl(cpu_R[regno], tn)
189 static inline void _t_gen_mov_TN_env(TCGv tn
, int offset
)
191 tcg_gen_ld_tl(tn
, cpu_env
, offset
);
193 static inline void _t_gen_mov_env_TN(int offset
, TCGv tn
)
195 tcg_gen_st_tl(tn
, cpu_env
, offset
);
198 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
200 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
201 tcg_gen_mov_tl(tn
, tcg_const_tl(0));
203 tcg_gen_mov_tl(tn
, tcg_const_tl(32));
205 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
207 static inline void t_gen_mov_preg_TN(int r
, TCGv tn
)
209 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
212 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
215 static inline void t_gen_mov_TN_im(TCGv tn
, int32_t val
)
217 tcg_gen_movi_tl(tn
, val
);
220 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
224 l1
= gen_new_label();
225 /* Speculative shift. */
226 tcg_gen_shl_tl(d
, a
, b
);
227 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
228 /* Clear dst if shift operands were to large. */
229 tcg_gen_movi_tl(d
, 0);
233 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
237 l1
= gen_new_label();
238 /* Speculative shift. */
239 tcg_gen_shr_tl(d
, a
, b
);
240 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
241 /* Clear dst if shift operands were to large. */
242 tcg_gen_movi_tl(d
, 0);
246 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
250 l1
= gen_new_label();
251 /* Speculative shift. */
252 tcg_gen_sar_tl(d
, a
, b
);
253 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
254 /* Clear dst if shift operands were to large. */
255 tcg_gen_movi_tl(d
, 0);
256 tcg_gen_brcond_tl(TCG_COND_LT
, b
, tcg_const_tl(0x80000000), l1
);
257 tcg_gen_movi_tl(d
, 0xffffffff);
261 /* 64-bit signed mul, lower result in d and upper in d2. */
262 static void t_gen_muls(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
266 t0
= tcg_temp_new(TCG_TYPE_I64
);
267 t1
= tcg_temp_new(TCG_TYPE_I64
);
269 tcg_gen_ext32s_i64(t0
, a
);
270 tcg_gen_ext32s_i64(t1
, b
);
271 tcg_gen_mul_i64(t0
, t0
, t1
);
273 tcg_gen_trunc_i64_i32(d
, t0
);
274 tcg_gen_shri_i64(t0
, t0
, 32);
275 tcg_gen_trunc_i64_i32(d2
, t0
);
278 /* 64-bit unsigned muls, lower result in d and upper in d2. */
279 static void t_gen_mulu(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
283 t0
= tcg_temp_new(TCG_TYPE_I64
);
284 t1
= tcg_temp_new(TCG_TYPE_I64
);
286 tcg_gen_extu_i32_i64(t0
, a
);
287 tcg_gen_extu_i32_i64(t1
, b
);
288 tcg_gen_mul_i64(t0
, t0
, t1
);
290 tcg_gen_trunc_i64_i32(d
, t0
);
291 tcg_gen_shri_i64(t0
, t0
, 32);
292 tcg_gen_trunc_i64_i32(d2
, t0
);
295 /* Extended arithmetics on CRIS. */
296 static inline void t_gen_add_flag(TCGv d
, int flag
)
300 c
= tcg_temp_new(TCG_TYPE_TL
);
301 t_gen_mov_TN_preg(c
, PR_CCS
);
302 /* Propagate carry into d. */
303 tcg_gen_andi_tl(c
, c
, 1 << flag
);
305 tcg_gen_shri_tl(c
, c
, flag
);
306 tcg_gen_add_tl(d
, d
, c
);
309 static inline void t_gen_addx_carry(TCGv d
)
313 x
= tcg_temp_new(TCG_TYPE_TL
);
314 c
= tcg_temp_new(TCG_TYPE_TL
);
315 t_gen_mov_TN_preg(x
, PR_CCS
);
316 tcg_gen_mov_tl(c
, x
);
318 /* Propagate carry into d if X is set. Branch free. */
319 tcg_gen_andi_tl(c
, c
, C_FLAG
);
320 tcg_gen_andi_tl(x
, x
, X_FLAG
);
321 tcg_gen_shri_tl(x
, x
, 4);
323 tcg_gen_and_tl(x
, x
, c
);
324 tcg_gen_add_tl(d
, d
, x
);
327 static inline void t_gen_subx_carry(TCGv d
)
331 x
= tcg_temp_new(TCG_TYPE_TL
);
332 c
= tcg_temp_new(TCG_TYPE_TL
);
333 t_gen_mov_TN_preg(x
, PR_CCS
);
334 tcg_gen_mov_tl(c
, x
);
336 /* Propagate carry into d if X is set. Branch free. */
337 tcg_gen_andi_tl(c
, c
, C_FLAG
);
338 tcg_gen_andi_tl(x
, x
, X_FLAG
);
339 tcg_gen_shri_tl(x
, x
, 4);
341 tcg_gen_and_tl(x
, x
, c
);
342 tcg_gen_sub_tl(d
, d
, x
);
345 /* Swap the two bytes within each half word of the s operand.
346 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
347 static inline void t_gen_swapb(TCGv d
, TCGv s
)
351 t
= tcg_temp_new(TCG_TYPE_TL
);
352 org_s
= tcg_temp_new(TCG_TYPE_TL
);
354 /* d and s may refer to the same object. */
355 tcg_gen_mov_tl(org_s
, s
);
356 tcg_gen_shli_tl(t
, org_s
, 8);
357 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
358 tcg_gen_shri_tl(t
, org_s
, 8);
359 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
360 tcg_gen_or_tl(d
, d
, t
);
363 /* Swap the halfwords of the s operand. */
364 static inline void t_gen_swapw(TCGv d
, TCGv s
)
367 /* d and s refer the same object. */
368 t
= tcg_temp_new(TCG_TYPE_TL
);
369 tcg_gen_mov_tl(t
, s
);
370 tcg_gen_shli_tl(d
, t
, 16);
371 tcg_gen_shri_tl(t
, t
, 16);
372 tcg_gen_or_tl(d
, d
, t
);
375 /* Reverse the within each byte.
376 T0 = (((T0 << 7) & 0x80808080) |
377 ((T0 << 5) & 0x40404040) |
378 ((T0 << 3) & 0x20202020) |
379 ((T0 << 1) & 0x10101010) |
380 ((T0 >> 1) & 0x08080808) |
381 ((T0 >> 3) & 0x04040404) |
382 ((T0 >> 5) & 0x02020202) |
383 ((T0 >> 7) & 0x01010101));
385 static inline void t_gen_swapr(TCGv d
, TCGv s
)
388 int shift
; /* LSL when positive, LSR when negative. */
403 /* d and s refer the same object. */
404 t
= tcg_temp_new(TCG_TYPE_TL
);
405 org_s
= tcg_temp_new(TCG_TYPE_TL
);
406 tcg_gen_mov_tl(org_s
, s
);
408 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
409 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
410 for (i
= 1; i
< sizeof bitrev
/ sizeof bitrev
[0]; i
++) {
411 if (bitrev
[i
].shift
>= 0) {
412 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
414 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
416 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
417 tcg_gen_or_tl(d
, d
, t
);
421 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
423 TranslationBlock
*tb
;
425 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
427 tcg_gen_movi_tl(cpu_T
[0], dest
);
428 t_gen_mov_env_TN(pc
, cpu_T
[0]);
429 tcg_gen_exit_tb((long)tb
+ n
);
431 t_gen_mov_env_TN(pc
, cpu_T
[0]);
436 /* Sign extend at translation time. */
437 static int sign_extend(unsigned int val
, unsigned int width
)
449 static inline void cris_clear_x_flag(DisasContext
*dc
)
451 if (!dc
->flagx_live
|| dc
->cc_op
!= CC_OP_FLAGS
) {
452 t_gen_mov_TN_preg(cpu_T
[0], PR_CCS
);
453 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], ~X_FLAG
);
454 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
460 static void cris_evaluate_flags(DisasContext
*dc
)
462 if (!dc
->flags_live
) {
466 gen_op_evaluate_flags_mcp ();
469 gen_op_evaluate_flags_muls ();
472 gen_op_evaluate_flags_mulu ();
478 gen_op_evaluate_flags_move_4();
481 gen_op_evaluate_flags_move_2();
484 gen_op_evaluate_flags ();
494 gen_op_evaluate_flags_alu_4 ();
497 gen_op_evaluate_flags ();
507 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
511 /* Check if we need to evaluate the condition codes due to
513 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
515 /* TODO: optimize this case. It trigs all the time. */
516 cris_evaluate_flags (dc
);
527 static void cris_update_cc_op(DisasContext
*dc
, int op
)
531 tcg_gen_movi_tl(cc_op
, op
);
533 static void cris_update_cc_size(DisasContext
*dc
, int size
)
536 tcg_gen_movi_tl(cc_size
, size
);
539 /* op is the operation.
540 T0, T1 are the operands.
541 dst is the destination reg.
543 static void crisv32_alu_op(DisasContext
*dc
, int op
, int rd
, int size
)
547 cris_update_cc_op(dc
, op
);
548 cris_update_cc_size(dc
, size
);
549 tcg_gen_mov_tl(cc_dest
, cpu_T
[0]);
550 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
552 /* FIXME: This shouldn't be needed. But we don't pass the
553 tests without it. Investigate. */
554 t_gen_mov_env_TN(cc_x_live
, tcg_const_tl(dc
->flagx_live
));
555 t_gen_mov_env_TN(cc_x
, tcg_const_tl(dc
->flags_x
));
558 /* Emit the ALU insns. */
562 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
563 /* Extended arithmetics. */
564 t_gen_addx_carry(cpu_T
[0]);
567 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
568 t_gen_add_flag(cpu_T
[0], 0); /* C_FLAG. */
571 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
572 t_gen_add_flag(cpu_T
[0], 8); /* R_FLAG. */
575 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
576 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
577 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
578 /* CRIS flag evaluation needs ~src. */
579 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
581 /* Extended arithmetics. */
582 t_gen_subx_carry(cpu_T
[0]);
585 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
588 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
591 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
594 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
597 t_gen_lsl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
600 t_gen_lsr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
603 t_gen_asr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
606 /* Hopefully the TCG backend recognizes this pattern
607 and makes a real neg out of it. */
608 tcg_gen_sub_tl(cpu_T
[0], tcg_const_tl(0), cpu_T
[1]);
609 /* Extended arithmetics. */
610 t_gen_subx_carry(cpu_T
[0]);
622 mof
= tcg_temp_new(TCG_TYPE_TL
);
623 t_gen_muls(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
624 t_gen_mov_preg_TN(PR_MOF
, mof
);
630 mof
= tcg_temp_new(TCG_TYPE_TL
);
631 t_gen_mulu(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
632 t_gen_mov_preg_TN(PR_MOF
, mof
);
636 gen_op_dstep_T0_T1();
641 l1
= gen_new_label();
642 tcg_gen_brcond_tl(TCG_COND_LEU
,
643 cpu_T
[0], cpu_T
[1], l1
);
644 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
649 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
650 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
651 /* CRIS flag evaluation needs ~src. */
652 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
653 /* CRIS flag evaluation needs ~src. */
654 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
656 /* Extended arithmetics. */
657 t_gen_subx_carry(cpu_T
[0]);
661 fprintf (logfile
, "illegal ALU op.\n");
667 tcg_gen_mov_tl(cc_src
, cpu_T
[1]);
670 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
672 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
677 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
679 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
680 t_gen_mov_TN_reg(cpu_T
[0], rd
);
682 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xff);
684 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xffff);
685 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
686 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
687 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
691 tcg_gen_mov_tl(cc_result
, cpu_T
[0]);
694 /* TODO: Optimize this. */
696 cris_evaluate_flags(dc
);
700 static int arith_cc(DisasContext
*dc
)
704 case CC_OP_ADD
: return 1;
705 case CC_OP_SUB
: return 1;
706 case CC_OP_LSL
: return 1;
707 case CC_OP_LSR
: return 1;
708 case CC_OP_ASR
: return 1;
709 case CC_OP_CMP
: return 1;
717 static void gen_tst_cc (DisasContext
*dc
, int cond
)
721 /* TODO: optimize more condition codes. */
722 arith_opt
= arith_cc(dc
) && !dc
->flags_live
;
726 gen_op_tst_cc_eq_fast ();
728 cris_evaluate_flags(dc
);
734 gen_op_tst_cc_ne_fast ();
736 cris_evaluate_flags(dc
);
741 cris_evaluate_flags(dc
);
745 cris_evaluate_flags(dc
);
749 cris_evaluate_flags(dc
);
753 cris_evaluate_flags(dc
);
758 gen_op_tst_cc_pl_fast ();
760 cris_evaluate_flags(dc
);
766 gen_op_tst_cc_mi_fast ();
768 cris_evaluate_flags(dc
);
773 cris_evaluate_flags(dc
);
777 cris_evaluate_flags(dc
);
781 cris_evaluate_flags(dc
);
785 cris_evaluate_flags(dc
);
789 cris_evaluate_flags(dc
);
793 cris_evaluate_flags(dc
);
797 cris_evaluate_flags(dc
);
801 cris_evaluate_flags(dc
);
802 gen_op_movl_T0_im (1);
810 static void cris_prepare_cc_branch (DisasContext
*dc
, int offset
, int cond
)
812 /* This helps us re-schedule the micro-code to insns in delay-slots
813 before the actual jump. */
814 dc
->delayed_branch
= 2;
815 dc
->delayed_pc
= dc
->pc
+ offset
;
819 gen_tst_cc (dc
, cond
);
820 gen_op_evaluate_bcc ();
822 tcg_gen_movi_tl(cpu_T
[0], dc
->delayed_pc
);
823 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
826 /* Dynamic jumps, when the dest is in a live reg for example. */
827 void cris_prepare_dyn_jmp (DisasContext
*dc
)
829 /* This helps us re-schedule the micro-code to insns in delay-slots
830 before the actual jump. */
831 dc
->delayed_branch
= 2;
836 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
)
838 /* This helps us re-schedule the micro-code to insns in delay-slots
839 before the actual jump. */
840 dc
->delayed_branch
= 2;
841 dc
->delayed_pc
= dst
;
846 void gen_load_T0_T0 (DisasContext
*dc
, unsigned int size
, int sign
)
850 gen_op_ldb_T0_T0(dc
);
852 gen_op_ldub_T0_T0(dc
);
854 else if (size
== 2) {
856 gen_op_ldw_T0_T0(dc
);
858 gen_op_lduw_T0_T0(dc
);
861 gen_op_ldl_T0_T0(dc
);
865 void gen_store_T0_T1 (DisasContext
*dc
, unsigned int size
)
867 /* Remember, operands are flipped. CRIS has reversed order. */
869 gen_op_stb_T0_T1(dc
);
871 else if (size
== 2) {
872 gen_op_stw_T0_T1(dc
);
875 gen_op_stl_T0_T1(dc
);
878 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
881 tcg_gen_ext8s_i32(d
, s
);
883 tcg_gen_ext16s_i32(d
, s
);
886 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
888 /* TCG-FIXME: this is not optimal. Many archs have fast zext insns. */
890 tcg_gen_andi_i32(d
, s
, 0xff);
892 tcg_gen_andi_i32(d
, s
, 0xffff);
896 static char memsize_char(int size
)
900 case 1: return 'b'; break;
901 case 2: return 'w'; break;
902 case 4: return 'd'; break;
910 static unsigned int memsize_z(DisasContext
*dc
)
912 return dc
->zsize
+ 1;
915 static unsigned int memsize_zz(DisasContext
*dc
)
926 static void do_postinc (DisasContext
*dc
, int size
)
930 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
931 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], size
);
932 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
936 static void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
939 t_gen_mov_TN_reg(cpu_T
[1], rs
);
941 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
943 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
946 /* Prepare T0 and T1 for a register alu operation.
947 s_ext decides if the operand1 should be sign-extended or zero-extended when
949 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
952 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
);
954 t_gen_mov_TN_reg(cpu_T
[0], rd
);
956 t_gen_sext(cpu_T
[0], cpu_T
[0], size
);
958 t_gen_zext(cpu_T
[0], cpu_T
[0], size
);
961 /* Prepare T0 and T1 for a memory + alu operation.
962 s_ext decides if the operand1 should be sign-extended or zero-extended when
964 static int dec_prep_alu_m(DisasContext
*dc
, int s_ext
, int memsize
)
973 is_imm
= rs
== 15 && dc
->postinc
;
975 /* Load [$rs] onto T1. */
977 insn_len
= 2 + memsize
;
981 imm
= ldl_code(dc
->pc
+ 2);
984 imm
= sign_extend(imm
, (memsize
* 8) - 1);
992 DIS(fprintf (logfile
, "imm=%x rd=%d sext=%d ms=%d\n",
993 imm
, rd
, s_ext
, memsize
));
994 tcg_gen_movi_tl(cpu_T
[1], imm
);
997 t_gen_mov_TN_reg(cpu_T
[0], rs
);
998 gen_load_T0_T0(dc
, memsize
, 0);
999 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1001 t_gen_sext(cpu_T
[1], cpu_T
[1], memsize
);
1003 t_gen_zext(cpu_T
[1], cpu_T
[1], memsize
);
1006 /* put dest in T0. */
1007 t_gen_mov_TN_reg(cpu_T
[0], rd
);
1012 static const char *cc_name(int cc
)
1014 static char *cc_names
[16] = {
1015 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1016 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1019 return cc_names
[cc
];
1023 static unsigned int dec_bccq(DisasContext
*dc
)
1027 uint32_t cond
= dc
->op2
;
1030 offset
= EXTRACT_FIELD (dc
->ir
, 1, 7);
1031 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1034 offset
|= sign
<< 8;
1036 offset
= sign_extend(offset
, 8);
1038 /* op2 holds the condition-code. */
1039 cris_cc_mask(dc
, 0);
1040 cris_prepare_cc_branch (dc
, offset
, cond
);
1043 static unsigned int dec_addoq(DisasContext
*dc
)
1047 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1048 imm
= sign_extend(dc
->op1
, 7);
1050 DIS(fprintf (logfile
, "addoq %d, $r%u\n", imm
, dc
->op2
));
1051 cris_cc_mask(dc
, 0);
1052 /* Fetch register operand, */
1053 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1054 tcg_gen_movi_tl(cpu_T
[1], imm
);
1055 crisv32_alu_op(dc
, CC_OP_ADD
, R_ACR
, 4);
1058 static unsigned int dec_addq(DisasContext
*dc
)
1060 DIS(fprintf (logfile
, "addq %u, $r%u\n", dc
->op1
, dc
->op2
));
1062 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1064 cris_cc_mask(dc
, CC_MASK_NZVC
);
1065 /* Fetch register operand, */
1066 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1067 tcg_gen_movi_tl(cpu_T
[1], dc
->op1
);
1068 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1071 static unsigned int dec_moveq(DisasContext
*dc
)
1075 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1076 imm
= sign_extend(dc
->op1
, 5);
1077 DIS(fprintf (logfile
, "moveq %d, $r%u\n", imm
, dc
->op2
));
1079 t_gen_mov_reg_TN(dc
->op2
, tcg_const_tl(imm
));
1082 static unsigned int dec_subq(DisasContext
*dc
)
1084 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1086 DIS(fprintf (logfile
, "subq %u, $r%u\n", dc
->op1
, dc
->op2
));
1088 cris_cc_mask(dc
, CC_MASK_NZVC
);
1089 /* Fetch register operand, */
1090 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1091 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1092 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1095 static unsigned int dec_cmpq(DisasContext
*dc
)
1098 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1099 imm
= sign_extend(dc
->op1
, 5);
1101 DIS(fprintf (logfile
, "cmpq %d, $r%d\n", imm
, dc
->op2
));
1102 cris_cc_mask(dc
, CC_MASK_NZVC
);
1103 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1104 t_gen_mov_TN_im(cpu_T
[1], imm
);
1105 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1108 static unsigned int dec_andq(DisasContext
*dc
)
1111 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1112 imm
= sign_extend(dc
->op1
, 5);
1114 DIS(fprintf (logfile
, "andq %d, $r%d\n", imm
, dc
->op2
));
1115 cris_cc_mask(dc
, CC_MASK_NZ
);
1116 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1117 t_gen_mov_TN_im(cpu_T
[1], imm
);
1118 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, 4);
1121 static unsigned int dec_orq(DisasContext
*dc
)
1124 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1125 imm
= sign_extend(dc
->op1
, 5);
1126 DIS(fprintf (logfile
, "orq %d, $r%d\n", imm
, dc
->op2
));
1127 cris_cc_mask(dc
, CC_MASK_NZ
);
1128 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1129 t_gen_mov_TN_im(cpu_T
[1], imm
);
1130 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, 4);
1133 static unsigned int dec_btstq(DisasContext
*dc
)
1135 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1136 DIS(fprintf (logfile
, "btstq %u, $r%d\n", dc
->op1
, dc
->op2
));
1137 cris_cc_mask(dc
, CC_MASK_NZ
);
1138 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1139 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1140 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1142 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1143 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1147 static unsigned int dec_asrq(DisasContext
*dc
)
1149 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1150 DIS(fprintf (logfile
, "asrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1151 cris_cc_mask(dc
, CC_MASK_NZ
);
1152 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1153 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1154 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, 4);
1157 static unsigned int dec_lslq(DisasContext
*dc
)
1159 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1160 DIS(fprintf (logfile
, "lslq %u, $r%d\n", dc
->op1
, dc
->op2
));
1162 cris_cc_mask(dc
, CC_MASK_NZ
);
1163 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1164 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1165 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, 4);
1168 static unsigned int dec_lsrq(DisasContext
*dc
)
1170 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1171 DIS(fprintf (logfile
, "lsrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1173 cris_cc_mask(dc
, CC_MASK_NZ
);
1174 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1175 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1176 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, 4);
1180 static unsigned int dec_move_r(DisasContext
*dc
)
1182 int size
= memsize_zz(dc
);
1184 DIS(fprintf (logfile
, "move.%c $r%u, $r%u\n",
1185 memsize_char(size
), dc
->op1
, dc
->op2
));
1187 cris_cc_mask(dc
, CC_MASK_NZ
);
1188 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1189 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, size
);
1193 static unsigned int dec_scc_r(DisasContext
*dc
)
1197 DIS(fprintf (logfile
, "s%s $r%u\n",
1198 cc_name(cond
), dc
->op1
));
1202 gen_tst_cc (dc
, cond
);
1203 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1206 tcg_gen_movi_tl(cpu_T
[1], 1);
1208 cris_cc_mask(dc
, 0);
1209 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1213 static unsigned int dec_and_r(DisasContext
*dc
)
1215 int size
= memsize_zz(dc
);
1217 DIS(fprintf (logfile
, "and.%c $r%u, $r%u\n",
1218 memsize_char(size
), dc
->op1
, dc
->op2
));
1219 cris_cc_mask(dc
, CC_MASK_NZ
);
1220 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1221 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, size
);
1225 static unsigned int dec_lz_r(DisasContext
*dc
)
1227 DIS(fprintf (logfile
, "lz $r%u, $r%u\n",
1229 cris_cc_mask(dc
, CC_MASK_NZ
);
1230 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1231 crisv32_alu_op(dc
, CC_OP_LZ
, dc
->op2
, 4);
1235 static unsigned int dec_lsl_r(DisasContext
*dc
)
1237 int size
= memsize_zz(dc
);
1239 DIS(fprintf (logfile
, "lsl.%c $r%u, $r%u\n",
1240 memsize_char(size
), dc
->op1
, dc
->op2
));
1241 cris_cc_mask(dc
, CC_MASK_NZ
);
1242 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1243 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1244 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, size
);
1248 static unsigned int dec_lsr_r(DisasContext
*dc
)
1250 int size
= memsize_zz(dc
);
1252 DIS(fprintf (logfile
, "lsr.%c $r%u, $r%u\n",
1253 memsize_char(size
), dc
->op1
, dc
->op2
));
1254 cris_cc_mask(dc
, CC_MASK_NZ
);
1255 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1256 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1257 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, size
);
1261 static unsigned int dec_asr_r(DisasContext
*dc
)
1263 int size
= memsize_zz(dc
);
1265 DIS(fprintf (logfile
, "asr.%c $r%u, $r%u\n",
1266 memsize_char(size
), dc
->op1
, dc
->op2
));
1267 cris_cc_mask(dc
, CC_MASK_NZ
);
1268 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1269 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1270 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, size
);
1274 static unsigned int dec_muls_r(DisasContext
*dc
)
1276 int size
= memsize_zz(dc
);
1278 DIS(fprintf (logfile
, "muls.%c $r%u, $r%u\n",
1279 memsize_char(size
), dc
->op1
, dc
->op2
));
1280 cris_cc_mask(dc
, CC_MASK_NZV
);
1281 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1282 t_gen_sext(cpu_T
[0], cpu_T
[0], size
);
1283 crisv32_alu_op(dc
, CC_OP_MULS
, dc
->op2
, 4);
1287 static unsigned int dec_mulu_r(DisasContext
*dc
)
1289 int size
= memsize_zz(dc
);
1291 DIS(fprintf (logfile
, "mulu.%c $r%u, $r%u\n",
1292 memsize_char(size
), dc
->op1
, dc
->op2
));
1293 cris_cc_mask(dc
, CC_MASK_NZV
);
1294 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1295 t_gen_zext(cpu_T
[0], cpu_T
[0], size
);
1296 crisv32_alu_op(dc
, CC_OP_MULU
, dc
->op2
, 4);
1301 static unsigned int dec_dstep_r(DisasContext
*dc
)
1303 DIS(fprintf (logfile
, "dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
));
1304 cris_cc_mask(dc
, CC_MASK_NZ
);
1305 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1306 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1307 crisv32_alu_op(dc
, CC_OP_DSTEP
, dc
->op2
, 4);
1311 static unsigned int dec_xor_r(DisasContext
*dc
)
1313 int size
= memsize_zz(dc
);
1314 DIS(fprintf (logfile
, "xor.%c $r%u, $r%u\n",
1315 memsize_char(size
), dc
->op1
, dc
->op2
));
1316 BUG_ON(size
!= 4); /* xor is dword. */
1317 cris_cc_mask(dc
, CC_MASK_NZ
);
1318 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1319 crisv32_alu_op(dc
, CC_OP_XOR
, dc
->op2
, 4);
1323 static unsigned int dec_bound_r(DisasContext
*dc
)
1325 int size
= memsize_zz(dc
);
1326 DIS(fprintf (logfile
, "bound.%c $r%u, $r%u\n",
1327 memsize_char(size
), dc
->op1
, dc
->op2
));
1328 cris_cc_mask(dc
, CC_MASK_NZ
);
1329 /* TODO: needs optmimization. */
1330 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1331 /* rd should be 4. */
1332 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1333 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1337 static unsigned int dec_cmp_r(DisasContext
*dc
)
1339 int size
= memsize_zz(dc
);
1340 DIS(fprintf (logfile
, "cmp.%c $r%u, $r%u\n",
1341 memsize_char(size
), dc
->op1
, dc
->op2
));
1342 cris_cc_mask(dc
, CC_MASK_NZVC
);
1343 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1344 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, size
);
1348 static unsigned int dec_abs_r(DisasContext
*dc
)
1352 DIS(fprintf (logfile
, "abs $r%u, $r%u\n",
1354 cris_cc_mask(dc
, CC_MASK_NZ
);
1355 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1357 /* TODO: consider a branch free approach. */
1358 l1
= gen_new_label();
1359 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_T
[1], tcg_const_tl(0), l1
);
1360 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
1362 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1366 static unsigned int dec_add_r(DisasContext
*dc
)
1368 int size
= memsize_zz(dc
);
1369 DIS(fprintf (logfile
, "add.%c $r%u, $r%u\n",
1370 memsize_char(size
), dc
->op1
, dc
->op2
));
1371 cris_cc_mask(dc
, CC_MASK_NZVC
);
1372 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1373 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, size
);
1377 static unsigned int dec_addc_r(DisasContext
*dc
)
1379 DIS(fprintf (logfile
, "addc $r%u, $r%u\n",
1381 cris_evaluate_flags(dc
);
1382 cris_cc_mask(dc
, CC_MASK_NZVC
);
1383 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1384 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1388 static unsigned int dec_mcp_r(DisasContext
*dc
)
1390 DIS(fprintf (logfile
, "mcp $p%u, $r%u\n",
1392 cris_evaluate_flags(dc
);
1393 cris_cc_mask(dc
, CC_MASK_RNZV
);
1394 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1395 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1396 crisv32_alu_op(dc
, CC_OP_MCP
, dc
->op1
, 4);
1401 static char * swapmode_name(int mode
, char *modename
) {
1404 modename
[i
++] = 'n';
1406 modename
[i
++] = 'w';
1408 modename
[i
++] = 'b';
1410 modename
[i
++] = 'r';
1416 static unsigned int dec_swap_r(DisasContext
*dc
)
1418 DIS(char modename
[4]);
1419 DIS(fprintf (logfile
, "swap%s $r%u\n",
1420 swapmode_name(dc
->op2
, modename
), dc
->op1
));
1422 cris_cc_mask(dc
, CC_MASK_NZ
);
1423 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1425 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], -1);
1427 t_gen_swapw(cpu_T
[0], cpu_T
[0]);
1429 t_gen_swapb(cpu_T
[0], cpu_T
[0]);
1431 t_gen_swapr(cpu_T
[0], cpu_T
[0]);
1432 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1433 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1437 static unsigned int dec_or_r(DisasContext
*dc
)
1439 int size
= memsize_zz(dc
);
1440 DIS(fprintf (logfile
, "or.%c $r%u, $r%u\n",
1441 memsize_char(size
), dc
->op1
, dc
->op2
));
1442 cris_cc_mask(dc
, CC_MASK_NZ
);
1443 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1444 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, size
);
1448 static unsigned int dec_addi_r(DisasContext
*dc
)
1450 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u\n",
1451 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1452 cris_cc_mask(dc
, 0);
1453 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1454 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1455 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1456 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
1460 static unsigned int dec_addi_acr(DisasContext
*dc
)
1462 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u, $acr\n",
1463 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1464 cris_cc_mask(dc
, 0);
1465 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1466 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1468 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1469 t_gen_mov_reg_TN(R_ACR
, cpu_T
[0]);
1473 static unsigned int dec_neg_r(DisasContext
*dc
)
1475 int size
= memsize_zz(dc
);
1476 DIS(fprintf (logfile
, "neg.%c $r%u, $r%u\n",
1477 memsize_char(size
), dc
->op1
, dc
->op2
));
1478 cris_cc_mask(dc
, CC_MASK_NZVC
);
1479 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1480 crisv32_alu_op(dc
, CC_OP_NEG
, dc
->op2
, size
);
1484 static unsigned int dec_btst_r(DisasContext
*dc
)
1486 DIS(fprintf (logfile
, "btst $r%u, $r%u\n",
1488 cris_cc_mask(dc
, CC_MASK_NZ
);
1489 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1490 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1492 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1493 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1498 static unsigned int dec_sub_r(DisasContext
*dc
)
1500 int size
= memsize_zz(dc
);
1501 DIS(fprintf (logfile
, "sub.%c $r%u, $r%u\n",
1502 memsize_char(size
), dc
->op1
, dc
->op2
));
1503 cris_cc_mask(dc
, CC_MASK_NZVC
);
1504 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1505 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, size
);
1509 /* Zero extension. From size to dword. */
1510 static unsigned int dec_movu_r(DisasContext
*dc
)
1512 int size
= memsize_z(dc
);
1513 DIS(fprintf (logfile
, "movu.%c $r%u, $r%u\n",
1517 cris_cc_mask(dc
, CC_MASK_NZ
);
1518 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1519 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1523 /* Sign extension. From size to dword. */
1524 static unsigned int dec_movs_r(DisasContext
*dc
)
1526 int size
= memsize_z(dc
);
1527 DIS(fprintf (logfile
, "movs.%c $r%u, $r%u\n",
1531 cris_cc_mask(dc
, CC_MASK_NZ
);
1532 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1533 /* Size can only be qi or hi. */
1534 t_gen_sext(cpu_T
[1], cpu_T
[0], size
);
1535 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1539 /* zero extension. From size to dword. */
1540 static unsigned int dec_addu_r(DisasContext
*dc
)
1542 int size
= memsize_z(dc
);
1543 DIS(fprintf (logfile
, "addu.%c $r%u, $r%u\n",
1547 cris_cc_mask(dc
, CC_MASK_NZVC
);
1548 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1549 /* Size can only be qi or hi. */
1550 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1551 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1552 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1556 /* Sign extension. From size to dword. */
1557 static unsigned int dec_adds_r(DisasContext
*dc
)
1559 int size
= memsize_z(dc
);
1560 DIS(fprintf (logfile
, "adds.%c $r%u, $r%u\n",
1564 cris_cc_mask(dc
, CC_MASK_NZVC
);
1565 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1566 /* Size can only be qi or hi. */
1567 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1568 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1570 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1574 /* Zero extension. From size to dword. */
1575 static unsigned int dec_subu_r(DisasContext
*dc
)
1577 int size
= memsize_z(dc
);
1578 DIS(fprintf (logfile
, "subu.%c $r%u, $r%u\n",
1582 cris_cc_mask(dc
, CC_MASK_NZVC
);
1583 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1584 /* Size can only be qi or hi. */
1585 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1586 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1587 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1591 /* Sign extension. From size to dword. */
1592 static unsigned int dec_subs_r(DisasContext
*dc
)
1594 int size
= memsize_z(dc
);
1595 DIS(fprintf (logfile
, "subs.%c $r%u, $r%u\n",
1599 cris_cc_mask(dc
, CC_MASK_NZVC
);
1600 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1601 /* Size can only be qi or hi. */
1602 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1603 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1604 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1608 static unsigned int dec_setclrf(DisasContext
*dc
)
1611 int set
= (~dc
->opcode
>> 2) & 1;
1613 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1614 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1615 DIS(fprintf (logfile
, "set=%d flags=%x\n", set
, flags
));
1616 if (set
&& flags
== 0)
1617 DIS(fprintf (logfile
, "nop\n"));
1618 else if (!set
&& (flags
& 0x20))
1619 DIS(fprintf (logfile
, "di\n"));
1621 DIS(fprintf (logfile
, "%sf %x\n",
1622 set
? "set" : "clr",
1625 if (set
&& (flags
& X_FLAG
)) {
1630 /* Simply decode the flags. */
1631 cris_evaluate_flags (dc
);
1632 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1641 static unsigned int dec_move_rs(DisasContext
*dc
)
1643 DIS(fprintf (logfile
, "move $r%u, $s%u\n", dc
->op1
, dc
->op2
));
1644 cris_cc_mask(dc
, 0);
1645 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1646 gen_op_movl_sreg_T0(dc
->op2
);
1648 #if !defined(CONFIG_USER_ONLY)
1650 gen_op_movl_tlb_hi_T0();
1651 else if (dc
->op2
== 5) { /* srs is checked at runtime. */
1652 tcg_gen_helper_0_1(helper_tlb_update
, cpu_T
[0]);
1653 gen_op_movl_tlb_lo_T0();
1658 static unsigned int dec_move_sr(DisasContext
*dc
)
1660 DIS(fprintf (logfile
, "move $s%u, $r%u\n", dc
->op2
, dc
->op1
));
1661 cris_cc_mask(dc
, 0);
1662 gen_op_movl_T0_sreg(dc
->op2
);
1663 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1664 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1667 static unsigned int dec_move_rp(DisasContext
*dc
)
1669 DIS(fprintf (logfile
, "move $r%u, $p%u\n", dc
->op1
, dc
->op2
));
1670 cris_cc_mask(dc
, 0);
1671 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1672 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
1675 static unsigned int dec_move_pr(DisasContext
*dc
)
1677 DIS(fprintf (logfile
, "move $p%u, $r%u\n", dc
->op1
, dc
->op2
));
1678 cris_cc_mask(dc
, 0);
1679 /* Support register 0 is hardwired to zero.
1680 Treat it specially. */
1682 tcg_gen_movi_tl(cpu_T
[1], 0);
1684 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1685 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, preg_sizes
[dc
->op2
]);
1689 static unsigned int dec_move_mr(DisasContext
*dc
)
1691 int memsize
= memsize_zz(dc
);
1693 DIS(fprintf (logfile
, "move.%c [$r%u%s, $r%u\n",
1694 memsize_char(memsize
),
1695 dc
->op1
, dc
->postinc
? "+]" : "]",
1698 cris_cc_mask(dc
, CC_MASK_NZ
);
1699 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1700 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, memsize
);
1701 do_postinc(dc
, memsize
);
1705 static unsigned int dec_movs_m(DisasContext
*dc
)
1707 int memsize
= memsize_z(dc
);
1709 DIS(fprintf (logfile
, "movs.%c [$r%u%s, $r%u\n",
1710 memsize_char(memsize
),
1711 dc
->op1
, dc
->postinc
? "+]" : "]",
1715 cris_cc_mask(dc
, CC_MASK_NZ
);
1716 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1717 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1718 do_postinc(dc
, memsize
);
1722 static unsigned int dec_addu_m(DisasContext
*dc
)
1724 int memsize
= memsize_z(dc
);
1726 DIS(fprintf (logfile
, "addu.%c [$r%u%s, $r%u\n",
1727 memsize_char(memsize
),
1728 dc
->op1
, dc
->postinc
? "+]" : "]",
1732 cris_cc_mask(dc
, CC_MASK_NZVC
);
1733 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1734 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1735 do_postinc(dc
, memsize
);
1739 static unsigned int dec_adds_m(DisasContext
*dc
)
1741 int memsize
= memsize_z(dc
);
1743 DIS(fprintf (logfile
, "adds.%c [$r%u%s, $r%u\n",
1744 memsize_char(memsize
),
1745 dc
->op1
, dc
->postinc
? "+]" : "]",
1749 cris_cc_mask(dc
, CC_MASK_NZVC
);
1750 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1751 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1752 do_postinc(dc
, memsize
);
1756 static unsigned int dec_subu_m(DisasContext
*dc
)
1758 int memsize
= memsize_z(dc
);
1760 DIS(fprintf (logfile
, "subu.%c [$r%u%s, $r%u\n",
1761 memsize_char(memsize
),
1762 dc
->op1
, dc
->postinc
? "+]" : "]",
1766 cris_cc_mask(dc
, CC_MASK_NZVC
);
1767 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1768 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1769 do_postinc(dc
, memsize
);
1773 static unsigned int dec_subs_m(DisasContext
*dc
)
1775 int memsize
= memsize_z(dc
);
1777 DIS(fprintf (logfile
, "subs.%c [$r%u%s, $r%u\n",
1778 memsize_char(memsize
),
1779 dc
->op1
, dc
->postinc
? "+]" : "]",
1783 cris_cc_mask(dc
, CC_MASK_NZVC
);
1784 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1785 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1786 do_postinc(dc
, memsize
);
1790 static unsigned int dec_movu_m(DisasContext
*dc
)
1792 int memsize
= memsize_z(dc
);
1795 DIS(fprintf (logfile
, "movu.%c [$r%u%s, $r%u\n",
1796 memsize_char(memsize
),
1797 dc
->op1
, dc
->postinc
? "+]" : "]",
1800 cris_cc_mask(dc
, CC_MASK_NZ
);
1801 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1802 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1803 do_postinc(dc
, memsize
);
1807 static unsigned int dec_cmpu_m(DisasContext
*dc
)
1809 int memsize
= memsize_z(dc
);
1811 DIS(fprintf (logfile
, "cmpu.%c [$r%u%s, $r%u\n",
1812 memsize_char(memsize
),
1813 dc
->op1
, dc
->postinc
? "+]" : "]",
1816 cris_cc_mask(dc
, CC_MASK_NZVC
);
1817 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1818 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1819 do_postinc(dc
, memsize
);
1823 static unsigned int dec_cmps_m(DisasContext
*dc
)
1825 int memsize
= memsize_z(dc
);
1827 DIS(fprintf (logfile
, "cmps.%c [$r%u%s, $r%u\n",
1828 memsize_char(memsize
),
1829 dc
->op1
, dc
->postinc
? "+]" : "]",
1832 cris_cc_mask(dc
, CC_MASK_NZVC
);
1833 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1834 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1835 do_postinc(dc
, memsize
);
1839 static unsigned int dec_cmp_m(DisasContext
*dc
)
1841 int memsize
= memsize_zz(dc
);
1843 DIS(fprintf (logfile
, "cmp.%c [$r%u%s, $r%u\n",
1844 memsize_char(memsize
),
1845 dc
->op1
, dc
->postinc
? "+]" : "]",
1848 cris_cc_mask(dc
, CC_MASK_NZVC
);
1849 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1850 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1851 do_postinc(dc
, memsize
);
1855 static unsigned int dec_test_m(DisasContext
*dc
)
1857 int memsize
= memsize_zz(dc
);
1859 DIS(fprintf (logfile
, "test.%d [$r%u%s] op2=%x\n",
1860 memsize_char(memsize
),
1861 dc
->op1
, dc
->postinc
? "+]" : "]",
1864 cris_cc_mask(dc
, CC_MASK_NZ
);
1866 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1867 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
1868 tcg_gen_movi_tl(cpu_T
[1], 0);
1869 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1870 do_postinc(dc
, memsize
);
1874 static unsigned int dec_and_m(DisasContext
*dc
)
1876 int memsize
= memsize_zz(dc
);
1878 DIS(fprintf (logfile
, "and.%d [$r%u%s, $r%u\n",
1879 memsize_char(memsize
),
1880 dc
->op1
, dc
->postinc
? "+]" : "]",
1883 cris_cc_mask(dc
, CC_MASK_NZ
);
1884 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1885 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, memsize_zz(dc
));
1886 do_postinc(dc
, memsize
);
1890 static unsigned int dec_add_m(DisasContext
*dc
)
1892 int memsize
= memsize_zz(dc
);
1894 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1895 memsize_char(memsize
),
1896 dc
->op1
, dc
->postinc
? "+]" : "]",
1899 cris_cc_mask(dc
, CC_MASK_NZVC
);
1900 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1901 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, memsize_zz(dc
));
1902 do_postinc(dc
, memsize
);
1906 static unsigned int dec_addo_m(DisasContext
*dc
)
1908 int memsize
= memsize_zz(dc
);
1910 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1911 memsize_char(memsize
),
1912 dc
->op1
, dc
->postinc
? "+]" : "]",
1915 cris_cc_mask(dc
, 0);
1916 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1917 crisv32_alu_op(dc
, CC_OP_ADD
, R_ACR
, 4);
1918 do_postinc(dc
, memsize
);
1922 static unsigned int dec_bound_m(DisasContext
*dc
)
1924 int memsize
= memsize_zz(dc
);
1926 DIS(fprintf (logfile
, "bound.%d [$r%u%s, $r%u\n",
1927 memsize_char(memsize
),
1928 dc
->op1
, dc
->postinc
? "+]" : "]",
1931 cris_cc_mask(dc
, CC_MASK_NZ
);
1932 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1933 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1934 do_postinc(dc
, memsize
);
1938 static unsigned int dec_addc_mr(DisasContext
*dc
)
1941 DIS(fprintf (logfile
, "addc [$r%u%s, $r%u\n",
1942 dc
->op1
, dc
->postinc
? "+]" : "]",
1945 cris_evaluate_flags(dc
);
1946 cris_cc_mask(dc
, CC_MASK_NZVC
);
1947 insn_len
= dec_prep_alu_m(dc
, 0, 4);
1948 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1953 static unsigned int dec_sub_m(DisasContext
*dc
)
1955 int memsize
= memsize_zz(dc
);
1957 DIS(fprintf (logfile
, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1958 memsize_char(memsize
),
1959 dc
->op1
, dc
->postinc
? "+]" : "]",
1960 dc
->op2
, dc
->ir
, dc
->zzsize
));
1962 cris_cc_mask(dc
, CC_MASK_NZVC
);
1963 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1964 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, memsize
);
1965 do_postinc(dc
, memsize
);
1969 static unsigned int dec_or_m(DisasContext
*dc
)
1971 int memsize
= memsize_zz(dc
);
1973 DIS(fprintf (logfile
, "or.%d [$r%u%s, $r%u pc=%x\n",
1974 memsize_char(memsize
),
1975 dc
->op1
, dc
->postinc
? "+]" : "]",
1978 cris_cc_mask(dc
, CC_MASK_NZ
);
1979 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1980 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, memsize_zz(dc
));
1981 do_postinc(dc
, memsize
);
1985 static unsigned int dec_move_mp(DisasContext
*dc
)
1987 int memsize
= memsize_zz(dc
);
1990 DIS(fprintf (logfile
, "move.%c [$r%u%s, $p%u\n",
1991 memsize_char(memsize
),
1993 dc
->postinc
? "+]" : "]",
1996 cris_cc_mask(dc
, 0);
1997 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1998 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[1]);
2000 do_postinc(dc
, memsize
);
2004 static unsigned int dec_move_pm(DisasContext
*dc
)
2008 memsize
= preg_sizes
[dc
->op2
];
2010 DIS(fprintf (logfile
, "move.%c $p%u, [$r%u%s\n",
2011 memsize_char(memsize
),
2012 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]"));
2014 cris_cc_mask(dc
, 0);
2015 /* prepare store. Address in T0, value in T1. */
2016 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
2017 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2018 gen_store_T0_T1(dc
, memsize
);
2021 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2022 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2027 static unsigned int dec_movem_mr(DisasContext
*dc
)
2031 DIS(fprintf (logfile
, "movem [$r%u%s, $r%u\n", dc
->op1
,
2032 dc
->postinc
? "+]" : "]", dc
->op2
));
2034 cris_cc_mask(dc
, 0);
2035 /* fetch the address into T0 and T1. */
2036 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
2037 for (i
= 0; i
<= dc
->op2
; i
++) {
2038 /* Perform the load onto regnum i. Always dword wide. */
2039 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
2040 gen_load_T0_T0(dc
, 4, 0);
2041 t_gen_mov_reg_TN(i
, cpu_T
[0]);
2042 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 4);
2044 /* writeback the updated pointer value. */
2046 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[1]);
2050 static unsigned int dec_movem_rm(DisasContext
*dc
)
2054 DIS(fprintf (logfile
, "movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2055 dc
->postinc
? "+]" : "]"));
2057 cris_cc_mask(dc
, 0);
2058 for (i
= 0; i
<= dc
->op2
; i
++) {
2059 /* Fetch register i into T1. */
2060 t_gen_mov_TN_reg(cpu_T
[1], i
);
2061 /* Fetch the address into T0. */
2062 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2064 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], i
* 4);
2065 /* Perform the store. */
2066 gen_store_T0_T1(dc
, 4);
2069 /* T0 should point to the last written addr, advance one more
2071 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 4);
2072 /* writeback the updated pointer value. */
2073 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2078 static unsigned int dec_move_rm(DisasContext
*dc
)
2082 memsize
= memsize_zz(dc
);
2084 DIS(fprintf (logfile
, "move.%d $r%u, [$r%u]\n",
2085 memsize
, dc
->op2
, dc
->op1
));
2087 cris_cc_mask(dc
, 0);
2088 /* prepare store. */
2089 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2090 t_gen_mov_TN_reg(cpu_T
[1], dc
->op2
);
2091 gen_store_T0_T1(dc
, memsize
);
2094 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2095 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2100 static unsigned int dec_lapcq(DisasContext
*dc
)
2102 DIS(fprintf (logfile
, "lapcq %x, $r%u\n",
2103 dc
->pc
+ dc
->op1
*2, dc
->op2
));
2104 cris_cc_mask(dc
, 0);
2105 tcg_gen_movi_tl(cpu_T
[1], dc
->pc
+ dc
->op1
* 2);
2106 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
2110 static unsigned int dec_lapc_im(DisasContext
*dc
)
2117 cris_cc_mask(dc
, 0);
2118 imm
= ldl_code(dc
->pc
+ 2);
2119 DIS(fprintf (logfile
, "lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
));
2120 t_gen_mov_reg_TN(rd
, tcg_const_tl(dc
->pc
+ imm
));
2124 /* Jump to special reg. */
2125 static unsigned int dec_jump_p(DisasContext
*dc
)
2127 DIS(fprintf (logfile
, "jump $p%u\n", dc
->op2
));
2128 cris_cc_mask(dc
, 0);
2129 /* Store the return address in Pd. */
2130 t_gen_mov_TN_preg(cpu_T
[0], dc
->op2
);
2131 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2132 cris_prepare_dyn_jmp(dc
);
2136 /* Jump and save. */
2137 static unsigned int dec_jas_r(DisasContext
*dc
)
2139 DIS(fprintf (logfile
, "jas $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2140 cris_cc_mask(dc
, 0);
2141 /* Stor the return address in Pd. */
2142 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2143 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2144 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 4);
2145 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2146 cris_prepare_dyn_jmp(dc
);
2150 static unsigned int dec_jas_im(DisasContext
*dc
)
2154 imm
= ldl_code(dc
->pc
+ 2);
2156 DIS(fprintf (logfile
, "jas 0x%x\n", imm
));
2157 cris_cc_mask(dc
, 0);
2158 /* Stor the return address in Pd. */
2159 t_gen_mov_env_TN(btarget
, tcg_const_tl(imm
));
2160 t_gen_mov_preg_TN(dc
->op2
, tcg_const_tl(dc
->pc
+ 8));
2161 cris_prepare_dyn_jmp(dc
);
2165 static unsigned int dec_jasc_im(DisasContext
*dc
)
2169 imm
= ldl_code(dc
->pc
+ 2);
2171 DIS(fprintf (logfile
, "jasc 0x%x\n", imm
));
2172 cris_cc_mask(dc
, 0);
2173 /* Stor the return address in Pd. */
2174 tcg_gen_movi_tl(cpu_T
[0], imm
);
2175 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2176 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8 + 4);
2177 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2178 cris_prepare_dyn_jmp(dc
);
2182 static unsigned int dec_jasc_r(DisasContext
*dc
)
2184 DIS(fprintf (logfile
, "jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2185 cris_cc_mask(dc
, 0);
2186 /* Stor the return address in Pd. */
2187 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2188 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2189 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 4 + 4);
2190 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2191 cris_prepare_dyn_jmp(dc
);
2195 static unsigned int dec_bcc_im(DisasContext
*dc
)
2198 uint32_t cond
= dc
->op2
;
2200 offset
= ldl_code(dc
->pc
+ 2);
2201 offset
= sign_extend(offset
, 15);
2203 DIS(fprintf (logfile
, "b%s %d pc=%x dst=%x\n",
2204 cc_name(cond
), offset
,
2205 dc
->pc
, dc
->pc
+ offset
));
2207 cris_cc_mask(dc
, 0);
2208 /* op2 holds the condition-code. */
2209 cris_prepare_cc_branch (dc
, offset
, cond
);
2213 static unsigned int dec_bas_im(DisasContext
*dc
)
2218 simm
= ldl_code(dc
->pc
+ 2);
2220 DIS(fprintf (logfile
, "bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2221 cris_cc_mask(dc
, 0);
2222 /* Stor the return address in Pd. */
2223 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2224 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2225 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8);
2226 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2227 cris_prepare_dyn_jmp(dc
);
2231 static unsigned int dec_basc_im(DisasContext
*dc
)
2234 simm
= ldl_code(dc
->pc
+ 2);
2236 DIS(fprintf (logfile
, "basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2237 cris_cc_mask(dc
, 0);
2238 /* Stor the return address in Pd. */
2239 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2240 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2241 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 12);
2242 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2243 cris_prepare_dyn_jmp(dc
);
2247 static unsigned int dec_rfe_etc(DisasContext
*dc
)
2249 DIS(fprintf (logfile
, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2250 dc
->opcode
, dc
->pc
, dc
->op1
, dc
->op2
));
2252 cris_cc_mask(dc
, 0);
2254 if (dc
->op2
== 15) /* ignore halt. */
2257 switch (dc
->op2
& 7) {
2260 cris_evaluate_flags(dc
);
2261 gen_op_ccs_rshift();
2269 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2270 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2271 /* Breaks start at 16 in the exception vector. */
2272 gen_op_break_im(dc
->op1
+ 16);
2273 dc
->is_jmp
= DISAS_SWI
;
2276 printf ("op2=%x\n", dc
->op2
);
2284 static unsigned int dec_ftag_fidx_d_m(DisasContext
*dc
)
2286 /* Ignore D-cache flushes. */
2290 static unsigned int dec_ftag_fidx_i_m(DisasContext
*dc
)
2292 /* Ignore I-cache flushes. */
2296 static unsigned int dec_null(DisasContext
*dc
)
2298 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2299 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2305 struct decoder_info
{
2310 unsigned int (*dec
)(DisasContext
*dc
);
2312 /* Order matters here. */
2313 {DEC_MOVEQ
, dec_moveq
},
2314 {DEC_BTSTQ
, dec_btstq
},
2315 {DEC_CMPQ
, dec_cmpq
},
2316 {DEC_ADDOQ
, dec_addoq
},
2317 {DEC_ADDQ
, dec_addq
},
2318 {DEC_SUBQ
, dec_subq
},
2319 {DEC_ANDQ
, dec_andq
},
2321 {DEC_ASRQ
, dec_asrq
},
2322 {DEC_LSLQ
, dec_lslq
},
2323 {DEC_LSRQ
, dec_lsrq
},
2324 {DEC_BCCQ
, dec_bccq
},
2326 {DEC_BCC_IM
, dec_bcc_im
},
2327 {DEC_JAS_IM
, dec_jas_im
},
2328 {DEC_JAS_R
, dec_jas_r
},
2329 {DEC_JASC_IM
, dec_jasc_im
},
2330 {DEC_JASC_R
, dec_jasc_r
},
2331 {DEC_BAS_IM
, dec_bas_im
},
2332 {DEC_BASC_IM
, dec_basc_im
},
2333 {DEC_JUMP_P
, dec_jump_p
},
2334 {DEC_LAPC_IM
, dec_lapc_im
},
2335 {DEC_LAPCQ
, dec_lapcq
},
2337 {DEC_RFE_ETC
, dec_rfe_etc
},
2338 {DEC_ADDC_MR
, dec_addc_mr
},
2340 {DEC_MOVE_MP
, dec_move_mp
},
2341 {DEC_MOVE_PM
, dec_move_pm
},
2342 {DEC_MOVEM_MR
, dec_movem_mr
},
2343 {DEC_MOVEM_RM
, dec_movem_rm
},
2344 {DEC_MOVE_PR
, dec_move_pr
},
2345 {DEC_SCC_R
, dec_scc_r
},
2346 {DEC_SETF
, dec_setclrf
},
2347 {DEC_CLEARF
, dec_setclrf
},
2349 {DEC_MOVE_SR
, dec_move_sr
},
2350 {DEC_MOVE_RP
, dec_move_rp
},
2351 {DEC_SWAP_R
, dec_swap_r
},
2352 {DEC_ABS_R
, dec_abs_r
},
2353 {DEC_LZ_R
, dec_lz_r
},
2354 {DEC_MOVE_RS
, dec_move_rs
},
2355 {DEC_BTST_R
, dec_btst_r
},
2356 {DEC_ADDC_R
, dec_addc_r
},
2358 {DEC_DSTEP_R
, dec_dstep_r
},
2359 {DEC_XOR_R
, dec_xor_r
},
2360 {DEC_MCP_R
, dec_mcp_r
},
2361 {DEC_CMP_R
, dec_cmp_r
},
2363 {DEC_ADDI_R
, dec_addi_r
},
2364 {DEC_ADDI_ACR
, dec_addi_acr
},
2366 {DEC_ADD_R
, dec_add_r
},
2367 {DEC_SUB_R
, dec_sub_r
},
2369 {DEC_ADDU_R
, dec_addu_r
},
2370 {DEC_ADDS_R
, dec_adds_r
},
2371 {DEC_SUBU_R
, dec_subu_r
},
2372 {DEC_SUBS_R
, dec_subs_r
},
2373 {DEC_LSL_R
, dec_lsl_r
},
2375 {DEC_AND_R
, dec_and_r
},
2376 {DEC_OR_R
, dec_or_r
},
2377 {DEC_BOUND_R
, dec_bound_r
},
2378 {DEC_ASR_R
, dec_asr_r
},
2379 {DEC_LSR_R
, dec_lsr_r
},
2381 {DEC_MOVU_R
, dec_movu_r
},
2382 {DEC_MOVS_R
, dec_movs_r
},
2383 {DEC_NEG_R
, dec_neg_r
},
2384 {DEC_MOVE_R
, dec_move_r
},
2386 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2387 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2389 {DEC_MULS_R
, dec_muls_r
},
2390 {DEC_MULU_R
, dec_mulu_r
},
2392 {DEC_ADDU_M
, dec_addu_m
},
2393 {DEC_ADDS_M
, dec_adds_m
},
2394 {DEC_SUBU_M
, dec_subu_m
},
2395 {DEC_SUBS_M
, dec_subs_m
},
2397 {DEC_CMPU_M
, dec_cmpu_m
},
2398 {DEC_CMPS_M
, dec_cmps_m
},
2399 {DEC_MOVU_M
, dec_movu_m
},
2400 {DEC_MOVS_M
, dec_movs_m
},
2402 {DEC_CMP_M
, dec_cmp_m
},
2403 {DEC_ADDO_M
, dec_addo_m
},
2404 {DEC_BOUND_M
, dec_bound_m
},
2405 {DEC_ADD_M
, dec_add_m
},
2406 {DEC_SUB_M
, dec_sub_m
},
2407 {DEC_AND_M
, dec_and_m
},
2408 {DEC_OR_M
, dec_or_m
},
2409 {DEC_MOVE_RM
, dec_move_rm
},
2410 {DEC_TEST_M
, dec_test_m
},
2411 {DEC_MOVE_MR
, dec_move_mr
},
2416 static inline unsigned int
2417 cris_decoder(DisasContext
*dc
)
2419 unsigned int insn_len
= 2;
2423 /* Load a halfword onto the instruction register. */
2424 tmp
= ldl_code(dc
->pc
);
2425 dc
->ir
= tmp
& 0xffff;
2427 /* Now decode it. */
2428 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2429 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2430 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2431 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2432 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2433 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2435 /* Large switch for all insns. */
2436 for (i
= 0; i
< sizeof decinfo
/ sizeof decinfo
[0]; i
++) {
2437 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
)
2439 insn_len
= decinfo
[i
].dec(dc
);
2447 static void check_breakpoint(CPUState
*env
, DisasContext
*dc
)
2450 if (env
->nb_breakpoints
> 0) {
2451 for(j
= 0; j
< env
->nb_breakpoints
; j
++) {
2452 if (env
->breakpoints
[j
] == dc
->pc
) {
2453 cris_evaluate_flags (dc
);
2454 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2455 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2457 dc
->is_jmp
= DISAS_UPDATE
;
2463 /* generate intermediate code for basic block 'tb'. */
2464 struct DisasContext ctx
;
2466 gen_intermediate_code_internal(CPUState
*env
, TranslationBlock
*tb
,
2469 uint16_t *gen_opc_end
;
2471 unsigned int insn_len
;
2473 struct DisasContext
*dc
= &ctx
;
2474 uint32_t next_page_start
;
2483 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
2485 dc
->is_jmp
= DISAS_NEXT
;
2487 dc
->singlestep_enabled
= env
->singlestep_enabled
;
2491 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
2495 check_breakpoint(env
, dc
);
2496 if (dc
->is_jmp
== DISAS_JUMP
2497 || dc
->is_jmp
== DISAS_SWI
)
2501 j
= gen_opc_ptr
- gen_opc_buf
;
2505 gen_opc_instr_start
[lj
++] = 0;
2507 gen_opc_pc
[lj
] = dc
->pc
;
2508 gen_opc_instr_start
[lj
] = 1;
2511 insn_len
= cris_decoder(dc
);
2512 STATS(gen_op_exec_insn());
2514 cris_clear_x_flag(dc
);
2516 /* Check for delayed branches here. If we do it before
2517 actually genereating any host code, the simulator will just
2518 loop doing nothing for on this program location. */
2519 if (dc
->delayed_branch
) {
2520 dc
->delayed_branch
--;
2521 if (dc
->delayed_branch
== 0)
2523 if (dc
->bcc
== CC_A
) {
2525 dc
->is_jmp
= DISAS_UPDATE
;
2528 /* Conditional jmp. */
2529 gen_op_cc_jmp (dc
->delayed_pc
, dc
->pc
);
2530 dc
->is_jmp
= DISAS_UPDATE
;
2535 if (env
->singlestep_enabled
)
2537 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
2538 && dc
->pc
< next_page_start
);
2541 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2542 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2545 cris_evaluate_flags (dc
);
2547 if (__builtin_expect(env
->singlestep_enabled
, 0)) {
2550 switch(dc
->is_jmp
) {
2552 gen_goto_tb(dc
, 1, dc
->pc
);
2557 /* indicate that the hash table must be used
2558 to find the next TB */
2563 /* nothing more to generate */
2567 *gen_opc_ptr
= INDEX_op_end
;
2569 j
= gen_opc_ptr
- gen_opc_buf
;
2572 gen_opc_instr_start
[lj
++] = 0;
2574 tb
->size
= dc
->pc
- pc_start
;
2578 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
2579 fprintf(logfile
, "--------------\n");
2580 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
2581 target_disas(logfile
, pc_start
, dc
->pc
+ 4 - pc_start
, 0);
2582 fprintf(logfile
, "\n");
2588 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
2590 return gen_intermediate_code_internal(env
, tb
, 0);
2593 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
2595 return gen_intermediate_code_internal(env
, tb
, 1);
2598 void cpu_dump_state (CPUState
*env
, FILE *f
,
2599 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
2608 cpu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2609 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2611 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
2613 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
,
2614 env
->debug1
, env
->debug2
, env
->debug3
);
2616 for (i
= 0; i
< 16; i
++) {
2617 cpu_fprintf(f
, "r%2.2d=%8.8x ", i
, env
->regs
[i
]);
2618 if ((i
+ 1) % 4 == 0)
2619 cpu_fprintf(f
, "\n");
2621 cpu_fprintf(f
, "\nspecial regs:\n");
2622 for (i
= 0; i
< 16; i
++) {
2623 cpu_fprintf(f
, "p%2.2d=%8.8x ", i
, env
->pregs
[i
]);
2624 if ((i
+ 1) % 4 == 0)
2625 cpu_fprintf(f
, "\n");
2627 srs
= env
->pregs
[PR_SRS
];
2628 cpu_fprintf(f
, "\nsupport function regs bank %d:\n", srs
);
2630 for (i
= 0; i
< 16; i
++) {
2631 cpu_fprintf(f
, "s%2.2d=%8.8x ",
2632 i
, env
->sregs
[srs
][i
]);
2633 if ((i
+ 1) % 4 == 0)
2634 cpu_fprintf(f
, "\n");
2637 cpu_fprintf(f
, "\n\n");
2641 static void tcg_macro_func(TCGContext
*s
, int macro_id
, const int *dead_args
)
2645 CPUCRISState
*cpu_cris_init (const char *cpu_model
)
2650 env
= qemu_mallocz(sizeof(CPUCRISState
));
2655 tcg_set_macro_func(&tcg_ctx
, tcg_macro_func
);
2656 cpu_env
= tcg_global_reg_new(TCG_TYPE_PTR
, TCG_AREG0
, "env");
2657 #if TARGET_LONG_BITS > HOST_LONG_BITS
2658 cpu_T
[0] = tcg_global_mem_new(TCG_TYPE_TL
,
2659 TCG_AREG0
, offsetof(CPUState
, t0
), "T0");
2660 cpu_T
[1] = tcg_global_mem_new(TCG_TYPE_TL
,
2661 TCG_AREG0
, offsetof(CPUState
, t1
), "T1");
2663 cpu_T
[0] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG1
, "T0");
2664 cpu_T
[1] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG2
, "T1");
2667 cc_src
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2668 offsetof(CPUState
, cc_src
), "cc_src");
2669 cc_dest
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2670 offsetof(CPUState
, cc_dest
),
2672 cc_result
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2673 offsetof(CPUState
, cc_result
),
2675 cc_op
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2676 offsetof(CPUState
, cc_op
), "cc_op");
2677 cc_size
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2678 offsetof(CPUState
, cc_size
),
2680 cc_mask
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2681 offsetof(CPUState
, cc_mask
),
2684 for (i
= 0; i
< 16; i
++) {
2685 cpu_R
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2686 offsetof(CPUState
, regs
[i
]),
2689 for (i
= 0; i
< 16; i
++) {
2690 cpu_PR
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2691 offsetof(CPUState
, pregs
[i
]),
2699 void cpu_reset (CPUCRISState
*env
)
2701 memset(env
, 0, offsetof(CPUCRISState
, breakpoints
));