2 * CRIS emulation for qemu: main translation routines.
4 * Copyright (c) 2007 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
23 * This file implements a CRIS decoder-stage in SW. The decoder translates the
24 * guest (CRIS) machine-code into host machine code via dyngen using the
25 * micro-operations described in op.c
27 * The micro-operations for CRIS translation implement a RISC style ISA.
28 * Note that the micro-operations typically order their operands
29 * starting with the dst. CRIS asm, does the opposite.
31 * For example the following CRIS code:
36 * gen_movl_T0_reg(0); // Fetch $r0 into T0
37 * gen_load_T0_T0(); // Load T0, @T0
38 * gen_movl_reg_T0(1); // Writeback T0 into $r1
40 * The actual names for the micro-code generators vary but the example
41 * illustrates the point.
54 #include "crisv32-decode.h"
70 #ifdef USE_DIRECT_JUMP
73 #define TBPARAM(x) (long)(x)
76 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
77 #define BUG_ON(x) ({if (x) BUG();})
79 /* Used by the decoder. */
80 #define EXTRACT_FIELD(src, start, end) \
81 (((src) >> start) & ((1 << (end - start + 1)) - 1))
83 #define CC_MASK_NZ 0xc
84 #define CC_MASK_NZV 0xe
85 #define CC_MASK_NZVC 0xf
86 #define CC_MASK_RNZV 0x10e
88 static uint16_t *gen_opc_ptr
;
89 static uint32_t *gen_opparam_ptr
;
92 #define DEF(s, n, copy_size) INDEX_op_ ## s,
99 /* This is the state at translation time. */
100 typedef struct DisasContext
{
102 target_ulong pc
, insn_pc
;
109 unsigned int zsize
, zzsize
;
111 unsigned int postinc
;
129 uint32_t tb_entry_flags
;
131 int memidx
; /* user or kernel mode. */
140 struct TranslationBlock
*tb
;
141 int singlestep_enabled
;
144 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
);
145 static void gen_BUG(DisasContext
*dc
, char *file
, int line
)
147 printf ("BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
148 fprintf (logfile
, "BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
149 cpu_dump_state (dc
->env
, stdout
, fprintf
, 0);
151 cris_prepare_jmp (dc
, 0x70000000 + line
);
154 /* Table to generate quick moves from T0 onto any register. */
155 static GenOpFunc
*gen_movl_reg_T0
[16] =
157 gen_op_movl_r0_T0
, gen_op_movl_r1_T0
,
158 gen_op_movl_r2_T0
, gen_op_movl_r3_T0
,
159 gen_op_movl_r4_T0
, gen_op_movl_r5_T0
,
160 gen_op_movl_r6_T0
, gen_op_movl_r7_T0
,
161 gen_op_movl_r8_T0
, gen_op_movl_r9_T0
,
162 gen_op_movl_r10_T0
, gen_op_movl_r11_T0
,
163 gen_op_movl_r12_T0
, gen_op_movl_r13_T0
,
164 gen_op_movl_r14_T0
, gen_op_movl_r15_T0
,
166 static GenOpFunc
*gen_movl_T0_reg
[16] =
168 gen_op_movl_T0_r0
, gen_op_movl_T0_r1
,
169 gen_op_movl_T0_r2
, gen_op_movl_T0_r3
,
170 gen_op_movl_T0_r4
, gen_op_movl_T0_r5
,
171 gen_op_movl_T0_r6
, gen_op_movl_T0_r7
,
172 gen_op_movl_T0_r8
, gen_op_movl_T0_r9
,
173 gen_op_movl_T0_r10
, gen_op_movl_T0_r11
,
174 gen_op_movl_T0_r12
, gen_op_movl_T0_r13
,
175 gen_op_movl_T0_r14
, gen_op_movl_T0_r15
,
178 static void noop_write(void) {
182 static void gen_vr_read(void) {
183 gen_op_movl_T0_im(32);
186 static void gen_ccs_read(void) {
187 gen_op_movl_T0_p13();
190 static void gen_ccs_write(void) {
191 gen_op_movl_p13_T0();
194 /* Table to generate quick moves from T0 onto any register. */
195 static GenOpFunc
*gen_movl_preg_T0
[16] =
197 noop_write
, /* bz, not writeable. */
198 noop_write
, /* vr, not writeable. */
199 gen_op_movl_p2_T0
, gen_op_movl_p3_T0
,
200 noop_write
, /* wz, not writeable. */
202 gen_op_movl_p6_T0
, gen_op_movl_p7_T0
,
203 noop_write
, /* dz, not writeable. */
205 gen_op_movl_p10_T0
, gen_op_movl_p11_T0
,
207 gen_ccs_write
, /* ccs needs special treatment. */
208 gen_op_movl_p14_T0
, gen_op_movl_p15_T0
,
210 static GenOpFunc
*gen_movl_T0_preg
[16] =
214 gen_op_movl_T0_p2
, gen_op_movl_T0_p3
,
215 gen_op_movl_T0_p4
, gen_op_movl_T0_p5
,
216 gen_op_movl_T0_p6
, gen_op_movl_T0_p7
,
217 gen_op_movl_T0_p8
, gen_op_movl_T0_p9
,
218 gen_op_movl_T0_p10
, gen_op_movl_T0_p11
,
220 gen_ccs_read
, /* ccs needs special treatment. */
221 gen_op_movl_T0_p14
, gen_op_movl_T0_p15
,
224 /* We need this table to handle moves with implicit width. */
236 #ifdef CONFIG_USER_ONLY
237 #define GEN_OP_LD(width, reg) \
238 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
239 gen_op_ld##width##_T0_##reg##_raw(); \
241 #define GEN_OP_ST(width, reg) \
242 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
243 gen_op_st##width##_##reg##_T1_raw(); \
246 #define GEN_OP_LD(width, reg) \
247 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
248 if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
249 else gen_op_ld##width##_T0_##reg##_user();\
251 #define GEN_OP_ST(width, reg) \
252 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
253 if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
254 else gen_op_st##width##_##reg##_T1_user();\
267 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
269 TranslationBlock
*tb
;
271 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
273 gen_op_goto_tb0(TBPARAM(tb
));
275 gen_op_goto_tb1(TBPARAM(tb
));
283 /* Sign extend at translation time. */
284 static int sign_extend(unsigned int val
, unsigned int width
)
296 static void cris_evaluate_flags(DisasContext
*dc
)
298 if (!dc
->flags_live
) {
303 gen_op_evaluate_flags_mcp ();
306 gen_op_evaluate_flags_muls ();
309 gen_op_evaluate_flags_mulu ();
315 gen_op_evaluate_flags_move_4();
318 gen_op_evaluate_flags_move_2();
321 gen_op_evaluate_flags ();
331 gen_op_evaluate_flags_alu_4 ();
334 gen_op_evaluate_flags ();
344 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
348 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
350 /* TODO: optimize this case. It trigs all the time. */
351 cris_evaluate_flags (dc
);
359 gen_op_update_cc_mask(mask
);
364 static void cris_update_cc_op(DisasContext
*dc
, int op
)
367 gen_op_update_cc_op(op
);
370 static void cris_update_cc_size(DisasContext
*dc
, int size
)
373 gen_op_update_cc_size_im(size
);
376 /* op is the operation.
377 T0, T1 are the operands.
378 dst is the destination reg.
380 static void crisv32_alu_op(DisasContext
*dc
, int op
, int rd
, int size
)
384 cris_update_cc_op(dc
, op
);
385 cris_update_cc_size(dc
, size
);
386 gen_op_update_cc_x(dc
->flagx_live
, dc
->flags_x
);
387 gen_op_update_cc_dest_T0();
390 /* Emit the ALU insns. */
395 /* Extended arithmetics. */
398 else if (dc
->flags_x
)
412 /* CRIS flag evaluation needs ~src. */
416 /* Extended arithmetics. */
419 else if (dc
->flags_x
)
445 /* Extended arithmetics. */
462 gen_op_dstep_T0_T1();
465 gen_op_bound_T0_T1();
470 /* CRIS flag evaluation needs ~src. */
474 /* Extended arithmetics. */
479 fprintf (logfile
, "illegal ALU op.\n");
485 gen_op_update_cc_src_T1();
488 gen_op_andl_T0_im(0xff);
490 gen_op_andl_T0_im(0xffff);
494 gen_movl_reg_T0
[rd
]();
497 gen_movl_T0_reg
[rd
]();
499 gen_op_andl_T0_im(~0xff);
501 gen_op_andl_T0_im(~0xffff);
503 gen_movl_reg_T0
[rd
]();
508 gen_op_update_cc_result_T0();
511 /* TODO: Optimize this. */
513 cris_evaluate_flags(dc
);
517 static int arith_cc(DisasContext
*dc
)
521 case CC_OP_ADD
: return 1;
522 case CC_OP_SUB
: return 1;
523 case CC_OP_LSL
: return 1;
524 case CC_OP_LSR
: return 1;
525 case CC_OP_ASR
: return 1;
526 case CC_OP_CMP
: return 1;
534 static void gen_tst_cc (DisasContext
*dc
, int cond
)
538 /* TODO: optimize more condition codes. */
539 arith_opt
= arith_cc(dc
) && !dc
->flags_live
;
543 gen_op_tst_cc_eq_fast ();
545 cris_evaluate_flags(dc
);
551 gen_op_tst_cc_ne_fast ();
553 cris_evaluate_flags(dc
);
558 cris_evaluate_flags(dc
);
562 cris_evaluate_flags(dc
);
566 cris_evaluate_flags(dc
);
570 cris_evaluate_flags(dc
);
575 gen_op_tst_cc_pl_fast ();
577 cris_evaluate_flags(dc
);
583 gen_op_tst_cc_mi_fast ();
585 cris_evaluate_flags(dc
);
590 cris_evaluate_flags(dc
);
594 cris_evaluate_flags(dc
);
598 cris_evaluate_flags(dc
);
602 cris_evaluate_flags(dc
);
606 cris_evaluate_flags(dc
);
610 cris_evaluate_flags(dc
);
614 cris_evaluate_flags(dc
);
618 cris_evaluate_flags(dc
);
619 gen_op_movl_T0_im (1);
627 static void cris_prepare_cc_branch (DisasContext
*dc
, int offset
, int cond
)
629 /* This helps us re-schedule the micro-code to insns in delay-slots
630 before the actual jump. */
631 dc
->delayed_branch
= 2;
632 dc
->delayed_pc
= dc
->pc
+ offset
;
636 gen_tst_cc (dc
, cond
);
637 gen_op_evaluate_bcc ();
639 gen_op_movl_T0_im (dc
->delayed_pc
);
640 gen_op_movl_btarget_T0 ();
643 /* Dynamic jumps, when the dest is in a live reg for example. */
644 void cris_prepare_dyn_jmp (DisasContext
*dc
)
646 /* This helps us re-schedule the micro-code to insns in delay-slots
647 before the actual jump. */
648 dc
->delayed_branch
= 2;
653 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
)
655 /* This helps us re-schedule the micro-code to insns in delay-slots
656 before the actual jump. */
657 dc
->delayed_branch
= 2;
658 dc
->delayed_pc
= dst
;
663 void gen_load_T0_T0 (DisasContext
*dc
, unsigned int size
, int sign
)
667 gen_op_ldb_T0_T0(dc
);
669 gen_op_ldub_T0_T0(dc
);
671 else if (size
== 2) {
673 gen_op_ldw_T0_T0(dc
);
675 gen_op_lduw_T0_T0(dc
);
678 gen_op_ldl_T0_T0(dc
);
682 void gen_store_T0_T1 (DisasContext
*dc
, unsigned int size
)
684 /* Remember, operands are flipped. CRIS has reversed order. */
686 gen_op_stb_T0_T1(dc
);
688 else if (size
== 2) {
689 gen_op_stw_T0_T1(dc
);
692 gen_op_stl_T0_T1(dc
);
695 /* sign extend T1 according to size. */
696 static void gen_sext_T1_T0(int size
)
704 static void gen_sext_T1_T1(int size
)
712 static void gen_sext_T0_T0(int size
)
720 static void gen_zext_T0_T0(int size
)
723 gen_op_zextb_T0_T0();
725 gen_op_zextw_T0_T0();
728 static void gen_zext_T1_T0(int size
)
731 gen_op_zextb_T1_T0();
733 gen_op_zextw_T1_T0();
736 static void gen_zext_T1_T1(int size
)
739 gen_op_zextb_T1_T1();
741 gen_op_zextw_T1_T1();
745 static char memsize_char(int size
)
749 case 1: return 'b'; break;
750 case 2: return 'w'; break;
751 case 4: return 'd'; break;
759 static unsigned int memsize_z(DisasContext
*dc
)
761 return dc
->zsize
+ 1;
764 static unsigned int memsize_zz(DisasContext
*dc
)
775 static void do_postinc (DisasContext
*dc
, int size
)
779 gen_movl_T0_reg
[dc
->op1
]();
780 gen_op_addl_T0_im(size
);
781 gen_movl_reg_T0
[dc
->op1
]();
785 static void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
788 gen_movl_T0_reg
[rs
]();
791 gen_sext_T1_T1(size
);
793 gen_zext_T1_T1(size
);
796 /* Prepare T0 and T1 for a register alu operation.
797 s_ext decides if the operand1 should be sign-extended or zero-extended when
799 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
802 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
);
804 gen_movl_T0_reg
[rd
]();
806 gen_sext_T0_T0(size
);
808 gen_zext_T0_T0(size
);
811 /* Prepare T0 and T1 for a memory + alu operation.
812 s_ext decides if the operand1 should be sign-extended or zero-extended when
814 static int dec_prep_alu_m(DisasContext
*dc
, int s_ext
, int memsize
)
823 is_imm
= rs
== 15 && dc
->postinc
;
825 /* Load [$rs] onto T1. */
827 insn_len
= 2 + memsize
;
831 imm
= ldl_code(dc
->pc
+ 2);
834 imm
= sign_extend(imm
, (memsize
* 8) - 1);
842 DIS(fprintf (logfile
, "imm=%x rd=%d sext=%d ms=%d\n",
843 imm
, rd
, s_ext
, memsize
));
844 gen_op_movl_T1_im (imm
);
847 gen_movl_T0_reg
[rs
]();
848 gen_load_T0_T0(dc
, memsize
, 0);
851 gen_sext_T1_T1(memsize
);
853 gen_zext_T1_T1(memsize
);
856 /* put dest in T0. */
857 gen_movl_T0_reg
[rd
]();
862 static const char *cc_name(int cc
)
864 static char *cc_names
[16] = {
865 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
866 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
873 static unsigned int dec_bccq(DisasContext
*dc
)
877 uint32_t cond
= dc
->op2
;
880 offset
= EXTRACT_FIELD (dc
->ir
, 1, 7);
881 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
886 offset
= sign_extend(offset
, 8);
888 /* op2 holds the condition-code. */
890 cris_prepare_cc_branch (dc
, offset
, cond
);
893 static unsigned int dec_addoq(DisasContext
*dc
)
897 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
898 imm
= sign_extend(dc
->op1
, 7);
900 DIS(fprintf (logfile
, "addoq %d, $r%u\n", imm
, dc
->op2
));
902 /* Fetch register operand, */
903 gen_movl_T0_reg
[dc
->op2
]();
904 gen_op_movl_T1_im(imm
);
905 crisv32_alu_op(dc
, CC_OP_ADD
, REG_ACR
, 4);
908 static unsigned int dec_addq(DisasContext
*dc
)
910 DIS(fprintf (logfile
, "addq %u, $r%u\n", dc
->op1
, dc
->op2
));
912 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
914 cris_cc_mask(dc
, CC_MASK_NZVC
);
915 /* Fetch register operand, */
916 gen_movl_T0_reg
[dc
->op2
]();
917 gen_op_movl_T1_im(dc
->op1
);
918 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
921 static unsigned int dec_moveq(DisasContext
*dc
)
925 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
926 imm
= sign_extend(dc
->op1
, 5);
927 DIS(fprintf (logfile
, "moveq %d, $r%u\n", imm
, dc
->op2
));
930 gen_op_movl_T1_im(imm
);
931 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
935 static unsigned int dec_subq(DisasContext
*dc
)
937 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
939 DIS(fprintf (logfile
, "subq %u, $r%u\n", dc
->op1
, dc
->op2
));
941 cris_cc_mask(dc
, CC_MASK_NZVC
);
942 /* Fetch register operand, */
943 gen_movl_T0_reg
[dc
->op2
]();
944 gen_op_movl_T1_im(dc
->op1
);
945 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
948 static unsigned int dec_cmpq(DisasContext
*dc
)
951 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
952 imm
= sign_extend(dc
->op1
, 5);
954 DIS(fprintf (logfile
, "cmpq %d, $r%d\n", imm
, dc
->op2
));
955 cris_cc_mask(dc
, CC_MASK_NZVC
);
956 gen_movl_T0_reg
[dc
->op2
]();
957 gen_op_movl_T1_im(imm
);
958 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
961 static unsigned int dec_andq(DisasContext
*dc
)
964 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
965 imm
= sign_extend(dc
->op1
, 5);
967 DIS(fprintf (logfile
, "andq %d, $r%d\n", imm
, dc
->op2
));
968 cris_cc_mask(dc
, CC_MASK_NZ
);
969 gen_movl_T0_reg
[dc
->op2
]();
970 gen_op_movl_T1_im(imm
);
971 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, 4);
974 static unsigned int dec_orq(DisasContext
*dc
)
977 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
978 imm
= sign_extend(dc
->op1
, 5);
979 DIS(fprintf (logfile
, "orq %d, $r%d\n", imm
, dc
->op2
));
980 cris_cc_mask(dc
, CC_MASK_NZ
);
981 gen_movl_T0_reg
[dc
->op2
]();
982 gen_op_movl_T1_im(imm
);
983 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, 4);
986 static unsigned int dec_btstq(DisasContext
*dc
)
988 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
989 DIS(fprintf (logfile
, "btstq %u, $r%d\n", dc
->op1
, dc
->op2
));
990 cris_evaluate_flags(dc
);
991 cris_cc_mask(dc
, CC_MASK_NZ
);
992 gen_movl_T0_reg
[dc
->op2
]();
993 gen_op_movl_T1_im(dc
->op1
);
994 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
996 cris_update_cc_op(dc
, CC_OP_FLAGS
);
997 gen_op_movl_flags_T0();
1001 static unsigned int dec_asrq(DisasContext
*dc
)
1003 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1004 DIS(fprintf (logfile
, "asrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1005 cris_cc_mask(dc
, CC_MASK_NZ
);
1006 gen_movl_T0_reg
[dc
->op2
]();
1007 gen_op_movl_T1_im(dc
->op1
);
1008 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, 4);
1011 static unsigned int dec_lslq(DisasContext
*dc
)
1013 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1014 DIS(fprintf (logfile
, "lslq %u, $r%d\n", dc
->op1
, dc
->op2
));
1016 cris_cc_mask(dc
, CC_MASK_NZ
);
1017 gen_movl_T0_reg
[dc
->op2
]();
1018 gen_op_movl_T1_im(dc
->op1
);
1019 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, 4);
1022 static unsigned int dec_lsrq(DisasContext
*dc
)
1024 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1025 DIS(fprintf (logfile
, "lsrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1027 cris_cc_mask(dc
, CC_MASK_NZ
);
1028 gen_movl_T0_reg
[dc
->op2
]();
1029 gen_op_movl_T1_im(dc
->op1
);
1030 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, 4);
1034 static unsigned int dec_move_r(DisasContext
*dc
)
1036 int size
= memsize_zz(dc
);
1038 DIS(fprintf (logfile
, "move.%c $r%u, $r%u\n",
1039 memsize_char(size
), dc
->op1
, dc
->op2
));
1041 cris_cc_mask(dc
, CC_MASK_NZ
);
1042 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1043 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, size
);
1047 static unsigned int dec_scc_r(DisasContext
*dc
)
1051 DIS(fprintf (logfile
, "s%s $r%u\n",
1052 cc_name(cond
), dc
->op1
));
1056 gen_tst_cc (dc
, cond
);
1057 gen_op_movl_T1_T0();
1060 gen_op_movl_T1_im(1);
1062 cris_cc_mask(dc
, 0);
1063 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1067 static unsigned int dec_and_r(DisasContext
*dc
)
1069 int size
= memsize_zz(dc
);
1071 DIS(fprintf (logfile
, "and.%c $r%u, $r%u\n",
1072 memsize_char(size
), dc
->op1
, dc
->op2
));
1073 cris_cc_mask(dc
, CC_MASK_NZ
);
1074 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1075 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, size
);
1079 static unsigned int dec_lz_r(DisasContext
*dc
)
1081 DIS(fprintf (logfile
, "lz $r%u, $r%u\n",
1083 cris_cc_mask(dc
, CC_MASK_NZ
);
1084 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1085 crisv32_alu_op(dc
, CC_OP_LZ
, dc
->op2
, 4);
1089 static unsigned int dec_lsl_r(DisasContext
*dc
)
1091 int size
= memsize_zz(dc
);
1093 DIS(fprintf (logfile
, "lsl.%c $r%u, $r%u\n",
1094 memsize_char(size
), dc
->op1
, dc
->op2
));
1095 cris_cc_mask(dc
, CC_MASK_NZ
);
1096 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1097 gen_op_andl_T1_im(63);
1098 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, size
);
1102 static unsigned int dec_lsr_r(DisasContext
*dc
)
1104 int size
= memsize_zz(dc
);
1106 DIS(fprintf (logfile
, "lsr.%c $r%u, $r%u\n",
1107 memsize_char(size
), dc
->op1
, dc
->op2
));
1108 cris_cc_mask(dc
, CC_MASK_NZ
);
1109 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1110 gen_op_andl_T1_im(63);
1111 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, size
);
1115 static unsigned int dec_asr_r(DisasContext
*dc
)
1117 int size
= memsize_zz(dc
);
1119 DIS(fprintf (logfile
, "asr.%c $r%u, $r%u\n",
1120 memsize_char(size
), dc
->op1
, dc
->op2
));
1121 cris_cc_mask(dc
, CC_MASK_NZ
);
1122 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1123 gen_op_andl_T1_im(63);
1124 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, size
);
1128 static unsigned int dec_muls_r(DisasContext
*dc
)
1130 int size
= memsize_zz(dc
);
1132 DIS(fprintf (logfile
, "muls.%c $r%u, $r%u\n",
1133 memsize_char(size
), dc
->op1
, dc
->op2
));
1134 cris_cc_mask(dc
, CC_MASK_NZV
);
1135 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1136 gen_sext_T0_T0(size
);
1137 crisv32_alu_op(dc
, CC_OP_MULS
, dc
->op2
, 4);
1141 static unsigned int dec_mulu_r(DisasContext
*dc
)
1143 int size
= memsize_zz(dc
);
1145 DIS(fprintf (logfile
, "mulu.%c $r%u, $r%u\n",
1146 memsize_char(size
), dc
->op1
, dc
->op2
));
1147 cris_cc_mask(dc
, CC_MASK_NZV
);
1148 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1149 gen_zext_T0_T0(size
);
1150 crisv32_alu_op(dc
, CC_OP_MULU
, dc
->op2
, 4);
1155 static unsigned int dec_dstep_r(DisasContext
*dc
)
1157 DIS(fprintf (logfile
, "dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
));
1158 cris_cc_mask(dc
, CC_MASK_NZ
);
1159 gen_movl_T0_reg
[dc
->op1
]();
1160 gen_op_movl_T1_T0();
1161 gen_movl_T0_reg
[dc
->op2
]();
1162 crisv32_alu_op(dc
, CC_OP_DSTEP
, dc
->op2
, 4);
1166 static unsigned int dec_xor_r(DisasContext
*dc
)
1168 int size
= memsize_zz(dc
);
1169 DIS(fprintf (logfile
, "xor.%c $r%u, $r%u\n",
1170 memsize_char(size
), dc
->op1
, dc
->op2
));
1171 BUG_ON(size
!= 4); /* xor is dword. */
1172 cris_cc_mask(dc
, CC_MASK_NZ
);
1173 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1174 crisv32_alu_op(dc
, CC_OP_XOR
, dc
->op2
, 4);
1178 static unsigned int dec_bound_r(DisasContext
*dc
)
1180 int size
= memsize_zz(dc
);
1181 DIS(fprintf (logfile
, "bound.%c $r%u, $r%u\n",
1182 memsize_char(size
), dc
->op1
, dc
->op2
));
1183 cris_cc_mask(dc
, CC_MASK_NZ
);
1184 /* TODO: needs optmimization. */
1185 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1186 /* rd should be 4. */
1187 gen_movl_T0_reg
[dc
->op2
]();
1188 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1192 static unsigned int dec_cmp_r(DisasContext
*dc
)
1194 int size
= memsize_zz(dc
);
1195 DIS(fprintf (logfile
, "cmp.%c $r%u, $r%u\n",
1196 memsize_char(size
), dc
->op1
, dc
->op2
));
1197 cris_cc_mask(dc
, CC_MASK_NZVC
);
1198 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1199 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, size
);
1203 static unsigned int dec_abs_r(DisasContext
*dc
)
1205 DIS(fprintf (logfile
, "abs $r%u, $r%u\n",
1207 cris_cc_mask(dc
, CC_MASK_NZ
);
1208 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1209 gen_op_absl_T1_T1();
1210 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1214 static unsigned int dec_add_r(DisasContext
*dc
)
1216 int size
= memsize_zz(dc
);
1217 DIS(fprintf (logfile
, "add.%c $r%u, $r%u\n",
1218 memsize_char(size
), dc
->op1
, dc
->op2
));
1219 cris_cc_mask(dc
, CC_MASK_NZVC
);
1220 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1221 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, size
);
1225 static unsigned int dec_addc_r(DisasContext
*dc
)
1227 DIS(fprintf (logfile
, "addc $r%u, $r%u\n",
1229 cris_evaluate_flags(dc
);
1230 cris_cc_mask(dc
, CC_MASK_NZVC
);
1231 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1232 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1236 static unsigned int dec_mcp_r(DisasContext
*dc
)
1238 DIS(fprintf (logfile
, "mcp $p%u, $r%u\n",
1240 cris_evaluate_flags(dc
);
1241 cris_cc_mask(dc
, CC_MASK_RNZV
);
1242 gen_movl_T0_preg
[dc
->op2
]();
1243 gen_op_movl_T1_T0();
1244 gen_movl_T0_reg
[dc
->op1
]();
1245 crisv32_alu_op(dc
, CC_OP_MCP
, dc
->op1
, 4);
1250 static char * swapmode_name(int mode
, char *modename
) {
1253 modename
[i
++] = 'n';
1255 modename
[i
++] = 'w';
1257 modename
[i
++] = 'b';
1259 modename
[i
++] = 'r';
1265 static unsigned int dec_swap_r(DisasContext
*dc
)
1267 DIS(char modename
[4]);
1268 DIS(fprintf (logfile
, "swap%s $r%u\n",
1269 swapmode_name(dc
->op2
, modename
), dc
->op1
));
1271 cris_cc_mask(dc
, CC_MASK_NZ
);
1272 gen_movl_T0_reg
[dc
->op1
]();
1276 gen_op_swapw_T0_T0();
1278 gen_op_swapb_T0_T0();
1280 gen_op_swapr_T0_T0();
1281 gen_op_movl_T1_T0();
1282 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1286 static unsigned int dec_or_r(DisasContext
*dc
)
1288 int size
= memsize_zz(dc
);
1289 DIS(fprintf (logfile
, "or.%c $r%u, $r%u\n",
1290 memsize_char(size
), dc
->op1
, dc
->op2
));
1291 cris_cc_mask(dc
, CC_MASK_NZ
);
1292 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1293 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, size
);
1297 static unsigned int dec_addi_r(DisasContext
*dc
)
1299 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u\n",
1300 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1301 cris_cc_mask(dc
, 0);
1302 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1303 gen_op_lsll_T0_im(dc
->zzsize
);
1304 gen_op_addl_T0_T1();
1305 gen_movl_reg_T0
[dc
->op1
]();
1309 static unsigned int dec_addi_acr(DisasContext
*dc
)
1311 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u, $acr\n",
1312 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1313 cris_cc_mask(dc
, 0);
1314 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1315 gen_op_lsll_T0_im(dc
->zzsize
);
1316 gen_op_addl_T0_T1();
1317 gen_movl_reg_T0
[REG_ACR
]();
1321 static unsigned int dec_neg_r(DisasContext
*dc
)
1323 int size
= memsize_zz(dc
);
1324 DIS(fprintf (logfile
, "neg.%c $r%u, $r%u\n",
1325 memsize_char(size
), dc
->op1
, dc
->op2
));
1326 cris_cc_mask(dc
, CC_MASK_NZVC
);
1327 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1328 crisv32_alu_op(dc
, CC_OP_NEG
, dc
->op2
, size
);
1332 static unsigned int dec_btst_r(DisasContext
*dc
)
1334 DIS(fprintf (logfile
, "btst $r%u, $r%u\n",
1336 cris_evaluate_flags(dc
);
1337 cris_cc_mask(dc
, CC_MASK_NZ
);
1338 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1339 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1341 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1342 gen_op_movl_flags_T0();
1347 static unsigned int dec_sub_r(DisasContext
*dc
)
1349 int size
= memsize_zz(dc
);
1350 DIS(fprintf (logfile
, "sub.%c $r%u, $r%u\n",
1351 memsize_char(size
), dc
->op1
, dc
->op2
));
1352 cris_cc_mask(dc
, CC_MASK_NZVC
);
1353 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1354 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, size
);
1358 /* Zero extension. From size to dword. */
1359 static unsigned int dec_movu_r(DisasContext
*dc
)
1361 int size
= memsize_z(dc
);
1362 DIS(fprintf (logfile
, "movu.%c $r%u, $r%u\n",
1366 cris_cc_mask(dc
, CC_MASK_NZ
);
1367 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1368 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1372 /* Sign extension. From size to dword. */
1373 static unsigned int dec_movs_r(DisasContext
*dc
)
1375 int size
= memsize_z(dc
);
1376 DIS(fprintf (logfile
, "movs.%c $r%u, $r%u\n",
1380 cris_cc_mask(dc
, CC_MASK_NZ
);
1381 gen_movl_T0_reg
[dc
->op1
]();
1382 /* Size can only be qi or hi. */
1383 gen_sext_T1_T0(size
);
1384 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1388 /* zero extension. From size to dword. */
1389 static unsigned int dec_addu_r(DisasContext
*dc
)
1391 int size
= memsize_z(dc
);
1392 DIS(fprintf (logfile
, "addu.%c $r%u, $r%u\n",
1396 cris_cc_mask(dc
, CC_MASK_NZVC
);
1397 gen_movl_T0_reg
[dc
->op1
]();
1398 /* Size can only be qi or hi. */
1399 gen_zext_T1_T0(size
);
1400 gen_movl_T0_reg
[dc
->op2
]();
1401 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1404 /* Sign extension. From size to dword. */
1405 static unsigned int dec_adds_r(DisasContext
*dc
)
1407 int size
= memsize_z(dc
);
1408 DIS(fprintf (logfile
, "adds.%c $r%u, $r%u\n",
1412 cris_cc_mask(dc
, CC_MASK_NZVC
);
1413 gen_movl_T0_reg
[dc
->op1
]();
1414 /* Size can only be qi or hi. */
1415 gen_sext_T1_T0(size
);
1416 gen_movl_T0_reg
[dc
->op2
]();
1417 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1421 /* Zero extension. From size to dword. */
1422 static unsigned int dec_subu_r(DisasContext
*dc
)
1424 int size
= memsize_z(dc
);
1425 DIS(fprintf (logfile
, "subu.%c $r%u, $r%u\n",
1429 cris_cc_mask(dc
, CC_MASK_NZVC
);
1430 gen_movl_T0_reg
[dc
->op1
]();
1431 /* Size can only be qi or hi. */
1432 gen_zext_T1_T0(size
);
1433 gen_movl_T0_reg
[dc
->op2
]();
1434 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1438 /* Sign extension. From size to dword. */
1439 static unsigned int dec_subs_r(DisasContext
*dc
)
1441 int size
= memsize_z(dc
);
1442 DIS(fprintf (logfile
, "subs.%c $r%u, $r%u\n",
1446 cris_cc_mask(dc
, CC_MASK_NZVC
);
1447 gen_movl_T0_reg
[dc
->op1
]();
1448 /* Size can only be qi or hi. */
1449 gen_sext_T1_T0(size
);
1450 gen_movl_T0_reg
[dc
->op2
]();
1451 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1455 static unsigned int dec_setclrf(DisasContext
*dc
)
1458 int set
= (~dc
->opcode
>> 2) & 1;
1460 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1461 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1462 DIS(fprintf (logfile
, "set=%d flags=%x\n", set
, flags
));
1463 if (set
&& flags
== 0)
1464 DIS(fprintf (logfile
, "nop\n"));
1465 else if (!set
&& (flags
& 0x20))
1466 DIS(fprintf (logfile
, "di\n"));
1468 DIS(fprintf (logfile
, "%sf %x\n",
1469 set
? "set" : "clr",
1472 if (set
&& (flags
& X_FLAG
)) {
1477 /* Simply decode the flags. */
1478 cris_evaluate_flags (dc
);
1479 cris_update_cc_op(dc
, CC_OP_FLAGS
);
1481 gen_op_setf (flags
);
1483 gen_op_clrf (flags
);
1488 static unsigned int dec_move_rs(DisasContext
*dc
)
1490 DIS(fprintf (logfile
, "move $r%u, $s%u\n", dc
->op1
, dc
->op2
));
1491 cris_cc_mask(dc
, 0);
1492 gen_movl_T0_reg
[dc
->op1
]();
1493 gen_op_movl_sreg_T0(dc
->op2
);
1495 if (dc
->op2
== 5) /* srs is checked at runtime. */
1496 gen_op_movl_tlb_lo_T0();
1499 static unsigned int dec_move_sr(DisasContext
*dc
)
1501 DIS(fprintf (logfile
, "move $s%u, $r%u\n", dc
->op1
, dc
->op2
));
1502 cris_cc_mask(dc
, 0);
1503 gen_op_movl_T0_sreg(dc
->op1
);
1504 gen_op_movl_T1_T0();
1505 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1508 static unsigned int dec_move_rp(DisasContext
*dc
)
1510 DIS(fprintf (logfile
, "move $r%u, $p%u\n", dc
->op1
, dc
->op2
));
1511 cris_cc_mask(dc
, 0);
1512 gen_movl_T0_reg
[dc
->op1
]();
1513 gen_op_movl_T1_T0();
1514 gen_movl_preg_T0
[dc
->op2
]();
1517 static unsigned int dec_move_pr(DisasContext
*dc
)
1519 DIS(fprintf (logfile
, "move $p%u, $r%u\n", dc
->op1
, dc
->op2
));
1520 cris_cc_mask(dc
, 0);
1521 gen_movl_T0_preg
[dc
->op2
]();
1522 gen_op_movl_T1_T0();
1523 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, preg_sizes
[dc
->op2
]);
1527 static unsigned int dec_move_mr(DisasContext
*dc
)
1529 int memsize
= memsize_zz(dc
);
1531 DIS(fprintf (logfile
, "move.%c [$r%u%s, $r%u\n",
1532 memsize_char(memsize
),
1533 dc
->op1
, dc
->postinc
? "+]" : "]",
1536 cris_cc_mask(dc
, CC_MASK_NZ
);
1537 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1538 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, memsize
);
1539 do_postinc(dc
, memsize
);
1543 static unsigned int dec_movs_m(DisasContext
*dc
)
1545 int memsize
= memsize_z(dc
);
1547 DIS(fprintf (logfile
, "movs.%c [$r%u%s, $r%u\n",
1548 memsize_char(memsize
),
1549 dc
->op1
, dc
->postinc
? "+]" : "]",
1553 cris_cc_mask(dc
, CC_MASK_NZ
);
1554 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1555 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1556 do_postinc(dc
, memsize
);
1560 static unsigned int dec_addu_m(DisasContext
*dc
)
1562 int memsize
= memsize_z(dc
);
1564 DIS(fprintf (logfile
, "addu.%c [$r%u%s, $r%u\n",
1565 memsize_char(memsize
),
1566 dc
->op1
, dc
->postinc
? "+]" : "]",
1570 cris_cc_mask(dc
, CC_MASK_NZVC
);
1571 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1572 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1573 do_postinc(dc
, memsize
);
1577 static unsigned int dec_adds_m(DisasContext
*dc
)
1579 int memsize
= memsize_z(dc
);
1581 DIS(fprintf (logfile
, "adds.%c [$r%u%s, $r%u\n",
1582 memsize_char(memsize
),
1583 dc
->op1
, dc
->postinc
? "+]" : "]",
1587 cris_cc_mask(dc
, CC_MASK_NZVC
);
1588 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1589 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1590 do_postinc(dc
, memsize
);
1594 static unsigned int dec_subu_m(DisasContext
*dc
)
1596 int memsize
= memsize_z(dc
);
1598 DIS(fprintf (logfile
, "subu.%c [$r%u%s, $r%u\n",
1599 memsize_char(memsize
),
1600 dc
->op1
, dc
->postinc
? "+]" : "]",
1604 cris_cc_mask(dc
, CC_MASK_NZVC
);
1605 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1606 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1607 do_postinc(dc
, memsize
);
1611 static unsigned int dec_subs_m(DisasContext
*dc
)
1613 int memsize
= memsize_z(dc
);
1615 DIS(fprintf (logfile
, "subs.%c [$r%u%s, $r%u\n",
1616 memsize_char(memsize
),
1617 dc
->op1
, dc
->postinc
? "+]" : "]",
1621 cris_cc_mask(dc
, CC_MASK_NZVC
);
1622 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1623 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1624 do_postinc(dc
, memsize
);
1628 static unsigned int dec_movu_m(DisasContext
*dc
)
1630 int memsize
= memsize_z(dc
);
1633 DIS(fprintf (logfile
, "movu.%c [$r%u%s, $r%u\n",
1634 memsize_char(memsize
),
1635 dc
->op1
, dc
->postinc
? "+]" : "]",
1638 cris_cc_mask(dc
, CC_MASK_NZ
);
1639 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1640 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1641 do_postinc(dc
, memsize
);
1645 static unsigned int dec_cmpu_m(DisasContext
*dc
)
1647 int memsize
= memsize_z(dc
);
1649 DIS(fprintf (logfile
, "cmpu.%c [$r%u%s, $r%u\n",
1650 memsize_char(memsize
),
1651 dc
->op1
, dc
->postinc
? "+]" : "]",
1654 cris_cc_mask(dc
, CC_MASK_NZVC
);
1655 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1656 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1657 do_postinc(dc
, memsize
);
1661 static unsigned int dec_cmps_m(DisasContext
*dc
)
1663 int memsize
= memsize_z(dc
);
1665 DIS(fprintf (logfile
, "cmps.%c [$r%u%s, $r%u\n",
1666 memsize_char(memsize
),
1667 dc
->op1
, dc
->postinc
? "+]" : "]",
1670 cris_cc_mask(dc
, CC_MASK_NZVC
);
1671 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1672 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1673 do_postinc(dc
, memsize
);
1677 static unsigned int dec_cmp_m(DisasContext
*dc
)
1679 int memsize
= memsize_zz(dc
);
1681 DIS(fprintf (logfile
, "cmp.%c [$r%u%s, $r%u\n",
1682 memsize_char(memsize
),
1683 dc
->op1
, dc
->postinc
? "+]" : "]",
1686 cris_cc_mask(dc
, CC_MASK_NZVC
);
1687 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1688 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1689 do_postinc(dc
, memsize
);
1693 static unsigned int dec_test_m(DisasContext
*dc
)
1695 int memsize
= memsize_zz(dc
);
1697 DIS(fprintf (logfile
, "test.%d [$r%u%s] op2=%x\n",
1698 memsize_char(memsize
),
1699 dc
->op1
, dc
->postinc
? "+]" : "]",
1702 cris_cc_mask(dc
, CC_MASK_NZ
);
1704 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1706 gen_op_movl_T1_im(0);
1707 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1708 do_postinc(dc
, memsize
);
1712 static unsigned int dec_and_m(DisasContext
*dc
)
1714 int memsize
= memsize_zz(dc
);
1716 DIS(fprintf (logfile
, "and.%d [$r%u%s, $r%u\n",
1717 memsize_char(memsize
),
1718 dc
->op1
, dc
->postinc
? "+]" : "]",
1721 cris_cc_mask(dc
, CC_MASK_NZ
);
1722 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1723 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, memsize_zz(dc
));
1724 do_postinc(dc
, memsize
);
1728 static unsigned int dec_add_m(DisasContext
*dc
)
1730 int memsize
= memsize_zz(dc
);
1732 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1733 memsize_char(memsize
),
1734 dc
->op1
, dc
->postinc
? "+]" : "]",
1737 cris_cc_mask(dc
, CC_MASK_NZVC
);
1738 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1739 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, memsize_zz(dc
));
1740 do_postinc(dc
, memsize
);
1744 static unsigned int dec_addo_m(DisasContext
*dc
)
1746 int memsize
= memsize_zz(dc
);
1748 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
1749 memsize_char(memsize
),
1750 dc
->op1
, dc
->postinc
? "+]" : "]",
1753 cris_cc_mask(dc
, 0);
1754 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1755 crisv32_alu_op(dc
, CC_OP_ADD
, REG_ACR
, 4);
1756 do_postinc(dc
, memsize
);
1760 static unsigned int dec_bound_m(DisasContext
*dc
)
1762 int memsize
= memsize_zz(dc
);
1764 DIS(fprintf (logfile
, "bound.%d [$r%u%s, $r%u\n",
1765 memsize_char(memsize
),
1766 dc
->op1
, dc
->postinc
? "+]" : "]",
1769 cris_cc_mask(dc
, CC_MASK_NZ
);
1770 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1771 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1772 do_postinc(dc
, memsize
);
1776 static unsigned int dec_addc_mr(DisasContext
*dc
)
1779 DIS(fprintf (logfile
, "addc [$r%u%s, $r%u\n",
1780 dc
->op1
, dc
->postinc
? "+]" : "]",
1783 cris_evaluate_flags(dc
);
1784 cris_cc_mask(dc
, CC_MASK_NZVC
);
1785 insn_len
= dec_prep_alu_m(dc
, 0, 4);
1786 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1791 static unsigned int dec_sub_m(DisasContext
*dc
)
1793 int memsize
= memsize_zz(dc
);
1795 DIS(fprintf (logfile
, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1796 memsize_char(memsize
),
1797 dc
->op1
, dc
->postinc
? "+]" : "]",
1798 dc
->op2
, dc
->ir
, dc
->zzsize
));
1800 cris_cc_mask(dc
, CC_MASK_NZVC
);
1801 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1802 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, memsize
);
1803 do_postinc(dc
, memsize
);
1807 static unsigned int dec_or_m(DisasContext
*dc
)
1809 int memsize
= memsize_zz(dc
);
1811 DIS(fprintf (logfile
, "or.%d [$r%u%s, $r%u pc=%x\n",
1812 memsize_char(memsize
),
1813 dc
->op1
, dc
->postinc
? "+]" : "]",
1816 cris_cc_mask(dc
, CC_MASK_NZ
);
1817 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1818 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, memsize_zz(dc
));
1819 do_postinc(dc
, memsize
);
1823 static unsigned int dec_move_mp(DisasContext
*dc
)
1825 int memsize
= memsize_zz(dc
);
1828 DIS(fprintf (logfile
, "move.%c [$r%u%s, $p%u\n",
1829 memsize_char(memsize
),
1831 dc
->postinc
? "+]" : "]",
1834 cris_cc_mask(dc
, 0);
1835 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1836 gen_op_movl_T0_T1();
1837 gen_movl_preg_T0
[dc
->op2
]();
1839 do_postinc(dc
, memsize
);
1843 static unsigned int dec_move_pm(DisasContext
*dc
)
1847 memsize
= preg_sizes
[dc
->op2
];
1849 DIS(fprintf (logfile
, "move.%d $p%u, [$r%u%s\n",
1850 memsize
, dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]"));
1852 cris_cc_mask(dc
, 0);
1853 /* prepare store. */
1854 gen_movl_T0_preg
[dc
->op2
]();
1855 gen_op_movl_T1_T0();
1856 gen_movl_T0_reg
[dc
->op1
]();
1857 gen_store_T0_T1(dc
, memsize
);
1860 gen_op_addl_T0_im(memsize
);
1861 gen_movl_reg_T0
[dc
->op1
]();
1866 static unsigned int dec_movem_mr(DisasContext
*dc
)
1870 DIS(fprintf (logfile
, "movem [$r%u%s, $r%u\n", dc
->op1
,
1871 dc
->postinc
? "+]" : "]", dc
->op2
));
1873 cris_cc_mask(dc
, 0);
1874 /* fetch the address into T1. */
1875 gen_movl_T0_reg
[dc
->op1
]();
1876 gen_op_movl_T1_T0();
1877 for (i
= 0; i
<= dc
->op2
; i
++) {
1878 /* Perform the load onto regnum i. Always dword wide. */
1879 gen_load_T0_T0(dc
, 4, 0);
1880 gen_movl_reg_T0
[i
]();
1881 /* Update the address. */
1882 gen_op_addl_T1_im(4);
1883 gen_op_movl_T0_T1();
1886 /* writeback the updated pointer value. */
1887 gen_movl_reg_T0
[dc
->op1
]();
1892 static unsigned int dec_movem_rm(DisasContext
*dc
)
1896 DIS(fprintf (logfile
, "movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
1897 dc
->postinc
? "+]" : "]"));
1899 cris_cc_mask(dc
, 0);
1900 for (i
= 0; i
<= dc
->op2
; i
++) {
1901 /* Fetch register i into T1. */
1902 gen_movl_T0_reg
[i
]();
1903 gen_op_movl_T1_T0();
1905 /* Fetch the address into T0. */
1906 gen_movl_T0_reg
[dc
->op1
]();
1908 gen_op_addl_T0_im(i
* 4);
1910 /* Perform the store. */
1911 gen_store_T0_T1(dc
, 4);
1914 /* Update the address. */
1915 gen_op_addl_T0_im(4);
1916 /* writeback the updated pointer value. */
1917 gen_movl_reg_T0
[dc
->op1
]();
1922 static unsigned int dec_move_rm(DisasContext
*dc
)
1926 memsize
= memsize_zz(dc
);
1928 DIS(fprintf (logfile
, "move.%d $r%u, [$r%u]\n",
1929 memsize
, dc
->op2
, dc
->op1
));
1931 cris_cc_mask(dc
, 0);
1932 /* prepare store. */
1933 gen_movl_T0_reg
[dc
->op2
]();
1934 gen_op_movl_T1_T0();
1935 gen_movl_T0_reg
[dc
->op1
]();
1936 gen_store_T0_T1(dc
, memsize
);
1939 gen_op_addl_T0_im(memsize
);
1940 gen_movl_reg_T0
[dc
->op1
]();
1946 static unsigned int dec_lapcq(DisasContext
*dc
)
1948 DIS(fprintf (logfile
, "lapcq %x, $r%u\n",
1949 dc
->pc
+ dc
->op1
*2, dc
->op2
));
1950 cris_cc_mask(dc
, 0);
1951 gen_op_movl_T1_im(dc
->pc
+ dc
->op1
*2);
1952 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1956 static unsigned int dec_lapc_im(DisasContext
*dc
)
1964 cris_cc_mask(dc
, 0);
1965 imm
= ldl_code(dc
->pc
+ 2);
1966 DIS(fprintf (logfile
, "lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
));
1967 gen_op_movl_T0_im (dc
->pc
+ imm
);
1968 gen_movl_reg_T0
[rd
] ();
1972 /* Jump to special reg. */
1973 static unsigned int dec_jump_p(DisasContext
*dc
)
1975 DIS(fprintf (logfile
, "jump $p%u\n", dc
->op2
));
1976 cris_cc_mask(dc
, 0);
1977 /* Store the return address in Pd. */
1978 gen_movl_T0_preg
[dc
->op2
]();
1979 gen_op_movl_btarget_T0();
1980 cris_prepare_dyn_jmp(dc
);
1984 /* Jump and save. */
1985 static unsigned int dec_jas_r(DisasContext
*dc
)
1987 DIS(fprintf (logfile
, "jas $r%u, $p%u\n", dc
->op1
, dc
->op2
));
1988 cris_cc_mask(dc
, 0);
1989 /* Stor the return address in Pd. */
1990 gen_movl_T0_reg
[dc
->op1
]();
1991 gen_op_movl_btarget_T0();
1992 gen_op_movl_T0_im(dc
->pc
+ 4);
1993 gen_movl_preg_T0
[dc
->op2
]();
1994 cris_prepare_dyn_jmp(dc
);
1998 static unsigned int dec_jas_im(DisasContext
*dc
)
2002 imm
= ldl_code(dc
->pc
+ 2);
2004 DIS(fprintf (logfile
, "jas 0x%x\n", imm
));
2005 cris_cc_mask(dc
, 0);
2006 /* Stor the return address in Pd. */
2007 gen_op_movl_T0_im(imm
);
2008 gen_op_movl_btarget_T0();
2009 gen_op_movl_T0_im(dc
->pc
+ 8);
2010 gen_movl_preg_T0
[dc
->op2
]();
2011 cris_prepare_dyn_jmp(dc
);
2015 static unsigned int dec_jasc_im(DisasContext
*dc
)
2019 imm
= ldl_code(dc
->pc
+ 2);
2021 DIS(fprintf (logfile
, "jasc 0x%x\n", imm
));
2022 cris_cc_mask(dc
, 0);
2023 /* Stor the return address in Pd. */
2024 gen_op_movl_T0_im(imm
);
2025 gen_op_movl_btarget_T0();
2026 gen_op_movl_T0_im(dc
->pc
+ 8 + 4);
2027 gen_movl_preg_T0
[dc
->op2
]();
2028 cris_prepare_dyn_jmp(dc
);
2032 static unsigned int dec_jasc_r(DisasContext
*dc
)
2034 DIS(fprintf (logfile
, "jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2035 cris_cc_mask(dc
, 0);
2036 /* Stor the return address in Pd. */
2037 gen_movl_T0_reg
[dc
->op1
]();
2038 gen_op_movl_btarget_T0();
2039 gen_op_movl_T0_im(dc
->pc
+ 4 + 4);
2040 gen_movl_preg_T0
[dc
->op2
]();
2041 cris_prepare_dyn_jmp(dc
);
2045 static unsigned int dec_bcc_im(DisasContext
*dc
)
2048 uint32_t cond
= dc
->op2
;
2050 offset
= ldl_code(dc
->pc
+ 2);
2051 offset
= sign_extend(offset
, 15);
2053 DIS(fprintf (logfile
, "b%s %d pc=%x dst=%x\n",
2054 cc_name(cond
), offset
,
2055 dc
->pc
, dc
->pc
+ offset
));
2057 cris_cc_mask(dc
, 0);
2058 /* op2 holds the condition-code. */
2059 cris_prepare_cc_branch (dc
, offset
, cond
);
2063 static unsigned int dec_bas_im(DisasContext
*dc
)
2068 simm
= ldl_code(dc
->pc
+ 2);
2070 DIS(fprintf (logfile
, "bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2071 cris_cc_mask(dc
, 0);
2072 /* Stor the return address in Pd. */
2073 gen_op_movl_T0_im(dc
->pc
+ simm
);
2074 gen_op_movl_btarget_T0();
2075 gen_op_movl_T0_im(dc
->pc
+ 8);
2076 gen_movl_preg_T0
[dc
->op2
]();
2077 cris_prepare_dyn_jmp(dc
);
2081 static unsigned int dec_basc_im(DisasContext
*dc
)
2084 simm
= ldl_code(dc
->pc
+ 2);
2086 DIS(fprintf (logfile
, "basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2087 cris_cc_mask(dc
, 0);
2088 /* Stor the return address in Pd. */
2089 gen_op_movl_T0_im(dc
->pc
+ simm
);
2090 gen_op_movl_btarget_T0();
2091 gen_op_movl_T0_im(dc
->pc
+ 12);
2092 gen_movl_preg_T0
[dc
->op2
]();
2093 cris_prepare_dyn_jmp(dc
);
2097 static unsigned int dec_rfe_etc(DisasContext
*dc
)
2099 DIS(fprintf (logfile
, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2100 dc
->opcode
, dc
->pc
, dc
->op1
, dc
->op2
));
2102 cris_cc_mask(dc
, 0);
2104 if (dc
->op2
== 15) /* ignore halt. */
2107 switch (dc
->op2
& 7) {
2110 cris_evaluate_flags(dc
);
2111 gen_op_ccs_rshift();
2119 gen_op_movl_T0_im(dc
->pc
);
2120 gen_op_movl_pc_T0();
2121 /* Breaks start at 16 in the exception vector. */
2122 gen_op_break_im(dc
->op1
+ 16);
2125 printf ("op2=%x\n", dc
->op2
);
2134 static unsigned int dec_null(DisasContext
*dc
)
2136 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2137 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2143 struct decoder_info
{
2148 unsigned int (*dec
)(DisasContext
*dc
);
2150 /* Order matters here. */
2151 {DEC_MOVEQ
, dec_moveq
},
2152 {DEC_BTSTQ
, dec_btstq
},
2153 {DEC_CMPQ
, dec_cmpq
},
2154 {DEC_ADDOQ
, dec_addoq
},
2155 {DEC_ADDQ
, dec_addq
},
2156 {DEC_SUBQ
, dec_subq
},
2157 {DEC_ANDQ
, dec_andq
},
2159 {DEC_ASRQ
, dec_asrq
},
2160 {DEC_LSLQ
, dec_lslq
},
2161 {DEC_LSRQ
, dec_lsrq
},
2162 {DEC_BCCQ
, dec_bccq
},
2164 {DEC_BCC_IM
, dec_bcc_im
},
2165 {DEC_JAS_IM
, dec_jas_im
},
2166 {DEC_JAS_R
, dec_jas_r
},
2167 {DEC_JASC_IM
, dec_jasc_im
},
2168 {DEC_JASC_R
, dec_jasc_r
},
2169 {DEC_BAS_IM
, dec_bas_im
},
2170 {DEC_BASC_IM
, dec_basc_im
},
2171 {DEC_JUMP_P
, dec_jump_p
},
2172 {DEC_LAPC_IM
, dec_lapc_im
},
2173 {DEC_LAPCQ
, dec_lapcq
},
2175 {DEC_RFE_ETC
, dec_rfe_etc
},
2176 {DEC_ADDC_MR
, dec_addc_mr
},
2178 {DEC_MOVE_MP
, dec_move_mp
},
2179 {DEC_MOVE_PM
, dec_move_pm
},
2180 {DEC_MOVEM_MR
, dec_movem_mr
},
2181 {DEC_MOVEM_RM
, dec_movem_rm
},
2182 {DEC_MOVE_PR
, dec_move_pr
},
2183 {DEC_SCC_R
, dec_scc_r
},
2184 {DEC_SETF
, dec_setclrf
},
2185 {DEC_CLEARF
, dec_setclrf
},
2187 {DEC_MOVE_SR
, dec_move_sr
},
2188 {DEC_MOVE_RP
, dec_move_rp
},
2189 {DEC_SWAP_R
, dec_swap_r
},
2190 {DEC_ABS_R
, dec_abs_r
},
2191 {DEC_LZ_R
, dec_lz_r
},
2192 {DEC_MOVE_RS
, dec_move_rs
},
2193 {DEC_BTST_R
, dec_btst_r
},
2194 {DEC_ADDC_R
, dec_addc_r
},
2196 {DEC_DSTEP_R
, dec_dstep_r
},
2197 {DEC_XOR_R
, dec_xor_r
},
2198 {DEC_MCP_R
, dec_mcp_r
},
2199 {DEC_CMP_R
, dec_cmp_r
},
2201 {DEC_ADDI_R
, dec_addi_r
},
2202 {DEC_ADDI_ACR
, dec_addi_acr
},
2204 {DEC_ADD_R
, dec_add_r
},
2205 {DEC_SUB_R
, dec_sub_r
},
2207 {DEC_ADDU_R
, dec_addu_r
},
2208 {DEC_ADDS_R
, dec_adds_r
},
2209 {DEC_SUBU_R
, dec_subu_r
},
2210 {DEC_SUBS_R
, dec_subs_r
},
2211 {DEC_LSL_R
, dec_lsl_r
},
2213 {DEC_AND_R
, dec_and_r
},
2214 {DEC_OR_R
, dec_or_r
},
2215 {DEC_BOUND_R
, dec_bound_r
},
2216 {DEC_ASR_R
, dec_asr_r
},
2217 {DEC_LSR_R
, dec_lsr_r
},
2219 {DEC_MOVU_R
, dec_movu_r
},
2220 {DEC_MOVS_R
, dec_movs_r
},
2221 {DEC_NEG_R
, dec_neg_r
},
2222 {DEC_MOVE_R
, dec_move_r
},
2224 /* ftag_fidx_i_m. */
2225 /* ftag_fidx_d_m. */
2227 {DEC_MULS_R
, dec_muls_r
},
2228 {DEC_MULU_R
, dec_mulu_r
},
2230 {DEC_ADDU_M
, dec_addu_m
},
2231 {DEC_ADDS_M
, dec_adds_m
},
2232 {DEC_SUBU_M
, dec_subu_m
},
2233 {DEC_SUBS_M
, dec_subs_m
},
2235 {DEC_CMPU_M
, dec_cmpu_m
},
2236 {DEC_CMPS_M
, dec_cmps_m
},
2237 {DEC_MOVU_M
, dec_movu_m
},
2238 {DEC_MOVS_M
, dec_movs_m
},
2240 {DEC_CMP_M
, dec_cmp_m
},
2241 {DEC_ADDO_M
, dec_addo_m
},
2242 {DEC_BOUND_M
, dec_bound_m
},
2243 {DEC_ADD_M
, dec_add_m
},
2244 {DEC_SUB_M
, dec_sub_m
},
2245 {DEC_AND_M
, dec_and_m
},
2246 {DEC_OR_M
, dec_or_m
},
2247 {DEC_MOVE_RM
, dec_move_rm
},
2248 {DEC_TEST_M
, dec_test_m
},
2249 {DEC_MOVE_MR
, dec_move_mr
},
2254 static inline unsigned int
2255 cris_decoder(DisasContext
*dc
)
2257 unsigned int insn_len
= 2;
2261 /* Load a halfword onto the instruction register. */
2262 tmp
= ldl_code(dc
->pc
);
2263 dc
->ir
= tmp
& 0xffff;
2265 /* Now decode it. */
2266 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2267 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2268 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2269 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2270 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2271 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2273 /* Large switch for all insns. */
2274 for (i
= 0; i
< sizeof decinfo
/ sizeof decinfo
[0]; i
++) {
2275 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
)
2277 insn_len
= decinfo
[i
].dec(dc
);
2285 static void check_breakpoint(CPUState
*env
, DisasContext
*dc
)
2288 if (env
->nb_breakpoints
> 0) {
2289 for(j
= 0; j
< env
->nb_breakpoints
; j
++) {
2290 if (env
->breakpoints
[j
] == dc
->pc
) {
2291 cris_evaluate_flags (dc
);
2292 gen_op_movl_T0_im((long)dc
->pc
);
2293 gen_op_movl_pc_T0();
2295 dc
->is_jmp
= DISAS_UPDATE
;
2302 /* generate intermediate code for basic block 'tb'. */
2303 struct DisasContext ctx
;
2305 gen_intermediate_code_internal(CPUState
*env
, TranslationBlock
*tb
,
2308 uint16_t *gen_opc_end
;
2310 unsigned int insn_len
;
2312 struct DisasContext
*dc
= &ctx
;
2313 uint32_t next_page_start
;
2319 gen_opc_ptr
= gen_opc_buf
;
2320 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
2321 gen_opparam_ptr
= gen_opparam_buf
;
2323 dc
->is_jmp
= DISAS_NEXT
;
2325 dc
->singlestep_enabled
= env
->singlestep_enabled
;
2328 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
2332 check_breakpoint(env
, dc
);
2333 if (dc
->is_jmp
== DISAS_JUMP
)
2337 j
= gen_opc_ptr
- gen_opc_buf
;
2341 gen_opc_instr_start
[lj
++] = 0;
2343 gen_opc_pc
[lj
] = dc
->pc
;
2344 gen_opc_instr_start
[lj
] = 1;
2347 insn_len
= cris_decoder(dc
);
2348 STATS(gen_op_exec_insn());
2351 || (dc
->flagx_live
&&
2352 !(dc
->cc_op
== CC_OP_FLAGS
&& dc
->flags_x
))) {
2353 gen_movl_T0_preg
[SR_CCS
]();
2354 gen_op_andl_T0_im(~X_FLAG
);
2355 gen_movl_preg_T0
[SR_CCS
]();
2360 /* Check for delayed branches here. If we do it before
2361 actually genereating any host code, the simulator will just
2362 loop doing nothing for on this program location. */
2363 if (dc
->delayed_branch
) {
2364 dc
->delayed_branch
--;
2365 if (dc
->delayed_branch
== 0)
2367 if (dc
->bcc
== CC_A
) {
2369 dc
->is_jmp
= DISAS_UPDATE
;
2372 /* Conditional jmp. */
2373 gen_op_cc_jmp (dc
->delayed_pc
, dc
->pc
);
2374 dc
->is_jmp
= DISAS_UPDATE
;
2379 if (env
->singlestep_enabled
)
2381 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
2382 && dc
->pc
< next_page_start
);
2385 gen_op_movl_T0_im((long)dc
->pc
);
2386 gen_op_movl_pc_T0();
2389 cris_evaluate_flags (dc
);
2391 if (__builtin_expect(env
->singlestep_enabled
, 0)) {
2394 switch(dc
->is_jmp
) {
2396 gen_goto_tb(dc
, 1, dc
->pc
);
2401 /* indicate that the hash table must be used
2402 to find the next TB */
2403 /* T0 is used to index the jmp tables. */
2408 /* nothing more to generate */
2412 *gen_opc_ptr
= INDEX_op_end
;
2414 j
= gen_opc_ptr
- gen_opc_buf
;
2417 gen_opc_instr_start
[lj
++] = 0;
2419 tb
->size
= dc
->pc
- pc_start
;
2423 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
2424 fprintf(logfile
, "--------------\n");
2425 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
2426 target_disas(logfile
, pc_start
, dc
->pc
+ 4 - pc_start
, 0);
2427 fprintf(logfile
, "\n");
2428 if (loglevel
& CPU_LOG_TB_OP
) {
2429 fprintf(logfile
, "OP:\n");
2430 dump_ops(gen_opc_buf
, gen_opparam_buf
);
2431 fprintf(logfile
, "\n");
2438 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
2440 return gen_intermediate_code_internal(env
, tb
, 0);
2443 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
2445 return gen_intermediate_code_internal(env
, tb
, 1);
2448 void cpu_dump_state (CPUState
*env
, FILE *f
,
2449 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
2458 cpu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2459 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2461 env
->pc
, env
->pregs
[SR_CCS
], env
->btaken
, env
->btarget
,
2463 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
,
2464 env
->debug1
, env
->debug2
, env
->debug3
);
2466 for (i
= 0; i
< 16; i
++) {
2467 cpu_fprintf(f
, "r%2.2d=%8.8x ", i
, env
->regs
[i
]);
2468 if ((i
+ 1) % 4 == 0)
2469 cpu_fprintf(f
, "\n");
2471 cpu_fprintf(f
, "\nspecial regs:\n");
2472 for (i
= 0; i
< 16; i
++) {
2473 cpu_fprintf(f
, "p%2.2d=%8.8x ", i
, env
->pregs
[i
]);
2474 if ((i
+ 1) % 4 == 0)
2475 cpu_fprintf(f
, "\n");
2477 srs
= env
->pregs
[SR_SRS
];
2478 cpu_fprintf(f
, "\nsupport function regs bank %d:\n", srs
);
2480 for (i
= 0; i
< 16; i
++) {
2481 cpu_fprintf(f
, "s%2.2d=%8.8x ",
2482 i
, env
->sregs
[srs
][i
]);
2483 if ((i
+ 1) % 4 == 0)
2484 cpu_fprintf(f
, "\n");
2487 cpu_fprintf(f
, "\n\n");
2491 CPUCRISState
*cpu_cris_init (void)
2495 env
= qemu_mallocz(sizeof(CPUCRISState
));
2503 void cpu_reset (CPUCRISState
*env
)
2505 memset(env
, 0, offsetof(CPUCRISState
, breakpoints
));