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