Add qemu 2.4.0
[kvmfornfv.git] / qemu / target-microblaze / translate.c
1 /*
2  *  Xilinx MicroBlaze emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2009 Edgar E. Iglesias.
5  *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
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 #include "cpu.h"
22 #include "disas/disas.h"
23 #include "tcg-op.h"
24 #include "exec/helper-proto.h"
25 #include "microblaze-decode.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/helper-gen.h"
28
29 #include "trace-tcg.h"
30
31
32 #define SIM_COMPAT 0
33 #define DISAS_GNU 1
34 #define DISAS_MB 1
35 #if DISAS_MB && !SIM_COMPAT
36 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
37 #else
38 #  define LOG_DIS(...) do { } while (0)
39 #endif
40
41 #define D(x)
42
43 #define EXTRACT_FIELD(src, start, end) \
44             (((src) >> start) & ((1 << (end - start + 1)) - 1))
45
46 static TCGv env_debug;
47 static TCGv_ptr cpu_env;
48 static TCGv cpu_R[32];
49 static TCGv cpu_SR[18];
50 static TCGv env_imm;
51 static TCGv env_btaken;
52 static TCGv env_btarget;
53 static TCGv env_iflags;
54 static TCGv env_res_addr;
55 static TCGv env_res_val;
56
57 #include "exec/gen-icount.h"
58
59 /* This is the state at translation time.  */
60 typedef struct DisasContext {
61     MicroBlazeCPU *cpu;
62     target_ulong pc;
63
64     /* Decoder.  */
65     int type_b;
66     uint32_t ir;
67     uint8_t opcode;
68     uint8_t rd, ra, rb;
69     uint16_t imm;
70
71     unsigned int cpustate_changed;
72     unsigned int delayed_branch;
73     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
74     unsigned int clear_imm;
75     int is_jmp;
76
77 #define JMP_NOJMP     0
78 #define JMP_DIRECT    1
79 #define JMP_DIRECT_CC 2
80 #define JMP_INDIRECT  3
81     unsigned int jmp;
82     uint32_t jmp_pc;
83
84     int abort_at_next_insn;
85     int nr_nops;
86     struct TranslationBlock *tb;
87     int singlestep_enabled;
88 } DisasContext;
89
90 static const char *regnames[] =
91 {
92     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
93     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
94     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
95     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
96 };
97
98 static const char *special_regnames[] =
99 {
100     "rpc", "rmsr", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
101     "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
102     "sr16", "sr17", "sr18"
103 };
104
105 static inline void t_sync_flags(DisasContext *dc)
106 {
107     /* Synch the tb dependent flags between translator and runtime.  */
108     if (dc->tb_flags != dc->synced_flags) {
109         tcg_gen_movi_tl(env_iflags, dc->tb_flags);
110         dc->synced_flags = dc->tb_flags;
111     }
112 }
113
114 static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
115 {
116     TCGv_i32 tmp = tcg_const_i32(index);
117
118     t_sync_flags(dc);
119     tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
120     gen_helper_raise_exception(cpu_env, tmp);
121     tcg_temp_free_i32(tmp);
122     dc->is_jmp = DISAS_UPDATE;
123 }
124
125 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
126 {
127     TranslationBlock *tb;
128     tb = dc->tb;
129     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
130         tcg_gen_goto_tb(n);
131         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
132         tcg_gen_exit_tb((uintptr_t)tb + n);
133     } else {
134         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
135         tcg_gen_exit_tb(0);
136     }
137 }
138
139 static void read_carry(DisasContext *dc, TCGv d)
140 {
141     tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
142 }
143
144 /*
145  * write_carry sets the carry bits in MSR based on bit 0 of v.
146  * v[31:1] are ignored.
147  */
148 static void write_carry(DisasContext *dc, TCGv v)
149 {
150     TCGv t0 = tcg_temp_new();
151     tcg_gen_shli_tl(t0, v, 31);
152     tcg_gen_sari_tl(t0, t0, 31);
153     tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC));
154     tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR],
155                     ~(MSR_C | MSR_CC));
156     tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0);
157     tcg_temp_free(t0);
158 }
159
160 static void write_carryi(DisasContext *dc, bool carry)
161 {
162     TCGv t0 = tcg_temp_new();
163     tcg_gen_movi_tl(t0, carry);
164     write_carry(dc, t0);
165     tcg_temp_free(t0);
166 }
167
168 /* True if ALU operand b is a small immediate that may deserve
169    faster treatment.  */
170 static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
171 {
172     /* Immediate insn without the imm prefix ?  */
173     return dc->type_b && !(dc->tb_flags & IMM_FLAG);
174 }
175
176 static inline TCGv *dec_alu_op_b(DisasContext *dc)
177 {
178     if (dc->type_b) {
179         if (dc->tb_flags & IMM_FLAG)
180             tcg_gen_ori_tl(env_imm, env_imm, dc->imm);
181         else
182             tcg_gen_movi_tl(env_imm, (int32_t)((int16_t)dc->imm));
183         return &env_imm;
184     } else
185         return &cpu_R[dc->rb];
186 }
187
188 static void dec_add(DisasContext *dc)
189 {
190     unsigned int k, c;
191     TCGv cf;
192
193     k = dc->opcode & 4;
194     c = dc->opcode & 2;
195
196     LOG_DIS("add%s%s%s r%d r%d r%d\n",
197             dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
198             dc->rd, dc->ra, dc->rb);
199
200     /* Take care of the easy cases first.  */
201     if (k) {
202         /* k - keep carry, no need to update MSR.  */
203         /* If rd == r0, it's a nop.  */
204         if (dc->rd) {
205             tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
206
207             if (c) {
208                 /* c - Add carry into the result.  */
209                 cf = tcg_temp_new();
210
211                 read_carry(dc, cf);
212                 tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
213                 tcg_temp_free(cf);
214             }
215         }
216         return;
217     }
218
219     /* From now on, we can assume k is zero.  So we need to update MSR.  */
220     /* Extract carry.  */
221     cf = tcg_temp_new();
222     if (c) {
223         read_carry(dc, cf);
224     } else {
225         tcg_gen_movi_tl(cf, 0);
226     }
227
228     if (dc->rd) {
229         TCGv ncf = tcg_temp_new();
230         gen_helper_carry(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
231         tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
232         tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
233         write_carry(dc, ncf);
234         tcg_temp_free(ncf);
235     } else {
236         gen_helper_carry(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
237         write_carry(dc, cf);
238     }
239     tcg_temp_free(cf);
240 }
241
242 static void dec_sub(DisasContext *dc)
243 {
244     unsigned int u, cmp, k, c;
245     TCGv cf, na;
246
247     u = dc->imm & 2;
248     k = dc->opcode & 4;
249     c = dc->opcode & 2;
250     cmp = (dc->imm & 1) && (!dc->type_b) && k;
251
252     if (cmp) {
253         LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir);
254         if (dc->rd) {
255             if (u)
256                 gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
257             else
258                 gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
259         }
260         return;
261     }
262
263     LOG_DIS("sub%s%s r%d, r%d r%d\n",
264              k ? "k" : "",  c ? "c" : "", dc->rd, dc->ra, dc->rb);
265
266     /* Take care of the easy cases first.  */
267     if (k) {
268         /* k - keep carry, no need to update MSR.  */
269         /* If rd == r0, it's a nop.  */
270         if (dc->rd) {
271             tcg_gen_sub_tl(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
272
273             if (c) {
274                 /* c - Add carry into the result.  */
275                 cf = tcg_temp_new();
276
277                 read_carry(dc, cf);
278                 tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
279                 tcg_temp_free(cf);
280             }
281         }
282         return;
283     }
284
285     /* From now on, we can assume k is zero.  So we need to update MSR.  */
286     /* Extract carry. And complement a into na.  */
287     cf = tcg_temp_new();
288     na = tcg_temp_new();
289     if (c) {
290         read_carry(dc, cf);
291     } else {
292         tcg_gen_movi_tl(cf, 1);
293     }
294
295     /* d = b + ~a + c. carry defaults to 1.  */
296     tcg_gen_not_tl(na, cpu_R[dc->ra]);
297
298     if (dc->rd) {
299         TCGv ncf = tcg_temp_new();
300         gen_helper_carry(ncf, na, *(dec_alu_op_b(dc)), cf);
301         tcg_gen_add_tl(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
302         tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
303         write_carry(dc, ncf);
304         tcg_temp_free(ncf);
305     } else {
306         gen_helper_carry(cf, na, *(dec_alu_op_b(dc)), cf);
307         write_carry(dc, cf);
308     }
309     tcg_temp_free(cf);
310     tcg_temp_free(na);
311 }
312
313 static void dec_pattern(DisasContext *dc)
314 {
315     unsigned int mode;
316     TCGLabel *l1;
317
318     if ((dc->tb_flags & MSR_EE_FLAG)
319           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
320           && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
321         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
322         t_gen_raise_exception(dc, EXCP_HW_EXCP);
323     }
324
325     mode = dc->opcode & 3;
326     switch (mode) {
327         case 0:
328             /* pcmpbf.  */
329             LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
330             if (dc->rd)
331                 gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
332             break;
333         case 2:
334             LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
335             if (dc->rd) {
336                 TCGv t0 = tcg_temp_local_new();
337                 l1 = gen_new_label();
338                 tcg_gen_movi_tl(t0, 1);
339                 tcg_gen_brcond_tl(TCG_COND_EQ,
340                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
341                 tcg_gen_movi_tl(t0, 0);
342                 gen_set_label(l1);
343                 tcg_gen_mov_tl(cpu_R[dc->rd], t0);
344                 tcg_temp_free(t0);
345             }
346             break;
347         case 3:
348             LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
349             l1 = gen_new_label();
350             if (dc->rd) {
351                 TCGv t0 = tcg_temp_local_new();
352                 tcg_gen_movi_tl(t0, 1);
353                 tcg_gen_brcond_tl(TCG_COND_NE,
354                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
355                 tcg_gen_movi_tl(t0, 0);
356                 gen_set_label(l1);
357                 tcg_gen_mov_tl(cpu_R[dc->rd], t0);
358                 tcg_temp_free(t0);
359             }
360             break;
361         default:
362             cpu_abort(CPU(dc->cpu),
363                       "unsupported pattern insn opcode=%x\n", dc->opcode);
364             break;
365     }
366 }
367
368 static void dec_and(DisasContext *dc)
369 {
370     unsigned int not;
371
372     if (!dc->type_b && (dc->imm & (1 << 10))) {
373         dec_pattern(dc);
374         return;
375     }
376
377     not = dc->opcode & (1 << 1);
378     LOG_DIS("and%s\n", not ? "n" : "");
379
380     if (!dc->rd)
381         return;
382
383     if (not) {
384         tcg_gen_andc_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
385     } else
386         tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
387 }
388
389 static void dec_or(DisasContext *dc)
390 {
391     if (!dc->type_b && (dc->imm & (1 << 10))) {
392         dec_pattern(dc);
393         return;
394     }
395
396     LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
397     if (dc->rd)
398         tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
399 }
400
401 static void dec_xor(DisasContext *dc)
402 {
403     if (!dc->type_b && (dc->imm & (1 << 10))) {
404         dec_pattern(dc);
405         return;
406     }
407
408     LOG_DIS("xor r%d\n", dc->rd);
409     if (dc->rd)
410         tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
411 }
412
413 static inline void msr_read(DisasContext *dc, TCGv d)
414 {
415     tcg_gen_mov_tl(d, cpu_SR[SR_MSR]);
416 }
417
418 static inline void msr_write(DisasContext *dc, TCGv v)
419 {
420     TCGv t;
421
422     t = tcg_temp_new();
423     dc->cpustate_changed = 1;
424     /* PVR bit is not writable.  */
425     tcg_gen_andi_tl(t, v, ~MSR_PVR);
426     tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
427     tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
428     tcg_temp_free(t);
429 }
430
431 static void dec_msr(DisasContext *dc)
432 {
433     CPUState *cs = CPU(dc->cpu);
434     TCGv t0, t1;
435     unsigned int sr, to, rn;
436     int mem_index = cpu_mmu_index(&dc->cpu->env);
437
438     sr = dc->imm & ((1 << 14) - 1);
439     to = dc->imm & (1 << 14);
440     dc->type_b = 1;
441     if (to)
442         dc->cpustate_changed = 1;
443
444     /* msrclr and msrset.  */
445     if (!(dc->imm & (1 << 15))) {
446         unsigned int clr = dc->ir & (1 << 16);
447
448         LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
449                 dc->rd, dc->imm);
450
451         if (!(dc->cpu->env.pvr.regs[2] & PVR2_USE_MSR_INSTR)) {
452             /* nop??? */
453             return;
454         }
455
456         if ((dc->tb_flags & MSR_EE_FLAG)
457             && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) {
458             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
459             t_gen_raise_exception(dc, EXCP_HW_EXCP);
460             return;
461         }
462
463         if (dc->rd)
464             msr_read(dc, cpu_R[dc->rd]);
465
466         t0 = tcg_temp_new();
467         t1 = tcg_temp_new();
468         msr_read(dc, t0);
469         tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc)));
470
471         if (clr) {
472             tcg_gen_not_tl(t1, t1);
473             tcg_gen_and_tl(t0, t0, t1);
474         } else
475             tcg_gen_or_tl(t0, t0, t1);
476         msr_write(dc, t0);
477         tcg_temp_free(t0);
478         tcg_temp_free(t1);
479         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
480         dc->is_jmp = DISAS_UPDATE;
481         return;
482     }
483
484     if (to) {
485         if ((dc->tb_flags & MSR_EE_FLAG)
486              && mem_index == MMU_USER_IDX) {
487             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
488             t_gen_raise_exception(dc, EXCP_HW_EXCP);
489             return;
490         }
491     }
492
493 #if !defined(CONFIG_USER_ONLY)
494     /* Catch read/writes to the mmu block.  */
495     if ((sr & ~0xff) == 0x1000) {
496         sr &= 7;
497         LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
498         if (to)
499             gen_helper_mmu_write(cpu_env, tcg_const_tl(sr), cpu_R[dc->ra]);
500         else
501             gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_tl(sr));
502         return;
503     }
504 #endif
505
506     if (to) {
507         LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
508         switch (sr) {
509             case 0:
510                 break;
511             case 1:
512                 msr_write(dc, cpu_R[dc->ra]);
513                 break;
514             case 0x3:
515                 tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]);
516                 break;
517             case 0x5:
518                 tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]);
519                 break;
520             case 0x7:
521                 tcg_gen_andi_tl(cpu_SR[SR_FSR], cpu_R[dc->ra], 31);
522                 break;
523             case 0x800:
524                 tcg_gen_st_tl(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, slr));
525                 break;
526             case 0x802:
527                 tcg_gen_st_tl(cpu_R[dc->ra], cpu_env, offsetof(CPUMBState, shr));
528                 break;
529             default:
530                 cpu_abort(CPU(dc->cpu), "unknown mts reg %x\n", sr);
531                 break;
532         }
533     } else {
534         LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);
535
536         switch (sr) {
537             case 0:
538                 tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
539                 break;
540             case 1:
541                 msr_read(dc, cpu_R[dc->rd]);
542                 break;
543             case 0x3:
544                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]);
545                 break;
546             case 0x5:
547                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]);
548                 break;
549              case 0x7:
550                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_FSR]);
551                 break;
552             case 0xb:
553                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]);
554                 break;
555             case 0x800:
556                 tcg_gen_ld_tl(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, slr));
557                 break;
558             case 0x802:
559                 tcg_gen_ld_tl(cpu_R[dc->rd], cpu_env, offsetof(CPUMBState, shr));
560                 break;
561             case 0x2000:
562             case 0x2001:
563             case 0x2002:
564             case 0x2003:
565             case 0x2004:
566             case 0x2005:
567             case 0x2006:
568             case 0x2007:
569             case 0x2008:
570             case 0x2009:
571             case 0x200a:
572             case 0x200b:
573             case 0x200c:
574                 rn = sr & 0xf;
575                 tcg_gen_ld_tl(cpu_R[dc->rd],
576                               cpu_env, offsetof(CPUMBState, pvr.regs[rn]));
577                 break;
578             default:
579                 cpu_abort(cs, "unknown mfs reg %x\n", sr);
580                 break;
581         }
582     }
583
584     if (dc->rd == 0) {
585         tcg_gen_movi_tl(cpu_R[0], 0);
586     }
587 }
588
589 /* 64-bit signed mul, lower result in d and upper in d2.  */
590 static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
591 {
592     TCGv_i64 t0, t1;
593
594     t0 = tcg_temp_new_i64();
595     t1 = tcg_temp_new_i64();
596
597     tcg_gen_ext_i32_i64(t0, a);
598     tcg_gen_ext_i32_i64(t1, b);
599     tcg_gen_mul_i64(t0, t0, t1);
600
601     tcg_gen_trunc_i64_i32(d, t0);
602     tcg_gen_shri_i64(t0, t0, 32);
603     tcg_gen_trunc_i64_i32(d2, t0);
604
605     tcg_temp_free_i64(t0);
606     tcg_temp_free_i64(t1);
607 }
608
609 /* 64-bit unsigned muls, lower result in d and upper in d2.  */
610 static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
611 {
612     TCGv_i64 t0, t1;
613
614     t0 = tcg_temp_new_i64();
615     t1 = tcg_temp_new_i64();
616
617     tcg_gen_extu_i32_i64(t0, a);
618     tcg_gen_extu_i32_i64(t1, b);
619     tcg_gen_mul_i64(t0, t0, t1);
620
621     tcg_gen_trunc_i64_i32(d, t0);
622     tcg_gen_shri_i64(t0, t0, 32);
623     tcg_gen_trunc_i64_i32(d2, t0);
624
625     tcg_temp_free_i64(t0);
626     tcg_temp_free_i64(t1);
627 }
628
629 /* Multiplier unit.  */
630 static void dec_mul(DisasContext *dc)
631 {
632     TCGv d[2];
633     unsigned int subcode;
634
635     if ((dc->tb_flags & MSR_EE_FLAG)
636          && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
637          && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
638         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
639         t_gen_raise_exception(dc, EXCP_HW_EXCP);
640         return;
641     }
642
643     subcode = dc->imm & 3;
644     d[0] = tcg_temp_new();
645     d[1] = tcg_temp_new();
646
647     if (dc->type_b) {
648         LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
649         t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
650         goto done;
651     }
652
653     /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
654     if (subcode >= 1 && subcode <= 3
655         && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
656         /* nop??? */
657     }
658
659     switch (subcode) {
660         case 0:
661             LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
662             t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
663             break;
664         case 1:
665             LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
666             t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
667             break;
668         case 2:
669             LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
670             t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
671             break;
672         case 3:
673             LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
674             t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
675             break;
676         default:
677             cpu_abort(CPU(dc->cpu), "unknown MUL insn %x\n", subcode);
678             break;
679     }
680 done:
681     tcg_temp_free(d[0]);
682     tcg_temp_free(d[1]);
683 }
684
685 /* Div unit.  */
686 static void dec_div(DisasContext *dc)
687 {
688     unsigned int u;
689
690     u = dc->imm & 2; 
691     LOG_DIS("div\n");
692
693     if ((dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
694           && !((dc->cpu->env.pvr.regs[0] & PVR0_USE_DIV_MASK))) {
695         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
696         t_gen_raise_exception(dc, EXCP_HW_EXCP);
697     }
698
699     if (u)
700         gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
701                         cpu_R[dc->ra]);
702     else
703         gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
704                         cpu_R[dc->ra]);
705     if (!dc->rd)
706         tcg_gen_movi_tl(cpu_R[dc->rd], 0);
707 }
708
709 static void dec_barrel(DisasContext *dc)
710 {
711     TCGv t0;
712     unsigned int s, t;
713
714     if ((dc->tb_flags & MSR_EE_FLAG)
715           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
716           && !(dc->cpu->env.pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
717         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
718         t_gen_raise_exception(dc, EXCP_HW_EXCP);
719         return;
720     }
721
722     s = dc->imm & (1 << 10);
723     t = dc->imm & (1 << 9);
724
725     LOG_DIS("bs%s%s r%d r%d r%d\n",
726             s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
727
728     t0 = tcg_temp_new();
729
730     tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
731     tcg_gen_andi_tl(t0, t0, 31);
732
733     if (s)
734         tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
735     else {
736         if (t)
737             tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
738         else
739             tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
740     }
741 }
742
743 static void dec_bit(DisasContext *dc)
744 {
745     CPUState *cs = CPU(dc->cpu);
746     TCGv t0;
747     unsigned int op;
748     int mem_index = cpu_mmu_index(&dc->cpu->env);
749
750     op = dc->ir & ((1 << 9) - 1);
751     switch (op) {
752         case 0x21:
753             /* src.  */
754             t0 = tcg_temp_new();
755
756             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
757             tcg_gen_andi_tl(t0, cpu_SR[SR_MSR], MSR_CC);
758             write_carry(dc, cpu_R[dc->ra]);
759             if (dc->rd) {
760                 tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
761                 tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t0);
762             }
763             tcg_temp_free(t0);
764             break;
765
766         case 0x1:
767         case 0x41:
768             /* srl.  */
769             LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
770
771             /* Update carry. Note that write carry only looks at the LSB.  */
772             write_carry(dc, cpu_R[dc->ra]);
773             if (dc->rd) {
774                 if (op == 0x41)
775                     tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
776                 else
777                     tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
778             }
779             break;
780         case 0x60:
781             LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
782             tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
783             break;
784         case 0x61:
785             LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
786             tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
787             break;
788         case 0x64:
789         case 0x66:
790         case 0x74:
791         case 0x76:
792             /* wdc.  */
793             LOG_DIS("wdc r%d\n", dc->ra);
794             if ((dc->tb_flags & MSR_EE_FLAG)
795                  && mem_index == MMU_USER_IDX) {
796                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
797                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
798                 return;
799             }
800             break;
801         case 0x68:
802             /* wic.  */
803             LOG_DIS("wic r%d\n", dc->ra);
804             if ((dc->tb_flags & MSR_EE_FLAG)
805                  && mem_index == MMU_USER_IDX) {
806                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
807                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
808                 return;
809             }
810             break;
811         case 0xe0:
812             if ((dc->tb_flags & MSR_EE_FLAG)
813                 && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
814                 && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
815                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
816                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
817             }
818             if (dc->cpu->env.pvr.regs[2] & PVR2_USE_PCMP_INSTR) {
819                 gen_helper_clz(cpu_R[dc->rd], cpu_R[dc->ra]);
820             }
821             break;
822         case 0x1e0:
823             /* swapb */
824             LOG_DIS("swapb r%d r%d\n", dc->rd, dc->ra);
825             tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
826             break;
827         case 0x1e2:
828             /*swaph */
829             LOG_DIS("swaph r%d r%d\n", dc->rd, dc->ra);
830             tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16);
831             break;
832         default:
833             cpu_abort(cs, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
834                       dc->pc, op, dc->rd, dc->ra, dc->rb);
835             break;
836     }
837 }
838
839 static inline void sync_jmpstate(DisasContext *dc)
840 {
841     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
842         if (dc->jmp == JMP_DIRECT) {
843             tcg_gen_movi_tl(env_btaken, 1);
844         }
845         dc->jmp = JMP_INDIRECT;
846         tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
847     }
848 }
849
850 static void dec_imm(DisasContext *dc)
851 {
852     LOG_DIS("imm %x\n", dc->imm << 16);
853     tcg_gen_movi_tl(env_imm, (dc->imm << 16));
854     dc->tb_flags |= IMM_FLAG;
855     dc->clear_imm = 0;
856 }
857
858 static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
859 {
860     unsigned int extimm = dc->tb_flags & IMM_FLAG;
861     /* Should be set to one if r1 is used by loadstores.  */
862     int stackprot = 0;
863
864     /* All load/stores use ra.  */
865     if (dc->ra == 1 && dc->cpu->cfg.stackprot) {
866         stackprot = 1;
867     }
868
869     /* Treat the common cases first.  */
870     if (!dc->type_b) {
871         /* If any of the regs is r0, return a ptr to the other.  */
872         if (dc->ra == 0) {
873             return &cpu_R[dc->rb];
874         } else if (dc->rb == 0) {
875             return &cpu_R[dc->ra];
876         }
877
878         if (dc->rb == 1 && dc->cpu->cfg.stackprot) {
879             stackprot = 1;
880         }
881
882         *t = tcg_temp_new();
883         tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
884
885         if (stackprot) {
886             gen_helper_stackprot(cpu_env, *t);
887         }
888         return t;
889     }
890     /* Immediate.  */
891     if (!extimm) {
892         if (dc->imm == 0) {
893             return &cpu_R[dc->ra];
894         }
895         *t = tcg_temp_new();
896         tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm));
897         tcg_gen_add_tl(*t, cpu_R[dc->ra], *t);
898     } else {
899         *t = tcg_temp_new();
900         tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
901     }
902
903     if (stackprot) {
904         gen_helper_stackprot(cpu_env, *t);
905     }
906     return t;
907 }
908
909 static void dec_load(DisasContext *dc)
910 {
911     TCGv t, v, *addr;
912     unsigned int size, rev = 0, ex = 0;
913     TCGMemOp mop;
914
915     mop = dc->opcode & 3;
916     size = 1 << mop;
917     if (!dc->type_b) {
918         rev = (dc->ir >> 9) & 1;
919         ex = (dc->ir >> 10) & 1;
920     }
921     mop |= MO_TE;
922     if (rev) {
923         mop ^= MO_BSWAP;
924     }
925
926     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
927           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
928         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
929         t_gen_raise_exception(dc, EXCP_HW_EXCP);
930         return;
931     }
932
933     LOG_DIS("l%d%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
934                                                         ex ? "x" : "");
935
936     t_sync_flags(dc);
937     addr = compute_ldst_addr(dc, &t);
938
939     /*
940      * When doing reverse accesses we need to do two things.
941      *
942      * 1. Reverse the address wrt endianness.
943      * 2. Byteswap the data lanes on the way back into the CPU core.
944      */
945     if (rev && size != 4) {
946         /* Endian reverse the address. t is addr.  */
947         switch (size) {
948             case 1:
949             {
950                 /* 00 -> 11
951                    01 -> 10
952                    10 -> 10
953                    11 -> 00 */
954                 TCGv low = tcg_temp_new();
955
956                 /* Force addr into the temp.  */
957                 if (addr != &t) {
958                     t = tcg_temp_new();
959                     tcg_gen_mov_tl(t, *addr);
960                     addr = &t;
961                 }
962
963                 tcg_gen_andi_tl(low, t, 3);
964                 tcg_gen_sub_tl(low, tcg_const_tl(3), low);
965                 tcg_gen_andi_tl(t, t, ~3);
966                 tcg_gen_or_tl(t, t, low);
967                 tcg_gen_mov_tl(env_imm, t);
968                 tcg_temp_free(low);
969                 break;
970             }
971
972             case 2:
973                 /* 00 -> 10
974                    10 -> 00.  */
975                 /* Force addr into the temp.  */
976                 if (addr != &t) {
977                     t = tcg_temp_new();
978                     tcg_gen_xori_tl(t, *addr, 2);
979                     addr = &t;
980                 } else {
981                     tcg_gen_xori_tl(t, t, 2);
982                 }
983                 break;
984             default:
985                 cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
986                 break;
987         }
988     }
989
990     /* lwx does not throw unaligned access errors, so force alignment */
991     if (ex) {
992         /* Force addr into the temp.  */
993         if (addr != &t) {
994             t = tcg_temp_new();
995             tcg_gen_mov_tl(t, *addr);
996             addr = &t;
997         }
998         tcg_gen_andi_tl(t, t, ~3);
999     }
1000
1001     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
1002     sync_jmpstate(dc);
1003
1004     /* Verify alignment if needed.  */
1005     /*
1006      * Microblaze gives MMU faults priority over faults due to
1007      * unaligned addresses. That's why we speculatively do the load
1008      * into v. If the load succeeds, we verify alignment of the
1009      * address and if that succeeds we write into the destination reg.
1010      */
1011     v = tcg_temp_new();
1012     tcg_gen_qemu_ld_tl(v, *addr, cpu_mmu_index(&dc->cpu->env), mop);
1013
1014     if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
1015         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
1016         gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
1017                             tcg_const_tl(0), tcg_const_tl(size - 1));
1018     }
1019
1020     if (ex) {
1021         tcg_gen_mov_tl(env_res_addr, *addr);
1022         tcg_gen_mov_tl(env_res_val, v);
1023     }
1024     if (dc->rd) {
1025         tcg_gen_mov_tl(cpu_R[dc->rd], v);
1026     }
1027     tcg_temp_free(v);
1028
1029     if (ex) { /* lwx */
1030         /* no support for for AXI exclusive so always clear C */
1031         write_carryi(dc, 0);
1032     }
1033
1034     if (addr == &t)
1035         tcg_temp_free(t);
1036 }
1037
1038 static void dec_store(DisasContext *dc)
1039 {
1040     TCGv t, *addr, swx_addr;
1041     TCGLabel *swx_skip = NULL;
1042     unsigned int size, rev = 0, ex = 0;
1043     TCGMemOp mop;
1044
1045     mop = dc->opcode & 3;
1046     size = 1 << mop;
1047     if (!dc->type_b) {
1048         rev = (dc->ir >> 9) & 1;
1049         ex = (dc->ir >> 10) & 1;
1050     }
1051     mop |= MO_TE;
1052     if (rev) {
1053         mop ^= MO_BSWAP;
1054     }
1055
1056     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
1057           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
1058         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1059         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1060         return;
1061     }
1062
1063     LOG_DIS("s%d%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
1064                                                         ex ? "x" : "");
1065     t_sync_flags(dc);
1066     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
1067     sync_jmpstate(dc);
1068     addr = compute_ldst_addr(dc, &t);
1069
1070     swx_addr = tcg_temp_local_new();
1071     if (ex) { /* swx */
1072         TCGv tval;
1073
1074         /* Force addr into the swx_addr. */
1075         tcg_gen_mov_tl(swx_addr, *addr);
1076         addr = &swx_addr;
1077         /* swx does not throw unaligned access errors, so force alignment */
1078         tcg_gen_andi_tl(swx_addr, swx_addr, ~3);
1079
1080         write_carryi(dc, 1);
1081         swx_skip = gen_new_label();
1082         tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, swx_addr, swx_skip);
1083
1084         /* Compare the value loaded at lwx with current contents of
1085            the reserved location.
1086            FIXME: This only works for system emulation where we can expect
1087            this compare and the following write to be atomic. For user
1088            emulation we need to add atomicity between threads.  */
1089         tval = tcg_temp_new();
1090         tcg_gen_qemu_ld_tl(tval, swx_addr, cpu_mmu_index(&dc->cpu->env),
1091                            MO_TEUL);
1092         tcg_gen_brcond_tl(TCG_COND_NE, env_res_val, tval, swx_skip);
1093         write_carryi(dc, 0);
1094         tcg_temp_free(tval);
1095     }
1096
1097     if (rev && size != 4) {
1098         /* Endian reverse the address. t is addr.  */
1099         switch (size) {
1100             case 1:
1101             {
1102                 /* 00 -> 11
1103                    01 -> 10
1104                    10 -> 10
1105                    11 -> 00 */
1106                 TCGv low = tcg_temp_new();
1107
1108                 /* Force addr into the temp.  */
1109                 if (addr != &t) {
1110                     t = tcg_temp_new();
1111                     tcg_gen_mov_tl(t, *addr);
1112                     addr = &t;
1113                 }
1114
1115                 tcg_gen_andi_tl(low, t, 3);
1116                 tcg_gen_sub_tl(low, tcg_const_tl(3), low);
1117                 tcg_gen_andi_tl(t, t, ~3);
1118                 tcg_gen_or_tl(t, t, low);
1119                 tcg_gen_mov_tl(env_imm, t);
1120                 tcg_temp_free(low);
1121                 break;
1122             }
1123
1124             case 2:
1125                 /* 00 -> 10
1126                    10 -> 00.  */
1127                 /* Force addr into the temp.  */
1128                 if (addr != &t) {
1129                     t = tcg_temp_new();
1130                     tcg_gen_xori_tl(t, *addr, 2);
1131                     addr = &t;
1132                 } else {
1133                     tcg_gen_xori_tl(t, t, 2);
1134                 }
1135                 break;
1136             default:
1137                 cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
1138                 break;
1139         }
1140     }
1141     tcg_gen_qemu_st_tl(cpu_R[dc->rd], *addr, cpu_mmu_index(&dc->cpu->env), mop);
1142
1143     /* Verify alignment if needed.  */
1144     if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
1145         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
1146         /* FIXME: if the alignment is wrong, we should restore the value
1147          *        in memory. One possible way to achieve this is to probe
1148          *        the MMU prior to the memaccess, thay way we could put
1149          *        the alignment checks in between the probe and the mem
1150          *        access.
1151          */
1152         gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
1153                             tcg_const_tl(1), tcg_const_tl(size - 1));
1154     }
1155
1156     if (ex) {
1157         gen_set_label(swx_skip);
1158     }
1159     tcg_temp_free(swx_addr);
1160
1161     if (addr == &t)
1162         tcg_temp_free(t);
1163 }
1164
1165 static inline void eval_cc(DisasContext *dc, unsigned int cc,
1166                            TCGv d, TCGv a, TCGv b)
1167 {
1168     switch (cc) {
1169         case CC_EQ:
1170             tcg_gen_setcond_tl(TCG_COND_EQ, d, a, b);
1171             break;
1172         case CC_NE:
1173             tcg_gen_setcond_tl(TCG_COND_NE, d, a, b);
1174             break;
1175         case CC_LT:
1176             tcg_gen_setcond_tl(TCG_COND_LT, d, a, b);
1177             break;
1178         case CC_LE:
1179             tcg_gen_setcond_tl(TCG_COND_LE, d, a, b);
1180             break;
1181         case CC_GE:
1182             tcg_gen_setcond_tl(TCG_COND_GE, d, a, b);
1183             break;
1184         case CC_GT:
1185             tcg_gen_setcond_tl(TCG_COND_GT, d, a, b);
1186             break;
1187         default:
1188             cpu_abort(CPU(dc->cpu), "Unknown condition code %x.\n", cc);
1189             break;
1190     }
1191 }
1192
1193 static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false)
1194 {
1195     TCGLabel *l1 = gen_new_label();
1196     /* Conditional jmp.  */
1197     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);
1198     tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
1199     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);
1200     gen_set_label(l1);
1201 }
1202
1203 static void dec_bcc(DisasContext *dc)
1204 {
1205     unsigned int cc;
1206     unsigned int dslot;
1207
1208     cc = EXTRACT_FIELD(dc->ir, 21, 23);
1209     dslot = dc->ir & (1 << 25);
1210     LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);
1211
1212     dc->delayed_branch = 1;
1213     if (dslot) {
1214         dc->delayed_branch = 2;
1215         dc->tb_flags |= D_FLAG;
1216         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1217                       cpu_env, offsetof(CPUMBState, bimm));
1218     }
1219
1220     if (dec_alu_op_b_is_small_imm(dc)) {
1221         int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
1222
1223         tcg_gen_movi_tl(env_btarget, dc->pc + offset);
1224         dc->jmp = JMP_DIRECT_CC;
1225         dc->jmp_pc = dc->pc + offset;
1226     } else {
1227         dc->jmp = JMP_INDIRECT;
1228         tcg_gen_movi_tl(env_btarget, dc->pc);
1229         tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
1230     }
1231     eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
1232 }
1233
1234 static void dec_br(DisasContext *dc)
1235 {
1236     unsigned int dslot, link, abs, mbar;
1237     int mem_index = cpu_mmu_index(&dc->cpu->env);
1238
1239     dslot = dc->ir & (1 << 20);
1240     abs = dc->ir & (1 << 19);
1241     link = dc->ir & (1 << 18);
1242
1243     /* Memory barrier.  */
1244     mbar = (dc->ir >> 16) & 31;
1245     if (mbar == 2 && dc->imm == 4) {
1246         /* mbar IMM & 16 decodes to sleep.  */
1247         if (dc->rd & 16) {
1248             TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
1249             TCGv_i32 tmp_1 = tcg_const_i32(1);
1250
1251             LOG_DIS("sleep\n");
1252
1253             t_sync_flags(dc);
1254             tcg_gen_st_i32(tmp_1, cpu_env,
1255                            -offsetof(MicroBlazeCPU, env)
1256                            +offsetof(CPUState, halted));
1257             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
1258             gen_helper_raise_exception(cpu_env, tmp_hlt);
1259             tcg_temp_free_i32(tmp_hlt);
1260             tcg_temp_free_i32(tmp_1);
1261             return;
1262         }
1263         LOG_DIS("mbar %d\n", dc->rd);
1264         /* Break the TB.  */
1265         dc->cpustate_changed = 1;
1266         return;
1267     }
1268
1269     LOG_DIS("br%s%s%s%s imm=%x\n",
1270              abs ? "a" : "", link ? "l" : "",
1271              dc->type_b ? "i" : "", dslot ? "d" : "",
1272              dc->imm);
1273
1274     dc->delayed_branch = 1;
1275     if (dslot) {
1276         dc->delayed_branch = 2;
1277         dc->tb_flags |= D_FLAG;
1278         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1279                       cpu_env, offsetof(CPUMBState, bimm));
1280     }
1281     if (link && dc->rd)
1282         tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
1283
1284     dc->jmp = JMP_INDIRECT;
1285     if (abs) {
1286         tcg_gen_movi_tl(env_btaken, 1);
1287         tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
1288         if (link && !dslot) {
1289             if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
1290                 t_gen_raise_exception(dc, EXCP_BREAK);
1291             if (dc->imm == 0) {
1292                 if ((dc->tb_flags & MSR_EE_FLAG) && mem_index == MMU_USER_IDX) {
1293                     tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1294                     t_gen_raise_exception(dc, EXCP_HW_EXCP);
1295                     return;
1296                 }
1297
1298                 t_gen_raise_exception(dc, EXCP_DEBUG);
1299             }
1300         }
1301     } else {
1302         if (dec_alu_op_b_is_small_imm(dc)) {
1303             dc->jmp = JMP_DIRECT;
1304             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
1305         } else {
1306             tcg_gen_movi_tl(env_btaken, 1);
1307             tcg_gen_movi_tl(env_btarget, dc->pc);
1308             tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
1309         }
1310     }
1311 }
1312
1313 static inline void do_rti(DisasContext *dc)
1314 {
1315     TCGv t0, t1;
1316     t0 = tcg_temp_new();
1317     t1 = tcg_temp_new();
1318     tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
1319     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE);
1320     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1321
1322     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1323     tcg_gen_or_tl(t1, t1, t0);
1324     msr_write(dc, t1);
1325     tcg_temp_free(t1);
1326     tcg_temp_free(t0);
1327     dc->tb_flags &= ~DRTI_FLAG;
1328 }
1329
1330 static inline void do_rtb(DisasContext *dc)
1331 {
1332     TCGv t0, t1;
1333     t0 = tcg_temp_new();
1334     t1 = tcg_temp_new();
1335     tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP);
1336     tcg_gen_shri_tl(t0, t1, 1);
1337     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1338
1339     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1340     tcg_gen_or_tl(t1, t1, t0);
1341     msr_write(dc, t1);
1342     tcg_temp_free(t1);
1343     tcg_temp_free(t0);
1344     dc->tb_flags &= ~DRTB_FLAG;
1345 }
1346
1347 static inline void do_rte(DisasContext *dc)
1348 {
1349     TCGv t0, t1;
1350     t0 = tcg_temp_new();
1351     t1 = tcg_temp_new();
1352
1353     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE);
1354     tcg_gen_andi_tl(t1, t1, ~MSR_EIP);
1355     tcg_gen_shri_tl(t0, t1, 1);
1356     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1357
1358     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1359     tcg_gen_or_tl(t1, t1, t0);
1360     msr_write(dc, t1);
1361     tcg_temp_free(t1);
1362     tcg_temp_free(t0);
1363     dc->tb_flags &= ~DRTE_FLAG;
1364 }
1365
1366 static void dec_rts(DisasContext *dc)
1367 {
1368     unsigned int b_bit, i_bit, e_bit;
1369     int mem_index = cpu_mmu_index(&dc->cpu->env);
1370
1371     i_bit = dc->ir & (1 << 21);
1372     b_bit = dc->ir & (1 << 22);
1373     e_bit = dc->ir & (1 << 23);
1374
1375     dc->delayed_branch = 2;
1376     dc->tb_flags |= D_FLAG;
1377     tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1378                   cpu_env, offsetof(CPUMBState, bimm));
1379
1380     if (i_bit) {
1381         LOG_DIS("rtid ir=%x\n", dc->ir);
1382         if ((dc->tb_flags & MSR_EE_FLAG)
1383              && mem_index == MMU_USER_IDX) {
1384             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1385             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1386         }
1387         dc->tb_flags |= DRTI_FLAG;
1388     } else if (b_bit) {
1389         LOG_DIS("rtbd ir=%x\n", dc->ir);
1390         if ((dc->tb_flags & MSR_EE_FLAG)
1391              && mem_index == MMU_USER_IDX) {
1392             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1393             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1394         }
1395         dc->tb_flags |= DRTB_FLAG;
1396     } else if (e_bit) {
1397         LOG_DIS("rted ir=%x\n", dc->ir);
1398         if ((dc->tb_flags & MSR_EE_FLAG)
1399              && mem_index == MMU_USER_IDX) {
1400             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1401             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1402         }
1403         dc->tb_flags |= DRTE_FLAG;
1404     } else
1405         LOG_DIS("rts ir=%x\n", dc->ir);
1406
1407     dc->jmp = JMP_INDIRECT;
1408     tcg_gen_movi_tl(env_btaken, 1);
1409     tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
1410 }
1411
1412 static int dec_check_fpuv2(DisasContext *dc)
1413 {
1414     if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
1415         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
1416         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1417     }
1418     return (dc->cpu->cfg.use_fpu == 2) ? 0 : PVR2_USE_FPU2_MASK;
1419 }
1420
1421 static void dec_fpu(DisasContext *dc)
1422 {
1423     unsigned int fpu_insn;
1424
1425     if ((dc->tb_flags & MSR_EE_FLAG)
1426           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
1427           && (dc->cpu->cfg.use_fpu != 1)) {
1428         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1429         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1430         return;
1431     }
1432
1433     fpu_insn = (dc->ir >> 7) & 7;
1434
1435     switch (fpu_insn) {
1436         case 0:
1437             gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1438                             cpu_R[dc->rb]);
1439             break;
1440
1441         case 1:
1442             gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1443                              cpu_R[dc->rb]);
1444             break;
1445
1446         case 2:
1447             gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1448                             cpu_R[dc->rb]);
1449             break;
1450
1451         case 3:
1452             gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1453                             cpu_R[dc->rb]);
1454             break;
1455
1456         case 4:
1457             switch ((dc->ir >> 4) & 7) {
1458                 case 0:
1459                     gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
1460                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1461                     break;
1462                 case 1:
1463                     gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
1464                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1465                     break;
1466                 case 2:
1467                     gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
1468                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1469                     break;
1470                 case 3:
1471                     gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
1472                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1473                     break;
1474                 case 4:
1475                     gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
1476                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1477                     break;
1478                 case 5:
1479                     gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
1480                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1481                     break;
1482                 case 6:
1483                     gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
1484                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1485                     break;
1486                 default:
1487                     qemu_log_mask(LOG_UNIMP,
1488                                   "unimplemented fcmp fpu_insn=%x pc=%x"
1489                                   " opc=%x\n",
1490                                   fpu_insn, dc->pc, dc->opcode);
1491                     dc->abort_at_next_insn = 1;
1492                     break;
1493             }
1494             break;
1495
1496         case 5:
1497             if (!dec_check_fpuv2(dc)) {
1498                 return;
1499             }
1500             gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1501             break;
1502
1503         case 6:
1504             if (!dec_check_fpuv2(dc)) {
1505                 return;
1506             }
1507             gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1508             break;
1509
1510         case 7:
1511             if (!dec_check_fpuv2(dc)) {
1512                 return;
1513             }
1514             gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1515             break;
1516
1517         default:
1518             qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
1519                           " opc=%x\n",
1520                           fpu_insn, dc->pc, dc->opcode);
1521             dc->abort_at_next_insn = 1;
1522             break;
1523     }
1524 }
1525
1526 static void dec_null(DisasContext *dc)
1527 {
1528     if ((dc->tb_flags & MSR_EE_FLAG)
1529           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
1530         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1531         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1532         return;
1533     }
1534     qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
1535     dc->abort_at_next_insn = 1;
1536 }
1537
1538 /* Insns connected to FSL or AXI stream attached devices.  */
1539 static void dec_stream(DisasContext *dc)
1540 {
1541     int mem_index = cpu_mmu_index(&dc->cpu->env);
1542     TCGv_i32 t_id, t_ctrl;
1543     int ctrl;
1544
1545     LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
1546             dc->type_b ? "" : "d", dc->imm);
1547
1548     if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) {
1549         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1550         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1551         return;
1552     }
1553
1554     t_id = tcg_temp_new();
1555     if (dc->type_b) {
1556         tcg_gen_movi_tl(t_id, dc->imm & 0xf);
1557         ctrl = dc->imm >> 10;
1558     } else {
1559         tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf);
1560         ctrl = dc->imm >> 5;
1561     }
1562
1563     t_ctrl = tcg_const_tl(ctrl);
1564
1565     if (dc->rd == 0) {
1566         gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
1567     } else {
1568         gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
1569     }
1570     tcg_temp_free(t_id);
1571     tcg_temp_free(t_ctrl);
1572 }
1573
1574 static struct decoder_info {
1575     struct {
1576         uint32_t bits;
1577         uint32_t mask;
1578     };
1579     void (*dec)(DisasContext *dc);
1580 } decinfo[] = {
1581     {DEC_ADD, dec_add},
1582     {DEC_SUB, dec_sub},
1583     {DEC_AND, dec_and},
1584     {DEC_XOR, dec_xor},
1585     {DEC_OR, dec_or},
1586     {DEC_BIT, dec_bit},
1587     {DEC_BARREL, dec_barrel},
1588     {DEC_LD, dec_load},
1589     {DEC_ST, dec_store},
1590     {DEC_IMM, dec_imm},
1591     {DEC_BR, dec_br},
1592     {DEC_BCC, dec_bcc},
1593     {DEC_RTS, dec_rts},
1594     {DEC_FPU, dec_fpu},
1595     {DEC_MUL, dec_mul},
1596     {DEC_DIV, dec_div},
1597     {DEC_MSR, dec_msr},
1598     {DEC_STREAM, dec_stream},
1599     {{0, 0}, dec_null}
1600 };
1601
1602 static inline void decode(DisasContext *dc, uint32_t ir)
1603 {
1604     int i;
1605
1606     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
1607         tcg_gen_debug_insn_start(dc->pc);
1608     }
1609
1610     dc->ir = ir;
1611     LOG_DIS("%8.8x\t", dc->ir);
1612
1613     if (dc->ir)
1614         dc->nr_nops = 0;
1615     else {
1616         if ((dc->tb_flags & MSR_EE_FLAG)
1617               && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
1618               && (dc->cpu->env.pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
1619             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1620             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1621             return;
1622         }
1623
1624         LOG_DIS("nr_nops=%d\t", dc->nr_nops);
1625         dc->nr_nops++;
1626         if (dc->nr_nops > 4) {
1627             cpu_abort(CPU(dc->cpu), "fetching nop sequence\n");
1628         }
1629     }
1630     /* bit 2 seems to indicate insn type.  */
1631     dc->type_b = ir & (1 << 29);
1632
1633     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
1634     dc->rd = EXTRACT_FIELD(ir, 21, 25);
1635     dc->ra = EXTRACT_FIELD(ir, 16, 20);
1636     dc->rb = EXTRACT_FIELD(ir, 11, 15);
1637     dc->imm = EXTRACT_FIELD(ir, 0, 15);
1638
1639     /* Large switch for all insns.  */
1640     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
1641         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
1642             decinfo[i].dec(dc);
1643             break;
1644         }
1645     }
1646 }
1647
1648 static void check_breakpoint(CPUMBState *env, DisasContext *dc)
1649 {
1650     CPUState *cs = CPU(mb_env_get_cpu(env));
1651     CPUBreakpoint *bp;
1652
1653     if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
1654         QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
1655             if (bp->pc == dc->pc) {
1656                 t_gen_raise_exception(dc, EXCP_DEBUG);
1657                 dc->is_jmp = DISAS_UPDATE;
1658              }
1659         }
1660     }
1661 }
1662
1663 /* generate intermediate code for basic block 'tb'.  */
1664 static inline void
1665 gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
1666                                bool search_pc)
1667 {
1668     CPUState *cs = CPU(cpu);
1669     CPUMBState *env = &cpu->env;
1670     uint32_t pc_start;
1671     int j, lj;
1672     struct DisasContext ctx;
1673     struct DisasContext *dc = &ctx;
1674     uint32_t next_page_start, org_flags;
1675     target_ulong npc;
1676     int num_insns;
1677     int max_insns;
1678
1679     pc_start = tb->pc;
1680     dc->cpu = cpu;
1681     dc->tb = tb;
1682     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
1683
1684     dc->is_jmp = DISAS_NEXT;
1685     dc->jmp = 0;
1686     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
1687     if (dc->delayed_branch) {
1688         dc->jmp = JMP_INDIRECT;
1689     }
1690     dc->pc = pc_start;
1691     dc->singlestep_enabled = cs->singlestep_enabled;
1692     dc->cpustate_changed = 0;
1693     dc->abort_at_next_insn = 0;
1694     dc->nr_nops = 0;
1695
1696     if (pc_start & 3) {
1697         cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
1698     }
1699
1700     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1701 #if !SIM_COMPAT
1702         qemu_log("--------------\n");
1703         log_cpu_state(CPU(cpu), 0);
1704 #endif
1705     }
1706
1707     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1708     lj = -1;
1709     num_insns = 0;
1710     max_insns = tb->cflags & CF_COUNT_MASK;
1711     if (max_insns == 0)
1712         max_insns = CF_COUNT_MASK;
1713
1714     gen_tb_start(tb);
1715     do
1716     {
1717 #if SIM_COMPAT
1718         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1719             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
1720             gen_helper_debug();
1721         }
1722 #endif
1723         check_breakpoint(env, dc);
1724
1725         if (search_pc) {
1726             j = tcg_op_buf_count();
1727             if (lj < j) {
1728                 lj++;
1729                 while (lj < j)
1730                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
1731             }
1732             tcg_ctx.gen_opc_pc[lj] = dc->pc;
1733             tcg_ctx.gen_opc_instr_start[lj] = 1;
1734                         tcg_ctx.gen_opc_icount[lj] = num_insns;
1735         }
1736
1737         /* Pretty disas.  */
1738         LOG_DIS("%8.8x:\t", dc->pc);
1739
1740         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1741             gen_io_start();
1742
1743         dc->clear_imm = 1;
1744         decode(dc, cpu_ldl_code(env, dc->pc));
1745         if (dc->clear_imm)
1746             dc->tb_flags &= ~IMM_FLAG;
1747         dc->pc += 4;
1748         num_insns++;
1749
1750         if (dc->delayed_branch) {
1751             dc->delayed_branch--;
1752             if (!dc->delayed_branch) {
1753                 if (dc->tb_flags & DRTI_FLAG)
1754                     do_rti(dc);
1755                  if (dc->tb_flags & DRTB_FLAG)
1756                     do_rtb(dc);
1757                 if (dc->tb_flags & DRTE_FLAG)
1758                     do_rte(dc);
1759                 /* Clear the delay slot flag.  */
1760                 dc->tb_flags &= ~D_FLAG;
1761                 /* If it is a direct jump, try direct chaining.  */
1762                 if (dc->jmp == JMP_INDIRECT) {
1763                     eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
1764                     dc->is_jmp = DISAS_JUMP;
1765                 } else if (dc->jmp == JMP_DIRECT) {
1766                     t_sync_flags(dc);
1767                     gen_goto_tb(dc, 0, dc->jmp_pc);
1768                     dc->is_jmp = DISAS_TB_JUMP;
1769                 } else if (dc->jmp == JMP_DIRECT_CC) {
1770                     TCGLabel *l1 = gen_new_label();
1771                     t_sync_flags(dc);
1772                     /* Conditional jmp.  */
1773                     tcg_gen_brcondi_tl(TCG_COND_NE, env_btaken, 0, l1);
1774                     gen_goto_tb(dc, 1, dc->pc);
1775                     gen_set_label(l1);
1776                     gen_goto_tb(dc, 0, dc->jmp_pc);
1777
1778                     dc->is_jmp = DISAS_TB_JUMP;
1779                 }
1780                 break;
1781             }
1782         }
1783         if (cs->singlestep_enabled) {
1784             break;
1785         }
1786     } while (!dc->is_jmp && !dc->cpustate_changed
1787              && !tcg_op_buf_full()
1788              && !singlestep
1789              && (dc->pc < next_page_start)
1790              && num_insns < max_insns);
1791
1792     npc = dc->pc;
1793     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1794         if (dc->tb_flags & D_FLAG) {
1795             dc->is_jmp = DISAS_UPDATE;
1796             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1797             sync_jmpstate(dc);
1798         } else
1799             npc = dc->jmp_pc;
1800     }
1801
1802     if (tb->cflags & CF_LAST_IO)
1803         gen_io_end();
1804     /* Force an update if the per-tb cpu state has changed.  */
1805     if (dc->is_jmp == DISAS_NEXT
1806         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
1807         dc->is_jmp = DISAS_UPDATE;
1808         tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1809     }
1810     t_sync_flags(dc);
1811
1812     if (unlikely(cs->singlestep_enabled)) {
1813         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
1814
1815         if (dc->is_jmp != DISAS_JUMP) {
1816             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1817         }
1818         gen_helper_raise_exception(cpu_env, tmp);
1819         tcg_temp_free_i32(tmp);
1820     } else {
1821         switch(dc->is_jmp) {
1822             case DISAS_NEXT:
1823                 gen_goto_tb(dc, 1, npc);
1824                 break;
1825             default:
1826             case DISAS_JUMP:
1827             case DISAS_UPDATE:
1828                 /* indicate that the hash table must be used
1829                    to find the next TB */
1830                 tcg_gen_exit_tb(0);
1831                 break;
1832             case DISAS_TB_JUMP:
1833                 /* nothing more to generate */
1834                 break;
1835         }
1836     }
1837     gen_tb_end(tb, num_insns);
1838
1839     if (search_pc) {
1840         j = tcg_op_buf_count();
1841         lj++;
1842         while (lj <= j)
1843             tcg_ctx.gen_opc_instr_start[lj++] = 0;
1844     } else {
1845         tb->size = dc->pc - pc_start;
1846                 tb->icount = num_insns;
1847     }
1848
1849 #ifdef DEBUG_DISAS
1850 #if !SIM_COMPAT
1851     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1852         qemu_log("\n");
1853 #if DISAS_GNU
1854         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
1855 #endif
1856         qemu_log("\nisize=%d osize=%d\n",
1857                  dc->pc - pc_start, tcg_op_buf_count());
1858     }
1859 #endif
1860 #endif
1861     assert(!dc->abort_at_next_insn);
1862 }
1863
1864 void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
1865 {
1866     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
1867 }
1868
1869 void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
1870 {
1871     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
1872 }
1873
1874 void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
1875                        int flags)
1876 {
1877     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
1878     CPUMBState *env = &cpu->env;
1879     int i;
1880
1881     if (!env || !f)
1882         return;
1883
1884     cpu_fprintf(f, "IN: PC=%x %s\n",
1885                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
1886     cpu_fprintf(f, "rmsr=%x resr=%x rear=%x debug=%x imm=%x iflags=%x fsr=%x\n",
1887              env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
1888              env->debug, env->imm, env->iflags, env->sregs[SR_FSR]);
1889     cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
1890              env->btaken, env->btarget,
1891              (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
1892              (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
1893              (env->sregs[SR_MSR] & MSR_EIP),
1894              (env->sregs[SR_MSR] & MSR_IE));
1895
1896     for (i = 0; i < 32; i++) {
1897         cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
1898         if ((i + 1) % 4 == 0)
1899             cpu_fprintf(f, "\n");
1900         }
1901     cpu_fprintf(f, "\n\n");
1902 }
1903
1904 MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
1905 {
1906     MicroBlazeCPU *cpu;
1907
1908     cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
1909
1910     object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
1911
1912     return cpu;
1913 }
1914
1915 void mb_tcg_init(void)
1916 {
1917     int i;
1918
1919     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1920
1921     env_debug = tcg_global_mem_new(TCG_AREG0, 
1922                     offsetof(CPUMBState, debug),
1923                     "debug0");
1924     env_iflags = tcg_global_mem_new(TCG_AREG0, 
1925                     offsetof(CPUMBState, iflags),
1926                     "iflags");
1927     env_imm = tcg_global_mem_new(TCG_AREG0, 
1928                     offsetof(CPUMBState, imm),
1929                     "imm");
1930     env_btarget = tcg_global_mem_new(TCG_AREG0,
1931                      offsetof(CPUMBState, btarget),
1932                      "btarget");
1933     env_btaken = tcg_global_mem_new(TCG_AREG0,
1934                      offsetof(CPUMBState, btaken),
1935                      "btaken");
1936     env_res_addr = tcg_global_mem_new(TCG_AREG0,
1937                      offsetof(CPUMBState, res_addr),
1938                      "res_addr");
1939     env_res_val = tcg_global_mem_new(TCG_AREG0,
1940                      offsetof(CPUMBState, res_val),
1941                      "res_val");
1942     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
1943         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
1944                           offsetof(CPUMBState, regs[i]),
1945                           regnames[i]);
1946     }
1947     for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
1948         cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
1949                           offsetof(CPUMBState, sregs[i]),
1950                           special_regnames[i]);
1951     }
1952 }
1953
1954 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)
1955 {
1956     env->sregs[SR_PC] = tcg_ctx.gen_opc_pc[pc_pos];
1957 }