added cpu_model parameter to cpu_init()
[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
114         struct
115         {
116                 int op;
117                 int size;
118                 unsigned int mask;
119         } cc_state[3];
120         int cc_i;
121
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;
130
131         int memidx; /* user or kernel mode.  */
132         int is_jmp;
133         int dyn_jmp;
134
135         uint32_t delayed_pc;
136         int delayed_branch;
137         int bcc;
138         uint32_t condlabel;
139
140         struct TranslationBlock *tb;
141         int singlestep_enabled;
142 } DisasContext;
143
144 void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
145 static void gen_BUG(DisasContext *dc, char *file, int line)
146 {
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);
152 }
153
154 /* Table to generate quick moves from T0 onto any register.  */
155 static GenOpFunc *gen_movl_reg_T0[16] =
156 {
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,
165 };
166 static GenOpFunc *gen_movl_T0_reg[16] =
167 {
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,
176 };
177
178 static void noop_write(void) {
179         /* nop.  */
180 }
181
182 static void gen_vr_read(void) {
183         gen_op_movl_T0_im(32);
184 }
185
186 static void gen_ccs_read(void) {
187         gen_op_movl_T0_p13();
188 }
189
190 static void gen_ccs_write(void) {
191         gen_op_movl_p13_T0();
192 }
193
194 /* Table to generate quick moves from T0 onto any register.  */
195 static GenOpFunc *gen_movl_preg_T0[16] =
196 {
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,
209 };
210 static GenOpFunc *gen_movl_T0_preg[16] =
211 {
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,
222 };
223
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,
234 };
235
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(); \
240   }
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(); \
244   }
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();\
250   }
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();\
255   }
256 #endif
257
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)
266
267 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
268 {
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();
279         }
280         gen_op_exit_tb();
281 }
282
283 /* Sign extend at translation time.  */
284 static int sign_extend(unsigned int val, unsigned int width)
285 {
286         int sval;
287
288         /* LSL.  */
289         val <<= 31 - width;
290         sval = val;
291         /* ASR.  */
292         sval >>= 31 - width;
293         return sval;
294 }
295
296 static void cris_evaluate_flags(DisasContext *dc)
297 {
298         if (!dc->flags_live) {
299
300                 switch (dc->cc_op)
301                 {
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)
313                                 {
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;
323                                 }
324                                 break;
325
326                         default:
327                         {
328                                 switch (dc->cc_size)
329                                 {
330                                         case 4:
331                                                 gen_op_evaluate_flags_alu_4 ();
332                                                 break;
333                                         default:
334                                                 gen_op_evaluate_flags ();
335                                                 break;
336                                 }
337                         }
338                         break;
339                 }
340                 dc->flags_live = 1;
341         }
342 }
343
344 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
345 {
346         uint32_t ovl;
347
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);
352         }
353         dc->cc_mask = mask;
354
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;
361         }
362 }
363
364 static void cris_update_cc_op(DisasContext *dc, int op)
365 {
366         dc->cc_op = op;
367         gen_op_update_cc_op(op);
368         dc->flags_live = 0;
369 }
370 static void cris_update_cc_size(DisasContext *dc, int size)
371 {
372         dc->cc_size = size;
373         gen_op_update_cc_size_im(size);
374 }
375
376 /* op is the operation.
377    T0, T1 are the operands.
378    dst is the destination reg.
379 */
380 static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
381 {
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();
388         }
389
390         /* Emit the ALU insns.  */
391         switch (op)
392         {
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();
415
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();
473
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;
482         }
483
484         if (dc->update_cc)
485                 gen_op_update_cc_src_T1();
486
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();
505                 }
506         }
507         if (dc->update_cc)
508                 gen_op_update_cc_result_T0();
509
510         {
511                 /* TODO: Optimize this.  */
512                 if (!dc->flagx_live)
513                         cris_evaluate_flags(dc);
514         }
515 }
516
517 static int arith_cc(DisasContext *dc)
518 {
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;
529                 }
530         }
531         return 0;
532 }
533
534 static void gen_tst_cc (DisasContext *dc, int cond)
535 {
536         int arith_opt;
537
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 ();
547                         }
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 ();
555                         }
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 ();
579                         }
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 ();
587                         }
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;
624         };
625 }
626
627 static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
628 {
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)
635         {
636                 gen_tst_cc (dc, cond);
637                 gen_op_evaluate_bcc ();
638         }
639         gen_op_movl_T0_im (dc->delayed_pc);
640         gen_op_movl_btarget_T0 ();
641 }
642
643 /* Dynamic jumps, when the dest is in a live reg for example.  */
644 void cris_prepare_dyn_jmp (DisasContext *dc)
645 {
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;
651 }
652
653 void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
654 {
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;
661 }
662
663 void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
664 {
665         if (size == 1) {
666                 if (sign)
667                         gen_op_ldb_T0_T0(dc);
668                 else
669                         gen_op_ldub_T0_T0(dc);
670         }
671         else if (size == 2) {
672                 if (sign)
673                         gen_op_ldw_T0_T0(dc);
674                 else
675                         gen_op_lduw_T0_T0(dc);
676         }
677         else {
678                 gen_op_ldl_T0_T0(dc);
679         }
680 }
681
682 void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
683 {
684         /* Remember, operands are flipped. CRIS has reversed order.  */
685         if (size == 1) {
686                 gen_op_stb_T0_T1(dc);
687         }
688         else if (size == 2) {
689                 gen_op_stw_T0_T1(dc);
690         }
691         else
692                 gen_op_stl_T0_T1(dc);
693 }
694
695 /* sign extend T1 according to size.  */
696 static void gen_sext_T1_T0(int size)
697 {
698         if (size == 1)
699                 gen_op_extb_T1_T0();
700         else if (size == 2)
701                 gen_op_extw_T1_T0();
702 }
703
704 static void gen_sext_T1_T1(int size)
705 {
706         if (size == 1)
707                 gen_op_extb_T1_T1();
708         else if (size == 2)
709                 gen_op_extw_T1_T1();
710 }
711
712 static void gen_sext_T0_T0(int size)
713 {
714         if (size == 1)
715                 gen_op_extb_T0_T0();
716         else if (size == 2)
717                 gen_op_extw_T0_T0();
718 }
719
720 static void gen_zext_T0_T0(int size)
721 {
722         if (size == 1)
723                 gen_op_zextb_T0_T0();
724         else if (size == 2)
725                 gen_op_zextw_T0_T0();
726 }
727
728 static void gen_zext_T1_T0(int size)
729 {
730         if (size == 1)
731                 gen_op_zextb_T1_T0();
732         else if (size == 2)
733                 gen_op_zextw_T1_T0();
734 }
735
736 static void gen_zext_T1_T1(int size)
737 {
738         if (size == 1)
739                 gen_op_zextb_T1_T1();
740         else if (size == 2)
741                 gen_op_zextw_T1_T1();
742 }
743
744 #if DISAS_CRIS
745 static char memsize_char(int size)
746 {
747         switch (size)
748         {
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;
755         }
756 }
757 #endif
758
759 static unsigned int memsize_z(DisasContext *dc)
760 {
761         return dc->zsize + 1;
762 }
763
764 static unsigned int memsize_zz(DisasContext *dc)
765 {
766         switch (dc->zzsize)
767         {
768                 case 0: return 1;
769                 case 1: return 2;
770                 default:
771                         return 4;
772         }
773 }
774
775 static void do_postinc (DisasContext *dc, int size)
776 {
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]();
782 }
783
784
785 static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
786                             int size, int s_ext)
787 {
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);
794 }
795
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)
801 {
802         dec_prep_move_r(dc, rs, rd, size, s_ext);
803
804         gen_movl_T0_reg[rd]();
805         if (s_ext)
806                 gen_sext_T0_T0(size);
807         else
808                 gen_zext_T0_T0(size);
809 }
810
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)
815 {
816         unsigned int rs, rd;
817         uint32_t imm;
818         int is_imm;
819         int insn_len = 2;
820
821         rs = dc->op1;
822         rd = dc->op2;
823         is_imm = rs == 15 && dc->postinc;
824
825         /* Load [$rs] onto T1.  */
826         if (is_imm) {
827                 insn_len = 2 + memsize;
828                 if (memsize == 1)
829                         insn_len++;
830
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;
840                         }
841                 }
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);
854         }
855
856         /* put dest in T0.  */
857         gen_movl_T0_reg[rd]();
858         return insn_len;
859 }
860
861 #if DISAS_CRIS
862 static const char *cc_name(int cc)
863 {
864         static char *cc_names[16] = {
865                 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
866                 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
867         };
868         assert(cc < 16);
869         return cc_names[cc];
870 }
871 #endif
872
873 static unsigned int dec_bccq(DisasContext *dc)
874 {
875         int32_t offset;
876         int sign;
877         uint32_t cond = dc->op2;
878         int tmp;
879
880         offset = EXTRACT_FIELD (dc->ir, 1, 7);
881         sign = EXTRACT_FIELD(dc->ir, 0, 0);
882
883         offset *= 2;
884         offset |= sign << 8;
885         tmp = offset;
886         offset = sign_extend(offset, 8);
887
888         /* op2 holds the condition-code.  */
889         cris_cc_mask(dc, 0);
890         cris_prepare_cc_branch (dc, offset, cond);
891         return 2;
892 }
893 static unsigned int dec_addoq(DisasContext *dc)
894 {
895         uint32_t imm;
896
897         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
898         imm = sign_extend(dc->op1, 7);
899
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;
907 }
908 static unsigned int dec_addq(DisasContext *dc)
909 {
910         DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
911
912         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
913
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;
920 }
921 static unsigned int dec_moveq(DisasContext *dc)
922 {
923         uint32_t imm;
924
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));
928
929         cris_cc_mask(dc, 0);
930         gen_op_movl_T1_im(imm);
931         crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
932
933         return 2;
934 }
935 static unsigned int dec_subq(DisasContext *dc)
936 {
937         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
938
939         DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
940
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;
947 }
948 static unsigned int dec_cmpq(DisasContext *dc)
949 {
950         uint32_t imm;
951         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
952         imm = sign_extend(dc->op1, 5);
953
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;
960 }
961 static unsigned int dec_andq(DisasContext *dc)
962 {
963         uint32_t imm;
964         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
965         imm = sign_extend(dc->op1, 5);
966
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;
973 }
974 static unsigned int dec_orq(DisasContext *dc)
975 {
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;
985 }
986 static unsigned int dec_btstq(DisasContext *dc)
987 {
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);
995
996         cris_update_cc_op(dc, CC_OP_FLAGS);
997         gen_op_movl_flags_T0();
998         dc->flags_live = 1;
999         return 2;
1000 }
1001 static unsigned int dec_asrq(DisasContext *dc)
1002 {
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;
1010 }
1011 static unsigned int dec_lslq(DisasContext *dc)
1012 {
1013         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1014         DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1015
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;
1021 }
1022 static unsigned int dec_lsrq(DisasContext *dc)
1023 {
1024         dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1025         DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1026
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;
1032 }
1033
1034 static unsigned int dec_move_r(DisasContext *dc)
1035 {
1036         int size = memsize_zz(dc);
1037
1038         DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1039                     memsize_char(size), dc->op1, dc->op2));
1040
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;
1045 }
1046
1047 static unsigned int dec_scc_r(DisasContext *dc)
1048 {
1049         int cond = dc->op2;
1050
1051         DIS(fprintf (logfile, "s%s $r%u\n",
1052                     cc_name(cond), dc->op1));
1053
1054         if (cond != CC_A)
1055         {
1056                 gen_tst_cc (dc, cond);
1057                 gen_op_movl_T1_T0();
1058         }
1059         else
1060                 gen_op_movl_T1_im(1);
1061
1062         cris_cc_mask(dc, 0);
1063         crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1064         return 2;
1065 }
1066
1067 static unsigned int dec_and_r(DisasContext *dc)
1068 {
1069         int size = memsize_zz(dc);
1070
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;
1077 }
1078
1079 static unsigned int dec_lz_r(DisasContext *dc)
1080 {
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;
1087 }
1088
1089 static unsigned int dec_lsl_r(DisasContext *dc)
1090 {
1091         int size = memsize_zz(dc);
1092
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;
1100 }
1101
1102 static unsigned int dec_lsr_r(DisasContext *dc)
1103 {
1104         int size = memsize_zz(dc);
1105
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;
1113 }
1114
1115 static unsigned int dec_asr_r(DisasContext *dc)
1116 {
1117         int size = memsize_zz(dc);
1118
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;
1126 }
1127
1128 static unsigned int dec_muls_r(DisasContext *dc)
1129 {
1130         int size = memsize_zz(dc);
1131
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;
1139 }
1140
1141 static unsigned int dec_mulu_r(DisasContext *dc)
1142 {
1143         int size = memsize_zz(dc);
1144
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;
1152 }
1153
1154
1155 static unsigned int dec_dstep_r(DisasContext *dc)
1156 {
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;
1164 }
1165
1166 static unsigned int dec_xor_r(DisasContext *dc)
1167 {
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;
1176 }
1177
1178 static unsigned int dec_bound_r(DisasContext *dc)
1179 {
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;
1190 }
1191
1192 static unsigned int dec_cmp_r(DisasContext *dc)
1193 {
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;
1201 }
1202
1203 static unsigned int dec_abs_r(DisasContext *dc)
1204 {
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;
1212 }
1213
1214 static unsigned int dec_add_r(DisasContext *dc)
1215 {
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;
1223 }
1224
1225 static unsigned int dec_addc_r(DisasContext *dc)
1226 {
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;
1234 }
1235
1236 static unsigned int dec_mcp_r(DisasContext *dc)
1237 {
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;
1247 }
1248
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;
1262 }
1263 #endif
1264
1265 static unsigned int dec_swap_r(DisasContext *dc)
1266 {
1267         DIS(char modename[4]);
1268         DIS(fprintf (logfile, "swap%s $r%u\n",
1269                      swapmode_name(dc->op2, modename), dc->op1));
1270
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;
1284 }
1285
1286 static unsigned int dec_or_r(DisasContext *dc)
1287 {
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;
1295 }
1296
1297 static unsigned int dec_addi_r(DisasContext *dc)
1298 {
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;
1307 }
1308
1309 static unsigned int dec_addi_acr(DisasContext *dc)
1310 {
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;
1319 }
1320
1321 static unsigned int dec_neg_r(DisasContext *dc)
1322 {
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;
1330 }
1331
1332 static unsigned int dec_btst_r(DisasContext *dc)
1333 {
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);
1340
1341         cris_update_cc_op(dc, CC_OP_FLAGS);
1342         gen_op_movl_flags_T0();
1343         dc->flags_live = 1;
1344         return 2;
1345 }
1346
1347 static unsigned int dec_sub_r(DisasContext *dc)
1348 {
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;
1356 }
1357
1358 /* Zero extension. From size to dword.  */
1359 static unsigned int dec_movu_r(DisasContext *dc)
1360 {
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));
1365
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;
1370 }
1371
1372 /* Sign extension. From size to dword.  */
1373 static unsigned int dec_movs_r(DisasContext *dc)
1374 {
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));
1379
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;
1386 }
1387
1388 /* zero extension. From size to dword.  */
1389 static unsigned int dec_addu_r(DisasContext *dc)
1390 {
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));
1395
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;
1403 }
1404 /* Sign extension. From size to dword.  */
1405 static unsigned int dec_adds_r(DisasContext *dc)
1406 {
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));
1411
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;
1419 }
1420
1421 /* Zero extension. From size to dword.  */
1422 static unsigned int dec_subu_r(DisasContext *dc)
1423 {
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));
1428
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;
1436 }
1437
1438 /* Sign extension. From size to dword.  */
1439 static unsigned int dec_subs_r(DisasContext *dc)
1440 {
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));
1445
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;
1453 }
1454
1455 static unsigned int dec_setclrf(DisasContext *dc)
1456 {
1457         uint32_t flags;
1458         int set = (~dc->opcode >> 2) & 1;
1459
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));
1471
1472         if (set && (flags & X_FLAG)) {
1473                 dc->flagx_live = 1;
1474                 dc->flags_x = 1;
1475         }
1476
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;
1486 }
1487
1488 static unsigned int dec_move_rs(DisasContext *dc)
1489 {
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);
1494
1495         if (dc->op2 == 5) /* srs is checked at runtime.  */
1496                 gen_op_movl_tlb_lo_T0();
1497         return 2;
1498 }
1499 static unsigned int dec_move_sr(DisasContext *dc)
1500 {
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;
1507 }
1508 static unsigned int dec_move_rp(DisasContext *dc)
1509 {
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;
1516 }
1517 static unsigned int dec_move_pr(DisasContext *dc)
1518 {
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;
1525 }
1526
1527 static unsigned int dec_move_mr(DisasContext *dc)
1528 {
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));
1535
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;
1541 }
1542
1543 static unsigned int dec_movs_m(DisasContext *dc)
1544 {
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));
1551
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;
1558 }
1559
1560 static unsigned int dec_addu_m(DisasContext *dc)
1561 {
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));
1568
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;
1575 }
1576
1577 static unsigned int dec_adds_m(DisasContext *dc)
1578 {
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));
1585
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;
1592 }
1593
1594 static unsigned int dec_subu_m(DisasContext *dc)
1595 {
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));
1602
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;
1609 }
1610
1611 static unsigned int dec_subs_m(DisasContext *dc)
1612 {
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));
1619
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;
1626 }
1627
1628 static unsigned int dec_movu_m(DisasContext *dc)
1629 {
1630         int memsize = memsize_z(dc);
1631         int insn_len;
1632
1633         DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1634                     memsize_char(memsize),
1635                     dc->op1, dc->postinc ? "+]" : "]",
1636                     dc->op2));
1637
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;
1643 }
1644
1645 static unsigned int dec_cmpu_m(DisasContext *dc)
1646 {
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));
1653
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;
1659 }
1660
1661 static unsigned int dec_cmps_m(DisasContext *dc)
1662 {
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));
1669
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;
1675 }
1676
1677 static unsigned int dec_cmp_m(DisasContext *dc)
1678 {
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));
1685
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;
1691 }
1692
1693 static unsigned int dec_test_m(DisasContext *dc)
1694 {
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));
1701
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;
1710 }
1711
1712 static unsigned int dec_and_m(DisasContext *dc)
1713 {
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));
1720
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;
1726 }
1727
1728 static unsigned int dec_add_m(DisasContext *dc)
1729 {
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));
1736
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;
1742 }
1743
1744 static unsigned int dec_addo_m(DisasContext *dc)
1745 {
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));
1752
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;
1758 }
1759
1760 static unsigned int dec_bound_m(DisasContext *dc)
1761 {
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));
1768
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;
1774 }
1775
1776 static unsigned int dec_addc_mr(DisasContext *dc)
1777 {
1778         int insn_len = 2;
1779         DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1780                     dc->op1, dc->postinc ? "+]" : "]",
1781                     dc->op2));
1782
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;
1789 }
1790
1791 static unsigned int dec_sub_m(DisasContext *dc)
1792 {
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));
1799
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;
1805 }
1806
1807 static unsigned int dec_or_m(DisasContext *dc)
1808 {
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));
1815
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;
1821 }
1822
1823 static unsigned int dec_move_mp(DisasContext *dc)
1824 {
1825         int memsize = memsize_zz(dc);
1826         int insn_len = 2;
1827
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));
1833
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]();
1838
1839         do_postinc(dc, memsize);
1840         return insn_len;
1841 }
1842
1843 static unsigned int dec_move_pm(DisasContext *dc)
1844 {
1845         int memsize;
1846
1847         memsize = preg_sizes[dc->op2];
1848
1849         DIS(fprintf (logfile, "move.%d $p%u, [$r%u%s\n",
1850                      memsize, dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
1851
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)
1859         {
1860                 gen_op_addl_T0_im(memsize);
1861                 gen_movl_reg_T0[dc->op1]();
1862         }
1863         return 2;
1864 }
1865
1866 static unsigned int dec_movem_mr(DisasContext *dc)
1867 {
1868         int i;
1869
1870         DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
1871                     dc->postinc ? "+]" : "]", dc->op2));
1872
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();
1884         }
1885         if (dc->postinc) {
1886                 /* writeback the updated pointer value.  */
1887                 gen_movl_reg_T0[dc->op1]();
1888         }
1889         return 2;
1890 }
1891
1892 static unsigned int dec_movem_rm(DisasContext *dc)
1893 {
1894         int i;
1895
1896         DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
1897                      dc->postinc ? "+]" : "]"));
1898
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();
1904
1905                 /* Fetch the address into T0.  */
1906                 gen_movl_T0_reg[dc->op1]();
1907                 /* Displace it.  */
1908                 gen_op_addl_T0_im(i * 4);
1909
1910                 /* Perform the store.  */
1911                 gen_store_T0_T1(dc, 4);
1912         }
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]();
1918         }
1919         return 2;
1920 }
1921
1922 static unsigned int dec_move_rm(DisasContext *dc)
1923 {
1924         int memsize;
1925
1926         memsize = memsize_zz(dc);
1927
1928         DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
1929                      memsize, dc->op2, dc->op1));
1930
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)
1938         {
1939                 gen_op_addl_T0_im(memsize);
1940                 gen_movl_reg_T0[dc->op1]();
1941         }
1942         return 2;
1943 }
1944
1945
1946 static unsigned int dec_lapcq(DisasContext *dc)
1947 {
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;
1954 }
1955
1956 static unsigned int dec_lapc_im(DisasContext *dc)
1957 {
1958         unsigned int rd;
1959         int32_t imm;
1960         int insn_len = 6;
1961
1962         rd = dc->op2;
1963
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;
1970 }
1971
1972 /* Jump to special reg.  */
1973 static unsigned int dec_jump_p(DisasContext *dc)
1974 {
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;
1982 }
1983
1984 /* Jump and save.  */
1985 static unsigned int dec_jas_r(DisasContext *dc)
1986 {
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;
1996 }
1997
1998 static unsigned int dec_jas_im(DisasContext *dc)
1999 {
2000         uint32_t imm;
2001
2002         imm = ldl_code(dc->pc + 2);
2003
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;
2013 }
2014
2015 static unsigned int dec_jasc_im(DisasContext *dc)
2016 {
2017         uint32_t imm;
2018
2019         imm = ldl_code(dc->pc + 2);
2020
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;
2030 }
2031
2032 static unsigned int dec_jasc_r(DisasContext *dc)
2033 {
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;
2043 }
2044
2045 static unsigned int dec_bcc_im(DisasContext *dc)
2046 {
2047         int32_t offset;
2048         uint32_t cond = dc->op2;
2049
2050         offset = ldl_code(dc->pc + 2);
2051         offset = sign_extend(offset, 15);
2052
2053         DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2054                     cc_name(cond), offset,
2055                     dc->pc, dc->pc + offset));
2056
2057         cris_cc_mask(dc, 0);
2058         /* op2 holds the condition-code.  */
2059         cris_prepare_cc_branch (dc, offset, cond);
2060         return 4;
2061 }
2062
2063 static unsigned int dec_bas_im(DisasContext *dc)
2064 {
2065         int32_t simm;
2066
2067
2068         simm = ldl_code(dc->pc + 2);
2069
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;
2079 }
2080
2081 static unsigned int dec_basc_im(DisasContext *dc)
2082 {
2083         int32_t simm;
2084         simm = ldl_code(dc->pc + 2);
2085
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;
2095 }
2096
2097 static unsigned int dec_rfe_etc(DisasContext *dc)
2098 {
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));
2101
2102         cris_cc_mask(dc, 0);
2103
2104         if (dc->op2 == 15) /* ignore halt.  */
2105                 goto done;
2106
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;
2128
2129         }
2130   done:
2131         return 2;
2132 }
2133
2134 static unsigned int dec_null(DisasContext *dc)
2135 {
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;
2141 }
2142
2143 struct decoder_info {
2144         struct {
2145                 uint32_t bits;
2146                 uint32_t mask;
2147         };
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},
2163
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},
2174
2175         {DEC_RFE_ETC, dec_rfe_etc},
2176         {DEC_ADDC_MR, dec_addc_mr},
2177
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},
2186
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},
2195
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},
2200
2201         {DEC_ADDI_R, dec_addi_r},
2202         {DEC_ADDI_ACR, dec_addi_acr},
2203
2204         {DEC_ADD_R, dec_add_r},
2205         {DEC_SUB_R, dec_sub_r},
2206
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},
2212
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},
2218
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},
2223
2224         /* ftag_fidx_i_m.  */
2225         /* ftag_fidx_d_m.  */
2226
2227         {DEC_MULS_R, dec_muls_r},
2228         {DEC_MULU_R, dec_mulu_r},
2229
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},
2234
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},
2239
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},
2250
2251         {{0, 0}, dec_null}
2252 };
2253
2254 static inline unsigned int
2255 cris_decoder(DisasContext *dc)
2256 {
2257         unsigned int insn_len = 2;
2258         uint32_t tmp;
2259         int i;
2260
2261         /* Load a halfword onto the instruction register.  */
2262         tmp = ldl_code(dc->pc);
2263         dc->ir = tmp & 0xffff;
2264
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);
2272
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)
2276                 {
2277                         insn_len = decinfo[i].dec(dc);
2278                         break;
2279                 }
2280         }
2281
2282         return insn_len;
2283 }
2284
2285 static void check_breakpoint(CPUState *env, DisasContext *dc)
2286 {
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;
2296                         }
2297                 }
2298         }
2299 }
2300
2301
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)
2307 {
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;
2314
2315         pc_start = tb->pc;
2316         dc->env = env;
2317         dc->tb = tb;
2318
2319         gen_opc_ptr = gen_opc_buf;
2320         gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2321         gen_opparam_ptr = gen_opparam_buf;
2322
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;
2330         do
2331         {
2332                 check_breakpoint(env, dc);
2333                 if (dc->is_jmp == DISAS_JUMP)
2334                         goto done;
2335
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;
2342                         }
2343                         gen_opc_pc[lj] = dc->pc;
2344                         gen_opc_instr_start[lj] = 1;
2345                 }
2346
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;
2358                 }
2359
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)
2366                         {
2367                                 if (dc->bcc == CC_A) {
2368                                         gen_op_jmp ();
2369                                         dc->is_jmp = DISAS_UPDATE;
2370                                 }
2371                                 else {
2372                                         /* Conditional jmp.  */
2373                                         gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2374                                         dc->is_jmp = DISAS_UPDATE;
2375                                 }
2376                         }
2377                 }
2378
2379                 if (env->singlestep_enabled)
2380                         break;
2381         } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2382                  && dc->pc < next_page_start);
2383
2384         if (!dc->is_jmp) {
2385                 gen_op_movl_T0_im((long)dc->pc);
2386                 gen_op_movl_pc_T0();
2387         }
2388
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;
2410                 }
2411         }
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;
2420         }
2421
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");
2432                 }
2433         }
2434 #endif
2435         return 0;
2436 }
2437
2438 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2439 {
2440     return gen_intermediate_code_internal(env, tb, 0);
2441 }
2442
2443 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2444 {
2445     return gen_intermediate_code_internal(env, tb, 1);
2446 }
2447
2448 void cpu_dump_state (CPUState *env, FILE *f,
2449                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2450                      int flags)
2451 {
2452         int i;
2453         uint32_t srs;
2454
2455         if (!env || !f)
2456                 return;
2457
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);
2465
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");
2470         }
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");
2476         }
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");
2485                 }
2486         }
2487         cpu_fprintf(f, "\n\n");
2488
2489 }
2490
2491 CPUCRISState *cpu_cris_init (const char *cpu_model)
2492 {
2493         CPUCRISState *env;
2494
2495         env = qemu_mallocz(sizeof(CPUCRISState));
2496         if (!env)
2497                 return NULL;
2498         cpu_exec_init(env);
2499         cpu_reset(env);
2500         return env;
2501 }
2502
2503 void cpu_reset (CPUCRISState *env)
2504 {
2505         memset(env, 0, offsetof(CPUCRISState, breakpoints));
2506         tlb_flush(env, 1);
2507 }