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