]> Git Repo - qemu.git/blob - target-cris/translate.c
c5a22afa66d1a989b566edb1a54985bd97eb2a81
[qemu.git] / target-cris / translate.c
1 /*
2  *  CRIS emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2008 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, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * FIXME:
23  * The condition code translation is in need of attention.
24  */
25
26 #include "cpu.h"
27 #include "disas/disas.h"
28 #include "tcg-op.h"
29 #include "exec/helper-proto.h"
30 #include "mmu.h"
31 #include "exec/cpu_ldst.h"
32 #include "crisv32-decode.h"
33
34 #include "exec/helper-gen.h"
35
36 #include "trace-tcg.h"
37
38
39 #define DISAS_CRIS 0
40 #if DISAS_CRIS
41 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
42 #else
43 #  define LOG_DIS(...) do { } while (0)
44 #endif
45
46 #define D(x)
47 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
48 #define BUG_ON(x) ({if (x) BUG();})
49
50 #define DISAS_SWI 5
51
52 /* Used by the decoder.  */
53 #define EXTRACT_FIELD(src, start, end) \
54             (((src) >> start) & ((1 << (end - start + 1)) - 1))
55
56 #define CC_MASK_NZ 0xc
57 #define CC_MASK_NZV 0xe
58 #define CC_MASK_NZVC 0xf
59 #define CC_MASK_RNZV 0x10e
60
61 static TCGv_ptr cpu_env;
62 static TCGv cpu_R[16];
63 static TCGv cpu_PR[16];
64 static TCGv cc_x;
65 static TCGv cc_src;
66 static TCGv cc_dest;
67 static TCGv cc_result;
68 static TCGv cc_op;
69 static TCGv cc_size;
70 static TCGv cc_mask;
71
72 static TCGv env_btaken;
73 static TCGv env_btarget;
74 static TCGv env_pc;
75
76 #include "exec/gen-icount.h"
77
78 /* This is the state at translation time.  */
79 typedef struct DisasContext {
80     CRISCPU *cpu;
81     target_ulong pc, ppc;
82
83     /* Decoder.  */
84         unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
85     uint32_t ir;
86     uint32_t opcode;
87     unsigned int op1;
88     unsigned int op2;
89     unsigned int zsize, zzsize;
90     unsigned int mode;
91     unsigned int postinc;
92
93     unsigned int size;
94     unsigned int src;
95     unsigned int dst;
96     unsigned int cond;
97
98     int update_cc;
99     int cc_op;
100     int cc_size;
101     uint32_t cc_mask;
102
103     int cc_size_uptodate; /* -1 invalid or last written value.  */
104
105     int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date.  */
106     int flags_uptodate; /* Whether or not $ccs is up-to-date.  */
107     int flagx_known; /* Whether or not flags_x has the x flag known at
108                 translation time.  */
109     int flags_x;
110
111     int clear_x; /* Clear x after this insn?  */
112     int clear_prefix; /* Clear prefix after this insn?  */
113     int clear_locked_irq; /* Clear the irq lockout.  */
114     int cpustate_changed;
115     unsigned int tb_flags; /* tb dependent flags.  */
116     int is_jmp;
117
118 #define JMP_NOJMP     0
119 #define JMP_DIRECT    1
120 #define JMP_DIRECT_CC 2
121 #define JMP_INDIRECT  3
122     int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */
123     uint32_t jmp_pc;
124
125     int delayed_branch;
126
127     struct TranslationBlock *tb;
128     int singlestep_enabled;
129 } DisasContext;
130
131 static void gen_BUG(DisasContext *dc, const char *file, int line)
132 {
133     printf("BUG: pc=%x %s %d\n", dc->pc, file, line);
134     qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
135     cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line);
136 }
137
138 static const char *regnames[] =
139 {
140     "$r0", "$r1", "$r2", "$r3",
141     "$r4", "$r5", "$r6", "$r7",
142     "$r8", "$r9", "$r10", "$r11",
143     "$r12", "$r13", "$sp", "$acr",
144 };
145 static const char *pregnames[] =
146 {
147     "$bz", "$vr", "$pid", "$srs",
148     "$wz", "$exs", "$eda", "$mof",
149     "$dz", "$ebp", "$erp", "$srp",
150     "$nrp", "$ccs", "$usp", "$spc",
151 };
152
153 /* We need this table to handle preg-moves with implicit width.  */
154 static int preg_sizes[] = {
155     1, /* bz.  */
156     1, /* vr.  */
157     4, /* pid.  */
158     1, /* srs.  */
159     2, /* wz.  */
160     4, 4, 4,
161     4, 4, 4, 4,
162     4, 4, 4, 4,
163 };
164
165 #define t_gen_mov_TN_env(tn, member) \
166     tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUCRISState, member))
167 #define t_gen_mov_env_TN(member, tn) \
168     tcg_gen_st_tl(tn, cpu_env, offsetof(CPUCRISState, member))
169
170 static inline void t_gen_mov_TN_preg(TCGv tn, int r)
171 {
172     assert(r >= 0 && r <= 15);
173     if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
174         tcg_gen_mov_tl(tn, tcg_const_tl(0));
175     } else if (r == PR_VR) {
176         tcg_gen_mov_tl(tn, tcg_const_tl(32));
177     } else {
178         tcg_gen_mov_tl(tn, cpu_PR[r]);
179     }
180 }
181 static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
182 {
183     assert(r >= 0 && r <= 15);
184     if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
185         return;
186     } else if (r == PR_SRS) {
187         tcg_gen_andi_tl(cpu_PR[r], tn, 3);
188     } else {
189         if (r == PR_PID) {
190             gen_helper_tlb_flush_pid(cpu_env, tn);
191         }
192         if (dc->tb_flags & S_FLAG && r == PR_SPC) {
193             gen_helper_spc_write(cpu_env, tn);
194         } else if (r == PR_CCS) {
195             dc->cpustate_changed = 1;
196         }
197         tcg_gen_mov_tl(cpu_PR[r], tn);
198     }
199 }
200
201 /* Sign extend at translation time.  */
202 static int sign_extend(unsigned int val, unsigned int width)
203 {
204     int sval;
205
206     /* LSL.  */
207     val <<= 31 - width;
208     sval = val;
209     /* ASR.  */
210     sval >>= 31 - width;
211     return sval;
212 }
213
214 static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
215               unsigned int size, unsigned int sign)
216 {
217     int r;
218
219     switch (size) {
220     case 4:
221     {
222         r = cpu_ldl_code(env, addr);
223         break;
224     }
225     case 2:
226     {
227         if (sign) {
228             r = cpu_ldsw_code(env, addr);
229         } else {
230             r = cpu_lduw_code(env, addr);
231         }
232         break;
233     }
234     case 1:
235     {
236         if (sign) {
237             r = cpu_ldsb_code(env, addr);
238         } else {
239             r = cpu_ldub_code(env, addr);
240         }
241         break;
242     }
243     default:
244         cpu_abort(CPU(dc->cpu), "Invalid fetch size %d\n", size);
245         break;
246     }
247     return r;
248 }
249
250 static void cris_lock_irq(DisasContext *dc)
251 {
252     dc->clear_locked_irq = 0;
253     t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
254 }
255
256 static inline void t_gen_raise_exception(uint32_t index)
257 {
258         TCGv_i32 tmp = tcg_const_i32(index);
259         gen_helper_raise_exception(cpu_env, tmp);
260         tcg_temp_free_i32(tmp);
261 }
262
263 static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
264 {
265     TCGv t0, t_31;
266
267     t0 = tcg_temp_new();
268     t_31 = tcg_const_tl(31);
269     tcg_gen_shl_tl(d, a, b);
270
271     tcg_gen_sub_tl(t0, t_31, b);
272     tcg_gen_sar_tl(t0, t0, t_31);
273     tcg_gen_and_tl(t0, t0, d);
274     tcg_gen_xor_tl(d, d, t0);
275     tcg_temp_free(t0);
276     tcg_temp_free(t_31);
277 }
278
279 static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
280 {
281     TCGv t0, t_31;
282
283     t0 = tcg_temp_new();
284     t_31 = tcg_temp_new();
285     tcg_gen_shr_tl(d, a, b);
286
287     tcg_gen_movi_tl(t_31, 31);
288     tcg_gen_sub_tl(t0, t_31, b);
289     tcg_gen_sar_tl(t0, t0, t_31);
290     tcg_gen_and_tl(t0, t0, d);
291     tcg_gen_xor_tl(d, d, t0);
292     tcg_temp_free(t0);
293     tcg_temp_free(t_31);
294 }
295
296 static void t_gen_asr(TCGv d, TCGv a, TCGv b)
297 {
298     TCGv t0, t_31;
299
300     t0 = tcg_temp_new();
301     t_31 = tcg_temp_new();
302     tcg_gen_sar_tl(d, a, b);
303
304     tcg_gen_movi_tl(t_31, 31);
305     tcg_gen_sub_tl(t0, t_31, b);
306     tcg_gen_sar_tl(t0, t0, t_31);
307     tcg_gen_or_tl(d, d, t0);
308     tcg_temp_free(t0);
309     tcg_temp_free(t_31);
310 }
311
312 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
313 {
314     TCGv t = tcg_temp_new();
315
316     /*
317      * d <<= 1
318      * if (d >= s)
319      *    d -= s;
320      */
321     tcg_gen_shli_tl(d, a, 1);
322     tcg_gen_sub_tl(t, d, b);
323     tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d);
324     tcg_temp_free(t);
325 }
326
327 static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
328 {
329     TCGv t;
330
331     /*
332      * d <<= 1
333      * if (n)
334      *    d += s;
335      */
336     t = tcg_temp_new();
337     tcg_gen_shli_tl(d, a, 1);
338     tcg_gen_shli_tl(t, ccs, 31 - 3);
339     tcg_gen_sari_tl(t, t, 31);
340     tcg_gen_and_tl(t, t, b);
341     tcg_gen_add_tl(d, d, t);
342     tcg_temp_free(t);
343 }
344
345 /* Extended arithmetics on CRIS.  */
346 static inline void t_gen_add_flag(TCGv d, int flag)
347 {
348     TCGv c;
349
350     c = tcg_temp_new();
351     t_gen_mov_TN_preg(c, PR_CCS);
352     /* Propagate carry into d.  */
353     tcg_gen_andi_tl(c, c, 1 << flag);
354     if (flag) {
355         tcg_gen_shri_tl(c, c, flag);
356     }
357     tcg_gen_add_tl(d, d, c);
358     tcg_temp_free(c);
359 }
360
361 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
362 {
363     if (dc->flagx_known) {
364         if (dc->flags_x) {
365             TCGv c;
366             
367             c = tcg_temp_new();
368             t_gen_mov_TN_preg(c, PR_CCS);
369             /* C flag is already at bit 0.  */
370             tcg_gen_andi_tl(c, c, C_FLAG);
371             tcg_gen_add_tl(d, d, c);
372             tcg_temp_free(c);
373         }
374     } else {
375         TCGv x, c;
376
377         x = tcg_temp_new();
378         c = tcg_temp_new();
379         t_gen_mov_TN_preg(x, PR_CCS);
380         tcg_gen_mov_tl(c, x);
381
382         /* Propagate carry into d if X is set. Branch free.  */
383         tcg_gen_andi_tl(c, c, C_FLAG);
384         tcg_gen_andi_tl(x, x, X_FLAG);
385         tcg_gen_shri_tl(x, x, 4);
386
387         tcg_gen_and_tl(x, x, c);
388         tcg_gen_add_tl(d, d, x);
389         tcg_temp_free(x);
390         tcg_temp_free(c);
391     }
392 }
393
394 static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
395 {
396     if (dc->flagx_known) {
397         if (dc->flags_x) {
398             TCGv c;
399             
400             c = tcg_temp_new();
401             t_gen_mov_TN_preg(c, PR_CCS);
402             /* C flag is already at bit 0.  */
403             tcg_gen_andi_tl(c, c, C_FLAG);
404             tcg_gen_sub_tl(d, d, c);
405             tcg_temp_free(c);
406         }
407     } else {
408         TCGv x, c;
409
410         x = tcg_temp_new();
411         c = tcg_temp_new();
412         t_gen_mov_TN_preg(x, PR_CCS);
413         tcg_gen_mov_tl(c, x);
414
415         /* Propagate carry into d if X is set. Branch free.  */
416         tcg_gen_andi_tl(c, c, C_FLAG);
417         tcg_gen_andi_tl(x, x, X_FLAG);
418         tcg_gen_shri_tl(x, x, 4);
419
420         tcg_gen_and_tl(x, x, c);
421         tcg_gen_sub_tl(d, d, x);
422         tcg_temp_free(x);
423         tcg_temp_free(c);
424     }
425 }
426
427 /* Swap the two bytes within each half word of the s operand.
428    T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
429 static inline void t_gen_swapb(TCGv d, TCGv s)
430 {
431     TCGv t, org_s;
432
433     t = tcg_temp_new();
434     org_s = tcg_temp_new();
435
436     /* d and s may refer to the same object.  */
437     tcg_gen_mov_tl(org_s, s);
438     tcg_gen_shli_tl(t, org_s, 8);
439     tcg_gen_andi_tl(d, t, 0xff00ff00);
440     tcg_gen_shri_tl(t, org_s, 8);
441     tcg_gen_andi_tl(t, t, 0x00ff00ff);
442     tcg_gen_or_tl(d, d, t);
443     tcg_temp_free(t);
444     tcg_temp_free(org_s);
445 }
446
447 /* Swap the halfwords of the s operand.  */
448 static inline void t_gen_swapw(TCGv d, TCGv s)
449 {
450     TCGv t;
451     /* d and s refer the same object.  */
452     t = tcg_temp_new();
453     tcg_gen_mov_tl(t, s);
454     tcg_gen_shli_tl(d, t, 16);
455     tcg_gen_shri_tl(t, t, 16);
456     tcg_gen_or_tl(d, d, t);
457     tcg_temp_free(t);
458 }
459
460 /* Reverse the within each byte.
461    T0 = (((T0 << 7) & 0x80808080) |
462    ((T0 << 5) & 0x40404040) |
463    ((T0 << 3) & 0x20202020) |
464    ((T0 << 1) & 0x10101010) |
465    ((T0 >> 1) & 0x08080808) |
466    ((T0 >> 3) & 0x04040404) |
467    ((T0 >> 5) & 0x02020202) |
468    ((T0 >> 7) & 0x01010101));
469  */
470 static inline void t_gen_swapr(TCGv d, TCGv s)
471 {
472     struct {
473         int shift; /* LSL when positive, LSR when negative.  */
474         uint32_t mask;
475     } bitrev[] = {
476         {7, 0x80808080},
477         {5, 0x40404040},
478         {3, 0x20202020},
479         {1, 0x10101010},
480         {-1, 0x08080808},
481         {-3, 0x04040404},
482         {-5, 0x02020202},
483         {-7, 0x01010101}
484     };
485     int i;
486     TCGv t, org_s;
487
488     /* d and s refer the same object.  */
489     t = tcg_temp_new();
490     org_s = tcg_temp_new();
491     tcg_gen_mov_tl(org_s, s);
492
493     tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
494     tcg_gen_andi_tl(d, t,  bitrev[0].mask);
495     for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
496         if (bitrev[i].shift >= 0) {
497             tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
498         } else {
499             tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
500         }
501         tcg_gen_andi_tl(t, t,  bitrev[i].mask);
502         tcg_gen_or_tl(d, d, t);
503     }
504     tcg_temp_free(t);
505     tcg_temp_free(org_s);
506 }
507
508 static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
509 {
510     TCGLabel *l1 = gen_new_label();
511
512     /* Conditional jmp.  */
513     tcg_gen_mov_tl(env_pc, pc_false);
514     tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
515     tcg_gen_mov_tl(env_pc, pc_true);
516     gen_set_label(l1);
517 }
518
519 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
520 {
521     TranslationBlock *tb;
522     tb = dc->tb;
523     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
524         tcg_gen_goto_tb(n);
525         tcg_gen_movi_tl(env_pc, dest);
526                 tcg_gen_exit_tb((uintptr_t)tb + n);
527     } else {
528         tcg_gen_movi_tl(env_pc, dest);
529         tcg_gen_exit_tb(0);
530     }
531 }
532
533 static inline void cris_clear_x_flag(DisasContext *dc)
534 {
535     if (dc->flagx_known && dc->flags_x) {
536         dc->flags_uptodate = 0;
537     }
538
539     dc->flagx_known = 1;
540     dc->flags_x = 0;
541 }
542
543 static void cris_flush_cc_state(DisasContext *dc)
544 {
545     if (dc->cc_size_uptodate != dc->cc_size) {
546         tcg_gen_movi_tl(cc_size, dc->cc_size);
547         dc->cc_size_uptodate = dc->cc_size;
548     }
549     tcg_gen_movi_tl(cc_op, dc->cc_op);
550     tcg_gen_movi_tl(cc_mask, dc->cc_mask);
551 }
552
553 static void cris_evaluate_flags(DisasContext *dc)
554 {
555     if (dc->flags_uptodate) {
556         return;
557     }
558
559     cris_flush_cc_state(dc);
560
561     switch (dc->cc_op) {
562     case CC_OP_MCP:
563         gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
564                 cpu_PR[PR_CCS], cc_src,
565                 cc_dest, cc_result);
566         break;
567     case CC_OP_MULS:
568         gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
569                 cpu_PR[PR_CCS], cc_result,
570                 cpu_PR[PR_MOF]);
571         break;
572     case CC_OP_MULU:
573         gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
574                 cpu_PR[PR_CCS], cc_result,
575                 cpu_PR[PR_MOF]);
576         break;
577     case CC_OP_MOVE:
578     case CC_OP_AND:
579     case CC_OP_OR:
580     case CC_OP_XOR:
581     case CC_OP_ASR:
582     case CC_OP_LSR:
583     case CC_OP_LSL:
584         switch (dc->cc_size) {
585         case 4:
586             gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
587                     cpu_env, cpu_PR[PR_CCS], cc_result);
588             break;
589         case 2:
590             gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
591                     cpu_env, cpu_PR[PR_CCS], cc_result);
592             break;
593         default:
594             gen_helper_evaluate_flags(cpu_env);
595             break;
596         }
597         break;
598     case CC_OP_FLAGS:
599         /* live.  */
600         break;
601     case CC_OP_SUB:
602     case CC_OP_CMP:
603         if (dc->cc_size == 4) {
604             gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
605                     cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
606         } else {
607             gen_helper_evaluate_flags(cpu_env);
608         }
609
610         break;
611     default:
612         switch (dc->cc_size) {
613         case 4:
614             gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
615                     cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
616             break;
617         default:
618             gen_helper_evaluate_flags(cpu_env);
619             break;
620         }
621         break;
622     }
623
624     if (dc->flagx_known) {
625         if (dc->flags_x) {
626             tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
627         } else if (dc->cc_op == CC_OP_FLAGS) {
628             tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
629         }
630     }
631     dc->flags_uptodate = 1;
632 }
633
634 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
635 {
636     uint32_t ovl;
637
638     if (!mask) {
639         dc->update_cc = 0;
640         return;
641     }
642
643     /* Check if we need to evaluate the condition codes due to
644        CC overlaying.  */
645     ovl = (dc->cc_mask ^ mask) & ~mask;
646     if (ovl) {
647         /* TODO: optimize this case. It trigs all the time.  */
648         cris_evaluate_flags(dc);
649     }
650     dc->cc_mask = mask;
651     dc->update_cc = 1;
652 }
653
654 static void cris_update_cc_op(DisasContext *dc, int op, int size)
655 {
656     dc->cc_op = op;
657     dc->cc_size = size;
658     dc->flags_uptodate = 0;
659 }
660
661 static inline void cris_update_cc_x(DisasContext *dc)
662 {
663     /* Save the x flag state at the time of the cc snapshot.  */
664     if (dc->flagx_known) {
665         if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
666             return;
667         }
668         tcg_gen_movi_tl(cc_x, dc->flags_x);
669         dc->cc_x_uptodate = 2 | dc->flags_x;
670     } else {
671         tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
672         dc->cc_x_uptodate = 1;
673     }
674 }
675
676 /* Update cc prior to executing ALU op. Needs source operands untouched.  */
677 static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
678                    TCGv dst, TCGv src, int size)
679 {
680     if (dc->update_cc) {
681         cris_update_cc_op(dc, op, size);
682         tcg_gen_mov_tl(cc_src, src);
683
684         if (op != CC_OP_MOVE
685             && op != CC_OP_AND
686             && op != CC_OP_OR
687             && op != CC_OP_XOR
688             && op != CC_OP_ASR
689             && op != CC_OP_LSR
690             && op != CC_OP_LSL) {
691             tcg_gen_mov_tl(cc_dest, dst);
692         }
693
694         cris_update_cc_x(dc);
695     }
696 }
697
698 /* Update cc after executing ALU op. needs the result.  */
699 static inline void cris_update_result(DisasContext *dc, TCGv res)
700 {
701     if (dc->update_cc) {
702         tcg_gen_mov_tl(cc_result, res);
703     }
704 }
705
706 /* Returns one if the write back stage should execute.  */
707 static void cris_alu_op_exec(DisasContext *dc, int op, 
708                    TCGv dst, TCGv a, TCGv b, int size)
709 {
710     /* Emit the ALU insns.  */
711     switch (op) {
712     case CC_OP_ADD:
713         tcg_gen_add_tl(dst, a, b);
714         /* Extended arithmetics.  */
715         t_gen_addx_carry(dc, dst);
716         break;
717     case CC_OP_ADDC:
718         tcg_gen_add_tl(dst, a, b);
719         t_gen_add_flag(dst, 0); /* C_FLAG.  */
720         break;
721     case CC_OP_MCP:
722         tcg_gen_add_tl(dst, a, b);
723         t_gen_add_flag(dst, 8); /* R_FLAG.  */
724         break;
725     case CC_OP_SUB:
726         tcg_gen_sub_tl(dst, a, b);
727         /* Extended arithmetics.  */
728         t_gen_subx_carry(dc, dst);
729         break;
730     case CC_OP_MOVE:
731         tcg_gen_mov_tl(dst, b);
732         break;
733     case CC_OP_OR:
734         tcg_gen_or_tl(dst, a, b);
735         break;
736     case CC_OP_AND:
737         tcg_gen_and_tl(dst, a, b);
738         break;
739     case CC_OP_XOR:
740         tcg_gen_xor_tl(dst, a, b);
741         break;
742     case CC_OP_LSL:
743         t_gen_lsl(dst, a, b);
744         break;
745     case CC_OP_LSR:
746         t_gen_lsr(dst, a, b);
747         break;
748     case CC_OP_ASR:
749         t_gen_asr(dst, a, b);
750         break;
751     case CC_OP_NEG:
752         tcg_gen_neg_tl(dst, b);
753         /* Extended arithmetics.  */
754         t_gen_subx_carry(dc, dst);
755         break;
756     case CC_OP_LZ:
757         gen_helper_lz(dst, b);
758         break;
759     case CC_OP_MULS:
760         tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
761         break;
762     case CC_OP_MULU:
763         tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b);
764         break;
765     case CC_OP_DSTEP:
766         t_gen_cris_dstep(dst, a, b);
767         break;
768     case CC_OP_MSTEP:
769         t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
770         break;
771     case CC_OP_BOUND:
772         tcg_gen_movcond_tl(TCG_COND_LEU, dst, a, b, a, b);
773         break;
774     case CC_OP_CMP:
775         tcg_gen_sub_tl(dst, a, b);
776         /* Extended arithmetics.  */
777         t_gen_subx_carry(dc, dst);
778         break;
779     default:
780         qemu_log("illegal ALU op.\n");
781         BUG();
782         break;
783     }
784
785     if (size == 1) {
786         tcg_gen_andi_tl(dst, dst, 0xff);
787     } else if (size == 2) {
788         tcg_gen_andi_tl(dst, dst, 0xffff);
789     }
790 }
791
792 static void cris_alu(DisasContext *dc, int op,
793                    TCGv d, TCGv op_a, TCGv op_b, int size)
794 {
795     TCGv tmp;
796     int writeback;
797
798     writeback = 1;
799
800     if (op == CC_OP_CMP) {
801         tmp = tcg_temp_new();
802         writeback = 0;
803     } else if (size == 4) {
804         tmp = d;
805         writeback = 0;
806     } else {
807         tmp = tcg_temp_new();
808     }
809
810
811     cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
812     cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
813     cris_update_result(dc, tmp);
814
815     /* Writeback.  */
816     if (writeback) {
817         if (size == 1) {
818             tcg_gen_andi_tl(d, d, ~0xff);
819         } else {
820             tcg_gen_andi_tl(d, d, ~0xffff);
821         }
822         tcg_gen_or_tl(d, d, tmp);
823     }
824     if (!TCGV_EQUAL(tmp, d)) {
825         tcg_temp_free(tmp);
826     }
827 }
828
829 static int arith_cc(DisasContext *dc)
830 {
831     if (dc->update_cc) {
832         switch (dc->cc_op) {
833         case CC_OP_ADDC: return 1;
834         case CC_OP_ADD: return 1;
835         case CC_OP_SUB: return 1;
836         case CC_OP_DSTEP: return 1;
837         case CC_OP_LSL: return 1;
838         case CC_OP_LSR: return 1;
839         case CC_OP_ASR: return 1;
840         case CC_OP_CMP: return 1;
841         case CC_OP_NEG: return 1;
842         case CC_OP_OR: return 1;
843         case CC_OP_AND: return 1;
844         case CC_OP_XOR: return 1;
845         case CC_OP_MULU: return 1;
846         case CC_OP_MULS: return 1;
847         default:
848             return 0;
849         }
850     }
851     return 0;
852 }
853
854 static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
855 {
856     int arith_opt, move_opt;
857
858     /* TODO: optimize more condition codes.  */
859
860     /*
861      * If the flags are live, we've gotta look into the bits of CCS.
862      * Otherwise, if we just did an arithmetic operation we try to
863      * evaluate the condition code faster.
864      *
865      * When this function is done, T0 should be non-zero if the condition
866      * code is true.
867      */
868     arith_opt = arith_cc(dc) && !dc->flags_uptodate;
869     move_opt = (dc->cc_op == CC_OP_MOVE);
870     switch (cond) {
871     case CC_EQ:
872         if ((arith_opt || move_opt)
873                 && dc->cc_x_uptodate != (2 | X_FLAG)) {
874             tcg_gen_setcond_tl(TCG_COND_EQ, cc,
875                     cc_result, tcg_const_tl(0));
876         } else {
877             cris_evaluate_flags(dc);
878             tcg_gen_andi_tl(cc,
879                     cpu_PR[PR_CCS], Z_FLAG);
880         }
881         break;
882     case CC_NE:
883         if ((arith_opt || move_opt)
884                 && dc->cc_x_uptodate != (2 | X_FLAG)) {
885             tcg_gen_mov_tl(cc, cc_result);
886         } else {
887             cris_evaluate_flags(dc);
888             tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
889                     Z_FLAG);
890             tcg_gen_andi_tl(cc, cc, Z_FLAG);
891         }
892         break;
893     case CC_CS:
894         cris_evaluate_flags(dc);
895         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
896         break;
897     case CC_CC:
898         cris_evaluate_flags(dc);
899         tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
900         tcg_gen_andi_tl(cc, cc, C_FLAG);
901         break;
902     case CC_VS:
903         cris_evaluate_flags(dc);
904         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
905         break;
906     case CC_VC:
907         cris_evaluate_flags(dc);
908         tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
909                 V_FLAG);
910         tcg_gen_andi_tl(cc, cc, V_FLAG);
911         break;
912     case CC_PL:
913         if (arith_opt || move_opt) {
914             int bits = 31;
915
916             if (dc->cc_size == 1) {
917                 bits = 7;
918             } else if (dc->cc_size == 2) {
919                 bits = 15;
920             }
921
922             tcg_gen_shri_tl(cc, cc_result, bits);
923             tcg_gen_xori_tl(cc, cc, 1);
924         } else {
925             cris_evaluate_flags(dc);
926             tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
927                     N_FLAG);
928             tcg_gen_andi_tl(cc, cc, N_FLAG);
929         }
930         break;
931     case CC_MI:
932         if (arith_opt || move_opt) {
933             int bits = 31;
934
935             if (dc->cc_size == 1) {
936                 bits = 7;
937             } else if (dc->cc_size == 2) {
938                 bits = 15;
939             }
940
941             tcg_gen_shri_tl(cc, cc_result, bits);
942             tcg_gen_andi_tl(cc, cc, 1);
943         } else {
944             cris_evaluate_flags(dc);
945             tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
946                     N_FLAG);
947         }
948         break;
949     case CC_LS:
950         cris_evaluate_flags(dc);
951         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
952                 C_FLAG | Z_FLAG);
953         break;
954     case CC_HI:
955         cris_evaluate_flags(dc);
956         {
957             TCGv tmp;
958
959             tmp = tcg_temp_new();
960             tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
961                     C_FLAG | Z_FLAG);
962             /* Overlay the C flag on top of the Z.  */
963             tcg_gen_shli_tl(cc, tmp, 2);
964             tcg_gen_and_tl(cc, tmp, cc);
965             tcg_gen_andi_tl(cc, cc, Z_FLAG);
966
967             tcg_temp_free(tmp);
968         }
969         break;
970     case CC_GE:
971         cris_evaluate_flags(dc);
972         /* Overlay the V flag on top of the N.  */
973         tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
974         tcg_gen_xor_tl(cc,
975                 cpu_PR[PR_CCS], cc);
976         tcg_gen_andi_tl(cc, cc, N_FLAG);
977         tcg_gen_xori_tl(cc, cc, N_FLAG);
978         break;
979     case CC_LT:
980         cris_evaluate_flags(dc);
981         /* Overlay the V flag on top of the N.  */
982         tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
983         tcg_gen_xor_tl(cc,
984                 cpu_PR[PR_CCS], cc);
985         tcg_gen_andi_tl(cc, cc, N_FLAG);
986         break;
987     case CC_GT:
988         cris_evaluate_flags(dc);
989         {
990             TCGv n, z;
991
992             n = tcg_temp_new();
993             z = tcg_temp_new();
994
995             /* To avoid a shift we overlay everything on
996                    the V flag.  */
997             tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
998             tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
999             /* invert Z.  */
1000             tcg_gen_xori_tl(z, z, 2);
1001
1002             tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1003             tcg_gen_xori_tl(n, n, 2);
1004             tcg_gen_and_tl(cc, z, n);
1005             tcg_gen_andi_tl(cc, cc, 2);
1006
1007             tcg_temp_free(n);
1008             tcg_temp_free(z);
1009         }
1010         break;
1011     case CC_LE:
1012         cris_evaluate_flags(dc);
1013         {
1014             TCGv n, z;
1015
1016             n = tcg_temp_new();
1017             z = tcg_temp_new();
1018
1019             /* To avoid a shift we overlay everything on
1020                    the V flag.  */
1021             tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1022             tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1023
1024             tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1025             tcg_gen_or_tl(cc, z, n);
1026             tcg_gen_andi_tl(cc, cc, 2);
1027
1028             tcg_temp_free(n);
1029             tcg_temp_free(z);
1030         }
1031         break;
1032     case CC_P:
1033         cris_evaluate_flags(dc);
1034         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1035         break;
1036     case CC_A:
1037         tcg_gen_movi_tl(cc, 1);
1038         break;
1039     default:
1040         BUG();
1041         break;
1042     };
1043 }
1044
1045 static void cris_store_direct_jmp(DisasContext *dc)
1046 {
1047     /* Store the direct jmp state into the cpu-state.  */
1048     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1049         if (dc->jmp == JMP_DIRECT) {
1050             tcg_gen_movi_tl(env_btaken, 1);
1051         }
1052         tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1053         dc->jmp = JMP_INDIRECT;
1054     }
1055 }
1056
1057 static void cris_prepare_cc_branch (DisasContext *dc, 
1058                     int offset, int cond)
1059 {
1060     /* This helps us re-schedule the micro-code to insns in delay-slots
1061        before the actual jump.  */
1062     dc->delayed_branch = 2;
1063     dc->jmp = JMP_DIRECT_CC;
1064     dc->jmp_pc = dc->pc + offset;
1065
1066     gen_tst_cc(dc, env_btaken, cond);
1067     tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1068 }
1069
1070
1071 /* jumps, when the dest is in a live reg for example. Direct should be set
1072    when the dest addr is constant to allow tb chaining.  */
1073 static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1074 {
1075     /* This helps us re-schedule the micro-code to insns in delay-slots
1076        before the actual jump.  */
1077     dc->delayed_branch = 2;
1078     dc->jmp = type;
1079     if (type == JMP_INDIRECT) {
1080         tcg_gen_movi_tl(env_btaken, 1);
1081     }
1082 }
1083
1084 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1085 {
1086     int mem_index = cpu_mmu_index(&dc->cpu->env, false);
1087
1088     /* If we get a fault on a delayslot we must keep the jmp state in
1089        the cpu-state to be able to re-execute the jmp.  */
1090     if (dc->delayed_branch == 1) {
1091         cris_store_direct_jmp(dc);
1092     }
1093
1094     tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEQ);
1095 }
1096
1097 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1098              unsigned int size, int sign)
1099 {
1100     int mem_index = cpu_mmu_index(&dc->cpu->env, false);
1101
1102     /* If we get a fault on a delayslot we must keep the jmp state in
1103        the cpu-state to be able to re-execute the jmp.  */
1104     if (dc->delayed_branch == 1) {
1105         cris_store_direct_jmp(dc);
1106     }
1107
1108     tcg_gen_qemu_ld_tl(dst, addr, mem_index,
1109                        MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
1110 }
1111
1112 static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1113                unsigned int size)
1114 {
1115     int mem_index = cpu_mmu_index(&dc->cpu->env, false);
1116
1117     /* If we get a fault on a delayslot we must keep the jmp state in
1118        the cpu-state to be able to re-execute the jmp.  */
1119     if (dc->delayed_branch == 1) {
1120         cris_store_direct_jmp(dc);
1121     }
1122
1123
1124     /* Conditional writes. We only support the kind were X and P are known
1125        at translation time.  */
1126     if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1127         dc->postinc = 0;
1128         cris_evaluate_flags(dc);
1129         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1130         return;
1131     }
1132
1133     tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
1134
1135     if (dc->flagx_known && dc->flags_x) {
1136         cris_evaluate_flags(dc);
1137         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1138     }
1139 }
1140
1141 static inline void t_gen_sext(TCGv d, TCGv s, int size)
1142 {
1143     if (size == 1) {
1144         tcg_gen_ext8s_i32(d, s);
1145     } else if (size == 2) {
1146         tcg_gen_ext16s_i32(d, s);
1147     } else if (!TCGV_EQUAL(d, s)) {
1148         tcg_gen_mov_tl(d, s);
1149     }
1150 }
1151
1152 static inline void t_gen_zext(TCGv d, TCGv s, int size)
1153 {
1154     if (size == 1) {
1155         tcg_gen_ext8u_i32(d, s);
1156     } else if (size == 2) {
1157         tcg_gen_ext16u_i32(d, s);
1158     } else if (!TCGV_EQUAL(d, s)) {
1159         tcg_gen_mov_tl(d, s);
1160     }
1161 }
1162
1163 #if DISAS_CRIS
1164 static char memsize_char(int size)
1165 {
1166     switch (size) {
1167     case 1: return 'b';  break;
1168     case 2: return 'w';  break;
1169     case 4: return 'd';  break;
1170     default:
1171         return 'x';
1172         break;
1173     }
1174 }
1175 #endif
1176
1177 static inline unsigned int memsize_z(DisasContext *dc)
1178 {
1179     return dc->zsize + 1;
1180 }
1181
1182 static inline unsigned int memsize_zz(DisasContext *dc)
1183 {
1184     switch (dc->zzsize) {
1185     case 0: return 1;
1186     case 1: return 2;
1187     default:
1188         return 4;
1189     }
1190 }
1191
1192 static inline void do_postinc (DisasContext *dc, int size)
1193 {
1194     if (dc->postinc) {
1195         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1196     }
1197 }
1198
1199 static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1200                    int size, int s_ext, TCGv dst)
1201 {
1202     if (s_ext) {
1203         t_gen_sext(dst, cpu_R[rs], size);
1204     } else {
1205         t_gen_zext(dst, cpu_R[rs], size);
1206     }
1207 }
1208
1209 /* Prepare T0 and T1 for a register alu operation.
1210    s_ext decides if the operand1 should be sign-extended or zero-extended when
1211    needed.  */
1212 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1213               int size, int s_ext, TCGv dst, TCGv src)
1214 {
1215     dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1216
1217     if (s_ext) {
1218         t_gen_sext(dst, cpu_R[rd], size);
1219     } else {
1220         t_gen_zext(dst, cpu_R[rd], size);
1221     }
1222 }
1223
1224 static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1225                            int s_ext, int memsize, TCGv dst)
1226 {
1227     unsigned int rs;
1228     uint32_t imm;
1229     int is_imm;
1230     int insn_len = 2;
1231
1232     rs = dc->op1;
1233     is_imm = rs == 15 && dc->postinc;
1234
1235     /* Load [$rs] onto T1.  */
1236     if (is_imm) {
1237         insn_len = 2 + memsize;
1238         if (memsize == 1) {
1239             insn_len++;
1240         }
1241
1242         imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1243         tcg_gen_movi_tl(dst, imm);
1244         dc->postinc = 0;
1245     } else {
1246         cris_flush_cc_state(dc);
1247         gen_load(dc, dst, cpu_R[rs], memsize, 0);
1248         if (s_ext) {
1249             t_gen_sext(dst, dst, memsize);
1250         } else {
1251             t_gen_zext(dst, dst, memsize);
1252         }
1253     }
1254     return insn_len;
1255 }
1256
1257 /* Prepare T0 and T1 for a memory + alu operation.
1258    s_ext decides if the operand1 should be sign-extended or zero-extended when
1259    needed.  */
1260 static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1261                           int s_ext, int memsize, TCGv dst, TCGv src)
1262 {
1263     int insn_len;
1264
1265     insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1266     tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1267     return insn_len;
1268 }
1269
1270 #if DISAS_CRIS
1271 static const char *cc_name(int cc)
1272 {
1273     static const char *cc_names[16] = {
1274         "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1275         "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1276     };
1277     assert(cc < 16);
1278     return cc_names[cc];
1279 }
1280 #endif
1281
1282 /* Start of insn decoders.  */
1283
1284 static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1285 {
1286     int32_t offset;
1287     int sign;
1288     uint32_t cond = dc->op2;
1289
1290     offset = EXTRACT_FIELD(dc->ir, 1, 7);
1291     sign = EXTRACT_FIELD(dc->ir, 0, 0);
1292
1293     offset *= 2;
1294     offset |= sign << 8;
1295     offset = sign_extend(offset, 8);
1296
1297     LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1298
1299     /* op2 holds the condition-code.  */
1300     cris_cc_mask(dc, 0);
1301     cris_prepare_cc_branch(dc, offset, cond);
1302     return 2;
1303 }
1304 static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1305 {
1306     int32_t imm;
1307
1308     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1309     imm = sign_extend(dc->op1, 7);
1310
1311     LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1312     cris_cc_mask(dc, 0);
1313     /* Fetch register operand,  */
1314     tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1315
1316     return 2;
1317 }
1318 static int dec_addq(CPUCRISState *env, DisasContext *dc)
1319 {
1320     LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1321
1322     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1323
1324     cris_cc_mask(dc, CC_MASK_NZVC);
1325
1326     cris_alu(dc, CC_OP_ADD,
1327             cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1328     return 2;
1329 }
1330 static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1331 {
1332     uint32_t imm;
1333
1334     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1335     imm = sign_extend(dc->op1, 5);
1336     LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1337
1338     tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1339     return 2;
1340 }
1341 static int dec_subq(CPUCRISState *env, DisasContext *dc)
1342 {
1343     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1344
1345     LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1346
1347     cris_cc_mask(dc, CC_MASK_NZVC);
1348     cris_alu(dc, CC_OP_SUB,
1349             cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1350     return 2;
1351 }
1352 static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1353 {
1354     uint32_t imm;
1355     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1356     imm = sign_extend(dc->op1, 5);
1357
1358     LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1359     cris_cc_mask(dc, CC_MASK_NZVC);
1360
1361     cris_alu(dc, CC_OP_CMP,
1362             cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1363     return 2;
1364 }
1365 static int dec_andq(CPUCRISState *env, DisasContext *dc)
1366 {
1367     uint32_t imm;
1368     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1369     imm = sign_extend(dc->op1, 5);
1370
1371     LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1372     cris_cc_mask(dc, CC_MASK_NZ);
1373
1374     cris_alu(dc, CC_OP_AND,
1375             cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1376     return 2;
1377 }
1378 static int dec_orq(CPUCRISState *env, DisasContext *dc)
1379 {
1380     uint32_t imm;
1381     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1382     imm = sign_extend(dc->op1, 5);
1383     LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1384     cris_cc_mask(dc, CC_MASK_NZ);
1385
1386     cris_alu(dc, CC_OP_OR,
1387             cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1388     return 2;
1389 }
1390 static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1391 {
1392     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1393     LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1394
1395     cris_cc_mask(dc, CC_MASK_NZ);
1396     cris_evaluate_flags(dc);
1397         gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1398             tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1399     cris_alu(dc, CC_OP_MOVE,
1400          cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1401     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1402     dc->flags_uptodate = 1;
1403     return 2;
1404 }
1405 static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1406 {
1407     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1408     LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1409     cris_cc_mask(dc, CC_MASK_NZ);
1410
1411     tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1412     cris_alu(dc, CC_OP_MOVE,
1413             cpu_R[dc->op2],
1414             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1415     return 2;
1416 }
1417 static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1418 {
1419     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1420     LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1421
1422     cris_cc_mask(dc, CC_MASK_NZ);
1423
1424     tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1425
1426     cris_alu(dc, CC_OP_MOVE,
1427             cpu_R[dc->op2],
1428             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1429     return 2;
1430 }
1431 static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1432 {
1433     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1434     LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1435
1436     cris_cc_mask(dc, CC_MASK_NZ);
1437
1438     tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1439     cris_alu(dc, CC_OP_MOVE,
1440             cpu_R[dc->op2],
1441             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1442     return 2;
1443 }
1444
1445 static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1446 {
1447     int size = memsize_zz(dc);
1448
1449     LOG_DIS("move.%c $r%u, $r%u\n",
1450             memsize_char(size), dc->op1, dc->op2);
1451
1452     cris_cc_mask(dc, CC_MASK_NZ);
1453     if (size == 4) {
1454         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1455         cris_cc_mask(dc, CC_MASK_NZ);
1456         cris_update_cc_op(dc, CC_OP_MOVE, 4);
1457         cris_update_cc_x(dc);
1458         cris_update_result(dc, cpu_R[dc->op2]);
1459     } else {
1460         TCGv t0;
1461
1462         t0 = tcg_temp_new();
1463         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1464         cris_alu(dc, CC_OP_MOVE,
1465              cpu_R[dc->op2],
1466              cpu_R[dc->op2], t0, size);
1467         tcg_temp_free(t0);
1468     }
1469     return 2;
1470 }
1471
1472 static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1473 {
1474     int cond = dc->op2;
1475
1476     LOG_DIS("s%s $r%u\n",
1477             cc_name(cond), dc->op1);
1478
1479     gen_tst_cc(dc, cpu_R[dc->op1], cond);
1480     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0);
1481
1482     cris_cc_mask(dc, 0);
1483     return 2;
1484 }
1485
1486 static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1487 {
1488     if (size == 4) {
1489         t[0] = cpu_R[dc->op2];
1490         t[1] = cpu_R[dc->op1];
1491     } else {
1492         t[0] = tcg_temp_new();
1493         t[1] = tcg_temp_new();
1494     }
1495 }
1496
1497 static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1498 {
1499     if (size != 4) {
1500         tcg_temp_free(t[0]);
1501         tcg_temp_free(t[1]);
1502     }
1503 }
1504
1505 static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1506 {
1507     TCGv t[2];
1508     int size = memsize_zz(dc);
1509
1510     LOG_DIS("and.%c $r%u, $r%u\n",
1511             memsize_char(size), dc->op1, dc->op2);
1512
1513     cris_cc_mask(dc, CC_MASK_NZ);
1514
1515     cris_alu_alloc_temps(dc, size, t);
1516     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1517     cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1518     cris_alu_free_temps(dc, size, t);
1519     return 2;
1520 }
1521
1522 static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1523 {
1524     TCGv t0;
1525     LOG_DIS("lz $r%u, $r%u\n",
1526             dc->op1, dc->op2);
1527     cris_cc_mask(dc, CC_MASK_NZ);
1528     t0 = tcg_temp_new();
1529     dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1530     cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1531     tcg_temp_free(t0);
1532     return 2;
1533 }
1534
1535 static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1536 {
1537     TCGv t[2];
1538     int size = memsize_zz(dc);
1539
1540     LOG_DIS("lsl.%c $r%u, $r%u\n",
1541             memsize_char(size), dc->op1, dc->op2);
1542
1543     cris_cc_mask(dc, CC_MASK_NZ);
1544     cris_alu_alloc_temps(dc, size, t);
1545     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1546     tcg_gen_andi_tl(t[1], t[1], 63);
1547     cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1548     cris_alu_alloc_temps(dc, size, t);
1549     return 2;
1550 }
1551
1552 static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1553 {
1554     TCGv t[2];
1555     int size = memsize_zz(dc);
1556
1557     LOG_DIS("lsr.%c $r%u, $r%u\n",
1558             memsize_char(size), dc->op1, dc->op2);
1559
1560     cris_cc_mask(dc, CC_MASK_NZ);
1561     cris_alu_alloc_temps(dc, size, t);
1562     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1563     tcg_gen_andi_tl(t[1], t[1], 63);
1564     cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1565     cris_alu_free_temps(dc, size, t);
1566     return 2;
1567 }
1568
1569 static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1570 {
1571     TCGv t[2];
1572     int size = memsize_zz(dc);
1573
1574     LOG_DIS("asr.%c $r%u, $r%u\n",
1575             memsize_char(size), dc->op1, dc->op2);
1576
1577     cris_cc_mask(dc, CC_MASK_NZ);
1578     cris_alu_alloc_temps(dc, size, t);
1579     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1580     tcg_gen_andi_tl(t[1], t[1], 63);
1581     cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1582     cris_alu_free_temps(dc, size, t);
1583     return 2;
1584 }
1585
1586 static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1587 {
1588     TCGv t[2];
1589     int size = memsize_zz(dc);
1590
1591     LOG_DIS("muls.%c $r%u, $r%u\n",
1592             memsize_char(size), dc->op1, dc->op2);
1593     cris_cc_mask(dc, CC_MASK_NZV);
1594     cris_alu_alloc_temps(dc, size, t);
1595     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1596
1597     cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1598     cris_alu_free_temps(dc, size, t);
1599     return 2;
1600 }
1601
1602 static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1603 {
1604     TCGv t[2];
1605     int size = memsize_zz(dc);
1606
1607     LOG_DIS("mulu.%c $r%u, $r%u\n",
1608             memsize_char(size), dc->op1, dc->op2);
1609     cris_cc_mask(dc, CC_MASK_NZV);
1610     cris_alu_alloc_temps(dc, size, t);
1611     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1612
1613     cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1614     cris_alu_alloc_temps(dc, size, t);
1615     return 2;
1616 }
1617
1618
1619 static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1620 {
1621     LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1622     cris_cc_mask(dc, CC_MASK_NZ);
1623     cris_alu(dc, CC_OP_DSTEP,
1624             cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1625     return 2;
1626 }
1627
1628 static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1629 {
1630     TCGv t[2];
1631     int size = memsize_zz(dc);
1632     LOG_DIS("xor.%c $r%u, $r%u\n",
1633             memsize_char(size), dc->op1, dc->op2);
1634     BUG_ON(size != 4); /* xor is dword.  */
1635     cris_cc_mask(dc, CC_MASK_NZ);
1636     cris_alu_alloc_temps(dc, size, t);
1637     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1638
1639     cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1640     cris_alu_free_temps(dc, size, t);
1641     return 2;
1642 }
1643
1644 static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1645 {
1646     TCGv l0;
1647     int size = memsize_zz(dc);
1648     LOG_DIS("bound.%c $r%u, $r%u\n",
1649             memsize_char(size), dc->op1, dc->op2);
1650     cris_cc_mask(dc, CC_MASK_NZ);
1651     l0 = tcg_temp_local_new();
1652     dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1653     cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1654     tcg_temp_free(l0);
1655     return 2;
1656 }
1657
1658 static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1659 {
1660     TCGv t[2];
1661     int size = memsize_zz(dc);
1662     LOG_DIS("cmp.%c $r%u, $r%u\n",
1663             memsize_char(size), dc->op1, dc->op2);
1664     cris_cc_mask(dc, CC_MASK_NZVC);
1665     cris_alu_alloc_temps(dc, size, t);
1666     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1667
1668     cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1669     cris_alu_free_temps(dc, size, t);
1670     return 2;
1671 }
1672
1673 static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1674 {
1675     TCGv t0;
1676
1677     LOG_DIS("abs $r%u, $r%u\n",
1678             dc->op1, dc->op2);
1679     cris_cc_mask(dc, CC_MASK_NZ);
1680
1681     t0 = tcg_temp_new();
1682     tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1683     tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1684     tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1685     tcg_temp_free(t0);
1686
1687     cris_alu(dc, CC_OP_MOVE,
1688             cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1689     return 2;
1690 }
1691
1692 static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1693 {
1694     TCGv t[2];
1695     int size = memsize_zz(dc);
1696     LOG_DIS("add.%c $r%u, $r%u\n",
1697             memsize_char(size), dc->op1, dc->op2);
1698     cris_cc_mask(dc, CC_MASK_NZVC);
1699     cris_alu_alloc_temps(dc, size, t);
1700     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1701
1702     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1703     cris_alu_free_temps(dc, size, t);
1704     return 2;
1705 }
1706
1707 static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1708 {
1709     LOG_DIS("addc $r%u, $r%u\n",
1710             dc->op1, dc->op2);
1711     cris_evaluate_flags(dc);
1712     /* Set for this insn.  */
1713     dc->flagx_known = 1;
1714     dc->flags_x = X_FLAG;
1715
1716     cris_cc_mask(dc, CC_MASK_NZVC);
1717     cris_alu(dc, CC_OP_ADDC,
1718          cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1719     return 2;
1720 }
1721
1722 static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1723 {
1724     LOG_DIS("mcp $p%u, $r%u\n",
1725              dc->op2, dc->op1);
1726     cris_evaluate_flags(dc);
1727     cris_cc_mask(dc, CC_MASK_RNZV);
1728     cris_alu(dc, CC_OP_MCP,
1729             cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1730     return 2;
1731 }
1732
1733 #if DISAS_CRIS
1734 static char * swapmode_name(int mode, char *modename) {
1735     int i = 0;
1736     if (mode & 8) {
1737         modename[i++] = 'n';
1738     }
1739     if (mode & 4) {
1740         modename[i++] = 'w';
1741     }
1742     if (mode & 2) {
1743         modename[i++] = 'b';
1744     }
1745     if (mode & 1) {
1746         modename[i++] = 'r';
1747     }
1748     modename[i++] = 0;
1749     return modename;
1750 }
1751 #endif
1752
1753 static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1754 {
1755     TCGv t0;
1756 #if DISAS_CRIS
1757     char modename[4];
1758 #endif
1759     LOG_DIS("swap%s $r%u\n",
1760              swapmode_name(dc->op2, modename), dc->op1);
1761
1762     cris_cc_mask(dc, CC_MASK_NZ);
1763     t0 = tcg_temp_new();
1764     tcg_gen_mov_tl(t0, cpu_R[dc->op1]);
1765     if (dc->op2 & 8) {
1766         tcg_gen_not_tl(t0, t0);
1767     }
1768     if (dc->op2 & 4) {
1769         t_gen_swapw(t0, t0);
1770     }
1771     if (dc->op2 & 2) {
1772         t_gen_swapb(t0, t0);
1773     }
1774     if (dc->op2 & 1) {
1775         t_gen_swapr(t0, t0);
1776     }
1777     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1778     tcg_temp_free(t0);
1779     return 2;
1780 }
1781
1782 static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1783 {
1784     TCGv t[2];
1785     int size = memsize_zz(dc);
1786     LOG_DIS("or.%c $r%u, $r%u\n",
1787             memsize_char(size), dc->op1, dc->op2);
1788     cris_cc_mask(dc, CC_MASK_NZ);
1789     cris_alu_alloc_temps(dc, size, t);
1790     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1791     cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1792     cris_alu_free_temps(dc, size, t);
1793     return 2;
1794 }
1795
1796 static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1797 {
1798     TCGv t0;
1799     LOG_DIS("addi.%c $r%u, $r%u\n",
1800             memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1801     cris_cc_mask(dc, 0);
1802     t0 = tcg_temp_new();
1803     tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1804     tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1805     tcg_temp_free(t0);
1806     return 2;
1807 }
1808
1809 static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1810 {
1811     TCGv t0;
1812     LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1813           memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1814     cris_cc_mask(dc, 0);
1815     t0 = tcg_temp_new();
1816     tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1817     tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1818     tcg_temp_free(t0);
1819     return 2;
1820 }
1821
1822 static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1823 {
1824     TCGv t[2];
1825     int size = memsize_zz(dc);
1826     LOG_DIS("neg.%c $r%u, $r%u\n",
1827             memsize_char(size), dc->op1, dc->op2);
1828     cris_cc_mask(dc, CC_MASK_NZVC);
1829     cris_alu_alloc_temps(dc, size, t);
1830     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1831
1832     cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1833     cris_alu_free_temps(dc, size, t);
1834     return 2;
1835 }
1836
1837 static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1838 {
1839     LOG_DIS("btst $r%u, $r%u\n",
1840             dc->op1, dc->op2);
1841     cris_cc_mask(dc, CC_MASK_NZ);
1842     cris_evaluate_flags(dc);
1843         gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1844             cpu_R[dc->op1], cpu_PR[PR_CCS]);
1845     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1846          cpu_R[dc->op2], cpu_R[dc->op2], 4);
1847     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1848     dc->flags_uptodate = 1;
1849     return 2;
1850 }
1851
1852 static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1853 {
1854     TCGv t[2];
1855     int size = memsize_zz(dc);
1856     LOG_DIS("sub.%c $r%u, $r%u\n",
1857             memsize_char(size), dc->op1, dc->op2);
1858     cris_cc_mask(dc, CC_MASK_NZVC);
1859     cris_alu_alloc_temps(dc, size, t);
1860     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1861     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1862     cris_alu_free_temps(dc, size, t);
1863     return 2;
1864 }
1865
1866 /* Zero extension. From size to dword.  */
1867 static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1868 {
1869     TCGv t0;
1870     int size = memsize_z(dc);
1871     LOG_DIS("movu.%c $r%u, $r%u\n",
1872             memsize_char(size),
1873             dc->op1, dc->op2);
1874
1875     cris_cc_mask(dc, CC_MASK_NZ);
1876     t0 = tcg_temp_new();
1877     dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1878     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1879     tcg_temp_free(t0);
1880     return 2;
1881 }
1882
1883 /* Sign extension. From size to dword.  */
1884 static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1885 {
1886     TCGv t0;
1887     int size = memsize_z(dc);
1888     LOG_DIS("movs.%c $r%u, $r%u\n",
1889             memsize_char(size),
1890             dc->op1, dc->op2);
1891
1892     cris_cc_mask(dc, CC_MASK_NZ);
1893     t0 = tcg_temp_new();
1894     /* Size can only be qi or hi.  */
1895     t_gen_sext(t0, cpu_R[dc->op1], size);
1896     cris_alu(dc, CC_OP_MOVE,
1897             cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1898     tcg_temp_free(t0);
1899     return 2;
1900 }
1901
1902 /* zero extension. From size to dword.  */
1903 static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
1904 {
1905     TCGv t0;
1906     int size = memsize_z(dc);
1907     LOG_DIS("addu.%c $r%u, $r%u\n",
1908             memsize_char(size),
1909             dc->op1, dc->op2);
1910
1911     cris_cc_mask(dc, CC_MASK_NZVC);
1912     t0 = tcg_temp_new();
1913     /* Size can only be qi or hi.  */
1914     t_gen_zext(t0, cpu_R[dc->op1], size);
1915     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1916     tcg_temp_free(t0);
1917     return 2;
1918 }
1919
1920 /* Sign extension. From size to dword.  */
1921 static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1922 {
1923     TCGv t0;
1924     int size = memsize_z(dc);
1925     LOG_DIS("adds.%c $r%u, $r%u\n",
1926             memsize_char(size),
1927             dc->op1, dc->op2);
1928
1929     cris_cc_mask(dc, CC_MASK_NZVC);
1930     t0 = tcg_temp_new();
1931     /* Size can only be qi or hi.  */
1932     t_gen_sext(t0, cpu_R[dc->op1], size);
1933     cris_alu(dc, CC_OP_ADD,
1934             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1935     tcg_temp_free(t0);
1936     return 2;
1937 }
1938
1939 /* Zero extension. From size to dword.  */
1940 static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
1941 {
1942     TCGv t0;
1943     int size = memsize_z(dc);
1944     LOG_DIS("subu.%c $r%u, $r%u\n",
1945             memsize_char(size),
1946             dc->op1, dc->op2);
1947
1948     cris_cc_mask(dc, CC_MASK_NZVC);
1949     t0 = tcg_temp_new();
1950     /* Size can only be qi or hi.  */
1951     t_gen_zext(t0, cpu_R[dc->op1], size);
1952     cris_alu(dc, CC_OP_SUB,
1953             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1954     tcg_temp_free(t0);
1955     return 2;
1956 }
1957
1958 /* Sign extension. From size to dword.  */
1959 static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
1960 {
1961     TCGv t0;
1962     int size = memsize_z(dc);
1963     LOG_DIS("subs.%c $r%u, $r%u\n",
1964             memsize_char(size),
1965             dc->op1, dc->op2);
1966
1967     cris_cc_mask(dc, CC_MASK_NZVC);
1968     t0 = tcg_temp_new();
1969     /* Size can only be qi or hi.  */
1970     t_gen_sext(t0, cpu_R[dc->op1], size);
1971     cris_alu(dc, CC_OP_SUB,
1972             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1973     tcg_temp_free(t0);
1974     return 2;
1975 }
1976
1977 static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
1978 {
1979     uint32_t flags;
1980     int set = (~dc->opcode >> 2) & 1;
1981
1982
1983     flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1984         | EXTRACT_FIELD(dc->ir, 0, 3);
1985     if (set && flags == 0) {
1986         LOG_DIS("nop\n");
1987         return 2;
1988     } else if (!set && (flags & 0x20)) {
1989         LOG_DIS("di\n");
1990     } else {
1991         LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
1992     }
1993
1994     /* User space is not allowed to touch these. Silently ignore.  */
1995     if (dc->tb_flags & U_FLAG) {
1996         flags &= ~(S_FLAG | I_FLAG | U_FLAG);
1997     }
1998
1999     if (flags & X_FLAG) {
2000         dc->flagx_known = 1;
2001         if (set) {
2002             dc->flags_x = X_FLAG;
2003         } else {
2004             dc->flags_x = 0;
2005         }
2006     }
2007
2008     /* Break the TB if any of the SPI flag changes.  */
2009     if (flags & (P_FLAG | S_FLAG)) {
2010         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2011         dc->is_jmp = DISAS_UPDATE;
2012         dc->cpustate_changed = 1;
2013     }
2014
2015     /* For the I flag, only act on posedge.  */
2016     if ((flags & I_FLAG)) {
2017         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2018         dc->is_jmp = DISAS_UPDATE;
2019         dc->cpustate_changed = 1;
2020     }
2021
2022
2023     /* Simply decode the flags.  */
2024     cris_evaluate_flags(dc);
2025     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2026     cris_update_cc_x(dc);
2027     tcg_gen_movi_tl(cc_op, dc->cc_op);
2028
2029     if (set) {
2030         if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2031             /* Enter user mode.  */
2032             t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2033             tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2034             dc->cpustate_changed = 1;
2035         }
2036         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2037     } else {
2038         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2039     }
2040
2041     dc->flags_uptodate = 1;
2042     dc->clear_x = 0;
2043     return 2;
2044 }
2045
2046 static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
2047 {
2048     LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2049     cris_cc_mask(dc, 0);
2050         gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
2051                                  tcg_const_tl(dc->op1));
2052     return 2;
2053 }
2054 static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
2055 {
2056     LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2057     cris_cc_mask(dc, 0);
2058         gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
2059                                  tcg_const_tl(dc->op2));
2060     return 2;
2061 }
2062
2063 static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
2064 {
2065     TCGv t[2];
2066     LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2067     cris_cc_mask(dc, 0);
2068
2069     t[0] = tcg_temp_new();
2070     if (dc->op2 == PR_CCS) {
2071         cris_evaluate_flags(dc);
2072         tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
2073         if (dc->tb_flags & U_FLAG) {
2074             t[1] = tcg_temp_new();
2075             /* User space is not allowed to touch all flags.  */
2076             tcg_gen_andi_tl(t[0], t[0], 0x39f);
2077             tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2078             tcg_gen_or_tl(t[0], t[1], t[0]);
2079             tcg_temp_free(t[1]);
2080         }
2081     } else {
2082         tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
2083     }
2084
2085     t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2086     if (dc->op2 == PR_CCS) {
2087         cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2088         dc->flags_uptodate = 1;
2089     }
2090     tcg_temp_free(t[0]);
2091     return 2;
2092 }
2093 static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
2094 {
2095     TCGv t0;
2096     LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2097     cris_cc_mask(dc, 0);
2098
2099     if (dc->op2 == PR_CCS) {
2100         cris_evaluate_flags(dc);
2101     }
2102
2103     if (dc->op2 == PR_DZ) {
2104         tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2105     } else {
2106         t0 = tcg_temp_new();
2107         t_gen_mov_TN_preg(t0, dc->op2);
2108         cris_alu(dc, CC_OP_MOVE,
2109                 cpu_R[dc->op1], cpu_R[dc->op1], t0,
2110                 preg_sizes[dc->op2]);
2111         tcg_temp_free(t0);
2112     }
2113     return 2;
2114 }
2115
2116 static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
2117 {
2118     int memsize = memsize_zz(dc);
2119     int insn_len;
2120     LOG_DIS("move.%c [$r%u%s, $r%u\n",
2121             memsize_char(memsize),
2122             dc->op1, dc->postinc ? "+]" : "]",
2123                     dc->op2);
2124
2125     if (memsize == 4) {
2126         insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2127         cris_cc_mask(dc, CC_MASK_NZ);
2128         cris_update_cc_op(dc, CC_OP_MOVE, 4);
2129         cris_update_cc_x(dc);
2130         cris_update_result(dc, cpu_R[dc->op2]);
2131     } else {
2132         TCGv t0;
2133
2134         t0 = tcg_temp_new();
2135         insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2136         cris_cc_mask(dc, CC_MASK_NZ);
2137         cris_alu(dc, CC_OP_MOVE,
2138                 cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2139         tcg_temp_free(t0);
2140     }
2141     do_postinc(dc, memsize);
2142     return insn_len;
2143 }
2144
2145 static inline void cris_alu_m_alloc_temps(TCGv *t)
2146 {
2147     t[0] = tcg_temp_new();
2148     t[1] = tcg_temp_new();
2149 }
2150
2151 static inline void cris_alu_m_free_temps(TCGv *t)
2152 {
2153     tcg_temp_free(t[0]);
2154     tcg_temp_free(t[1]);
2155 }
2156
2157 static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
2158 {
2159     TCGv t[2];
2160     int memsize = memsize_z(dc);
2161     int insn_len;
2162     LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2163             memsize_char(memsize),
2164             dc->op1, dc->postinc ? "+]" : "]",
2165             dc->op2);
2166
2167     cris_alu_m_alloc_temps(t);
2168     /* sign extend.  */
2169         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2170     cris_cc_mask(dc, CC_MASK_NZ);
2171     cris_alu(dc, CC_OP_MOVE,
2172             cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2173     do_postinc(dc, memsize);
2174     cris_alu_m_free_temps(t);
2175     return insn_len;
2176 }
2177
2178 static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
2179 {
2180     TCGv t[2];
2181     int memsize = memsize_z(dc);
2182     int insn_len;
2183     LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2184             memsize_char(memsize),
2185             dc->op1, dc->postinc ? "+]" : "]",
2186             dc->op2);
2187
2188     cris_alu_m_alloc_temps(t);
2189     /* sign extend.  */
2190         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2191     cris_cc_mask(dc, CC_MASK_NZVC);
2192     cris_alu(dc, CC_OP_ADD,
2193             cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2194     do_postinc(dc, memsize);
2195     cris_alu_m_free_temps(t);
2196     return insn_len;
2197 }
2198
2199 static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
2200 {
2201     TCGv t[2];
2202     int memsize = memsize_z(dc);
2203     int insn_len;
2204     LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2205             memsize_char(memsize),
2206             dc->op1, dc->postinc ? "+]" : "]",
2207             dc->op2);
2208
2209     cris_alu_m_alloc_temps(t);
2210     /* sign extend.  */
2211         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2212     cris_cc_mask(dc, CC_MASK_NZVC);
2213     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2214     do_postinc(dc, memsize);
2215     cris_alu_m_free_temps(t);
2216     return insn_len;
2217 }
2218
2219 static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
2220 {
2221     TCGv t[2];
2222     int memsize = memsize_z(dc);
2223     int insn_len;
2224     LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2225             memsize_char(memsize),
2226             dc->op1, dc->postinc ? "+]" : "]",
2227             dc->op2);
2228
2229     cris_alu_m_alloc_temps(t);
2230     /* sign extend.  */
2231         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2232     cris_cc_mask(dc, CC_MASK_NZVC);
2233     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2234     do_postinc(dc, memsize);
2235     cris_alu_m_free_temps(t);
2236     return insn_len;
2237 }
2238
2239 static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
2240 {
2241     TCGv t[2];
2242     int memsize = memsize_z(dc);
2243     int insn_len;
2244     LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2245             memsize_char(memsize),
2246             dc->op1, dc->postinc ? "+]" : "]",
2247             dc->op2);
2248
2249     cris_alu_m_alloc_temps(t);
2250     /* sign extend.  */
2251         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2252     cris_cc_mask(dc, CC_MASK_NZVC);
2253     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2254     do_postinc(dc, memsize);
2255     cris_alu_m_free_temps(t);
2256     return insn_len;
2257 }
2258
2259 static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2260 {
2261     TCGv t[2];
2262     int memsize = memsize_z(dc);
2263     int insn_len;
2264
2265     LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2266             memsize_char(memsize),
2267             dc->op1, dc->postinc ? "+]" : "]",
2268             dc->op2);
2269
2270     cris_alu_m_alloc_temps(t);
2271         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2272     cris_cc_mask(dc, CC_MASK_NZ);
2273     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2274     do_postinc(dc, memsize);
2275     cris_alu_m_free_temps(t);
2276     return insn_len;
2277 }
2278
2279 static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2280 {
2281     TCGv t[2];
2282     int memsize = memsize_z(dc);
2283     int insn_len;
2284     LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2285             memsize_char(memsize),
2286             dc->op1, dc->postinc ? "+]" : "]",
2287             dc->op2);
2288
2289     cris_alu_m_alloc_temps(t);
2290         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2291     cris_cc_mask(dc, CC_MASK_NZVC);
2292     cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2293     do_postinc(dc, memsize);
2294     cris_alu_m_free_temps(t);
2295     return insn_len;
2296 }
2297
2298 static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
2299 {
2300     TCGv t[2];
2301     int memsize = memsize_z(dc);
2302     int insn_len;
2303     LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2304             memsize_char(memsize),
2305             dc->op1, dc->postinc ? "+]" : "]",
2306             dc->op2);
2307
2308     cris_alu_m_alloc_temps(t);
2309         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2310     cris_cc_mask(dc, CC_MASK_NZVC);
2311     cris_alu(dc, CC_OP_CMP,
2312             cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2313             memsize_zz(dc));
2314     do_postinc(dc, memsize);
2315     cris_alu_m_free_temps(t);
2316     return insn_len;
2317 }
2318
2319 static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
2320 {
2321     TCGv t[2];
2322     int memsize = memsize_zz(dc);
2323     int insn_len;
2324     LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2325             memsize_char(memsize),
2326             dc->op1, dc->postinc ? "+]" : "]",
2327             dc->op2);
2328
2329     cris_alu_m_alloc_temps(t);
2330         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2331     cris_cc_mask(dc, CC_MASK_NZVC);
2332     cris_alu(dc, CC_OP_CMP,
2333             cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2334             memsize_zz(dc));
2335     do_postinc(dc, memsize);
2336     cris_alu_m_free_temps(t);
2337     return insn_len;
2338 }
2339
2340 static int dec_test_m(CPUCRISState *env, DisasContext *dc)
2341 {
2342     TCGv t[2];
2343     int memsize = memsize_zz(dc);
2344     int insn_len;
2345     LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2346             memsize_char(memsize),
2347             dc->op1, dc->postinc ? "+]" : "]",
2348             dc->op2);
2349
2350     cris_evaluate_flags(dc);
2351
2352     cris_alu_m_alloc_temps(t);
2353         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2354     cris_cc_mask(dc, CC_MASK_NZ);
2355     tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2356
2357     cris_alu(dc, CC_OP_CMP,
2358          cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2359     do_postinc(dc, memsize);
2360     cris_alu_m_free_temps(t);
2361     return insn_len;
2362 }
2363
2364 static int dec_and_m(CPUCRISState *env, DisasContext *dc)
2365 {
2366     TCGv t[2];
2367     int memsize = memsize_zz(dc);
2368     int insn_len;
2369     LOG_DIS("and.%c [$r%u%s, $r%u\n",
2370             memsize_char(memsize),
2371             dc->op1, dc->postinc ? "+]" : "]",
2372             dc->op2);
2373
2374     cris_alu_m_alloc_temps(t);
2375         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2376     cris_cc_mask(dc, CC_MASK_NZ);
2377     cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2378     do_postinc(dc, memsize);
2379     cris_alu_m_free_temps(t);
2380     return insn_len;
2381 }
2382
2383 static int dec_add_m(CPUCRISState *env, DisasContext *dc)
2384 {
2385     TCGv t[2];
2386     int memsize = memsize_zz(dc);
2387     int insn_len;
2388     LOG_DIS("add.%c [$r%u%s, $r%u\n",
2389             memsize_char(memsize),
2390             dc->op1, dc->postinc ? "+]" : "]",
2391             dc->op2);
2392
2393     cris_alu_m_alloc_temps(t);
2394         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2395     cris_cc_mask(dc, CC_MASK_NZVC);
2396     cris_alu(dc, CC_OP_ADD,
2397          cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2398     do_postinc(dc, memsize);
2399     cris_alu_m_free_temps(t);
2400     return insn_len;
2401 }
2402
2403 static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
2404 {
2405     TCGv t[2];
2406     int memsize = memsize_zz(dc);
2407     int insn_len;
2408     LOG_DIS("add.%c [$r%u%s, $r%u\n",
2409             memsize_char(memsize),
2410             dc->op1, dc->postinc ? "+]" : "]",
2411             dc->op2);
2412
2413     cris_alu_m_alloc_temps(t);
2414         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2415     cris_cc_mask(dc, 0);
2416     cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2417     do_postinc(dc, memsize);
2418     cris_alu_m_free_temps(t);
2419     return insn_len;
2420 }
2421
2422 static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
2423 {
2424     TCGv l[2];
2425     int memsize = memsize_zz(dc);
2426     int insn_len;
2427     LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2428             memsize_char(memsize),
2429             dc->op1, dc->postinc ? "+]" : "]",
2430             dc->op2);
2431
2432     l[0] = tcg_temp_local_new();
2433     l[1] = tcg_temp_local_new();
2434         insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2435     cris_cc_mask(dc, CC_MASK_NZ);
2436     cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2437     do_postinc(dc, memsize);
2438     tcg_temp_free(l[0]);
2439     tcg_temp_free(l[1]);
2440     return insn_len;
2441 }
2442
2443 static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2444 {
2445     TCGv t[2];
2446     int insn_len = 2;
2447     LOG_DIS("addc [$r%u%s, $r%u\n",
2448             dc->op1, dc->postinc ? "+]" : "]",
2449             dc->op2);
2450
2451     cris_evaluate_flags(dc);
2452
2453     /* Set for this insn.  */
2454     dc->flagx_known = 1;
2455     dc->flags_x = X_FLAG;
2456
2457     cris_alu_m_alloc_temps(t);
2458         insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2459     cris_cc_mask(dc, CC_MASK_NZVC);
2460     cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2461     do_postinc(dc, 4);
2462     cris_alu_m_free_temps(t);
2463     return insn_len;
2464 }
2465
2466 static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2467 {
2468     TCGv t[2];
2469     int memsize = memsize_zz(dc);
2470     int insn_len;
2471     LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2472             memsize_char(memsize),
2473             dc->op1, dc->postinc ? "+]" : "]",
2474             dc->op2, dc->ir, dc->zzsize);
2475
2476     cris_alu_m_alloc_temps(t);
2477         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2478     cris_cc_mask(dc, CC_MASK_NZVC);
2479     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2480     do_postinc(dc, memsize);
2481     cris_alu_m_free_temps(t);
2482     return insn_len;
2483 }
2484
2485 static int dec_or_m(CPUCRISState *env, DisasContext *dc)
2486 {
2487     TCGv t[2];
2488     int memsize = memsize_zz(dc);
2489     int insn_len;
2490     LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2491             memsize_char(memsize),
2492             dc->op1, dc->postinc ? "+]" : "]",
2493             dc->op2, dc->pc);
2494
2495     cris_alu_m_alloc_temps(t);
2496         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2497     cris_cc_mask(dc, CC_MASK_NZ);
2498     cris_alu(dc, CC_OP_OR,
2499             cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2500     do_postinc(dc, memsize);
2501     cris_alu_m_free_temps(t);
2502     return insn_len;
2503 }
2504
2505 static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2506 {
2507     TCGv t[2];
2508     int memsize = memsize_zz(dc);
2509     int insn_len = 2;
2510
2511     LOG_DIS("move.%c [$r%u%s, $p%u\n",
2512             memsize_char(memsize),
2513             dc->op1,
2514             dc->postinc ? "+]" : "]",
2515             dc->op2);
2516
2517     cris_alu_m_alloc_temps(t);
2518         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2519     cris_cc_mask(dc, 0);
2520     if (dc->op2 == PR_CCS) {
2521         cris_evaluate_flags(dc);
2522         if (dc->tb_flags & U_FLAG) {
2523             /* User space is not allowed to touch all flags.  */
2524             tcg_gen_andi_tl(t[1], t[1], 0x39f);
2525             tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2526             tcg_gen_or_tl(t[1], t[0], t[1]);
2527         }
2528     }
2529
2530     t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2531
2532     do_postinc(dc, memsize);
2533     cris_alu_m_free_temps(t);
2534     return insn_len;
2535 }
2536
2537 static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2538 {
2539     TCGv t0;
2540     int memsize;
2541
2542     memsize = preg_sizes[dc->op2];
2543
2544     LOG_DIS("move.%c $p%u, [$r%u%s\n",
2545             memsize_char(memsize),
2546             dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2547
2548     /* prepare store. Address in T0, value in T1.  */
2549     if (dc->op2 == PR_CCS) {
2550         cris_evaluate_flags(dc);
2551     }
2552     t0 = tcg_temp_new();
2553     t_gen_mov_TN_preg(t0, dc->op2);
2554     cris_flush_cc_state(dc);
2555     gen_store(dc, cpu_R[dc->op1], t0, memsize);
2556     tcg_temp_free(t0);
2557
2558     cris_cc_mask(dc, 0);
2559     if (dc->postinc) {
2560         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2561     }
2562     return 2;
2563 }
2564
2565 static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2566 {
2567     TCGv_i64 tmp[16];
2568     TCGv tmp32;
2569     TCGv addr;
2570     int i;
2571     int nr = dc->op2 + 1;
2572
2573     LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2574             dc->postinc ? "+]" : "]", dc->op2);
2575
2576     addr = tcg_temp_new();
2577     /* There are probably better ways of doing this.  */
2578     cris_flush_cc_state(dc);
2579     for (i = 0; i < (nr >> 1); i++) {
2580         tmp[i] = tcg_temp_new_i64();
2581         tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2582         gen_load64(dc, tmp[i], addr);
2583     }
2584     if (nr & 1) {
2585         tmp32 = tcg_temp_new_i32();
2586         tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2587         gen_load(dc, tmp32, addr, 4, 0);
2588     } else {
2589         TCGV_UNUSED(tmp32);
2590     }
2591     tcg_temp_free(addr);
2592
2593     for (i = 0; i < (nr >> 1); i++) {
2594         tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]);
2595         tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2596         tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2597         tcg_temp_free_i64(tmp[i]);
2598     }
2599     if (nr & 1) {
2600         tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2601         tcg_temp_free(tmp32);
2602     }
2603
2604     /* writeback the updated pointer value.  */
2605     if (dc->postinc) {
2606         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2607     }
2608
2609     /* gen_load might want to evaluate the previous insns flags.  */
2610     cris_cc_mask(dc, 0);
2611     return 2;
2612 }
2613
2614 static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2615 {
2616     TCGv tmp;
2617     TCGv addr;
2618     int i;
2619
2620     LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2621             dc->postinc ? "+]" : "]");
2622
2623     cris_flush_cc_state(dc);
2624
2625     tmp = tcg_temp_new();
2626     addr = tcg_temp_new();
2627     tcg_gen_movi_tl(tmp, 4);
2628     tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2629     for (i = 0; i <= dc->op2; i++) {
2630         /* Displace addr.  */
2631         /* Perform the store.  */
2632         gen_store(dc, addr, cpu_R[i], 4);
2633         tcg_gen_add_tl(addr, addr, tmp);
2634     }
2635     if (dc->postinc) {
2636         tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2637     }
2638     cris_cc_mask(dc, 0);
2639     tcg_temp_free(tmp);
2640     tcg_temp_free(addr);
2641     return 2;
2642 }
2643
2644 static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2645 {
2646     int memsize;
2647
2648     memsize = memsize_zz(dc);
2649
2650     LOG_DIS("move.%c $r%u, [$r%u]\n",
2651             memsize_char(memsize), dc->op2, dc->op1);
2652
2653     /* prepare store.  */
2654     cris_flush_cc_state(dc);
2655     gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2656
2657     if (dc->postinc) {
2658         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2659     }
2660     cris_cc_mask(dc, 0);
2661     return 2;
2662 }
2663
2664 static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2665 {
2666     LOG_DIS("lapcq %x, $r%u\n",
2667             dc->pc + dc->op1*2, dc->op2);
2668     cris_cc_mask(dc, 0);
2669     tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2670     return 2;
2671 }
2672
2673 static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2674 {
2675     unsigned int rd;
2676     int32_t imm;
2677     int32_t pc;
2678
2679     rd = dc->op2;
2680
2681     cris_cc_mask(dc, 0);
2682     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2683     LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2684
2685     pc = dc->pc;
2686     pc += imm;
2687     tcg_gen_movi_tl(cpu_R[rd], pc);
2688     return 6;
2689 }
2690
2691 /* Jump to special reg.  */
2692 static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2693 {
2694     LOG_DIS("jump $p%u\n", dc->op2);
2695
2696     if (dc->op2 == PR_CCS) {
2697         cris_evaluate_flags(dc);
2698     }
2699     t_gen_mov_TN_preg(env_btarget, dc->op2);
2700     /* rete will often have low bit set to indicate delayslot.  */
2701     tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2702     cris_cc_mask(dc, 0);
2703     cris_prepare_jmp(dc, JMP_INDIRECT);
2704     return 2;
2705 }
2706
2707 /* Jump and save.  */
2708 static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2709 {
2710     LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2711     cris_cc_mask(dc, 0);
2712     /* Store the return address in Pd.  */
2713     tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2714     if (dc->op2 > 15) {
2715         abort();
2716     }
2717     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2718
2719     cris_prepare_jmp(dc, JMP_INDIRECT);
2720     return 2;
2721 }
2722
2723 static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2724 {
2725     uint32_t imm;
2726
2727     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2728
2729     LOG_DIS("jas 0x%x\n", imm);
2730     cris_cc_mask(dc, 0);
2731     /* Store the return address in Pd.  */
2732     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2733
2734     dc->jmp_pc = imm;
2735     cris_prepare_jmp(dc, JMP_DIRECT);
2736     return 6;
2737 }
2738
2739 static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2740 {
2741     uint32_t imm;
2742
2743     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2744
2745     LOG_DIS("jasc 0x%x\n", imm);
2746     cris_cc_mask(dc, 0);
2747     /* Store the return address in Pd.  */
2748     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2749
2750     dc->jmp_pc = imm;
2751     cris_prepare_jmp(dc, JMP_DIRECT);
2752     return 6;
2753 }
2754
2755 static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2756 {
2757     LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2758     cris_cc_mask(dc, 0);
2759     /* Store the return address in Pd.  */
2760     tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2761     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2762     cris_prepare_jmp(dc, JMP_INDIRECT);
2763     return 2;
2764 }
2765
2766 static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2767 {
2768     int32_t offset;
2769     uint32_t cond = dc->op2;
2770
2771     offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2772
2773     LOG_DIS("b%s %d pc=%x dst=%x\n",
2774             cc_name(cond), offset,
2775             dc->pc, dc->pc + offset);
2776
2777     cris_cc_mask(dc, 0);
2778     /* op2 holds the condition-code.  */
2779     cris_prepare_cc_branch(dc, offset, cond);
2780     return 4;
2781 }
2782
2783 static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2784 {
2785     int32_t simm;
2786
2787     simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2788
2789     LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2790     cris_cc_mask(dc, 0);
2791     /* Store the return address in Pd.  */
2792     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2793
2794     dc->jmp_pc = dc->pc + simm;
2795     cris_prepare_jmp(dc, JMP_DIRECT);
2796     return 6;
2797 }
2798
2799 static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2800 {
2801     int32_t simm;
2802     simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2803
2804     LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2805     cris_cc_mask(dc, 0);
2806     /* Store the return address in Pd.  */
2807     t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2808
2809     dc->jmp_pc = dc->pc + simm;
2810     cris_prepare_jmp(dc, JMP_DIRECT);
2811     return 6;
2812 }
2813
2814 static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2815 {
2816     cris_cc_mask(dc, 0);
2817
2818     if (dc->op2 == 15) {
2819         tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
2820                        -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2821         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2822         t_gen_raise_exception(EXCP_HLT);
2823         return 2;
2824     }
2825
2826     switch (dc->op2 & 7) {
2827     case 2:
2828         /* rfe.  */
2829         LOG_DIS("rfe\n");
2830         cris_evaluate_flags(dc);
2831         gen_helper_rfe(cpu_env);
2832         dc->is_jmp = DISAS_UPDATE;
2833         break;
2834     case 5:
2835         /* rfn.  */
2836         LOG_DIS("rfn\n");
2837         cris_evaluate_flags(dc);
2838         gen_helper_rfn(cpu_env);
2839         dc->is_jmp = DISAS_UPDATE;
2840         break;
2841     case 6:
2842         LOG_DIS("break %d\n", dc->op1);
2843         cris_evaluate_flags(dc);
2844         /* break.  */
2845         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2846
2847         /* Breaks start at 16 in the exception vector.  */
2848         t_gen_mov_env_TN(trap_vector,
2849                 tcg_const_tl(dc->op1 + 16));
2850         t_gen_raise_exception(EXCP_BREAK);
2851         dc->is_jmp = DISAS_UPDATE;
2852         break;
2853     default:
2854         printf("op2=%x\n", dc->op2);
2855         BUG();
2856         break;
2857
2858     }
2859     return 2;
2860 }
2861
2862 static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2863 {
2864     return 2;
2865 }
2866
2867 static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2868 {
2869     return 2;
2870 }
2871
2872 static int dec_null(CPUCRISState *env, DisasContext *dc)
2873 {
2874     printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2875         dc->pc, dc->opcode, dc->op1, dc->op2);
2876     fflush(NULL);
2877     BUG();
2878     return 2;
2879 }
2880
2881 static struct decoder_info {
2882     struct {
2883         uint32_t bits;
2884         uint32_t mask;
2885     };
2886     int (*dec)(CPUCRISState *env, DisasContext *dc);
2887 } decinfo[] = {
2888     /* Order matters here.  */
2889     {DEC_MOVEQ, dec_moveq},
2890     {DEC_BTSTQ, dec_btstq},
2891     {DEC_CMPQ, dec_cmpq},
2892     {DEC_ADDOQ, dec_addoq},
2893     {DEC_ADDQ, dec_addq},
2894     {DEC_SUBQ, dec_subq},
2895     {DEC_ANDQ, dec_andq},
2896     {DEC_ORQ, dec_orq},
2897     {DEC_ASRQ, dec_asrq},
2898     {DEC_LSLQ, dec_lslq},
2899     {DEC_LSRQ, dec_lsrq},
2900     {DEC_BCCQ, dec_bccq},
2901
2902     {DEC_BCC_IM, dec_bcc_im},
2903     {DEC_JAS_IM, dec_jas_im},
2904     {DEC_JAS_R, dec_jas_r},
2905     {DEC_JASC_IM, dec_jasc_im},
2906     {DEC_JASC_R, dec_jasc_r},
2907     {DEC_BAS_IM, dec_bas_im},
2908     {DEC_BASC_IM, dec_basc_im},
2909     {DEC_JUMP_P, dec_jump_p},
2910     {DEC_LAPC_IM, dec_lapc_im},
2911     {DEC_LAPCQ, dec_lapcq},
2912
2913     {DEC_RFE_ETC, dec_rfe_etc},
2914     {DEC_ADDC_MR, dec_addc_mr},
2915
2916     {DEC_MOVE_MP, dec_move_mp},
2917     {DEC_MOVE_PM, dec_move_pm},
2918     {DEC_MOVEM_MR, dec_movem_mr},
2919     {DEC_MOVEM_RM, dec_movem_rm},
2920     {DEC_MOVE_PR, dec_move_pr},
2921     {DEC_SCC_R, dec_scc_r},
2922     {DEC_SETF, dec_setclrf},
2923     {DEC_CLEARF, dec_setclrf},
2924
2925     {DEC_MOVE_SR, dec_move_sr},
2926     {DEC_MOVE_RP, dec_move_rp},
2927     {DEC_SWAP_R, dec_swap_r},
2928     {DEC_ABS_R, dec_abs_r},
2929     {DEC_LZ_R, dec_lz_r},
2930     {DEC_MOVE_RS, dec_move_rs},
2931     {DEC_BTST_R, dec_btst_r},
2932     {DEC_ADDC_R, dec_addc_r},
2933
2934     {DEC_DSTEP_R, dec_dstep_r},
2935     {DEC_XOR_R, dec_xor_r},
2936     {DEC_MCP_R, dec_mcp_r},
2937     {DEC_CMP_R, dec_cmp_r},
2938
2939     {DEC_ADDI_R, dec_addi_r},
2940     {DEC_ADDI_ACR, dec_addi_acr},
2941
2942     {DEC_ADD_R, dec_add_r},
2943     {DEC_SUB_R, dec_sub_r},
2944
2945     {DEC_ADDU_R, dec_addu_r},
2946     {DEC_ADDS_R, dec_adds_r},
2947     {DEC_SUBU_R, dec_subu_r},
2948     {DEC_SUBS_R, dec_subs_r},
2949     {DEC_LSL_R, dec_lsl_r},
2950
2951     {DEC_AND_R, dec_and_r},
2952     {DEC_OR_R, dec_or_r},
2953     {DEC_BOUND_R, dec_bound_r},
2954     {DEC_ASR_R, dec_asr_r},
2955     {DEC_LSR_R, dec_lsr_r},
2956
2957     {DEC_MOVU_R, dec_movu_r},
2958     {DEC_MOVS_R, dec_movs_r},
2959     {DEC_NEG_R, dec_neg_r},
2960     {DEC_MOVE_R, dec_move_r},
2961
2962     {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2963     {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2964
2965     {DEC_MULS_R, dec_muls_r},
2966     {DEC_MULU_R, dec_mulu_r},
2967
2968     {DEC_ADDU_M, dec_addu_m},
2969     {DEC_ADDS_M, dec_adds_m},
2970     {DEC_SUBU_M, dec_subu_m},
2971     {DEC_SUBS_M, dec_subs_m},
2972
2973     {DEC_CMPU_M, dec_cmpu_m},
2974     {DEC_CMPS_M, dec_cmps_m},
2975     {DEC_MOVU_M, dec_movu_m},
2976     {DEC_MOVS_M, dec_movs_m},
2977
2978     {DEC_CMP_M, dec_cmp_m},
2979     {DEC_ADDO_M, dec_addo_m},
2980     {DEC_BOUND_M, dec_bound_m},
2981     {DEC_ADD_M, dec_add_m},
2982     {DEC_SUB_M, dec_sub_m},
2983     {DEC_AND_M, dec_and_m},
2984     {DEC_OR_M, dec_or_m},
2985     {DEC_MOVE_RM, dec_move_rm},
2986     {DEC_TEST_M, dec_test_m},
2987     {DEC_MOVE_MR, dec_move_mr},
2988
2989     {{0, 0}, dec_null}
2990 };
2991
2992 static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
2993 {
2994     int insn_len = 2;
2995     int i;
2996
2997     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
2998         tcg_gen_insn_start(dc->pc);
2999     }
3000
3001     /* Load a halfword onto the instruction register.  */
3002         dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
3003
3004     /* Now decode it.  */
3005     dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3006     dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3007     dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3008     dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3009     dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3010     dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3011
3012     /* Large switch for all insns.  */
3013     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3014         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
3015             insn_len = decinfo[i].dec(env, dc);
3016             break;
3017         }
3018     }
3019
3020 #if !defined(CONFIG_USER_ONLY)
3021     /* Single-stepping ?  */
3022     if (dc->tb_flags & S_FLAG) {
3023         TCGLabel *l1 = gen_new_label();
3024         tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3025         /* We treat SPC as a break with an odd trap vector.  */
3026         cris_evaluate_flags(dc);
3027         t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3028         tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3029         tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3030         t_gen_raise_exception(EXCP_BREAK);
3031         gen_set_label(l1);
3032     }
3033 #endif
3034     return insn_len;
3035 }
3036
3037 static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
3038 {
3039     CPUState *cs = CPU(cris_env_get_cpu(env));
3040     CPUBreakpoint *bp;
3041
3042     if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
3043         QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
3044             if (bp->pc == dc->pc) {
3045                 cris_evaluate_flags(dc);
3046                 tcg_gen_movi_tl(env_pc, dc->pc);
3047                 t_gen_raise_exception(EXCP_DEBUG);
3048                 dc->is_jmp = DISAS_UPDATE;
3049             }
3050         }
3051     }
3052 }
3053
3054 #include "translate_v10.c"
3055
3056 /*
3057  * Delay slots on QEMU/CRIS.
3058  *
3059  * If an exception hits on a delayslot, the core will let ERP (the Exception
3060  * Return Pointer) point to the branch (the previous) insn and set the lsb to
3061  * to give SW a hint that the exception actually hit on the dslot.
3062  *
3063  * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
3064  * the core and any jmp to an odd addresses will mask off that lsb. It is 
3065  * simply there to let sw know there was an exception on a dslot.
3066  *
3067  * When the software returns from an exception, the branch will re-execute.
3068  * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3069  * and the branch and delayslot dont share pages.
3070  *
3071  * The TB contaning the branch insn will set up env->btarget and evaluate 
3072  * env->btaken. When the translation loop exits we will note that the branch 
3073  * sequence is broken and let env->dslot be the size of the branch insn (those
3074  * vary in length).
3075  *
3076  * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3077  * set). It will also expect to have env->dslot setup with the size of the 
3078  * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3079  * will execute the dslot and take the branch, either to btarget or just one 
3080  * insn ahead.
3081  *
3082  * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3083  * broken branch sequences and setup $erp accordingly (i.e let it point to the
3084  * branch and set lsb). Then env->dslot gets cleared so that the exception 
3085  * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3086  * masked off and we will reexecute the branch insn.
3087  *
3088  */
3089
3090 /* generate intermediate code for basic block 'tb'.  */
3091 static inline void
3092 gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
3093                                bool search_pc)
3094 {
3095     CPUState *cs = CPU(cpu);
3096     CPUCRISState *env = &cpu->env;
3097     uint32_t pc_start;
3098     unsigned int insn_len;
3099     int j, lj;
3100     struct DisasContext ctx;
3101     struct DisasContext *dc = &ctx;
3102     uint32_t next_page_start;
3103     target_ulong npc;
3104     int num_insns;
3105     int max_insns;
3106
3107     if (env->pregs[PR_VR] == 32) {
3108         dc->decoder = crisv32_decoder;
3109         dc->clear_locked_irq = 0;
3110     } else {
3111         dc->decoder = crisv10_decoder;
3112         dc->clear_locked_irq = 1;
3113     }
3114
3115     /* Odd PC indicates that branch is rexecuting due to exception in the
3116      * delayslot, like in real hw.
3117      */
3118     pc_start = tb->pc & ~1;
3119     dc->cpu = cpu;
3120     dc->tb = tb;
3121
3122     dc->is_jmp = DISAS_NEXT;
3123     dc->ppc = pc_start;
3124     dc->pc = pc_start;
3125     dc->singlestep_enabled = cs->singlestep_enabled;
3126     dc->flags_uptodate = 1;
3127     dc->flagx_known = 1;
3128     dc->flags_x = tb->flags & X_FLAG;
3129     dc->cc_x_uptodate = 0;
3130     dc->cc_mask = 0;
3131     dc->update_cc = 0;
3132     dc->clear_prefix = 0;
3133
3134     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3135     dc->cc_size_uptodate = -1;
3136
3137     /* Decode TB flags.  */
3138     dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3139             | X_FLAG | PFIX_FLAG);
3140     dc->delayed_branch = !!(tb->flags & 7);
3141     if (dc->delayed_branch) {
3142         dc->jmp = JMP_INDIRECT;
3143     } else {
3144         dc->jmp = JMP_NOJMP;
3145     }
3146
3147     dc->cpustate_changed = 0;
3148
3149     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3150         qemu_log(
3151                 "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3152                 "pid=%x usp=%x\n"
3153                 "%x.%x.%x.%x\n"
3154                 "%x.%x.%x.%x\n"
3155                 "%x.%x.%x.%x\n"
3156                 "%x.%x.%x.%x\n",
3157                 search_pc, dc->pc, dc->ppc,
3158                 (uint64_t)tb->flags,
3159                 env->btarget, (unsigned)tb->flags & 7,
3160                 env->pregs[PR_CCS],
3161                 env->pregs[PR_PID], env->pregs[PR_USP],
3162                 env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3163                 env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3164                 env->regs[8], env->regs[9],
3165                 env->regs[10], env->regs[11],
3166                 env->regs[12], env->regs[13],
3167                 env->regs[14], env->regs[15]);
3168         qemu_log("--------------\n");
3169         qemu_log("IN: %s\n", lookup_symbol(pc_start));
3170     }
3171
3172     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3173     lj = -1;
3174     num_insns = 0;
3175     max_insns = tb->cflags & CF_COUNT_MASK;
3176     if (max_insns == 0) {
3177         max_insns = CF_COUNT_MASK;
3178     }
3179
3180     gen_tb_start(tb);
3181     do {
3182         check_breakpoint(env, dc);
3183
3184         if (search_pc) {
3185             j = tcg_op_buf_count();
3186             if (lj < j) {
3187                 lj++;
3188                 while (lj < j) {
3189                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
3190                 }
3191             }
3192             if (dc->delayed_branch == 1) {
3193                 tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;
3194             } else {
3195                 tcg_ctx.gen_opc_pc[lj] = dc->pc;
3196             }
3197             tcg_ctx.gen_opc_instr_start[lj] = 1;
3198             tcg_ctx.gen_opc_icount[lj] = num_insns;
3199         }
3200
3201         /* Pretty disas.  */
3202         LOG_DIS("%8.8x:\t", dc->pc);
3203
3204         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3205             gen_io_start();
3206         }
3207         dc->clear_x = 1;
3208
3209         insn_len = dc->decoder(env, dc);
3210         dc->ppc = dc->pc;
3211         dc->pc += insn_len;
3212         if (dc->clear_x) {
3213             cris_clear_x_flag(dc);
3214         }
3215
3216         num_insns++;
3217         /* Check for delayed branches here. If we do it before
3218            actually generating any host code, the simulator will just
3219            loop doing nothing for on this program location.  */
3220         if (dc->delayed_branch) {
3221             dc->delayed_branch--;
3222             if (dc->delayed_branch == 0) {
3223                 if (tb->flags & 7) {
3224                     t_gen_mov_env_TN(dslot, tcg_const_tl(0));
3225                 }
3226                 if (dc->cpustate_changed || !dc->flagx_known
3227                     || (dc->flags_x != (tb->flags & X_FLAG))) {
3228                     cris_store_direct_jmp(dc);
3229                 }
3230
3231                 if (dc->clear_locked_irq) {
3232                     dc->clear_locked_irq = 0;
3233                     t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3234                 }
3235
3236                 if (dc->jmp == JMP_DIRECT_CC) {
3237                     TCGLabel *l1 = gen_new_label();
3238                     cris_evaluate_flags(dc);
3239
3240                     /* Conditional jmp.  */
3241                     tcg_gen_brcondi_tl(TCG_COND_EQ,
3242                                env_btaken, 0, l1);
3243                     gen_goto_tb(dc, 1, dc->jmp_pc);
3244                     gen_set_label(l1);
3245                     gen_goto_tb(dc, 0, dc->pc);
3246                     dc->is_jmp = DISAS_TB_JUMP;
3247                     dc->jmp = JMP_NOJMP;
3248                 } else if (dc->jmp == JMP_DIRECT) {
3249                     cris_evaluate_flags(dc);
3250                     gen_goto_tb(dc, 0, dc->jmp_pc);
3251                     dc->is_jmp = DISAS_TB_JUMP;
3252                     dc->jmp = JMP_NOJMP;
3253                 } else {
3254                     t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
3255                     dc->is_jmp = DISAS_JUMP;
3256                 }
3257                 break;
3258             }
3259         }
3260
3261         /* If we are rexecuting a branch due to exceptions on
3262            delay slots dont break.  */
3263         if (!(tb->pc & 1) && cs->singlestep_enabled) {
3264             break;
3265         }
3266     } while (!dc->is_jmp && !dc->cpustate_changed
3267             && !tcg_op_buf_full()
3268             && !singlestep
3269             && (dc->pc < next_page_start)
3270             && num_insns < max_insns);
3271
3272     if (dc->clear_locked_irq) {
3273         t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3274     }
3275
3276     npc = dc->pc;
3277
3278         if (tb->cflags & CF_LAST_IO)
3279             gen_io_end();
3280     /* Force an update if the per-tb cpu state has changed.  */
3281     if (dc->is_jmp == DISAS_NEXT
3282         && (dc->cpustate_changed || !dc->flagx_known
3283         || (dc->flags_x != (tb->flags & X_FLAG)))) {
3284         dc->is_jmp = DISAS_UPDATE;
3285         tcg_gen_movi_tl(env_pc, npc);
3286     }
3287     /* Broken branch+delayslot sequence.  */
3288     if (dc->delayed_branch == 1) {
3289         /* Set env->dslot to the size of the branch insn.  */
3290         t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3291         cris_store_direct_jmp(dc);
3292     }
3293
3294     cris_evaluate_flags(dc);
3295
3296     if (unlikely(cs->singlestep_enabled)) {
3297         if (dc->is_jmp == DISAS_NEXT) {
3298             tcg_gen_movi_tl(env_pc, npc);
3299         }
3300         t_gen_raise_exception(EXCP_DEBUG);
3301     } else {
3302         switch (dc->is_jmp) {
3303         case DISAS_NEXT:
3304             gen_goto_tb(dc, 1, npc);
3305             break;
3306         default:
3307         case DISAS_JUMP:
3308         case DISAS_UPDATE:
3309             /* indicate that the hash table must be used
3310                    to find the next TB */
3311             tcg_gen_exit_tb(0);
3312             break;
3313         case DISAS_SWI:
3314         case DISAS_TB_JUMP:
3315             /* nothing more to generate */
3316             break;
3317         }
3318     }
3319     gen_tb_end(tb, num_insns);
3320
3321     if (search_pc) {
3322         j = tcg_op_buf_count();
3323         lj++;
3324         while (lj <= j) {
3325             tcg_ctx.gen_opc_instr_start[lj++] = 0;
3326         }
3327     } else {
3328         tb->size = dc->pc - pc_start;
3329         tb->icount = num_insns;
3330     }
3331
3332 #ifdef DEBUG_DISAS
3333 #if !DISAS_CRIS
3334     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3335         log_target_disas(cs, pc_start, dc->pc - pc_start,
3336                          env->pregs[PR_VR]);
3337         qemu_log("\nisize=%d osize=%d\n",
3338                  dc->pc - pc_start, tcg_op_buf_count());
3339     }
3340 #endif
3341 #endif
3342 }
3343
3344 void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
3345 {
3346     gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
3347 }
3348
3349 void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
3350 {
3351     gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
3352 }
3353
3354 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
3355                          int flags)
3356 {
3357     CRISCPU *cpu = CRIS_CPU(cs);
3358     CPUCRISState *env = &cpu->env;
3359     int i;
3360     uint32_t srs;
3361
3362     if (!env || !f) {
3363         return;
3364     }
3365
3366     cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3367             "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3368             env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3369             env->cc_op,
3370             env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3371
3372
3373     for (i = 0; i < 16; i++) {
3374         cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3375         if ((i + 1) % 4 == 0) {
3376             cpu_fprintf(f, "\n");
3377         }
3378     }
3379     cpu_fprintf(f, "\nspecial regs:\n");
3380     for (i = 0; i < 16; i++) {
3381         cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3382         if ((i + 1) % 4 == 0) {
3383             cpu_fprintf(f, "\n");
3384         }
3385     }
3386     srs = env->pregs[PR_SRS];
3387     cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3388     if (srs < ARRAY_SIZE(env->sregs)) {
3389         for (i = 0; i < 16; i++) {
3390             cpu_fprintf(f, "s%2.2d=%8.8x ",
3391                     i, env->sregs[srs][i]);
3392             if ((i + 1) % 4 == 0) {
3393                 cpu_fprintf(f, "\n");
3394             }
3395         }
3396     }
3397     cpu_fprintf(f, "\n\n");
3398
3399 }
3400
3401 void cris_initialize_tcg(void)
3402 {
3403     int i;
3404
3405     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3406     cc_x = tcg_global_mem_new(TCG_AREG0,
3407                               offsetof(CPUCRISState, cc_x), "cc_x");
3408     cc_src = tcg_global_mem_new(TCG_AREG0,
3409                                 offsetof(CPUCRISState, cc_src), "cc_src");
3410     cc_dest = tcg_global_mem_new(TCG_AREG0,
3411                                  offsetof(CPUCRISState, cc_dest),
3412                                  "cc_dest");
3413     cc_result = tcg_global_mem_new(TCG_AREG0,
3414                                    offsetof(CPUCRISState, cc_result),
3415                                    "cc_result");
3416     cc_op = tcg_global_mem_new(TCG_AREG0,
3417                                offsetof(CPUCRISState, cc_op), "cc_op");
3418     cc_size = tcg_global_mem_new(TCG_AREG0,
3419                                  offsetof(CPUCRISState, cc_size),
3420                                  "cc_size");
3421     cc_mask = tcg_global_mem_new(TCG_AREG0,
3422                                  offsetof(CPUCRISState, cc_mask),
3423                                  "cc_mask");
3424
3425     env_pc = tcg_global_mem_new(TCG_AREG0,
3426                                 offsetof(CPUCRISState, pc),
3427                                 "pc");
3428     env_btarget = tcg_global_mem_new(TCG_AREG0,
3429                                      offsetof(CPUCRISState, btarget),
3430                                      "btarget");
3431     env_btaken = tcg_global_mem_new(TCG_AREG0,
3432                                     offsetof(CPUCRISState, btaken),
3433                                     "btaken");
3434     for (i = 0; i < 16; i++) {
3435         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3436                                       offsetof(CPUCRISState, regs[i]),
3437                                       regnames[i]);
3438     }
3439     for (i = 0; i < 16; i++) {
3440         cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3441                                        offsetof(CPUCRISState, pregs[i]),
3442                                        pregnames[i]);
3443     }
3444 }
3445
3446 void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
3447 {
3448     env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3449 }
This page took 0.211267 seconds and 2 git commands to generate.