xref: /qemu/target/microblaze/translate.c (revision 138ca49a)
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.1 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/tcg-op.h"
26 #include "exec/helper-proto.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/helper-gen.h"
29 #include "exec/translator.h"
30 #include "qemu/qemu-print.h"
31 
32 #include "trace-tcg.h"
33 #include "exec/log.h"
34 
35 #define EXTRACT_FIELD(src, start, end) \
36             (((src) >> start) & ((1 << (end - start + 1)) - 1))
37 
38 /* is_jmp field values */
39 #define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
40 #define DISAS_EXIT    DISAS_TARGET_1 /* all cpu state modified dynamically */
41 
42 /* cpu state besides pc was modified dynamically; update pc to next */
43 #define DISAS_EXIT_NEXT DISAS_TARGET_2
44 /* cpu state besides pc was modified dynamically; update pc to btarget */
45 #define DISAS_EXIT_JUMP DISAS_TARGET_3
46 
47 static TCGv_i32 cpu_R[32];
48 static TCGv_i32 cpu_pc;
49 static TCGv_i32 cpu_msr;
50 static TCGv_i32 cpu_msr_c;
51 static TCGv_i32 cpu_imm;
52 static TCGv_i32 cpu_bvalue;
53 static TCGv_i32 cpu_btarget;
54 static TCGv_i32 cpu_iflags;
55 static TCGv cpu_res_addr;
56 static TCGv_i32 cpu_res_val;
57 
58 #include "exec/gen-icount.h"
59 
60 /* This is the state at translation time.  */
61 typedef struct DisasContext {
62     DisasContextBase base;
63     const MicroBlazeCPUConfig *cfg;
64 
65     /* TCG op of the current insn_start.  */
66     TCGOp *insn_start;
67 
68     TCGv_i32 r0;
69     bool r0_set;
70 
71     /* Decoder.  */
72     uint32_t ext_imm;
73     unsigned int tb_flags;
74     unsigned int tb_flags_to_set;
75     int mem_index;
76 
77     /* Condition under which to jump, including NEVER and ALWAYS. */
78     TCGCond jmp_cond;
79 
80     /* Immediate branch-taken destination, or -1 for indirect. */
81     uint32_t jmp_dest;
82 } DisasContext;
83 
84 static int typeb_imm(DisasContext *dc, int x)
85 {
86     if (dc->tb_flags & IMM_FLAG) {
87         return deposit32(dc->ext_imm, 0, 16, x);
88     }
89     return x;
90 }
91 
92 /* Include the auto-generated decoder.  */
93 #include "decode-insns.c.inc"
94 
95 static void t_sync_flags(DisasContext *dc)
96 {
97     /* Synch the tb dependent flags between translator and runtime.  */
98     if ((dc->tb_flags ^ dc->base.tb->flags) & IFLAGS_TB_MASK) {
99         tcg_gen_movi_i32(cpu_iflags, dc->tb_flags & IFLAGS_TB_MASK);
100     }
101 }
102 
103 static void gen_raise_exception(DisasContext *dc, uint32_t index)
104 {
105     TCGv_i32 tmp = tcg_const_i32(index);
106 
107     gen_helper_raise_exception(cpu_env, tmp);
108     tcg_temp_free_i32(tmp);
109     dc->base.is_jmp = DISAS_NORETURN;
110 }
111 
112 static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
113 {
114     t_sync_flags(dc);
115     tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
116     gen_raise_exception(dc, index);
117 }
118 
119 static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
120 {
121     TCGv_i32 tmp = tcg_const_i32(esr_ec);
122     tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, esr));
123     tcg_temp_free_i32(tmp);
124 
125     gen_raise_exception_sync(dc, EXCP_HW_EXCP);
126 }
127 
128 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
129 {
130 #ifndef CONFIG_USER_ONLY
131     return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
132 #else
133     return true;
134 #endif
135 }
136 
137 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
138 {
139     if (dc->base.singlestep_enabled) {
140         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
141         tcg_gen_movi_i32(cpu_pc, dest);
142         gen_helper_raise_exception(cpu_env, tmp);
143         tcg_temp_free_i32(tmp);
144     } else if (use_goto_tb(dc, dest)) {
145         tcg_gen_goto_tb(n);
146         tcg_gen_movi_i32(cpu_pc, dest);
147         tcg_gen_exit_tb(dc->base.tb, n);
148     } else {
149         tcg_gen_movi_i32(cpu_pc, dest);
150         tcg_gen_lookup_and_goto_ptr();
151     }
152     dc->base.is_jmp = DISAS_NORETURN;
153 }
154 
155 /*
156  * Returns true if the insn an illegal operation.
157  * If exceptions are enabled, an exception is raised.
158  */
159 static bool trap_illegal(DisasContext *dc, bool cond)
160 {
161     if (cond && (dc->tb_flags & MSR_EE)
162         && dc->cfg->illegal_opcode_exception) {
163         gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
164     }
165     return cond;
166 }
167 
168 /*
169  * Returns true if the insn is illegal in userspace.
170  * If exceptions are enabled, an exception is raised.
171  */
172 static bool trap_userspace(DisasContext *dc, bool cond)
173 {
174     bool cond_user = cond && dc->mem_index == MMU_USER_IDX;
175 
176     if (cond_user && (dc->tb_flags & MSR_EE)) {
177         gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
178     }
179     return cond_user;
180 }
181 
182 /*
183  * Return true, and log an error, if the current insn is
184  * within a delay slot.
185  */
186 static bool invalid_delay_slot(DisasContext *dc, const char *insn_type)
187 {
188     if (dc->tb_flags & D_FLAG) {
189         qemu_log_mask(LOG_GUEST_ERROR,
190                       "Invalid insn in delay slot: %s at %08x\n",
191                       insn_type, (uint32_t)dc->base.pc_next);
192         return true;
193     }
194     return false;
195 }
196 
197 static TCGv_i32 reg_for_read(DisasContext *dc, int reg)
198 {
199     if (likely(reg != 0)) {
200         return cpu_R[reg];
201     }
202     if (!dc->r0_set) {
203         if (dc->r0 == NULL) {
204             dc->r0 = tcg_temp_new_i32();
205         }
206         tcg_gen_movi_i32(dc->r0, 0);
207         dc->r0_set = true;
208     }
209     return dc->r0;
210 }
211 
212 static TCGv_i32 reg_for_write(DisasContext *dc, int reg)
213 {
214     if (likely(reg != 0)) {
215         return cpu_R[reg];
216     }
217     if (dc->r0 == NULL) {
218         dc->r0 = tcg_temp_new_i32();
219     }
220     return dc->r0;
221 }
222 
223 static bool do_typea(DisasContext *dc, arg_typea *arg, bool side_effects,
224                      void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
225 {
226     TCGv_i32 rd, ra, rb;
227 
228     if (arg->rd == 0 && !side_effects) {
229         return true;
230     }
231 
232     rd = reg_for_write(dc, arg->rd);
233     ra = reg_for_read(dc, arg->ra);
234     rb = reg_for_read(dc, arg->rb);
235     fn(rd, ra, rb);
236     return true;
237 }
238 
239 static bool do_typea0(DisasContext *dc, arg_typea0 *arg, bool side_effects,
240                       void (*fn)(TCGv_i32, TCGv_i32))
241 {
242     TCGv_i32 rd, ra;
243 
244     if (arg->rd == 0 && !side_effects) {
245         return true;
246     }
247 
248     rd = reg_for_write(dc, arg->rd);
249     ra = reg_for_read(dc, arg->ra);
250     fn(rd, ra);
251     return true;
252 }
253 
254 static bool do_typeb_imm(DisasContext *dc, arg_typeb *arg, bool side_effects,
255                          void (*fni)(TCGv_i32, TCGv_i32, int32_t))
256 {
257     TCGv_i32 rd, ra;
258 
259     if (arg->rd == 0 && !side_effects) {
260         return true;
261     }
262 
263     rd = reg_for_write(dc, arg->rd);
264     ra = reg_for_read(dc, arg->ra);
265     fni(rd, ra, arg->imm);
266     return true;
267 }
268 
269 static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
270                          void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
271 {
272     TCGv_i32 rd, ra, imm;
273 
274     if (arg->rd == 0 && !side_effects) {
275         return true;
276     }
277 
278     rd = reg_for_write(dc, arg->rd);
279     ra = reg_for_read(dc, arg->ra);
280     imm = tcg_const_i32(arg->imm);
281 
282     fn(rd, ra, imm);
283 
284     tcg_temp_free_i32(imm);
285     return true;
286 }
287 
288 #define DO_TYPEA(NAME, SE, FN) \
289     static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
290     { return do_typea(dc, a, SE, FN); }
291 
292 #define DO_TYPEA_CFG(NAME, CFG, SE, FN) \
293     static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
294     { return dc->cfg->CFG && do_typea(dc, a, SE, FN); }
295 
296 #define DO_TYPEA0(NAME, SE, FN) \
297     static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
298     { return do_typea0(dc, a, SE, FN); }
299 
300 #define DO_TYPEA0_CFG(NAME, CFG, SE, FN) \
301     static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
302     { return dc->cfg->CFG && do_typea0(dc, a, SE, FN); }
303 
304 #define DO_TYPEBI(NAME, SE, FNI) \
305     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
306     { return do_typeb_imm(dc, a, SE, FNI); }
307 
308 #define DO_TYPEBI_CFG(NAME, CFG, SE, FNI) \
309     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
310     { return dc->cfg->CFG && do_typeb_imm(dc, a, SE, FNI); }
311 
312 #define DO_TYPEBV(NAME, SE, FN) \
313     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
314     { return do_typeb_val(dc, a, SE, FN); }
315 
316 #define ENV_WRAPPER2(NAME, HELPER) \
317     static void NAME(TCGv_i32 out, TCGv_i32 ina) \
318     { HELPER(out, cpu_env, ina); }
319 
320 #define ENV_WRAPPER3(NAME, HELPER) \
321     static void NAME(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb) \
322     { HELPER(out, cpu_env, ina, inb); }
323 
324 /* No input carry, but output carry. */
325 static void gen_add(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
326 {
327     TCGv_i32 zero = tcg_const_i32(0);
328 
329     tcg_gen_add2_i32(out, cpu_msr_c, ina, zero, inb, zero);
330 
331     tcg_temp_free_i32(zero);
332 }
333 
334 /* Input and output carry. */
335 static void gen_addc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
336 {
337     TCGv_i32 zero = tcg_const_i32(0);
338     TCGv_i32 tmp = tcg_temp_new_i32();
339 
340     tcg_gen_add2_i32(tmp, cpu_msr_c, ina, zero, cpu_msr_c, zero);
341     tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
342 
343     tcg_temp_free_i32(tmp);
344     tcg_temp_free_i32(zero);
345 }
346 
347 /* Input carry, but no output carry. */
348 static void gen_addkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
349 {
350     tcg_gen_add_i32(out, ina, inb);
351     tcg_gen_add_i32(out, out, cpu_msr_c);
352 }
353 
354 DO_TYPEA(add, true, gen_add)
355 DO_TYPEA(addc, true, gen_addc)
356 DO_TYPEA(addk, false, tcg_gen_add_i32)
357 DO_TYPEA(addkc, true, gen_addkc)
358 
359 DO_TYPEBV(addi, true, gen_add)
360 DO_TYPEBV(addic, true, gen_addc)
361 DO_TYPEBI(addik, false, tcg_gen_addi_i32)
362 DO_TYPEBV(addikc, true, gen_addkc)
363 
364 static void gen_andni(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
365 {
366     tcg_gen_andi_i32(out, ina, ~imm);
367 }
368 
369 DO_TYPEA(and, false, tcg_gen_and_i32)
370 DO_TYPEBI(andi, false, tcg_gen_andi_i32)
371 DO_TYPEA(andn, false, tcg_gen_andc_i32)
372 DO_TYPEBI(andni, false, gen_andni)
373 
374 static void gen_bsra(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
375 {
376     TCGv_i32 tmp = tcg_temp_new_i32();
377     tcg_gen_andi_i32(tmp, inb, 31);
378     tcg_gen_sar_i32(out, ina, tmp);
379     tcg_temp_free_i32(tmp);
380 }
381 
382 static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
383 {
384     TCGv_i32 tmp = tcg_temp_new_i32();
385     tcg_gen_andi_i32(tmp, inb, 31);
386     tcg_gen_shr_i32(out, ina, tmp);
387     tcg_temp_free_i32(tmp);
388 }
389 
390 static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
391 {
392     TCGv_i32 tmp = tcg_temp_new_i32();
393     tcg_gen_andi_i32(tmp, inb, 31);
394     tcg_gen_shl_i32(out, ina, tmp);
395     tcg_temp_free_i32(tmp);
396 }
397 
398 static void gen_bsefi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
399 {
400     /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
401     int imm_w = extract32(imm, 5, 5);
402     int imm_s = extract32(imm, 0, 5);
403 
404     if (imm_w + imm_s > 32 || imm_w == 0) {
405         /* These inputs have an undefined behavior.  */
406         qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
407                       imm_w, imm_s);
408     } else {
409         tcg_gen_extract_i32(out, ina, imm_s, imm_w);
410     }
411 }
412 
413 static void gen_bsifi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
414 {
415     /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
416     int imm_w = extract32(imm, 5, 5);
417     int imm_s = extract32(imm, 0, 5);
418     int width = imm_w - imm_s + 1;
419 
420     if (imm_w < imm_s) {
421         /* These inputs have an undefined behavior.  */
422         qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
423                       imm_w, imm_s);
424     } else {
425         tcg_gen_deposit_i32(out, out, ina, imm_s, width);
426     }
427 }
428 
429 DO_TYPEA_CFG(bsra, use_barrel, false, gen_bsra)
430 DO_TYPEA_CFG(bsrl, use_barrel, false, gen_bsrl)
431 DO_TYPEA_CFG(bsll, use_barrel, false, gen_bsll)
432 
433 DO_TYPEBI_CFG(bsrai, use_barrel, false, tcg_gen_sari_i32)
434 DO_TYPEBI_CFG(bsrli, use_barrel, false, tcg_gen_shri_i32)
435 DO_TYPEBI_CFG(bslli, use_barrel, false, tcg_gen_shli_i32)
436 
437 DO_TYPEBI_CFG(bsefi, use_barrel, false, gen_bsefi)
438 DO_TYPEBI_CFG(bsifi, use_barrel, false, gen_bsifi)
439 
440 static void gen_clz(TCGv_i32 out, TCGv_i32 ina)
441 {
442     tcg_gen_clzi_i32(out, ina, 32);
443 }
444 
445 DO_TYPEA0_CFG(clz, use_pcmp_instr, false, gen_clz)
446 
447 static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
448 {
449     TCGv_i32 lt = tcg_temp_new_i32();
450 
451     tcg_gen_setcond_i32(TCG_COND_LT, lt, inb, ina);
452     tcg_gen_sub_i32(out, inb, ina);
453     tcg_gen_deposit_i32(out, out, lt, 31, 1);
454     tcg_temp_free_i32(lt);
455 }
456 
457 static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
458 {
459     TCGv_i32 lt = tcg_temp_new_i32();
460 
461     tcg_gen_setcond_i32(TCG_COND_LTU, lt, inb, ina);
462     tcg_gen_sub_i32(out, inb, ina);
463     tcg_gen_deposit_i32(out, out, lt, 31, 1);
464     tcg_temp_free_i32(lt);
465 }
466 
467 DO_TYPEA(cmp, false, gen_cmp)
468 DO_TYPEA(cmpu, false, gen_cmpu)
469 
470 ENV_WRAPPER3(gen_fadd, gen_helper_fadd)
471 ENV_WRAPPER3(gen_frsub, gen_helper_frsub)
472 ENV_WRAPPER3(gen_fmul, gen_helper_fmul)
473 ENV_WRAPPER3(gen_fdiv, gen_helper_fdiv)
474 ENV_WRAPPER3(gen_fcmp_un, gen_helper_fcmp_un)
475 ENV_WRAPPER3(gen_fcmp_lt, gen_helper_fcmp_lt)
476 ENV_WRAPPER3(gen_fcmp_eq, gen_helper_fcmp_eq)
477 ENV_WRAPPER3(gen_fcmp_le, gen_helper_fcmp_le)
478 ENV_WRAPPER3(gen_fcmp_gt, gen_helper_fcmp_gt)
479 ENV_WRAPPER3(gen_fcmp_ne, gen_helper_fcmp_ne)
480 ENV_WRAPPER3(gen_fcmp_ge, gen_helper_fcmp_ge)
481 
482 DO_TYPEA_CFG(fadd, use_fpu, true, gen_fadd)
483 DO_TYPEA_CFG(frsub, use_fpu, true, gen_frsub)
484 DO_TYPEA_CFG(fmul, use_fpu, true, gen_fmul)
485 DO_TYPEA_CFG(fdiv, use_fpu, true, gen_fdiv)
486 DO_TYPEA_CFG(fcmp_un, use_fpu, true, gen_fcmp_un)
487 DO_TYPEA_CFG(fcmp_lt, use_fpu, true, gen_fcmp_lt)
488 DO_TYPEA_CFG(fcmp_eq, use_fpu, true, gen_fcmp_eq)
489 DO_TYPEA_CFG(fcmp_le, use_fpu, true, gen_fcmp_le)
490 DO_TYPEA_CFG(fcmp_gt, use_fpu, true, gen_fcmp_gt)
491 DO_TYPEA_CFG(fcmp_ne, use_fpu, true, gen_fcmp_ne)
492 DO_TYPEA_CFG(fcmp_ge, use_fpu, true, gen_fcmp_ge)
493 
494 ENV_WRAPPER2(gen_flt, gen_helper_flt)
495 ENV_WRAPPER2(gen_fint, gen_helper_fint)
496 ENV_WRAPPER2(gen_fsqrt, gen_helper_fsqrt)
497 
498 DO_TYPEA0_CFG(flt, use_fpu >= 2, true, gen_flt)
499 DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
500 DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
501 
502 /* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
503 static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
504 {
505     gen_helper_divs(out, cpu_env, inb, ina);
506 }
507 
508 static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
509 {
510     gen_helper_divu(out, cpu_env, inb, ina);
511 }
512 
513 DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
514 DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
515 
516 static bool trans_imm(DisasContext *dc, arg_imm *arg)
517 {
518     if (invalid_delay_slot(dc, "imm")) {
519         return true;
520     }
521     dc->ext_imm = arg->imm << 16;
522     tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
523     dc->tb_flags_to_set = IMM_FLAG;
524     return true;
525 }
526 
527 static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
528 {
529     TCGv_i32 tmp = tcg_temp_new_i32();
530     tcg_gen_muls2_i32(tmp, out, ina, inb);
531     tcg_temp_free_i32(tmp);
532 }
533 
534 static void gen_mulhu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
535 {
536     TCGv_i32 tmp = tcg_temp_new_i32();
537     tcg_gen_mulu2_i32(tmp, out, ina, inb);
538     tcg_temp_free_i32(tmp);
539 }
540 
541 static void gen_mulhsu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
542 {
543     TCGv_i32 tmp = tcg_temp_new_i32();
544     tcg_gen_mulsu2_i32(tmp, out, ina, inb);
545     tcg_temp_free_i32(tmp);
546 }
547 
548 DO_TYPEA_CFG(mul, use_hw_mul, false, tcg_gen_mul_i32)
549 DO_TYPEA_CFG(mulh, use_hw_mul >= 2, false, gen_mulh)
550 DO_TYPEA_CFG(mulhu, use_hw_mul >= 2, false, gen_mulhu)
551 DO_TYPEA_CFG(mulhsu, use_hw_mul >= 2, false, gen_mulhsu)
552 DO_TYPEBI_CFG(muli, use_hw_mul, false, tcg_gen_muli_i32)
553 
554 DO_TYPEA(or, false, tcg_gen_or_i32)
555 DO_TYPEBI(ori, false, tcg_gen_ori_i32)
556 
557 static void gen_pcmpeq(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
558 {
559     tcg_gen_setcond_i32(TCG_COND_EQ, out, ina, inb);
560 }
561 
562 static void gen_pcmpne(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
563 {
564     tcg_gen_setcond_i32(TCG_COND_NE, out, ina, inb);
565 }
566 
567 DO_TYPEA_CFG(pcmpbf, use_pcmp_instr, false, gen_helper_pcmpbf)
568 DO_TYPEA_CFG(pcmpeq, use_pcmp_instr, false, gen_pcmpeq)
569 DO_TYPEA_CFG(pcmpne, use_pcmp_instr, false, gen_pcmpne)
570 
571 /* No input carry, but output carry. */
572 static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
573 {
574     tcg_gen_setcond_i32(TCG_COND_GEU, cpu_msr_c, inb, ina);
575     tcg_gen_sub_i32(out, inb, ina);
576 }
577 
578 /* Input and output carry. */
579 static void gen_rsubc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
580 {
581     TCGv_i32 zero = tcg_const_i32(0);
582     TCGv_i32 tmp = tcg_temp_new_i32();
583 
584     tcg_gen_not_i32(tmp, ina);
585     tcg_gen_add2_i32(tmp, cpu_msr_c, tmp, zero, cpu_msr_c, zero);
586     tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
587 
588     tcg_temp_free_i32(zero);
589     tcg_temp_free_i32(tmp);
590 }
591 
592 /* No input or output carry. */
593 static void gen_rsubk(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
594 {
595     tcg_gen_sub_i32(out, inb, ina);
596 }
597 
598 /* Input carry, no output carry. */
599 static void gen_rsubkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
600 {
601     TCGv_i32 nota = tcg_temp_new_i32();
602 
603     tcg_gen_not_i32(nota, ina);
604     tcg_gen_add_i32(out, inb, nota);
605     tcg_gen_add_i32(out, out, cpu_msr_c);
606 
607     tcg_temp_free_i32(nota);
608 }
609 
610 DO_TYPEA(rsub, true, gen_rsub)
611 DO_TYPEA(rsubc, true, gen_rsubc)
612 DO_TYPEA(rsubk, false, gen_rsubk)
613 DO_TYPEA(rsubkc, true, gen_rsubkc)
614 
615 DO_TYPEBV(rsubi, true, gen_rsub)
616 DO_TYPEBV(rsubic, true, gen_rsubc)
617 DO_TYPEBV(rsubik, false, gen_rsubk)
618 DO_TYPEBV(rsubikc, true, gen_rsubkc)
619 
620 DO_TYPEA0(sext8, false, tcg_gen_ext8s_i32)
621 DO_TYPEA0(sext16, false, tcg_gen_ext16s_i32)
622 
623 static void gen_sra(TCGv_i32 out, TCGv_i32 ina)
624 {
625     tcg_gen_andi_i32(cpu_msr_c, ina, 1);
626     tcg_gen_sari_i32(out, ina, 1);
627 }
628 
629 static void gen_src(TCGv_i32 out, TCGv_i32 ina)
630 {
631     TCGv_i32 tmp = tcg_temp_new_i32();
632 
633     tcg_gen_mov_i32(tmp, cpu_msr_c);
634     tcg_gen_andi_i32(cpu_msr_c, ina, 1);
635     tcg_gen_extract2_i32(out, ina, tmp, 1);
636 
637     tcg_temp_free_i32(tmp);
638 }
639 
640 static void gen_srl(TCGv_i32 out, TCGv_i32 ina)
641 {
642     tcg_gen_andi_i32(cpu_msr_c, ina, 1);
643     tcg_gen_shri_i32(out, ina, 1);
644 }
645 
646 DO_TYPEA0(sra, false, gen_sra)
647 DO_TYPEA0(src, false, gen_src)
648 DO_TYPEA0(srl, false, gen_srl)
649 
650 static void gen_swaph(TCGv_i32 out, TCGv_i32 ina)
651 {
652     tcg_gen_rotri_i32(out, ina, 16);
653 }
654 
655 DO_TYPEA0(swapb, false, tcg_gen_bswap32_i32)
656 DO_TYPEA0(swaph, false, gen_swaph)
657 
658 static bool trans_wdic(DisasContext *dc, arg_wdic *a)
659 {
660     /* Cache operations are nops: only check for supervisor mode.  */
661     trap_userspace(dc, true);
662     return true;
663 }
664 
665 DO_TYPEA(xor, false, tcg_gen_xor_i32)
666 DO_TYPEBI(xori, false, tcg_gen_xori_i32)
667 
668 static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
669 {
670     TCGv ret = tcg_temp_new();
671 
672     /* If any of the regs is r0, set t to the value of the other reg.  */
673     if (ra && rb) {
674         TCGv_i32 tmp = tcg_temp_new_i32();
675         tcg_gen_add_i32(tmp, cpu_R[ra], cpu_R[rb]);
676         tcg_gen_extu_i32_tl(ret, tmp);
677         tcg_temp_free_i32(tmp);
678     } else if (ra) {
679         tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
680     } else if (rb) {
681         tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
682     } else {
683         tcg_gen_movi_tl(ret, 0);
684     }
685 
686     if ((ra == 1 || rb == 1) && dc->cfg->stackprot) {
687         gen_helper_stackprot(cpu_env, ret);
688     }
689     return ret;
690 }
691 
692 static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
693 {
694     TCGv ret = tcg_temp_new();
695 
696     /* If any of the regs is r0, set t to the value of the other reg.  */
697     if (ra) {
698         TCGv_i32 tmp = tcg_temp_new_i32();
699         tcg_gen_addi_i32(tmp, cpu_R[ra], imm);
700         tcg_gen_extu_i32_tl(ret, tmp);
701         tcg_temp_free_i32(tmp);
702     } else {
703         tcg_gen_movi_tl(ret, (uint32_t)imm);
704     }
705 
706     if (ra == 1 && dc->cfg->stackprot) {
707         gen_helper_stackprot(cpu_env, ret);
708     }
709     return ret;
710 }
711 
712 #ifndef CONFIG_USER_ONLY
713 static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
714 {
715     int addr_size = dc->cfg->addr_size;
716     TCGv ret = tcg_temp_new();
717 
718     if (addr_size == 32 || ra == 0) {
719         if (rb) {
720             tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
721         } else {
722             tcg_gen_movi_tl(ret, 0);
723         }
724     } else {
725         if (rb) {
726             tcg_gen_concat_i32_i64(ret, cpu_R[rb], cpu_R[ra]);
727         } else {
728             tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
729             tcg_gen_shli_tl(ret, ret, 32);
730         }
731         if (addr_size < 64) {
732             /* Mask off out of range bits.  */
733             tcg_gen_andi_i64(ret, ret, MAKE_64BIT_MASK(0, addr_size));
734         }
735     }
736     return ret;
737 }
738 #endif
739 
740 static void record_unaligned_ess(DisasContext *dc, int rd,
741                                  MemOp size, bool store)
742 {
743     uint32_t iflags = tcg_get_insn_start_param(dc->insn_start, 1);
744 
745     iflags |= ESR_ESS_FLAG;
746     iflags |= rd << 5;
747     iflags |= store * ESR_S;
748     iflags |= (size == MO_32) * ESR_W;
749 
750     tcg_set_insn_start_param(dc->insn_start, 1, iflags);
751 }
752 
753 static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
754                     int mem_index, bool rev)
755 {
756     MemOp size = mop & MO_SIZE;
757 
758     /*
759      * When doing reverse accesses we need to do two things.
760      *
761      * 1. Reverse the address wrt endianness.
762      * 2. Byteswap the data lanes on the way back into the CPU core.
763      */
764     if (rev) {
765         if (size > MO_8) {
766             mop ^= MO_BSWAP;
767         }
768         if (size < MO_32) {
769             tcg_gen_xori_tl(addr, addr, 3 - size);
770         }
771     }
772 
773     if (size > MO_8 &&
774         (dc->tb_flags & MSR_EE) &&
775         dc->cfg->unaligned_exceptions) {
776         record_unaligned_ess(dc, rd, size, false);
777         mop |= MO_ALIGN;
778     }
779 
780     tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
781 
782     tcg_temp_free(addr);
783     return true;
784 }
785 
786 static bool trans_lbu(DisasContext *dc, arg_typea *arg)
787 {
788     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
789     return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
790 }
791 
792 static bool trans_lbur(DisasContext *dc, arg_typea *arg)
793 {
794     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
795     return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
796 }
797 
798 static bool trans_lbuea(DisasContext *dc, arg_typea *arg)
799 {
800     if (trap_userspace(dc, true)) {
801         return true;
802     }
803 #ifdef CONFIG_USER_ONLY
804     return true;
805 #else
806     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
807     return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
808 #endif
809 }
810 
811 static bool trans_lbui(DisasContext *dc, arg_typeb *arg)
812 {
813     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
814     return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
815 }
816 
817 static bool trans_lhu(DisasContext *dc, arg_typea *arg)
818 {
819     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
820     return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
821 }
822 
823 static bool trans_lhur(DisasContext *dc, arg_typea *arg)
824 {
825     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
826     return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
827 }
828 
829 static bool trans_lhuea(DisasContext *dc, arg_typea *arg)
830 {
831     if (trap_userspace(dc, true)) {
832         return true;
833     }
834 #ifdef CONFIG_USER_ONLY
835     return true;
836 #else
837     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
838     return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
839 #endif
840 }
841 
842 static bool trans_lhui(DisasContext *dc, arg_typeb *arg)
843 {
844     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
845     return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
846 }
847 
848 static bool trans_lw(DisasContext *dc, arg_typea *arg)
849 {
850     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
851     return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
852 }
853 
854 static bool trans_lwr(DisasContext *dc, arg_typea *arg)
855 {
856     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
857     return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
858 }
859 
860 static bool trans_lwea(DisasContext *dc, arg_typea *arg)
861 {
862     if (trap_userspace(dc, true)) {
863         return true;
864     }
865 #ifdef CONFIG_USER_ONLY
866     return true;
867 #else
868     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
869     return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
870 #endif
871 }
872 
873 static bool trans_lwi(DisasContext *dc, arg_typeb *arg)
874 {
875     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
876     return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
877 }
878 
879 static bool trans_lwx(DisasContext *dc, arg_typea *arg)
880 {
881     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
882 
883     /* lwx does not throw unaligned access errors, so force alignment */
884     tcg_gen_andi_tl(addr, addr, ~3);
885 
886     tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
887     tcg_gen_mov_tl(cpu_res_addr, addr);
888     tcg_temp_free(addr);
889 
890     if (arg->rd) {
891         tcg_gen_mov_i32(cpu_R[arg->rd], cpu_res_val);
892     }
893 
894     /* No support for AXI exclusive so always clear C */
895     tcg_gen_movi_i32(cpu_msr_c, 0);
896     return true;
897 }
898 
899 static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
900                      int mem_index, bool rev)
901 {
902     MemOp size = mop & MO_SIZE;
903 
904     /*
905      * When doing reverse accesses we need to do two things.
906      *
907      * 1. Reverse the address wrt endianness.
908      * 2. Byteswap the data lanes on the way back into the CPU core.
909      */
910     if (rev) {
911         if (size > MO_8) {
912             mop ^= MO_BSWAP;
913         }
914         if (size < MO_32) {
915             tcg_gen_xori_tl(addr, addr, 3 - size);
916         }
917     }
918 
919     if (size > MO_8 &&
920         (dc->tb_flags & MSR_EE) &&
921         dc->cfg->unaligned_exceptions) {
922         record_unaligned_ess(dc, rd, size, true);
923         mop |= MO_ALIGN;
924     }
925 
926     tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
927 
928     tcg_temp_free(addr);
929     return true;
930 }
931 
932 static bool trans_sb(DisasContext *dc, arg_typea *arg)
933 {
934     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
935     return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
936 }
937 
938 static bool trans_sbr(DisasContext *dc, arg_typea *arg)
939 {
940     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
941     return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
942 }
943 
944 static bool trans_sbea(DisasContext *dc, arg_typea *arg)
945 {
946     if (trap_userspace(dc, true)) {
947         return true;
948     }
949 #ifdef CONFIG_USER_ONLY
950     return true;
951 #else
952     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
953     return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
954 #endif
955 }
956 
957 static bool trans_sbi(DisasContext *dc, arg_typeb *arg)
958 {
959     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
960     return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
961 }
962 
963 static bool trans_sh(DisasContext *dc, arg_typea *arg)
964 {
965     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
966     return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
967 }
968 
969 static bool trans_shr(DisasContext *dc, arg_typea *arg)
970 {
971     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
972     return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
973 }
974 
975 static bool trans_shea(DisasContext *dc, arg_typea *arg)
976 {
977     if (trap_userspace(dc, true)) {
978         return true;
979     }
980 #ifdef CONFIG_USER_ONLY
981     return true;
982 #else
983     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
984     return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
985 #endif
986 }
987 
988 static bool trans_shi(DisasContext *dc, arg_typeb *arg)
989 {
990     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
991     return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
992 }
993 
994 static bool trans_sw(DisasContext *dc, arg_typea *arg)
995 {
996     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
997     return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
998 }
999 
1000 static bool trans_swr(DisasContext *dc, arg_typea *arg)
1001 {
1002     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
1003     return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
1004 }
1005 
1006 static bool trans_swea(DisasContext *dc, arg_typea *arg)
1007 {
1008     if (trap_userspace(dc, true)) {
1009         return true;
1010     }
1011 #ifdef CONFIG_USER_ONLY
1012     return true;
1013 #else
1014     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
1015     return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
1016 #endif
1017 }
1018 
1019 static bool trans_swi(DisasContext *dc, arg_typeb *arg)
1020 {
1021     TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
1022     return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
1023 }
1024 
1025 static bool trans_swx(DisasContext *dc, arg_typea *arg)
1026 {
1027     TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
1028     TCGLabel *swx_done = gen_new_label();
1029     TCGLabel *swx_fail = gen_new_label();
1030     TCGv_i32 tval;
1031 
1032     /* swx does not throw unaligned access errors, so force alignment */
1033     tcg_gen_andi_tl(addr, addr, ~3);
1034 
1035     /*
1036      * Compare the address vs the one we used during lwx.
1037      * On mismatch, the operation fails.  On match, addr dies at the
1038      * branch, but we know we can use the equal version in the global.
1039      * In either case, addr is no longer needed.
1040      */
1041     tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_fail);
1042     tcg_temp_free(addr);
1043 
1044     /*
1045      * Compare the value loaded during lwx with current contents of
1046      * the reserved location.
1047      */
1048     tval = tcg_temp_new_i32();
1049 
1050     tcg_gen_atomic_cmpxchg_i32(tval, cpu_res_addr, cpu_res_val,
1051                                reg_for_write(dc, arg->rd),
1052                                dc->mem_index, MO_TEUL);
1053 
1054     tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail);
1055     tcg_temp_free_i32(tval);
1056 
1057     /* Success */
1058     tcg_gen_movi_i32(cpu_msr_c, 0);
1059     tcg_gen_br(swx_done);
1060 
1061     /* Failure */
1062     gen_set_label(swx_fail);
1063     tcg_gen_movi_i32(cpu_msr_c, 1);
1064 
1065     gen_set_label(swx_done);
1066 
1067     /*
1068      * Prevent the saved address from working again without another ldx.
1069      * Akin to the pseudocode setting reservation = 0.
1070      */
1071     tcg_gen_movi_tl(cpu_res_addr, -1);
1072     return true;
1073 }
1074 
1075 static void setup_dslot(DisasContext *dc, bool type_b)
1076 {
1077     dc->tb_flags_to_set |= D_FLAG;
1078     if (type_b && (dc->tb_flags & IMM_FLAG)) {
1079         dc->tb_flags_to_set |= BIMM_FLAG;
1080     }
1081 }
1082 
1083 static bool do_branch(DisasContext *dc, int dest_rb, int dest_imm,
1084                       bool delay, bool abs, int link)
1085 {
1086     uint32_t add_pc;
1087 
1088     if (invalid_delay_slot(dc, "branch")) {
1089         return true;
1090     }
1091     if (delay) {
1092         setup_dslot(dc, dest_rb < 0);
1093     }
1094 
1095     if (link) {
1096         tcg_gen_movi_i32(cpu_R[link], dc->base.pc_next);
1097     }
1098 
1099     /* Store the branch taken destination into btarget.  */
1100     add_pc = abs ? 0 : dc->base.pc_next;
1101     if (dest_rb > 0) {
1102         dc->jmp_dest = -1;
1103         tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], add_pc);
1104     } else {
1105         dc->jmp_dest = add_pc + dest_imm;
1106         tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
1107     }
1108     dc->jmp_cond = TCG_COND_ALWAYS;
1109     return true;
1110 }
1111 
1112 #define DO_BR(NAME, NAMEI, DELAY, ABS, LINK)                               \
1113     static bool trans_##NAME(DisasContext *dc, arg_typea_br *arg)          \
1114     { return do_branch(dc, arg->rb, 0, DELAY, ABS, LINK ? arg->rd : 0); }  \
1115     static bool trans_##NAMEI(DisasContext *dc, arg_typeb_br *arg)         \
1116     { return do_branch(dc, -1, arg->imm, DELAY, ABS, LINK ? arg->rd : 0); }
1117 
1118 DO_BR(br, bri, false, false, false)
1119 DO_BR(bra, brai, false, true, false)
1120 DO_BR(brd, brid, true, false, false)
1121 DO_BR(brad, braid, true, true, false)
1122 DO_BR(brld, brlid, true, false, true)
1123 DO_BR(brald, bralid, true, true, true)
1124 
1125 static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
1126                    TCGCond cond, int ra, bool delay)
1127 {
1128     TCGv_i32 zero, next;
1129 
1130     if (invalid_delay_slot(dc, "bcc")) {
1131         return true;
1132     }
1133     if (delay) {
1134         setup_dslot(dc, dest_rb < 0);
1135     }
1136 
1137     dc->jmp_cond = cond;
1138 
1139     /* Cache the condition register in cpu_bvalue across any delay slot.  */
1140     tcg_gen_mov_i32(cpu_bvalue, reg_for_read(dc, ra));
1141 
1142     /* Store the branch taken destination into btarget.  */
1143     if (dest_rb > 0) {
1144         dc->jmp_dest = -1;
1145         tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], dc->base.pc_next);
1146     } else {
1147         dc->jmp_dest = dc->base.pc_next + dest_imm;
1148         tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
1149     }
1150 
1151     /* Compute the final destination into btarget.  */
1152     zero = tcg_const_i32(0);
1153     next = tcg_const_i32(dc->base.pc_next + (delay + 1) * 4);
1154     tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
1155                         reg_for_read(dc, ra), zero,
1156                         cpu_btarget, next);
1157     tcg_temp_free_i32(zero);
1158     tcg_temp_free_i32(next);
1159 
1160     return true;
1161 }
1162 
1163 #define DO_BCC(NAME, COND)                                              \
1164     static bool trans_##NAME(DisasContext *dc, arg_typea_bc *arg)       \
1165     { return do_bcc(dc, arg->rb, 0, COND, arg->ra, false); }            \
1166     static bool trans_##NAME##d(DisasContext *dc, arg_typea_bc *arg)    \
1167     { return do_bcc(dc, arg->rb, 0, COND, arg->ra, true); }             \
1168     static bool trans_##NAME##i(DisasContext *dc, arg_typeb_bc *arg)    \
1169     { return do_bcc(dc, -1, arg->imm, COND, arg->ra, false); }          \
1170     static bool trans_##NAME##id(DisasContext *dc, arg_typeb_bc *arg)   \
1171     { return do_bcc(dc, -1, arg->imm, COND, arg->ra, true); }
1172 
1173 DO_BCC(beq, TCG_COND_EQ)
1174 DO_BCC(bge, TCG_COND_GE)
1175 DO_BCC(bgt, TCG_COND_GT)
1176 DO_BCC(ble, TCG_COND_LE)
1177 DO_BCC(blt, TCG_COND_LT)
1178 DO_BCC(bne, TCG_COND_NE)
1179 
1180 static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
1181 {
1182     if (trap_userspace(dc, true)) {
1183         return true;
1184     }
1185     if (invalid_delay_slot(dc, "brk")) {
1186         return true;
1187     }
1188 
1189     tcg_gen_mov_i32(cpu_pc, reg_for_read(dc, arg->rb));
1190     if (arg->rd) {
1191         tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
1192     }
1193     tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_BIP);
1194     tcg_gen_movi_tl(cpu_res_addr, -1);
1195 
1196     dc->base.is_jmp = DISAS_EXIT;
1197     return true;
1198 }
1199 
1200 static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
1201 {
1202     uint32_t imm = arg->imm;
1203 
1204     if (trap_userspace(dc, imm != 0x8 && imm != 0x18)) {
1205         return true;
1206     }
1207     if (invalid_delay_slot(dc, "brki")) {
1208         return true;
1209     }
1210 
1211     tcg_gen_movi_i32(cpu_pc, imm);
1212     if (arg->rd) {
1213         tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
1214     }
1215     tcg_gen_movi_tl(cpu_res_addr, -1);
1216 
1217 #ifdef CONFIG_USER_ONLY
1218     switch (imm) {
1219     case 0x8:  /* syscall trap */
1220         gen_raise_exception_sync(dc, EXCP_SYSCALL);
1221         break;
1222     case 0x18: /* debug trap */
1223         gen_raise_exception_sync(dc, EXCP_DEBUG);
1224         break;
1225     default:   /* eliminated with trap_userspace check */
1226         g_assert_not_reached();
1227     }
1228 #else
1229     uint32_t msr_to_set = 0;
1230 
1231     if (imm != 0x18) {
1232         msr_to_set |= MSR_BIP;
1233     }
1234     if (imm == 0x8 || imm == 0x18) {
1235         /* MSR_UM and MSR_VM are in tb_flags, so we know their value. */
1236         msr_to_set |= (dc->tb_flags & (MSR_UM | MSR_VM)) << 1;
1237         tcg_gen_andi_i32(cpu_msr, cpu_msr,
1238                          ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM));
1239     }
1240     tcg_gen_ori_i32(cpu_msr, cpu_msr, msr_to_set);
1241     dc->base.is_jmp = DISAS_EXIT;
1242 #endif
1243 
1244     return true;
1245 }
1246 
1247 static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
1248 {
1249     int mbar_imm = arg->imm;
1250 
1251     /* Note that mbar is a specialized branch instruction. */
1252     if (invalid_delay_slot(dc, "mbar")) {
1253         return true;
1254     }
1255 
1256     /* Data access memory barrier.  */
1257     if ((mbar_imm & 2) == 0) {
1258         tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1259     }
1260 
1261     /* Sleep. */
1262     if (mbar_imm & 16) {
1263         TCGv_i32 tmp_1;
1264 
1265         if (trap_userspace(dc, true)) {
1266             /* Sleep is a privileged instruction.  */
1267             return true;
1268         }
1269 
1270         t_sync_flags(dc);
1271 
1272         tmp_1 = tcg_const_i32(1);
1273         tcg_gen_st_i32(tmp_1, cpu_env,
1274                        -offsetof(MicroBlazeCPU, env)
1275                        +offsetof(CPUState, halted));
1276         tcg_temp_free_i32(tmp_1);
1277 
1278         tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
1279 
1280         gen_raise_exception(dc, EXCP_HLT);
1281     }
1282 
1283     /*
1284      * If !(mbar_imm & 1), this is an instruction access memory barrier
1285      * and we need to end the TB so that we recognize self-modified
1286      * code immediately.
1287      *
1288      * However, there are some data mbars that need the TB break
1289      * (and return to main loop) to recognize interrupts right away.
1290      * E.g. recognizing a change to an interrupt controller register.
1291      *
1292      * Therefore, choose to end the TB always.
1293      */
1294     dc->base.is_jmp = DISAS_EXIT_NEXT;
1295     return true;
1296 }
1297 
1298 static bool do_rts(DisasContext *dc, arg_typeb_bc *arg, int to_set)
1299 {
1300     if (trap_userspace(dc, to_set)) {
1301         return true;
1302     }
1303     if (invalid_delay_slot(dc, "rts")) {
1304         return true;
1305     }
1306 
1307     dc->tb_flags_to_set |= to_set;
1308     setup_dslot(dc, true);
1309 
1310     dc->jmp_cond = TCG_COND_ALWAYS;
1311     dc->jmp_dest = -1;
1312     tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, arg->ra), arg->imm);
1313     return true;
1314 }
1315 
1316 #define DO_RTS(NAME, IFLAG) \
1317     static bool trans_##NAME(DisasContext *dc, arg_typeb_bc *arg) \
1318     { return do_rts(dc, arg, IFLAG); }
1319 
1320 DO_RTS(rtbd, DRTB_FLAG)
1321 DO_RTS(rtid, DRTI_FLAG)
1322 DO_RTS(rted, DRTE_FLAG)
1323 DO_RTS(rtsd, 0)
1324 
1325 static bool trans_zero(DisasContext *dc, arg_zero *arg)
1326 {
1327     /* If opcode_0_illegal, trap.  */
1328     if (dc->cfg->opcode_0_illegal) {
1329         trap_illegal(dc, true);
1330         return true;
1331     }
1332     /*
1333      * Otherwise, this is "add r0, r0, r0".
1334      * Continue to trans_add so that MSR[C] gets cleared.
1335      */
1336     return false;
1337 }
1338 
1339 static void msr_read(DisasContext *dc, TCGv_i32 d)
1340 {
1341     TCGv_i32 t;
1342 
1343     /* Replicate the cpu_msr_c boolean into the proper bit and the copy. */
1344     t = tcg_temp_new_i32();
1345     tcg_gen_muli_i32(t, cpu_msr_c, MSR_C | MSR_CC);
1346     tcg_gen_or_i32(d, cpu_msr, t);
1347     tcg_temp_free_i32(t);
1348 }
1349 
1350 static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
1351 {
1352     uint32_t imm = arg->imm;
1353 
1354     if (trap_userspace(dc, imm != MSR_C)) {
1355         return true;
1356     }
1357 
1358     if (arg->rd) {
1359         msr_read(dc, cpu_R[arg->rd]);
1360     }
1361 
1362     /*
1363      * Handle the carry bit separately.
1364      * This is the only bit that userspace can modify.
1365      */
1366     if (imm & MSR_C) {
1367         tcg_gen_movi_i32(cpu_msr_c, set);
1368     }
1369 
1370     /*
1371      * MSR_C and MSR_CC set above.
1372      * MSR_PVR is not writable, and is always clear.
1373      */
1374     imm &= ~(MSR_C | MSR_CC | MSR_PVR);
1375 
1376     if (imm != 0) {
1377         if (set) {
1378             tcg_gen_ori_i32(cpu_msr, cpu_msr, imm);
1379         } else {
1380             tcg_gen_andi_i32(cpu_msr, cpu_msr, ~imm);
1381         }
1382         dc->base.is_jmp = DISAS_EXIT_NEXT;
1383     }
1384     return true;
1385 }
1386 
1387 static bool trans_msrclr(DisasContext *dc, arg_type_msr *arg)
1388 {
1389     return do_msrclrset(dc, arg, false);
1390 }
1391 
1392 static bool trans_msrset(DisasContext *dc, arg_type_msr *arg)
1393 {
1394     return do_msrclrset(dc, arg, true);
1395 }
1396 
1397 static bool trans_mts(DisasContext *dc, arg_mts *arg)
1398 {
1399     if (trap_userspace(dc, true)) {
1400         return true;
1401     }
1402 
1403 #ifdef CONFIG_USER_ONLY
1404     g_assert_not_reached();
1405 #else
1406     if (arg->e && arg->rs != 0x1003) {
1407         qemu_log_mask(LOG_GUEST_ERROR,
1408                       "Invalid extended mts reg 0x%x\n", arg->rs);
1409         return true;
1410     }
1411 
1412     TCGv_i32 src = reg_for_read(dc, arg->ra);
1413     switch (arg->rs) {
1414     case SR_MSR:
1415         /* Install MSR_C.  */
1416         tcg_gen_extract_i32(cpu_msr_c, src, 2, 1);
1417         /*
1418          * Clear MSR_C and MSR_CC;
1419          * MSR_PVR is not writable, and is always clear.
1420          */
1421         tcg_gen_andi_i32(cpu_msr, src, ~(MSR_C | MSR_CC | MSR_PVR));
1422         break;
1423     case SR_FSR:
1424         tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, fsr));
1425         break;
1426     case 0x800:
1427         tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, slr));
1428         break;
1429     case 0x802:
1430         tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, shr));
1431         break;
1432 
1433     case 0x1000: /* PID */
1434     case 0x1001: /* ZPR */
1435     case 0x1002: /* TLBX */
1436     case 0x1003: /* TLBLO */
1437     case 0x1004: /* TLBHI */
1438     case 0x1005: /* TLBSX */
1439         {
1440             TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
1441             TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
1442 
1443             gen_helper_mmu_write(cpu_env, tmp_ext, tmp_reg, src);
1444             tcg_temp_free_i32(tmp_reg);
1445             tcg_temp_free_i32(tmp_ext);
1446         }
1447         break;
1448 
1449     default:
1450         qemu_log_mask(LOG_GUEST_ERROR, "Invalid mts reg 0x%x\n", arg->rs);
1451         return true;
1452     }
1453     dc->base.is_jmp = DISAS_EXIT_NEXT;
1454     return true;
1455 #endif
1456 }
1457 
1458 static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
1459 {
1460     TCGv_i32 dest = reg_for_write(dc, arg->rd);
1461 
1462     if (arg->e) {
1463         switch (arg->rs) {
1464         case SR_EAR:
1465             {
1466                 TCGv_i64 t64 = tcg_temp_new_i64();
1467                 tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
1468                 tcg_gen_extrh_i64_i32(dest, t64);
1469                 tcg_temp_free_i64(t64);
1470             }
1471             return true;
1472 #ifndef CONFIG_USER_ONLY
1473         case 0x1003: /* TLBLO */
1474             /* Handled below. */
1475             break;
1476 #endif
1477         case 0x2006 ... 0x2009:
1478             /* High bits of PVR6-9 not implemented. */
1479             tcg_gen_movi_i32(dest, 0);
1480             return true;
1481         default:
1482             qemu_log_mask(LOG_GUEST_ERROR,
1483                           "Invalid extended mfs reg 0x%x\n", arg->rs);
1484             return true;
1485         }
1486     }
1487 
1488     switch (arg->rs) {
1489     case SR_PC:
1490         tcg_gen_movi_i32(dest, dc->base.pc_next);
1491         break;
1492     case SR_MSR:
1493         msr_read(dc, dest);
1494         break;
1495     case SR_EAR:
1496         {
1497             TCGv_i64 t64 = tcg_temp_new_i64();
1498             tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
1499             tcg_gen_extrl_i64_i32(dest, t64);
1500             tcg_temp_free_i64(t64);
1501         }
1502         break;
1503     case SR_ESR:
1504         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, esr));
1505         break;
1506     case SR_FSR:
1507         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, fsr));
1508         break;
1509     case SR_BTR:
1510         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, btr));
1511         break;
1512     case SR_EDR:
1513         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, edr));
1514         break;
1515     case 0x800:
1516         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, slr));
1517         break;
1518     case 0x802:
1519         tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, shr));
1520         break;
1521 
1522 #ifndef CONFIG_USER_ONLY
1523     case 0x1000: /* PID */
1524     case 0x1001: /* ZPR */
1525     case 0x1002: /* TLBX */
1526     case 0x1003: /* TLBLO */
1527     case 0x1004: /* TLBHI */
1528     case 0x1005: /* TLBSX */
1529         {
1530             TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
1531             TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
1532 
1533             gen_helper_mmu_read(dest, cpu_env, tmp_ext, tmp_reg);
1534             tcg_temp_free_i32(tmp_reg);
1535             tcg_temp_free_i32(tmp_ext);
1536         }
1537         break;
1538 #endif
1539 
1540     case 0x2000 ... 0x200c:
1541         tcg_gen_ld_i32(dest, cpu_env,
1542                        offsetof(MicroBlazeCPU, cfg.pvr_regs[arg->rs - 0x2000])
1543                        - offsetof(MicroBlazeCPU, env));
1544         break;
1545     default:
1546         qemu_log_mask(LOG_GUEST_ERROR, "Invalid mfs reg 0x%x\n", arg->rs);
1547         break;
1548     }
1549     return true;
1550 }
1551 
1552 static void do_rti(DisasContext *dc)
1553 {
1554     TCGv_i32 tmp = tcg_temp_new_i32();
1555 
1556     tcg_gen_shri_i32(tmp, cpu_msr, 1);
1557     tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_IE);
1558     tcg_gen_andi_i32(tmp, tmp, MSR_VM | MSR_UM);
1559     tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM));
1560     tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
1561 
1562     tcg_temp_free_i32(tmp);
1563 }
1564 
1565 static void do_rtb(DisasContext *dc)
1566 {
1567     TCGv_i32 tmp = tcg_temp_new_i32();
1568 
1569     tcg_gen_shri_i32(tmp, cpu_msr, 1);
1570     tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_BIP));
1571     tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
1572     tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
1573 
1574     tcg_temp_free_i32(tmp);
1575 }
1576 
1577 static void do_rte(DisasContext *dc)
1578 {
1579     TCGv_i32 tmp = tcg_temp_new_i32();
1580 
1581     tcg_gen_shri_i32(tmp, cpu_msr, 1);
1582     tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_EE);
1583     tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
1584     tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_EIP));
1585     tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
1586 
1587     tcg_temp_free_i32(tmp);
1588 }
1589 
1590 /* Insns connected to FSL or AXI stream attached devices.  */
1591 static bool do_get(DisasContext *dc, int rd, int rb, int imm, int ctrl)
1592 {
1593     TCGv_i32 t_id, t_ctrl;
1594 
1595     if (trap_userspace(dc, true)) {
1596         return true;
1597     }
1598 
1599     t_id = tcg_temp_new_i32();
1600     if (rb) {
1601         tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
1602     } else {
1603         tcg_gen_movi_i32(t_id, imm);
1604     }
1605 
1606     t_ctrl = tcg_const_i32(ctrl);
1607     gen_helper_get(reg_for_write(dc, rd), t_id, t_ctrl);
1608     tcg_temp_free_i32(t_id);
1609     tcg_temp_free_i32(t_ctrl);
1610     return true;
1611 }
1612 
1613 static bool trans_get(DisasContext *dc, arg_get *arg)
1614 {
1615     return do_get(dc, arg->rd, 0, arg->imm, arg->ctrl);
1616 }
1617 
1618 static bool trans_getd(DisasContext *dc, arg_getd *arg)
1619 {
1620     return do_get(dc, arg->rd, arg->rb, 0, arg->ctrl);
1621 }
1622 
1623 static bool do_put(DisasContext *dc, int ra, int rb, int imm, int ctrl)
1624 {
1625     TCGv_i32 t_id, t_ctrl;
1626 
1627     if (trap_userspace(dc, true)) {
1628         return true;
1629     }
1630 
1631     t_id = tcg_temp_new_i32();
1632     if (rb) {
1633         tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
1634     } else {
1635         tcg_gen_movi_i32(t_id, imm);
1636     }
1637 
1638     t_ctrl = tcg_const_i32(ctrl);
1639     gen_helper_put(t_id, t_ctrl, reg_for_read(dc, ra));
1640     tcg_temp_free_i32(t_id);
1641     tcg_temp_free_i32(t_ctrl);
1642     return true;
1643 }
1644 
1645 static bool trans_put(DisasContext *dc, arg_put *arg)
1646 {
1647     return do_put(dc, arg->ra, 0, arg->imm, arg->ctrl);
1648 }
1649 
1650 static bool trans_putd(DisasContext *dc, arg_putd *arg)
1651 {
1652     return do_put(dc, arg->ra, arg->rb, 0, arg->ctrl);
1653 }
1654 
1655 static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
1656 {
1657     DisasContext *dc = container_of(dcb, DisasContext, base);
1658     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
1659     int bound;
1660 
1661     dc->cfg = &cpu->cfg;
1662     dc->tb_flags = dc->base.tb->flags;
1663     dc->ext_imm = dc->base.tb->cs_base;
1664     dc->r0 = NULL;
1665     dc->r0_set = false;
1666     dc->mem_index = cpu_mmu_index(&cpu->env, false);
1667     dc->jmp_cond = dc->tb_flags & D_FLAG ? TCG_COND_ALWAYS : TCG_COND_NEVER;
1668     dc->jmp_dest = -1;
1669 
1670     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
1671     dc->base.max_insns = MIN(dc->base.max_insns, bound);
1672 }
1673 
1674 static void mb_tr_tb_start(DisasContextBase *dcb, CPUState *cs)
1675 {
1676 }
1677 
1678 static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
1679 {
1680     DisasContext *dc = container_of(dcb, DisasContext, base);
1681 
1682     tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
1683     dc->insn_start = tcg_last_op();
1684 }
1685 
1686 static bool mb_tr_breakpoint_check(DisasContextBase *dcb, CPUState *cs,
1687                                    const CPUBreakpoint *bp)
1688 {
1689     DisasContext *dc = container_of(dcb, DisasContext, base);
1690 
1691     gen_raise_exception_sync(dc, EXCP_DEBUG);
1692 
1693     /*
1694      * The address covered by the breakpoint must be included in
1695      * [tb->pc, tb->pc + tb->size) in order to for it to be
1696      * properly cleared -- thus we increment the PC here so that
1697      * the logic setting tb->size below does the right thing.
1698      */
1699     dc->base.pc_next += 4;
1700     return true;
1701 }
1702 
1703 static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
1704 {
1705     DisasContext *dc = container_of(dcb, DisasContext, base);
1706     CPUMBState *env = cs->env_ptr;
1707     uint32_t ir;
1708 
1709     /* TODO: This should raise an exception, not terminate qemu. */
1710     if (dc->base.pc_next & 3) {
1711         cpu_abort(cs, "Microblaze: unaligned PC=%x\n",
1712                   (uint32_t)dc->base.pc_next);
1713     }
1714 
1715     dc->tb_flags_to_set = 0;
1716 
1717     ir = cpu_ldl_code(env, dc->base.pc_next);
1718     if (!decode(dc, ir)) {
1719         trap_illegal(dc, true);
1720     }
1721 
1722     if (dc->r0) {
1723         tcg_temp_free_i32(dc->r0);
1724         dc->r0 = NULL;
1725         dc->r0_set = false;
1726     }
1727 
1728     /* Discard the imm global when its contents cannot be used. */
1729     if ((dc->tb_flags & ~dc->tb_flags_to_set) & IMM_FLAG) {
1730         tcg_gen_discard_i32(cpu_imm);
1731     }
1732 
1733     dc->tb_flags &= ~(IMM_FLAG | BIMM_FLAG | D_FLAG);
1734     dc->tb_flags |= dc->tb_flags_to_set;
1735     dc->base.pc_next += 4;
1736 
1737     if (dc->jmp_cond != TCG_COND_NEVER && !(dc->tb_flags & D_FLAG)) {
1738         /*
1739          * Finish any return-from branch.
1740          */
1741         uint32_t rt_ibe = dc->tb_flags & (DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
1742         if (unlikely(rt_ibe != 0)) {
1743             dc->tb_flags &= ~(DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
1744             if (rt_ibe & DRTI_FLAG) {
1745                 do_rti(dc);
1746             } else if (rt_ibe & DRTB_FLAG) {
1747                 do_rtb(dc);
1748             } else {
1749                 do_rte(dc);
1750             }
1751         }
1752 
1753         /* Complete the branch, ending the TB. */
1754         switch (dc->base.is_jmp) {
1755         case DISAS_NORETURN:
1756             /*
1757              * E.g. illegal insn in a delay slot.  We've already exited
1758              * and will handle D_FLAG in mb_cpu_do_interrupt.
1759              */
1760             break;
1761         case DISAS_NEXT:
1762             /*
1763              * Normal insn a delay slot.
1764              * However, the return-from-exception type insns should
1765              * return to the main loop, as they have adjusted MSR.
1766              */
1767             dc->base.is_jmp = (rt_ibe ? DISAS_EXIT_JUMP : DISAS_JUMP);
1768             break;
1769         case DISAS_EXIT_NEXT:
1770             /*
1771              * E.g. mts insn in a delay slot.  Continue with btarget,
1772              * but still return to the main loop.
1773              */
1774             dc->base.is_jmp = DISAS_EXIT_JUMP;
1775             break;
1776         default:
1777             g_assert_not_reached();
1778         }
1779     }
1780 }
1781 
1782 static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
1783 {
1784     DisasContext *dc = container_of(dcb, DisasContext, base);
1785 
1786     if (dc->base.is_jmp == DISAS_NORETURN) {
1787         /* We have already exited the TB. */
1788         return;
1789     }
1790 
1791     t_sync_flags(dc);
1792 
1793     switch (dc->base.is_jmp) {
1794     case DISAS_TOO_MANY:
1795         gen_goto_tb(dc, 0, dc->base.pc_next);
1796         return;
1797 
1798     case DISAS_EXIT:
1799         break;
1800     case DISAS_EXIT_NEXT:
1801         tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
1802         break;
1803     case DISAS_EXIT_JUMP:
1804         tcg_gen_mov_i32(cpu_pc, cpu_btarget);
1805         tcg_gen_discard_i32(cpu_btarget);
1806         break;
1807 
1808     case DISAS_JUMP:
1809         if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
1810             /* Direct jump. */
1811             tcg_gen_discard_i32(cpu_btarget);
1812 
1813             if (dc->jmp_cond != TCG_COND_ALWAYS) {
1814                 /* Conditional direct jump. */
1815                 TCGLabel *taken = gen_new_label();
1816                 TCGv_i32 tmp = tcg_temp_new_i32();
1817 
1818                 /*
1819                  * Copy bvalue to a temp now, so we can discard bvalue.
1820                  * This can avoid writing bvalue to memory when the
1821                  * delay slot cannot raise an exception.
1822                  */
1823                 tcg_gen_mov_i32(tmp, cpu_bvalue);
1824                 tcg_gen_discard_i32(cpu_bvalue);
1825 
1826                 tcg_gen_brcondi_i32(dc->jmp_cond, tmp, 0, taken);
1827                 gen_goto_tb(dc, 1, dc->base.pc_next);
1828                 gen_set_label(taken);
1829             }
1830             gen_goto_tb(dc, 0, dc->jmp_dest);
1831             return;
1832         }
1833 
1834         /* Indirect jump (or direct jump w/ singlestep) */
1835         tcg_gen_mov_i32(cpu_pc, cpu_btarget);
1836         tcg_gen_discard_i32(cpu_btarget);
1837 
1838         if (unlikely(cs->singlestep_enabled)) {
1839             gen_raise_exception(dc, EXCP_DEBUG);
1840         } else {
1841             tcg_gen_lookup_and_goto_ptr();
1842         }
1843         return;
1844 
1845     default:
1846         g_assert_not_reached();
1847     }
1848 
1849     /* Finish DISAS_EXIT_* */
1850     if (unlikely(cs->singlestep_enabled)) {
1851         gen_raise_exception(dc, EXCP_DEBUG);
1852     } else {
1853         tcg_gen_exit_tb(NULL, 0);
1854     }
1855 }
1856 
1857 static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
1858 {
1859     qemu_log("IN: %s\n", lookup_symbol(dcb->pc_first));
1860     log_target_disas(cs, dcb->pc_first, dcb->tb->size);
1861 }
1862 
1863 static const TranslatorOps mb_tr_ops = {
1864     .init_disas_context = mb_tr_init_disas_context,
1865     .tb_start           = mb_tr_tb_start,
1866     .insn_start         = mb_tr_insn_start,
1867     .breakpoint_check   = mb_tr_breakpoint_check,
1868     .translate_insn     = mb_tr_translate_insn,
1869     .tb_stop            = mb_tr_tb_stop,
1870     .disas_log          = mb_tr_disas_log,
1871 };
1872 
1873 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
1874 {
1875     DisasContext dc;
1876     translator_loop(&mb_tr_ops, &dc.base, cpu, tb, max_insns);
1877 }
1878 
1879 void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1880 {
1881     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
1882     CPUMBState *env = &cpu->env;
1883     uint32_t iflags;
1884     int i;
1885 
1886     qemu_fprintf(f, "pc=0x%08x msr=0x%05x mode=%s(saved=%s) eip=%d ie=%d\n",
1887                  env->pc, env->msr,
1888                  (env->msr & MSR_UM) ? "user" : "kernel",
1889                  (env->msr & MSR_UMS) ? "user" : "kernel",
1890                  (bool)(env->msr & MSR_EIP),
1891                  (bool)(env->msr & MSR_IE));
1892 
1893     iflags = env->iflags;
1894     qemu_fprintf(f, "iflags: 0x%08x", iflags);
1895     if (iflags & IMM_FLAG) {
1896         qemu_fprintf(f, " IMM(0x%08x)", env->imm);
1897     }
1898     if (iflags & BIMM_FLAG) {
1899         qemu_fprintf(f, " BIMM");
1900     }
1901     if (iflags & D_FLAG) {
1902         qemu_fprintf(f, " D(btarget=0x%08x)", env->btarget);
1903     }
1904     if (iflags & DRTI_FLAG) {
1905         qemu_fprintf(f, " DRTI");
1906     }
1907     if (iflags & DRTE_FLAG) {
1908         qemu_fprintf(f, " DRTE");
1909     }
1910     if (iflags & DRTB_FLAG) {
1911         qemu_fprintf(f, " DRTB");
1912     }
1913     if (iflags & ESR_ESS_FLAG) {
1914         qemu_fprintf(f, " ESR_ESS(0x%04x)", iflags & ESR_ESS_MASK);
1915     }
1916 
1917     qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n"
1918                  "ear=0x" TARGET_FMT_lx " slr=0x%x shr=0x%x\n",
1919                  env->esr, env->fsr, env->btr, env->edr,
1920                  env->ear, env->slr, env->shr);
1921 
1922     for (i = 0; i < 32; i++) {
1923         qemu_fprintf(f, "r%2.2d=%08x%c",
1924                      i, env->regs[i], i % 4 == 3 ? '\n' : ' ');
1925     }
1926     qemu_fprintf(f, "\n");
1927 }
1928 
1929 void mb_tcg_init(void)
1930 {
1931 #define R(X)  { &cpu_R[X], offsetof(CPUMBState, regs[X]), "r" #X }
1932 #define SP(X) { &cpu_##X, offsetof(CPUMBState, X), #X }
1933 
1934     static const struct {
1935         TCGv_i32 *var; int ofs; char name[8];
1936     } i32s[] = {
1937         /*
1938          * Note that r0 is handled specially in reg_for_read
1939          * and reg_for_write.  Nothing should touch cpu_R[0].
1940          * Leave that element NULL, which will assert quickly
1941          * inside the tcg generator functions.
1942          */
1943                R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
1944         R(8),  R(9),  R(10), R(11), R(12), R(13), R(14), R(15),
1945         R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
1946         R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
1947 
1948         SP(pc),
1949         SP(msr),
1950         SP(msr_c),
1951         SP(imm),
1952         SP(iflags),
1953         SP(bvalue),
1954         SP(btarget),
1955         SP(res_val),
1956     };
1957 
1958 #undef R
1959 #undef SP
1960 
1961     for (int i = 0; i < ARRAY_SIZE(i32s); ++i) {
1962         *i32s[i].var =
1963           tcg_global_mem_new_i32(cpu_env, i32s[i].ofs, i32s[i].name);
1964     }
1965 
1966     cpu_res_addr =
1967         tcg_global_mem_new(cpu_env, offsetof(CPUMBState, res_addr), "res_addr");
1968 }
1969 
1970 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
1971                           target_ulong *data)
1972 {
1973     env->pc = data[0];
1974     env->iflags = data[1];
1975 }
1976