xref: /qemu/target/openrisc/translate.c (revision fbb3e29aace97a3c51c7ed434dfa799e7ba7f652)
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 
1050*fbb3e29aSRichard Henderson static bool trans_l_sfeq(DisasContext *dc, arg_ab *a, TCGCond cond)
1051bbe418f2SJia Liu {
1052*fbb3e29aSRichard Henderson     LOG_DIS("l.sfeq r%d, r%d\n", a->a, a->b);
1053*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1054*fbb3e29aSRichard Henderson     return true;
1055bbe418f2SJia Liu }
1056*fbb3e29aSRichard Henderson 
1057*fbb3e29aSRichard Henderson static bool trans_l_sfne(DisasContext *dc, arg_ab *a, TCGCond cond)
1058*fbb3e29aSRichard Henderson {
1059*fbb3e29aSRichard Henderson     LOG_DIS("l.sfne r%d, r%d\n", a->a, a->b);
1060*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1061*fbb3e29aSRichard Henderson     return true;
1062*fbb3e29aSRichard Henderson }
1063*fbb3e29aSRichard Henderson 
1064*fbb3e29aSRichard Henderson static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a, TCGCond cond)
1065*fbb3e29aSRichard Henderson {
1066*fbb3e29aSRichard Henderson     LOG_DIS("l.sfgtu r%d, r%d\n", a->a, a->b);
1067*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1068*fbb3e29aSRichard Henderson     return true;
1069*fbb3e29aSRichard Henderson }
1070*fbb3e29aSRichard Henderson 
1071*fbb3e29aSRichard Henderson static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a, TCGCond cond)
1072*fbb3e29aSRichard Henderson {
1073*fbb3e29aSRichard Henderson     LOG_DIS("l.sfgeu r%d, r%d\n", a->a, a->b);
1074*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1075*fbb3e29aSRichard Henderson     return true;
1076*fbb3e29aSRichard Henderson }
1077*fbb3e29aSRichard Henderson 
1078*fbb3e29aSRichard Henderson static bool trans_l_sfltu(DisasContext *dc, arg_ab *a, TCGCond cond)
1079*fbb3e29aSRichard Henderson {
1080*fbb3e29aSRichard Henderson     LOG_DIS("l.sfltu r%d, r%d\n", a->a, a->b);
1081*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1082*fbb3e29aSRichard Henderson     return true;
1083*fbb3e29aSRichard Henderson }
1084*fbb3e29aSRichard Henderson 
1085*fbb3e29aSRichard Henderson static bool trans_l_sfleu(DisasContext *dc, arg_ab *a, TCGCond cond)
1086*fbb3e29aSRichard Henderson {
1087*fbb3e29aSRichard Henderson     LOG_DIS("l.sfleu r%d, r%d\n", a->a, a->b);
1088*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1089*fbb3e29aSRichard Henderson     return true;
1090*fbb3e29aSRichard Henderson }
1091*fbb3e29aSRichard Henderson 
1092*fbb3e29aSRichard Henderson static bool trans_l_sfgts(DisasContext *dc, arg_ab *a, TCGCond cond)
1093*fbb3e29aSRichard Henderson {
1094*fbb3e29aSRichard Henderson     LOG_DIS("l.sfgts r%d, r%d\n", a->a, a->b);
1095*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1096*fbb3e29aSRichard Henderson     return true;
1097*fbb3e29aSRichard Henderson }
1098*fbb3e29aSRichard Henderson 
1099*fbb3e29aSRichard Henderson static bool trans_l_sfges(DisasContext *dc, arg_ab *a, TCGCond cond)
1100*fbb3e29aSRichard Henderson {
1101*fbb3e29aSRichard Henderson     LOG_DIS("l.sfges r%d, r%d\n", a->a, a->b);
1102*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1103*fbb3e29aSRichard Henderson     return true;
1104*fbb3e29aSRichard Henderson }
1105*fbb3e29aSRichard Henderson 
1106*fbb3e29aSRichard Henderson static bool trans_l_sflts(DisasContext *dc, arg_ab *a, TCGCond cond)
1107*fbb3e29aSRichard Henderson {
1108*fbb3e29aSRichard Henderson     LOG_DIS("l.sflts r%d, r%d\n", a->a, a->b);
1109*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1110*fbb3e29aSRichard Henderson     return true;
1111*fbb3e29aSRichard Henderson }
1112*fbb3e29aSRichard Henderson 
1113*fbb3e29aSRichard Henderson static bool trans_l_sfles(DisasContext *dc, arg_ab *a, TCGCond cond)
1114*fbb3e29aSRichard Henderson {
1115*fbb3e29aSRichard Henderson     LOG_DIS("l.sfles r%d, r%d\n", a->a, a->b);
1116*fbb3e29aSRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
1117*fbb3e29aSRichard Henderson     return true;
1118bbe418f2SJia Liu }
1119bbe418f2SJia Liu 
1120bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn)
1121bbe418f2SJia Liu {
11226da544a6SRichard Henderson     uint32_t op0, ra;
11236da544a6SRichard Henderson     int32_t I16;
1124bbe418f2SJia Liu 
1125bbe418f2SJia Liu     op0 = extract32(insn, 21, 5);
1126bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
11276da544a6SRichard Henderson     I16 = sextract32(insn, 0, 16);
1128bbe418f2SJia Liu 
1129bbe418f2SJia Liu     switch (op0) {
1130bbe418f2SJia Liu     case 0x0:    /* l.sfeqi */
1131bbe418f2SJia Liu         LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
113284775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
1133bbe418f2SJia Liu         break;
1134bbe418f2SJia Liu 
1135bbe418f2SJia Liu     case 0x1:    /* l.sfnei */
1136bbe418f2SJia Liu         LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
113784775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
1138bbe418f2SJia Liu         break;
1139bbe418f2SJia Liu 
1140bbe418f2SJia Liu     case 0x2:    /* l.sfgtui */
1141bbe418f2SJia Liu         LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
114284775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
1143bbe418f2SJia Liu         break;
1144bbe418f2SJia Liu 
1145bbe418f2SJia Liu     case 0x3:    /* l.sfgeui */
1146bbe418f2SJia Liu         LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
114784775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
1148bbe418f2SJia Liu         break;
1149bbe418f2SJia Liu 
1150bbe418f2SJia Liu     case 0x4:    /* l.sfltui */
1151bbe418f2SJia Liu         LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
115284775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
1153bbe418f2SJia Liu         break;
1154bbe418f2SJia Liu 
1155bbe418f2SJia Liu     case 0x5:    /* l.sfleui */
1156bbe418f2SJia Liu         LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
115784775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
1158bbe418f2SJia Liu         break;
1159bbe418f2SJia Liu 
1160bbe418f2SJia Liu     case 0xa:    /* l.sfgtsi */
1161bbe418f2SJia Liu         LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
116284775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
1163bbe418f2SJia Liu         break;
1164bbe418f2SJia Liu 
1165bbe418f2SJia Liu     case 0xb:    /* l.sfgesi */
1166bbe418f2SJia Liu         LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
116784775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
1168bbe418f2SJia Liu         break;
1169bbe418f2SJia Liu 
1170bbe418f2SJia Liu     case 0xc:    /* l.sfltsi */
1171bbe418f2SJia Liu         LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
117284775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
1173bbe418f2SJia Liu         break;
1174bbe418f2SJia Liu 
1175bbe418f2SJia Liu     case 0xd:    /* l.sflesi */
1176bbe418f2SJia Liu         LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
117784775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
1178bbe418f2SJia Liu         break;
1179bbe418f2SJia Liu 
1180bbe418f2SJia Liu     default:
1181bbe418f2SJia Liu         gen_illegal_exception(dc);
1182bbe418f2SJia Liu         break;
1183bbe418f2SJia Liu     }
1184bbe418f2SJia Liu }
1185bbe418f2SJia Liu 
11867de9729fSRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
1187bbe418f2SJia Liu {
11887de9729fSRichard Henderson     LOG_DIS("l.sys %d\n", a->k);
11891ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1190bbe418f2SJia Liu     gen_exception(dc, EXCP_SYSCALL);
11911ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
11927de9729fSRichard Henderson     return true;
11937de9729fSRichard Henderson }
1194bbe418f2SJia Liu 
11957de9729fSRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
11967de9729fSRichard Henderson {
11977de9729fSRichard Henderson     LOG_DIS("l.trap %d\n", a->k);
11981ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1199bbe418f2SJia Liu     gen_exception(dc, EXCP_TRAP);
12001ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
12017de9729fSRichard Henderson     return true;
12027de9729fSRichard Henderson }
1203bbe418f2SJia Liu 
12047de9729fSRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
12057de9729fSRichard Henderson {
1206bbe418f2SJia Liu     LOG_DIS("l.msync\n");
120724fc5c0fSRichard Henderson     tcg_gen_mb(TCG_MO_ALL);
12087de9729fSRichard Henderson     return true;
1209bbe418f2SJia Liu }
12107de9729fSRichard Henderson 
12117de9729fSRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
12127de9729fSRichard Henderson {
12137de9729fSRichard Henderson     LOG_DIS("l.psync\n");
12147de9729fSRichard Henderson     return true;
12157de9729fSRichard Henderson }
12167de9729fSRichard Henderson 
12177de9729fSRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
12187de9729fSRichard Henderson {
12197de9729fSRichard Henderson     LOG_DIS("l.csync\n");
12207de9729fSRichard Henderson     return true;
1221bbe418f2SJia Liu }
1222bbe418f2SJia Liu 
12238816f70bSRichard Henderson static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a, uint32_t insn)
12248816f70bSRichard Henderson {
12258816f70bSRichard Henderson     LOG_DIS("l.rfe\n");
12268816f70bSRichard Henderson 
12278816f70bSRichard Henderson #ifdef CONFIG_USER_ONLY
12288816f70bSRichard Henderson     gen_illegal_exception(dc);
12298816f70bSRichard Henderson #else
12308816f70bSRichard Henderson     if (dc->mem_idx == MMU_USER_IDX) {
12318816f70bSRichard Henderson         gen_illegal_exception(dc);
12328816f70bSRichard Henderson     } else {
12338816f70bSRichard Henderson         gen_helper_rfe(cpu_env);
12348816f70bSRichard Henderson         dc->base.is_jmp = DISAS_UPDATE;
12358816f70bSRichard Henderson     }
12368816f70bSRichard Henderson #endif
12378816f70bSRichard Henderson     return true;
12388816f70bSRichard Henderson }
12398816f70bSRichard Henderson 
1240bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn)
1241bbe418f2SJia Liu {
1242bbe418f2SJia Liu     uint32_t op0;
1243bbe418f2SJia Liu     uint32_t ra, rb, rd;
1244bbe418f2SJia Liu     op0 = extract32(insn, 0, 8);
1245bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1246bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1247bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1248bbe418f2SJia Liu 
1249bbe418f2SJia Liu     switch (op0) {
1250bbe418f2SJia Liu     case 0x00: /* lf.add.s */
1251bbe418f2SJia Liu         LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
12526597c28dSRichard Henderson         check_r0_write(rd);
1253bbe418f2SJia Liu         gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12544e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1255bbe418f2SJia Liu         break;
1256bbe418f2SJia Liu 
1257bbe418f2SJia Liu     case 0x01: /* lf.sub.s */
1258bbe418f2SJia Liu         LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
12596597c28dSRichard Henderson         check_r0_write(rd);
1260bbe418f2SJia Liu         gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12614e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1262bbe418f2SJia Liu         break;
1263bbe418f2SJia Liu 
1264bbe418f2SJia Liu     case 0x02:    /* lf.mul.s */
1265bbe418f2SJia Liu         LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
12666597c28dSRichard Henderson         check_r0_write(rd);
1267bbe418f2SJia Liu         gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12684e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1269bbe418f2SJia Liu         break;
1270bbe418f2SJia Liu 
1271bbe418f2SJia Liu     case 0x03: /* lf.div.s */
1272bbe418f2SJia Liu         LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
12736597c28dSRichard Henderson         check_r0_write(rd);
1274bbe418f2SJia Liu         gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12754e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1276bbe418f2SJia Liu         break;
1277bbe418f2SJia Liu 
1278bbe418f2SJia Liu     case 0x04: /* lf.itof.s */
1279bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
12806597c28dSRichard Henderson         check_r0_write(rd);
1281bbe418f2SJia Liu         gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
12824e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1283bbe418f2SJia Liu         break;
1284bbe418f2SJia Liu 
1285bbe418f2SJia Liu     case 0x05: /* lf.ftoi.s */
1286bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
12876597c28dSRichard Henderson         check_r0_write(rd);
1288bbe418f2SJia Liu         gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
12894e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1290bbe418f2SJia Liu         break;
1291bbe418f2SJia Liu 
1292bbe418f2SJia Liu     case 0x06: /* lf.rem.s */
1293bbe418f2SJia Liu         LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
12946597c28dSRichard Henderson         check_r0_write(rd);
1295bbe418f2SJia Liu         gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12964e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1297bbe418f2SJia Liu         break;
1298bbe418f2SJia Liu 
1299bbe418f2SJia Liu     case 0x07: /* lf.madd.s */
1300bbe418f2SJia Liu         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
13016597c28dSRichard Henderson         check_r0_write(rd);
1302762e22edSRichard Henderson         gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
1303762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
13044e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1305bbe418f2SJia Liu         break;
1306bbe418f2SJia Liu 
1307bbe418f2SJia Liu     case 0x08: /* lf.sfeq.s */
1308bbe418f2SJia Liu         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
130984775c43SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13104e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1311bbe418f2SJia Liu         break;
1312bbe418f2SJia Liu 
1313bbe418f2SJia Liu     case 0x09: /* lf.sfne.s */
1314bbe418f2SJia Liu         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
13154e2d3007SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13164e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
13174e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1318bbe418f2SJia Liu         break;
1319bbe418f2SJia Liu 
1320bbe418f2SJia Liu     case 0x0a: /* lf.sfgt.s */
1321bbe418f2SJia Liu         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
13224e2d3007SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13234e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1324bbe418f2SJia Liu         break;
1325bbe418f2SJia Liu 
1326bbe418f2SJia Liu     case 0x0b: /* lf.sfge.s */
1327bbe418f2SJia Liu         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
13284e2d3007SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13294e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1330bbe418f2SJia Liu         break;
1331bbe418f2SJia Liu 
1332bbe418f2SJia Liu     case 0x0c: /* lf.sflt.s */
1333bbe418f2SJia Liu         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
133484775c43SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13354e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1336bbe418f2SJia Liu         break;
1337bbe418f2SJia Liu 
1338bbe418f2SJia Liu     case 0x0d: /* lf.sfle.s */
1339bbe418f2SJia Liu         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
134084775c43SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13414e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1342bbe418f2SJia Liu         break;
1343bbe418f2SJia Liu 
13444e2d3007SRichard Henderson #ifdef TARGET_OPENRISC64
13454e2d3007SRichard Henderson     case 0x10: /* lf.add.d */
1346bbe418f2SJia Liu         LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1347bbe418f2SJia Liu         check_of64s(dc);
13486597c28dSRichard Henderson         check_r0_write(rd);
1349bbe418f2SJia Liu         gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13504e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1351bbe418f2SJia Liu         break;
1352bbe418f2SJia Liu 
13534e2d3007SRichard Henderson     case 0x11: /* lf.sub.d */
1354bbe418f2SJia Liu         LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1355bbe418f2SJia Liu         check_of64s(dc);
13566597c28dSRichard Henderson         check_r0_write(rd);
1357bbe418f2SJia Liu         gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13584e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1359bbe418f2SJia Liu         break;
1360bbe418f2SJia Liu 
13614e2d3007SRichard Henderson     case 0x12: /* lf.mul.d */
1362bbe418f2SJia Liu         LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1363bbe418f2SJia Liu         check_of64s(dc);
13646597c28dSRichard Henderson         check_r0_write(rd);
1365bbe418f2SJia Liu         gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13664e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1367bbe418f2SJia Liu         break;
1368bbe418f2SJia Liu 
13694e2d3007SRichard Henderson     case 0x13: /* lf.div.d */
1370bbe418f2SJia Liu         LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1371bbe418f2SJia Liu         check_of64s(dc);
13726597c28dSRichard Henderson         check_r0_write(rd);
1373bbe418f2SJia Liu         gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13744e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1375bbe418f2SJia Liu         break;
1376bbe418f2SJia Liu 
13774e2d3007SRichard Henderson     case 0x14: /* lf.itof.d */
1378bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1379bbe418f2SJia Liu         check_of64s(dc);
13806597c28dSRichard Henderson         check_r0_write(rd);
1381bbe418f2SJia Liu         gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
13824e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1383bbe418f2SJia Liu         break;
1384bbe418f2SJia Liu 
13854e2d3007SRichard Henderson     case 0x15: /* lf.ftoi.d */
1386bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1387bbe418f2SJia Liu         check_of64s(dc);
13886597c28dSRichard Henderson         check_r0_write(rd);
1389bbe418f2SJia Liu         gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
13904e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1391bbe418f2SJia Liu         break;
1392bbe418f2SJia Liu 
13934e2d3007SRichard Henderson     case 0x16: /* lf.rem.d */
1394bbe418f2SJia Liu         LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1395bbe418f2SJia Liu         check_of64s(dc);
13966597c28dSRichard Henderson         check_r0_write(rd);
1397bbe418f2SJia Liu         gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13984e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1399bbe418f2SJia Liu         break;
1400bbe418f2SJia Liu 
14014e2d3007SRichard Henderson     case 0x17: /* lf.madd.d */
1402bbe418f2SJia Liu         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1403bbe418f2SJia Liu         check_of64s(dc);
14046597c28dSRichard Henderson         check_r0_write(rd);
1405762e22edSRichard Henderson         gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
1406762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
14074e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1408bbe418f2SJia Liu         break;
1409bbe418f2SJia Liu 
14104e2d3007SRichard Henderson     case 0x18: /* lf.sfeq.d */
1411bbe418f2SJia Liu         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1412bbe418f2SJia Liu         check_of64s(dc);
141384775c43SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14144e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1415bbe418f2SJia Liu         break;
1416bbe418f2SJia Liu 
14174e2d3007SRichard Henderson     case 0x1a: /* lf.sfgt.d */
1418bbe418f2SJia Liu         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1419bbe418f2SJia Liu         check_of64s(dc);
14204e2d3007SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14214e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1422bbe418f2SJia Liu         break;
1423bbe418f2SJia Liu 
14244e2d3007SRichard Henderson     case 0x1b: /* lf.sfge.d */
1425bbe418f2SJia Liu         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1426bbe418f2SJia Liu         check_of64s(dc);
14274e2d3007SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14284e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1429bbe418f2SJia Liu         break;
1430bbe418f2SJia Liu 
14314e2d3007SRichard Henderson     case 0x19: /* lf.sfne.d */
1432bbe418f2SJia Liu         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1433bbe418f2SJia Liu         check_of64s(dc);
14344e2d3007SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14354e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
14364e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1437bbe418f2SJia Liu         break;
1438bbe418f2SJia Liu 
14394e2d3007SRichard Henderson     case 0x1c: /* lf.sflt.d */
1440bbe418f2SJia Liu         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1441bbe418f2SJia Liu         check_of64s(dc);
144284775c43SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14434e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1444bbe418f2SJia Liu         break;
1445bbe418f2SJia Liu 
14464e2d3007SRichard Henderson     case 0x1d: /* lf.sfle.d */
1447bbe418f2SJia Liu         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1448bbe418f2SJia Liu         check_of64s(dc);
144984775c43SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14504e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1451bbe418f2SJia Liu         break;
14524e2d3007SRichard Henderson #endif
1453bbe418f2SJia Liu 
1454bbe418f2SJia Liu     default:
1455bbe418f2SJia Liu         gen_illegal_exception(dc);
1456bbe418f2SJia Liu         break;
1457bbe418f2SJia Liu     }
1458bbe418f2SJia Liu }
1459bbe418f2SJia Liu 
1460bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1461bbe418f2SJia Liu {
1462bbe418f2SJia Liu     uint32_t op0;
14637de9729fSRichard Henderson     uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next);
1464bbe418f2SJia Liu 
14657de9729fSRichard Henderson     /* Transition to the auto-generated decoder.  */
14667de9729fSRichard Henderson     if (decode(dc, insn)) {
14677de9729fSRichard Henderson         return;
14687de9729fSRichard Henderson     }
14697de9729fSRichard Henderson 
14707de9729fSRichard Henderson     op0 = extract32(insn, 26, 6);
1471bbe418f2SJia Liu     switch (op0) {
1472bbe418f2SJia Liu     case 0x2f:
1473bbe418f2SJia Liu         dec_compi(dc, insn);
1474bbe418f2SJia Liu         break;
1475bbe418f2SJia Liu 
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