Formatting fix.
[qemu/qemu_0_9_1_stable.git] / target-cris / translate.c
blob40caef07342fdab524e81232e0dc54d46ce457bf
1 /*
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:
32 * add.d [$r0], $r1
34 * translates into:
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.
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <inttypes.h>
49 #include <assert.h>
51 #include "cpu.h"
52 #include "exec-all.h"
53 #include "disas.h"
54 #include "crisv32-decode.h"
56 #define CRIS_STATS 0
57 #if CRIS_STATS
58 #define STATS(x) x
59 #else
60 #define STATS(x)
61 #endif
63 #define DISAS_CRIS 0
64 #if DISAS_CRIS
65 #define DIS(x) x
66 #else
67 #define DIS(x)
68 #endif
70 #ifdef USE_DIRECT_JUMP
71 #define TBPARAM(x)
72 #else
73 #define TBPARAM(x) (long)(x)
74 #endif
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;
91 enum {
92 #define DEF(s, n, copy_size) INDEX_op_ ## s,
93 #include "opc.h"
94 #undef DEF
95 NB_OPS,
97 #include "gen-op.h"
99 /* This is the state at translation time. */
100 typedef struct DisasContext {
101 CPUState *env;
102 target_ulong pc, insn_pc;
104 /* Decoder. */
105 uint32_t ir;
106 uint32_t opcode;
107 unsigned int op1;
108 unsigned int op2;
109 unsigned int zsize, zzsize;
110 unsigned int mode;
111 unsigned int postinc;
114 struct
116 int op;
117 int size;
118 unsigned int mask;
119 } cc_state[3];
120 int cc_i;
122 int update_cc;
123 int cc_op;
124 int cc_size;
125 uint32_t cc_mask;
126 int flags_live;
127 int flagx_live;
128 int flags_x;
129 uint32_t tb_entry_flags;
131 int memidx; /* user or kernel mode. */
132 int is_jmp;
133 int dyn_jmp;
135 uint32_t delayed_pc;
136 int delayed_branch;
137 int bcc;
138 uint32_t condlabel;
140 struct TranslationBlock *tb;
141 int singlestep_enabled;
142 } DisasContext;
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);
150 fflush(NULL);
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) {
179 /* nop. */
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. */
201 gen_op_movl_p5_T0,
202 gen_op_movl_p6_T0, gen_op_movl_p7_T0,
203 noop_write, /* dz, not writeable. */
204 gen_op_movl_p9_T0,
205 gen_op_movl_p10_T0, gen_op_movl_p11_T0,
206 gen_op_movl_p12_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] =
212 gen_op_movl_T0_p0,
213 gen_vr_read,
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,
219 gen_op_movl_T0_p12,
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. */
225 int preg_sizes[] = {
226 1, /* bz. */
227 1, /* vr. */
228 4, /* pid. */
229 1, /* srs. */
230 2, /* wz. */
231 4, 4, 4,
232 4, 4, 4, 4,
233 4, 4, 4, 4,
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(); \
245 #else
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();\
256 #endif
258 GEN_OP_LD(ub, T0)
259 GEN_OP_LD(b, T0)
260 GEN_OP_ST(b, T0)
261 GEN_OP_LD(uw, T0)
262 GEN_OP_LD(w, T0)
263 GEN_OP_ST(w, T0)
264 GEN_OP_LD(l, T0)
265 GEN_OP_ST(l, T0)
267 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
269 TranslationBlock *tb;
270 tb = dc->tb;
271 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
272 if (n == 0)
273 gen_op_goto_tb0(TBPARAM(tb));
274 else
275 gen_op_goto_tb1(TBPARAM(tb));
276 gen_op_movl_T0_0();
277 } else {
278 gen_op_movl_T0_0();
280 gen_op_exit_tb();
283 /* Sign extend at translation time. */
284 static int sign_extend(unsigned int val, unsigned int width)
286 int sval;
288 /* LSL. */
289 val <<= 31 - width;
290 sval = val;
291 /* ASR. */
292 sval >>= 31 - width;
293 return sval;
296 static void cris_evaluate_flags(DisasContext *dc)
298 if (!dc->flags_live) {
300 switch (dc->cc_op)
302 case CC_OP_MCP:
303 gen_op_evaluate_flags_mcp ();
304 break;
305 case CC_OP_MULS:
306 gen_op_evaluate_flags_muls ();
307 break;
308 case CC_OP_MULU:
309 gen_op_evaluate_flags_mulu ();
310 break;
311 case CC_OP_MOVE:
312 switch (dc->cc_size)
314 case 4:
315 gen_op_evaluate_flags_move_4();
316 break;
317 case 2:
318 gen_op_evaluate_flags_move_2();
319 break;
320 default:
321 gen_op_evaluate_flags ();
322 break;
324 break;
326 default:
328 switch (dc->cc_size)
330 case 4:
331 gen_op_evaluate_flags_alu_4 ();
332 break;
333 default:
334 gen_op_evaluate_flags ();
335 break;
338 break;
340 dc->flags_live = 1;
344 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
346 uint32_t ovl;
348 ovl = (dc->cc_mask ^ mask) & ~mask;
349 if (ovl) {
350 /* TODO: optimize this case. It trigs all the time. */
351 cris_evaluate_flags (dc);
353 dc->cc_mask = mask;
355 dc->update_cc = 1;
356 if (mask == 0)
357 dc->update_cc = 0;
358 else {
359 gen_op_update_cc_mask(mask);
360 dc->flags_live = 0;
364 static void cris_update_cc_op(DisasContext *dc, int op)
366 dc->cc_op = op;
367 gen_op_update_cc_op(op);
368 dc->flags_live = 0;
370 static void cris_update_cc_size(DisasContext *dc, int size)
372 dc->cc_size = 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)
382 int writeback = 1;
383 if (dc->update_cc) {
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. */
391 switch (op)
393 case CC_OP_ADD:
394 gen_op_addl_T0_T1();
395 /* Extended arithmetics. */
396 if (!dc->flagx_live)
397 gen_op_addxl_T0_C();
398 else if (dc->flags_x)
399 gen_op_addxl_T0_C();
400 break;
401 case CC_OP_ADDC:
402 gen_op_addl_T0_T1();
403 gen_op_addl_T0_C();
404 break;
405 case CC_OP_MCP:
406 gen_op_addl_T0_T1();
407 gen_op_addl_T0_R();
408 break;
409 case CC_OP_SUB:
410 gen_op_negl_T1_T1();
411 gen_op_addl_T0_T1();
412 /* CRIS flag evaluation needs ~src. */
413 gen_op_negl_T1_T1();
414 gen_op_not_T1_T1();
416 /* Extended arithmetics. */
417 if (!dc->flagx_live)
418 gen_op_subxl_T0_C();
419 else if (dc->flags_x)
420 gen_op_subxl_T0_C();
421 break;
422 case CC_OP_MOVE:
423 gen_op_movl_T0_T1();
424 break;
425 case CC_OP_OR:
426 gen_op_orl_T0_T1();
427 break;
428 case CC_OP_AND:
429 gen_op_andl_T0_T1();
430 break;
431 case CC_OP_XOR:
432 gen_op_xorl_T0_T1();
433 break;
434 case CC_OP_LSL:
435 gen_op_lsll_T0_T1();
436 break;
437 case CC_OP_LSR:
438 gen_op_lsrl_T0_T1();
439 break;
440 case CC_OP_ASR:
441 gen_op_asrl_T0_T1();
442 break;
443 case CC_OP_NEG:
444 gen_op_negl_T0_T1();
445 /* Extended arithmetics. */
446 gen_op_subxl_T0_C();
447 break;
448 case CC_OP_LZ:
449 gen_op_lz_T0_T1();
450 break;
451 case CC_OP_BTST:
452 gen_op_btst_T0_T1();
453 writeback = 0;
454 break;
455 case CC_OP_MULS:
456 gen_op_muls_T0_T1();
457 break;
458 case CC_OP_MULU:
459 gen_op_mulu_T0_T1();
460 break;
461 case CC_OP_DSTEP:
462 gen_op_dstep_T0_T1();
463 break;
464 case CC_OP_BOUND:
465 gen_op_bound_T0_T1();
466 break;
467 case CC_OP_CMP:
468 gen_op_negl_T1_T1();
469 gen_op_addl_T0_T1();
470 /* CRIS flag evaluation needs ~src. */
471 gen_op_negl_T1_T1();
472 gen_op_not_T1_T1();
474 /* Extended arithmetics. */
475 gen_op_subxl_T0_C();
476 writeback = 0;
477 break;
478 default:
479 fprintf (logfile, "illegal ALU op.\n");
480 BUG();
481 break;
484 if (dc->update_cc)
485 gen_op_update_cc_src_T1();
487 if (size == 1)
488 gen_op_andl_T0_im(0xff);
489 else if (size == 2)
490 gen_op_andl_T0_im(0xffff);
491 /* Writeback. */
492 if (writeback) {
493 if (size == 4)
494 gen_movl_reg_T0[rd]();
495 else {
496 gen_op_movl_T1_T0();
497 gen_movl_T0_reg[rd]();
498 if (size == 1)
499 gen_op_andl_T0_im(~0xff);
500 else
501 gen_op_andl_T0_im(~0xffff);
502 gen_op_orl_T0_T1();
503 gen_movl_reg_T0[rd]();
504 gen_op_movl_T0_T1();
507 if (dc->update_cc)
508 gen_op_update_cc_result_T0();
511 /* TODO: Optimize this. */
512 if (!dc->flagx_live)
513 cris_evaluate_flags(dc);
517 static int arith_cc(DisasContext *dc)
519 if (dc->update_cc) {
520 switch (dc->cc_op) {
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;
527 default:
528 return 0;
531 return 0;
534 static void gen_tst_cc (DisasContext *dc, int cond)
536 int arith_opt;
538 /* TODO: optimize more condition codes. */
539 arith_opt = arith_cc(dc) && !dc->flags_live;
540 switch (cond) {
541 case CC_EQ:
542 if (arith_opt)
543 gen_op_tst_cc_eq_fast ();
544 else {
545 cris_evaluate_flags(dc);
546 gen_op_tst_cc_eq ();
548 break;
549 case CC_NE:
550 if (arith_opt)
551 gen_op_tst_cc_ne_fast ();
552 else {
553 cris_evaluate_flags(dc);
554 gen_op_tst_cc_ne ();
556 break;
557 case CC_CS:
558 cris_evaluate_flags(dc);
559 gen_op_tst_cc_cs ();
560 break;
561 case CC_CC:
562 cris_evaluate_flags(dc);
563 gen_op_tst_cc_cc ();
564 break;
565 case CC_VS:
566 cris_evaluate_flags(dc);
567 gen_op_tst_cc_vs ();
568 break;
569 case CC_VC:
570 cris_evaluate_flags(dc);
571 gen_op_tst_cc_vc ();
572 break;
573 case CC_PL:
574 if (arith_opt)
575 gen_op_tst_cc_pl_fast ();
576 else {
577 cris_evaluate_flags(dc);
578 gen_op_tst_cc_pl ();
580 break;
581 case CC_MI:
582 if (arith_opt)
583 gen_op_tst_cc_mi_fast ();
584 else {
585 cris_evaluate_flags(dc);
586 gen_op_tst_cc_mi ();
588 break;
589 case CC_LS:
590 cris_evaluate_flags(dc);
591 gen_op_tst_cc_ls ();
592 break;
593 case CC_HI:
594 cris_evaluate_flags(dc);
595 gen_op_tst_cc_hi ();
596 break;
597 case CC_GE:
598 cris_evaluate_flags(dc);
599 gen_op_tst_cc_ge ();
600 break;
601 case CC_LT:
602 cris_evaluate_flags(dc);
603 gen_op_tst_cc_lt ();
604 break;
605 case CC_GT:
606 cris_evaluate_flags(dc);
607 gen_op_tst_cc_gt ();
608 break;
609 case CC_LE:
610 cris_evaluate_flags(dc);
611 gen_op_tst_cc_le ();
612 break;
613 case CC_P:
614 cris_evaluate_flags(dc);
615 gen_op_tst_cc_p ();
616 break;
617 case CC_A:
618 cris_evaluate_flags(dc);
619 gen_op_movl_T0_im (1);
620 break;
621 default:
622 BUG();
623 break;
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;
633 dc->bcc = cond;
634 if (cond != CC_A)
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;
649 dc->dyn_jmp = 1;
650 dc->bcc = CC_A;
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;
659 dc->dyn_jmp = 0;
660 dc->bcc = CC_A;
663 void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
665 if (size == 1) {
666 if (sign)
667 gen_op_ldb_T0_T0(dc);
668 else
669 gen_op_ldub_T0_T0(dc);
671 else if (size == 2) {
672 if (sign)
673 gen_op_ldw_T0_T0(dc);
674 else
675 gen_op_lduw_T0_T0(dc);
677 else {
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. */
685 if (size == 1) {
686 gen_op_stb_T0_T1(dc);
688 else if (size == 2) {
689 gen_op_stw_T0_T1(dc);
691 else
692 gen_op_stl_T0_T1(dc);
695 /* sign extend T1 according to size. */
696 static void gen_sext_T1_T0(int size)
698 if (size == 1)
699 gen_op_extb_T1_T0();
700 else if (size == 2)
701 gen_op_extw_T1_T0();
704 static void gen_sext_T1_T1(int size)
706 if (size == 1)
707 gen_op_extb_T1_T1();
708 else if (size == 2)
709 gen_op_extw_T1_T1();
712 static void gen_sext_T0_T0(int size)
714 if (size == 1)
715 gen_op_extb_T0_T0();
716 else if (size == 2)
717 gen_op_extw_T0_T0();
720 static void gen_zext_T0_T0(int size)
722 if (size == 1)
723 gen_op_zextb_T0_T0();
724 else if (size == 2)
725 gen_op_zextw_T0_T0();
728 static void gen_zext_T1_T0(int size)
730 if (size == 1)
731 gen_op_zextb_T1_T0();
732 else if (size == 2)
733 gen_op_zextw_T1_T0();
736 static void gen_zext_T1_T1(int size)
738 if (size == 1)
739 gen_op_zextb_T1_T1();
740 else if (size == 2)
741 gen_op_zextw_T1_T1();
744 #if DISAS_CRIS
745 static char memsize_char(int size)
747 switch (size)
749 case 1: return 'b'; break;
750 case 2: return 'w'; break;
751 case 4: return 'd'; break;
752 default:
753 return 'x';
754 break;
757 #endif
759 static unsigned int memsize_z(DisasContext *dc)
761 return dc->zsize + 1;
764 static unsigned int memsize_zz(DisasContext *dc)
766 switch (dc->zzsize)
768 case 0: return 1;
769 case 1: return 2;
770 default:
771 return 4;
775 static void do_postinc (DisasContext *dc, int size)
777 if (!dc->postinc)
778 return;
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,
786 int size, int s_ext)
788 gen_movl_T0_reg[rs]();
789 gen_op_movl_T1_T0();
790 if (s_ext)
791 gen_sext_T1_T1(size);
792 else
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
798 needed. */
799 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
800 int size, int s_ext)
802 dec_prep_move_r(dc, rs, rd, size, s_ext);
804 gen_movl_T0_reg[rd]();
805 if (s_ext)
806 gen_sext_T0_T0(size);
807 else
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
813 needed. */
814 static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
816 unsigned int rs, rd;
817 uint32_t imm;
818 int is_imm;
819 int insn_len = 2;
821 rs = dc->op1;
822 rd = dc->op2;
823 is_imm = rs == 15 && dc->postinc;
825 /* Load [$rs] onto T1. */
826 if (is_imm) {
827 insn_len = 2 + memsize;
828 if (memsize == 1)
829 insn_len++;
831 imm = ldl_code(dc->pc + 2);
832 if (memsize != 4) {
833 if (s_ext) {
834 imm = sign_extend(imm, (memsize * 8) - 1);
835 } else {
836 if (memsize == 1)
837 imm &= 0xff;
838 else
839 imm &= 0xffff;
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);
845 dc->postinc = 0;
846 } else {
847 gen_movl_T0_reg[rs]();
848 gen_load_T0_T0(dc, memsize, 0);
849 gen_op_movl_T1_T0();
850 if (s_ext)
851 gen_sext_T1_T1(memsize);
852 else
853 gen_zext_T1_T1(memsize);
856 /* put dest in T0. */
857 gen_movl_T0_reg[rd]();
858 return insn_len;
861 #if DISAS_CRIS
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"
868 assert(cc < 16);
869 return cc_names[cc];
871 #endif
873 static unsigned int dec_bccq(DisasContext *dc)
875 int32_t offset;
876 int sign;
877 uint32_t cond = dc->op2;
878 int tmp;
880 offset = EXTRACT_FIELD (dc->ir, 1, 7);
881 sign = EXTRACT_FIELD(dc->ir, 0, 0);
883 offset *= 2;
884 offset |= sign << 8;
885 tmp = offset;
886 offset = sign_extend(offset, 8);
888 /* op2 holds the condition-code. */
889 cris_cc_mask(dc, 0);
890 cris_prepare_cc_branch (dc, offset, cond);
891 return 2;
893 static unsigned int dec_addoq(DisasContext *dc)
895 uint32_t imm;
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));
901 cris_cc_mask(dc, 0);
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);
906 return 2;
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);
919 return 2;
921 static unsigned int dec_moveq(DisasContext *dc)
923 uint32_t imm;
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));
929 cris_cc_mask(dc, 0);
930 gen_op_movl_T1_im(imm);
931 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
933 return 2;
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);
946 return 2;
948 static unsigned int dec_cmpq(DisasContext *dc)
950 uint32_t imm;
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);
959 return 2;
961 static unsigned int dec_andq(DisasContext *dc)
963 uint32_t imm;
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);
972 return 2;
974 static unsigned int dec_orq(DisasContext *dc)
976 uint32_t imm;
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);
984 return 2;
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();
998 dc->flags_live = 1;
999 return 2;
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);
1009 return 2;
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);
1020 return 2;
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);
1031 return 2;
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);
1044 return 2;
1047 static unsigned int dec_scc_r(DisasContext *dc)
1049 int cond = dc->op2;
1051 DIS(fprintf (logfile, "s%s $r%u\n",
1052 cc_name(cond), dc->op1));
1054 if (cond != CC_A)
1056 gen_tst_cc (dc, cond);
1057 gen_op_movl_T1_T0();
1059 else
1060 gen_op_movl_T1_im(1);
1062 cris_cc_mask(dc, 0);
1063 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1064 return 2;
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);
1076 return 2;
1079 static unsigned int dec_lz_r(DisasContext *dc)
1081 DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1082 dc->op1, dc->op2));
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);
1086 return 2;
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);
1099 return 2;
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);
1112 return 2;
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);
1125 return 2;
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);
1138 return 2;
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);
1151 return 2;
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);
1163 return 2;
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);
1175 return 2;
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);
1189 return 2;
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);
1200 return 2;
1203 static unsigned int dec_abs_r(DisasContext *dc)
1205 DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1206 dc->op1, dc->op2));
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);
1211 return 2;
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);
1222 return 2;
1225 static unsigned int dec_addc_r(DisasContext *dc)
1227 DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1228 dc->op1, dc->op2));
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);
1233 return 2;
1236 static unsigned int dec_mcp_r(DisasContext *dc)
1238 DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1239 dc->op2, dc->op1));
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);
1246 return 2;
1249 #if DISAS_CRIS
1250 static char * swapmode_name(int mode, char *modename) {
1251 int i = 0;
1252 if (mode & 8)
1253 modename[i++] = 'n';
1254 if (mode & 4)
1255 modename[i++] = 'w';
1256 if (mode & 2)
1257 modename[i++] = 'b';
1258 if (mode & 1)
1259 modename[i++] = 'r';
1260 modename[i++] = 0;
1261 return modename;
1263 #endif
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]();
1273 if (dc->op2 & 8)
1274 gen_op_not_T0_T0();
1275 if (dc->op2 & 4)
1276 gen_op_swapw_T0_T0();
1277 if (dc->op2 & 2)
1278 gen_op_swapb_T0_T0();
1279 if (dc->op2 & 1)
1280 gen_op_swapr_T0_T0();
1281 gen_op_movl_T1_T0();
1282 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1283 return 2;
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);
1294 return 2;
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]();
1306 return 2;
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]();
1318 return 2;
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);
1329 return 2;
1332 static unsigned int dec_btst_r(DisasContext *dc)
1334 DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1335 dc->op1, dc->op2));
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();
1343 dc->flags_live = 1;
1344 return 2;
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);
1355 return 2;
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",
1363 memsize_char(size),
1364 dc->op1, dc->op2));
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);
1369 return 2;
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",
1377 memsize_char(size),
1378 dc->op1, dc->op2));
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);
1385 return 2;
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",
1393 memsize_char(size),
1394 dc->op1, dc->op2));
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);
1402 return 2;
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",
1409 memsize_char(size),
1410 dc->op1, dc->op2));
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);
1418 return 2;
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",
1426 memsize_char(size),
1427 dc->op1, dc->op2));
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);
1435 return 2;
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",
1443 memsize_char(size),
1444 dc->op1, dc->op2));
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);
1452 return 2;
1455 static unsigned int dec_setclrf(DisasContext *dc)
1457 uint32_t flags;
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"));
1467 else
1468 DIS(fprintf (logfile, "%sf %x\n",
1469 set ? "set" : "clr",
1470 flags));
1472 if (set && (flags & X_FLAG)) {
1473 dc->flagx_live = 1;
1474 dc->flags_x = 1;
1477 /* Simply decode the flags. */
1478 cris_evaluate_flags (dc);
1479 cris_update_cc_op(dc, CC_OP_FLAGS);
1480 if (set)
1481 gen_op_setf (flags);
1482 else
1483 gen_op_clrf (flags);
1484 dc->flags_live = 1;
1485 return 2;
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();
1497 return 2;
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);
1506 return 2;
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]();
1515 return 2;
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]);
1524 return 2;
1527 static unsigned int dec_move_mr(DisasContext *dc)
1529 int memsize = memsize_zz(dc);
1530 int insn_len;
1531 DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1532 memsize_char(memsize),
1533 dc->op1, dc->postinc ? "+]" : "]",
1534 dc->op2));
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);
1540 return insn_len;
1543 static unsigned int dec_movs_m(DisasContext *dc)
1545 int memsize = memsize_z(dc);
1546 int insn_len;
1547 DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1548 memsize_char(memsize),
1549 dc->op1, dc->postinc ? "+]" : "]",
1550 dc->op2));
1552 /* sign extend. */
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);
1557 return insn_len;
1560 static unsigned int dec_addu_m(DisasContext *dc)
1562 int memsize = memsize_z(dc);
1563 int insn_len;
1564 DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1565 memsize_char(memsize),
1566 dc->op1, dc->postinc ? "+]" : "]",
1567 dc->op2));
1569 /* sign extend. */
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);
1574 return insn_len;
1577 static unsigned int dec_adds_m(DisasContext *dc)
1579 int memsize = memsize_z(dc);
1580 int insn_len;
1581 DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1582 memsize_char(memsize),
1583 dc->op1, dc->postinc ? "+]" : "]",
1584 dc->op2));
1586 /* sign extend. */
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);
1591 return insn_len;
1594 static unsigned int dec_subu_m(DisasContext *dc)
1596 int memsize = memsize_z(dc);
1597 int insn_len;
1598 DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1599 memsize_char(memsize),
1600 dc->op1, dc->postinc ? "+]" : "]",
1601 dc->op2));
1603 /* sign extend. */
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);
1608 return insn_len;
1611 static unsigned int dec_subs_m(DisasContext *dc)
1613 int memsize = memsize_z(dc);
1614 int insn_len;
1615 DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1616 memsize_char(memsize),
1617 dc->op1, dc->postinc ? "+]" : "]",
1618 dc->op2));
1620 /* sign extend. */
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);
1625 return insn_len;
1628 static unsigned int dec_movu_m(DisasContext *dc)
1630 int memsize = memsize_z(dc);
1631 int insn_len;
1633 DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1634 memsize_char(memsize),
1635 dc->op1, dc->postinc ? "+]" : "]",
1636 dc->op2));
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);
1642 return insn_len;
1645 static unsigned int dec_cmpu_m(DisasContext *dc)
1647 int memsize = memsize_z(dc);
1648 int insn_len;
1649 DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1650 memsize_char(memsize),
1651 dc->op1, dc->postinc ? "+]" : "]",
1652 dc->op2));
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);
1658 return insn_len;
1661 static unsigned int dec_cmps_m(DisasContext *dc)
1663 int memsize = memsize_z(dc);
1664 int insn_len;
1665 DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1666 memsize_char(memsize),
1667 dc->op1, dc->postinc ? "+]" : "]",
1668 dc->op2));
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);
1674 return insn_len;
1677 static unsigned int dec_cmp_m(DisasContext *dc)
1679 int memsize = memsize_zz(dc);
1680 int insn_len;
1681 DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1682 memsize_char(memsize),
1683 dc->op1, dc->postinc ? "+]" : "]",
1684 dc->op2));
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);
1690 return insn_len;
1693 static unsigned int dec_test_m(DisasContext *dc)
1695 int memsize = memsize_zz(dc);
1696 int insn_len;
1697 DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1698 memsize_char(memsize),
1699 dc->op1, dc->postinc ? "+]" : "]",
1700 dc->op2));
1702 cris_cc_mask(dc, CC_MASK_NZ);
1703 gen_op_clrf(3);
1704 insn_len = dec_prep_alu_m(dc, 0, memsize);
1705 gen_op_swp_T0_T1();
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);
1709 return insn_len;
1712 static unsigned int dec_and_m(DisasContext *dc)
1714 int memsize = memsize_zz(dc);
1715 int insn_len;
1716 DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1717 memsize_char(memsize),
1718 dc->op1, dc->postinc ? "+]" : "]",
1719 dc->op2));
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);
1725 return insn_len;
1728 static unsigned int dec_add_m(DisasContext *dc)
1730 int memsize = memsize_zz(dc);
1731 int insn_len;
1732 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1733 memsize_char(memsize),
1734 dc->op1, dc->postinc ? "+]" : "]",
1735 dc->op2));
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);
1741 return insn_len;
1744 static unsigned int dec_addo_m(DisasContext *dc)
1746 int memsize = memsize_zz(dc);
1747 int insn_len;
1748 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1749 memsize_char(memsize),
1750 dc->op1, dc->postinc ? "+]" : "]",
1751 dc->op2));
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);
1757 return insn_len;
1760 static unsigned int dec_bound_m(DisasContext *dc)
1762 int memsize = memsize_zz(dc);
1763 int insn_len;
1764 DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1765 memsize_char(memsize),
1766 dc->op1, dc->postinc ? "+]" : "]",
1767 dc->op2));
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);
1773 return insn_len;
1776 static unsigned int dec_addc_mr(DisasContext *dc)
1778 int insn_len = 2;
1779 DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1780 dc->op1, dc->postinc ? "+]" : "]",
1781 dc->op2));
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);
1787 do_postinc(dc, 4);
1788 return insn_len;
1791 static unsigned int dec_sub_m(DisasContext *dc)
1793 int memsize = memsize_zz(dc);
1794 int insn_len;
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);
1804 return insn_len;
1807 static unsigned int dec_or_m(DisasContext *dc)
1809 int memsize = memsize_zz(dc);
1810 int insn_len;
1811 DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1812 memsize_char(memsize),
1813 dc->op1, dc->postinc ? "+]" : "]",
1814 dc->op2, dc->pc));
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);
1820 return insn_len;
1823 static unsigned int dec_move_mp(DisasContext *dc)
1825 int memsize = memsize_zz(dc);
1826 int insn_len = 2;
1828 DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1829 memsize_char(memsize),
1830 dc->op1,
1831 dc->postinc ? "+]" : "]",
1832 dc->op2));
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);
1840 return insn_len;
1843 static unsigned int dec_move_pm(DisasContext *dc)
1845 int memsize;
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);
1858 if (dc->postinc)
1860 gen_op_addl_T0_im(memsize);
1861 gen_movl_reg_T0[dc->op1]();
1863 return 2;
1866 static unsigned int dec_movem_mr(DisasContext *dc)
1868 int i;
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();
1885 if (dc->postinc) {
1886 /* writeback the updated pointer value. */
1887 gen_movl_reg_T0[dc->op1]();
1889 return 2;
1892 static unsigned int dec_movem_rm(DisasContext *dc)
1894 int i;
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]();
1907 /* Displace it. */
1908 gen_op_addl_T0_im(i * 4);
1910 /* Perform the store. */
1911 gen_store_T0_T1(dc, 4);
1913 if (dc->postinc) {
1914 /* Update the address. */
1915 gen_op_addl_T0_im(4);
1916 /* writeback the updated pointer value. */
1917 gen_movl_reg_T0[dc->op1]();
1919 return 2;
1922 static unsigned int dec_move_rm(DisasContext *dc)
1924 int memsize;
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);
1937 if (dc->postinc)
1939 gen_op_addl_T0_im(memsize);
1940 gen_movl_reg_T0[dc->op1]();
1942 return 2;
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);
1953 return 2;
1956 static unsigned int dec_lapc_im(DisasContext *dc)
1958 unsigned int rd;
1959 int32_t imm;
1960 int insn_len = 6;
1962 rd = dc->op2;
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] ();
1969 return insn_len;
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);
1981 return 2;
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);
1995 return 2;
1998 static unsigned int dec_jas_im(DisasContext *dc)
2000 uint32_t imm;
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);
2012 return 6;
2015 static unsigned int dec_jasc_im(DisasContext *dc)
2017 uint32_t imm;
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);
2029 return 6;
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);
2042 return 2;
2045 static unsigned int dec_bcc_im(DisasContext *dc)
2047 int32_t offset;
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);
2060 return 4;
2063 static unsigned int dec_bas_im(DisasContext *dc)
2065 int32_t simm;
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);
2078 return 6;
2081 static unsigned int dec_basc_im(DisasContext *dc)
2083 int32_t simm;
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);
2094 return 6;
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. */
2105 goto done;
2107 switch (dc->op2 & 7) {
2108 case 2:
2109 /* rfe. */
2110 cris_evaluate_flags(dc);
2111 gen_op_ccs_rshift();
2112 break;
2113 case 5:
2114 /* rfn. */
2115 BUG();
2116 break;
2117 case 6:
2118 /* break. */
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);
2123 break;
2124 default:
2125 printf ("op2=%x\n", dc->op2);
2126 BUG();
2127 break;
2130 done:
2131 return 2;
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);
2138 fflush(NULL);
2139 BUG();
2140 return 2;
2143 struct decoder_info {
2144 struct {
2145 uint32_t bits;
2146 uint32_t mask;
2148 unsigned int (*dec)(DisasContext *dc);
2149 } decinfo[] = {
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},
2158 {DEC_ORQ, dec_orq},
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},
2251 {{0, 0}, dec_null}
2254 static inline unsigned int
2255 cris_decoder(DisasContext *dc)
2257 unsigned int insn_len = 2;
2258 uint32_t tmp;
2259 int i;
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);
2278 break;
2282 return insn_len;
2285 static void check_breakpoint(CPUState *env, DisasContext *dc)
2287 int j;
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();
2294 gen_op_debug();
2295 dc->is_jmp = DISAS_UPDATE;
2302 /* generate intermediate code for basic block 'tb'. */
2303 struct DisasContext ctx;
2304 static int
2305 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2306 int search_pc)
2308 uint16_t *gen_opc_end;
2309 uint32_t pc_start;
2310 unsigned int insn_len;
2311 int j, lj;
2312 struct DisasContext *dc = &ctx;
2313 uint32_t next_page_start;
2315 pc_start = tb->pc;
2316 dc->env = env;
2317 dc->tb = tb;
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;
2324 dc->pc = pc_start;
2325 dc->singlestep_enabled = env->singlestep_enabled;
2326 dc->flagx_live = 0;
2327 dc->flags_x = 0;
2328 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2329 lj = -1;
2332 check_breakpoint(env, dc);
2333 if (dc->is_jmp == DISAS_JUMP)
2334 goto done;
2336 if (search_pc) {
2337 j = gen_opc_ptr - gen_opc_buf;
2338 if (lj < j) {
2339 lj++;
2340 while (lj < j)
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());
2349 dc->pc += insn_len;
2350 if (!dc->flagx_live
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]();
2356 dc->flagx_live = 1;
2357 dc->flags_x = 0;
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) {
2368 gen_op_jmp ();
2369 dc->is_jmp = DISAS_UPDATE;
2371 else {
2372 /* Conditional jmp. */
2373 gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2374 dc->is_jmp = DISAS_UPDATE;
2379 if (env->singlestep_enabled)
2380 break;
2381 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2382 && dc->pc < next_page_start);
2384 if (!dc->is_jmp) {
2385 gen_op_movl_T0_im((long)dc->pc);
2386 gen_op_movl_pc_T0();
2389 cris_evaluate_flags (dc);
2390 done:
2391 if (__builtin_expect(env->singlestep_enabled, 0)) {
2392 gen_op_debug();
2393 } else {
2394 switch(dc->is_jmp) {
2395 case DISAS_NEXT:
2396 gen_goto_tb(dc, 1, dc->pc);
2397 break;
2398 default:
2399 case DISAS_JUMP:
2400 case DISAS_UPDATE:
2401 /* indicate that the hash table must be used
2402 to find the next TB */
2403 /* T0 is used to index the jmp tables. */
2404 gen_op_movl_T0_0();
2405 gen_op_exit_tb();
2406 break;
2407 case DISAS_TB_JUMP:
2408 /* nothing more to generate */
2409 break;
2412 *gen_opc_ptr = INDEX_op_end;
2413 if (search_pc) {
2414 j = gen_opc_ptr - gen_opc_buf;
2415 lj++;
2416 while (lj <= j)
2417 gen_opc_instr_start[lj++] = 0;
2418 } else {
2419 tb->size = dc->pc - pc_start;
2422 #ifdef DEBUG_DISAS
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");
2434 #endif
2435 return 0;
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, ...),
2450 int flags)
2452 int i;
2453 uint32_t srs;
2455 if (!env || !f)
2456 return;
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"
2460 "debug=%x %x %x\n",
2461 env->pc, env->pregs[SR_CCS], env->btaken, env->btarget,
2462 env->cc_op,
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);
2479 if (srs < 256) {
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)
2493 CPUCRISState *env;
2495 env = qemu_mallocz(sizeof(CPUCRISState));
2496 if (!env)
2497 return NULL;
2498 cpu_exec_init(env);
2499 cpu_reset(env);
2500 return env;
2503 void cpu_reset (CPUCRISState *env)
2505 memset(env, 0, offsetof(CPUCRISState, breakpoints));
2506 tlb_flush(env, 1);