These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / target-unicore32 / translate.c
1 /*
2  *  UniCore32 translation
3  *
4  * Copyright (C) 2010-2012 Guan Xuetao
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation, or (at your option) any
9  * later version. See the COPYING file in the top-level directory.
10  */
11 #include "qemu/osdep.h"
12
13 #include "cpu.h"
14 #include "disas/disas.h"
15 #include "tcg-op.h"
16 #include "qemu/log.h"
17 #include "exec/cpu_ldst.h"
18
19 #include "exec/helper-proto.h"
20 #include "exec/helper-gen.h"
21
22 #include "trace-tcg.h"
23 #include "exec/log.h"
24
25
26 /* internal defines */
27 typedef struct DisasContext {
28     target_ulong pc;
29     int is_jmp;
30     /* Nonzero if this instruction has been conditionally skipped.  */
31     int condjmp;
32     /* The label that will be jumped to when the instruction is skipped.  */
33     TCGLabel *condlabel;
34     struct TranslationBlock *tb;
35     int singlestep_enabled;
36 #ifndef CONFIG_USER_ONLY
37     int user;
38 #endif
39 } DisasContext;
40
41 #ifndef CONFIG_USER_ONLY
42 #define IS_USER(s)      (s->user)
43 #else
44 #define IS_USER(s)      1
45 #endif
46
47 /* These instructions trap after executing, so defer them until after the
48    conditional executions state has been updated.  */
49 #define DISAS_SYSCALL 5
50
51 static TCGv_env cpu_env;
52 static TCGv_i32 cpu_R[32];
53
54 /* FIXME:  These should be removed.  */
55 static TCGv cpu_F0s, cpu_F1s;
56 static TCGv_i64 cpu_F0d, cpu_F1d;
57
58 #include "exec/gen-icount.h"
59
60 static const char *regnames[] = {
61       "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
62       "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
63       "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
64       "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };
65
66 /* initialize TCG globals.  */
67 void uc32_translate_init(void)
68 {
69     int i;
70
71     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
72
73     for (i = 0; i < 32; i++) {
74         cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
75                                 offsetof(CPUUniCore32State, regs[i]), regnames[i]);
76     }
77 }
78
79 static int num_temps;
80
81 /* Allocate a temporary variable.  */
82 static TCGv_i32 new_tmp(void)
83 {
84     num_temps++;
85     return tcg_temp_new_i32();
86 }
87
88 /* Release a temporary variable.  */
89 static void dead_tmp(TCGv tmp)
90 {
91     tcg_temp_free(tmp);
92     num_temps--;
93 }
94
95 static inline TCGv load_cpu_offset(int offset)
96 {
97     TCGv tmp = new_tmp();
98     tcg_gen_ld_i32(tmp, cpu_env, offset);
99     return tmp;
100 }
101
102 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUUniCore32State, name))
103
104 static inline void store_cpu_offset(TCGv var, int offset)
105 {
106     tcg_gen_st_i32(var, cpu_env, offset);
107     dead_tmp(var);
108 }
109
110 #define store_cpu_field(var, name) \
111     store_cpu_offset(var, offsetof(CPUUniCore32State, name))
112
113 /* Set a variable to the value of a CPU register.  */
114 static void load_reg_var(DisasContext *s, TCGv var, int reg)
115 {
116     if (reg == 31) {
117         uint32_t addr;
118         /* normaly, since we updated PC */
119         addr = (long)s->pc;
120         tcg_gen_movi_i32(var, addr);
121     } else {
122         tcg_gen_mov_i32(var, cpu_R[reg]);
123     }
124 }
125
126 /* Create a new temporary and set it to the value of a CPU register.  */
127 static inline TCGv load_reg(DisasContext *s, int reg)
128 {
129     TCGv tmp = new_tmp();
130     load_reg_var(s, tmp, reg);
131     return tmp;
132 }
133
134 /* Set a CPU register.  The source must be a temporary and will be
135    marked as dead.  */
136 static void store_reg(DisasContext *s, int reg, TCGv var)
137 {
138     if (reg == 31) {
139         tcg_gen_andi_i32(var, var, ~3);
140         s->is_jmp = DISAS_JUMP;
141     }
142     tcg_gen_mov_i32(cpu_R[reg], var);
143     dead_tmp(var);
144 }
145
146 /* Value extensions.  */
147 #define gen_uxtb(var)           tcg_gen_ext8u_i32(var, var)
148 #define gen_uxth(var)           tcg_gen_ext16u_i32(var, var)
149 #define gen_sxtb(var)           tcg_gen_ext8s_i32(var, var)
150 #define gen_sxth(var)           tcg_gen_ext16s_i32(var, var)
151
152 #define UCOP_REG_M              (((insn) >>  0) & 0x1f)
153 #define UCOP_REG_N              (((insn) >> 19) & 0x1f)
154 #define UCOP_REG_D              (((insn) >> 14) & 0x1f)
155 #define UCOP_REG_S              (((insn) >>  9) & 0x1f)
156 #define UCOP_REG_LO             (((insn) >> 14) & 0x1f)
157 #define UCOP_REG_HI             (((insn) >>  9) & 0x1f)
158 #define UCOP_SH_OP              (((insn) >>  6) & 0x03)
159 #define UCOP_SH_IM              (((insn) >>  9) & 0x1f)
160 #define UCOP_OPCODES            (((insn) >> 25) & 0x0f)
161 #define UCOP_IMM_9              (((insn) >>  0) & 0x1ff)
162 #define UCOP_IMM10              (((insn) >>  0) & 0x3ff)
163 #define UCOP_IMM14              (((insn) >>  0) & 0x3fff)
164 #define UCOP_COND               (((insn) >> 25) & 0x0f)
165 #define UCOP_CMOV_COND          (((insn) >> 19) & 0x0f)
166 #define UCOP_CPNUM              (((insn) >> 10) & 0x0f)
167 #define UCOP_UCF64_FMT          (((insn) >> 24) & 0x03)
168 #define UCOP_UCF64_FUNC         (((insn) >>  6) & 0x0f)
169 #define UCOP_UCF64_COND         (((insn) >>  6) & 0x0f)
170
171 #define UCOP_SET(i)             ((insn) & (1 << (i)))
172 #define UCOP_SET_P              UCOP_SET(28)
173 #define UCOP_SET_U              UCOP_SET(27)
174 #define UCOP_SET_B              UCOP_SET(26)
175 #define UCOP_SET_W              UCOP_SET(25)
176 #define UCOP_SET_L              UCOP_SET(24)
177 #define UCOP_SET_S              UCOP_SET(24)
178
179 #define ILLEGAL         cpu_abort(CPU(cpu),                             \
180                         "Illegal UniCore32 instruction %x at line %d!", \
181                         insn, __LINE__)
182
183 #ifndef CONFIG_USER_ONLY
184 static void disas_cp0_insn(CPUUniCore32State *env, DisasContext *s,
185         uint32_t insn)
186 {
187     UniCore32CPU *cpu = uc32_env_get_cpu(env);
188     TCGv tmp, tmp2, tmp3;
189     if ((insn & 0xfe000000) == 0xe0000000) {
190         tmp2 = new_tmp();
191         tmp3 = new_tmp();
192         tcg_gen_movi_i32(tmp2, UCOP_REG_N);
193         tcg_gen_movi_i32(tmp3, UCOP_IMM10);
194         if (UCOP_SET_L) {
195             tmp = new_tmp();
196             gen_helper_cp0_get(tmp, cpu_env, tmp2, tmp3);
197             store_reg(s, UCOP_REG_D, tmp);
198         } else {
199             tmp = load_reg(s, UCOP_REG_D);
200             gen_helper_cp0_set(cpu_env, tmp, tmp2, tmp3);
201             dead_tmp(tmp);
202         }
203         dead_tmp(tmp2);
204         dead_tmp(tmp3);
205         return;
206     }
207     ILLEGAL;
208 }
209
210 static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
211         uint32_t insn)
212 {
213     UniCore32CPU *cpu = uc32_env_get_cpu(env);
214     TCGv tmp;
215
216     if ((insn & 0xff003fff) == 0xe1000400) {
217         /*
218          * movc rd, pp.nn, #imm9
219          *      rd: UCOP_REG_D
220          *      nn: UCOP_REG_N (must be 0)
221          *      imm9: 0
222          */
223         if (UCOP_REG_N == 0) {
224             tmp = new_tmp();
225             tcg_gen_movi_i32(tmp, 0);
226             store_reg(s, UCOP_REG_D, tmp);
227             return;
228         } else {
229             ILLEGAL;
230         }
231     }
232     if ((insn & 0xff003fff) == 0xe0000401) {
233         /*
234          * movc pp.nn, rn, #imm9
235          *      rn: UCOP_REG_D
236          *      nn: UCOP_REG_N (must be 1)
237          *      imm9: 1
238          */
239         if (UCOP_REG_N == 1) {
240             tmp = load_reg(s, UCOP_REG_D);
241             gen_helper_cp1_putc(tmp);
242             dead_tmp(tmp);
243             return;
244         } else {
245             ILLEGAL;
246         }
247     }
248     ILLEGAL;
249 }
250 #endif
251
252 static inline void gen_set_asr(TCGv var, uint32_t mask)
253 {
254     TCGv tmp_mask = tcg_const_i32(mask);
255     gen_helper_asr_write(cpu_env, var, tmp_mask);
256     tcg_temp_free_i32(tmp_mask);
257 }
258 /* Set NZCV flags from the high 4 bits of var.  */
259 #define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)
260
261 static void gen_exception(int excp)
262 {
263     TCGv tmp = new_tmp();
264     tcg_gen_movi_i32(tmp, excp);
265     gen_helper_exception(cpu_env, tmp);
266     dead_tmp(tmp);
267 }
268
269 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, CF))
270
271 /* Set CF to the top bit of var.  */
272 static void gen_set_CF_bit31(TCGv var)
273 {
274     TCGv tmp = new_tmp();
275     tcg_gen_shri_i32(tmp, var, 31);
276     gen_set_CF(tmp);
277     dead_tmp(tmp);
278 }
279
280 /* Set N and Z flags from var.  */
281 static inline void gen_logic_CC(TCGv var)
282 {
283     tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, NF));
284     tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, ZF));
285 }
286
287 /* dest = T0 + T1 + CF. */
288 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
289 {
290     TCGv tmp;
291     tcg_gen_add_i32(dest, t0, t1);
292     tmp = load_cpu_field(CF);
293     tcg_gen_add_i32(dest, dest, tmp);
294     dead_tmp(tmp);
295 }
296
297 /* dest = T0 - T1 + CF - 1.  */
298 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
299 {
300     TCGv tmp;
301     tcg_gen_sub_i32(dest, t0, t1);
302     tmp = load_cpu_field(CF);
303     tcg_gen_add_i32(dest, dest, tmp);
304     tcg_gen_subi_i32(dest, dest, 1);
305     dead_tmp(tmp);
306 }
307
308 static void shifter_out_im(TCGv var, int shift)
309 {
310     TCGv tmp = new_tmp();
311     if (shift == 0) {
312         tcg_gen_andi_i32(tmp, var, 1);
313     } else {
314         tcg_gen_shri_i32(tmp, var, shift);
315         if (shift != 31) {
316             tcg_gen_andi_i32(tmp, tmp, 1);
317         }
318     }
319     gen_set_CF(tmp);
320     dead_tmp(tmp);
321 }
322
323 /* Shift by immediate.  Includes special handling for shift == 0.  */
324 static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
325         int flags)
326 {
327     switch (shiftop) {
328     case 0: /* LSL */
329         if (shift != 0) {
330             if (flags) {
331                 shifter_out_im(var, 32 - shift);
332             }
333             tcg_gen_shli_i32(var, var, shift);
334         }
335         break;
336     case 1: /* LSR */
337         if (shift == 0) {
338             if (flags) {
339                 tcg_gen_shri_i32(var, var, 31);
340                 gen_set_CF(var);
341             }
342             tcg_gen_movi_i32(var, 0);
343         } else {
344             if (flags) {
345                 shifter_out_im(var, shift - 1);
346             }
347             tcg_gen_shri_i32(var, var, shift);
348         }
349         break;
350     case 2: /* ASR */
351         if (shift == 0) {
352             shift = 32;
353         }
354         if (flags) {
355             shifter_out_im(var, shift - 1);
356         }
357         if (shift == 32) {
358             shift = 31;
359         }
360         tcg_gen_sari_i32(var, var, shift);
361         break;
362     case 3: /* ROR/RRX */
363         if (shift != 0) {
364             if (flags) {
365                 shifter_out_im(var, shift - 1);
366             }
367             tcg_gen_rotri_i32(var, var, shift); break;
368         } else {
369             TCGv tmp = load_cpu_field(CF);
370             if (flags) {
371                 shifter_out_im(var, 0);
372             }
373             tcg_gen_shri_i32(var, var, 1);
374             tcg_gen_shli_i32(tmp, tmp, 31);
375             tcg_gen_or_i32(var, var, tmp);
376             dead_tmp(tmp);
377         }
378     }
379 };
380
381 static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
382                                      TCGv shift, int flags)
383 {
384     if (flags) {
385         switch (shiftop) {
386         case 0:
387             gen_helper_shl_cc(var, cpu_env, var, shift);
388             break;
389         case 1:
390             gen_helper_shr_cc(var, cpu_env, var, shift);
391             break;
392         case 2:
393             gen_helper_sar_cc(var, cpu_env, var, shift);
394             break;
395         case 3:
396             gen_helper_ror_cc(var, cpu_env, var, shift);
397             break;
398         }
399     } else {
400         switch (shiftop) {
401         case 0:
402             gen_helper_shl(var, var, shift);
403             break;
404         case 1:
405             gen_helper_shr(var, var, shift);
406             break;
407         case 2:
408             gen_helper_sar(var, var, shift);
409             break;
410         case 3:
411             tcg_gen_andi_i32(shift, shift, 0x1f);
412             tcg_gen_rotr_i32(var, var, shift);
413             break;
414         }
415     }
416     dead_tmp(shift);
417 }
418
419 static void gen_test_cc(int cc, TCGLabel *label)
420 {
421     TCGv tmp;
422     TCGv tmp2;
423     TCGLabel *inv;
424
425     switch (cc) {
426     case 0: /* eq: Z */
427         tmp = load_cpu_field(ZF);
428         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
429         break;
430     case 1: /* ne: !Z */
431         tmp = load_cpu_field(ZF);
432         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
433         break;
434     case 2: /* cs: C */
435         tmp = load_cpu_field(CF);
436         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
437         break;
438     case 3: /* cc: !C */
439         tmp = load_cpu_field(CF);
440         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
441         break;
442     case 4: /* mi: N */
443         tmp = load_cpu_field(NF);
444         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
445         break;
446     case 5: /* pl: !N */
447         tmp = load_cpu_field(NF);
448         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
449         break;
450     case 6: /* vs: V */
451         tmp = load_cpu_field(VF);
452         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
453         break;
454     case 7: /* vc: !V */
455         tmp = load_cpu_field(VF);
456         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
457         break;
458     case 8: /* hi: C && !Z */
459         inv = gen_new_label();
460         tmp = load_cpu_field(CF);
461         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
462         dead_tmp(tmp);
463         tmp = load_cpu_field(ZF);
464         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
465         gen_set_label(inv);
466         break;
467     case 9: /* ls: !C || Z */
468         tmp = load_cpu_field(CF);
469         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
470         dead_tmp(tmp);
471         tmp = load_cpu_field(ZF);
472         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
473         break;
474     case 10: /* ge: N == V -> N ^ V == 0 */
475         tmp = load_cpu_field(VF);
476         tmp2 = load_cpu_field(NF);
477         tcg_gen_xor_i32(tmp, tmp, tmp2);
478         dead_tmp(tmp2);
479         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
480         break;
481     case 11: /* lt: N != V -> N ^ V != 0 */
482         tmp = load_cpu_field(VF);
483         tmp2 = load_cpu_field(NF);
484         tcg_gen_xor_i32(tmp, tmp, tmp2);
485         dead_tmp(tmp2);
486         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
487         break;
488     case 12: /* gt: !Z && N == V */
489         inv = gen_new_label();
490         tmp = load_cpu_field(ZF);
491         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
492         dead_tmp(tmp);
493         tmp = load_cpu_field(VF);
494         tmp2 = load_cpu_field(NF);
495         tcg_gen_xor_i32(tmp, tmp, tmp2);
496         dead_tmp(tmp2);
497         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
498         gen_set_label(inv);
499         break;
500     case 13: /* le: Z || N != V */
501         tmp = load_cpu_field(ZF);
502         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
503         dead_tmp(tmp);
504         tmp = load_cpu_field(VF);
505         tmp2 = load_cpu_field(NF);
506         tcg_gen_xor_i32(tmp, tmp, tmp2);
507         dead_tmp(tmp2);
508         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
509         break;
510     default:
511         fprintf(stderr, "Bad condition code 0x%x\n", cc);
512         abort();
513     }
514     dead_tmp(tmp);
515 }
516
517 static const uint8_t table_logic_cc[16] = {
518     1, /* and */    1, /* xor */    0, /* sub */    0, /* rsb */
519     0, /* add */    0, /* adc */    0, /* sbc */    0, /* rsc */
520     1, /* andl */   1, /* xorl */   0, /* cmp */    0, /* cmn */
521     1, /* orr */    1, /* mov */    1, /* bic */    1, /* mvn */
522 };
523
524 /* Set PC state from an immediate address.  */
525 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
526 {
527     s->is_jmp = DISAS_UPDATE;
528     tcg_gen_movi_i32(cpu_R[31], addr & ~3);
529 }
530
531 /* Set PC state from var.  var is marked as dead.  */
532 static inline void gen_bx(DisasContext *s, TCGv var)
533 {
534     s->is_jmp = DISAS_UPDATE;
535     tcg_gen_andi_i32(cpu_R[31], var, ~3);
536     dead_tmp(var);
537 }
538
539 static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
540 {
541     store_reg(s, reg, var);
542 }
543
544 static inline TCGv gen_ld8s(TCGv addr, int index)
545 {
546     TCGv tmp = new_tmp();
547     tcg_gen_qemu_ld8s(tmp, addr, index);
548     return tmp;
549 }
550
551 static inline TCGv gen_ld8u(TCGv addr, int index)
552 {
553     TCGv tmp = new_tmp();
554     tcg_gen_qemu_ld8u(tmp, addr, index);
555     return tmp;
556 }
557
558 static inline TCGv gen_ld16s(TCGv addr, int index)
559 {
560     TCGv tmp = new_tmp();
561     tcg_gen_qemu_ld16s(tmp, addr, index);
562     return tmp;
563 }
564
565 static inline TCGv gen_ld16u(TCGv addr, int index)
566 {
567     TCGv tmp = new_tmp();
568     tcg_gen_qemu_ld16u(tmp, addr, index);
569     return tmp;
570 }
571
572 static inline TCGv gen_ld32(TCGv addr, int index)
573 {
574     TCGv tmp = new_tmp();
575     tcg_gen_qemu_ld32u(tmp, addr, index);
576     return tmp;
577 }
578
579 static inline void gen_st8(TCGv val, TCGv addr, int index)
580 {
581     tcg_gen_qemu_st8(val, addr, index);
582     dead_tmp(val);
583 }
584
585 static inline void gen_st16(TCGv val, TCGv addr, int index)
586 {
587     tcg_gen_qemu_st16(val, addr, index);
588     dead_tmp(val);
589 }
590
591 static inline void gen_st32(TCGv val, TCGv addr, int index)
592 {
593     tcg_gen_qemu_st32(val, addr, index);
594     dead_tmp(val);
595 }
596
597 static inline void gen_set_pc_im(uint32_t val)
598 {
599     tcg_gen_movi_i32(cpu_R[31], val);
600 }
601
602 /* Force a TB lookup after an instruction that changes the CPU state.  */
603 static inline void gen_lookup_tb(DisasContext *s)
604 {
605     tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
606     s->is_jmp = DISAS_UPDATE;
607 }
608
609 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
610         TCGv var)
611 {
612     int val;
613     TCGv offset;
614
615     if (UCOP_SET(29)) {
616         /* immediate */
617         val = UCOP_IMM14;
618         if (!UCOP_SET_U) {
619             val = -val;
620         }
621         if (val != 0) {
622             tcg_gen_addi_i32(var, var, val);
623         }
624     } else {
625         /* shift/register */
626         offset = load_reg(s, UCOP_REG_M);
627         gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
628         if (!UCOP_SET_U) {
629             tcg_gen_sub_i32(var, var, offset);
630         } else {
631             tcg_gen_add_i32(var, var, offset);
632         }
633         dead_tmp(offset);
634     }
635 }
636
637 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
638         TCGv var)
639 {
640     int val;
641     TCGv offset;
642
643     if (UCOP_SET(26)) {
644         /* immediate */
645         val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
646         if (!UCOP_SET_U) {
647             val = -val;
648         }
649         if (val != 0) {
650             tcg_gen_addi_i32(var, var, val);
651         }
652     } else {
653         /* register */
654         offset = load_reg(s, UCOP_REG_M);
655         if (!UCOP_SET_U) {
656             tcg_gen_sub_i32(var, var, offset);
657         } else {
658             tcg_gen_add_i32(var, var, offset);
659         }
660         dead_tmp(offset);
661     }
662 }
663
664 static inline long ucf64_reg_offset(int reg)
665 {
666     if (reg & 1) {
667         return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
668           + offsetof(CPU_DoubleU, l.upper);
669     } else {
670         return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
671           + offsetof(CPU_DoubleU, l.lower);
672     }
673 }
674
675 #define ucf64_gen_ld32(reg)      load_cpu_offset(ucf64_reg_offset(reg))
676 #define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))
677
678 /* UniCore-F64 single load/store I_offset */
679 static void do_ucf64_ldst_i(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
680 {
681     UniCore32CPU *cpu = uc32_env_get_cpu(env);
682     int offset;
683     TCGv tmp;
684     TCGv addr;
685
686     addr = load_reg(s, UCOP_REG_N);
687     if (!UCOP_SET_P && !UCOP_SET_W) {
688         ILLEGAL;
689     }
690
691     if (UCOP_SET_P) {
692         offset = UCOP_IMM10 << 2;
693         if (!UCOP_SET_U) {
694             offset = -offset;
695         }
696         if (offset != 0) {
697             tcg_gen_addi_i32(addr, addr, offset);
698         }
699     }
700
701     if (UCOP_SET_L) { /* load */
702         tmp = gen_ld32(addr, IS_USER(s));
703         ucf64_gen_st32(tmp, UCOP_REG_D);
704     } else { /* store */
705         tmp = ucf64_gen_ld32(UCOP_REG_D);
706         gen_st32(tmp, addr, IS_USER(s));
707     }
708
709     if (!UCOP_SET_P) {
710         offset = UCOP_IMM10 << 2;
711         if (!UCOP_SET_U) {
712             offset = -offset;
713         }
714         if (offset != 0) {
715             tcg_gen_addi_i32(addr, addr, offset);
716         }
717     }
718     if (UCOP_SET_W) {
719         store_reg(s, UCOP_REG_N, addr);
720     } else {
721         dead_tmp(addr);
722     }
723 }
724
725 /* UniCore-F64 load/store multiple words */
726 static void do_ucf64_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
727 {
728     UniCore32CPU *cpu = uc32_env_get_cpu(env);
729     unsigned int i;
730     int j, n, freg;
731     TCGv tmp;
732     TCGv addr;
733
734     if (UCOP_REG_D != 0) {
735         ILLEGAL;
736     }
737     if (UCOP_REG_N == 31) {
738         ILLEGAL;
739     }
740     if ((insn << 24) == 0) {
741         ILLEGAL;
742     }
743
744     addr = load_reg(s, UCOP_REG_N);
745
746     n = 0;
747     for (i = 0; i < 8; i++) {
748         if (UCOP_SET(i)) {
749             n++;
750         }
751     }
752
753     if (UCOP_SET_U) {
754         if (UCOP_SET_P) { /* pre increment */
755             tcg_gen_addi_i32(addr, addr, 4);
756         } /* unnecessary to do anything when post increment */
757     } else {
758         if (UCOP_SET_P) { /* pre decrement */
759             tcg_gen_addi_i32(addr, addr, -(n * 4));
760         } else { /* post decrement */
761             if (n != 1) {
762                 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
763             }
764         }
765     }
766
767     freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */
768
769     for (i = 0, j = 0; i < 8; i++, freg++) {
770         if (!UCOP_SET(i)) {
771             continue;
772         }
773
774         if (UCOP_SET_L) { /* load */
775             tmp = gen_ld32(addr, IS_USER(s));
776             ucf64_gen_st32(tmp, freg);
777         } else { /* store */
778             tmp = ucf64_gen_ld32(freg);
779             gen_st32(tmp, addr, IS_USER(s));
780         }
781
782         j++;
783         /* unnecessary to add after the last transfer */
784         if (j != n) {
785             tcg_gen_addi_i32(addr, addr, 4);
786         }
787     }
788
789     if (UCOP_SET_W) { /* write back */
790         if (UCOP_SET_U) {
791             if (!UCOP_SET_P) { /* post increment */
792                 tcg_gen_addi_i32(addr, addr, 4);
793             } /* unnecessary to do anything when pre increment */
794         } else {
795             if (UCOP_SET_P) {
796                 /* pre decrement */
797                 if (n != 1) {
798                     tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
799                 }
800             } else {
801                 /* post decrement */
802                 tcg_gen_addi_i32(addr, addr, -(n * 4));
803             }
804         }
805         store_reg(s, UCOP_REG_N, addr);
806     } else {
807         dead_tmp(addr);
808     }
809 }
810
811 /* UniCore-F64 mrc/mcr */
812 static void do_ucf64_trans(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
813 {
814     UniCore32CPU *cpu = uc32_env_get_cpu(env);
815     TCGv tmp;
816
817     if ((insn & 0xfe0003ff) == 0xe2000000) {
818         /* control register */
819         if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
820             ILLEGAL;
821         }
822         if (UCOP_SET(24)) {
823             /* CFF */
824             tmp = new_tmp();
825             gen_helper_ucf64_get_fpscr(tmp, cpu_env);
826             store_reg(s, UCOP_REG_D, tmp);
827         } else {
828             /* CTF */
829             tmp = load_reg(s, UCOP_REG_D);
830             gen_helper_ucf64_set_fpscr(cpu_env, tmp);
831             dead_tmp(tmp);
832             gen_lookup_tb(s);
833         }
834         return;
835     }
836     if ((insn & 0xfe0003ff) == 0xe0000000) {
837         /* general register */
838         if (UCOP_REG_D == 31) {
839             ILLEGAL;
840         }
841         if (UCOP_SET(24)) { /* MFF */
842             tmp = ucf64_gen_ld32(UCOP_REG_N);
843             store_reg(s, UCOP_REG_D, tmp);
844         } else { /* MTF */
845             tmp = load_reg(s, UCOP_REG_D);
846             ucf64_gen_st32(tmp, UCOP_REG_N);
847         }
848         return;
849     }
850     if ((insn & 0xfb000000) == 0xe9000000) {
851         /* MFFC */
852         if (UCOP_REG_D != 31) {
853             ILLEGAL;
854         }
855         if (UCOP_UCF64_COND & 0x8) {
856             ILLEGAL;
857         }
858
859         tmp = new_tmp();
860         tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
861         if (UCOP_SET(26)) {
862             tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
863             tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
864             gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
865         } else {
866             tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
867             tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
868             gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
869         }
870         dead_tmp(tmp);
871         return;
872     }
873     ILLEGAL;
874 }
875
876 /* UniCore-F64 convert instructions */
877 static void do_ucf64_fcvt(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
878 {
879     UniCore32CPU *cpu = uc32_env_get_cpu(env);
880
881     if (UCOP_UCF64_FMT == 3) {
882         ILLEGAL;
883     }
884     if (UCOP_REG_N != 0) {
885         ILLEGAL;
886     }
887     switch (UCOP_UCF64_FUNC) {
888     case 0: /* cvt.s */
889         switch (UCOP_UCF64_FMT) {
890         case 1 /* d */:
891             tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
892             gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
893             tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
894             break;
895         case 2 /* w */:
896             tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
897             gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
898             tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
899             break;
900         default /* s */:
901             ILLEGAL;
902             break;
903         }
904         break;
905     case 1: /* cvt.d */
906         switch (UCOP_UCF64_FMT) {
907         case 0 /* s */:
908             tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
909             gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
910             tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
911             break;
912         case 2 /* w */:
913             tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
914             gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
915             tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
916             break;
917         default /* d */:
918             ILLEGAL;
919             break;
920         }
921         break;
922     case 4: /* cvt.w */
923         switch (UCOP_UCF64_FMT) {
924         case 0 /* s */:
925             tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
926             gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
927             tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
928             break;
929         case 1 /* d */:
930             tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
931             gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
932             tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
933             break;
934     default /* w */:
935             ILLEGAL;
936             break;
937         }
938         break;
939     default:
940         ILLEGAL;
941     }
942 }
943
944 /* UniCore-F64 compare instructions */
945 static void do_ucf64_fcmp(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
946 {
947     UniCore32CPU *cpu = uc32_env_get_cpu(env);
948
949     if (UCOP_SET(25)) {
950         ILLEGAL;
951     }
952     if (UCOP_REG_D != 0) {
953         ILLEGAL;
954     }
955
956     ILLEGAL; /* TODO */
957     if (UCOP_SET(24)) {
958         tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
959         tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
960         /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
961     } else {
962         tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
963         tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
964         /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
965     }
966 }
967
968 #define gen_helper_ucf64_movs(x, y)      do { } while (0)
969 #define gen_helper_ucf64_movd(x, y)      do { } while (0)
970
971 #define UCF64_OP1(name)    do {                           \
972         if (UCOP_REG_N != 0) {                            \
973             ILLEGAL;                                      \
974         }                                                 \
975         switch (UCOP_UCF64_FMT) {                         \
976         case 0 /* s */:                                   \
977             tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
978                            ucf64_reg_offset(UCOP_REG_M)); \
979             gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
980             tcg_gen_st_i32(cpu_F0s, cpu_env,              \
981                            ucf64_reg_offset(UCOP_REG_D)); \
982             break;                                        \
983         case 1 /* d */:                                   \
984             tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
985                            ucf64_reg_offset(UCOP_REG_M)); \
986             gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
987             tcg_gen_st_i64(cpu_F0d, cpu_env,              \
988                            ucf64_reg_offset(UCOP_REG_D)); \
989             break;                                        \
990         case 2 /* w */:                                   \
991             ILLEGAL;                                      \
992             break;                                        \
993         }                                                 \
994     } while (0)
995
996 #define UCF64_OP2(name)    do {                           \
997         switch (UCOP_UCF64_FMT) {                         \
998         case 0 /* s */:                                   \
999             tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
1000                            ucf64_reg_offset(UCOP_REG_N)); \
1001             tcg_gen_ld_i32(cpu_F1s, cpu_env,              \
1002                            ucf64_reg_offset(UCOP_REG_M)); \
1003             gen_helper_ucf64_##name##s(cpu_F0s,           \
1004                            cpu_F0s, cpu_F1s, cpu_env);    \
1005             tcg_gen_st_i32(cpu_F0s, cpu_env,              \
1006                            ucf64_reg_offset(UCOP_REG_D)); \
1007             break;                                        \
1008         case 1 /* d */:                                   \
1009             tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
1010                            ucf64_reg_offset(UCOP_REG_N)); \
1011             tcg_gen_ld_i64(cpu_F1d, cpu_env,              \
1012                            ucf64_reg_offset(UCOP_REG_M)); \
1013             gen_helper_ucf64_##name##d(cpu_F0d,           \
1014                            cpu_F0d, cpu_F1d, cpu_env);    \
1015             tcg_gen_st_i64(cpu_F0d, cpu_env,              \
1016                            ucf64_reg_offset(UCOP_REG_D)); \
1017             break;                                        \
1018         case 2 /* w */:                                   \
1019             ILLEGAL;                                      \
1020             break;                                        \
1021         }                                                 \
1022     } while (0)
1023
1024 /* UniCore-F64 data processing */
1025 static void do_ucf64_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1026 {
1027     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1028
1029     if (UCOP_UCF64_FMT == 3) {
1030         ILLEGAL;
1031     }
1032     switch (UCOP_UCF64_FUNC) {
1033     case 0: /* add */
1034         UCF64_OP2(add);
1035         break;
1036     case 1: /* sub */
1037         UCF64_OP2(sub);
1038         break;
1039     case 2: /* mul */
1040         UCF64_OP2(mul);
1041         break;
1042     case 4: /* div */
1043         UCF64_OP2(div);
1044         break;
1045     case 5: /* abs */
1046         UCF64_OP1(abs);
1047         break;
1048     case 6: /* mov */
1049         UCF64_OP1(mov);
1050         break;
1051     case 7: /* neg */
1052         UCF64_OP1(neg);
1053         break;
1054     default:
1055         ILLEGAL;
1056     }
1057 }
1058
1059 /* Disassemble an F64 instruction */
1060 static void disas_ucf64_insn(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1061 {
1062     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1063
1064     if (!UCOP_SET(29)) {
1065         if (UCOP_SET(26)) {
1066             do_ucf64_ldst_m(env, s, insn);
1067         } else {
1068             do_ucf64_ldst_i(env, s, insn);
1069         }
1070     } else {
1071         if (UCOP_SET(5)) {
1072             switch ((insn >> 26) & 0x3) {
1073             case 0:
1074                 do_ucf64_datap(env, s, insn);
1075                 break;
1076             case 1:
1077                 ILLEGAL;
1078                 break;
1079             case 2:
1080                 do_ucf64_fcvt(env, s, insn);
1081                 break;
1082             case 3:
1083                 do_ucf64_fcmp(env, s, insn);
1084                 break;
1085             }
1086         } else {
1087             do_ucf64_trans(env, s, insn);
1088         }
1089     }
1090 }
1091
1092 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
1093 {
1094     TranslationBlock *tb;
1095
1096     tb = s->tb;
1097     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1098         tcg_gen_goto_tb(n);
1099         gen_set_pc_im(dest);
1100         tcg_gen_exit_tb((uintptr_t)tb + n);
1101     } else {
1102         gen_set_pc_im(dest);
1103         tcg_gen_exit_tb(0);
1104     }
1105 }
1106
1107 static inline void gen_jmp(DisasContext *s, uint32_t dest)
1108 {
1109     if (unlikely(s->singlestep_enabled)) {
1110         /* An indirect jump so that we still trigger the debug exception.  */
1111         gen_bx_im(s, dest);
1112     } else {
1113         gen_goto_tb(s, 0, dest);
1114         s->is_jmp = DISAS_TB_JUMP;
1115     }
1116 }
1117
1118 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
1119 static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
1120 {
1121     TCGv tmp;
1122     if (bsr) {
1123         /* ??? This is also undefined in system mode.  */
1124         if (IS_USER(s)) {
1125             return 1;
1126         }
1127
1128         tmp = load_cpu_field(bsr);
1129         tcg_gen_andi_i32(tmp, tmp, ~mask);
1130         tcg_gen_andi_i32(t0, t0, mask);
1131         tcg_gen_or_i32(tmp, tmp, t0);
1132         store_cpu_field(tmp, bsr);
1133     } else {
1134         gen_set_asr(t0, mask);
1135     }
1136     dead_tmp(t0);
1137     gen_lookup_tb(s);
1138     return 0;
1139 }
1140
1141 /* Generate an old-style exception return. Marks pc as dead. */
1142 static void gen_exception_return(DisasContext *s, TCGv pc)
1143 {
1144     TCGv tmp;
1145     store_reg(s, 31, pc);
1146     tmp = load_cpu_field(bsr);
1147     gen_set_asr(tmp, 0xffffffff);
1148     dead_tmp(tmp);
1149     s->is_jmp = DISAS_UPDATE;
1150 }
1151
1152 static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s,
1153         uint32_t insn)
1154 {
1155     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1156
1157     switch (UCOP_CPNUM) {
1158 #ifndef CONFIG_USER_ONLY
1159     case 0:
1160         disas_cp0_insn(env, s, insn);
1161         break;
1162     case 1:
1163         disas_ocd_insn(env, s, insn);
1164         break;
1165 #endif
1166     case 2:
1167         disas_ucf64_insn(env, s, insn);
1168         break;
1169     default:
1170         /* Unknown coprocessor. */
1171         cpu_abort(CPU(cpu), "Unknown coprocessor!");
1172     }
1173 }
1174
1175 /* data processing instructions */
1176 static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1177 {
1178     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1179     TCGv tmp;
1180     TCGv tmp2;
1181     int logic_cc;
1182
1183     if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
1184         if (UCOP_SET(23)) { /* CMOV instructions */
1185             if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
1186                 ILLEGAL;
1187             }
1188             /* if not always execute, we generate a conditional jump to
1189                next instruction */
1190             s->condlabel = gen_new_label();
1191             gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
1192             s->condjmp = 1;
1193         }
1194     }
1195
1196     logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);
1197
1198     if (UCOP_SET(29)) {
1199         unsigned int val;
1200         /* immediate operand */
1201         val = UCOP_IMM_9;
1202         if (UCOP_SH_IM) {
1203             val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
1204         }
1205         tmp2 = new_tmp();
1206         tcg_gen_movi_i32(tmp2, val);
1207         if (logic_cc && UCOP_SH_IM) {
1208             gen_set_CF_bit31(tmp2);
1209         }
1210    } else {
1211         /* register */
1212         tmp2 = load_reg(s, UCOP_REG_M);
1213         if (UCOP_SET(5)) {
1214             tmp = load_reg(s, UCOP_REG_S);
1215             gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
1216         } else {
1217             gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
1218         }
1219     }
1220
1221     if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
1222         tmp = load_reg(s, UCOP_REG_N);
1223     } else {
1224         TCGV_UNUSED(tmp);
1225     }
1226
1227     switch (UCOP_OPCODES) {
1228     case 0x00:
1229         tcg_gen_and_i32(tmp, tmp, tmp2);
1230         if (logic_cc) {
1231             gen_logic_CC(tmp);
1232         }
1233         store_reg_bx(s, UCOP_REG_D, tmp);
1234         break;
1235     case 0x01:
1236         tcg_gen_xor_i32(tmp, tmp, tmp2);
1237         if (logic_cc) {
1238             gen_logic_CC(tmp);
1239         }
1240         store_reg_bx(s, UCOP_REG_D, tmp);
1241         break;
1242     case 0x02:
1243         if (UCOP_SET_S && UCOP_REG_D == 31) {
1244             /* SUBS r31, ... is used for exception return.  */
1245             if (IS_USER(s)) {
1246                 ILLEGAL;
1247             }
1248             gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
1249             gen_exception_return(s, tmp);
1250         } else {
1251             if (UCOP_SET_S) {
1252                 gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
1253             } else {
1254                 tcg_gen_sub_i32(tmp, tmp, tmp2);
1255             }
1256             store_reg_bx(s, UCOP_REG_D, tmp);
1257         }
1258         break;
1259     case 0x03:
1260         if (UCOP_SET_S) {
1261             gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
1262         } else {
1263             tcg_gen_sub_i32(tmp, tmp2, tmp);
1264         }
1265         store_reg_bx(s, UCOP_REG_D, tmp);
1266         break;
1267     case 0x04:
1268         if (UCOP_SET_S) {
1269             gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
1270         } else {
1271             tcg_gen_add_i32(tmp, tmp, tmp2);
1272         }
1273         store_reg_bx(s, UCOP_REG_D, tmp);
1274         break;
1275     case 0x05:
1276         if (UCOP_SET_S) {
1277             gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
1278         } else {
1279             gen_add_carry(tmp, tmp, tmp2);
1280         }
1281         store_reg_bx(s, UCOP_REG_D, tmp);
1282         break;
1283     case 0x06:
1284         if (UCOP_SET_S) {
1285             gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
1286         } else {
1287             gen_sub_carry(tmp, tmp, tmp2);
1288         }
1289         store_reg_bx(s, UCOP_REG_D, tmp);
1290         break;
1291     case 0x07:
1292         if (UCOP_SET_S) {
1293             gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
1294         } else {
1295             gen_sub_carry(tmp, tmp2, tmp);
1296         }
1297         store_reg_bx(s, UCOP_REG_D, tmp);
1298         break;
1299     case 0x08:
1300         if (UCOP_SET_S) {
1301             tcg_gen_and_i32(tmp, tmp, tmp2);
1302             gen_logic_CC(tmp);
1303         }
1304         dead_tmp(tmp);
1305         break;
1306     case 0x09:
1307         if (UCOP_SET_S) {
1308             tcg_gen_xor_i32(tmp, tmp, tmp2);
1309             gen_logic_CC(tmp);
1310         }
1311         dead_tmp(tmp);
1312         break;
1313     case 0x0a:
1314         if (UCOP_SET_S) {
1315             gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
1316         }
1317         dead_tmp(tmp);
1318         break;
1319     case 0x0b:
1320         if (UCOP_SET_S) {
1321             gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
1322         }
1323         dead_tmp(tmp);
1324         break;
1325     case 0x0c:
1326         tcg_gen_or_i32(tmp, tmp, tmp2);
1327         if (logic_cc) {
1328             gen_logic_CC(tmp);
1329         }
1330         store_reg_bx(s, UCOP_REG_D, tmp);
1331         break;
1332     case 0x0d:
1333         if (logic_cc && UCOP_REG_D == 31) {
1334             /* MOVS r31, ... is used for exception return.  */
1335             if (IS_USER(s)) {
1336                 ILLEGAL;
1337             }
1338             gen_exception_return(s, tmp2);
1339         } else {
1340             if (logic_cc) {
1341                 gen_logic_CC(tmp2);
1342             }
1343             store_reg_bx(s, UCOP_REG_D, tmp2);
1344         }
1345         break;
1346     case 0x0e:
1347         tcg_gen_andc_i32(tmp, tmp, tmp2);
1348         if (logic_cc) {
1349             gen_logic_CC(tmp);
1350         }
1351         store_reg_bx(s, UCOP_REG_D, tmp);
1352         break;
1353     default:
1354     case 0x0f:
1355         tcg_gen_not_i32(tmp2, tmp2);
1356         if (logic_cc) {
1357             gen_logic_CC(tmp2);
1358         }
1359         store_reg_bx(s, UCOP_REG_D, tmp2);
1360         break;
1361     }
1362     if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
1363         dead_tmp(tmp2);
1364     }
1365 }
1366
1367 /* multiply */
1368 static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1369 {
1370     TCGv tmp, tmp2, tmp3, tmp4;
1371
1372     if (UCOP_SET(27)) {
1373         /* 64 bit mul */
1374         tmp = load_reg(s, UCOP_REG_M);
1375         tmp2 = load_reg(s, UCOP_REG_N);
1376         if (UCOP_SET(26)) {
1377             tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
1378         } else {
1379             tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
1380         }
1381         if (UCOP_SET(25)) { /* mult accumulate */
1382             tmp3 = load_reg(s, UCOP_REG_LO);
1383             tmp4 = load_reg(s, UCOP_REG_HI);
1384             tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4);
1385             dead_tmp(tmp3);
1386             dead_tmp(tmp4);
1387         }
1388         store_reg(s, UCOP_REG_LO, tmp);
1389         store_reg(s, UCOP_REG_HI, tmp2);
1390     } else {
1391         /* 32 bit mul */
1392         tmp = load_reg(s, UCOP_REG_M);
1393         tmp2 = load_reg(s, UCOP_REG_N);
1394         tcg_gen_mul_i32(tmp, tmp, tmp2);
1395         dead_tmp(tmp2);
1396         if (UCOP_SET(25)) {
1397             /* Add */
1398             tmp2 = load_reg(s, UCOP_REG_S);
1399             tcg_gen_add_i32(tmp, tmp, tmp2);
1400             dead_tmp(tmp2);
1401         }
1402         if (UCOP_SET_S) {
1403             gen_logic_CC(tmp);
1404         }
1405         store_reg(s, UCOP_REG_D, tmp);
1406     }
1407 }
1408
1409 /* miscellaneous instructions */
1410 static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1411 {
1412     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1413     unsigned int val;
1414     TCGv tmp;
1415
1416     if ((insn & 0xffffffe0) == 0x10ffc120) {
1417         /* Trivial implementation equivalent to bx.  */
1418         tmp = load_reg(s, UCOP_REG_M);
1419         gen_bx(s, tmp);
1420         return;
1421     }
1422
1423     if ((insn & 0xfbffc000) == 0x30ffc000) {
1424         /* PSR = immediate */
1425         val = UCOP_IMM_9;
1426         if (UCOP_SH_IM) {
1427             val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
1428         }
1429         tmp = new_tmp();
1430         tcg_gen_movi_i32(tmp, val);
1431         if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
1432             ILLEGAL;
1433         }
1434         return;
1435     }
1436
1437     if ((insn & 0xfbffffe0) == 0x12ffc020) {
1438         /* PSR.flag = reg */
1439         tmp = load_reg(s, UCOP_REG_M);
1440         if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
1441             ILLEGAL;
1442         }
1443         return;
1444     }
1445
1446     if ((insn & 0xfbffffe0) == 0x10ffc020) {
1447         /* PSR = reg */
1448         tmp = load_reg(s, UCOP_REG_M);
1449         if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
1450             ILLEGAL;
1451         }
1452         return;
1453     }
1454
1455     if ((insn & 0xfbf83fff) == 0x10f80000) {
1456         /* reg = PSR */
1457         if (UCOP_SET_B) {
1458             if (IS_USER(s)) {
1459                 ILLEGAL;
1460             }
1461             tmp = load_cpu_field(bsr);
1462         } else {
1463             tmp = new_tmp();
1464             gen_helper_asr_read(tmp, cpu_env);
1465         }
1466         store_reg(s, UCOP_REG_D, tmp);
1467         return;
1468     }
1469
1470     if ((insn & 0xfbf83fe0) == 0x12f80120) {
1471         /* clz */
1472         tmp = load_reg(s, UCOP_REG_M);
1473         if (UCOP_SET(26)) {
1474             gen_helper_clo(tmp, tmp);
1475         } else {
1476             gen_helper_clz(tmp, tmp);
1477         }
1478         store_reg(s, UCOP_REG_D, tmp);
1479         return;
1480     }
1481
1482     /* otherwise */
1483     ILLEGAL;
1484 }
1485
1486 /* load/store I_offset and R_offset */
1487 static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1488 {
1489     unsigned int mmu_idx;
1490     TCGv tmp;
1491     TCGv tmp2;
1492
1493     tmp2 = load_reg(s, UCOP_REG_N);
1494     mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
1495
1496     /* immediate */
1497     if (UCOP_SET_P) {
1498         gen_add_data_offset(s, insn, tmp2);
1499     }
1500
1501     if (UCOP_SET_L) {
1502         /* load */
1503         if (UCOP_SET_B) {
1504             tmp = gen_ld8u(tmp2, mmu_idx);
1505         } else {
1506             tmp = gen_ld32(tmp2, mmu_idx);
1507         }
1508     } else {
1509         /* store */
1510         tmp = load_reg(s, UCOP_REG_D);
1511         if (UCOP_SET_B) {
1512             gen_st8(tmp, tmp2, mmu_idx);
1513         } else {
1514             gen_st32(tmp, tmp2, mmu_idx);
1515         }
1516     }
1517     if (!UCOP_SET_P) {
1518         gen_add_data_offset(s, insn, tmp2);
1519         store_reg(s, UCOP_REG_N, tmp2);
1520     } else if (UCOP_SET_W) {
1521         store_reg(s, UCOP_REG_N, tmp2);
1522     } else {
1523         dead_tmp(tmp2);
1524     }
1525     if (UCOP_SET_L) {
1526         /* Complete the load.  */
1527         if (UCOP_REG_D == 31) {
1528             gen_bx(s, tmp);
1529         } else {
1530             store_reg(s, UCOP_REG_D, tmp);
1531         }
1532     }
1533 }
1534
1535 /* SWP instruction */
1536 static void do_swap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1537 {
1538     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1539     TCGv addr;
1540     TCGv tmp;
1541     TCGv tmp2;
1542
1543     if ((insn & 0xff003fe0) != 0x40000120) {
1544         ILLEGAL;
1545     }
1546
1547     /* ??? This is not really atomic.  However we know
1548        we never have multiple CPUs running in parallel,
1549        so it is good enough.  */
1550     addr = load_reg(s, UCOP_REG_N);
1551     tmp = load_reg(s, UCOP_REG_M);
1552     if (UCOP_SET_B) {
1553         tmp2 = gen_ld8u(addr, IS_USER(s));
1554         gen_st8(tmp, addr, IS_USER(s));
1555     } else {
1556         tmp2 = gen_ld32(addr, IS_USER(s));
1557         gen_st32(tmp, addr, IS_USER(s));
1558     }
1559     dead_tmp(addr);
1560     store_reg(s, UCOP_REG_D, tmp2);
1561 }
1562
1563 /* load/store hw/sb */
1564 static void do_ldst_hwsb(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1565 {
1566     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1567     TCGv addr;
1568     TCGv tmp;
1569
1570     if (UCOP_SH_OP == 0) {
1571         do_swap(env, s, insn);
1572         return;
1573     }
1574
1575     addr = load_reg(s, UCOP_REG_N);
1576     if (UCOP_SET_P) {
1577         gen_add_datah_offset(s, insn, addr);
1578     }
1579
1580     if (UCOP_SET_L) { /* load */
1581         switch (UCOP_SH_OP) {
1582         case 1:
1583             tmp = gen_ld16u(addr, IS_USER(s));
1584             break;
1585         case 2:
1586             tmp = gen_ld8s(addr, IS_USER(s));
1587             break;
1588         default: /* see do_swap */
1589         case 3:
1590             tmp = gen_ld16s(addr, IS_USER(s));
1591             break;
1592         }
1593     } else { /* store */
1594         if (UCOP_SH_OP != 1) {
1595             ILLEGAL;
1596         }
1597         tmp = load_reg(s, UCOP_REG_D);
1598         gen_st16(tmp, addr, IS_USER(s));
1599     }
1600     /* Perform base writeback before the loaded value to
1601        ensure correct behavior with overlapping index registers. */
1602     if (!UCOP_SET_P) {
1603         gen_add_datah_offset(s, insn, addr);
1604         store_reg(s, UCOP_REG_N, addr);
1605     } else if (UCOP_SET_W) {
1606         store_reg(s, UCOP_REG_N, addr);
1607     } else {
1608         dead_tmp(addr);
1609     }
1610     if (UCOP_SET_L) {
1611         /* Complete the load.  */
1612         store_reg(s, UCOP_REG_D, tmp);
1613     }
1614 }
1615
1616 /* load/store multiple words */
1617 static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1618 {
1619     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1620     unsigned int val, i, mmu_idx;
1621     int j, n, reg, user, loaded_base;
1622     TCGv tmp;
1623     TCGv tmp2;
1624     TCGv addr;
1625     TCGv loaded_var;
1626
1627     if (UCOP_SET(7)) {
1628         ILLEGAL;
1629     }
1630     /* XXX: store correct base if write back */
1631     user = 0;
1632     if (UCOP_SET_B) { /* S bit in instruction table */
1633         if (IS_USER(s)) {
1634             ILLEGAL; /* only usable in supervisor mode */
1635         }
1636         if (UCOP_SET(18) == 0) { /* pc reg */
1637             user = 1;
1638         }
1639     }
1640
1641     mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
1642     addr = load_reg(s, UCOP_REG_N);
1643
1644     /* compute total size */
1645     loaded_base = 0;
1646     TCGV_UNUSED(loaded_var);
1647     n = 0;
1648     for (i = 0; i < 6; i++) {
1649         if (UCOP_SET(i)) {
1650             n++;
1651         }
1652     }
1653     for (i = 9; i < 19; i++) {
1654         if (UCOP_SET(i)) {
1655             n++;
1656         }
1657     }
1658     /* XXX: test invalid n == 0 case ? */
1659     if (UCOP_SET_U) {
1660         if (UCOP_SET_P) {
1661             /* pre increment */
1662             tcg_gen_addi_i32(addr, addr, 4);
1663         } else {
1664             /* post increment */
1665         }
1666     } else {
1667         if (UCOP_SET_P) {
1668             /* pre decrement */
1669             tcg_gen_addi_i32(addr, addr, -(n * 4));
1670         } else {
1671             /* post decrement */
1672             if (n != 1) {
1673                 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
1674             }
1675         }
1676     }
1677
1678     j = 0;
1679     reg = UCOP_SET(6) ? 16 : 0;
1680     for (i = 0; i < 19; i++, reg++) {
1681         if (i == 6) {
1682             i = i + 3;
1683         }
1684         if (UCOP_SET(i)) {
1685             if (UCOP_SET_L) { /* load */
1686                 tmp = gen_ld32(addr, mmu_idx);
1687                 if (reg == 31) {
1688                     gen_bx(s, tmp);
1689                 } else if (user) {
1690                     tmp2 = tcg_const_i32(reg);
1691                     gen_helper_set_user_reg(cpu_env, tmp2, tmp);
1692                     tcg_temp_free_i32(tmp2);
1693                     dead_tmp(tmp);
1694                 } else if (reg == UCOP_REG_N) {
1695                     loaded_var = tmp;
1696                     loaded_base = 1;
1697                 } else {
1698                     store_reg(s, reg, tmp);
1699                 }
1700             } else { /* store */
1701                 if (reg == 31) {
1702                     /* special case: r31 = PC + 4 */
1703                     val = (long)s->pc;
1704                     tmp = new_tmp();
1705                     tcg_gen_movi_i32(tmp, val);
1706                 } else if (user) {
1707                     tmp = new_tmp();
1708                     tmp2 = tcg_const_i32(reg);
1709                     gen_helper_get_user_reg(tmp, cpu_env, tmp2);
1710                     tcg_temp_free_i32(tmp2);
1711                 } else {
1712                     tmp = load_reg(s, reg);
1713                 }
1714                 gen_st32(tmp, addr, mmu_idx);
1715             }
1716             j++;
1717             /* no need to add after the last transfer */
1718             if (j != n) {
1719                 tcg_gen_addi_i32(addr, addr, 4);
1720             }
1721         }
1722     }
1723     if (UCOP_SET_W) { /* write back */
1724         if (UCOP_SET_U) {
1725             if (UCOP_SET_P) {
1726                 /* pre increment */
1727             } else {
1728                 /* post increment */
1729                 tcg_gen_addi_i32(addr, addr, 4);
1730             }
1731         } else {
1732             if (UCOP_SET_P) {
1733                 /* pre decrement */
1734                 if (n != 1) {
1735                     tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
1736                 }
1737             } else {
1738                 /* post decrement */
1739                 tcg_gen_addi_i32(addr, addr, -(n * 4));
1740             }
1741         }
1742         store_reg(s, UCOP_REG_N, addr);
1743     } else {
1744         dead_tmp(addr);
1745     }
1746     if (loaded_base) {
1747         store_reg(s, UCOP_REG_N, loaded_var);
1748     }
1749     if (UCOP_SET_B && !user) {
1750         /* Restore ASR from BSR.  */
1751         tmp = load_cpu_field(bsr);
1752         gen_set_asr(tmp, 0xffffffff);
1753         dead_tmp(tmp);
1754         s->is_jmp = DISAS_UPDATE;
1755     }
1756 }
1757
1758 /* branch (and link) */
1759 static void do_branch(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1760 {
1761     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1762     unsigned int val;
1763     int32_t offset;
1764     TCGv tmp;
1765
1766     if (UCOP_COND == 0xf) {
1767         ILLEGAL;
1768     }
1769
1770     if (UCOP_COND != 0xe) {
1771         /* if not always execute, we generate a conditional jump to
1772            next instruction */
1773         s->condlabel = gen_new_label();
1774         gen_test_cc(UCOP_COND ^ 1, s->condlabel);
1775         s->condjmp = 1;
1776     }
1777
1778     val = (int32_t)s->pc;
1779     if (UCOP_SET_L) {
1780         tmp = new_tmp();
1781         tcg_gen_movi_i32(tmp, val);
1782         store_reg(s, 30, tmp);
1783     }
1784     offset = (((int32_t)insn << 8) >> 8);
1785     val += (offset << 2); /* unicore is pc+4 */
1786     gen_jmp(s, val);
1787 }
1788
1789 static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
1790 {
1791     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1792     unsigned int insn;
1793
1794     insn = cpu_ldl_code(env, s->pc);
1795     s->pc += 4;
1796
1797     /* UniCore instructions class:
1798      * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
1799      * AAA  : see switch case
1800      * BBBB : opcodes or cond or PUBW
1801      * C    : S OR L
1802      * D    : 8
1803      * E    : 5
1804      */
1805     switch (insn >> 29) {
1806     case 0x0:
1807         if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
1808             do_mult(env, s, insn);
1809             break;
1810         }
1811
1812         if (UCOP_SET(8)) {
1813             do_misc(env, s, insn);
1814             break;
1815         }
1816     case 0x1:
1817         if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
1818             do_misc(env, s, insn);
1819             break;
1820         }
1821         do_datap(env, s, insn);
1822         break;
1823
1824     case 0x2:
1825         if (UCOP_SET(8) && UCOP_SET(5)) {
1826             do_ldst_hwsb(env, s, insn);
1827             break;
1828         }
1829         if (UCOP_SET(8) || UCOP_SET(5)) {
1830             ILLEGAL;
1831         }
1832     case 0x3:
1833         do_ldst_ir(env, s, insn);
1834         break;
1835
1836     case 0x4:
1837         if (UCOP_SET(8)) {
1838             ILLEGAL; /* extended instructions */
1839         }
1840         do_ldst_m(env, s, insn);
1841         break;
1842     case 0x5:
1843         do_branch(env, s, insn);
1844         break;
1845     case 0x6:
1846         /* Coprocessor.  */
1847         disas_coproc_insn(env, s, insn);
1848         break;
1849     case 0x7:
1850         if (!UCOP_SET(28)) {
1851             disas_coproc_insn(env, s, insn);
1852             break;
1853         }
1854         if ((insn & 0xff000000) == 0xff000000) { /* syscall */
1855             gen_set_pc_im(s->pc);
1856             s->is_jmp = DISAS_SYSCALL;
1857             break;
1858         }
1859         ILLEGAL;
1860     }
1861 }
1862
1863 /* generate intermediate code for basic block 'tb'.  */
1864 void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
1865 {
1866     UniCore32CPU *cpu = uc32_env_get_cpu(env);
1867     CPUState *cs = CPU(cpu);
1868     DisasContext dc1, *dc = &dc1;
1869     target_ulong pc_start;
1870     uint32_t next_page_start;
1871     int num_insns;
1872     int max_insns;
1873
1874     /* generate intermediate code */
1875     num_temps = 0;
1876
1877     pc_start = tb->pc;
1878
1879     dc->tb = tb;
1880
1881     dc->is_jmp = DISAS_NEXT;
1882     dc->pc = pc_start;
1883     dc->singlestep_enabled = cs->singlestep_enabled;
1884     dc->condjmp = 0;
1885     cpu_F0s = tcg_temp_new_i32();
1886     cpu_F1s = tcg_temp_new_i32();
1887     cpu_F0d = tcg_temp_new_i64();
1888     cpu_F1d = tcg_temp_new_i64();
1889     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1890     num_insns = 0;
1891     max_insns = tb->cflags & CF_COUNT_MASK;
1892     if (max_insns == 0) {
1893         max_insns = CF_COUNT_MASK;
1894     }
1895     if (max_insns > TCG_MAX_INSNS) {
1896         max_insns = TCG_MAX_INSNS;
1897     }
1898
1899 #ifndef CONFIG_USER_ONLY
1900     if ((env->uncached_asr & ASR_M) == ASR_MODE_USER) {
1901         dc->user = 1;
1902     } else {
1903         dc->user = 0;
1904     }
1905 #endif
1906
1907     gen_tb_start(tb);
1908     do {
1909         tcg_gen_insn_start(dc->pc);
1910         num_insns++;
1911
1912         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
1913             gen_set_pc_im(dc->pc);
1914             gen_exception(EXCP_DEBUG);
1915             dc->is_jmp = DISAS_JUMP;
1916             /* The address covered by the breakpoint must be included in
1917                [tb->pc, tb->pc + tb->size) in order to for it to be
1918                properly cleared -- thus we increment the PC here so that
1919                the logic setting tb->size below does the right thing.  */
1920             dc->pc += 4;
1921             goto done_generating;
1922         }
1923
1924         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
1925             gen_io_start();
1926         }
1927
1928         disas_uc32_insn(env, dc);
1929
1930         if (num_temps) {
1931             fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
1932             num_temps = 0;
1933         }
1934
1935         if (dc->condjmp && !dc->is_jmp) {
1936             gen_set_label(dc->condlabel);
1937             dc->condjmp = 0;
1938         }
1939         /* Translation stops when a conditional branch is encountered.
1940          * Otherwise the subsequent code could get translated several times.
1941          * Also stop translation when a page boundary is reached.  This
1942          * ensures prefetch aborts occur at the right place.  */
1943     } while (!dc->is_jmp && !tcg_op_buf_full() &&
1944              !cs->singlestep_enabled &&
1945              !singlestep &&
1946              dc->pc < next_page_start &&
1947              num_insns < max_insns);
1948
1949     if (tb->cflags & CF_LAST_IO) {
1950         if (dc->condjmp) {
1951             /* FIXME:  This can theoretically happen with self-modifying
1952                code.  */
1953             cpu_abort(cs, "IO on conditional branch instruction");
1954         }
1955         gen_io_end();
1956     }
1957
1958     /* At this stage dc->condjmp will only be set when the skipped
1959        instruction was a conditional branch or trap, and the PC has
1960        already been written.  */
1961     if (unlikely(cs->singlestep_enabled)) {
1962         /* Make sure the pc is updated, and raise a debug exception.  */
1963         if (dc->condjmp) {
1964             if (dc->is_jmp == DISAS_SYSCALL) {
1965                 gen_exception(UC32_EXCP_PRIV);
1966             } else {
1967                 gen_exception(EXCP_DEBUG);
1968             }
1969             gen_set_label(dc->condlabel);
1970         }
1971         if (dc->condjmp || !dc->is_jmp) {
1972             gen_set_pc_im(dc->pc);
1973             dc->condjmp = 0;
1974         }
1975         if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
1976             gen_exception(UC32_EXCP_PRIV);
1977         } else {
1978             gen_exception(EXCP_DEBUG);
1979         }
1980     } else {
1981         /* While branches must always occur at the end of an IT block,
1982            there are a few other things that can cause us to terminate
1983            the TB in the middel of an IT block:
1984             - Exception generating instructions (bkpt, swi, undefined).
1985             - Page boundaries.
1986             - Hardware watchpoints.
1987            Hardware breakpoints have already been handled and skip this code.
1988          */
1989         switch (dc->is_jmp) {
1990         case DISAS_NEXT:
1991             gen_goto_tb(dc, 1, dc->pc);
1992             break;
1993         default:
1994         case DISAS_JUMP:
1995         case DISAS_UPDATE:
1996             /* indicate that the hash table must be used to find the next TB */
1997             tcg_gen_exit_tb(0);
1998             break;
1999         case DISAS_TB_JUMP:
2000             /* nothing more to generate */
2001             break;
2002         case DISAS_SYSCALL:
2003             gen_exception(UC32_EXCP_PRIV);
2004             break;
2005         }
2006         if (dc->condjmp) {
2007             gen_set_label(dc->condlabel);
2008             gen_goto_tb(dc, 1, dc->pc);
2009             dc->condjmp = 0;
2010         }
2011     }
2012
2013 done_generating:
2014     gen_tb_end(tb, num_insns);
2015
2016 #ifdef DEBUG_DISAS
2017     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
2018         qemu_log("----------------\n");
2019         qemu_log("IN: %s\n", lookup_symbol(pc_start));
2020         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
2021         qemu_log("\n");
2022     }
2023 #endif
2024     tb->size = dc->pc - pc_start;
2025     tb->icount = num_insns;
2026 }
2027
2028 static const char *cpu_mode_names[16] = {
2029     "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
2030     "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
2031 };
2032
2033 #undef UCF64_DUMP_STATE
2034 #ifdef UCF64_DUMP_STATE
2035 static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
2036         fprintf_function cpu_fprintf, int flags)
2037 {
2038     int i;
2039     union {
2040         uint32_t i;
2041         float s;
2042     } s0, s1;
2043     CPU_DoubleU d;
2044     /* ??? This assumes float64 and double have the same layout.
2045        Oh well, it's only debug dumps.  */
2046     union {
2047         float64 f64;
2048         double d;
2049     } d0;
2050
2051     for (i = 0; i < 16; i++) {
2052         d.d = env->ucf64.regs[i];
2053         s0.i = d.l.lower;
2054         s1.i = d.l.upper;
2055         d0.f64 = d.d;
2056         cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
2057                     i * 2, (int)s0.i, s0.s,
2058                     i * 2 + 1, (int)s1.i, s1.s);
2059         cpu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
2060                     i, (uint64_t)d0.f64, d0.d);
2061     }
2062     cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
2063 }
2064 #else
2065 #define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
2066 #endif
2067
2068 void uc32_cpu_dump_state(CPUState *cs, FILE *f,
2069                          fprintf_function cpu_fprintf, int flags)
2070 {
2071     UniCore32CPU *cpu = UNICORE32_CPU(cs);
2072     CPUUniCore32State *env = &cpu->env;
2073     int i;
2074     uint32_t psr;
2075
2076     for (i = 0; i < 32; i++) {
2077         cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
2078         if ((i % 4) == 3) {
2079             cpu_fprintf(f, "\n");
2080         } else {
2081             cpu_fprintf(f, " ");
2082         }
2083     }
2084     psr = cpu_asr_read(env);
2085     cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
2086                 psr,
2087                 psr & (1 << 31) ? 'N' : '-',
2088                 psr & (1 << 30) ? 'Z' : '-',
2089                 psr & (1 << 29) ? 'C' : '-',
2090                 psr & (1 << 28) ? 'V' : '-',
2091                 cpu_mode_names[psr & 0xf]);
2092
2093     cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
2094 }
2095
2096 void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
2097                           target_ulong *data)
2098 {
2099     env->regs[31] = data[0];
2100 }