]> Git Repo - qemu.git/blob - target-microblaze/translate.c
Merge remote-tracking branch 'remotes/otubo/tags/pull-seccomp-20150105' into staging
[qemu.git] / 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     int 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) {
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) {
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     int swx_skip = 0;
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     int l1;
1196
1197     l1 = gen_new_label();
1198     /* Conditional jmp.  */
1199     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);
1200     tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
1201     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);
1202     gen_set_label(l1);
1203 }
1204
1205 static void dec_bcc(DisasContext *dc)
1206 {
1207     unsigned int cc;
1208     unsigned int dslot;
1209
1210     cc = EXTRACT_FIELD(dc->ir, 21, 23);
1211     dslot = dc->ir & (1 << 25);
1212     LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);
1213
1214     dc->delayed_branch = 1;
1215     if (dslot) {
1216         dc->delayed_branch = 2;
1217         dc->tb_flags |= D_FLAG;
1218         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1219                       cpu_env, offsetof(CPUMBState, bimm));
1220     }
1221
1222     if (dec_alu_op_b_is_small_imm(dc)) {
1223         int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
1224
1225         tcg_gen_movi_tl(env_btarget, dc->pc + offset);
1226         dc->jmp = JMP_DIRECT_CC;
1227         dc->jmp_pc = dc->pc + offset;
1228     } else {
1229         dc->jmp = JMP_INDIRECT;
1230         tcg_gen_movi_tl(env_btarget, dc->pc);
1231         tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
1232     }
1233     eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
1234 }
1235
1236 static void dec_br(DisasContext *dc)
1237 {
1238     unsigned int dslot, link, abs, mbar;
1239     int mem_index = cpu_mmu_index(&dc->cpu->env);
1240
1241     dslot = dc->ir & (1 << 20);
1242     abs = dc->ir & (1 << 19);
1243     link = dc->ir & (1 << 18);
1244
1245     /* Memory barrier.  */
1246     mbar = (dc->ir >> 16) & 31;
1247     if (mbar == 2 && dc->imm == 4) {
1248         /* mbar IMM & 16 decodes to sleep.  */
1249         if (dc->rd & 16) {
1250             TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
1251             TCGv_i32 tmp_1 = tcg_const_i32(1);
1252
1253             LOG_DIS("sleep\n");
1254
1255             t_sync_flags(dc);
1256             tcg_gen_st_i32(tmp_1, cpu_env,
1257                            -offsetof(MicroBlazeCPU, env)
1258                            +offsetof(CPUState, halted));
1259             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
1260             gen_helper_raise_exception(cpu_env, tmp_hlt);
1261             tcg_temp_free_i32(tmp_hlt);
1262             tcg_temp_free_i32(tmp_1);
1263             return;
1264         }
1265         LOG_DIS("mbar %d\n", dc->rd);
1266         /* Break the TB.  */
1267         dc->cpustate_changed = 1;
1268         return;
1269     }
1270
1271     LOG_DIS("br%s%s%s%s imm=%x\n",
1272              abs ? "a" : "", link ? "l" : "",
1273              dc->type_b ? "i" : "", dslot ? "d" : "",
1274              dc->imm);
1275
1276     dc->delayed_branch = 1;
1277     if (dslot) {
1278         dc->delayed_branch = 2;
1279         dc->tb_flags |= D_FLAG;
1280         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1281                       cpu_env, offsetof(CPUMBState, bimm));
1282     }
1283     if (link && dc->rd)
1284         tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
1285
1286     dc->jmp = JMP_INDIRECT;
1287     if (abs) {
1288         tcg_gen_movi_tl(env_btaken, 1);
1289         tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
1290         if (link && !dslot) {
1291             if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
1292                 t_gen_raise_exception(dc, EXCP_BREAK);
1293             if (dc->imm == 0) {
1294                 if ((dc->tb_flags & MSR_EE_FLAG) && mem_index == MMU_USER_IDX) {
1295                     tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1296                     t_gen_raise_exception(dc, EXCP_HW_EXCP);
1297                     return;
1298                 }
1299
1300                 t_gen_raise_exception(dc, EXCP_DEBUG);
1301             }
1302         }
1303     } else {
1304         if (dec_alu_op_b_is_small_imm(dc)) {
1305             dc->jmp = JMP_DIRECT;
1306             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
1307         } else {
1308             tcg_gen_movi_tl(env_btaken, 1);
1309             tcg_gen_movi_tl(env_btarget, dc->pc);
1310             tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
1311         }
1312     }
1313 }
1314
1315 static inline void do_rti(DisasContext *dc)
1316 {
1317     TCGv t0, t1;
1318     t0 = tcg_temp_new();
1319     t1 = tcg_temp_new();
1320     tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
1321     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE);
1322     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1323
1324     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1325     tcg_gen_or_tl(t1, t1, t0);
1326     msr_write(dc, t1);
1327     tcg_temp_free(t1);
1328     tcg_temp_free(t0);
1329     dc->tb_flags &= ~DRTI_FLAG;
1330 }
1331
1332 static inline void do_rtb(DisasContext *dc)
1333 {
1334     TCGv t0, t1;
1335     t0 = tcg_temp_new();
1336     t1 = tcg_temp_new();
1337     tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP);
1338     tcg_gen_shri_tl(t0, t1, 1);
1339     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1340
1341     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1342     tcg_gen_or_tl(t1, t1, t0);
1343     msr_write(dc, t1);
1344     tcg_temp_free(t1);
1345     tcg_temp_free(t0);
1346     dc->tb_flags &= ~DRTB_FLAG;
1347 }
1348
1349 static inline void do_rte(DisasContext *dc)
1350 {
1351     TCGv t0, t1;
1352     t0 = tcg_temp_new();
1353     t1 = tcg_temp_new();
1354
1355     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE);
1356     tcg_gen_andi_tl(t1, t1, ~MSR_EIP);
1357     tcg_gen_shri_tl(t0, t1, 1);
1358     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
1359
1360     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
1361     tcg_gen_or_tl(t1, t1, t0);
1362     msr_write(dc, t1);
1363     tcg_temp_free(t1);
1364     tcg_temp_free(t0);
1365     dc->tb_flags &= ~DRTE_FLAG;
1366 }
1367
1368 static void dec_rts(DisasContext *dc)
1369 {
1370     unsigned int b_bit, i_bit, e_bit;
1371     int mem_index = cpu_mmu_index(&dc->cpu->env);
1372
1373     i_bit = dc->ir & (1 << 21);
1374     b_bit = dc->ir & (1 << 22);
1375     e_bit = dc->ir & (1 << 23);
1376
1377     dc->delayed_branch = 2;
1378     dc->tb_flags |= D_FLAG;
1379     tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1380                   cpu_env, offsetof(CPUMBState, bimm));
1381
1382     if (i_bit) {
1383         LOG_DIS("rtid ir=%x\n", dc->ir);
1384         if ((dc->tb_flags & MSR_EE_FLAG)
1385              && mem_index == MMU_USER_IDX) {
1386             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1387             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1388         }
1389         dc->tb_flags |= DRTI_FLAG;
1390     } else if (b_bit) {
1391         LOG_DIS("rtbd ir=%x\n", dc->ir);
1392         if ((dc->tb_flags & MSR_EE_FLAG)
1393              && mem_index == MMU_USER_IDX) {
1394             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1395             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1396         }
1397         dc->tb_flags |= DRTB_FLAG;
1398     } else if (e_bit) {
1399         LOG_DIS("rted ir=%x\n", dc->ir);
1400         if ((dc->tb_flags & MSR_EE_FLAG)
1401              && mem_index == MMU_USER_IDX) {
1402             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1403             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1404         }
1405         dc->tb_flags |= DRTE_FLAG;
1406     } else
1407         LOG_DIS("rts ir=%x\n", dc->ir);
1408
1409     dc->jmp = JMP_INDIRECT;
1410     tcg_gen_movi_tl(env_btaken, 1);
1411     tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
1412 }
1413
1414 static int dec_check_fpuv2(DisasContext *dc)
1415 {
1416     int r;
1417
1418     r = dc->cpu->env.pvr.regs[2] & PVR2_USE_FPU2_MASK;
1419
1420     if (!r && (dc->tb_flags & MSR_EE_FLAG)) {
1421         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
1422         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1423     }
1424     return r;
1425 }
1426
1427 static void dec_fpu(DisasContext *dc)
1428 {
1429     unsigned int fpu_insn;
1430
1431     if ((dc->tb_flags & MSR_EE_FLAG)
1432           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
1433           && !((dc->cpu->env.pvr.regs[2] & PVR2_USE_FPU_MASK))) {
1434         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1435         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1436         return;
1437     }
1438
1439     fpu_insn = (dc->ir >> 7) & 7;
1440
1441     switch (fpu_insn) {
1442         case 0:
1443             gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1444                             cpu_R[dc->rb]);
1445             break;
1446
1447         case 1:
1448             gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1449                              cpu_R[dc->rb]);
1450             break;
1451
1452         case 2:
1453             gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1454                             cpu_R[dc->rb]);
1455             break;
1456
1457         case 3:
1458             gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1459                             cpu_R[dc->rb]);
1460             break;
1461
1462         case 4:
1463             switch ((dc->ir >> 4) & 7) {
1464                 case 0:
1465                     gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
1466                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1467                     break;
1468                 case 1:
1469                     gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
1470                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1471                     break;
1472                 case 2:
1473                     gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
1474                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1475                     break;
1476                 case 3:
1477                     gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
1478                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1479                     break;
1480                 case 4:
1481                     gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
1482                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1483                     break;
1484                 case 5:
1485                     gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
1486                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1487                     break;
1488                 case 6:
1489                     gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
1490                                        cpu_R[dc->ra], cpu_R[dc->rb]);
1491                     break;
1492                 default:
1493                     qemu_log_mask(LOG_UNIMP,
1494                                   "unimplemented fcmp fpu_insn=%x pc=%x"
1495                                   " opc=%x\n",
1496                                   fpu_insn, dc->pc, dc->opcode);
1497                     dc->abort_at_next_insn = 1;
1498                     break;
1499             }
1500             break;
1501
1502         case 5:
1503             if (!dec_check_fpuv2(dc)) {
1504                 return;
1505             }
1506             gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1507             break;
1508
1509         case 6:
1510             if (!dec_check_fpuv2(dc)) {
1511                 return;
1512             }
1513             gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1514             break;
1515
1516         case 7:
1517             if (!dec_check_fpuv2(dc)) {
1518                 return;
1519             }
1520             gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1521             break;
1522
1523         default:
1524             qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
1525                           " opc=%x\n",
1526                           fpu_insn, dc->pc, dc->opcode);
1527             dc->abort_at_next_insn = 1;
1528             break;
1529     }
1530 }
1531
1532 static void dec_null(DisasContext *dc)
1533 {
1534     if ((dc->tb_flags & MSR_EE_FLAG)
1535           && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
1536         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1537         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1538         return;
1539     }
1540     qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
1541     dc->abort_at_next_insn = 1;
1542 }
1543
1544 /* Insns connected to FSL or AXI stream attached devices.  */
1545 static void dec_stream(DisasContext *dc)
1546 {
1547     int mem_index = cpu_mmu_index(&dc->cpu->env);
1548     TCGv_i32 t_id, t_ctrl;
1549     int ctrl;
1550
1551     LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
1552             dc->type_b ? "" : "d", dc->imm);
1553
1554     if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) {
1555         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
1556         t_gen_raise_exception(dc, EXCP_HW_EXCP);
1557         return;
1558     }
1559
1560     t_id = tcg_temp_new();
1561     if (dc->type_b) {
1562         tcg_gen_movi_tl(t_id, dc->imm & 0xf);
1563         ctrl = dc->imm >> 10;
1564     } else {
1565         tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf);
1566         ctrl = dc->imm >> 5;
1567     }
1568
1569     t_ctrl = tcg_const_tl(ctrl);
1570
1571     if (dc->rd == 0) {
1572         gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
1573     } else {
1574         gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
1575     }
1576     tcg_temp_free(t_id);
1577     tcg_temp_free(t_ctrl);
1578 }
1579
1580 static struct decoder_info {
1581     struct {
1582         uint32_t bits;
1583         uint32_t mask;
1584     };
1585     void (*dec)(DisasContext *dc);
1586 } decinfo[] = {
1587     {DEC_ADD, dec_add},
1588     {DEC_SUB, dec_sub},
1589     {DEC_AND, dec_and},
1590     {DEC_XOR, dec_xor},
1591     {DEC_OR, dec_or},
1592     {DEC_BIT, dec_bit},
1593     {DEC_BARREL, dec_barrel},
1594     {DEC_LD, dec_load},
1595     {DEC_ST, dec_store},
1596     {DEC_IMM, dec_imm},
1597     {DEC_BR, dec_br},
1598     {DEC_BCC, dec_bcc},
1599     {DEC_RTS, dec_rts},
1600     {DEC_FPU, dec_fpu},
1601     {DEC_MUL, dec_mul},
1602     {DEC_DIV, dec_div},
1603     {DEC_MSR, dec_msr},
1604     {DEC_STREAM, dec_stream},
1605     {{0, 0}, dec_null}
1606 };
1607
1608 static inline void decode(DisasContext *dc, uint32_t ir)
1609 {
1610     int i;
1611
1612     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
1613         tcg_gen_debug_insn_start(dc->pc);
1614     }
1615
1616     dc->ir = ir;
1617     LOG_DIS("%8.8x\t", dc->ir);
1618
1619     if (dc->ir)
1620         dc->nr_nops = 0;
1621     else {
1622         if ((dc->tb_flags & MSR_EE_FLAG)
1623               && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
1624               && (dc->cpu->env.pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
1625             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1626             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1627             return;
1628         }
1629
1630         LOG_DIS("nr_nops=%d\t", dc->nr_nops);
1631         dc->nr_nops++;
1632         if (dc->nr_nops > 4) {
1633             cpu_abort(CPU(dc->cpu), "fetching nop sequence\n");
1634         }
1635     }
1636     /* bit 2 seems to indicate insn type.  */
1637     dc->type_b = ir & (1 << 29);
1638
1639     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
1640     dc->rd = EXTRACT_FIELD(ir, 21, 25);
1641     dc->ra = EXTRACT_FIELD(ir, 16, 20);
1642     dc->rb = EXTRACT_FIELD(ir, 11, 15);
1643     dc->imm = EXTRACT_FIELD(ir, 0, 15);
1644
1645     /* Large switch for all insns.  */
1646     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
1647         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
1648             decinfo[i].dec(dc);
1649             break;
1650         }
1651     }
1652 }
1653
1654 static void check_breakpoint(CPUMBState *env, DisasContext *dc)
1655 {
1656     CPUState *cs = CPU(mb_env_get_cpu(env));
1657     CPUBreakpoint *bp;
1658
1659     if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
1660         QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
1661             if (bp->pc == dc->pc) {
1662                 t_gen_raise_exception(dc, EXCP_DEBUG);
1663                 dc->is_jmp = DISAS_UPDATE;
1664              }
1665         }
1666     }
1667 }
1668
1669 /* generate intermediate code for basic block 'tb'.  */
1670 static inline void
1671 gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
1672                                bool search_pc)
1673 {
1674     CPUState *cs = CPU(cpu);
1675     CPUMBState *env = &cpu->env;
1676     uint16_t *gen_opc_end;
1677     uint32_t pc_start;
1678     int j, lj;
1679     struct DisasContext ctx;
1680     struct DisasContext *dc = &ctx;
1681     uint32_t next_page_start, org_flags;
1682     target_ulong npc;
1683     int num_insns;
1684     int max_insns;
1685
1686     pc_start = tb->pc;
1687     dc->cpu = cpu;
1688     dc->tb = tb;
1689     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
1690
1691     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
1692
1693     dc->is_jmp = DISAS_NEXT;
1694     dc->jmp = 0;
1695     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
1696     if (dc->delayed_branch) {
1697         dc->jmp = JMP_INDIRECT;
1698     }
1699     dc->pc = pc_start;
1700     dc->singlestep_enabled = cs->singlestep_enabled;
1701     dc->cpustate_changed = 0;
1702     dc->abort_at_next_insn = 0;
1703     dc->nr_nops = 0;
1704
1705     if (pc_start & 3) {
1706         cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
1707     }
1708
1709     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1710 #if !SIM_COMPAT
1711         qemu_log("--------------\n");
1712         log_cpu_state(CPU(cpu), 0);
1713 #endif
1714     }
1715
1716     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1717     lj = -1;
1718     num_insns = 0;
1719     max_insns = tb->cflags & CF_COUNT_MASK;
1720     if (max_insns == 0)
1721         max_insns = CF_COUNT_MASK;
1722
1723     gen_tb_start(tb);
1724     do
1725     {
1726 #if SIM_COMPAT
1727         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1728             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
1729             gen_helper_debug();
1730         }
1731 #endif
1732         check_breakpoint(env, dc);
1733
1734         if (search_pc) {
1735             j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
1736             if (lj < j) {
1737                 lj++;
1738                 while (lj < j)
1739                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
1740             }
1741             tcg_ctx.gen_opc_pc[lj] = dc->pc;
1742             tcg_ctx.gen_opc_instr_start[lj] = 1;
1743                         tcg_ctx.gen_opc_icount[lj] = num_insns;
1744         }
1745
1746         /* Pretty disas.  */
1747         LOG_DIS("%8.8x:\t", dc->pc);
1748
1749         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1750             gen_io_start();
1751
1752         dc->clear_imm = 1;
1753         decode(dc, cpu_ldl_code(env, dc->pc));
1754         if (dc->clear_imm)
1755             dc->tb_flags &= ~IMM_FLAG;
1756         dc->pc += 4;
1757         num_insns++;
1758
1759         if (dc->delayed_branch) {
1760             dc->delayed_branch--;
1761             if (!dc->delayed_branch) {
1762                 if (dc->tb_flags & DRTI_FLAG)
1763                     do_rti(dc);
1764                  if (dc->tb_flags & DRTB_FLAG)
1765                     do_rtb(dc);
1766                 if (dc->tb_flags & DRTE_FLAG)
1767                     do_rte(dc);
1768                 /* Clear the delay slot flag.  */
1769                 dc->tb_flags &= ~D_FLAG;
1770                 /* If it is a direct jump, try direct chaining.  */
1771                 if (dc->jmp == JMP_INDIRECT) {
1772                     eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
1773                     dc->is_jmp = DISAS_JUMP;
1774                 } else if (dc->jmp == JMP_DIRECT) {
1775                     t_sync_flags(dc);
1776                     gen_goto_tb(dc, 0, dc->jmp_pc);
1777                     dc->is_jmp = DISAS_TB_JUMP;
1778                 } else if (dc->jmp == JMP_DIRECT_CC) {
1779                     int l1;
1780
1781                     t_sync_flags(dc);
1782                     l1 = gen_new_label();
1783                     /* Conditional jmp.  */
1784                     tcg_gen_brcondi_tl(TCG_COND_NE, env_btaken, 0, l1);
1785                     gen_goto_tb(dc, 1, dc->pc);
1786                     gen_set_label(l1);
1787                     gen_goto_tb(dc, 0, dc->jmp_pc);
1788
1789                     dc->is_jmp = DISAS_TB_JUMP;
1790                 }
1791                 break;
1792             }
1793         }
1794         if (cs->singlestep_enabled) {
1795             break;
1796         }
1797     } while (!dc->is_jmp && !dc->cpustate_changed
1798          && tcg_ctx.gen_opc_ptr < gen_opc_end
1799                  && !singlestep
1800          && (dc->pc < next_page_start)
1801                  && num_insns < max_insns);
1802
1803     npc = dc->pc;
1804     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1805         if (dc->tb_flags & D_FLAG) {
1806             dc->is_jmp = DISAS_UPDATE;
1807             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1808             sync_jmpstate(dc);
1809         } else
1810             npc = dc->jmp_pc;
1811     }
1812
1813     if (tb->cflags & CF_LAST_IO)
1814         gen_io_end();
1815     /* Force an update if the per-tb cpu state has changed.  */
1816     if (dc->is_jmp == DISAS_NEXT
1817         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
1818         dc->is_jmp = DISAS_UPDATE;
1819         tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1820     }
1821     t_sync_flags(dc);
1822
1823     if (unlikely(cs->singlestep_enabled)) {
1824         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
1825
1826         if (dc->is_jmp != DISAS_JUMP) {
1827             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1828         }
1829         gen_helper_raise_exception(cpu_env, tmp);
1830         tcg_temp_free_i32(tmp);
1831     } else {
1832         switch(dc->is_jmp) {
1833             case DISAS_NEXT:
1834                 gen_goto_tb(dc, 1, npc);
1835                 break;
1836             default:
1837             case DISAS_JUMP:
1838             case DISAS_UPDATE:
1839                 /* indicate that the hash table must be used
1840                    to find the next TB */
1841                 tcg_gen_exit_tb(0);
1842                 break;
1843             case DISAS_TB_JUMP:
1844                 /* nothing more to generate */
1845                 break;
1846         }
1847     }
1848     gen_tb_end(tb, num_insns);
1849     *tcg_ctx.gen_opc_ptr = INDEX_op_end;
1850     if (search_pc) {
1851         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
1852         lj++;
1853         while (lj <= j)
1854             tcg_ctx.gen_opc_instr_start[lj++] = 0;
1855     } else {
1856         tb->size = dc->pc - pc_start;
1857                 tb->icount = num_insns;
1858     }
1859
1860 #ifdef DEBUG_DISAS
1861 #if !SIM_COMPAT
1862     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1863         qemu_log("\n");
1864 #if DISAS_GNU
1865         log_target_disas(env, pc_start, dc->pc - pc_start, 0);
1866 #endif
1867         qemu_log("\nisize=%d osize=%td\n",
1868             dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
1869             tcg_ctx.gen_opc_buf);
1870     }
1871 #endif
1872 #endif
1873     assert(!dc->abort_at_next_insn);
1874 }
1875
1876 void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
1877 {
1878     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
1879 }
1880
1881 void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
1882 {
1883     gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
1884 }
1885
1886 void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
1887                        int flags)
1888 {
1889     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
1890     CPUMBState *env = &cpu->env;
1891     int i;
1892
1893     if (!env || !f)
1894         return;
1895
1896     cpu_fprintf(f, "IN: PC=%x %s\n",
1897                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
1898     cpu_fprintf(f, "rmsr=%x resr=%x rear=%x debug=%x imm=%x iflags=%x fsr=%x\n",
1899              env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
1900              env->debug, env->imm, env->iflags, env->sregs[SR_FSR]);
1901     cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
1902              env->btaken, env->btarget,
1903              (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
1904              (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
1905              (env->sregs[SR_MSR] & MSR_EIP),
1906              (env->sregs[SR_MSR] & MSR_IE));
1907
1908     for (i = 0; i < 32; i++) {
1909         cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
1910         if ((i + 1) % 4 == 0)
1911             cpu_fprintf(f, "\n");
1912         }
1913     cpu_fprintf(f, "\n\n");
1914 }
1915
1916 MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
1917 {
1918     MicroBlazeCPU *cpu;
1919
1920     cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
1921
1922     object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
1923
1924     return cpu;
1925 }
1926
1927 void mb_tcg_init(void)
1928 {
1929     int i;
1930
1931     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1932
1933     env_debug = tcg_global_mem_new(TCG_AREG0, 
1934                     offsetof(CPUMBState, debug),
1935                     "debug0");
1936     env_iflags = tcg_global_mem_new(TCG_AREG0, 
1937                     offsetof(CPUMBState, iflags),
1938                     "iflags");
1939     env_imm = tcg_global_mem_new(TCG_AREG0, 
1940                     offsetof(CPUMBState, imm),
1941                     "imm");
1942     env_btarget = tcg_global_mem_new(TCG_AREG0,
1943                      offsetof(CPUMBState, btarget),
1944                      "btarget");
1945     env_btaken = tcg_global_mem_new(TCG_AREG0,
1946                      offsetof(CPUMBState, btaken),
1947                      "btaken");
1948     env_res_addr = tcg_global_mem_new(TCG_AREG0,
1949                      offsetof(CPUMBState, res_addr),
1950                      "res_addr");
1951     env_res_val = tcg_global_mem_new(TCG_AREG0,
1952                      offsetof(CPUMBState, res_val),
1953                      "res_val");
1954     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
1955         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
1956                           offsetof(CPUMBState, regs[i]),
1957                           regnames[i]);
1958     }
1959     for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
1960         cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
1961                           offsetof(CPUMBState, sregs[i]),
1962                           special_regnames[i]);
1963     }
1964 }
1965
1966 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)
1967 {
1968     env->sregs[SR_PC] = tcg_ctx.gen_opc_pc[pc_pos];
1969 }
This page took 0.142021 seconds and 4 git commands to generate.