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.  */
sign_extend(unsigned int val,unsigned int width)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 
t_sync_flags(DisasContext * dc)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 
t_gen_raise_exception(DisasContext * dc,uint32_t index)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 
gen_goto_tb(DisasContext * dc,int n,target_ulong dest)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((long)tb + n);
150     } else {
151         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
152         tcg_gen_exit_tb(0);
153     }
154 }
155 
read_carry(DisasContext * dc,TCGv d)156 static void read_carry(DisasContext *dc, TCGv d)
157 {
158     tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
159 }
160 
write_carry(DisasContext * dc,TCGv v)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.  */
dec_alu_op_b_is_small_imm(DisasContext * dc)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 
dec_alu_op_b(DisasContext * dc)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 
dec_add(DisasContext * dc)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 
dec_sub(DisasContext * dc)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 
dec_pattern(DisasContext * dc)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 
dec_and(DisasContext * dc)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 
dec_or(DisasContext * dc)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 
dec_xor(DisasContext * dc)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 
msr_read(DisasContext * dc,TCGv d)421 static inline void msr_read(DisasContext *dc, TCGv d)
422 {
423     tcg_gen_mov_tl(d, cpu_SR[SR_MSR]);
424 }
425 
msr_write(DisasContext * dc,TCGv v)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 
dec_msr(DisasContext * dc)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.  */
t_gen_muls(TCGv d,TCGv d2,TCGv a,TCGv b)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.  */
t_gen_mulu(TCGv d,TCGv d2,TCGv a,TCGv b)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.  */
dec_mul(DisasContext * dc)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.  */
dec_div(DisasContext * dc)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 
dec_barrel(DisasContext * dc)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 
dec_bit(DisasContext * dc)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 
sync_jmpstate(DisasContext * dc)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 
dec_imm(DisasContext * dc)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 
gen_load(DisasContext * dc,TCGv dst,TCGv addr,unsigned int size)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 
compute_ldst_addr(DisasContext * dc,TCGv * t)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 
dec_byteswap(DisasContext * dc,TCGv dst,TCGv src,int size)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 
dec_load(DisasContext * dc)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 endianess.
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 
gen_store(DisasContext * dc,TCGv addr,TCGv val,unsigned int size)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 
dec_store(DisasContext * dc)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 
eval_cc(DisasContext * dc,unsigned int cc,TCGv d,TCGv a,TCGv b)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 
eval_cond_jmp(DisasContext * dc,TCGv pc_true,TCGv pc_false)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 
dec_bcc(DisasContext * dc)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 
dec_br(DisasContext * dc)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 
do_rti(DisasContext * dc)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 
do_rtb(DisasContext * dc)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 
do_rte(DisasContext * dc)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 
dec_rts(DisasContext * dc)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 
dec_check_fpuv2(DisasContext * dc)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 
dec_fpu(DisasContext * dc)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 
dec_null(DisasContext * dc)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 static struct decoder_info {
1480     struct {
1481         uint32_t bits;
1482         uint32_t mask;
1483     };
1484     void (*dec)(DisasContext *dc);
1485 } decinfo[] = {
1486     {DEC_ADD, dec_add},
1487     {DEC_SUB, dec_sub},
1488     {DEC_AND, dec_and},
1489     {DEC_XOR, dec_xor},
1490     {DEC_OR, dec_or},
1491     {DEC_BIT, dec_bit},
1492     {DEC_BARREL, dec_barrel},
1493     {DEC_LD, dec_load},
1494     {DEC_ST, dec_store},
1495     {DEC_IMM, dec_imm},
1496     {DEC_BR, dec_br},
1497     {DEC_BCC, dec_bcc},
1498     {DEC_RTS, dec_rts},
1499     {DEC_FPU, dec_fpu},
1500     {DEC_MUL, dec_mul},
1501     {DEC_DIV, dec_div},
1502     {DEC_MSR, dec_msr},
1503     {{0, 0}, dec_null}
1504 };
1505 
decode(DisasContext * dc)1506 static inline void decode(DisasContext *dc)
1507 {
1508     uint32_t ir;
1509     int i;
1510 
1511     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1512         tcg_gen_debug_insn_start(dc->pc);
1513 
1514     dc->ir = ir = ldl_code(dc->pc);
1515     LOG_DIS("%8.8x\t", dc->ir);
1516 
1517     if (dc->ir)
1518         dc->nr_nops = 0;
1519     else {
1520         if ((dc->tb_flags & MSR_EE_FLAG)
1521               && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
1522               && (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
1523             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
1524             t_gen_raise_exception(dc, EXCP_HW_EXCP);
1525             return;
1526         }
1527 
1528         LOG_DIS("nr_nops=%d\t", dc->nr_nops);
1529         dc->nr_nops++;
1530         if (dc->nr_nops > 4)
1531             cpu_abort(dc->env, "fetching nop sequence\n");
1532     }
1533     /* bit 2 seems to indicate insn type.  */
1534     dc->type_b = ir & (1 << 29);
1535 
1536     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
1537     dc->rd = EXTRACT_FIELD(ir, 21, 25);
1538     dc->ra = EXTRACT_FIELD(ir, 16, 20);
1539     dc->rb = EXTRACT_FIELD(ir, 11, 15);
1540     dc->imm = EXTRACT_FIELD(ir, 0, 15);
1541 
1542     /* Large switch for all insns.  */
1543     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
1544         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
1545             decinfo[i].dec(dc);
1546             break;
1547         }
1548     }
1549 }
1550 
check_breakpoint(CPUState * env,DisasContext * dc)1551 static void check_breakpoint(CPUState *env, DisasContext *dc)
1552 {
1553     CPUBreakpoint *bp;
1554 
1555     if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
1556         QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1557             if (bp->pc == dc->pc) {
1558                 t_gen_raise_exception(dc, EXCP_DEBUG);
1559                 dc->is_jmp = DISAS_UPDATE;
1560              }
1561         }
1562     }
1563 }
1564 
1565 /* generate intermediate code for basic block 'tb'.  */
1566 static void
gen_intermediate_code_internal(CPUState * env,TranslationBlock * tb,int search_pc)1567 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
1568                                int search_pc)
1569 {
1570     uint16_t *gen_opc_end;
1571     uint32_t pc_start;
1572     int j, lj;
1573     struct DisasContext ctx;
1574     struct DisasContext *dc = &ctx;
1575     uint32_t next_page_start, org_flags;
1576     target_ulong npc;
1577     int num_insns;
1578     int max_insns;
1579 
1580     qemu_log_try_set_file(stderr);
1581 
1582     pc_start = tb->pc;
1583     dc->env = env;
1584     dc->tb = tb;
1585     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
1586 
1587     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1588 
1589     dc->is_jmp = DISAS_NEXT;
1590     dc->jmp = 0;
1591     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
1592     if (dc->delayed_branch) {
1593         dc->jmp = JMP_INDIRECT;
1594     }
1595     dc->pc = pc_start;
1596     dc->singlestep_enabled = env->singlestep_enabled;
1597     dc->cpustate_changed = 0;
1598     dc->abort_at_next_insn = 0;
1599     dc->nr_nops = 0;
1600 
1601     if (pc_start & 3)
1602         cpu_abort(env, "Microblaze: unaligned PC=%x\n", pc_start);
1603 
1604     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1605 #if !SIM_COMPAT
1606         qemu_log("--------------\n");
1607         log_cpu_state(env, 0);
1608 #endif
1609     }
1610 
1611     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1612     lj = -1;
1613     num_insns = 0;
1614     max_insns = tb->cflags & CF_COUNT_MASK;
1615     if (max_insns == 0)
1616         max_insns = CF_COUNT_MASK;
1617 
1618     gen_icount_start();
1619     do
1620     {
1621 #if SIM_COMPAT
1622         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1623             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
1624             gen_helper_debug();
1625         }
1626 #endif
1627         check_breakpoint(env, dc);
1628 
1629         if (search_pc) {
1630             j = gen_opc_ptr - gen_opc_buf;
1631             if (lj < j) {
1632                 lj++;
1633                 while (lj < j)
1634                     gen_opc_instr_start[lj++] = 0;
1635             }
1636             gen_opc_pc[lj] = dc->pc;
1637             gen_opc_instr_start[lj] = 1;
1638                         gen_opc_icount[lj] = num_insns;
1639         }
1640 
1641         /* Pretty disas.  */
1642         LOG_DIS("%8.8x:\t", dc->pc);
1643 
1644         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1645             gen_io_start();
1646 
1647         dc->clear_imm = 1;
1648 	decode(dc);
1649         if (dc->clear_imm)
1650             dc->tb_flags &= ~IMM_FLAG;
1651         dc->pc += 4;
1652         num_insns++;
1653 
1654         if (dc->delayed_branch) {
1655             dc->delayed_branch--;
1656             if (!dc->delayed_branch) {
1657                 if (dc->tb_flags & DRTI_FLAG)
1658                     do_rti(dc);
1659                  if (dc->tb_flags & DRTB_FLAG)
1660                     do_rtb(dc);
1661                 if (dc->tb_flags & DRTE_FLAG)
1662                     do_rte(dc);
1663                 /* Clear the delay slot flag.  */
1664                 dc->tb_flags &= ~D_FLAG;
1665                 /* If it is a direct jump, try direct chaining.  */
1666                 if (dc->jmp == JMP_INDIRECT) {
1667                     eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
1668                     dc->is_jmp = DISAS_JUMP;
1669                 } else if (dc->jmp == JMP_DIRECT) {
1670                     t_sync_flags(dc);
1671                     gen_goto_tb(dc, 0, dc->jmp_pc);
1672                     dc->is_jmp = DISAS_TB_JUMP;
1673                 } else if (dc->jmp == JMP_DIRECT_CC) {
1674                     int l1;
1675 
1676                     t_sync_flags(dc);
1677                     l1 = gen_new_label();
1678                     /* Conditional jmp.  */
1679                     tcg_gen_brcondi_tl(TCG_COND_NE, env_btaken, 0, l1);
1680                     gen_goto_tb(dc, 1, dc->pc);
1681                     gen_set_label(l1);
1682                     gen_goto_tb(dc, 0, dc->jmp_pc);
1683 
1684                     dc->is_jmp = DISAS_TB_JUMP;
1685                 }
1686                 break;
1687             }
1688         }
1689         if (env->singlestep_enabled)
1690             break;
1691     } while (!dc->is_jmp && !dc->cpustate_changed
1692          && gen_opc_ptr < gen_opc_end
1693                  && !singlestep
1694          && (dc->pc < next_page_start)
1695                  && num_insns < max_insns);
1696 
1697     npc = dc->pc;
1698     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1699         if (dc->tb_flags & D_FLAG) {
1700             dc->is_jmp = DISAS_UPDATE;
1701             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1702             sync_jmpstate(dc);
1703         } else
1704             npc = dc->jmp_pc;
1705     }
1706 
1707     if (tb->cflags & CF_LAST_IO)
1708         gen_io_end();
1709     /* Force an update if the per-tb cpu state has changed.  */
1710     if (dc->is_jmp == DISAS_NEXT
1711         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
1712         dc->is_jmp = DISAS_UPDATE;
1713         tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1714     }
1715     t_sync_flags(dc);
1716 
1717     if (unlikely(env->singlestep_enabled)) {
1718         t_gen_raise_exception(dc, EXCP_DEBUG);
1719         if (dc->is_jmp == DISAS_NEXT)
1720             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
1721     } else {
1722         switch(dc->is_jmp) {
1723             case DISAS_NEXT:
1724                 gen_goto_tb(dc, 1, npc);
1725                 break;
1726             default:
1727             case DISAS_JUMP:
1728             case DISAS_UPDATE:
1729                 /* indicate that the hash table must be used
1730                    to find the next TB */
1731                 tcg_gen_exit_tb(0);
1732                 break;
1733             case DISAS_TB_JUMP:
1734                 /* nothing more to generate */
1735                 break;
1736         }
1737     }
1738     gen_icount_end(tb, num_insns);
1739     *gen_opc_ptr = INDEX_op_end;
1740     if (search_pc) {
1741         j = gen_opc_ptr - gen_opc_buf;
1742         lj++;
1743         while (lj <= j)
1744             gen_opc_instr_start[lj++] = 0;
1745     } else {
1746         tb->size = dc->pc - pc_start;
1747                 tb->icount = num_insns;
1748     }
1749 
1750 #ifdef DEBUG_DISAS
1751 #if !SIM_COMPAT
1752     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1753         qemu_log("\n");
1754 #if DISAS_GNU
1755         log_target_disas(pc_start, dc->pc - pc_start, 0);
1756 #endif
1757         qemu_log("\nisize=%d osize=%td\n",
1758             dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
1759     }
1760 #endif
1761 #endif
1762     assert(!dc->abort_at_next_insn);
1763 }
1764 
gen_intermediate_code(CPUState * env,struct TranslationBlock * tb)1765 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1766 {
1767     gen_intermediate_code_internal(env, tb, 0);
1768 }
1769 
gen_intermediate_code_pc(CPUState * env,struct TranslationBlock * tb)1770 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1771 {
1772     gen_intermediate_code_internal(env, tb, 1);
1773 }
1774 
cpu_dump_state(CPUState * env,FILE * f,fprintf_function cpu_fprintf,int flags)1775 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1776                      int flags)
1777 {
1778     int i;
1779 
1780     if (!env || !f)
1781         return;
1782 
1783     cpu_fprintf(f, "IN: PC=%x %s\n",
1784                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
1785     cpu_fprintf(f, "rmsr=%x resr=%x rear=%x debug=%x imm=%x iflags=%x fsr=%x\n",
1786              env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
1787              env->debug, env->imm, env->iflags, env->sregs[SR_FSR]);
1788     cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
1789              env->btaken, env->btarget,
1790              (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
1791              (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
1792              (env->sregs[SR_MSR] & MSR_EIP),
1793              (env->sregs[SR_MSR] & MSR_IE));
1794 
1795     for (i = 0; i < 32; i++) {
1796         cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
1797         if ((i + 1) % 4 == 0)
1798             cpu_fprintf(f, "\n");
1799         }
1800     cpu_fprintf(f, "\n\n");
1801 }
1802 
cpu_mb_init(const char * cpu_model)1803 CPUState *cpu_mb_init (const char *cpu_model)
1804 {
1805     CPUState *env;
1806     static int tcg_initialized = 0;
1807     int i;
1808 
1809     env = qemu_mallocz(sizeof(CPUState));
1810 
1811     cpu_exec_init(env);
1812     cpu_reset(env);
1813     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1814 
1815     if (tcg_initialized)
1816         return env;
1817 
1818     tcg_initialized = 1;
1819 
1820     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1821 
1822     env_debug = tcg_global_mem_new(TCG_AREG0,
1823                     offsetof(CPUState, debug),
1824                     "debug0");
1825     env_iflags = tcg_global_mem_new(TCG_AREG0,
1826                     offsetof(CPUState, iflags),
1827                     "iflags");
1828     env_imm = tcg_global_mem_new(TCG_AREG0,
1829                     offsetof(CPUState, imm),
1830                     "imm");
1831     env_btarget = tcg_global_mem_new(TCG_AREG0,
1832                      offsetof(CPUState, btarget),
1833                      "btarget");
1834     env_btaken = tcg_global_mem_new(TCG_AREG0,
1835                      offsetof(CPUState, btaken),
1836                      "btaken");
1837     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
1838         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
1839                           offsetof(CPUState, regs[i]),
1840                           regnames[i]);
1841     }
1842     for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
1843         cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
1844                           offsetof(CPUState, sregs[i]),
1845                           special_regnames[i]);
1846     }
1847 #define GEN_HELPER 2
1848 #include "helper.h"
1849 
1850     return env;
1851 }
1852 
cpu_reset(CPUState * env)1853 void cpu_reset (CPUState *env)
1854 {
1855     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1856         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
1857         log_cpu_state(env, 0);
1858     }
1859 
1860     memset(env, 0, offsetof(CPUMBState, breakpoints));
1861     tlb_flush(env, 1);
1862 
1863     env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
1864                        | PVR0_USE_BARREL_MASK \
1865                        | PVR0_USE_DIV_MASK \
1866                        | PVR0_USE_HW_MUL_MASK \
1867                        | PVR0_USE_EXC_MASK \
1868                        | PVR0_USE_ICACHE_MASK \
1869                        | PVR0_USE_DCACHE_MASK \
1870                        | PVR0_USE_MMU \
1871                        | (0xb << 8);
1872     env->pvr.regs[2] = PVR2_D_OPB_MASK \
1873                         | PVR2_D_LMB_MASK \
1874                         | PVR2_I_OPB_MASK \
1875                         | PVR2_I_LMB_MASK \
1876                         | PVR2_USE_MSR_INSTR \
1877                         | PVR2_USE_PCMP_INSTR \
1878                         | PVR2_USE_BARREL_MASK \
1879                         | PVR2_USE_DIV_MASK \
1880                         | PVR2_USE_HW_MUL_MASK \
1881                         | PVR2_USE_MUL64_MASK \
1882                         | PVR2_USE_FPU_MASK \
1883                         | PVR2_USE_FPU2_MASK \
1884                         | PVR2_FPU_EXC_MASK \
1885                         | 0;
1886     env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family.  */
1887     env->pvr.regs[11] = PVR11_USE_MMU | (16 << 17);
1888 
1889 #if defined(CONFIG_USER_ONLY)
1890     /* start in user mode with interrupts enabled.  */
1891     env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
1892     env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp.  */
1893 #else
1894     env->sregs[SR_MSR] = 0;
1895     mmu_init(&env->mmu);
1896     env->mmu.c_mmu = 3;
1897     env->mmu.c_mmu_tlb_access = 3;
1898     env->mmu.c_mmu_zones = 16;
1899 #endif
1900 }
1901 
gen_pc_load(CPUState * env,struct TranslationBlock * tb,unsigned long searched_pc,int pc_pos,void * puc)1902 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
1903                  unsigned long searched_pc, int pc_pos, void *puc)
1904 {
1905     env->sregs[SR_PC] = gen_opc_pc[pc_pos];
1906 }
1907