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