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