Optimize clear insns by treating support reg P0 specially and
[qemu] / target-cris / translate.c
1 /*
2  *  CRIS emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2007 AXIS Communications AB
5  *  Written by Edgar E. Iglesias.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 /*
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
26  *
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.
30  *
31  * For example the following CRIS code:
32  * add.d [$r0], $r1
33  *
34  * translates into:
35  *
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
39  *
40  * The actual names for the micro-code generators vary but the example
41  * illustrates the point.
42  */
43
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <inttypes.h>
49 #include <assert.h>
50
51 #include "cpu.h"
52 #include "exec-all.h"
53 #include "disas.h"
54 #include "crisv32-decode.h"
55
56 #define CRIS_STATS 0
57 #if CRIS_STATS
58 #define STATS(x) x
59 #else
60 #define STATS(x)
61 #endif
62
63 #define DISAS_CRIS 0
64 #if DISAS_CRIS
65 #define DIS(x) x
66 #else
67 #define DIS(x)
68 #endif
69
70 #ifdef USE_DIRECT_JUMP
71 #define TBPARAM(x)
72 #else
73 #define TBPARAM(x) (long)(x)
74 #endif
75
76 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
77 #define BUG_ON(x) ({if (x) BUG();})
78
79 /* Used by the decoder.  */
80 #define EXTRACT_FIELD(src, start, end) \
81             (((src) >> start) & ((1 << (end - start + 1)) - 1))
82
83 #define CC_MASK_NZ 0xc
84 #define CC_MASK_NZV 0xe
85 #define CC_MASK_NZVC 0xf
86 #define CC_MASK_RNZV 0x10e
87
88 static uint16_t *gen_opc_ptr;
89 static uint32_t *gen_opparam_ptr;
90
91 enum {
92 #define DEF(s, n, copy_size) INDEX_op_ ## s,
93 #include "opc.h"
94 #undef DEF
95     NB_OPS,
96 };
97 #include "gen-op.h"
98
99 /* This is the state at translation time.  */
100 typedef struct DisasContext {
101         CPUState *env;
102         target_ulong pc, insn_pc;
103
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;
112
113         int update_cc;
114         int cc_op;
115         int cc_size;
116         uint32_t cc_mask;
117         int flags_live;
118         int flagx_live;
119         int flags_x;
120         uint32_t tb_entry_flags;
121
122         int memidx; /* user or kernel mode.  */
123         int is_jmp;
124         int dyn_jmp;
125
126         uint32_t delayed_pc;
127         int delayed_branch;
128         int bcc;
129         uint32_t condlabel;
130
131         struct TranslationBlock *tb;
132         int singlestep_enabled;
133 } DisasContext;
134
135 void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
136 static void gen_BUG(DisasContext *dc, char *file, int line)
137 {
138         printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
139         fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
140         cpu_dump_state (dc->env, stdout, fprintf, 0);
141         fflush(NULL);
142         cris_prepare_jmp (dc, 0x70000000 + line);
143 }
144
145 /* Table to generate quick moves from T0 onto any register.  */
146 static GenOpFunc *gen_movl_reg_T0[16] =
147 {
148         gen_op_movl_r0_T0, gen_op_movl_r1_T0,
149         gen_op_movl_r2_T0, gen_op_movl_r3_T0,
150         gen_op_movl_r4_T0, gen_op_movl_r5_T0,
151         gen_op_movl_r6_T0, gen_op_movl_r7_T0,
152         gen_op_movl_r8_T0, gen_op_movl_r9_T0,
153         gen_op_movl_r10_T0, gen_op_movl_r11_T0,
154         gen_op_movl_r12_T0, gen_op_movl_r13_T0,
155         gen_op_movl_r14_T0, gen_op_movl_r15_T0,
156 };
157 static GenOpFunc *gen_movl_T0_reg[16] =
158 {
159         gen_op_movl_T0_r0, gen_op_movl_T0_r1,
160         gen_op_movl_T0_r2, gen_op_movl_T0_r3,
161         gen_op_movl_T0_r4, gen_op_movl_T0_r5,
162         gen_op_movl_T0_r6, gen_op_movl_T0_r7,
163         gen_op_movl_T0_r8, gen_op_movl_T0_r9,
164         gen_op_movl_T0_r10, gen_op_movl_T0_r11,
165         gen_op_movl_T0_r12, gen_op_movl_T0_r13,
166         gen_op_movl_T0_r14, gen_op_movl_T0_r15,
167 };
168
169 static void noop_write(void) {
170         /* nop.  */
171 }
172
173 static void gen_vr_read(void) {
174         gen_op_movl_T0_im(32);
175 }
176
177 static void gen_movl_T0_p0(void) {
178         gen_op_movl_T0_im(0);
179 }
180
181 static void gen_ccs_read(void) {
182         gen_op_movl_T0_p13();
183 }
184
185 static void gen_ccs_write(void) {
186         gen_op_movl_p13_T0();
187 }
188
189 /* Table to generate quick moves from T0 onto any register.  */
190 static GenOpFunc *gen_movl_preg_T0[16] =
191 {
192         noop_write,  /* bz, not writeable.  */
193         noop_write,  /* vr, not writeable.  */
194         gen_op_movl_p2_T0, gen_op_movl_p3_T0,
195         noop_write,  /* wz, not writeable.  */
196         gen_op_movl_p5_T0,
197         gen_op_movl_p6_T0, gen_op_movl_p7_T0,
198         noop_write,  /* dz, not writeable.  */
199         gen_op_movl_p9_T0,
200         gen_op_movl_p10_T0, gen_op_movl_p11_T0,
201         gen_op_movl_p12_T0,
202         gen_ccs_write, /* ccs needs special treatment.  */
203         gen_op_movl_p14_T0, gen_op_movl_p15_T0,
204 };
205 static GenOpFunc *gen_movl_T0_preg[16] =
206 {
207         gen_movl_T0_p0,
208         gen_vr_read,
209         gen_op_movl_T0_p2, gen_op_movl_T0_p3,
210         gen_op_movl_T0_p4, gen_op_movl_T0_p5,
211         gen_op_movl_T0_p6, gen_op_movl_T0_p7,
212         gen_op_movl_T0_p8, gen_op_movl_T0_p9,
213         gen_op_movl_T0_p10, gen_op_movl_T0_p11,
214         gen_op_movl_T0_p12,
215         gen_ccs_read, /* ccs needs special treatment.  */
216         gen_op_movl_T0_p14, gen_op_movl_T0_p15,
217 };
218
219 /* We need this table to handle moves with implicit width.  */
220 int preg_sizes[] = {
221         1, /* bz.  */
222         1, /* vr.  */
223         4, /* pid.  */
224         1, /* srs.  */
225         2, /* wz.  */
226         4, 4, 4,
227         4, 4, 4, 4,
228         4, 4, 4, 4,
229 };
230
231 #ifdef CONFIG_USER_ONLY
232 #define GEN_OP_LD(width, reg) \
233   void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
234     gen_op_ld##width##_T0_##reg##_raw(); \
235   }
236 #define GEN_OP_ST(width, reg) \
237   void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
238     gen_op_st##width##_##reg##_T1_raw(); \
239   }
240 #else
241 #define GEN_OP_LD(width, reg) \
242   void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
243     if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
244     else gen_op_ld##width##_T0_##reg##_user();\
245   }
246 #define GEN_OP_ST(width, reg) \
247   void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
248     if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
249     else gen_op_st##width##_##reg##_T1_user();\
250   }
251 #endif
252
253 GEN_OP_LD(ub, T0)
254 GEN_OP_LD(b, T0)
255 GEN_OP_ST(b, T0)
256 GEN_OP_LD(uw, T0)
257 GEN_OP_LD(w, T0)
258 GEN_OP_ST(w, T0)
259 GEN_OP_LD(l, T0)
260 GEN_OP_ST(l, T0)
261
262 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
263 {
264         TranslationBlock *tb;
265         tb = dc->tb;
266         if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
267                 if (n == 0)
268                         gen_op_goto_tb0(TBPARAM(tb));
269                 else
270                         gen_op_goto_tb1(TBPARAM(tb));
271                 gen_op_movl_T0_0();
272         } else {
273                 gen_op_movl_T0_0();
274         }
275         gen_op_exit_tb();
276 }
277
278 /* Sign extend at translation time.  */
279 static int sign_extend(unsigned int val, unsigned int width)
280 {
281         int sval;
282
283         /* LSL.  */
284         val <<= 31 - width;
285         sval = val;
286         /* ASR.  */
287         sval >>= 31 - width;
288         return sval;
289 }
290
291 static void cris_evaluate_flags(DisasContext *dc)
292 {
293         if (!dc->flags_live) {
294
295                 switch (dc->cc_op)
296                 {
297                         case CC_OP_MCP:
298                                 gen_op_evaluate_flags_mcp ();
299                                 break;
300                         case CC_OP_MULS:
301                                 gen_op_evaluate_flags_muls ();
302                                 break;
303                         case CC_OP_MULU:
304                                 gen_op_evaluate_flags_mulu ();
305                                 break;
306                         case CC_OP_MOVE:
307                                 switch (dc->cc_size)
308                                 {
309                                         case 4:
310                                                 gen_op_evaluate_flags_move_4();
311                                                 break;
312                                         case 2:
313                                                 gen_op_evaluate_flags_move_2();
314                                                 break;
315                                         default:
316                                                 gen_op_evaluate_flags ();
317                                                 break;
318                                 }
319                                 break;
320
321                         default:
322                         {
323                                 switch (dc->cc_size)
324                                 {
325                                         case 4:
326                                                 gen_op_evaluate_flags_alu_4 ();
327                                                 break;
328                                         default:
329                                                 gen_op_evaluate_flags ();
330                                                 break;
331                                 }
332                         }
333                         break;
334                 }
335                 dc->flags_live = 1;
336         }
337 }
338
339 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
340 {
341         uint32_t ovl;
342
343         /* Check if we need to evaluate the condition codes due to 
344            CC overlaying.  */
345         ovl = (dc->cc_mask ^ mask) & ~mask;
346         if (ovl) {
347                 /* TODO: optimize this case. It trigs all the time.  */
348                 cris_evaluate_flags (dc);
349         }
350         dc->cc_mask = mask;
351
352         dc->update_cc = 1;
353         if (mask == 0)
354                 dc->update_cc = 0;
355         else {
356                 gen_op_update_cc_mask(mask);
357                 dc->flags_live = 0;
358         }
359 }
360
361 static void cris_update_cc_op(DisasContext *dc, int op)
362 {
363         dc->cc_op = op;
364         gen_op_update_cc_op(op);
365         dc->flags_live = 0;
366 }
367 static void cris_update_cc_size(DisasContext *dc, int size)
368 {
369         dc->cc_size = size;
370         gen_op_update_cc_size_im(size);
371 }
372
373 /* op is the operation.
374    T0, T1 are the operands.
375    dst is the destination reg.
376 */
377 static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
378 {
379         int writeback = 1;
380         if (dc->update_cc) {
381                 cris_update_cc_op(dc, op);
382                 cris_update_cc_size(dc, size);
383                 gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
384                 gen_op_update_cc_dest_T0();
385         }
386
387         /* Emit the ALU insns.  */
388         switch (op)
389         {
390                 case CC_OP_ADD:
391                         gen_op_addl_T0_T1();
392                         /* Extended arithmetics.  */
393                         if (!dc->flagx_live)
394                                 gen_op_addxl_T0_C();
395                         else if (dc->flags_x)
396                                 gen_op_addxl_T0_C();
397                         break;
398                 case CC_OP_ADDC:
399                         gen_op_addl_T0_T1();
400                         gen_op_addl_T0_C();
401                         break;
402                 case CC_OP_MCP:
403                         gen_op_addl_T0_T1();
404                         gen_op_addl_T0_R();
405                         break;
406                 case CC_OP_SUB:
407                         gen_op_negl_T1_T1();
408                         gen_op_addl_T0_T1();
409                         /* CRIS flag evaluation needs ~src.  */
410                         gen_op_negl_T1_T1();
411                         gen_op_not_T1_T1();
412
413                         /* Extended arithmetics.  */
414                         if (!dc->flagx_live)
415                                 gen_op_subxl_T0_C();
416                         else if (dc->flags_x)
417                                 gen_op_subxl_T0_C();
418                         break;
419                 case CC_OP_MOVE:
420                         gen_op_movl_T0_T1();
421                         break;
422                 case CC_OP_OR:
423                         gen_op_orl_T0_T1();
424                         break;
425                 case CC_OP_AND:
426                         gen_op_andl_T0_T1();
427                         break;
428                 case CC_OP_XOR:
429                         gen_op_xorl_T0_T1();
430                         break;
431                 case CC_OP_LSL:
432                         gen_op_lsll_T0_T1();
433                         break;
434                 case CC_OP_LSR:
435                         gen_op_lsrl_T0_T1();
436                         break;
437                 case CC_OP_ASR:
438                         gen_op_asrl_T0_T1();
439                         break;
440                 case CC_OP_NEG:
441                         gen_op_negl_T0_T1();
442                         /* Extended arithmetics.  */
443                         gen_op_subxl_T0_C();
444                         break;
445                 case CC_OP_LZ:
446                         gen_op_lz_T0_T1();
447                         break;
448                 case CC_OP_BTST:
449                         gen_op_btst_T0_T1();
450                         writeback = 0;
451                         break;
452                 case CC_OP_MULS:
453                         gen_op_muls_T0_T1();
454                         break;
455                 case CC_OP_MULU:
456                         gen_op_mulu_T0_T1();
457                         break;
458                 case CC_OP_DSTEP:
459                         gen_op_dstep_T0_T1();
460                         break;
461                 case CC_OP_BOUND:
462                         gen_op_bound_T0_T1();
463                         break;
464                 case CC_OP_CMP:
465                         gen_op_negl_T1_T1();
466                         gen_op_addl_T0_T1();
467                         /* CRIS flag evaluation needs ~src.  */
468                         gen_op_negl_T1_T1();
469                         gen_op_not_T1_T1();
470
471                         /* Extended arithmetics.  */
472                         gen_op_subxl_T0_C();
473                         writeback = 0;
474                         break;
475                 default:
476                         fprintf (logfile, "illegal ALU op.\n");
477                         BUG();
478                         break;
479         }
480
481         if (dc->update_cc)
482                 gen_op_update_cc_src_T1();
483
484         if (size == 1)
485                 gen_op_andl_T0_im(0xff);
486         else if (size == 2)
487                 gen_op_andl_T0_im(0xffff);
488         /* Writeback.  */
489         if (writeback) {
490                 if (size == 4)
491                         gen_movl_reg_T0[rd]();
492                 else {
493                         gen_op_movl_T1_T0();
494                         gen_movl_T0_reg[rd]();
495                         if (size == 1)
496                                 gen_op_andl_T0_im(~0xff);
497                         else
498                                 gen_op_andl_T0_im(~0xffff);
499                         gen_op_orl_T0_T1();
500                         gen_movl_reg_T0[rd]();
501                         gen_op_movl_T0_T1();
502                 }
503         }
504         if (dc->update_cc)
505                 gen_op_update_cc_result_T0();
506
507         {
508                 /* TODO: Optimize this.  */
509                 if (!dc->flagx_live)
510                         cris_evaluate_flags(dc);
511         }
512 }
513
514 static int arith_cc(DisasContext *dc)
515 {
516         if (dc->update_cc) {
517                 switch (dc->cc_op) {
518                         case CC_OP_ADD: return 1;
519                         case CC_OP_SUB: return 1;
520                         case CC_OP_LSL: return 1;
521                         case CC_OP_LSR: return 1;
522                         case CC_OP_ASR: return 1;
523                         case CC_OP_CMP: return 1;
524                         default:
525                                 return 0;
526                 }
527         }
528         return 0;
529 }
530
531 static void gen_tst_cc (DisasContext *dc, int cond)
532 {
533         int arith_opt;
534
535         /* TODO: optimize more condition codes.  */
536         arith_opt = arith_cc(dc) && !dc->flags_live;
537         switch (cond) {
538                 case CC_EQ:
539                         if (arith_opt)
540                                 gen_op_tst_cc_eq_fast ();
541                         else {
542                                 cris_evaluate_flags(dc);
543                                 gen_op_tst_cc_eq ();
544                         }
545                         break;
546                 case CC_NE:
547                         if (arith_opt)
548                                 gen_op_tst_cc_ne_fast ();
549                         else {
550                                 cris_evaluate_flags(dc);
551                                 gen_op_tst_cc_ne ();
552                         }
553                         break;
554                 case CC_CS:
555                         cris_evaluate_flags(dc);
556                         gen_op_tst_cc_cs ();
557                         break;
558                 case CC_CC:
559                         cris_evaluate_flags(dc);
560                         gen_op_tst_cc_cc ();
561                         break;
562                 case CC_VS:
563                         cris_evaluate_flags(dc);
564                         gen_op_tst_cc_vs ();
565                         break;
566                 case CC_VC:
567                         cris_evaluate_flags(dc);
568                         gen_op_tst_cc_vc ();
569                         break;
570                 case CC_PL:
571                         if (arith_opt)
572                                 gen_op_tst_cc_pl_fast ();
573                         else {
574                                 cris_evaluate_flags(dc);
575                                 gen_op_tst_cc_pl ();
576                         }
577                         break;
578                 case CC_MI:
579                         if (arith_opt)
580                                 gen_op_tst_cc_mi_fast ();
581                         else {
582                                 cris_evaluate_flags(dc);
583                                 gen_op_tst_cc_mi ();
584                         }
585                         break;
586                 case CC_LS:
587                         cris_evaluate_flags(dc);
588                         gen_op_tst_cc_ls ();
589                         break;
590                 case CC_HI:
591                         cris_evaluate_flags(dc);
592                         gen_op_tst_cc_hi ();
593                         break;
594                 case CC_GE:
595                         cris_evaluate_flags(dc);
596                         gen_op_tst_cc_ge ();
597                         break;
598                 case CC_LT:
599                         cris_evaluate_flags(dc);
600                         gen_op_tst_cc_lt ();
601                         break;
602                 case CC_GT:
603                         cris_evaluate_flags(dc);
604                         gen_op_tst_cc_gt ();
605                         break;
606                 case CC_LE:
607                         cris_evaluate_flags(dc);
608                         gen_op_tst_cc_le ();
609                         break;
610                 case CC_P:
611                         cris_evaluate_flags(dc);
612                         gen_op_tst_cc_p ();
613                         break;
614                 case CC_A:
615                         cris_evaluate_flags(dc);
616                         gen_op_movl_T0_im (1);
617                         break;
618                 default:
619                         BUG();
620                         break;
621         };
622 }
623
624 static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
625 {
626         /* This helps us re-schedule the micro-code to insns in delay-slots
627            before the actual jump.  */
628         dc->delayed_branch = 2;
629         dc->delayed_pc = dc->pc + offset;
630         dc->bcc = cond;
631         if (cond != CC_A)
632         {
633                 gen_tst_cc (dc, cond);
634                 gen_op_evaluate_bcc ();
635         }
636         gen_op_movl_T0_im (dc->delayed_pc);
637         gen_op_movl_btarget_T0 ();
638 }
639
640 /* Dynamic jumps, when the dest is in a live reg for example.  */
641 void cris_prepare_dyn_jmp (DisasContext *dc)
642 {
643         /* This helps us re-schedule the micro-code to insns in delay-slots
644            before the actual jump.  */
645         dc->delayed_branch = 2;
646         dc->dyn_jmp = 1;
647         dc->bcc = CC_A;
648 }
649
650 void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
651 {
652         /* This helps us re-schedule the micro-code to insns in delay-slots
653            before the actual jump.  */
654         dc->delayed_branch = 2;
655         dc->delayed_pc = dst;
656         dc->dyn_jmp = 0;
657         dc->bcc = CC_A;
658 }
659
660 void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
661 {
662         if (size == 1) {
663                 if (sign)
664                         gen_op_ldb_T0_T0(dc);
665                 else
666                         gen_op_ldub_T0_T0(dc);
667         }
668         else if (size == 2) {
669                 if (sign)
670                         gen_op_ldw_T0_T0(dc);
671                 else
672                         gen_op_lduw_T0_T0(dc);
673         }
674         else {
675                 gen_op_ldl_T0_T0(dc);
676         }
677 }
678
679 void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
680 {
681         /* Remember, operands are flipped. CRIS has reversed order.  */
682         if (size == 1) {
683                 gen_op_stb_T0_T1(dc);
684         }
685         else if (size == 2) {
686                 gen_op_stw_T0_T1(dc);
687         }
688         else
689                 gen_op_stl_T0_T1(dc);
690 }
691
692 /* sign extend T1 according to size.  */
693 static void gen_sext_T1_T0(int size)
694 {
695         if (size == 1)
696                 gen_op_extb_T1_T0();
697         else if (size == 2)
698                 gen_op_extw_T1_T0();
699 }
700
701 static void gen_sext_T1_T1(int size)
702 {
703         if (size == 1)
704                 gen_op_extb_T1_T1();
705         else if (size == 2)
706                 gen_op_extw_T1_T1();
707 }
708
709 static void gen_sext_T0_T0(int size)
710 {
711         if (size == 1)
712                 gen_op_extb_T0_T0();
713         else if (size == 2)
714                 gen_op_extw_T0_T0();
715 }
716
717 static void gen_zext_T0_T0(int size)
718 {
719         if (size == 1)
720                 gen_op_zextb_T0_T0();
721         else if (size == 2)
722                 gen_op_zextw_T0_T0();
723 }
724
725 static void gen_zext_T1_T0(int size)
726 {
727         if (size == 1)
728                 gen_op_zextb_T1_T0();
729         else if (size == 2)
730                 gen_op_zextw_T1_T0();
731 }
732
733 static void gen_zext_T1_T1(int size)
734 {
735         if (size == 1)
736                 gen_op_zextb_T1_T1();
737         else if (size == 2)
738                 gen_op_zextw_T1_T1();
739 }
740
741 #if DISAS_CRIS
742 static char memsize_char(int size)
743 {
744         switch (size)
745         {
746                 case 1: return 'b';  break;
747                 case 2: return 'w';  break;
748                 case 4: return 'd';  break;
749                 default:
750                         return 'x';
751                         break;
752         }
753 }
754 #endif
755
756 static unsigned int memsize_z(DisasContext *dc)
757 {
758         return dc->zsize + 1;
759 }
760
761 static unsigned int memsize_zz(DisasContext *dc)
762 {
763         switch (dc->zzsize)
764         {
765                 case 0: return 1;
766                 case 1: return 2;
767                 default:
768                         return 4;
769         }
770 }
771
772 static void do_postinc (DisasContext *dc, int size)
773 {
774         if (!dc->postinc)
775                 return;
776         gen_movl_T0_reg[dc->op1]();
777         gen_op_addl_T0_im(size);
778         gen_movl_reg_T0[dc->op1]();
779 }
780
781
782 static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
783                             int size, int s_ext)
784 {
785         gen_movl_T0_reg[rs]();
786         gen_op_movl_T1_T0();
787         if (s_ext)
788                 gen_sext_T1_T1(size);
789         else
790                 gen_zext_T1_T1(size);
791 }
792
793 /* Prepare T0 and T1 for a register alu operation.
794    s_ext decides if the operand1 should be sign-extended or zero-extended when
795    needed.  */
796 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
797                           int size, int s_ext)
798 {
799         dec_prep_move_r(dc, rs, rd, size, s_ext);
800
801         gen_movl_T0_reg[rd]();
802         if (s_ext)
803                 gen_sext_T0_T0(size);
804         else
805                 gen_zext_T0_T0(size);
806 }
807
808 /* Prepare T0 and T1 for a memory + alu operation.
809    s_ext decides if the operand1 should be sign-extended or zero-extended when
810    needed.  */
811 static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
812 {
813         unsigned int rs, rd;
814         uint32_t imm;
815         int is_imm;
816         int insn_len = 2;
817
818         rs = dc->op1;
819         rd = dc->op2;
820         is_imm = rs == 15 && dc->postinc;
821
822         /* Load [$rs] onto T1.  */
823         if (is_imm) {
824                 insn_len = 2 + memsize;
825                 if (memsize == 1)
826                         insn_len++;
827
828                 imm = ldl_code(dc->pc + 2);
829                 if (memsize != 4) {
830                         if (s_ext) {
831                                 imm = sign_extend(imm, (memsize * 8) - 1);
832                         } else {
833                                 if (memsize == 1)
834                                         imm &= 0xff;
835                                 else
836                                         imm &= 0xffff;
837                         }
838                 }
839                 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
840                             imm, rd, s_ext, memsize));
841                 gen_op_movl_T1_im (imm);
842                 dc->postinc = 0;
843         } else {
844                 gen_movl_T0_reg[rs]();
845                 gen_load_T0_T0(dc, memsize, 0);
846                 gen_op_movl_T1_T0();
847                 if (s_ext)
848                         gen_sext_T1_T1(memsize);
849                 else
850                         gen_zext_T1_T1(memsize);
851         }
852
853         /* put dest in T0.  */
854         gen_movl_T0_reg[rd]();
855         return insn_len;
856 }
857
858 #if DISAS_CRIS
859 static const char *cc_name(int cc)
860 {
861         static char *cc_names[16] = {
862                 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
863                 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
864         };
865         assert(cc < 16);
866         return cc_names[cc];
867 }
868 #endif
869
870 static unsigned int dec_bccq(DisasContext *dc)
871 {
872         int32_t offset;
873         int sign;
874         uint32_t cond = dc->op2;
875         int tmp;
876
877         offset = EXTRACT_FIELD (dc->ir, 1, 7);
878         sign = EXTRACT_FIELD(dc->ir, 0, 0);
879
880         offset *= 2;
881         offset |= sign << 8;
882         tmp = offset;
883         offset = sign_extend(offset, 8);
884
885         /* op2 holds the condition-code.  */
886         cris_cc_mask(dc, 0);
887         cris_prepare_cc_branch (dc, offset, cond);
888         return 2;
889 }
890 static unsigned int dec_addoq(DisasContext *dc)
891 {
892         uint32_t imm;
893
894         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
895         imm = sign_extend(dc->op1, 7);
896
897         DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
898         cris_cc_mask(dc, 0);
899         /* Fetch register operand,  */
900         gen_movl_T0_reg[dc->op2]();
901         gen_op_movl_T1_im(imm);
902         crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
903         return 2;
904 }
905 static unsigned int dec_addq(DisasContext *dc)
906 {
907         DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
908
909         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
910
911         cris_cc_mask(dc, CC_MASK_NZVC);
912         /* Fetch register operand,  */
913         gen_movl_T0_reg[dc->op2]();
914         gen_op_movl_T1_im(dc->op1);
915         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
916         return 2;
917 }
918 static unsigned int dec_moveq(DisasContext *dc)
919 {
920         uint32_t imm;
921
922         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
923         imm = sign_extend(dc->op1, 5);
924         DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
925
926         cris_cc_mask(dc, 0);
927         gen_op_movl_T1_im(imm);
928         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
929
930         return 2;
931 }
932 static unsigned int dec_subq(DisasContext *dc)
933 {
934         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
935
936         DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
937
938         cris_cc_mask(dc, CC_MASK_NZVC);
939         /* Fetch register operand,  */
940         gen_movl_T0_reg[dc->op2]();
941         gen_op_movl_T1_im(dc->op1);
942         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
943         return 2;
944 }
945 static unsigned int dec_cmpq(DisasContext *dc)
946 {
947         uint32_t imm;
948         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
949         imm = sign_extend(dc->op1, 5);
950
951         DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
952         cris_cc_mask(dc, CC_MASK_NZVC);
953         gen_movl_T0_reg[dc->op2]();
954         gen_op_movl_T1_im(imm);
955         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
956         return 2;
957 }
958 static unsigned int dec_andq(DisasContext *dc)
959 {
960         uint32_t imm;
961         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
962         imm = sign_extend(dc->op1, 5);
963
964         DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
965         cris_cc_mask(dc, CC_MASK_NZ);
966         gen_movl_T0_reg[dc->op2]();
967         gen_op_movl_T1_im(imm);
968         crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
969         return 2;
970 }
971 static unsigned int dec_orq(DisasContext *dc)
972 {
973         uint32_t imm;
974         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
975         imm = sign_extend(dc->op1, 5);
976         DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
977         cris_cc_mask(dc, CC_MASK_NZ);
978         gen_movl_T0_reg[dc->op2]();
979         gen_op_movl_T1_im(imm);
980         crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
981         return 2;
982 }
983 static unsigned int dec_btstq(DisasContext *dc)
984 {
985         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
986         DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
987         cris_cc_mask(dc, CC_MASK_NZ);
988         gen_movl_T0_reg[dc->op2]();
989         gen_op_movl_T1_im(dc->op1);
990         crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
991
992         cris_update_cc_op(dc, CC_OP_FLAGS);
993         gen_op_movl_flags_T0();
994         dc->flags_live = 1;
995         return 2;
996 }
997 static unsigned int dec_asrq(DisasContext *dc)
998 {
999         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1000         DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
1001         cris_cc_mask(dc, CC_MASK_NZ);
1002         gen_movl_T0_reg[dc->op2]();
1003         gen_op_movl_T1_im(dc->op1);
1004         crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
1005         return 2;
1006 }
1007 static unsigned int dec_lslq(DisasContext *dc)
1008 {
1009         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1010         DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1011
1012         cris_cc_mask(dc, CC_MASK_NZ);
1013         gen_movl_T0_reg[dc->op2]();
1014         gen_op_movl_T1_im(dc->op1);
1015         crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
1016         return 2;
1017 }
1018 static unsigned int dec_lsrq(DisasContext *dc)
1019 {
1020         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1021         DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1022
1023         cris_cc_mask(dc, CC_MASK_NZ);
1024         gen_movl_T0_reg[dc->op2]();
1025         gen_op_movl_T1_im(dc->op1);
1026         crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1027         return 2;
1028 }
1029
1030 static unsigned int dec_move_r(DisasContext *dc)
1031 {
1032         int size = memsize_zz(dc);
1033
1034         DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1035                     memsize_char(size), dc->op1, dc->op2));
1036
1037         cris_cc_mask(dc, CC_MASK_NZ);
1038         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1039         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1040         return 2;
1041 }
1042
1043 static unsigned int dec_scc_r(DisasContext *dc)
1044 {
1045         int cond = dc->op2;
1046
1047         DIS(fprintf (logfile, "s%s $r%u\n",
1048                     cc_name(cond), dc->op1));
1049
1050         if (cond != CC_A)
1051         {
1052                 gen_tst_cc (dc, cond);
1053                 gen_op_movl_T1_T0();
1054         }
1055         else
1056                 gen_op_movl_T1_im(1);
1057
1058         cris_cc_mask(dc, 0);
1059         crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1060         return 2;
1061 }
1062
1063 static unsigned int dec_and_r(DisasContext *dc)
1064 {
1065         int size = memsize_zz(dc);
1066
1067         DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1068                     memsize_char(size), dc->op1, dc->op2));
1069         cris_cc_mask(dc, CC_MASK_NZ);
1070         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1071         crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1072         return 2;
1073 }
1074
1075 static unsigned int dec_lz_r(DisasContext *dc)
1076 {
1077         DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1078                     dc->op1, dc->op2));
1079         cris_cc_mask(dc, CC_MASK_NZ);
1080         dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1081         crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1082         return 2;
1083 }
1084
1085 static unsigned int dec_lsl_r(DisasContext *dc)
1086 {
1087         int size = memsize_zz(dc);
1088
1089         DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1090                     memsize_char(size), dc->op1, dc->op2));
1091         cris_cc_mask(dc, CC_MASK_NZ);
1092         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1093         gen_op_andl_T1_im(63);
1094         crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1095         return 2;
1096 }
1097
1098 static unsigned int dec_lsr_r(DisasContext *dc)
1099 {
1100         int size = memsize_zz(dc);
1101
1102         DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1103                     memsize_char(size), dc->op1, dc->op2));
1104         cris_cc_mask(dc, CC_MASK_NZ);
1105         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1106         gen_op_andl_T1_im(63);
1107         crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1108         return 2;
1109 }
1110
1111 static unsigned int dec_asr_r(DisasContext *dc)
1112 {
1113         int size = memsize_zz(dc);
1114
1115         DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1116                     memsize_char(size), dc->op1, dc->op2));
1117         cris_cc_mask(dc, CC_MASK_NZ);
1118         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1119         gen_op_andl_T1_im(63);
1120         crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1121         return 2;
1122 }
1123
1124 static unsigned int dec_muls_r(DisasContext *dc)
1125 {
1126         int size = memsize_zz(dc);
1127
1128         DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1129                     memsize_char(size), dc->op1, dc->op2));
1130         cris_cc_mask(dc, CC_MASK_NZV);
1131         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1132         gen_sext_T0_T0(size);
1133         crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1134         return 2;
1135 }
1136
1137 static unsigned int dec_mulu_r(DisasContext *dc)
1138 {
1139         int size = memsize_zz(dc);
1140
1141         DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1142                     memsize_char(size), dc->op1, dc->op2));
1143         cris_cc_mask(dc, CC_MASK_NZV);
1144         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1145         gen_zext_T0_T0(size);
1146         crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1147         return 2;
1148 }
1149
1150
1151 static unsigned int dec_dstep_r(DisasContext *dc)
1152 {
1153         DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1154         cris_cc_mask(dc, CC_MASK_NZ);
1155         gen_movl_T0_reg[dc->op1]();
1156         gen_op_movl_T1_T0();
1157         gen_movl_T0_reg[dc->op2]();
1158         crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1159         return 2;
1160 }
1161
1162 static unsigned int dec_xor_r(DisasContext *dc)
1163 {
1164         int size = memsize_zz(dc);
1165         DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1166                     memsize_char(size), dc->op1, dc->op2));
1167         BUG_ON(size != 4); /* xor is dword.  */
1168         cris_cc_mask(dc, CC_MASK_NZ);
1169         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1170         crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1171         return 2;
1172 }
1173
1174 static unsigned int dec_bound_r(DisasContext *dc)
1175 {
1176         int size = memsize_zz(dc);
1177         DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1178                     memsize_char(size), dc->op1, dc->op2));
1179         cris_cc_mask(dc, CC_MASK_NZ);
1180         /* TODO: needs optmimization.  */
1181         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1182         /* rd should be 4.  */
1183         gen_movl_T0_reg[dc->op2]();
1184         crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1185         return 2;
1186 }
1187
1188 static unsigned int dec_cmp_r(DisasContext *dc)
1189 {
1190         int size = memsize_zz(dc);
1191         DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1192                     memsize_char(size), dc->op1, dc->op2));
1193         cris_cc_mask(dc, CC_MASK_NZVC);
1194         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1195         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1196         return 2;
1197 }
1198
1199 static unsigned int dec_abs_r(DisasContext *dc)
1200 {
1201         DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1202                     dc->op1, dc->op2));
1203         cris_cc_mask(dc, CC_MASK_NZ);
1204         dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1205         gen_op_absl_T1_T1();
1206         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1207         return 2;
1208 }
1209
1210 static unsigned int dec_add_r(DisasContext *dc)
1211 {
1212         int size = memsize_zz(dc);
1213         DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1214                     memsize_char(size), dc->op1, dc->op2));
1215         cris_cc_mask(dc, CC_MASK_NZVC);
1216         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1217         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1218         return 2;
1219 }
1220
1221 static unsigned int dec_addc_r(DisasContext *dc)
1222 {
1223         DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1224                     dc->op1, dc->op2));
1225         cris_evaluate_flags(dc);
1226         cris_cc_mask(dc, CC_MASK_NZVC);
1227         dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1228         crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1229         return 2;
1230 }
1231
1232 static unsigned int dec_mcp_r(DisasContext *dc)
1233 {
1234         DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1235                      dc->op2, dc->op1));
1236         cris_evaluate_flags(dc);
1237         cris_cc_mask(dc, CC_MASK_RNZV);
1238         gen_movl_T0_preg[dc->op2]();
1239         gen_op_movl_T1_T0();
1240         gen_movl_T0_reg[dc->op1]();
1241         crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1242         return 2;
1243 }
1244
1245 #if DISAS_CRIS
1246 static char * swapmode_name(int mode, char *modename) {
1247         int i = 0;
1248         if (mode & 8)
1249                 modename[i++] = 'n';
1250         if (mode & 4)
1251                 modename[i++] = 'w';
1252         if (mode & 2)
1253                 modename[i++] = 'b';
1254         if (mode & 1)
1255                 modename[i++] = 'r';
1256         modename[i++] = 0;
1257         return modename;
1258 }
1259 #endif
1260
1261 static unsigned int dec_swap_r(DisasContext *dc)
1262 {
1263         DIS(char modename[4]);
1264         DIS(fprintf (logfile, "swap%s $r%u\n",
1265                      swapmode_name(dc->op2, modename), dc->op1));
1266
1267         cris_cc_mask(dc, CC_MASK_NZ);
1268         gen_movl_T0_reg[dc->op1]();
1269         if (dc->op2 & 8)
1270                 gen_op_not_T0_T0();
1271         if (dc->op2 & 4)
1272                 gen_op_swapw_T0_T0();
1273         if (dc->op2 & 2)
1274                 gen_op_swapb_T0_T0();
1275         if (dc->op2 & 1)
1276                 gen_op_swapr_T0_T0();
1277         gen_op_movl_T1_T0();
1278         crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1279         return 2;
1280 }
1281
1282 static unsigned int dec_or_r(DisasContext *dc)
1283 {
1284         int size = memsize_zz(dc);
1285         DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1286                     memsize_char(size), dc->op1, dc->op2));
1287         cris_cc_mask(dc, CC_MASK_NZ);
1288         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1289         crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1290         return 2;
1291 }
1292
1293 static unsigned int dec_addi_r(DisasContext *dc)
1294 {
1295         DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1296                     memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1297         cris_cc_mask(dc, 0);
1298         dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1299         gen_op_lsll_T0_im(dc->zzsize);
1300         gen_op_addl_T0_T1();
1301         gen_movl_reg_T0[dc->op1]();
1302         return 2;
1303 }
1304
1305 static unsigned int dec_addi_acr(DisasContext *dc)
1306 {
1307         DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1308                     memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1309         cris_cc_mask(dc, 0);
1310         dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1311         gen_op_lsll_T0_im(dc->zzsize);
1312         gen_op_addl_T0_T1();
1313         gen_movl_reg_T0[REG_ACR]();
1314         return 2;
1315 }
1316
1317 static unsigned int dec_neg_r(DisasContext *dc)
1318 {
1319         int size = memsize_zz(dc);
1320         DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1321                     memsize_char(size), dc->op1, dc->op2));
1322         cris_cc_mask(dc, CC_MASK_NZVC);
1323         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1324         crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1325         return 2;
1326 }
1327
1328 static unsigned int dec_btst_r(DisasContext *dc)
1329 {
1330         DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1331                     dc->op1, dc->op2));
1332         cris_cc_mask(dc, CC_MASK_NZ);
1333         dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1334         crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1335
1336         cris_update_cc_op(dc, CC_OP_FLAGS);
1337         gen_op_movl_flags_T0();
1338         dc->flags_live = 1;
1339         return 2;
1340 }
1341
1342 static unsigned int dec_sub_r(DisasContext *dc)
1343 {
1344         int size = memsize_zz(dc);
1345         DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1346                     memsize_char(size), dc->op1, dc->op2));
1347         cris_cc_mask(dc, CC_MASK_NZVC);
1348         dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1349         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1350         return 2;
1351 }
1352
1353 /* Zero extension. From size to dword.  */
1354 static unsigned int dec_movu_r(DisasContext *dc)
1355 {
1356         int size = memsize_z(dc);
1357         DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1358                     memsize_char(size),
1359                     dc->op1, dc->op2));
1360
1361         cris_cc_mask(dc, CC_MASK_NZ);
1362         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1363         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1364         return 2;
1365 }
1366
1367 /* Sign extension. From size to dword.  */
1368 static unsigned int dec_movs_r(DisasContext *dc)
1369 {
1370         int size = memsize_z(dc);
1371         DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1372                     memsize_char(size),
1373                     dc->op1, dc->op2));
1374
1375         cris_cc_mask(dc, CC_MASK_NZ);
1376         gen_movl_T0_reg[dc->op1]();
1377         /* Size can only be qi or hi.  */
1378         gen_sext_T1_T0(size);
1379         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1380         return 2;
1381 }
1382
1383 /* zero extension. From size to dword.  */
1384 static unsigned int dec_addu_r(DisasContext *dc)
1385 {
1386         int size = memsize_z(dc);
1387         DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1388                     memsize_char(size),
1389                     dc->op1, dc->op2));
1390
1391         cris_cc_mask(dc, CC_MASK_NZVC);
1392         gen_movl_T0_reg[dc->op1]();
1393         /* Size can only be qi or hi.  */
1394         gen_zext_T1_T0(size);
1395         gen_movl_T0_reg[dc->op2]();
1396         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1397         return 2;
1398 }
1399 /* Sign extension. From size to dword.  */
1400 static unsigned int dec_adds_r(DisasContext *dc)
1401 {
1402         int size = memsize_z(dc);
1403         DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1404                     memsize_char(size),
1405                     dc->op1, dc->op2));
1406
1407         cris_cc_mask(dc, CC_MASK_NZVC);
1408         gen_movl_T0_reg[dc->op1]();
1409         /* Size can only be qi or hi.  */
1410         gen_sext_T1_T0(size);
1411         gen_movl_T0_reg[dc->op2]();
1412         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1413         return 2;
1414 }
1415
1416 /* Zero extension. From size to dword.  */
1417 static unsigned int dec_subu_r(DisasContext *dc)
1418 {
1419         int size = memsize_z(dc);
1420         DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1421                     memsize_char(size),
1422                     dc->op1, dc->op2));
1423
1424         cris_cc_mask(dc, CC_MASK_NZVC);
1425         gen_movl_T0_reg[dc->op1]();
1426         /* Size can only be qi or hi.  */
1427         gen_zext_T1_T0(size);
1428         gen_movl_T0_reg[dc->op2]();
1429         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1430         return 2;
1431 }
1432
1433 /* Sign extension. From size to dword.  */
1434 static unsigned int dec_subs_r(DisasContext *dc)
1435 {
1436         int size = memsize_z(dc);
1437         DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1438                     memsize_char(size),
1439                     dc->op1, dc->op2));
1440
1441         cris_cc_mask(dc, CC_MASK_NZVC);
1442         gen_movl_T0_reg[dc->op1]();
1443         /* Size can only be qi or hi.  */
1444         gen_sext_T1_T0(size);
1445         gen_movl_T0_reg[dc->op2]();
1446         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1447         return 2;
1448 }
1449
1450 static unsigned int dec_setclrf(DisasContext *dc)
1451 {
1452         uint32_t flags;
1453         int set = (~dc->opcode >> 2) & 1;
1454
1455         flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1456                 | EXTRACT_FIELD(dc->ir, 0, 3);
1457         DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1458         if (set && flags == 0)
1459                 DIS(fprintf (logfile, "nop\n"));
1460         else if (!set && (flags & 0x20))
1461                 DIS(fprintf (logfile, "di\n"));
1462         else
1463                 DIS(fprintf (logfile, "%sf %x\n",
1464                             set ? "set" : "clr",
1465                             flags));
1466
1467         if (set && (flags & X_FLAG)) {
1468                 dc->flagx_live = 1;
1469                 dc->flags_x = 1;
1470         }
1471
1472         /* Simply decode the flags.  */
1473         cris_evaluate_flags (dc);
1474         cris_update_cc_op(dc, CC_OP_FLAGS);
1475         if (set)
1476                 gen_op_setf (flags);
1477         else
1478                 gen_op_clrf (flags);
1479         dc->flags_live = 1;
1480         return 2;
1481 }
1482
1483 static unsigned int dec_move_rs(DisasContext *dc)
1484 {
1485         DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1486         cris_cc_mask(dc, 0);
1487         gen_movl_T0_reg[dc->op1]();
1488         gen_op_movl_sreg_T0(dc->op2);
1489
1490         if (dc->op2 == 5) /* srs is checked at runtime.  */
1491                 gen_op_movl_tlb_lo_T0();
1492         return 2;
1493 }
1494 static unsigned int dec_move_sr(DisasContext *dc)
1495 {
1496         DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op1, dc->op2));
1497         cris_cc_mask(dc, 0);
1498         gen_op_movl_T0_sreg(dc->op1);
1499         gen_op_movl_T1_T0();
1500         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1501         return 2;
1502 }
1503 static unsigned int dec_move_rp(DisasContext *dc)
1504 {
1505         DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1506         cris_cc_mask(dc, 0);
1507         gen_movl_T0_reg[dc->op1]();
1508         gen_op_movl_T1_T0();
1509         gen_movl_preg_T0[dc->op2]();
1510         return 2;
1511 }
1512 static unsigned int dec_move_pr(DisasContext *dc)
1513 {
1514         DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1515         cris_cc_mask(dc, 0);
1516         /* Support register 0 is hardwired to zero. 
1517            Treat it specially. */
1518         if (dc->op2 == 0)
1519                 gen_op_movl_T1_im(0);
1520         else {
1521                 gen_movl_T0_preg[dc->op2]();
1522                 gen_op_movl_T1_T0();
1523         }
1524         crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1525         return 2;
1526 }
1527
1528 static unsigned int dec_move_mr(DisasContext *dc)
1529 {
1530         int memsize = memsize_zz(dc);
1531         int insn_len;
1532         DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1533                     memsize_char(memsize),
1534                     dc->op1, dc->postinc ? "+]" : "]",
1535                     dc->op2));
1536
1537         cris_cc_mask(dc, CC_MASK_NZ);
1538         insn_len = dec_prep_alu_m(dc, 0, memsize);
1539         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1540         do_postinc(dc, memsize);
1541         return insn_len;
1542 }
1543
1544 static unsigned int dec_movs_m(DisasContext *dc)
1545 {
1546         int memsize = memsize_z(dc);
1547         int insn_len;
1548         DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1549                     memsize_char(memsize),
1550                     dc->op1, dc->postinc ? "+]" : "]",
1551                     dc->op2));
1552
1553         /* sign extend.  */
1554         cris_cc_mask(dc, CC_MASK_NZ);
1555         insn_len = dec_prep_alu_m(dc, 1, memsize);
1556         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1557         do_postinc(dc, memsize);
1558         return insn_len;
1559 }
1560
1561 static unsigned int dec_addu_m(DisasContext *dc)
1562 {
1563         int memsize = memsize_z(dc);
1564         int insn_len;
1565         DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1566                     memsize_char(memsize),
1567                     dc->op1, dc->postinc ? "+]" : "]",
1568                     dc->op2));
1569
1570         /* sign extend.  */
1571         cris_cc_mask(dc, CC_MASK_NZVC);
1572         insn_len = dec_prep_alu_m(dc, 0, memsize);
1573         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1574         do_postinc(dc, memsize);
1575         return insn_len;
1576 }
1577
1578 static unsigned int dec_adds_m(DisasContext *dc)
1579 {
1580         int memsize = memsize_z(dc);
1581         int insn_len;
1582         DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1583                     memsize_char(memsize),
1584                     dc->op1, dc->postinc ? "+]" : "]",
1585                     dc->op2));
1586
1587         /* sign extend.  */
1588         cris_cc_mask(dc, CC_MASK_NZVC);
1589         insn_len = dec_prep_alu_m(dc, 1, memsize);
1590         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1591         do_postinc(dc, memsize);
1592         return insn_len;
1593 }
1594
1595 static unsigned int dec_subu_m(DisasContext *dc)
1596 {
1597         int memsize = memsize_z(dc);
1598         int insn_len;
1599         DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1600                     memsize_char(memsize),
1601                     dc->op1, dc->postinc ? "+]" : "]",
1602                     dc->op2));
1603
1604         /* sign extend.  */
1605         cris_cc_mask(dc, CC_MASK_NZVC);
1606         insn_len = dec_prep_alu_m(dc, 0, memsize);
1607         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1608         do_postinc(dc, memsize);
1609         return insn_len;
1610 }
1611
1612 static unsigned int dec_subs_m(DisasContext *dc)
1613 {
1614         int memsize = memsize_z(dc);
1615         int insn_len;
1616         DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1617                     memsize_char(memsize),
1618                     dc->op1, dc->postinc ? "+]" : "]",
1619                     dc->op2));
1620
1621         /* sign extend.  */
1622         cris_cc_mask(dc, CC_MASK_NZVC);
1623         insn_len = dec_prep_alu_m(dc, 1, memsize);
1624         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1625         do_postinc(dc, memsize);
1626         return insn_len;
1627 }
1628
1629 static unsigned int dec_movu_m(DisasContext *dc)
1630 {
1631         int memsize = memsize_z(dc);
1632         int insn_len;
1633
1634         DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1635                     memsize_char(memsize),
1636                     dc->op1, dc->postinc ? "+]" : "]",
1637                     dc->op2));
1638
1639         cris_cc_mask(dc, CC_MASK_NZ);
1640         insn_len = dec_prep_alu_m(dc, 0, memsize);
1641         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1642         do_postinc(dc, memsize);
1643         return insn_len;
1644 }
1645
1646 static unsigned int dec_cmpu_m(DisasContext *dc)
1647 {
1648         int memsize = memsize_z(dc);
1649         int insn_len;
1650         DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1651                     memsize_char(memsize),
1652                     dc->op1, dc->postinc ? "+]" : "]",
1653                     dc->op2));
1654
1655         cris_cc_mask(dc, CC_MASK_NZVC);
1656         insn_len = dec_prep_alu_m(dc, 0, memsize);
1657         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1658         do_postinc(dc, memsize);
1659         return insn_len;
1660 }
1661
1662 static unsigned int dec_cmps_m(DisasContext *dc)
1663 {
1664         int memsize = memsize_z(dc);
1665         int insn_len;
1666         DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1667                     memsize_char(memsize),
1668                     dc->op1, dc->postinc ? "+]" : "]",
1669                     dc->op2));
1670
1671         cris_cc_mask(dc, CC_MASK_NZVC);
1672         insn_len = dec_prep_alu_m(dc, 1, memsize);
1673         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1674         do_postinc(dc, memsize);
1675         return insn_len;
1676 }
1677
1678 static unsigned int dec_cmp_m(DisasContext *dc)
1679 {
1680         int memsize = memsize_zz(dc);
1681         int insn_len;
1682         DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1683                     memsize_char(memsize),
1684                     dc->op1, dc->postinc ? "+]" : "]",
1685                     dc->op2));
1686
1687         cris_cc_mask(dc, CC_MASK_NZVC);
1688         insn_len = dec_prep_alu_m(dc, 0, memsize);
1689         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1690         do_postinc(dc, memsize);
1691         return insn_len;
1692 }
1693
1694 static unsigned int dec_test_m(DisasContext *dc)
1695 {
1696         int memsize = memsize_zz(dc);
1697         int insn_len;
1698         DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1699                     memsize_char(memsize),
1700                     dc->op1, dc->postinc ? "+]" : "]",
1701                     dc->op2));
1702
1703         cris_cc_mask(dc, CC_MASK_NZ);
1704         gen_op_clrf(3);
1705         insn_len = dec_prep_alu_m(dc, 0, memsize);
1706         gen_op_swp_T0_T1();
1707         gen_op_movl_T1_im(0);
1708         crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1709         do_postinc(dc, memsize);
1710         return insn_len;
1711 }
1712
1713 static unsigned int dec_and_m(DisasContext *dc)
1714 {
1715         int memsize = memsize_zz(dc);
1716         int insn_len;
1717         DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1718                     memsize_char(memsize),
1719                     dc->op1, dc->postinc ? "+]" : "]",
1720                     dc->op2));
1721
1722         cris_cc_mask(dc, CC_MASK_NZ);
1723         insn_len = dec_prep_alu_m(dc, 0, memsize);
1724         crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1725         do_postinc(dc, memsize);
1726         return insn_len;
1727 }
1728
1729 static unsigned int dec_add_m(DisasContext *dc)
1730 {
1731         int memsize = memsize_zz(dc);
1732         int insn_len;
1733         DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1734                     memsize_char(memsize),
1735                     dc->op1, dc->postinc ? "+]" : "]",
1736                     dc->op2));
1737
1738         cris_cc_mask(dc, CC_MASK_NZVC);
1739         insn_len = dec_prep_alu_m(dc, 0, memsize);
1740         crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1741         do_postinc(dc, memsize);
1742         return insn_len;
1743 }
1744
1745 static unsigned int dec_addo_m(DisasContext *dc)
1746 {
1747         int memsize = memsize_zz(dc);
1748         int insn_len;
1749         DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1750                     memsize_char(memsize),
1751                     dc->op1, dc->postinc ? "+]" : "]",
1752                     dc->op2));
1753
1754         cris_cc_mask(dc, 0);
1755         insn_len = dec_prep_alu_m(dc, 1, memsize);
1756         crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
1757         do_postinc(dc, memsize);
1758         return insn_len;
1759 }
1760
1761 static unsigned int dec_bound_m(DisasContext *dc)
1762 {
1763         int memsize = memsize_zz(dc);
1764         int insn_len;
1765         DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1766                     memsize_char(memsize),
1767                     dc->op1, dc->postinc ? "+]" : "]",
1768                     dc->op2));
1769
1770         cris_cc_mask(dc, CC_MASK_NZ);
1771         insn_len = dec_prep_alu_m(dc, 0, memsize);
1772         crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1773         do_postinc(dc, memsize);
1774         return insn_len;
1775 }
1776
1777 static unsigned int dec_addc_mr(DisasContext *dc)
1778 {
1779         int insn_len = 2;
1780         DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1781                     dc->op1, dc->postinc ? "+]" : "]",
1782                     dc->op2));
1783
1784         cris_evaluate_flags(dc);
1785         cris_cc_mask(dc, CC_MASK_NZVC);
1786         insn_len = dec_prep_alu_m(dc, 0, 4);
1787         crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1788         do_postinc(dc, 4);
1789         return insn_len;
1790 }
1791
1792 static unsigned int dec_sub_m(DisasContext *dc)
1793 {
1794         int memsize = memsize_zz(dc);
1795         int insn_len;
1796         DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1797                     memsize_char(memsize),
1798                     dc->op1, dc->postinc ? "+]" : "]",
1799                     dc->op2, dc->ir, dc->zzsize));
1800
1801         cris_cc_mask(dc, CC_MASK_NZVC);
1802         insn_len = dec_prep_alu_m(dc, 0, memsize);
1803         crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1804         do_postinc(dc, memsize);
1805         return insn_len;
1806 }
1807
1808 static unsigned int dec_or_m(DisasContext *dc)
1809 {
1810         int memsize = memsize_zz(dc);
1811         int insn_len;
1812         DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1813                     memsize_char(memsize),
1814                     dc->op1, dc->postinc ? "+]" : "]",
1815                     dc->op2, dc->pc));
1816
1817         cris_cc_mask(dc, CC_MASK_NZ);
1818         insn_len = dec_prep_alu_m(dc, 0, memsize);
1819         crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1820         do_postinc(dc, memsize);
1821         return insn_len;
1822 }
1823
1824 static unsigned int dec_move_mp(DisasContext *dc)
1825 {
1826         int memsize = memsize_zz(dc);
1827         int insn_len = 2;
1828
1829         DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1830                     memsize_char(memsize),
1831                     dc->op1,
1832                     dc->postinc ? "+]" : "]",
1833                     dc->op2));
1834
1835         cris_cc_mask(dc, 0);
1836         insn_len = dec_prep_alu_m(dc, 0, memsize);
1837         gen_op_movl_T0_T1();
1838         gen_movl_preg_T0[dc->op2]();
1839
1840         do_postinc(dc, memsize);
1841         return insn_len;
1842 }
1843
1844 static unsigned int dec_move_pm(DisasContext *dc)
1845 {
1846         int memsize;
1847
1848         memsize = preg_sizes[dc->op2];
1849
1850         DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
1851                      memsize_char(memsize), 
1852                      dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
1853
1854         cris_cc_mask(dc, 0);
1855         /* prepare store. Address in T0, value in T1.  */
1856         /* Support register 0 is hardwired to zero. 
1857            Treat it specially. */
1858         if (dc->op2 == 0)
1859                 gen_op_movl_T1_im(0);
1860         else
1861         {
1862                 gen_movl_T0_preg[dc->op2]();
1863                 gen_op_movl_T1_T0();
1864         }
1865         gen_movl_T0_reg[dc->op1]();
1866         gen_store_T0_T1(dc, memsize);
1867         if (dc->postinc)
1868         {
1869                 gen_op_addl_T0_im(memsize);
1870                 gen_movl_reg_T0[dc->op1]();
1871         }
1872         return 2;
1873 }
1874
1875 static unsigned int dec_movem_mr(DisasContext *dc)
1876 {
1877         int i;
1878
1879         DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
1880                     dc->postinc ? "+]" : "]", dc->op2));
1881
1882         cris_cc_mask(dc, 0);
1883         /* fetch the address into T1.  */
1884         gen_movl_T0_reg[dc->op1]();
1885         gen_op_movl_T1_T0();
1886         for (i = 0; i <= dc->op2; i++) {
1887                 /* Perform the load onto regnum i. Always dword wide.  */
1888                 gen_load_T0_T0(dc, 4, 0);
1889                 gen_movl_reg_T0[i]();
1890                 /* Update the address.  */
1891                 gen_op_addl_T1_im(4);
1892                 gen_op_movl_T0_T1();
1893         }
1894         if (dc->postinc) {
1895                 /* writeback the updated pointer value.  */
1896                 gen_movl_reg_T0[dc->op1]();
1897         }
1898         return 2;
1899 }
1900
1901 static unsigned int dec_movem_rm(DisasContext *dc)
1902 {
1903         int i;
1904
1905         DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
1906                      dc->postinc ? "+]" : "]"));
1907
1908         cris_cc_mask(dc, 0);
1909         for (i = 0; i <= dc->op2; i++) {
1910                 /* Fetch register i into T1.  */
1911                 gen_movl_T0_reg[i]();
1912                 gen_op_movl_T1_T0();
1913
1914                 /* Fetch the address into T0.  */
1915                 gen_movl_T0_reg[dc->op1]();
1916                 /* Displace it.  */
1917                 gen_op_addl_T0_im(i * 4);
1918
1919                 /* Perform the store.  */
1920                 gen_store_T0_T1(dc, 4);
1921         }
1922         if (dc->postinc) {
1923                 /* Update the address.  */
1924                 gen_op_addl_T0_im(4);
1925                 /* writeback the updated pointer value.  */
1926                 gen_movl_reg_T0[dc->op1]();
1927         }
1928         return 2;
1929 }
1930
1931 static unsigned int dec_move_rm(DisasContext *dc)
1932 {
1933         int memsize;
1934
1935         memsize = memsize_zz(dc);
1936
1937         DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
1938                      memsize, dc->op2, dc->op1));
1939
1940         cris_cc_mask(dc, 0);
1941         /* prepare store.  */
1942         gen_movl_T0_reg[dc->op2]();
1943         gen_op_movl_T1_T0();
1944         gen_movl_T0_reg[dc->op1]();
1945         gen_store_T0_T1(dc, memsize);
1946         if (dc->postinc)
1947         {
1948                 gen_op_addl_T0_im(memsize);
1949                 gen_movl_reg_T0[dc->op1]();
1950         }
1951         return 2;
1952 }
1953
1954
1955 static unsigned int dec_lapcq(DisasContext *dc)
1956 {
1957         DIS(fprintf (logfile, "lapcq %x, $r%u\n",
1958                     dc->pc + dc->op1*2, dc->op2));
1959         cris_cc_mask(dc, 0);
1960         gen_op_movl_T1_im(dc->pc + dc->op1*2);
1961         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1962         return 2;
1963 }
1964
1965 static unsigned int dec_lapc_im(DisasContext *dc)
1966 {
1967         unsigned int rd;
1968         int32_t imm;
1969         int insn_len = 6;
1970
1971         rd = dc->op2;
1972
1973         cris_cc_mask(dc, 0);
1974         imm = ldl_code(dc->pc + 2);
1975         DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
1976         gen_op_movl_T0_im (dc->pc + imm);
1977         gen_movl_reg_T0[rd] ();
1978         return insn_len;
1979 }
1980
1981 /* Jump to special reg.  */
1982 static unsigned int dec_jump_p(DisasContext *dc)
1983 {
1984         DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
1985         cris_cc_mask(dc, 0);
1986         /* Store the return address in Pd.  */
1987         gen_movl_T0_preg[dc->op2]();
1988         gen_op_movl_btarget_T0();
1989         cris_prepare_dyn_jmp(dc);
1990         return 2;
1991 }
1992
1993 /* Jump and save.  */
1994 static unsigned int dec_jas_r(DisasContext *dc)
1995 {
1996         DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
1997         cris_cc_mask(dc, 0);
1998         /* Stor the return address in Pd.  */
1999         gen_movl_T0_reg[dc->op1]();
2000         gen_op_movl_btarget_T0();
2001         gen_op_movl_T0_im(dc->pc + 4);
2002         gen_movl_preg_T0[dc->op2]();
2003         cris_prepare_dyn_jmp(dc);
2004         return 2;
2005 }
2006
2007 static unsigned int dec_jas_im(DisasContext *dc)
2008 {
2009         uint32_t imm;
2010
2011         imm = ldl_code(dc->pc + 2);
2012
2013         DIS(fprintf (logfile, "jas 0x%x\n", imm));
2014         cris_cc_mask(dc, 0);
2015         /* Stor the return address in Pd.  */
2016         gen_op_movl_T0_im(imm);
2017         gen_op_movl_btarget_T0();
2018         gen_op_movl_T0_im(dc->pc + 8);
2019         gen_movl_preg_T0[dc->op2]();
2020         cris_prepare_dyn_jmp(dc);
2021         return 6;
2022 }
2023
2024 static unsigned int dec_jasc_im(DisasContext *dc)
2025 {
2026         uint32_t imm;
2027
2028         imm = ldl_code(dc->pc + 2);
2029
2030         DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2031         cris_cc_mask(dc, 0);
2032         /* Stor the return address in Pd.  */
2033         gen_op_movl_T0_im(imm);
2034         gen_op_movl_btarget_T0();
2035         gen_op_movl_T0_im(dc->pc + 8 + 4);
2036         gen_movl_preg_T0[dc->op2]();
2037         cris_prepare_dyn_jmp(dc);
2038         return 6;
2039 }
2040
2041 static unsigned int dec_jasc_r(DisasContext *dc)
2042 {
2043         DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2044         cris_cc_mask(dc, 0);
2045         /* Stor the return address in Pd.  */
2046         gen_movl_T0_reg[dc->op1]();
2047         gen_op_movl_btarget_T0();
2048         gen_op_movl_T0_im(dc->pc + 4 + 4);
2049         gen_movl_preg_T0[dc->op2]();
2050         cris_prepare_dyn_jmp(dc);
2051         return 2;
2052 }
2053
2054 static unsigned int dec_bcc_im(DisasContext *dc)
2055 {
2056         int32_t offset;
2057         uint32_t cond = dc->op2;
2058
2059         offset = ldl_code(dc->pc + 2);
2060         offset = sign_extend(offset, 15);
2061
2062         DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2063                     cc_name(cond), offset,
2064                     dc->pc, dc->pc + offset));
2065
2066         cris_cc_mask(dc, 0);
2067         /* op2 holds the condition-code.  */
2068         cris_prepare_cc_branch (dc, offset, cond);
2069         return 4;
2070 }
2071
2072 static unsigned int dec_bas_im(DisasContext *dc)
2073 {
2074         int32_t simm;
2075
2076
2077         simm = ldl_code(dc->pc + 2);
2078
2079         DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2080         cris_cc_mask(dc, 0);
2081         /* Stor the return address in Pd.  */
2082         gen_op_movl_T0_im(dc->pc + simm);
2083         gen_op_movl_btarget_T0();
2084         gen_op_movl_T0_im(dc->pc + 8);
2085         gen_movl_preg_T0[dc->op2]();
2086         cris_prepare_dyn_jmp(dc);
2087         return 6;
2088 }
2089
2090 static unsigned int dec_basc_im(DisasContext *dc)
2091 {
2092         int32_t simm;
2093         simm = ldl_code(dc->pc + 2);
2094
2095         DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2096         cris_cc_mask(dc, 0);
2097         /* Stor the return address in Pd.  */
2098         gen_op_movl_T0_im(dc->pc + simm);
2099         gen_op_movl_btarget_T0();
2100         gen_op_movl_T0_im(dc->pc + 12);
2101         gen_movl_preg_T0[dc->op2]();
2102         cris_prepare_dyn_jmp(dc);
2103         return 6;
2104 }
2105
2106 static unsigned int dec_rfe_etc(DisasContext *dc)
2107 {
2108         DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2109                     dc->opcode, dc->pc, dc->op1, dc->op2));
2110
2111         cris_cc_mask(dc, 0);
2112
2113         if (dc->op2 == 15) /* ignore halt.  */
2114                 goto done;
2115
2116         switch (dc->op2 & 7) {
2117                 case 2:
2118                         /* rfe.  */
2119                         cris_evaluate_flags(dc);
2120                         gen_op_ccs_rshift();
2121                         break;
2122                 case 5:
2123                         /* rfn.  */
2124                         BUG();
2125                         break;
2126                 case 6:
2127                         /* break.  */
2128                         gen_op_movl_T0_im(dc->pc);
2129                         gen_op_movl_pc_T0();
2130                         /* Breaks start at 16 in the exception vector.  */
2131                         gen_op_break_im(dc->op1 + 16);
2132                         break;
2133                 default:
2134                         printf ("op2=%x\n", dc->op2);
2135                         BUG();
2136                         break;
2137
2138         }
2139   done:
2140         return 2;
2141 }
2142
2143 static unsigned int dec_null(DisasContext *dc)
2144 {
2145         printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2146                 dc->pc, dc->opcode, dc->op1, dc->op2);
2147         fflush(NULL);
2148         BUG();
2149         return 2;
2150 }
2151
2152 struct decoder_info {
2153         struct {
2154                 uint32_t bits;
2155                 uint32_t mask;
2156         };
2157         unsigned int (*dec)(DisasContext *dc);
2158 } decinfo[] = {
2159         /* Order matters here.  */
2160         {DEC_MOVEQ, dec_moveq},
2161         {DEC_BTSTQ, dec_btstq},
2162         {DEC_CMPQ, dec_cmpq},
2163         {DEC_ADDOQ, dec_addoq},
2164         {DEC_ADDQ, dec_addq},
2165         {DEC_SUBQ, dec_subq},
2166         {DEC_ANDQ, dec_andq},
2167         {DEC_ORQ, dec_orq},
2168         {DEC_ASRQ, dec_asrq},
2169         {DEC_LSLQ, dec_lslq},
2170         {DEC_LSRQ, dec_lsrq},
2171         {DEC_BCCQ, dec_bccq},
2172
2173         {DEC_BCC_IM, dec_bcc_im},
2174         {DEC_JAS_IM, dec_jas_im},
2175         {DEC_JAS_R, dec_jas_r},
2176         {DEC_JASC_IM, dec_jasc_im},
2177         {DEC_JASC_R, dec_jasc_r},
2178         {DEC_BAS_IM, dec_bas_im},
2179         {DEC_BASC_IM, dec_basc_im},
2180         {DEC_JUMP_P, dec_jump_p},
2181         {DEC_LAPC_IM, dec_lapc_im},
2182         {DEC_LAPCQ, dec_lapcq},
2183
2184         {DEC_RFE_ETC, dec_rfe_etc},
2185         {DEC_ADDC_MR, dec_addc_mr},
2186
2187         {DEC_MOVE_MP, dec_move_mp},
2188         {DEC_MOVE_PM, dec_move_pm},
2189         {DEC_MOVEM_MR, dec_movem_mr},
2190         {DEC_MOVEM_RM, dec_movem_rm},
2191         {DEC_MOVE_PR, dec_move_pr},
2192         {DEC_SCC_R, dec_scc_r},
2193         {DEC_SETF, dec_setclrf},
2194         {DEC_CLEARF, dec_setclrf},
2195
2196         {DEC_MOVE_SR, dec_move_sr},
2197         {DEC_MOVE_RP, dec_move_rp},
2198         {DEC_SWAP_R, dec_swap_r},
2199         {DEC_ABS_R, dec_abs_r},
2200         {DEC_LZ_R, dec_lz_r},
2201         {DEC_MOVE_RS, dec_move_rs},
2202         {DEC_BTST_R, dec_btst_r},
2203         {DEC_ADDC_R, dec_addc_r},
2204
2205         {DEC_DSTEP_R, dec_dstep_r},
2206         {DEC_XOR_R, dec_xor_r},
2207         {DEC_MCP_R, dec_mcp_r},
2208         {DEC_CMP_R, dec_cmp_r},
2209
2210         {DEC_ADDI_R, dec_addi_r},
2211         {DEC_ADDI_ACR, dec_addi_acr},
2212
2213         {DEC_ADD_R, dec_add_r},
2214         {DEC_SUB_R, dec_sub_r},
2215
2216         {DEC_ADDU_R, dec_addu_r},
2217         {DEC_ADDS_R, dec_adds_r},
2218         {DEC_SUBU_R, dec_subu_r},
2219         {DEC_SUBS_R, dec_subs_r},
2220         {DEC_LSL_R, dec_lsl_r},
2221
2222         {DEC_AND_R, dec_and_r},
2223         {DEC_OR_R, dec_or_r},
2224         {DEC_BOUND_R, dec_bound_r},
2225         {DEC_ASR_R, dec_asr_r},
2226         {DEC_LSR_R, dec_lsr_r},
2227
2228         {DEC_MOVU_R, dec_movu_r},
2229         {DEC_MOVS_R, dec_movs_r},
2230         {DEC_NEG_R, dec_neg_r},
2231         {DEC_MOVE_R, dec_move_r},
2232
2233         /* ftag_fidx_i_m.  */
2234         /* ftag_fidx_d_m.  */
2235
2236         {DEC_MULS_R, dec_muls_r},
2237         {DEC_MULU_R, dec_mulu_r},
2238
2239         {DEC_ADDU_M, dec_addu_m},
2240         {DEC_ADDS_M, dec_adds_m},
2241         {DEC_SUBU_M, dec_subu_m},
2242         {DEC_SUBS_M, dec_subs_m},
2243
2244         {DEC_CMPU_M, dec_cmpu_m},
2245         {DEC_CMPS_M, dec_cmps_m},
2246         {DEC_MOVU_M, dec_movu_m},
2247         {DEC_MOVS_M, dec_movs_m},
2248
2249         {DEC_CMP_M, dec_cmp_m},
2250         {DEC_ADDO_M, dec_addo_m},
2251         {DEC_BOUND_M, dec_bound_m},
2252         {DEC_ADD_M, dec_add_m},
2253         {DEC_SUB_M, dec_sub_m},
2254         {DEC_AND_M, dec_and_m},
2255         {DEC_OR_M, dec_or_m},
2256         {DEC_MOVE_RM, dec_move_rm},
2257         {DEC_TEST_M, dec_test_m},
2258         {DEC_MOVE_MR, dec_move_mr},
2259
2260         {{0, 0}, dec_null}
2261 };
2262
2263 static inline unsigned int
2264 cris_decoder(DisasContext *dc)
2265 {
2266         unsigned int insn_len = 2;
2267         uint32_t tmp;
2268         int i;
2269
2270         /* Load a halfword onto the instruction register.  */
2271         tmp = ldl_code(dc->pc);
2272         dc->ir = tmp & 0xffff;
2273
2274         /* Now decode it.  */
2275         dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2276         dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2277         dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2278         dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2279         dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2280         dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2281
2282         /* Large switch for all insns.  */
2283         for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2284                 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2285                 {
2286                         insn_len = decinfo[i].dec(dc);
2287                         break;
2288                 }
2289         }
2290
2291         return insn_len;
2292 }
2293
2294 static void check_breakpoint(CPUState *env, DisasContext *dc)
2295 {
2296         int j;
2297         if (env->nb_breakpoints > 0) {
2298                 for(j = 0; j < env->nb_breakpoints; j++) {
2299                         if (env->breakpoints[j] == dc->pc) {
2300                                 cris_evaluate_flags (dc);
2301                                 gen_op_movl_T0_im((long)dc->pc);
2302                                 gen_op_movl_pc_T0();
2303                                 gen_op_debug();
2304                                 dc->is_jmp = DISAS_UPDATE;
2305                         }
2306                 }
2307         }
2308 }
2309
2310
2311 /* generate intermediate code for basic block 'tb'.  */
2312 struct DisasContext ctx;
2313 static int
2314 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2315                                int search_pc)
2316 {
2317         uint16_t *gen_opc_end;
2318         uint32_t pc_start;
2319         unsigned int insn_len;
2320         int j, lj;
2321         struct DisasContext *dc = &ctx;
2322         uint32_t next_page_start;
2323
2324         pc_start = tb->pc;
2325         dc->env = env;
2326         dc->tb = tb;
2327
2328         gen_opc_ptr = gen_opc_buf;
2329         gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2330         gen_opparam_ptr = gen_opparam_buf;
2331
2332         dc->is_jmp = DISAS_NEXT;
2333         dc->pc = pc_start;
2334         dc->singlestep_enabled = env->singlestep_enabled;
2335         dc->flagx_live = 0;
2336         dc->flags_x = 0;
2337         next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2338         lj = -1;
2339         do
2340         {
2341                 check_breakpoint(env, dc);
2342                 if (dc->is_jmp == DISAS_JUMP)
2343                         goto done;
2344
2345                 if (search_pc) {
2346                         j = gen_opc_ptr - gen_opc_buf;
2347                         if (lj < j) {
2348                                 lj++;
2349                                 while (lj < j)
2350                                         gen_opc_instr_start[lj++] = 0;
2351                         }
2352                         gen_opc_pc[lj] = dc->pc;
2353                         gen_opc_instr_start[lj] = 1;
2354                 }
2355
2356                 insn_len = cris_decoder(dc);
2357                 STATS(gen_op_exec_insn());
2358                 dc->pc += insn_len;
2359                 if (!dc->flagx_live
2360                     || (dc->flagx_live &&
2361                         !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
2362                         gen_movl_T0_preg[SR_CCS]();
2363                         gen_op_andl_T0_im(~X_FLAG);
2364                         gen_movl_preg_T0[SR_CCS]();
2365                         dc->flagx_live = 1;
2366                         dc->flags_x = 0;
2367                 }
2368
2369                 /* Check for delayed branches here. If we do it before
2370                    actually genereating any host code, the simulator will just
2371                    loop doing nothing for on this program location.  */
2372                 if (dc->delayed_branch) {
2373                         dc->delayed_branch--;
2374                         if (dc->delayed_branch == 0)
2375                         {
2376                                 if (dc->bcc == CC_A) {
2377                                         gen_op_jmp ();
2378                                         dc->is_jmp = DISAS_UPDATE;
2379                                 }
2380                                 else {
2381                                         /* Conditional jmp.  */
2382                                         gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2383                                         dc->is_jmp = DISAS_UPDATE;
2384                                 }
2385                         }
2386                 }
2387
2388                 if (env->singlestep_enabled)
2389                         break;
2390         } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2391                  && dc->pc < next_page_start);
2392
2393         if (!dc->is_jmp) {
2394                 gen_op_movl_T0_im((long)dc->pc);
2395                 gen_op_movl_pc_T0();
2396         }
2397
2398         cris_evaluate_flags (dc);
2399   done:
2400         if (__builtin_expect(env->singlestep_enabled, 0)) {
2401                 gen_op_debug();
2402         } else {
2403                 switch(dc->is_jmp) {
2404                         case DISAS_NEXT:
2405                                 gen_goto_tb(dc, 1, dc->pc);
2406                                 break;
2407                         default:
2408                         case DISAS_JUMP:
2409                         case DISAS_UPDATE:
2410                                 /* indicate that the hash table must be used
2411                                    to find the next TB */
2412                                 /* T0 is used to index the jmp tables.  */
2413                                 gen_op_movl_T0_0();
2414                                 gen_op_exit_tb();
2415                                 break;
2416                         case DISAS_TB_JUMP:
2417                                 /* nothing more to generate */
2418                                 break;
2419                 }
2420         }
2421         *gen_opc_ptr = INDEX_op_end;
2422         if (search_pc) {
2423                 j = gen_opc_ptr - gen_opc_buf;
2424                 lj++;
2425                 while (lj <= j)
2426                         gen_opc_instr_start[lj++] = 0;
2427         } else {
2428                 tb->size = dc->pc - pc_start;
2429         }
2430
2431 #ifdef DEBUG_DISAS
2432         if (loglevel & CPU_LOG_TB_IN_ASM) {
2433                 fprintf(logfile, "--------------\n");
2434                 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2435                 target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2436                 fprintf(logfile, "\n");
2437                 if (loglevel & CPU_LOG_TB_OP) {
2438                         fprintf(logfile, "OP:\n");
2439                         dump_ops(gen_opc_buf, gen_opparam_buf);
2440                         fprintf(logfile, "\n");
2441                 }
2442         }
2443 #endif
2444         return 0;
2445 }
2446
2447 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2448 {
2449     return gen_intermediate_code_internal(env, tb, 0);
2450 }
2451
2452 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2453 {
2454     return gen_intermediate_code_internal(env, tb, 1);
2455 }
2456
2457 void cpu_dump_state (CPUState *env, FILE *f,
2458                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2459                      int flags)
2460 {
2461         int i;
2462         uint32_t srs;
2463
2464         if (!env || !f)
2465                 return;
2466
2467         cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2468                     "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2469                     "debug=%x %x %x\n",
2470                     env->pc, env->pregs[SR_CCS], env->btaken, env->btarget,
2471                     env->cc_op,
2472                     env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2473                     env->debug1, env->debug2, env->debug3);
2474
2475         for (i = 0; i < 16; i++) {
2476                 cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2477                 if ((i + 1) % 4 == 0)
2478                         cpu_fprintf(f, "\n");
2479         }
2480         cpu_fprintf(f, "\nspecial regs:\n");
2481         for (i = 0; i < 16; i++) {
2482                 cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2483                 if ((i + 1) % 4 == 0)
2484                         cpu_fprintf(f, "\n");
2485         }
2486         srs = env->pregs[SR_SRS];
2487         cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2488         if (srs < 256) {
2489                 for (i = 0; i < 16; i++) {
2490                         cpu_fprintf(f, "s%2.2d=%8.8x ",
2491                                     i, env->sregs[srs][i]);
2492                         if ((i + 1) % 4 == 0)
2493                                 cpu_fprintf(f, "\n");
2494                 }
2495         }
2496         cpu_fprintf(f, "\n\n");
2497
2498 }
2499
2500 CPUCRISState *cpu_cris_init (const char *cpu_model)
2501 {
2502         CPUCRISState *env;
2503
2504         env = qemu_mallocz(sizeof(CPUCRISState));
2505         if (!env)
2506                 return NULL;
2507         cpu_exec_init(env);
2508         cpu_reset(env);
2509         return env;
2510 }
2511
2512 void cpu_reset (CPUCRISState *env)
2513 {
2514         memset(env, 0, offsetof(CPUCRISState, breakpoints));
2515         tlb_flush(env, 1);
2516 }