xref: /qemu/target/openrisc/translate.c (revision 032de4fc38b9d1bac933c3be7f95b16c60db5cea)
1e67db06eSJia Liu /*
2e67db06eSJia Liu  * OpenRISC translation
3e67db06eSJia Liu  *
4e67db06eSJia Liu  * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
5e67db06eSJia Liu  *                         Feng Gao <gf91597@gmail.com>
6e67db06eSJia Liu  *
7e67db06eSJia Liu  * This library is free software; you can redistribute it and/or
8e67db06eSJia Liu  * modify it under the terms of the GNU Lesser General Public
9e67db06eSJia Liu  * License as published by the Free Software Foundation; either
10e67db06eSJia Liu  * version 2 of the License, or (at your option) any later version.
11e67db06eSJia Liu  *
12e67db06eSJia Liu  * This library is distributed in the hope that it will be useful,
13e67db06eSJia Liu  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14e67db06eSJia Liu  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15e67db06eSJia Liu  * Lesser General Public License for more details.
16e67db06eSJia Liu  *
17e67db06eSJia Liu  * You should have received a copy of the GNU Lesser General Public
18e67db06eSJia Liu  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19e67db06eSJia Liu  */
20e67db06eSJia Liu 
21ed2decc6SPeter Maydell #include "qemu/osdep.h"
22e67db06eSJia Liu #include "cpu.h"
23022c62cbSPaolo Bonzini #include "exec/exec-all.h"
2476cad711SPaolo Bonzini #include "disas/disas.h"
25e67db06eSJia Liu #include "tcg-op.h"
26e67db06eSJia Liu #include "qemu-common.h"
271de7afc9SPaolo Bonzini #include "qemu/log.h"
281de7afc9SPaolo Bonzini #include "qemu/bitops.h"
29f08b6170SPaolo Bonzini #include "exec/cpu_ldst.h"
3077fc6f5eSLluís Vilanova #include "exec/translator.h"
31bbe418f2SJia Liu 
322ef6175aSRichard Henderson #include "exec/helper-proto.h"
332ef6175aSRichard Henderson #include "exec/helper-gen.h"
347de9729fSRichard Henderson #include "exec/gen-icount.h"
35e67db06eSJia Liu 
36a7e30d84SLluís Vilanova #include "trace-tcg.h"
37508127e2SPaolo Bonzini #include "exec/log.h"
38a7e30d84SLluís Vilanova 
39111ece51SRichard Henderson #define LOG_DIS(str, ...) \
401ffa4bceSEmilio G. Cota     qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->base.pc_next,    \
411ffa4bceSEmilio G. Cota                   ## __VA_ARGS__)
42e67db06eSJia Liu 
4377fc6f5eSLluís Vilanova /* is_jmp field values */
4477fc6f5eSLluís Vilanova #define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
4577fc6f5eSLluís Vilanova #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
4677fc6f5eSLluís Vilanova #define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
4777fc6f5eSLluís Vilanova 
48bbe418f2SJia Liu typedef struct DisasContext {
491ffa4bceSEmilio G. Cota     DisasContextBase base;
50bbe418f2SJia Liu     uint32_t mem_idx;
51a01deb36SRichard Henderson     uint32_t tb_flags;
52bbe418f2SJia Liu     uint32_t delayed_branch;
53bbe418f2SJia Liu } DisasContext;
54bbe418f2SJia Liu 
557de9729fSRichard Henderson /* Include the auto-generated decoder.  */
567de9729fSRichard Henderson #include "decode.inc.c"
577de9729fSRichard Henderson 
58bbe418f2SJia Liu static TCGv cpu_sr;
59bbe418f2SJia Liu static TCGv cpu_R[32];
606597c28dSRichard Henderson static TCGv cpu_R0;
61bbe418f2SJia Liu static TCGv cpu_pc;
62bbe418f2SJia Liu static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
63bbe418f2SJia Liu static TCGv cpu_ppc;
6484775c43SRichard Henderson static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
6597458071SRichard Henderson static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
6697458071SRichard Henderson static TCGv cpu_sr_ov;          /* signed overflow */
67930c3d00SRichard Henderson static TCGv cpu_lock_addr;
68930c3d00SRichard Henderson static TCGv cpu_lock_value;
69bbe418f2SJia Liu static TCGv_i32 fpcsr;
706f7332baSRichard Henderson static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
71a01deb36SRichard Henderson static TCGv_i32 cpu_dflag;
72bbe418f2SJia Liu 
73e67db06eSJia Liu void openrisc_translate_init(void)
74e67db06eSJia Liu {
75bbe418f2SJia Liu     static const char * const regnames[] = {
76bbe418f2SJia Liu         "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77bbe418f2SJia Liu         "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
78bbe418f2SJia Liu         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
79bbe418f2SJia Liu         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
80bbe418f2SJia Liu     };
81bbe418f2SJia Liu     int i;
82bbe418f2SJia Liu 
83e1ccc054SRichard Henderson     cpu_sr = tcg_global_mem_new(cpu_env,
84bbe418f2SJia Liu                                 offsetof(CPUOpenRISCState, sr), "sr");
85a01deb36SRichard Henderson     cpu_dflag = tcg_global_mem_new_i32(cpu_env,
86a01deb36SRichard Henderson                                        offsetof(CPUOpenRISCState, dflag),
87a01deb36SRichard Henderson                                        "dflag");
88e1ccc054SRichard Henderson     cpu_pc = tcg_global_mem_new(cpu_env,
89bbe418f2SJia Liu                                 offsetof(CPUOpenRISCState, pc), "pc");
90e1ccc054SRichard Henderson     cpu_ppc = tcg_global_mem_new(cpu_env,
91bbe418f2SJia Liu                                  offsetof(CPUOpenRISCState, ppc), "ppc");
92e1ccc054SRichard Henderson     jmp_pc = tcg_global_mem_new(cpu_env,
93bbe418f2SJia Liu                                 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
9484775c43SRichard Henderson     cpu_sr_f = tcg_global_mem_new(cpu_env,
9584775c43SRichard Henderson                                   offsetof(CPUOpenRISCState, sr_f), "sr_f");
9697458071SRichard Henderson     cpu_sr_cy = tcg_global_mem_new(cpu_env,
9797458071SRichard Henderson                                    offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
9897458071SRichard Henderson     cpu_sr_ov = tcg_global_mem_new(cpu_env,
9997458071SRichard Henderson                                    offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
100930c3d00SRichard Henderson     cpu_lock_addr = tcg_global_mem_new(cpu_env,
101930c3d00SRichard Henderson                                        offsetof(CPUOpenRISCState, lock_addr),
102930c3d00SRichard Henderson                                        "lock_addr");
103930c3d00SRichard Henderson     cpu_lock_value = tcg_global_mem_new(cpu_env,
104930c3d00SRichard Henderson                                         offsetof(CPUOpenRISCState, lock_value),
105930c3d00SRichard Henderson                                         "lock_value");
106e1ccc054SRichard Henderson     fpcsr = tcg_global_mem_new_i32(cpu_env,
107bbe418f2SJia Liu                                    offsetof(CPUOpenRISCState, fpcsr),
108bbe418f2SJia Liu                                    "fpcsr");
1096f7332baSRichard Henderson     cpu_mac = tcg_global_mem_new_i64(cpu_env,
1106f7332baSRichard Henderson                                      offsetof(CPUOpenRISCState, mac),
1116f7332baSRichard Henderson                                      "mac");
112bbe418f2SJia Liu     for (i = 0; i < 32; i++) {
113e1ccc054SRichard Henderson         cpu_R[i] = tcg_global_mem_new(cpu_env,
114d89e71e8SStafford Horne                                       offsetof(CPUOpenRISCState,
115d89e71e8SStafford Horne                                                shadow_gpr[0][i]),
116bbe418f2SJia Liu                                       regnames[i]);
117bbe418f2SJia Liu     }
1186597c28dSRichard Henderson     cpu_R0 = cpu_R[0];
119bbe418f2SJia Liu }
120bbe418f2SJia Liu 
121bbe418f2SJia Liu static void gen_exception(DisasContext *dc, unsigned int excp)
122bbe418f2SJia Liu {
123bbe418f2SJia Liu     TCGv_i32 tmp = tcg_const_i32(excp);
124bbe418f2SJia Liu     gen_helper_exception(cpu_env, tmp);
125bbe418f2SJia Liu     tcg_temp_free_i32(tmp);
126bbe418f2SJia Liu }
127bbe418f2SJia Liu 
128bbe418f2SJia Liu static void gen_illegal_exception(DisasContext *dc)
129bbe418f2SJia Liu {
1301ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
131bbe418f2SJia Liu     gen_exception(dc, EXCP_ILLEGAL);
1321ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
133bbe418f2SJia Liu }
134bbe418f2SJia Liu 
135bbe418f2SJia Liu /* not used yet, open it when we need or64.  */
136bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64
137bbe418f2SJia Liu static void check_ob64s(DisasContext *dc)
138bbe418f2SJia Liu {
139bbe418f2SJia Liu     if (!(dc->flags & CPUCFGR_OB64S)) {
140bbe418f2SJia Liu         gen_illegal_exception(dc);
141bbe418f2SJia Liu     }
142bbe418f2SJia Liu }
143bbe418f2SJia Liu 
144bbe418f2SJia Liu static void check_of64s(DisasContext *dc)
145bbe418f2SJia Liu {
146bbe418f2SJia Liu     if (!(dc->flags & CPUCFGR_OF64S)) {
147bbe418f2SJia Liu         gen_illegal_exception(dc);
148bbe418f2SJia Liu     }
149bbe418f2SJia Liu }
150bbe418f2SJia Liu 
151bbe418f2SJia Liu static void check_ov64s(DisasContext *dc)
152bbe418f2SJia Liu {
153bbe418f2SJia Liu     if (!(dc->flags & CPUCFGR_OV64S)) {
154bbe418f2SJia Liu         gen_illegal_exception(dc);
155bbe418f2SJia Liu     }
156bbe418f2SJia Liu }
157bbe418f2SJia Liu #endif*/
158bbe418f2SJia Liu 
1596597c28dSRichard Henderson /* We're about to write to REG.  On the off-chance that the user is
1606597c28dSRichard Henderson    writing to R0, re-instate the architectural register.  */
1616597c28dSRichard Henderson #define check_r0_write(reg)             \
1626597c28dSRichard Henderson     do {                                \
1636597c28dSRichard Henderson         if (unlikely(reg == 0)) {       \
1646597c28dSRichard Henderson             cpu_R[0] = cpu_R0;          \
1656597c28dSRichard Henderson         }                               \
1666597c28dSRichard Henderson     } while (0)
1676597c28dSRichard Henderson 
16890aa39a1SSergey Fedorov static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
16990aa39a1SSergey Fedorov {
1701ffa4bceSEmilio G. Cota     if (unlikely(dc->base.singlestep_enabled)) {
17190aa39a1SSergey Fedorov         return false;
17290aa39a1SSergey Fedorov     }
17390aa39a1SSergey Fedorov 
17490aa39a1SSergey Fedorov #ifndef CONFIG_USER_ONLY
1751ffa4bceSEmilio G. Cota     return (dc->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
17690aa39a1SSergey Fedorov #else
17790aa39a1SSergey Fedorov     return true;
17890aa39a1SSergey Fedorov #endif
17990aa39a1SSergey Fedorov }
18090aa39a1SSergey Fedorov 
181bbe418f2SJia Liu static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
182bbe418f2SJia Liu {
18390aa39a1SSergey Fedorov     if (use_goto_tb(dc, dest)) {
184bbe418f2SJia Liu         tcg_gen_movi_tl(cpu_pc, dest);
185bbe418f2SJia Liu         tcg_gen_goto_tb(n);
1861ffa4bceSEmilio G. Cota         tcg_gen_exit_tb((uintptr_t)dc->base.tb + n);
187bbe418f2SJia Liu     } else {
188bbe418f2SJia Liu         tcg_gen_movi_tl(cpu_pc, dest);
1891ffa4bceSEmilio G. Cota         if (dc->base.singlestep_enabled) {
190bbe418f2SJia Liu             gen_exception(dc, EXCP_DEBUG);
191bbe418f2SJia Liu         }
192bbe418f2SJia Liu         tcg_gen_exit_tb(0);
193bbe418f2SJia Liu     }
194bbe418f2SJia Liu }
195bbe418f2SJia Liu 
19697458071SRichard Henderson static void gen_ove_cy(DisasContext *dc)
1979ecaa27eSRichard Henderson {
1980c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
19997458071SRichard Henderson         gen_helper_ove_cy(cpu_env);
2009ecaa27eSRichard Henderson     }
2010c53d734SRichard Henderson }
2029ecaa27eSRichard Henderson 
20397458071SRichard Henderson static void gen_ove_ov(DisasContext *dc)
2049ecaa27eSRichard Henderson {
2050c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
20697458071SRichard Henderson         gen_helper_ove_ov(cpu_env);
2079ecaa27eSRichard Henderson     }
2080c53d734SRichard Henderson }
2099ecaa27eSRichard Henderson 
21097458071SRichard Henderson static void gen_ove_cyov(DisasContext *dc)
2119ecaa27eSRichard Henderson {
2120c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
21397458071SRichard Henderson         gen_helper_ove_cyov(cpu_env);
2149ecaa27eSRichard Henderson     }
2150c53d734SRichard Henderson }
2169ecaa27eSRichard Henderson 
2179ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2189ecaa27eSRichard Henderson {
2199ecaa27eSRichard Henderson     TCGv t0 = tcg_const_tl(0);
2209ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
2219ecaa27eSRichard Henderson 
22297458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
22397458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2249ecaa27eSRichard Henderson     tcg_gen_xor_tl(t0, res, srcb);
22597458071SRichard Henderson     tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2269ecaa27eSRichard Henderson     tcg_temp_free(t0);
2279ecaa27eSRichard Henderson 
2289ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
2299ecaa27eSRichard Henderson     tcg_temp_free(res);
2309ecaa27eSRichard Henderson 
23197458071SRichard Henderson     gen_ove_cyov(dc);
2329ecaa27eSRichard Henderson }
2339ecaa27eSRichard Henderson 
2349ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2359ecaa27eSRichard Henderson {
2369ecaa27eSRichard Henderson     TCGv t0 = tcg_const_tl(0);
2379ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
2389ecaa27eSRichard Henderson 
23997458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
24097458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
24197458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2429ecaa27eSRichard Henderson     tcg_gen_xor_tl(t0, res, srcb);
24397458071SRichard Henderson     tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2449ecaa27eSRichard Henderson     tcg_temp_free(t0);
2459ecaa27eSRichard Henderson 
2469ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
2479ecaa27eSRichard Henderson     tcg_temp_free(res);
2489ecaa27eSRichard Henderson 
24997458071SRichard Henderson     gen_ove_cyov(dc);
2509ecaa27eSRichard Henderson }
2519ecaa27eSRichard Henderson 
2529ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2539ecaa27eSRichard Henderson {
2549ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
2559ecaa27eSRichard Henderson 
2569ecaa27eSRichard Henderson     tcg_gen_sub_tl(res, srca, srcb);
25797458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
25897458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
25997458071SRichard Henderson     tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
26097458071SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
2619ecaa27eSRichard Henderson 
2629ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
2639ecaa27eSRichard Henderson     tcg_temp_free(res);
2649ecaa27eSRichard Henderson 
26597458071SRichard Henderson     gen_ove_cyov(dc);
2669ecaa27eSRichard Henderson }
2679ecaa27eSRichard Henderson 
2689ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2699ecaa27eSRichard Henderson {
2709ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
2719ecaa27eSRichard Henderson 
27297458071SRichard Henderson     tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
2739ecaa27eSRichard Henderson     tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
27497458071SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
2759ecaa27eSRichard Henderson     tcg_temp_free(t0);
2769ecaa27eSRichard Henderson 
27797458071SRichard Henderson     tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
27897458071SRichard Henderson     gen_ove_ov(dc);
2799ecaa27eSRichard Henderson }
2809ecaa27eSRichard Henderson 
2819ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2829ecaa27eSRichard Henderson {
28397458071SRichard Henderson     tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
28497458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
2859ecaa27eSRichard Henderson 
28697458071SRichard Henderson     gen_ove_cy(dc);
2879ecaa27eSRichard Henderson }
2889ecaa27eSRichard Henderson 
2899ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2909ecaa27eSRichard Henderson {
2919ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
2929ecaa27eSRichard Henderson 
29397458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
2949ecaa27eSRichard Henderson     /* The result of divide-by-zero is undefined.
2959ecaa27eSRichard Henderson        Supress the host-side exception by dividing by 1.  */
29697458071SRichard Henderson     tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
2979ecaa27eSRichard Henderson     tcg_gen_div_tl(dest, srca, t0);
2989ecaa27eSRichard Henderson     tcg_temp_free(t0);
2999ecaa27eSRichard Henderson 
30097458071SRichard Henderson     tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
30197458071SRichard Henderson     gen_ove_ov(dc);
3029ecaa27eSRichard Henderson }
3039ecaa27eSRichard Henderson 
3049ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
3059ecaa27eSRichard Henderson {
3069ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
3079ecaa27eSRichard Henderson 
30897458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
3099ecaa27eSRichard Henderson     /* The result of divide-by-zero is undefined.
3109ecaa27eSRichard Henderson        Supress the host-side exception by dividing by 1.  */
31197458071SRichard Henderson     tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
3129ecaa27eSRichard Henderson     tcg_gen_divu_tl(dest, srca, t0);
3139ecaa27eSRichard Henderson     tcg_temp_free(t0);
3149ecaa27eSRichard Henderson 
31597458071SRichard Henderson     gen_ove_cy(dc);
3169ecaa27eSRichard Henderson }
317da1d7759SSebastian Macke 
318cc5de49eSRichard Henderson static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
319cc5de49eSRichard Henderson {
320cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
321cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
322cc5de49eSRichard Henderson 
323cc5de49eSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
324cc5de49eSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
325cc5de49eSRichard Henderson     if (TARGET_LONG_BITS == 32) {
326cc5de49eSRichard Henderson         tcg_gen_mul_i64(cpu_mac, t1, t2);
327cc5de49eSRichard Henderson         tcg_gen_movi_tl(cpu_sr_ov, 0);
328cc5de49eSRichard Henderson     } else {
329cc5de49eSRichard Henderson         TCGv_i64 high = tcg_temp_new_i64();
330cc5de49eSRichard Henderson 
331cc5de49eSRichard Henderson         tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
332cc5de49eSRichard Henderson         tcg_gen_sari_i64(t1, cpu_mac, 63);
333cc5de49eSRichard Henderson         tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
334cc5de49eSRichard Henderson         tcg_temp_free_i64(high);
335cc5de49eSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
336cc5de49eSRichard Henderson         tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
337cc5de49eSRichard Henderson 
338cc5de49eSRichard Henderson         gen_ove_ov(dc);
339cc5de49eSRichard Henderson     }
340cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
341cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
342cc5de49eSRichard Henderson }
343cc5de49eSRichard Henderson 
344cc5de49eSRichard Henderson static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
345cc5de49eSRichard Henderson {
346cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
347cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
348cc5de49eSRichard Henderson 
349cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
350cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
351cc5de49eSRichard Henderson     if (TARGET_LONG_BITS == 32) {
352cc5de49eSRichard Henderson         tcg_gen_mul_i64(cpu_mac, t1, t2);
353cc5de49eSRichard Henderson         tcg_gen_movi_tl(cpu_sr_cy, 0);
354cc5de49eSRichard Henderson     } else {
355cc5de49eSRichard Henderson         TCGv_i64 high = tcg_temp_new_i64();
356cc5de49eSRichard Henderson 
357cc5de49eSRichard Henderson         tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
358cc5de49eSRichard Henderson         tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
359cc5de49eSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
360cc5de49eSRichard Henderson         tcg_temp_free_i64(high);
361cc5de49eSRichard Henderson 
362cc5de49eSRichard Henderson         gen_ove_cy(dc);
363cc5de49eSRichard Henderson     }
364cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
365cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
366cc5de49eSRichard Henderson }
367cc5de49eSRichard Henderson 
3686f7332baSRichard Henderson static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
3696f7332baSRichard Henderson {
3706f7332baSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
3716f7332baSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
3726f7332baSRichard Henderson 
3736f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
3746f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
3756f7332baSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
3766f7332baSRichard Henderson 
3776f7332baSRichard Henderson     /* Note that overflow is only computed during addition stage.  */
3786f7332baSRichard Henderson     tcg_gen_xor_i64(t2, cpu_mac, t1);
3796f7332baSRichard Henderson     tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
3806f7332baSRichard Henderson     tcg_gen_xor_i64(t1, t1, cpu_mac);
3816f7332baSRichard Henderson     tcg_gen_andc_i64(t1, t1, t2);
3826f7332baSRichard Henderson     tcg_temp_free_i64(t2);
3836f7332baSRichard Henderson 
3846f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
3856f7332baSRichard Henderson     tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
3866f7332baSRichard Henderson #else
3876f7332baSRichard Henderson     tcg_gen_mov_i64(cpu_sr_ov, t1);
3886f7332baSRichard Henderson #endif
3896f7332baSRichard Henderson     tcg_temp_free_i64(t1);
3906f7332baSRichard Henderson 
3916f7332baSRichard Henderson     gen_ove_ov(dc);
3926f7332baSRichard Henderson }
3936f7332baSRichard Henderson 
394cc5de49eSRichard Henderson static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
395cc5de49eSRichard Henderson {
396cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
397cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
398cc5de49eSRichard Henderson 
399cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
400cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
401cc5de49eSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
402cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
403cc5de49eSRichard Henderson 
404cc5de49eSRichard Henderson     /* Note that overflow is only computed during addition stage.  */
405cc5de49eSRichard Henderson     tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
406cc5de49eSRichard Henderson     tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
407cc5de49eSRichard Henderson     tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
408cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
409cc5de49eSRichard Henderson 
410cc5de49eSRichard Henderson     gen_ove_cy(dc);
411cc5de49eSRichard Henderson }
412cc5de49eSRichard Henderson 
4136f7332baSRichard Henderson static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
4146f7332baSRichard Henderson {
4156f7332baSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
4166f7332baSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
4176f7332baSRichard Henderson 
4186f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
4196f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
4206f7332baSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
4216f7332baSRichard Henderson 
4226f7332baSRichard Henderson     /* Note that overflow is only computed during subtraction stage.  */
4236f7332baSRichard Henderson     tcg_gen_xor_i64(t2, cpu_mac, t1);
4246f7332baSRichard Henderson     tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
4256f7332baSRichard Henderson     tcg_gen_xor_i64(t1, t1, cpu_mac);
4266f7332baSRichard Henderson     tcg_gen_and_i64(t1, t1, t2);
4276f7332baSRichard Henderson     tcg_temp_free_i64(t2);
4286f7332baSRichard Henderson 
4296f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
4306f7332baSRichard Henderson     tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
4316f7332baSRichard Henderson #else
4326f7332baSRichard Henderson     tcg_gen_mov_i64(cpu_sr_ov, t1);
4336f7332baSRichard Henderson #endif
4346f7332baSRichard Henderson     tcg_temp_free_i64(t1);
4356f7332baSRichard Henderson 
4366f7332baSRichard Henderson     gen_ove_ov(dc);
4376f7332baSRichard Henderson }
4386f7332baSRichard Henderson 
439cc5de49eSRichard Henderson static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
440cc5de49eSRichard Henderson {
441cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
442cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
443cc5de49eSRichard Henderson 
444cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
445cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
446cc5de49eSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
447cc5de49eSRichard Henderson 
448cc5de49eSRichard Henderson     /* Note that overflow is only computed during subtraction stage.  */
449cc5de49eSRichard Henderson     tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
450cc5de49eSRichard Henderson     tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
451cc5de49eSRichard Henderson     tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
452cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
453cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
454cc5de49eSRichard Henderson 
455cc5de49eSRichard Henderson     gen_ove_cy(dc);
456cc5de49eSRichard Henderson }
457cc5de49eSRichard Henderson 
4586ad216abSRichard Henderson static bool trans_l_add(DisasContext *dc, arg_dab *a, uint32_t insn)
459bbe418f2SJia Liu {
4606ad216abSRichard Henderson     LOG_DIS("l.add r%d, r%d, r%d\n", a->d, a->a, a->b);
4616ad216abSRichard Henderson     check_r0_write(a->d);
4626ad216abSRichard Henderson     gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
4636ad216abSRichard Henderson     return true;
464bbe418f2SJia Liu }
465bbe418f2SJia Liu 
4666ad216abSRichard Henderson static bool trans_l_addc(DisasContext *dc, arg_dab *a, uint32_t insn)
467bbe418f2SJia Liu {
4686ad216abSRichard Henderson     LOG_DIS("l.addc r%d, r%d, r%d\n", a->d, a->a, a->b);
4696ad216abSRichard Henderson     check_r0_write(a->d);
4706ad216abSRichard Henderson     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
4716ad216abSRichard Henderson     return true;
4726ad216abSRichard Henderson }
4736ad216abSRichard Henderson 
4746ad216abSRichard Henderson static bool trans_l_sub(DisasContext *dc, arg_dab *a, uint32_t insn)
4756ad216abSRichard Henderson {
4766ad216abSRichard Henderson     LOG_DIS("l.sub r%d, r%d, r%d\n", a->d, a->a, a->b);
4776ad216abSRichard Henderson     check_r0_write(a->d);
4786ad216abSRichard Henderson     gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
4796ad216abSRichard Henderson     return true;
4806ad216abSRichard Henderson }
4816ad216abSRichard Henderson 
4826ad216abSRichard Henderson static bool trans_l_and(DisasContext *dc, arg_dab *a, uint32_t insn)
4836ad216abSRichard Henderson {
4846ad216abSRichard Henderson     LOG_DIS("l.and r%d, r%d, r%d\n", a->d, a->a, a->b);
4856ad216abSRichard Henderson     check_r0_write(a->d);
4866ad216abSRichard Henderson     tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
4876ad216abSRichard Henderson     return true;
4886ad216abSRichard Henderson }
4896ad216abSRichard Henderson 
4906ad216abSRichard Henderson static bool trans_l_or(DisasContext *dc, arg_dab *a, uint32_t insn)
4916ad216abSRichard Henderson {
4926ad216abSRichard Henderson     LOG_DIS("l.or r%d, r%d, r%d\n", a->d, a->a, a->b);
4936ad216abSRichard Henderson     check_r0_write(a->d);
4946ad216abSRichard Henderson     tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
4956ad216abSRichard Henderson     return true;
4966ad216abSRichard Henderson }
4976ad216abSRichard Henderson 
4986ad216abSRichard Henderson static bool trans_l_xor(DisasContext *dc, arg_dab *a, uint32_t insn)
4996ad216abSRichard Henderson {
5006ad216abSRichard Henderson     LOG_DIS("l.xor r%d, r%d, r%d\n", a->d, a->a, a->b);
5016ad216abSRichard Henderson     check_r0_write(a->d);
5026ad216abSRichard Henderson     tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
5036ad216abSRichard Henderson     return true;
5046ad216abSRichard Henderson }
5056ad216abSRichard Henderson 
5066ad216abSRichard Henderson static bool trans_l_sll(DisasContext *dc, arg_dab *a, uint32_t insn)
5076ad216abSRichard Henderson {
5086ad216abSRichard Henderson     LOG_DIS("l.sll r%d, r%d, r%d\n", a->d, a->a, a->b);
5096ad216abSRichard Henderson     check_r0_write(a->d);
5106ad216abSRichard Henderson     tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
5116ad216abSRichard Henderson     return true;
5126ad216abSRichard Henderson }
5136ad216abSRichard Henderson 
5146ad216abSRichard Henderson static bool trans_l_srl(DisasContext *dc, arg_dab *a, uint32_t insn)
5156ad216abSRichard Henderson {
5166ad216abSRichard Henderson     LOG_DIS("l.srl r%d, r%d, r%d\n", a->d, a->a, a->b);
5176ad216abSRichard Henderson     check_r0_write(a->d);
5186ad216abSRichard Henderson     tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
5196ad216abSRichard Henderson     return true;
5206ad216abSRichard Henderson }
5216ad216abSRichard Henderson 
5226ad216abSRichard Henderson static bool trans_l_sra(DisasContext *dc, arg_dab *a, uint32_t insn)
5236ad216abSRichard Henderson {
5246ad216abSRichard Henderson     LOG_DIS("l.sra r%d, r%d, r%d\n", a->d, a->a, a->b);
5256ad216abSRichard Henderson     check_r0_write(a->d);
5266ad216abSRichard Henderson     tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
5276ad216abSRichard Henderson     return true;
5286ad216abSRichard Henderson }
5296ad216abSRichard Henderson 
5306ad216abSRichard Henderson static bool trans_l_ror(DisasContext *dc, arg_dab *a, uint32_t insn)
5316ad216abSRichard Henderson {
5326ad216abSRichard Henderson     LOG_DIS("l.ror r%d, r%d, r%d\n", a->d, a->a, a->b);
5336ad216abSRichard Henderson     check_r0_write(a->d);
5346ad216abSRichard Henderson     tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
5356ad216abSRichard Henderson     return true;
5366ad216abSRichard Henderson }
5376ad216abSRichard Henderson 
5386ad216abSRichard Henderson static bool trans_l_exths(DisasContext *dc, arg_da *a, uint32_t insn)
5396ad216abSRichard Henderson {
5406ad216abSRichard Henderson     LOG_DIS("l.exths r%d, r%d\n", a->d, a->a);
5416ad216abSRichard Henderson     check_r0_write(a->d);
5426ad216abSRichard Henderson     tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]);
5436ad216abSRichard Henderson     return true;
5446ad216abSRichard Henderson }
5456ad216abSRichard Henderson 
5466ad216abSRichard Henderson static bool trans_l_extbs(DisasContext *dc, arg_da *a, uint32_t insn)
5476ad216abSRichard Henderson {
5486ad216abSRichard Henderson     LOG_DIS("l.extbs r%d, r%d\n", a->d, a->a);
5496ad216abSRichard Henderson     check_r0_write(a->d);
5506ad216abSRichard Henderson     tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]);
5516ad216abSRichard Henderson     return true;
5526ad216abSRichard Henderson }
5536ad216abSRichard Henderson 
5546ad216abSRichard Henderson static bool trans_l_exthz(DisasContext *dc, arg_da *a, uint32_t insn)
5556ad216abSRichard Henderson {
5566ad216abSRichard Henderson     LOG_DIS("l.exthz r%d, r%d\n", a->d, a->a);
5576ad216abSRichard Henderson     check_r0_write(a->d);
5586ad216abSRichard Henderson     tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]);
5596ad216abSRichard Henderson     return true;
5606ad216abSRichard Henderson }
5616ad216abSRichard Henderson 
5626ad216abSRichard Henderson static bool trans_l_extbz(DisasContext *dc, arg_da *a, uint32_t insn)
5636ad216abSRichard Henderson {
5646ad216abSRichard Henderson     LOG_DIS("l.extbz r%d, r%d\n", a->d, a->a);
5656ad216abSRichard Henderson     check_r0_write(a->d);
5666ad216abSRichard Henderson     tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]);
5676ad216abSRichard Henderson     return true;
5686ad216abSRichard Henderson }
5696ad216abSRichard Henderson 
5706ad216abSRichard Henderson static bool trans_l_cmov(DisasContext *dc, arg_dab *a, uint32_t insn)
5716ad216abSRichard Henderson {
5726ad216abSRichard Henderson     TCGv zero;
5736ad216abSRichard Henderson     LOG_DIS("l.cmov r%d, r%d, r%d\n", a->d, a->a, a->b);
5746ad216abSRichard Henderson 
5756ad216abSRichard Henderson     check_r0_write(a->d);
5766ad216abSRichard Henderson     zero = tcg_const_tl(0);
5776ad216abSRichard Henderson     tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[a->d], cpu_sr_f, zero,
5786ad216abSRichard Henderson                        cpu_R[a->a], cpu_R[a->b]);
579784696d1SRichard Henderson     tcg_temp_free(zero);
5806ad216abSRichard Henderson     return true;
581bbe418f2SJia Liu }
582bbe418f2SJia Liu 
5836ad216abSRichard Henderson static bool trans_l_ff1(DisasContext *dc, arg_da *a, uint32_t insn)
5846ad216abSRichard Henderson {
5856ad216abSRichard Henderson     LOG_DIS("l.ff1 r%d, r%d\n", a->d, a->a);
5866ad216abSRichard Henderson 
5876ad216abSRichard Henderson     check_r0_write(a->d);
5886ad216abSRichard Henderson     tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1);
5896ad216abSRichard Henderson     tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1);
5906ad216abSRichard Henderson     return true;
591cf2ae442SRichard Henderson }
592cf2ae442SRichard Henderson 
5936ad216abSRichard Henderson static bool trans_l_fl1(DisasContext *dc, arg_da *a, uint32_t insn)
5946ad216abSRichard Henderson {
5956ad216abSRichard Henderson     LOG_DIS("l.fl1 r%d, r%d\n", a->d, a->a);
5966ad216abSRichard Henderson 
5976ad216abSRichard Henderson     check_r0_write(a->d);
5986ad216abSRichard Henderson     tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS);
5996ad216abSRichard Henderson     tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]);
6006ad216abSRichard Henderson     return true;
601bbe418f2SJia Liu }
602bbe418f2SJia Liu 
6036ad216abSRichard Henderson static bool trans_l_mul(DisasContext *dc, arg_dab *a, uint32_t insn)
6046ad216abSRichard Henderson {
6056ad216abSRichard Henderson     LOG_DIS("l.mul r%d, r%d, r%d\n", a->d, a->a, a->b);
606bbe418f2SJia Liu 
6076ad216abSRichard Henderson     check_r0_write(a->d);
6086ad216abSRichard Henderson     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
6096ad216abSRichard Henderson     return true;
610bbe418f2SJia Liu }
6116ad216abSRichard Henderson 
6126ad216abSRichard Henderson static bool trans_l_mulu(DisasContext *dc, arg_dab *a, uint32_t insn)
6136ad216abSRichard Henderson {
6146ad216abSRichard Henderson     LOG_DIS("l.mulu r%d, r%d, r%d\n", a->d, a->a, a->b);
6156ad216abSRichard Henderson 
6166ad216abSRichard Henderson     check_r0_write(a->d);
6176ad216abSRichard Henderson     gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
6186ad216abSRichard Henderson     return true;
619bbe418f2SJia Liu }
6206ad216abSRichard Henderson 
6216ad216abSRichard Henderson static bool trans_l_div(DisasContext *dc, arg_dab *a, uint32_t insn)
6226ad216abSRichard Henderson {
6236ad216abSRichard Henderson     LOG_DIS("l.div r%d, r%d, r%d\n", a->d, a->a, a->b);
6246ad216abSRichard Henderson 
6256ad216abSRichard Henderson     check_r0_write(a->d);
6266ad216abSRichard Henderson     gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
6276ad216abSRichard Henderson     return true;
6286ad216abSRichard Henderson }
6296ad216abSRichard Henderson 
6306ad216abSRichard Henderson static bool trans_l_divu(DisasContext *dc, arg_dab *a, uint32_t insn)
6316ad216abSRichard Henderson {
6326ad216abSRichard Henderson     LOG_DIS("l.divu r%d, r%d, r%d\n", a->d, a->a, a->b);
6336ad216abSRichard Henderson 
6346ad216abSRichard Henderson     check_r0_write(a->d);
6356ad216abSRichard Henderson     gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
6366ad216abSRichard Henderson     return true;
6376ad216abSRichard Henderson }
6386ad216abSRichard Henderson 
6396ad216abSRichard Henderson static bool trans_l_muld(DisasContext *dc, arg_ab *a, uint32_t insn)
6406ad216abSRichard Henderson {
6416ad216abSRichard Henderson     LOG_DIS("l.muld r%d, r%d\n", a->a, a->b);
6426ad216abSRichard Henderson     gen_muld(dc, cpu_R[a->a], cpu_R[a->b]);
6436ad216abSRichard Henderson     return true;
6446ad216abSRichard Henderson }
6456ad216abSRichard Henderson 
6466ad216abSRichard Henderson static bool trans_l_muldu(DisasContext *dc, arg_ab *a, uint32_t insn)
6476ad216abSRichard Henderson {
6486ad216abSRichard Henderson     LOG_DIS("l.muldu r%d, r%d\n", a->a, a->b);
6496ad216abSRichard Henderson     gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]);
6506ad216abSRichard Henderson     return true;
651bbe418f2SJia Liu }
652bbe418f2SJia Liu 
653136e13aeSRichard Henderson static bool trans_l_j(DisasContext *dc, arg_l_j *a, uint32_t insn)
654136e13aeSRichard Henderson {
655136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
656136e13aeSRichard Henderson 
657136e13aeSRichard Henderson     LOG_DIS("l.j %d\n", a->n);
658136e13aeSRichard Henderson     tcg_gen_movi_tl(jmp_pc, tmp_pc);
659136e13aeSRichard Henderson     dc->delayed_branch = 2;
660136e13aeSRichard Henderson     return true;
661136e13aeSRichard Henderson }
662136e13aeSRichard Henderson 
663136e13aeSRichard Henderson static bool trans_l_jal(DisasContext *dc, arg_l_jal *a, uint32_t insn)
664136e13aeSRichard Henderson {
665136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
666136e13aeSRichard Henderson     target_ulong ret_pc = dc->base.pc_next + 8;
667136e13aeSRichard Henderson 
668136e13aeSRichard Henderson     LOG_DIS("l.jal %d\n", a->n);
669136e13aeSRichard Henderson     tcg_gen_movi_tl(cpu_R[9], ret_pc);
670136e13aeSRichard Henderson     /* Optimize jal being used to load the PC for PIC.  */
671136e13aeSRichard Henderson     if (tmp_pc != ret_pc) {
672136e13aeSRichard Henderson         tcg_gen_movi_tl(jmp_pc, tmp_pc);
673136e13aeSRichard Henderson         dc->delayed_branch = 2;
674136e13aeSRichard Henderson     }
675136e13aeSRichard Henderson     return true;
676136e13aeSRichard Henderson }
677136e13aeSRichard Henderson 
678136e13aeSRichard Henderson static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
679136e13aeSRichard Henderson {
680136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
681136e13aeSRichard Henderson     TCGv t_next = tcg_const_tl(dc->base.pc_next + 8);
682136e13aeSRichard Henderson     TCGv t_true = tcg_const_tl(tmp_pc);
683136e13aeSRichard Henderson     TCGv t_zero = tcg_const_tl(0);
684136e13aeSRichard Henderson 
685136e13aeSRichard Henderson     tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
686136e13aeSRichard Henderson 
687136e13aeSRichard Henderson     tcg_temp_free(t_next);
688136e13aeSRichard Henderson     tcg_temp_free(t_true);
689136e13aeSRichard Henderson     tcg_temp_free(t_zero);
690136e13aeSRichard Henderson     dc->delayed_branch = 2;
691136e13aeSRichard Henderson }
692136e13aeSRichard Henderson 
693136e13aeSRichard Henderson static bool trans_l_bf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
694136e13aeSRichard Henderson {
695136e13aeSRichard Henderson     LOG_DIS("l.bf %d\n", a->n);
696136e13aeSRichard Henderson     do_bf(dc, a, TCG_COND_NE);
697136e13aeSRichard Henderson     return true;
698136e13aeSRichard Henderson }
699136e13aeSRichard Henderson 
700136e13aeSRichard Henderson static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
701136e13aeSRichard Henderson {
702136e13aeSRichard Henderson     LOG_DIS("l.bnf %d\n", a->n);
703136e13aeSRichard Henderson     do_bf(dc, a, TCG_COND_EQ);
704136e13aeSRichard Henderson     return true;
705136e13aeSRichard Henderson }
706136e13aeSRichard Henderson 
707136e13aeSRichard Henderson static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
708136e13aeSRichard Henderson {
709136e13aeSRichard Henderson     LOG_DIS("l.jr r%d\n", a->b);
710136e13aeSRichard Henderson     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
711136e13aeSRichard Henderson     dc->delayed_branch = 2;
712136e13aeSRichard Henderson     return true;
713136e13aeSRichard Henderson }
714136e13aeSRichard Henderson 
715136e13aeSRichard Henderson static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a, uint32_t insn)
716136e13aeSRichard Henderson {
717136e13aeSRichard Henderson     LOG_DIS("l.jalr r%d\n", a->b);
718136e13aeSRichard Henderson     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
719136e13aeSRichard Henderson     tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
720136e13aeSRichard Henderson     dc->delayed_branch = 2;
721136e13aeSRichard Henderson     return true;
722136e13aeSRichard Henderson }
723136e13aeSRichard Henderson 
724d80bff19SRichard Henderson static bool trans_l_lwa(DisasContext *dc, arg_load *a, uint32_t insn)
725d80bff19SRichard Henderson {
726d80bff19SRichard Henderson     TCGv ea;
727d80bff19SRichard Henderson 
728d80bff19SRichard Henderson     LOG_DIS("l.lwa r%d, r%d, %d\n", a->d, a->a, a->i);
729d80bff19SRichard Henderson 
730d80bff19SRichard Henderson     check_r0_write(a->d);
731d80bff19SRichard Henderson     ea = tcg_temp_new();
732d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
733d80bff19SRichard Henderson     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL);
734d80bff19SRichard Henderson     tcg_gen_mov_tl(cpu_lock_addr, ea);
735d80bff19SRichard Henderson     tcg_gen_mov_tl(cpu_lock_value, cpu_R[a->d]);
736d80bff19SRichard Henderson     tcg_temp_free(ea);
737d80bff19SRichard Henderson     return true;
738d80bff19SRichard Henderson }
739d80bff19SRichard Henderson 
740d80bff19SRichard Henderson static void do_load(DisasContext *dc, arg_load *a, TCGMemOp mop)
741d80bff19SRichard Henderson {
742d80bff19SRichard Henderson     TCGv ea;
743d80bff19SRichard Henderson 
744d80bff19SRichard Henderson     check_r0_write(a->d);
745d80bff19SRichard Henderson     ea = tcg_temp_new();
746d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
747d80bff19SRichard Henderson     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop);
748d80bff19SRichard Henderson     tcg_temp_free(ea);
749d80bff19SRichard Henderson }
750d80bff19SRichard Henderson 
751d80bff19SRichard Henderson static bool trans_l_lwz(DisasContext *dc, arg_load *a, uint32_t insn)
752d80bff19SRichard Henderson {
753d80bff19SRichard Henderson     LOG_DIS("l.lwz r%d, r%d, %d\n", a->d, a->a, a->i);
754d80bff19SRichard Henderson     do_load(dc, a, MO_TEUL);
755d80bff19SRichard Henderson     return true;
756d80bff19SRichard Henderson }
757d80bff19SRichard Henderson 
758d80bff19SRichard Henderson static bool trans_l_lws(DisasContext *dc, arg_load *a, uint32_t insn)
759d80bff19SRichard Henderson {
760d80bff19SRichard Henderson     LOG_DIS("l.lws r%d, r%d, %d\n", a->d, a->a, a->i);
761d80bff19SRichard Henderson     do_load(dc, a, MO_TESL);
762d80bff19SRichard Henderson     return true;
763d80bff19SRichard Henderson }
764d80bff19SRichard Henderson 
765d80bff19SRichard Henderson static bool trans_l_lbz(DisasContext *dc, arg_load *a, uint32_t insn)
766d80bff19SRichard Henderson {
767d80bff19SRichard Henderson     LOG_DIS("l.lbz r%d, r%d, %d\n", a->d, a->a, a->i);
768d80bff19SRichard Henderson     do_load(dc, a, MO_UB);
769d80bff19SRichard Henderson     return true;
770d80bff19SRichard Henderson }
771d80bff19SRichard Henderson 
772d80bff19SRichard Henderson static bool trans_l_lbs(DisasContext *dc, arg_load *a, uint32_t insn)
773d80bff19SRichard Henderson {
774d80bff19SRichard Henderson     LOG_DIS("l.lbs r%d, r%d, %d\n", a->d, a->a, a->i);
775d80bff19SRichard Henderson     do_load(dc, a, MO_SB);
776d80bff19SRichard Henderson     return true;
777d80bff19SRichard Henderson }
778d80bff19SRichard Henderson 
779d80bff19SRichard Henderson static bool trans_l_lhz(DisasContext *dc, arg_load *a, uint32_t insn)
780d80bff19SRichard Henderson {
781d80bff19SRichard Henderson     LOG_DIS("l.lhz r%d, r%d, %d\n", a->d, a->a, a->i);
782d80bff19SRichard Henderson     do_load(dc, a, MO_TEUW);
783d80bff19SRichard Henderson     return true;
784d80bff19SRichard Henderson }
785d80bff19SRichard Henderson 
786d80bff19SRichard Henderson static bool trans_l_lhs(DisasContext *dc, arg_load *a, uint32_t insn)
787d80bff19SRichard Henderson {
788d80bff19SRichard Henderson     LOG_DIS("l.lhs r%d, r%d, %d\n", a->d, a->a, a->i);
789d80bff19SRichard Henderson     do_load(dc, a, MO_TESW);
790d80bff19SRichard Henderson     return true;
791d80bff19SRichard Henderson }
792d80bff19SRichard Henderson 
793d80bff19SRichard Henderson static bool trans_l_swa(DisasContext *dc, arg_store *a, uint32_t insn)
794d80bff19SRichard Henderson {
795d80bff19SRichard Henderson     TCGv ea, val;
796d80bff19SRichard Henderson     TCGLabel *lab_fail, *lab_done;
797d80bff19SRichard Henderson 
798d80bff19SRichard Henderson     LOG_DIS("l.swa r%d, r%d, %d\n", a->a, a->b, a->i);
799d80bff19SRichard Henderson 
800d80bff19SRichard Henderson     ea = tcg_temp_new();
801d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
802d80bff19SRichard Henderson 
803d80bff19SRichard Henderson     /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
804d80bff19SRichard Henderson        to cpu_R[0].  Since l.swa is quite often immediately followed by a
805d80bff19SRichard Henderson        branch, don't bother reallocating; finish the TB using the "real" R0.
806d80bff19SRichard Henderson        This also takes care of RB input across the branch.  */
807d80bff19SRichard Henderson     cpu_R[0] = cpu_R0;
808d80bff19SRichard Henderson 
809d80bff19SRichard Henderson     lab_fail = gen_new_label();
810d80bff19SRichard Henderson     lab_done = gen_new_label();
811d80bff19SRichard Henderson     tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
812d80bff19SRichard Henderson     tcg_temp_free(ea);
813d80bff19SRichard Henderson 
814d80bff19SRichard Henderson     val = tcg_temp_new();
815d80bff19SRichard Henderson     tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
816d80bff19SRichard Henderson                               cpu_R[a->b], dc->mem_idx, MO_TEUL);
817d80bff19SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
818d80bff19SRichard Henderson     tcg_temp_free(val);
819d80bff19SRichard Henderson 
820d80bff19SRichard Henderson     tcg_gen_br(lab_done);
821d80bff19SRichard Henderson 
822d80bff19SRichard Henderson     gen_set_label(lab_fail);
823d80bff19SRichard Henderson     tcg_gen_movi_tl(cpu_sr_f, 0);
824d80bff19SRichard Henderson 
825d80bff19SRichard Henderson     gen_set_label(lab_done);
826d80bff19SRichard Henderson     tcg_gen_movi_tl(cpu_lock_addr, -1);
827d80bff19SRichard Henderson     return true;
828d80bff19SRichard Henderson }
829d80bff19SRichard Henderson 
830d80bff19SRichard Henderson static void do_store(DisasContext *dc, arg_store *a, TCGMemOp mop)
831d80bff19SRichard Henderson {
832d80bff19SRichard Henderson     TCGv t0 = tcg_temp_new();
833d80bff19SRichard Henderson     tcg_gen_addi_tl(t0, cpu_R[a->a], a->i);
834d80bff19SRichard Henderson     tcg_gen_qemu_st_tl(cpu_R[a->b], t0, dc->mem_idx, mop);
835d80bff19SRichard Henderson     tcg_temp_free(t0);
836d80bff19SRichard Henderson }
837d80bff19SRichard Henderson 
838d80bff19SRichard Henderson static bool trans_l_sw(DisasContext *dc, arg_store *a, uint32_t insn)
839d80bff19SRichard Henderson {
840d80bff19SRichard Henderson     LOG_DIS("l.sw r%d, r%d, %d\n", a->a, a->b, a->i);
841d80bff19SRichard Henderson     do_store(dc, a, MO_TEUL);
842d80bff19SRichard Henderson     return true;
843d80bff19SRichard Henderson }
844d80bff19SRichard Henderson 
845d80bff19SRichard Henderson static bool trans_l_sb(DisasContext *dc, arg_store *a, uint32_t insn)
846d80bff19SRichard Henderson {
847d80bff19SRichard Henderson     LOG_DIS("l.sb r%d, r%d, %d\n", a->a, a->b, a->i);
848d80bff19SRichard Henderson     do_store(dc, a, MO_UB);
849d80bff19SRichard Henderson     return true;
850d80bff19SRichard Henderson }
851d80bff19SRichard Henderson 
852d80bff19SRichard Henderson static bool trans_l_sh(DisasContext *dc, arg_store *a, uint32_t insn)
853d80bff19SRichard Henderson {
854d80bff19SRichard Henderson     LOG_DIS("l.sh r%d, r%d, %d\n", a->a, a->b, a->i);
855d80bff19SRichard Henderson     do_store(dc, a, MO_TEUW);
856d80bff19SRichard Henderson     return true;
857d80bff19SRichard Henderson }
858d80bff19SRichard Henderson 
8598816f70bSRichard Henderson static bool trans_l_nop(DisasContext *dc, arg_l_nop *a, uint32_t insn)
860bbe418f2SJia Liu {
8618816f70bSRichard Henderson     LOG_DIS("l.nop %d\n", a->k);
8628816f70bSRichard Henderson     return true;
8638816f70bSRichard Henderson }
8648816f70bSRichard Henderson 
8658816f70bSRichard Henderson static bool trans_l_addi(DisasContext *dc, arg_rri *a, uint32_t insn)
8668816f70bSRichard Henderson {
8679ecaa27eSRichard Henderson     TCGv t0;
8685631e69cSRichard Henderson 
8698816f70bSRichard Henderson     LOG_DIS("l.addi r%d, r%d, %d\n", a->d, a->a, a->i);
8708816f70bSRichard Henderson     check_r0_write(a->d);
8718816f70bSRichard Henderson     t0 = tcg_const_tl(a->i);
8728816f70bSRichard Henderson     gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0);
8736f7332baSRichard Henderson     tcg_temp_free(t0);
8748816f70bSRichard Henderson     return true;
8758816f70bSRichard Henderson }
876bbe418f2SJia Liu 
8778816f70bSRichard Henderson static bool trans_l_addic(DisasContext *dc, arg_rri *a, uint32_t insn)
878bbe418f2SJia Liu {
8798816f70bSRichard Henderson     TCGv t0;
8808816f70bSRichard Henderson 
8818816f70bSRichard Henderson     LOG_DIS("l.addic r%d, r%d, %d\n", a->d, a->a, a->i);
8828816f70bSRichard Henderson     check_r0_write(a->d);
8838816f70bSRichard Henderson     t0 = tcg_const_tl(a->i);
8848816f70bSRichard Henderson     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0);
8858816f70bSRichard Henderson     tcg_temp_free(t0);
8868816f70bSRichard Henderson     return true;
8878816f70bSRichard Henderson }
8888816f70bSRichard Henderson 
8898816f70bSRichard Henderson static bool trans_l_muli(DisasContext *dc, arg_rri *a, uint32_t insn)
8908816f70bSRichard Henderson {
8918816f70bSRichard Henderson     TCGv t0;
8928816f70bSRichard Henderson 
8938816f70bSRichard Henderson     LOG_DIS("l.muli r%d, r%d, %d\n", a->d, a->a, a->i);
8948816f70bSRichard Henderson     check_r0_write(a->d);
8958816f70bSRichard Henderson     t0 = tcg_const_tl(a->i);
8968816f70bSRichard Henderson     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0);
8978816f70bSRichard Henderson     tcg_temp_free(t0);
8988816f70bSRichard Henderson     return true;
8998816f70bSRichard Henderson }
9008816f70bSRichard Henderson 
9018816f70bSRichard Henderson static bool trans_l_maci(DisasContext *dc, arg_l_maci *a, uint32_t insn)
9028816f70bSRichard Henderson {
9038816f70bSRichard Henderson     TCGv t0;
9048816f70bSRichard Henderson 
9058816f70bSRichard Henderson     LOG_DIS("l.maci r%d, %d\n", a->a, a->i);
9068816f70bSRichard Henderson     t0 = tcg_const_tl(a->i);
9078816f70bSRichard Henderson     gen_mac(dc, cpu_R[a->a], t0);
9088816f70bSRichard Henderson     tcg_temp_free(t0);
9098816f70bSRichard Henderson     return true;
9108816f70bSRichard Henderson }
9118816f70bSRichard Henderson 
9128816f70bSRichard Henderson static bool trans_l_andi(DisasContext *dc, arg_rrk *a, uint32_t insn)
9138816f70bSRichard Henderson {
9148816f70bSRichard Henderson     LOG_DIS("l.andi r%d, r%d, %d\n", a->d, a->a, a->k);
9158816f70bSRichard Henderson     check_r0_write(a->d);
9168816f70bSRichard Henderson     tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k);
9178816f70bSRichard Henderson     return true;
9188816f70bSRichard Henderson }
9198816f70bSRichard Henderson 
9208816f70bSRichard Henderson static bool trans_l_ori(DisasContext *dc, arg_rrk *a, uint32_t insn)
9218816f70bSRichard Henderson {
9228816f70bSRichard Henderson     LOG_DIS("l.ori r%d, r%d, %d\n", a->d, a->a, a->k);
9238816f70bSRichard Henderson     check_r0_write(a->d);
9248816f70bSRichard Henderson     tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k);
9258816f70bSRichard Henderson     return true;
9268816f70bSRichard Henderson }
9278816f70bSRichard Henderson 
9288816f70bSRichard Henderson static bool trans_l_xori(DisasContext *dc, arg_rri *a, uint32_t insn)
9298816f70bSRichard Henderson {
9308816f70bSRichard Henderson     LOG_DIS("l.xori r%d, r%d, %d\n", a->d, a->a, a->i);
9318816f70bSRichard Henderson     check_r0_write(a->d);
9328816f70bSRichard Henderson     tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i);
9338816f70bSRichard Henderson     return true;
9348816f70bSRichard Henderson }
9358816f70bSRichard Henderson 
9368816f70bSRichard Henderson static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a, uint32_t insn)
9378816f70bSRichard Henderson {
9388816f70bSRichard Henderson     LOG_DIS("l.mfspr r%d, r%d, %d\n", a->d, a->a, a->k);
9398816f70bSRichard Henderson     check_r0_write(a->d);
9408816f70bSRichard Henderson 
9418816f70bSRichard Henderson #ifdef CONFIG_USER_ONLY
9428816f70bSRichard Henderson     gen_illegal_exception(dc);
943bbe418f2SJia Liu #else
944bbe418f2SJia Liu     if (dc->mem_idx == MMU_USER_IDX) {
945bbe418f2SJia Liu         gen_illegal_exception(dc);
9468816f70bSRichard Henderson     } else {
9478816f70bSRichard Henderson         TCGv_i32 ti = tcg_const_i32(a->k);
9488816f70bSRichard Henderson         gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], cpu_R[a->a], ti);
9494dd044c6SJia Liu         tcg_temp_free_i32(ti);
9504dd044c6SJia Liu     }
9518816f70bSRichard Henderson #endif
9528816f70bSRichard Henderson     return true;
9538816f70bSRichard Henderson }
954bbe418f2SJia Liu 
9558816f70bSRichard Henderson static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a, uint32_t insn)
9564dd044c6SJia Liu {
9578816f70bSRichard Henderson     LOG_DIS("l.mtspr r%d, r%d, %d\n", a->a, a->b, a->k);
9588816f70bSRichard Henderson 
9598816f70bSRichard Henderson #ifdef CONFIG_USER_ONLY
9608816f70bSRichard Henderson     gen_illegal_exception(dc);
9614dd044c6SJia Liu #else
9624dd044c6SJia Liu     if (dc->mem_idx == MMU_USER_IDX) {
9634dd044c6SJia Liu         gen_illegal_exception(dc);
9648816f70bSRichard Henderson     } else {
9658816f70bSRichard Henderson         TCGv_i32 ti = tcg_const_i32(a->k);
9668816f70bSRichard Henderson         gen_helper_mtspr(cpu_env, cpu_R[a->a], cpu_R[a->b], ti);
9678816f70bSRichard Henderson         tcg_temp_free_i32(ti);
9684dd044c6SJia Liu     }
9694dd044c6SJia Liu #endif
9708816f70bSRichard Henderson     return true;
971bbe418f2SJia Liu }
972bbe418f2SJia Liu 
97399d863d6SRichard Henderson static bool trans_l_mac(DisasContext *dc, arg_ab *a, uint32_t insn)
974bbe418f2SJia Liu {
97599d863d6SRichard Henderson     LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
97699d863d6SRichard Henderson     gen_mac(dc, cpu_R[a->a], cpu_R[a->b]);
97799d863d6SRichard Henderson     return true;
978bbe418f2SJia Liu }
97999d863d6SRichard Henderson 
98099d863d6SRichard Henderson static bool trans_l_msb(DisasContext *dc, arg_ab *a, uint32_t insn)
98199d863d6SRichard Henderson {
98299d863d6SRichard Henderson     LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
98399d863d6SRichard Henderson     gen_msb(dc, cpu_R[a->a], cpu_R[a->b]);
98499d863d6SRichard Henderson     return true;
98599d863d6SRichard Henderson }
98699d863d6SRichard Henderson 
98799d863d6SRichard Henderson static bool trans_l_macu(DisasContext *dc, arg_ab *a, uint32_t insn)
98899d863d6SRichard Henderson {
98999d863d6SRichard Henderson     LOG_DIS("l.mac r%d, r%d\n", a->a, a->b);
99099d863d6SRichard Henderson     gen_macu(dc, cpu_R[a->a], cpu_R[a->b]);
99199d863d6SRichard Henderson     return true;
99299d863d6SRichard Henderson }
99399d863d6SRichard Henderson 
99499d863d6SRichard Henderson static bool trans_l_msbu(DisasContext *dc, arg_ab *a, uint32_t insn)
99599d863d6SRichard Henderson {
99699d863d6SRichard Henderson     LOG_DIS("l.msb r%d, r%d\n", a->a, a->b);
99799d863d6SRichard Henderson     gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]);
99899d863d6SRichard Henderson     return true;
999bbe418f2SJia Liu }
1000bbe418f2SJia Liu 
1001e20c2592SRichard Henderson static bool trans_l_slli(DisasContext *dc, arg_dal *a, uint32_t insn)
1002bbe418f2SJia Liu {
1003e20c2592SRichard Henderson     LOG_DIS("l.slli r%d, r%d, %d\n", a->d, a->a, a->l);
1004e20c2592SRichard Henderson     check_r0_write(a->d);
1005e20c2592SRichard Henderson     tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
1006e20c2592SRichard Henderson     return true;
1007bbe418f2SJia Liu }
1008e20c2592SRichard Henderson 
1009e20c2592SRichard Henderson static bool trans_l_srli(DisasContext *dc, arg_dal *a, uint32_t insn)
1010e20c2592SRichard Henderson {
1011e20c2592SRichard Henderson     LOG_DIS("l.srli r%d, r%d, %d\n", a->d, a->a, a->l);
1012e20c2592SRichard Henderson     check_r0_write(a->d);
1013e20c2592SRichard Henderson     tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
1014e20c2592SRichard Henderson     return true;
1015e20c2592SRichard Henderson }
1016e20c2592SRichard Henderson 
1017e20c2592SRichard Henderson static bool trans_l_srai(DisasContext *dc, arg_dal *a, uint32_t insn)
1018e20c2592SRichard Henderson {
1019e20c2592SRichard Henderson     LOG_DIS("l.srai r%d, r%d, %d\n", a->d, a->a, a->l);
1020e20c2592SRichard Henderson     check_r0_write(a->d);
1021e20c2592SRichard Henderson     tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
1022e20c2592SRichard Henderson     return true;
1023e20c2592SRichard Henderson }
1024e20c2592SRichard Henderson 
1025e20c2592SRichard Henderson static bool trans_l_rori(DisasContext *dc, arg_dal *a, uint32_t insn)
1026e20c2592SRichard Henderson {
1027e20c2592SRichard Henderson     LOG_DIS("l.rori r%d, r%d, %d\n", a->d, a->a, a->l);
1028e20c2592SRichard Henderson     check_r0_write(a->d);
1029e20c2592SRichard Henderson     tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
1030e20c2592SRichard Henderson     return true;
1031bbe418f2SJia Liu }
1032bbe418f2SJia Liu 
1033e720a571SRichard Henderson static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a, uint32_t insn)
1034bbe418f2SJia Liu {
1035e720a571SRichard Henderson     LOG_DIS("l.movhi r%d, %d\n", a->d, a->k);
1036e720a571SRichard Henderson     check_r0_write(a->d);
1037e720a571SRichard Henderson     tcg_gen_movi_tl(cpu_R[a->d], a->k << 16);
1038e720a571SRichard Henderson     return true;
1039bbe418f2SJia Liu }
1040e720a571SRichard Henderson 
1041e720a571SRichard Henderson static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a, uint32_t insn)
1042e720a571SRichard Henderson {
1043e720a571SRichard Henderson     LOG_DIS("l.macrc r%d\n", a->d);
1044e720a571SRichard Henderson     check_r0_write(a->d);
1045e720a571SRichard Henderson     tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac);
1046e720a571SRichard Henderson     tcg_gen_movi_i64(cpu_mac, 0);
1047e720a571SRichard Henderson     return true;
1048bbe418f2SJia Liu }
1049bbe418f2SJia Liu 
1050fbb3e29aSRichard Henderson static bool trans_l_sfeq(DisasContext *dc, arg_ab *a, TCGCond cond)
1051bbe418f2SJia Liu {
1052fbb3e29aSRichard Henderson     LOG_DIS("l.sfeq r%d, r%d\n", a->a, a->b);
1053fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1054fbb3e29aSRichard Henderson     return true;
1055bbe418f2SJia Liu }
1056fbb3e29aSRichard Henderson 
1057fbb3e29aSRichard Henderson static bool trans_l_sfne(DisasContext *dc, arg_ab *a, TCGCond cond)
1058fbb3e29aSRichard Henderson {
1059fbb3e29aSRichard Henderson     LOG_DIS("l.sfne r%d, r%d\n", a->a, a->b);
1060fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1061fbb3e29aSRichard Henderson     return true;
1062fbb3e29aSRichard Henderson }
1063fbb3e29aSRichard Henderson 
1064fbb3e29aSRichard Henderson static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a, TCGCond cond)
1065fbb3e29aSRichard Henderson {
1066fbb3e29aSRichard Henderson     LOG_DIS("l.sfgtu r%d, r%d\n", a->a, a->b);
1067fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1068fbb3e29aSRichard Henderson     return true;
1069fbb3e29aSRichard Henderson }
1070fbb3e29aSRichard Henderson 
1071fbb3e29aSRichard Henderson static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a, TCGCond cond)
1072fbb3e29aSRichard Henderson {
1073fbb3e29aSRichard Henderson     LOG_DIS("l.sfgeu r%d, r%d\n", a->a, a->b);
1074fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1075fbb3e29aSRichard Henderson     return true;
1076fbb3e29aSRichard Henderson }
1077fbb3e29aSRichard Henderson 
1078fbb3e29aSRichard Henderson static bool trans_l_sfltu(DisasContext *dc, arg_ab *a, TCGCond cond)
1079fbb3e29aSRichard Henderson {
1080fbb3e29aSRichard Henderson     LOG_DIS("l.sfltu r%d, r%d\n", a->a, a->b);
1081fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1082fbb3e29aSRichard Henderson     return true;
1083fbb3e29aSRichard Henderson }
1084fbb3e29aSRichard Henderson 
1085fbb3e29aSRichard Henderson static bool trans_l_sfleu(DisasContext *dc, arg_ab *a, TCGCond cond)
1086fbb3e29aSRichard Henderson {
1087fbb3e29aSRichard Henderson     LOG_DIS("l.sfleu r%d, r%d\n", a->a, a->b);
1088fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1089fbb3e29aSRichard Henderson     return true;
1090fbb3e29aSRichard Henderson }
1091fbb3e29aSRichard Henderson 
1092fbb3e29aSRichard Henderson static bool trans_l_sfgts(DisasContext *dc, arg_ab *a, TCGCond cond)
1093fbb3e29aSRichard Henderson {
1094fbb3e29aSRichard Henderson     LOG_DIS("l.sfgts r%d, r%d\n", a->a, a->b);
1095fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1096fbb3e29aSRichard Henderson     return true;
1097fbb3e29aSRichard Henderson }
1098fbb3e29aSRichard Henderson 
1099fbb3e29aSRichard Henderson static bool trans_l_sfges(DisasContext *dc, arg_ab *a, TCGCond cond)
1100fbb3e29aSRichard Henderson {
1101fbb3e29aSRichard Henderson     LOG_DIS("l.sfges r%d, r%d\n", a->a, a->b);
1102fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1103fbb3e29aSRichard Henderson     return true;
1104fbb3e29aSRichard Henderson }
1105fbb3e29aSRichard Henderson 
1106fbb3e29aSRichard Henderson static bool trans_l_sflts(DisasContext *dc, arg_ab *a, TCGCond cond)
1107fbb3e29aSRichard Henderson {
1108fbb3e29aSRichard Henderson     LOG_DIS("l.sflts r%d, r%d\n", a->a, a->b);
1109fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1110fbb3e29aSRichard Henderson     return true;
1111fbb3e29aSRichard Henderson }
1112fbb3e29aSRichard Henderson 
1113fbb3e29aSRichard Henderson static bool trans_l_sfles(DisasContext *dc, arg_ab *a, TCGCond cond)
1114fbb3e29aSRichard Henderson {
1115fbb3e29aSRichard Henderson     LOG_DIS("l.sfles r%d, r%d\n", a->a, a->b);
1116fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1117fbb3e29aSRichard Henderson     return true;
1118bbe418f2SJia Liu }
1119bbe418f2SJia Liu 
1120*032de4fcSRichard Henderson static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a, TCGCond cond)
1121bbe418f2SJia Liu {
1122*032de4fcSRichard Henderson     LOG_DIS("l.sfeqi r%d, %d\n", a->a, a->i);
1123*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i);
1124*032de4fcSRichard Henderson     return true;
1125bbe418f2SJia Liu }
1126*032de4fcSRichard Henderson 
1127*032de4fcSRichard Henderson static bool trans_l_sfnei(DisasContext *dc, arg_ai *a, TCGCond cond)
1128*032de4fcSRichard Henderson {
1129*032de4fcSRichard Henderson     LOG_DIS("l.sfnei r%d, %d\n", a->a, a->i);
1130*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i);
1131*032de4fcSRichard Henderson     return true;
1132*032de4fcSRichard Henderson }
1133*032de4fcSRichard Henderson 
1134*032de4fcSRichard Henderson static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a, TCGCond cond)
1135*032de4fcSRichard Henderson {
1136*032de4fcSRichard Henderson     LOG_DIS("l.sfgtui r%d, %d\n", a->a, a->i);
1137*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i);
1138*032de4fcSRichard Henderson     return true;
1139*032de4fcSRichard Henderson }
1140*032de4fcSRichard Henderson 
1141*032de4fcSRichard Henderson static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a, TCGCond cond)
1142*032de4fcSRichard Henderson {
1143*032de4fcSRichard Henderson     LOG_DIS("l.sfgeui r%d, %d\n", a->a, a->i);
1144*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i);
1145*032de4fcSRichard Henderson     return true;
1146*032de4fcSRichard Henderson }
1147*032de4fcSRichard Henderson 
1148*032de4fcSRichard Henderson static bool trans_l_sfltui(DisasContext *dc, arg_ai *a, TCGCond cond)
1149*032de4fcSRichard Henderson {
1150*032de4fcSRichard Henderson     LOG_DIS("l.sfltui r%d, %d\n", a->a, a->i);
1151*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i);
1152*032de4fcSRichard Henderson     return true;
1153*032de4fcSRichard Henderson }
1154*032de4fcSRichard Henderson 
1155*032de4fcSRichard Henderson static bool trans_l_sfleui(DisasContext *dc, arg_ai *a, TCGCond cond)
1156*032de4fcSRichard Henderson {
1157*032de4fcSRichard Henderson     LOG_DIS("l.sfleui r%d, %d\n", a->a, a->i);
1158*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i);
1159*032de4fcSRichard Henderson     return true;
1160*032de4fcSRichard Henderson }
1161*032de4fcSRichard Henderson 
1162*032de4fcSRichard Henderson static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a, TCGCond cond)
1163*032de4fcSRichard Henderson {
1164*032de4fcSRichard Henderson     LOG_DIS("l.sfgtsi r%d, %d\n", a->a, a->i);
1165*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i);
1166*032de4fcSRichard Henderson     return true;
1167*032de4fcSRichard Henderson }
1168*032de4fcSRichard Henderson 
1169*032de4fcSRichard Henderson static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a, TCGCond cond)
1170*032de4fcSRichard Henderson {
1171*032de4fcSRichard Henderson     LOG_DIS("l.sfgesi r%d, %d\n", a->a, a->i);
1172*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i);
1173*032de4fcSRichard Henderson     return true;
1174*032de4fcSRichard Henderson }
1175*032de4fcSRichard Henderson 
1176*032de4fcSRichard Henderson static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a, TCGCond cond)
1177*032de4fcSRichard Henderson {
1178*032de4fcSRichard Henderson     LOG_DIS("l.sfltsi r%d, %d\n", a->a, a->i);
1179*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i);
1180*032de4fcSRichard Henderson     return true;
1181*032de4fcSRichard Henderson }
1182*032de4fcSRichard Henderson 
1183*032de4fcSRichard Henderson static bool trans_l_sflesi(DisasContext *dc, arg_ai *a, TCGCond cond)
1184*032de4fcSRichard Henderson {
1185*032de4fcSRichard Henderson     LOG_DIS("l.sflesi r%d, %d\n", a->a, a->i);
1186*032de4fcSRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i);
1187*032de4fcSRichard Henderson     return true;
1188bbe418f2SJia Liu }
1189bbe418f2SJia Liu 
11907de9729fSRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
1191bbe418f2SJia Liu {
11927de9729fSRichard Henderson     LOG_DIS("l.sys %d\n", a->k);
11931ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1194bbe418f2SJia Liu     gen_exception(dc, EXCP_SYSCALL);
11951ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
11967de9729fSRichard Henderson     return true;
11977de9729fSRichard Henderson }
1198bbe418f2SJia Liu 
11997de9729fSRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
12007de9729fSRichard Henderson {
12017de9729fSRichard Henderson     LOG_DIS("l.trap %d\n", a->k);
12021ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1203bbe418f2SJia Liu     gen_exception(dc, EXCP_TRAP);
12041ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
12057de9729fSRichard Henderson     return true;
12067de9729fSRichard Henderson }
1207bbe418f2SJia Liu 
12087de9729fSRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
12097de9729fSRichard Henderson {
1210bbe418f2SJia Liu     LOG_DIS("l.msync\n");
121124fc5c0fSRichard Henderson     tcg_gen_mb(TCG_MO_ALL);
12127de9729fSRichard Henderson     return true;
1213bbe418f2SJia Liu }
12147de9729fSRichard Henderson 
12157de9729fSRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
12167de9729fSRichard Henderson {
12177de9729fSRichard Henderson     LOG_DIS("l.psync\n");
12187de9729fSRichard Henderson     return true;
12197de9729fSRichard Henderson }
12207de9729fSRichard Henderson 
12217de9729fSRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
12227de9729fSRichard Henderson {
12237de9729fSRichard Henderson     LOG_DIS("l.csync\n");
12247de9729fSRichard Henderson     return true;
1225bbe418f2SJia Liu }
1226bbe418f2SJia Liu 
12278816f70bSRichard Henderson static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
12288816f70bSRichard Henderson {
12298816f70bSRichard Henderson     LOG_DIS("l.rfe\n");
12308816f70bSRichard Henderson 
12318816f70bSRichard Henderson #ifdef CONFIG_USER_ONLY
12328816f70bSRichard Henderson     gen_illegal_exception(dc);
12338816f70bSRichard Henderson #else
12348816f70bSRichard Henderson     if (dc->mem_idx == MMU_USER_IDX) {
12358816f70bSRichard Henderson         gen_illegal_exception(dc);
12368816f70bSRichard Henderson     } else {
12378816f70bSRichard Henderson         gen_helper_rfe(cpu_env);
12388816f70bSRichard Henderson         dc->base.is_jmp = DISAS_UPDATE;
12398816f70bSRichard Henderson     }
12408816f70bSRichard Henderson #endif
12418816f70bSRichard Henderson     return true;
12428816f70bSRichard Henderson }
12438816f70bSRichard Henderson 
1244bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn)
1245bbe418f2SJia Liu {
1246bbe418f2SJia Liu     uint32_t op0;
1247bbe418f2SJia Liu     uint32_t ra, rb, rd;
1248bbe418f2SJia Liu     op0 = extract32(insn, 0, 8);
1249bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1250bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1251bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1252bbe418f2SJia Liu 
1253bbe418f2SJia Liu     switch (op0) {
1254bbe418f2SJia Liu     case 0x00: /* lf.add.s */
1255bbe418f2SJia Liu         LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
12566597c28dSRichard Henderson         check_r0_write(rd);
1257bbe418f2SJia Liu         gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12584e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1259bbe418f2SJia Liu         break;
1260bbe418f2SJia Liu 
1261bbe418f2SJia Liu     case 0x01: /* lf.sub.s */
1262bbe418f2SJia Liu         LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
12636597c28dSRichard Henderson         check_r0_write(rd);
1264bbe418f2SJia Liu         gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12654e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1266bbe418f2SJia Liu         break;
1267bbe418f2SJia Liu 
1268bbe418f2SJia Liu     case 0x02:    /* lf.mul.s */
1269bbe418f2SJia Liu         LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
12706597c28dSRichard Henderson         check_r0_write(rd);
1271bbe418f2SJia Liu         gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12724e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1273bbe418f2SJia Liu         break;
1274bbe418f2SJia Liu 
1275bbe418f2SJia Liu     case 0x03: /* lf.div.s */
1276bbe418f2SJia Liu         LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
12776597c28dSRichard Henderson         check_r0_write(rd);
1278bbe418f2SJia Liu         gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12794e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1280bbe418f2SJia Liu         break;
1281bbe418f2SJia Liu 
1282bbe418f2SJia Liu     case 0x04: /* lf.itof.s */
1283bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
12846597c28dSRichard Henderson         check_r0_write(rd);
1285bbe418f2SJia Liu         gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
12864e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1287bbe418f2SJia Liu         break;
1288bbe418f2SJia Liu 
1289bbe418f2SJia Liu     case 0x05: /* lf.ftoi.s */
1290bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
12916597c28dSRichard Henderson         check_r0_write(rd);
1292bbe418f2SJia Liu         gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
12934e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1294bbe418f2SJia Liu         break;
1295bbe418f2SJia Liu 
1296bbe418f2SJia Liu     case 0x06: /* lf.rem.s */
1297bbe418f2SJia Liu         LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
12986597c28dSRichard Henderson         check_r0_write(rd);
1299bbe418f2SJia Liu         gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13004e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1301bbe418f2SJia Liu         break;
1302bbe418f2SJia Liu 
1303bbe418f2SJia Liu     case 0x07: /* lf.madd.s */
1304bbe418f2SJia Liu         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
13056597c28dSRichard Henderson         check_r0_write(rd);
1306762e22edSRichard Henderson         gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
1307762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
13084e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1309bbe418f2SJia Liu         break;
1310bbe418f2SJia Liu 
1311bbe418f2SJia Liu     case 0x08: /* lf.sfeq.s */
1312bbe418f2SJia Liu         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
131384775c43SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13144e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1315bbe418f2SJia Liu         break;
1316bbe418f2SJia Liu 
1317bbe418f2SJia Liu     case 0x09: /* lf.sfne.s */
1318bbe418f2SJia Liu         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
13194e2d3007SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13204e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
13214e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1322bbe418f2SJia Liu         break;
1323bbe418f2SJia Liu 
1324bbe418f2SJia Liu     case 0x0a: /* lf.sfgt.s */
1325bbe418f2SJia Liu         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
13264e2d3007SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13274e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1328bbe418f2SJia Liu         break;
1329bbe418f2SJia Liu 
1330bbe418f2SJia Liu     case 0x0b: /* lf.sfge.s */
1331bbe418f2SJia Liu         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
13324e2d3007SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13334e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1334bbe418f2SJia Liu         break;
1335bbe418f2SJia Liu 
1336bbe418f2SJia Liu     case 0x0c: /* lf.sflt.s */
1337bbe418f2SJia Liu         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
133884775c43SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13394e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1340bbe418f2SJia Liu         break;
1341bbe418f2SJia Liu 
1342bbe418f2SJia Liu     case 0x0d: /* lf.sfle.s */
1343bbe418f2SJia Liu         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
134484775c43SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13454e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1346bbe418f2SJia Liu         break;
1347bbe418f2SJia Liu 
13484e2d3007SRichard Henderson #ifdef TARGET_OPENRISC64
13494e2d3007SRichard Henderson     case 0x10: /* lf.add.d */
1350bbe418f2SJia Liu         LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1351bbe418f2SJia Liu         check_of64s(dc);
13526597c28dSRichard Henderson         check_r0_write(rd);
1353bbe418f2SJia Liu         gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13544e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1355bbe418f2SJia Liu         break;
1356bbe418f2SJia Liu 
13574e2d3007SRichard Henderson     case 0x11: /* lf.sub.d */
1358bbe418f2SJia Liu         LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1359bbe418f2SJia Liu         check_of64s(dc);
13606597c28dSRichard Henderson         check_r0_write(rd);
1361bbe418f2SJia Liu         gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13624e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1363bbe418f2SJia Liu         break;
1364bbe418f2SJia Liu 
13654e2d3007SRichard Henderson     case 0x12: /* lf.mul.d */
1366bbe418f2SJia Liu         LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1367bbe418f2SJia Liu         check_of64s(dc);
13686597c28dSRichard Henderson         check_r0_write(rd);
1369bbe418f2SJia Liu         gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13704e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1371bbe418f2SJia Liu         break;
1372bbe418f2SJia Liu 
13734e2d3007SRichard Henderson     case 0x13: /* lf.div.d */
1374bbe418f2SJia Liu         LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1375bbe418f2SJia Liu         check_of64s(dc);
13766597c28dSRichard Henderson         check_r0_write(rd);
1377bbe418f2SJia Liu         gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13784e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1379bbe418f2SJia Liu         break;
1380bbe418f2SJia Liu 
13814e2d3007SRichard Henderson     case 0x14: /* lf.itof.d */
1382bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1383bbe418f2SJia Liu         check_of64s(dc);
13846597c28dSRichard Henderson         check_r0_write(rd);
1385bbe418f2SJia Liu         gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
13864e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1387bbe418f2SJia Liu         break;
1388bbe418f2SJia Liu 
13894e2d3007SRichard Henderson     case 0x15: /* lf.ftoi.d */
1390bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1391bbe418f2SJia Liu         check_of64s(dc);
13926597c28dSRichard Henderson         check_r0_write(rd);
1393bbe418f2SJia Liu         gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
13944e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1395bbe418f2SJia Liu         break;
1396bbe418f2SJia Liu 
13974e2d3007SRichard Henderson     case 0x16: /* lf.rem.d */
1398bbe418f2SJia Liu         LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1399bbe418f2SJia Liu         check_of64s(dc);
14006597c28dSRichard Henderson         check_r0_write(rd);
1401bbe418f2SJia Liu         gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14024e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1403bbe418f2SJia Liu         break;
1404bbe418f2SJia Liu 
14054e2d3007SRichard Henderson     case 0x17: /* lf.madd.d */
1406bbe418f2SJia Liu         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1407bbe418f2SJia Liu         check_of64s(dc);
14086597c28dSRichard Henderson         check_r0_write(rd);
1409762e22edSRichard Henderson         gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
1410762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
14114e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1412bbe418f2SJia Liu         break;
1413bbe418f2SJia Liu 
14144e2d3007SRichard Henderson     case 0x18: /* lf.sfeq.d */
1415bbe418f2SJia Liu         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1416bbe418f2SJia Liu         check_of64s(dc);
141784775c43SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14184e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1419bbe418f2SJia Liu         break;
1420bbe418f2SJia Liu 
14214e2d3007SRichard Henderson     case 0x1a: /* lf.sfgt.d */
1422bbe418f2SJia Liu         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1423bbe418f2SJia Liu         check_of64s(dc);
14244e2d3007SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14254e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1426bbe418f2SJia Liu         break;
1427bbe418f2SJia Liu 
14284e2d3007SRichard Henderson     case 0x1b: /* lf.sfge.d */
1429bbe418f2SJia Liu         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1430bbe418f2SJia Liu         check_of64s(dc);
14314e2d3007SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14324e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1433bbe418f2SJia Liu         break;
1434bbe418f2SJia Liu 
14354e2d3007SRichard Henderson     case 0x19: /* lf.sfne.d */
1436bbe418f2SJia Liu         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1437bbe418f2SJia Liu         check_of64s(dc);
14384e2d3007SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14394e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
14404e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1441bbe418f2SJia Liu         break;
1442bbe418f2SJia Liu 
14434e2d3007SRichard Henderson     case 0x1c: /* lf.sflt.d */
1444bbe418f2SJia Liu         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1445bbe418f2SJia Liu         check_of64s(dc);
144684775c43SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14474e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1448bbe418f2SJia Liu         break;
1449bbe418f2SJia Liu 
14504e2d3007SRichard Henderson     case 0x1d: /* lf.sfle.d */
1451bbe418f2SJia Liu         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1452bbe418f2SJia Liu         check_of64s(dc);
145384775c43SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14544e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1455bbe418f2SJia Liu         break;
14564e2d3007SRichard Henderson #endif
1457bbe418f2SJia Liu 
1458bbe418f2SJia Liu     default:
1459bbe418f2SJia Liu         gen_illegal_exception(dc);
1460bbe418f2SJia Liu         break;
1461bbe418f2SJia Liu     }
1462bbe418f2SJia Liu }
1463bbe418f2SJia Liu 
1464bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1465bbe418f2SJia Liu {
1466bbe418f2SJia Liu     uint32_t op0;
14677de9729fSRichard Henderson     uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next);
1468bbe418f2SJia Liu 
14697de9729fSRichard Henderson     /* Transition to the auto-generated decoder.  */
14707de9729fSRichard Henderson     if (decode(dc, insn)) {
14717de9729fSRichard Henderson         return;
14727de9729fSRichard Henderson     }
14737de9729fSRichard Henderson 
14747de9729fSRichard Henderson     op0 = extract32(insn, 26, 6);
1475bbe418f2SJia Liu     switch (op0) {
1476bbe418f2SJia Liu     case 0x32:
1477bbe418f2SJia Liu         dec_float(dc, insn);
1478bbe418f2SJia Liu         break;
1479bbe418f2SJia Liu 
1480bbe418f2SJia Liu     default:
14818816f70bSRichard Henderson         gen_illegal_exception(dc);
1482bbe418f2SJia Liu         break;
1483bbe418f2SJia Liu     }
1484bbe418f2SJia Liu }
1485bbe418f2SJia Liu 
1486a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
1487e67db06eSJia Liu {
1488a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcb, DisasContext, base);
14899c489ea6SLluís Vilanova     CPUOpenRISCState *env = cs->env_ptr;
1490a4fd3ec3SEmilio G. Cota     int bound;
1491bbe418f2SJia Liu 
1492a4fd3ec3SEmilio G. Cota     dc->mem_idx = cpu_mmu_index(env, false);
14931ffa4bceSEmilio G. Cota     dc->tb_flags = dc->base.tb->flags;
1494a01deb36SRichard Henderson     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
1495a4fd3ec3SEmilio G. Cota     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
1496a4fd3ec3SEmilio G. Cota     dc->base.max_insns = MIN(dc->base.max_insns, bound);
1497190ce7fbSRichard Henderson }
1498bbe418f2SJia Liu 
1499a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
1500a4fd3ec3SEmilio G. Cota {
1501a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(db, DisasContext, base);
1502bbe418f2SJia Liu 
15036597c28dSRichard Henderson     /* Allow the TCG optimizer to see that R0 == 0,
15046597c28dSRichard Henderson        when it's true, which is the common case.  */
15056597c28dSRichard Henderson     if (dc->tb_flags & TB_FLAGS_R0_0) {
15066597c28dSRichard Henderson         cpu_R[0] = tcg_const_tl(0);
15076597c28dSRichard Henderson     } else {
15086597c28dSRichard Henderson         cpu_R[0] = cpu_R0;
15096597c28dSRichard Henderson     }
1510a4fd3ec3SEmilio G. Cota }
15116597c28dSRichard Henderson 
1512a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
1513a4fd3ec3SEmilio G. Cota {
1514a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1515a4fd3ec3SEmilio G. Cota 
15161ffa4bceSEmilio G. Cota     tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
1517a4fd3ec3SEmilio G. Cota                        | (dc->base.num_insns > 1 ? 2 : 0));
1518a4fd3ec3SEmilio G. Cota }
1519bbe418f2SJia Liu 
1520a4fd3ec3SEmilio G. Cota static bool openrisc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
1521a4fd3ec3SEmilio G. Cota                                          const CPUBreakpoint *bp)
1522a4fd3ec3SEmilio G. Cota {
1523a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1524a4fd3ec3SEmilio G. Cota 
15251ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1526b933066aSRichard Henderson     gen_exception(dc, EXCP_DEBUG);
15271ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
1528522a0d4eSRichard Henderson     /* The address covered by the breakpoint must be included in
1529522a0d4eSRichard Henderson        [tb->pc, tb->pc + tb->size) in order to for it to be
1530522a0d4eSRichard Henderson        properly cleared -- thus we increment the PC here so that
1531522a0d4eSRichard Henderson        the logic setting tb->size below does the right thing.  */
15321ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
1533a4fd3ec3SEmilio G. Cota     return true;
1534b933066aSRichard Henderson }
1535b933066aSRichard Henderson 
1536a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
1537a4fd3ec3SEmilio G. Cota {
1538a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1539a4fd3ec3SEmilio G. Cota     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1540a4fd3ec3SEmilio G. Cota 
1541bbe418f2SJia Liu     disas_openrisc_insn(dc, cpu);
15421ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
154324c32852SRichard Henderson 
1544bbe418f2SJia Liu     /* delay slot */
1545bbe418f2SJia Liu     if (dc->delayed_branch) {
1546bbe418f2SJia Liu         dc->delayed_branch--;
1547bbe418f2SJia Liu         if (!dc->delayed_branch) {
1548bbe418f2SJia Liu             tcg_gen_mov_tl(cpu_pc, jmp_pc);
154924c32852SRichard Henderson             tcg_gen_discard_tl(jmp_pc);
15501ffa4bceSEmilio G. Cota             dc->base.is_jmp = DISAS_UPDATE;
1551a4fd3ec3SEmilio G. Cota             return;
1552bbe418f2SJia Liu         }
1553bbe418f2SJia Liu     }
1554a4fd3ec3SEmilio G. Cota }
1555bbe418f2SJia Liu 
1556a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
1557a4fd3ec3SEmilio G. Cota {
1558a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
155924c32852SRichard Henderson 
1560a01deb36SRichard Henderson     if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
1561a01deb36SRichard Henderson         tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
1562a01deb36SRichard Henderson     }
1563a01deb36SRichard Henderson 
15641ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
15651ffa4bceSEmilio G. Cota     if (dc->base.is_jmp == DISAS_NEXT) {
15661ffa4bceSEmilio G. Cota         dc->base.is_jmp = DISAS_UPDATE;
15671ffa4bceSEmilio G. Cota         tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1568bbe418f2SJia Liu     }
15691ffa4bceSEmilio G. Cota     if (unlikely(dc->base.singlestep_enabled)) {
1570bbe418f2SJia Liu         gen_exception(dc, EXCP_DEBUG);
1571bbe418f2SJia Liu     } else {
15721ffa4bceSEmilio G. Cota         switch (dc->base.is_jmp) {
1573a4fd3ec3SEmilio G. Cota         case DISAS_TOO_MANY:
15741ffa4bceSEmilio G. Cota             gen_goto_tb(dc, 0, dc->base.pc_next);
1575bbe418f2SJia Liu             break;
15761ffa4bceSEmilio G. Cota         case DISAS_NORETURN:
1577bbe418f2SJia Liu         case DISAS_JUMP:
15781ffa4bceSEmilio G. Cota         case DISAS_TB_JUMP:
1579bbe418f2SJia Liu             break;
1580bbe418f2SJia Liu         case DISAS_UPDATE:
1581bbe418f2SJia Liu             /* indicate that the hash table must be used
1582bbe418f2SJia Liu                to find the next TB */
1583bbe418f2SJia Liu             tcg_gen_exit_tb(0);
1584bbe418f2SJia Liu             break;
1585a4fd3ec3SEmilio G. Cota         default:
1586a4fd3ec3SEmilio G. Cota             g_assert_not_reached();
1587a4fd3ec3SEmilio G. Cota         }
1588bbe418f2SJia Liu     }
1589bbe418f2SJia Liu }
1590bbe418f2SJia Liu 
1591a4fd3ec3SEmilio G. Cota static void openrisc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
1592a4fd3ec3SEmilio G. Cota {
1593a4fd3ec3SEmilio G. Cota     DisasContext *s = container_of(dcbase, DisasContext, base);
15940a7df5daSRichard Henderson 
1595a4fd3ec3SEmilio G. Cota     qemu_log("IN: %s\n", lookup_symbol(s->base.pc_first));
1596a4fd3ec3SEmilio G. Cota     log_target_disas(cs, s->base.pc_first, s->base.tb->size);
1597bbe418f2SJia Liu }
1598a4fd3ec3SEmilio G. Cota 
1599a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = {
1600a4fd3ec3SEmilio G. Cota     .init_disas_context = openrisc_tr_init_disas_context,
1601a4fd3ec3SEmilio G. Cota     .tb_start           = openrisc_tr_tb_start,
1602a4fd3ec3SEmilio G. Cota     .insn_start         = openrisc_tr_insn_start,
1603a4fd3ec3SEmilio G. Cota     .breakpoint_check   = openrisc_tr_breakpoint_check,
1604a4fd3ec3SEmilio G. Cota     .translate_insn     = openrisc_tr_translate_insn,
1605a4fd3ec3SEmilio G. Cota     .tb_stop            = openrisc_tr_tb_stop,
1606a4fd3ec3SEmilio G. Cota     .disas_log          = openrisc_tr_disas_log,
1607a4fd3ec3SEmilio G. Cota };
1608a4fd3ec3SEmilio G. Cota 
1609a4fd3ec3SEmilio G. Cota void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
1610a4fd3ec3SEmilio G. Cota {
1611a4fd3ec3SEmilio G. Cota     DisasContext ctx;
1612a4fd3ec3SEmilio G. Cota 
1613a4fd3ec3SEmilio G. Cota     translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb);
1614e67db06eSJia Liu }
1615e67db06eSJia Liu 
1616878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
1617e67db06eSJia Liu                              fprintf_function cpu_fprintf,
1618e67db06eSJia Liu                              int flags)
1619e67db06eSJia Liu {
1620878096eeSAndreas Färber     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1621878096eeSAndreas Färber     CPUOpenRISCState *env = &cpu->env;
1622e67db06eSJia Liu     int i;
1623878096eeSAndreas Färber 
1624e67db06eSJia Liu     cpu_fprintf(f, "PC=%08x\n", env->pc);
1625e67db06eSJia Liu     for (i = 0; i < 32; ++i) {
1626d89e71e8SStafford Horne         cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
1627e67db06eSJia Liu                     (i % 4) == 3 ? '\n' : ' ');
1628e67db06eSJia Liu     }
1629e67db06eSJia Liu }
1630e67db06eSJia Liu 
1631e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
1632bad729e2SRichard Henderson                           target_ulong *data)
1633e67db06eSJia Liu {
1634bad729e2SRichard Henderson     env->pc = data[0];
1635a01deb36SRichard Henderson     env->dflag = data[1] & 1;
1636a01deb36SRichard Henderson     if (data[1] & 2) {
163724c32852SRichard Henderson         env->ppc = env->pc - 4;
163824c32852SRichard Henderson     }
1639e67db06eSJia Liu }
1640