xref: /qemu/target/openrisc/translate.c (revision d80bff19f9c6dbde11e8c246e245dff77ae8ac94)
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 
458bbe418f2SJia Liu static void dec_calc(DisasContext *dc, uint32_t insn)
459bbe418f2SJia Liu {
460bbe418f2SJia Liu     uint32_t op0, op1, op2;
461bbe418f2SJia Liu     uint32_t ra, rb, rd;
462bbe418f2SJia Liu     op0 = extract32(insn, 0, 4);
463bbe418f2SJia Liu     op1 = extract32(insn, 8, 2);
464bbe418f2SJia Liu     op2 = extract32(insn, 6, 2);
465bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
466bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
467bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
468bbe418f2SJia Liu 
469bbe418f2SJia Liu     switch (op1) {
470cf2ae442SRichard Henderson     case 0:
471cf2ae442SRichard Henderson         switch (op0) {
472cf2ae442SRichard Henderson         case 0x0: /* l.add */
473bbe418f2SJia Liu             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
4749ecaa27eSRichard Henderson             gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
475cf2ae442SRichard Henderson             return;
476bbe418f2SJia Liu 
477cf2ae442SRichard Henderson         case 0x1: /* l.addc */
478bbe418f2SJia Liu             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
4799ecaa27eSRichard Henderson             gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
480cf2ae442SRichard Henderson             return;
481bbe418f2SJia Liu 
482cf2ae442SRichard Henderson         case 0x2: /* l.sub */
483bbe418f2SJia Liu             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
4849ecaa27eSRichard Henderson             gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
485cf2ae442SRichard Henderson             return;
486bbe418f2SJia Liu 
487cf2ae442SRichard Henderson         case 0x3: /* l.and */
488bbe418f2SJia Liu             LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
489bbe418f2SJia Liu             tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
490cf2ae442SRichard Henderson             return;
491bbe418f2SJia Liu 
492cf2ae442SRichard Henderson         case 0x4: /* l.or */
493bbe418f2SJia Liu             LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
494bbe418f2SJia Liu             tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
495cf2ae442SRichard Henderson             return;
496bbe418f2SJia Liu 
497cf2ae442SRichard Henderson         case 0x5: /* l.xor */
498bbe418f2SJia Liu             LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
499bbe418f2SJia Liu             tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
500cf2ae442SRichard Henderson             return;
501cf2ae442SRichard Henderson 
502cf2ae442SRichard Henderson         case 0x8:
503cf2ae442SRichard Henderson             switch (op2) {
504cf2ae442SRichard Henderson             case 0: /* l.sll */
505cf2ae442SRichard Henderson                 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
506cf2ae442SRichard Henderson                 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
507cf2ae442SRichard Henderson                 return;
508cf2ae442SRichard Henderson             case 1: /* l.srl */
509cf2ae442SRichard Henderson                 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
510cf2ae442SRichard Henderson                 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
511cf2ae442SRichard Henderson                 return;
512cf2ae442SRichard Henderson             case 2: /* l.sra */
513cf2ae442SRichard Henderson                 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
514cf2ae442SRichard Henderson                 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
515cf2ae442SRichard Henderson                 return;
516cf2ae442SRichard Henderson             case 3: /* l.ror */
517cf2ae442SRichard Henderson                 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
518cf2ae442SRichard Henderson                 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
519cf2ae442SRichard Henderson                 return;
520bbe418f2SJia Liu             }
521bbe418f2SJia Liu             break;
522bbe418f2SJia Liu 
523cf2ae442SRichard Henderson         case 0xc:
524cf2ae442SRichard Henderson             switch (op2) {
525cf2ae442SRichard Henderson             case 0: /* l.exths */
526cf2ae442SRichard Henderson                 LOG_DIS("l.exths r%d, r%d\n", rd, ra);
527cf2ae442SRichard Henderson                 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
528cf2ae442SRichard Henderson                 return;
529cf2ae442SRichard Henderson             case 1: /* l.extbs */
530cf2ae442SRichard Henderson                 LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
531cf2ae442SRichard Henderson                 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
532cf2ae442SRichard Henderson                 return;
533cf2ae442SRichard Henderson             case 2: /* l.exthz */
534cf2ae442SRichard Henderson                 LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
535cf2ae442SRichard Henderson                 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
536cf2ae442SRichard Henderson                 return;
537cf2ae442SRichard Henderson             case 3: /* l.extbz */
538cf2ae442SRichard Henderson                 LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
539cf2ae442SRichard Henderson                 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
540cf2ae442SRichard Henderson                 return;
541bbe418f2SJia Liu             }
542bbe418f2SJia Liu             break;
543bbe418f2SJia Liu 
544cf2ae442SRichard Henderson         case 0xd:
545cf2ae442SRichard Henderson             switch (op2) {
546cf2ae442SRichard Henderson             case 0: /* l.extws */
547cf2ae442SRichard Henderson                 LOG_DIS("l.extws r%d, r%d\n", rd, ra);
548cf2ae442SRichard Henderson                 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
549cf2ae442SRichard Henderson                 return;
550cf2ae442SRichard Henderson             case 1: /* l.extwz */
551cf2ae442SRichard Henderson                 LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
552cf2ae442SRichard Henderson                 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
553cf2ae442SRichard Henderson                 return;
554bbe418f2SJia Liu             }
555bbe418f2SJia Liu             break;
556bbe418f2SJia Liu 
557cf2ae442SRichard Henderson         case 0xe: /* l.cmov */
558bbe418f2SJia Liu             LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
559bbe418f2SJia Liu             {
560784696d1SRichard Henderson                 TCGv zero = tcg_const_tl(0);
561784696d1SRichard Henderson                 tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero,
562784696d1SRichard Henderson                                    cpu_R[ra], cpu_R[rb]);
563784696d1SRichard Henderson                 tcg_temp_free(zero);
564bbe418f2SJia Liu             }
565cf2ae442SRichard Henderson             return;
566bbe418f2SJia Liu 
567cf2ae442SRichard Henderson         case 0xf: /* l.ff1 */
568bbe418f2SJia Liu             LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
569555baef8SRichard Henderson             tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);
570555baef8SRichard Henderson             tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);
571cf2ae442SRichard Henderson             return;
572cf2ae442SRichard Henderson         }
573bbe418f2SJia Liu         break;
574cf2ae442SRichard Henderson 
575cf2ae442SRichard Henderson     case 1:
576cf2ae442SRichard Henderson         switch (op0) {
577cf2ae442SRichard Henderson         case 0xf: /* l.fl1 */
578bbe418f2SJia Liu             LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
579555baef8SRichard Henderson             tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);
580555baef8SRichard Henderson             tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);
581cf2ae442SRichard Henderson             return;
582bbe418f2SJia Liu         }
583bbe418f2SJia Liu         break;
584bbe418f2SJia Liu 
585cf2ae442SRichard Henderson     case 2:
586bbe418f2SJia Liu         break;
587bbe418f2SJia Liu 
588cf2ae442SRichard Henderson     case 3:
589cf2ae442SRichard Henderson         switch (op0) {
590cf2ae442SRichard Henderson         case 0x6: /* l.mul */
591cf2ae442SRichard Henderson             LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
592cf2ae442SRichard Henderson             gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
593cf2ae442SRichard Henderson             return;
594cf2ae442SRichard Henderson 
595cc5de49eSRichard Henderson         case 0x7: /* l.muld */
596cc5de49eSRichard Henderson             LOG_DIS("l.muld r%d, r%d\n", ra, rb);
597cc5de49eSRichard Henderson             gen_muld(dc, cpu_R[ra], cpu_R[rb]);
598cc5de49eSRichard Henderson             break;
599cc5de49eSRichard Henderson 
600cf2ae442SRichard Henderson         case 0x9: /* l.div */
601cf2ae442SRichard Henderson             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
602cf2ae442SRichard Henderson             gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
603cf2ae442SRichard Henderson             return;
604cf2ae442SRichard Henderson 
605cf2ae442SRichard Henderson         case 0xa: /* l.divu */
606cf2ae442SRichard Henderson             LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
607cf2ae442SRichard Henderson             gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
608cf2ae442SRichard Henderson             return;
609cf2ae442SRichard Henderson 
610cf2ae442SRichard Henderson         case 0xb: /* l.mulu */
611cf2ae442SRichard Henderson             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
612cf2ae442SRichard Henderson             gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
613cf2ae442SRichard Henderson             return;
614cc5de49eSRichard Henderson 
615cc5de49eSRichard Henderson         case 0xc: /* l.muldu */
616cc5de49eSRichard Henderson             LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
617cc5de49eSRichard Henderson             gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
618cc5de49eSRichard Henderson             return;
619bbe418f2SJia Liu         }
620bbe418f2SJia Liu         break;
621bbe418f2SJia Liu     }
622bbe418f2SJia Liu     gen_illegal_exception(dc);
623bbe418f2SJia Liu }
624bbe418f2SJia Liu 
625136e13aeSRichard Henderson static bool trans_l_j(DisasContext *dc, arg_l_j *a, uint32_t insn)
626136e13aeSRichard Henderson {
627136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
628136e13aeSRichard Henderson 
629136e13aeSRichard Henderson     LOG_DIS("l.j %d\n", a->n);
630136e13aeSRichard Henderson     tcg_gen_movi_tl(jmp_pc, tmp_pc);
631136e13aeSRichard Henderson     dc->delayed_branch = 2;
632136e13aeSRichard Henderson     return true;
633136e13aeSRichard Henderson }
634136e13aeSRichard Henderson 
635136e13aeSRichard Henderson static bool trans_l_jal(DisasContext *dc, arg_l_jal *a, uint32_t insn)
636136e13aeSRichard Henderson {
637136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
638136e13aeSRichard Henderson     target_ulong ret_pc = dc->base.pc_next + 8;
639136e13aeSRichard Henderson 
640136e13aeSRichard Henderson     LOG_DIS("l.jal %d\n", a->n);
641136e13aeSRichard Henderson     tcg_gen_movi_tl(cpu_R[9], ret_pc);
642136e13aeSRichard Henderson     /* Optimize jal being used to load the PC for PIC.  */
643136e13aeSRichard Henderson     if (tmp_pc != ret_pc) {
644136e13aeSRichard Henderson         tcg_gen_movi_tl(jmp_pc, tmp_pc);
645136e13aeSRichard Henderson         dc->delayed_branch = 2;
646136e13aeSRichard Henderson     }
647136e13aeSRichard Henderson     return true;
648136e13aeSRichard Henderson }
649136e13aeSRichard Henderson 
650136e13aeSRichard Henderson static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
651136e13aeSRichard Henderson {
652136e13aeSRichard Henderson     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
653136e13aeSRichard Henderson     TCGv t_next = tcg_const_tl(dc->base.pc_next + 8);
654136e13aeSRichard Henderson     TCGv t_true = tcg_const_tl(tmp_pc);
655136e13aeSRichard Henderson     TCGv t_zero = tcg_const_tl(0);
656136e13aeSRichard Henderson 
657136e13aeSRichard Henderson     tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
658136e13aeSRichard Henderson 
659136e13aeSRichard Henderson     tcg_temp_free(t_next);
660136e13aeSRichard Henderson     tcg_temp_free(t_true);
661136e13aeSRichard Henderson     tcg_temp_free(t_zero);
662136e13aeSRichard Henderson     dc->delayed_branch = 2;
663136e13aeSRichard Henderson }
664136e13aeSRichard Henderson 
665136e13aeSRichard Henderson static bool trans_l_bf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
666136e13aeSRichard Henderson {
667136e13aeSRichard Henderson     LOG_DIS("l.bf %d\n", a->n);
668136e13aeSRichard Henderson     do_bf(dc, a, TCG_COND_NE);
669136e13aeSRichard Henderson     return true;
670136e13aeSRichard Henderson }
671136e13aeSRichard Henderson 
672136e13aeSRichard Henderson static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a, uint32_t insn)
673136e13aeSRichard Henderson {
674136e13aeSRichard Henderson     LOG_DIS("l.bnf %d\n", a->n);
675136e13aeSRichard Henderson     do_bf(dc, a, TCG_COND_EQ);
676136e13aeSRichard Henderson     return true;
677136e13aeSRichard Henderson }
678136e13aeSRichard Henderson 
679136e13aeSRichard Henderson static bool trans_l_jr(DisasContext *dc, arg_l_jr *a, uint32_t insn)
680136e13aeSRichard Henderson {
681136e13aeSRichard Henderson     LOG_DIS("l.jr r%d\n", a->b);
682136e13aeSRichard Henderson     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
683136e13aeSRichard Henderson     dc->delayed_branch = 2;
684136e13aeSRichard Henderson     return true;
685136e13aeSRichard Henderson }
686136e13aeSRichard Henderson 
687136e13aeSRichard Henderson static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a, uint32_t insn)
688136e13aeSRichard Henderson {
689136e13aeSRichard Henderson     LOG_DIS("l.jalr r%d\n", a->b);
690136e13aeSRichard Henderson     tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
691136e13aeSRichard Henderson     tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
692136e13aeSRichard Henderson     dc->delayed_branch = 2;
693136e13aeSRichard Henderson     return true;
694136e13aeSRichard Henderson }
695136e13aeSRichard Henderson 
696*d80bff19SRichard Henderson static bool trans_l_lwa(DisasContext *dc, arg_load *a, uint32_t insn)
697*d80bff19SRichard Henderson {
698*d80bff19SRichard Henderson     TCGv ea;
699*d80bff19SRichard Henderson 
700*d80bff19SRichard Henderson     LOG_DIS("l.lwa r%d, r%d, %d\n", a->d, a->a, a->i);
701*d80bff19SRichard Henderson 
702*d80bff19SRichard Henderson     check_r0_write(a->d);
703*d80bff19SRichard Henderson     ea = tcg_temp_new();
704*d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
705*d80bff19SRichard Henderson     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL);
706*d80bff19SRichard Henderson     tcg_gen_mov_tl(cpu_lock_addr, ea);
707*d80bff19SRichard Henderson     tcg_gen_mov_tl(cpu_lock_value, cpu_R[a->d]);
708*d80bff19SRichard Henderson     tcg_temp_free(ea);
709*d80bff19SRichard Henderson     return true;
710*d80bff19SRichard Henderson }
711*d80bff19SRichard Henderson 
712*d80bff19SRichard Henderson static void do_load(DisasContext *dc, arg_load *a, TCGMemOp mop)
713*d80bff19SRichard Henderson {
714*d80bff19SRichard Henderson     TCGv ea;
715*d80bff19SRichard Henderson 
716*d80bff19SRichard Henderson     check_r0_write(a->d);
717*d80bff19SRichard Henderson     ea = tcg_temp_new();
718*d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
719*d80bff19SRichard Henderson     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop);
720*d80bff19SRichard Henderson     tcg_temp_free(ea);
721*d80bff19SRichard Henderson }
722*d80bff19SRichard Henderson 
723*d80bff19SRichard Henderson static bool trans_l_lwz(DisasContext *dc, arg_load *a, uint32_t insn)
724*d80bff19SRichard Henderson {
725*d80bff19SRichard Henderson     LOG_DIS("l.lwz r%d, r%d, %d\n", a->d, a->a, a->i);
726*d80bff19SRichard Henderson     do_load(dc, a, MO_TEUL);
727*d80bff19SRichard Henderson     return true;
728*d80bff19SRichard Henderson }
729*d80bff19SRichard Henderson 
730*d80bff19SRichard Henderson static bool trans_l_lws(DisasContext *dc, arg_load *a, uint32_t insn)
731*d80bff19SRichard Henderson {
732*d80bff19SRichard Henderson     LOG_DIS("l.lws r%d, r%d, %d\n", a->d, a->a, a->i);
733*d80bff19SRichard Henderson     do_load(dc, a, MO_TESL);
734*d80bff19SRichard Henderson     return true;
735*d80bff19SRichard Henderson }
736*d80bff19SRichard Henderson 
737*d80bff19SRichard Henderson static bool trans_l_lbz(DisasContext *dc, arg_load *a, uint32_t insn)
738*d80bff19SRichard Henderson {
739*d80bff19SRichard Henderson     LOG_DIS("l.lbz r%d, r%d, %d\n", a->d, a->a, a->i);
740*d80bff19SRichard Henderson     do_load(dc, a, MO_UB);
741*d80bff19SRichard Henderson     return true;
742*d80bff19SRichard Henderson }
743*d80bff19SRichard Henderson 
744*d80bff19SRichard Henderson static bool trans_l_lbs(DisasContext *dc, arg_load *a, uint32_t insn)
745*d80bff19SRichard Henderson {
746*d80bff19SRichard Henderson     LOG_DIS("l.lbs r%d, r%d, %d\n", a->d, a->a, a->i);
747*d80bff19SRichard Henderson     do_load(dc, a, MO_SB);
748*d80bff19SRichard Henderson     return true;
749*d80bff19SRichard Henderson }
750*d80bff19SRichard Henderson 
751*d80bff19SRichard Henderson static bool trans_l_lhz(DisasContext *dc, arg_load *a, uint32_t insn)
752*d80bff19SRichard Henderson {
753*d80bff19SRichard Henderson     LOG_DIS("l.lhz r%d, r%d, %d\n", a->d, a->a, a->i);
754*d80bff19SRichard Henderson     do_load(dc, a, MO_TEUW);
755*d80bff19SRichard Henderson     return true;
756*d80bff19SRichard Henderson }
757*d80bff19SRichard Henderson 
758*d80bff19SRichard Henderson static bool trans_l_lhs(DisasContext *dc, arg_load *a, uint32_t insn)
759*d80bff19SRichard Henderson {
760*d80bff19SRichard Henderson     LOG_DIS("l.lhs r%d, r%d, %d\n", a->d, a->a, a->i);
761*d80bff19SRichard Henderson     do_load(dc, a, MO_TESW);
762*d80bff19SRichard Henderson     return true;
763*d80bff19SRichard Henderson }
764*d80bff19SRichard Henderson 
765*d80bff19SRichard Henderson static bool trans_l_swa(DisasContext *dc, arg_store *a, uint32_t insn)
766*d80bff19SRichard Henderson {
767*d80bff19SRichard Henderson     TCGv ea, val;
768*d80bff19SRichard Henderson     TCGLabel *lab_fail, *lab_done;
769*d80bff19SRichard Henderson 
770*d80bff19SRichard Henderson     LOG_DIS("l.swa r%d, r%d, %d\n", a->a, a->b, a->i);
771*d80bff19SRichard Henderson 
772*d80bff19SRichard Henderson     ea = tcg_temp_new();
773*d80bff19SRichard Henderson     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
774*d80bff19SRichard Henderson 
775*d80bff19SRichard Henderson     /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
776*d80bff19SRichard Henderson        to cpu_R[0].  Since l.swa is quite often immediately followed by a
777*d80bff19SRichard Henderson        branch, don't bother reallocating; finish the TB using the "real" R0.
778*d80bff19SRichard Henderson        This also takes care of RB input across the branch.  */
779*d80bff19SRichard Henderson     cpu_R[0] = cpu_R0;
780*d80bff19SRichard Henderson 
781*d80bff19SRichard Henderson     lab_fail = gen_new_label();
782*d80bff19SRichard Henderson     lab_done = gen_new_label();
783*d80bff19SRichard Henderson     tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
784*d80bff19SRichard Henderson     tcg_temp_free(ea);
785*d80bff19SRichard Henderson 
786*d80bff19SRichard Henderson     val = tcg_temp_new();
787*d80bff19SRichard Henderson     tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
788*d80bff19SRichard Henderson                               cpu_R[a->b], dc->mem_idx, MO_TEUL);
789*d80bff19SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
790*d80bff19SRichard Henderson     tcg_temp_free(val);
791*d80bff19SRichard Henderson 
792*d80bff19SRichard Henderson     tcg_gen_br(lab_done);
793*d80bff19SRichard Henderson 
794*d80bff19SRichard Henderson     gen_set_label(lab_fail);
795*d80bff19SRichard Henderson     tcg_gen_movi_tl(cpu_sr_f, 0);
796*d80bff19SRichard Henderson 
797*d80bff19SRichard Henderson     gen_set_label(lab_done);
798*d80bff19SRichard Henderson     tcg_gen_movi_tl(cpu_lock_addr, -1);
799*d80bff19SRichard Henderson     return true;
800*d80bff19SRichard Henderson }
801*d80bff19SRichard Henderson 
802*d80bff19SRichard Henderson static void do_store(DisasContext *dc, arg_store *a, TCGMemOp mop)
803*d80bff19SRichard Henderson {
804*d80bff19SRichard Henderson     TCGv t0 = tcg_temp_new();
805*d80bff19SRichard Henderson     tcg_gen_addi_tl(t0, cpu_R[a->a], a->i);
806*d80bff19SRichard Henderson     tcg_gen_qemu_st_tl(cpu_R[a->b], t0, dc->mem_idx, mop);
807*d80bff19SRichard Henderson     tcg_temp_free(t0);
808*d80bff19SRichard Henderson }
809*d80bff19SRichard Henderson 
810*d80bff19SRichard Henderson static bool trans_l_sw(DisasContext *dc, arg_store *a, uint32_t insn)
811*d80bff19SRichard Henderson {
812*d80bff19SRichard Henderson     LOG_DIS("l.sw r%d, r%d, %d\n", a->a, a->b, a->i);
813*d80bff19SRichard Henderson     do_store(dc, a, MO_TEUL);
814*d80bff19SRichard Henderson     return true;
815*d80bff19SRichard Henderson }
816*d80bff19SRichard Henderson 
817*d80bff19SRichard Henderson static bool trans_l_sb(DisasContext *dc, arg_store *a, uint32_t insn)
818*d80bff19SRichard Henderson {
819*d80bff19SRichard Henderson     LOG_DIS("l.sb r%d, r%d, %d\n", a->a, a->b, a->i);
820*d80bff19SRichard Henderson     do_store(dc, a, MO_UB);
821*d80bff19SRichard Henderson     return true;
822*d80bff19SRichard Henderson }
823*d80bff19SRichard Henderson 
824*d80bff19SRichard Henderson static bool trans_l_sh(DisasContext *dc, arg_store *a, uint32_t insn)
825*d80bff19SRichard Henderson {
826*d80bff19SRichard Henderson     LOG_DIS("l.sh r%d, r%d, %d\n", a->a, a->b, a->i);
827*d80bff19SRichard Henderson     do_store(dc, a, MO_TEUW);
828*d80bff19SRichard Henderson     return true;
829*d80bff19SRichard Henderson }
830*d80bff19SRichard Henderson 
831bbe418f2SJia Liu static void dec_misc(DisasContext *dc, uint32_t insn)
832bbe418f2SJia Liu {
833bbe418f2SJia Liu     uint32_t op0, op1;
834bbe418f2SJia Liu     uint32_t ra, rb, rd;
8356da544a6SRichard Henderson     uint32_t L6, K5, K16, K5_11;
836*d80bff19SRichard Henderson     int32_t I16;
8379ecaa27eSRichard Henderson     TCGv t0;
8385631e69cSRichard Henderson 
839bbe418f2SJia Liu     op0 = extract32(insn, 26, 6);
840bbe418f2SJia Liu     op1 = extract32(insn, 24, 2);
841bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
842bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
843bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
844bbe418f2SJia Liu     L6 = extract32(insn, 5, 6);
845bbe418f2SJia Liu     K5 = extract32(insn, 0, 5);
8466da544a6SRichard Henderson     K16 = extract32(insn, 0, 16);
8476da544a6SRichard Henderson     I16 = (int16_t)K16;
8486da544a6SRichard Henderson     K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11);
849bbe418f2SJia Liu 
850bbe418f2SJia Liu     switch (op0) {
851bbe418f2SJia Liu     case 0x05:
852bbe418f2SJia Liu         switch (op1) {
853bbe418f2SJia Liu         case 0x01:    /* l.nop */
854bbe418f2SJia Liu             LOG_DIS("l.nop %d\n", I16);
855bbe418f2SJia Liu             break;
856bbe418f2SJia Liu 
857bbe418f2SJia Liu         default:
858bbe418f2SJia Liu             gen_illegal_exception(dc);
859bbe418f2SJia Liu             break;
860bbe418f2SJia Liu         }
861bbe418f2SJia Liu         break;
862bbe418f2SJia Liu 
863bbe418f2SJia Liu     case 0x13:    /* l.maci */
8646da544a6SRichard Henderson         LOG_DIS("l.maci r%d, %d\n", ra, I16);
8656f7332baSRichard Henderson         t0 = tcg_const_tl(I16);
8666f7332baSRichard Henderson         gen_mac(dc, cpu_R[ra], t0);
8676f7332baSRichard Henderson         tcg_temp_free(t0);
868bbe418f2SJia Liu         break;
869bbe418f2SJia Liu 
870bbe418f2SJia Liu     case 0x09:    /* l.rfe */
871bbe418f2SJia Liu         LOG_DIS("l.rfe\n");
872bbe418f2SJia Liu         {
873bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY)
874bbe418f2SJia Liu             return;
875bbe418f2SJia Liu #else
876bbe418f2SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
877bbe418f2SJia Liu                 gen_illegal_exception(dc);
878bbe418f2SJia Liu                 return;
879bbe418f2SJia Liu             }
880bbe418f2SJia Liu             gen_helper_rfe(cpu_env);
8811ffa4bceSEmilio G. Cota             dc->base.is_jmp = DISAS_UPDATE;
882bbe418f2SJia Liu #endif
883bbe418f2SJia Liu         }
884bbe418f2SJia Liu         break;
885bbe418f2SJia Liu 
886bbe418f2SJia Liu     case 0x1c:    /* l.cust1 */
887bbe418f2SJia Liu         LOG_DIS("l.cust1\n");
888bbe418f2SJia Liu         break;
889bbe418f2SJia Liu 
890bbe418f2SJia Liu     case 0x1d:    /* l.cust2 */
891bbe418f2SJia Liu         LOG_DIS("l.cust2\n");
892bbe418f2SJia Liu         break;
893bbe418f2SJia Liu 
894bbe418f2SJia Liu     case 0x1e:    /* l.cust3 */
895bbe418f2SJia Liu         LOG_DIS("l.cust3\n");
896bbe418f2SJia Liu         break;
897bbe418f2SJia Liu 
898bbe418f2SJia Liu     case 0x1f:    /* l.cust4 */
899bbe418f2SJia Liu         LOG_DIS("l.cust4\n");
900bbe418f2SJia Liu         break;
901bbe418f2SJia Liu 
902bbe418f2SJia Liu     case 0x3c:    /* l.cust5 */
903bbe418f2SJia Liu         LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5);
904bbe418f2SJia Liu         break;
905bbe418f2SJia Liu 
906bbe418f2SJia Liu     case 0x3d:    /* l.cust6 */
907bbe418f2SJia Liu         LOG_DIS("l.cust6\n");
908bbe418f2SJia Liu         break;
909bbe418f2SJia Liu 
910bbe418f2SJia Liu     case 0x3e:    /* l.cust7 */
911bbe418f2SJia Liu         LOG_DIS("l.cust7\n");
912bbe418f2SJia Liu         break;
913bbe418f2SJia Liu 
914bbe418f2SJia Liu     case 0x3f:    /* l.cust8 */
915bbe418f2SJia Liu         LOG_DIS("l.cust8\n");
916bbe418f2SJia Liu         break;
917bbe418f2SJia Liu 
918bbe418f2SJia Liu     case 0x27:    /* l.addi */
919bbe418f2SJia Liu         LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
9206597c28dSRichard Henderson         check_r0_write(rd);
9219ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
9229ecaa27eSRichard Henderson         gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
9239ecaa27eSRichard Henderson         tcg_temp_free(t0);
924bbe418f2SJia Liu         break;
925bbe418f2SJia Liu 
926bbe418f2SJia Liu     case 0x28:    /* l.addic */
927bbe418f2SJia Liu         LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
9286597c28dSRichard Henderson         check_r0_write(rd);
9299ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
9309ecaa27eSRichard Henderson         gen_addc(dc, cpu_R[rd], cpu_R[ra], t0);
9319ecaa27eSRichard Henderson         tcg_temp_free(t0);
932bbe418f2SJia Liu         break;
933bbe418f2SJia Liu 
934bbe418f2SJia Liu     case 0x29:    /* l.andi */
9356da544a6SRichard Henderson         LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16);
9366597c28dSRichard Henderson         check_r0_write(rd);
9376da544a6SRichard Henderson         tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16);
938bbe418f2SJia Liu         break;
939bbe418f2SJia Liu 
940bbe418f2SJia Liu     case 0x2a:    /* l.ori */
9416da544a6SRichard Henderson         LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16);
9426597c28dSRichard Henderson         check_r0_write(rd);
9436da544a6SRichard Henderson         tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16);
944bbe418f2SJia Liu         break;
945bbe418f2SJia Liu 
946bbe418f2SJia Liu     case 0x2b:    /* l.xori */
947bbe418f2SJia Liu         LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
9486597c28dSRichard Henderson         check_r0_write(rd);
9496da544a6SRichard Henderson         tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16);
950bbe418f2SJia Liu         break;
951bbe418f2SJia Liu 
952bbe418f2SJia Liu     case 0x2c:    /* l.muli */
953bbe418f2SJia Liu         LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
9546597c28dSRichard Henderson         check_r0_write(rd);
9559ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
9569ecaa27eSRichard Henderson         gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
9579ecaa27eSRichard Henderson         tcg_temp_free(t0);
958bbe418f2SJia Liu         break;
959bbe418f2SJia Liu 
960bbe418f2SJia Liu     case 0x2d:    /* l.mfspr */
9616da544a6SRichard Henderson         LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
9626597c28dSRichard Henderson         check_r0_write(rd);
9634dd044c6SJia Liu         {
9644dd044c6SJia Liu #if defined(CONFIG_USER_ONLY)
9654dd044c6SJia Liu             return;
9664dd044c6SJia Liu #else
9676da544a6SRichard Henderson             TCGv_i32 ti = tcg_const_i32(K16);
9684dd044c6SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
9694dd044c6SJia Liu                 gen_illegal_exception(dc);
9704dd044c6SJia Liu                 return;
9714dd044c6SJia Liu             }
9724dd044c6SJia Liu             gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
9734dd044c6SJia Liu             tcg_temp_free_i32(ti);
9744dd044c6SJia Liu #endif
9754dd044c6SJia Liu         }
976bbe418f2SJia Liu         break;
977bbe418f2SJia Liu 
978bbe418f2SJia Liu     case 0x30:    /* l.mtspr */
9796da544a6SRichard Henderson         LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
9804dd044c6SJia Liu         {
9814dd044c6SJia Liu #if defined(CONFIG_USER_ONLY)
9824dd044c6SJia Liu             return;
9834dd044c6SJia Liu #else
9846da544a6SRichard Henderson             TCGv_i32 im = tcg_const_i32(K5_11);
9854dd044c6SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
9864dd044c6SJia Liu                 gen_illegal_exception(dc);
9874dd044c6SJia Liu                 return;
9884dd044c6SJia Liu             }
9894dd044c6SJia Liu             gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
9904dd044c6SJia Liu             tcg_temp_free_i32(im);
9914dd044c6SJia Liu #endif
9924dd044c6SJia Liu         }
993bbe418f2SJia Liu         break;
994bbe418f2SJia Liu 
995bbe418f2SJia Liu     default:
996bbe418f2SJia Liu         gen_illegal_exception(dc);
997bbe418f2SJia Liu         break;
998bbe418f2SJia Liu     }
999bbe418f2SJia Liu }
1000bbe418f2SJia Liu 
1001bbe418f2SJia Liu static void dec_mac(DisasContext *dc, uint32_t insn)
1002bbe418f2SJia Liu {
1003bbe418f2SJia Liu     uint32_t op0;
1004bbe418f2SJia Liu     uint32_t ra, rb;
1005bbe418f2SJia Liu     op0 = extract32(insn, 0, 4);
1006bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1007bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1008bbe418f2SJia Liu 
1009bbe418f2SJia Liu     switch (op0) {
1010bbe418f2SJia Liu     case 0x0001:    /* l.mac */
1011bbe418f2SJia Liu         LOG_DIS("l.mac r%d, r%d\n", ra, rb);
10126f7332baSRichard Henderson         gen_mac(dc, cpu_R[ra], cpu_R[rb]);
1013bbe418f2SJia Liu         break;
1014bbe418f2SJia Liu 
1015bbe418f2SJia Liu     case 0x0002:    /* l.msb */
1016bbe418f2SJia Liu         LOG_DIS("l.msb r%d, r%d\n", ra, rb);
10176f7332baSRichard Henderson         gen_msb(dc, cpu_R[ra], cpu_R[rb]);
1018bbe418f2SJia Liu         break;
1019bbe418f2SJia Liu 
1020cc5de49eSRichard Henderson     case 0x0003:    /* l.macu */
1021cc5de49eSRichard Henderson         LOG_DIS("l.macu r%d, r%d\n", ra, rb);
1022cc5de49eSRichard Henderson         gen_macu(dc, cpu_R[ra], cpu_R[rb]);
1023cc5de49eSRichard Henderson         break;
1024cc5de49eSRichard Henderson 
1025cc5de49eSRichard Henderson     case 0x0004:    /* l.msbu */
1026cc5de49eSRichard Henderson         LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
1027cc5de49eSRichard Henderson         gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
1028cc5de49eSRichard Henderson         break;
1029cc5de49eSRichard Henderson 
1030bbe418f2SJia Liu     default:
1031bbe418f2SJia Liu         gen_illegal_exception(dc);
1032bbe418f2SJia Liu         break;
1033bbe418f2SJia Liu    }
1034bbe418f2SJia Liu }
1035bbe418f2SJia Liu 
1036bbe418f2SJia Liu static void dec_logic(DisasContext *dc, uint32_t insn)
1037bbe418f2SJia Liu {
1038bbe418f2SJia Liu     uint32_t op0;
10396da544a6SRichard Henderson     uint32_t rd, ra, L6, S6;
1040bbe418f2SJia Liu     op0 = extract32(insn, 6, 2);
1041bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1042bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1043bbe418f2SJia Liu     L6 = extract32(insn, 0, 6);
10446da544a6SRichard Henderson     S6 = L6 & (TARGET_LONG_BITS - 1);
1045bbe418f2SJia Liu 
10466597c28dSRichard Henderson     check_r0_write(rd);
1047bbe418f2SJia Liu     switch (op0) {
1048bbe418f2SJia Liu     case 0x00:    /* l.slli */
1049bbe418f2SJia Liu         LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
10506da544a6SRichard Henderson         tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6);
1051bbe418f2SJia Liu         break;
1052bbe418f2SJia Liu 
1053bbe418f2SJia Liu     case 0x01:    /* l.srli */
1054bbe418f2SJia Liu         LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
10556da544a6SRichard Henderson         tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6);
1056bbe418f2SJia Liu         break;
1057bbe418f2SJia Liu 
1058bbe418f2SJia Liu     case 0x02:    /* l.srai */
1059bbe418f2SJia Liu         LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
10606da544a6SRichard Henderson         tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6);
10616da544a6SRichard Henderson         break;
1062bbe418f2SJia Liu 
1063bbe418f2SJia Liu     case 0x03:    /* l.rori */
1064bbe418f2SJia Liu         LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
10656da544a6SRichard Henderson         tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6);
1066bbe418f2SJia Liu         break;
1067bbe418f2SJia Liu 
1068bbe418f2SJia Liu     default:
1069bbe418f2SJia Liu         gen_illegal_exception(dc);
1070bbe418f2SJia Liu         break;
1071bbe418f2SJia Liu     }
1072bbe418f2SJia Liu }
1073bbe418f2SJia Liu 
1074bbe418f2SJia Liu static void dec_M(DisasContext *dc, uint32_t insn)
1075bbe418f2SJia Liu {
1076bbe418f2SJia Liu     uint32_t op0;
1077bbe418f2SJia Liu     uint32_t rd;
1078bbe418f2SJia Liu     uint32_t K16;
1079bbe418f2SJia Liu     op0 = extract32(insn, 16, 1);
1080bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1081bbe418f2SJia Liu     K16 = extract32(insn, 0, 16);
1082bbe418f2SJia Liu 
10836597c28dSRichard Henderson     check_r0_write(rd);
1084bbe418f2SJia Liu     switch (op0) {
1085bbe418f2SJia Liu     case 0x0:    /* l.movhi */
1086bbe418f2SJia Liu         LOG_DIS("l.movhi  r%d, %d\n", rd, K16);
1087bbe418f2SJia Liu         tcg_gen_movi_tl(cpu_R[rd], (K16 << 16));
1088bbe418f2SJia Liu         break;
1089bbe418f2SJia Liu 
1090bbe418f2SJia Liu     case 0x1:    /* l.macrc */
1091bbe418f2SJia Liu         LOG_DIS("l.macrc  r%d\n", rd);
10926f7332baSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
10936f7332baSRichard Henderson         tcg_gen_movi_i64(cpu_mac, 0);
1094bbe418f2SJia Liu         break;
1095bbe418f2SJia Liu 
1096bbe418f2SJia Liu     default:
1097bbe418f2SJia Liu         gen_illegal_exception(dc);
1098bbe418f2SJia Liu         break;
1099bbe418f2SJia Liu     }
1100bbe418f2SJia Liu }
1101bbe418f2SJia Liu 
1102bbe418f2SJia Liu static void dec_comp(DisasContext *dc, uint32_t insn)
1103bbe418f2SJia Liu {
1104bbe418f2SJia Liu     uint32_t op0;
1105bbe418f2SJia Liu     uint32_t ra, rb;
1106bbe418f2SJia Liu 
1107bbe418f2SJia Liu     op0 = extract32(insn, 21, 5);
1108bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1109bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1110bbe418f2SJia Liu 
1111bbe418f2SJia Liu     /* unsigned integers  */
1112bbe418f2SJia Liu     tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
1113bbe418f2SJia Liu     tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
1114bbe418f2SJia Liu 
1115bbe418f2SJia Liu     switch (op0) {
1116bbe418f2SJia Liu     case 0x0:    /* l.sfeq */
1117bbe418f2SJia Liu         LOG_DIS("l.sfeq  r%d, r%d\n", ra, rb);
111884775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1119bbe418f2SJia Liu         break;
1120bbe418f2SJia Liu 
1121bbe418f2SJia Liu     case 0x1:    /* l.sfne */
1122bbe418f2SJia Liu         LOG_DIS("l.sfne  r%d, r%d\n", ra, rb);
112384775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1124bbe418f2SJia Liu         break;
1125bbe418f2SJia Liu 
1126bbe418f2SJia Liu     case 0x2:    /* l.sfgtu */
1127bbe418f2SJia Liu         LOG_DIS("l.sfgtu  r%d, r%d\n", ra, rb);
112884775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1129bbe418f2SJia Liu         break;
1130bbe418f2SJia Liu 
1131bbe418f2SJia Liu     case 0x3:    /* l.sfgeu */
1132bbe418f2SJia Liu         LOG_DIS("l.sfgeu  r%d, r%d\n", ra, rb);
113384775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1134bbe418f2SJia Liu         break;
1135bbe418f2SJia Liu 
1136bbe418f2SJia Liu     case 0x4:    /* l.sfltu */
1137bbe418f2SJia Liu         LOG_DIS("l.sfltu  r%d, r%d\n", ra, rb);
113884775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1139bbe418f2SJia Liu         break;
1140bbe418f2SJia Liu 
1141bbe418f2SJia Liu     case 0x5:    /* l.sfleu */
1142bbe418f2SJia Liu         LOG_DIS("l.sfleu  r%d, r%d\n", ra, rb);
114384775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1144bbe418f2SJia Liu         break;
1145bbe418f2SJia Liu 
1146bbe418f2SJia Liu     case 0xa:    /* l.sfgts */
1147bbe418f2SJia Liu         LOG_DIS("l.sfgts  r%d, r%d\n", ra, rb);
114884775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1149bbe418f2SJia Liu         break;
1150bbe418f2SJia Liu 
1151bbe418f2SJia Liu     case 0xb:    /* l.sfges */
1152bbe418f2SJia Liu         LOG_DIS("l.sfges  r%d, r%d\n", ra, rb);
115384775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1154bbe418f2SJia Liu         break;
1155bbe418f2SJia Liu 
1156bbe418f2SJia Liu     case 0xc:    /* l.sflts */
1157bbe418f2SJia Liu         LOG_DIS("l.sflts  r%d, r%d\n", ra, rb);
115884775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1159bbe418f2SJia Liu         break;
1160bbe418f2SJia Liu 
1161bbe418f2SJia Liu     case 0xd:    /* l.sfles */
1162bbe418f2SJia Liu         LOG_DIS("l.sfles  r%d, r%d\n", ra, rb);
116384775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1164bbe418f2SJia Liu         break;
1165bbe418f2SJia Liu 
1166bbe418f2SJia Liu     default:
1167bbe418f2SJia Liu         gen_illegal_exception(dc);
1168bbe418f2SJia Liu         break;
1169bbe418f2SJia Liu     }
1170bbe418f2SJia Liu }
1171bbe418f2SJia Liu 
1172bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn)
1173bbe418f2SJia Liu {
11746da544a6SRichard Henderson     uint32_t op0, ra;
11756da544a6SRichard Henderson     int32_t I16;
1176bbe418f2SJia Liu 
1177bbe418f2SJia Liu     op0 = extract32(insn, 21, 5);
1178bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
11796da544a6SRichard Henderson     I16 = sextract32(insn, 0, 16);
1180bbe418f2SJia Liu 
1181bbe418f2SJia Liu     switch (op0) {
1182bbe418f2SJia Liu     case 0x0:    /* l.sfeqi */
1183bbe418f2SJia Liu         LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
118484775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
1185bbe418f2SJia Liu         break;
1186bbe418f2SJia Liu 
1187bbe418f2SJia Liu     case 0x1:    /* l.sfnei */
1188bbe418f2SJia Liu         LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
118984775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
1190bbe418f2SJia Liu         break;
1191bbe418f2SJia Liu 
1192bbe418f2SJia Liu     case 0x2:    /* l.sfgtui */
1193bbe418f2SJia Liu         LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
119484775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
1195bbe418f2SJia Liu         break;
1196bbe418f2SJia Liu 
1197bbe418f2SJia Liu     case 0x3:    /* l.sfgeui */
1198bbe418f2SJia Liu         LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
119984775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
1200bbe418f2SJia Liu         break;
1201bbe418f2SJia Liu 
1202bbe418f2SJia Liu     case 0x4:    /* l.sfltui */
1203bbe418f2SJia Liu         LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
120484775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
1205bbe418f2SJia Liu         break;
1206bbe418f2SJia Liu 
1207bbe418f2SJia Liu     case 0x5:    /* l.sfleui */
1208bbe418f2SJia Liu         LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
120984775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
1210bbe418f2SJia Liu         break;
1211bbe418f2SJia Liu 
1212bbe418f2SJia Liu     case 0xa:    /* l.sfgtsi */
1213bbe418f2SJia Liu         LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
121484775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
1215bbe418f2SJia Liu         break;
1216bbe418f2SJia Liu 
1217bbe418f2SJia Liu     case 0xb:    /* l.sfgesi */
1218bbe418f2SJia Liu         LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
121984775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
1220bbe418f2SJia Liu         break;
1221bbe418f2SJia Liu 
1222bbe418f2SJia Liu     case 0xc:    /* l.sfltsi */
1223bbe418f2SJia Liu         LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
122484775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
1225bbe418f2SJia Liu         break;
1226bbe418f2SJia Liu 
1227bbe418f2SJia Liu     case 0xd:    /* l.sflesi */
1228bbe418f2SJia Liu         LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
122984775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
1230bbe418f2SJia Liu         break;
1231bbe418f2SJia Liu 
1232bbe418f2SJia Liu     default:
1233bbe418f2SJia Liu         gen_illegal_exception(dc);
1234bbe418f2SJia Liu         break;
1235bbe418f2SJia Liu     }
1236bbe418f2SJia Liu }
1237bbe418f2SJia Liu 
12387de9729fSRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
1239bbe418f2SJia Liu {
12407de9729fSRichard Henderson     LOG_DIS("l.sys %d\n", a->k);
12411ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1242bbe418f2SJia Liu     gen_exception(dc, EXCP_SYSCALL);
12431ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
12447de9729fSRichard Henderson     return true;
12457de9729fSRichard Henderson }
1246bbe418f2SJia Liu 
12477de9729fSRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
12487de9729fSRichard Henderson {
12497de9729fSRichard Henderson     LOG_DIS("l.trap %d\n", a->k);
12501ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1251bbe418f2SJia Liu     gen_exception(dc, EXCP_TRAP);
12521ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
12537de9729fSRichard Henderson     return true;
12547de9729fSRichard Henderson }
1255bbe418f2SJia Liu 
12567de9729fSRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
12577de9729fSRichard Henderson {
1258bbe418f2SJia Liu     LOG_DIS("l.msync\n");
125924fc5c0fSRichard Henderson     tcg_gen_mb(TCG_MO_ALL);
12607de9729fSRichard Henderson     return true;
1261bbe418f2SJia Liu }
12627de9729fSRichard Henderson 
12637de9729fSRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
12647de9729fSRichard Henderson {
12657de9729fSRichard Henderson     LOG_DIS("l.psync\n");
12667de9729fSRichard Henderson     return true;
12677de9729fSRichard Henderson }
12687de9729fSRichard Henderson 
12697de9729fSRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
12707de9729fSRichard Henderson {
12717de9729fSRichard Henderson     LOG_DIS("l.csync\n");
12727de9729fSRichard Henderson     return true;
1273bbe418f2SJia Liu }
1274bbe418f2SJia Liu 
1275bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn)
1276bbe418f2SJia Liu {
1277bbe418f2SJia Liu     uint32_t op0;
1278bbe418f2SJia Liu     uint32_t ra, rb, rd;
1279bbe418f2SJia Liu     op0 = extract32(insn, 0, 8);
1280bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1281bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1282bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1283bbe418f2SJia Liu 
1284bbe418f2SJia Liu     switch (op0) {
1285bbe418f2SJia Liu     case 0x00: /* lf.add.s */
1286bbe418f2SJia Liu         LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
12876597c28dSRichard Henderson         check_r0_write(rd);
1288bbe418f2SJia Liu         gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12894e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1290bbe418f2SJia Liu         break;
1291bbe418f2SJia Liu 
1292bbe418f2SJia Liu     case 0x01: /* lf.sub.s */
1293bbe418f2SJia Liu         LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
12946597c28dSRichard Henderson         check_r0_write(rd);
1295bbe418f2SJia Liu         gen_helper_float_sub_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 0x02:    /* lf.mul.s */
1300bbe418f2SJia Liu         LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
13016597c28dSRichard Henderson         check_r0_write(rd);
1302bbe418f2SJia Liu         gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13034e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1304bbe418f2SJia Liu         break;
1305bbe418f2SJia Liu 
1306bbe418f2SJia Liu     case 0x03: /* lf.div.s */
1307bbe418f2SJia Liu         LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
13086597c28dSRichard Henderson         check_r0_write(rd);
1309bbe418f2SJia Liu         gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13104e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1311bbe418f2SJia Liu         break;
1312bbe418f2SJia Liu 
1313bbe418f2SJia Liu     case 0x04: /* lf.itof.s */
1314bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
13156597c28dSRichard Henderson         check_r0_write(rd);
1316bbe418f2SJia Liu         gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
13174e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1318bbe418f2SJia Liu         break;
1319bbe418f2SJia Liu 
1320bbe418f2SJia Liu     case 0x05: /* lf.ftoi.s */
1321bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
13226597c28dSRichard Henderson         check_r0_write(rd);
1323bbe418f2SJia Liu         gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
13244e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1325bbe418f2SJia Liu         break;
1326bbe418f2SJia Liu 
1327bbe418f2SJia Liu     case 0x06: /* lf.rem.s */
1328bbe418f2SJia Liu         LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
13296597c28dSRichard Henderson         check_r0_write(rd);
1330bbe418f2SJia Liu         gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13314e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1332bbe418f2SJia Liu         break;
1333bbe418f2SJia Liu 
1334bbe418f2SJia Liu     case 0x07: /* lf.madd.s */
1335bbe418f2SJia Liu         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
13366597c28dSRichard Henderson         check_r0_write(rd);
1337762e22edSRichard Henderson         gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
1338762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
13394e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1340bbe418f2SJia Liu         break;
1341bbe418f2SJia Liu 
1342bbe418f2SJia Liu     case 0x08: /* lf.sfeq.s */
1343bbe418f2SJia Liu         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
134484775c43SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13454e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1346bbe418f2SJia Liu         break;
1347bbe418f2SJia Liu 
1348bbe418f2SJia Liu     case 0x09: /* lf.sfne.s */
1349bbe418f2SJia Liu         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
13504e2d3007SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13514e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
13524e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1353bbe418f2SJia Liu         break;
1354bbe418f2SJia Liu 
1355bbe418f2SJia Liu     case 0x0a: /* lf.sfgt.s */
1356bbe418f2SJia Liu         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
13574e2d3007SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13584e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1359bbe418f2SJia Liu         break;
1360bbe418f2SJia Liu 
1361bbe418f2SJia Liu     case 0x0b: /* lf.sfge.s */
1362bbe418f2SJia Liu         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
13634e2d3007SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13644e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1365bbe418f2SJia Liu         break;
1366bbe418f2SJia Liu 
1367bbe418f2SJia Liu     case 0x0c: /* lf.sflt.s */
1368bbe418f2SJia Liu         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
136984775c43SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13704e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1371bbe418f2SJia Liu         break;
1372bbe418f2SJia Liu 
1373bbe418f2SJia Liu     case 0x0d: /* lf.sfle.s */
1374bbe418f2SJia Liu         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
137584775c43SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13764e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1377bbe418f2SJia Liu         break;
1378bbe418f2SJia Liu 
13794e2d3007SRichard Henderson #ifdef TARGET_OPENRISC64
13804e2d3007SRichard Henderson     case 0x10: /* lf.add.d */
1381bbe418f2SJia Liu         LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1382bbe418f2SJia Liu         check_of64s(dc);
13836597c28dSRichard Henderson         check_r0_write(rd);
1384bbe418f2SJia Liu         gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13854e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1386bbe418f2SJia Liu         break;
1387bbe418f2SJia Liu 
13884e2d3007SRichard Henderson     case 0x11: /* lf.sub.d */
1389bbe418f2SJia Liu         LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1390bbe418f2SJia Liu         check_of64s(dc);
13916597c28dSRichard Henderson         check_r0_write(rd);
1392bbe418f2SJia Liu         gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13934e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1394bbe418f2SJia Liu         break;
1395bbe418f2SJia Liu 
13964e2d3007SRichard Henderson     case 0x12: /* lf.mul.d */
1397bbe418f2SJia Liu         LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1398bbe418f2SJia Liu         check_of64s(dc);
13996597c28dSRichard Henderson         check_r0_write(rd);
1400bbe418f2SJia Liu         gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14014e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1402bbe418f2SJia Liu         break;
1403bbe418f2SJia Liu 
14044e2d3007SRichard Henderson     case 0x13: /* lf.div.d */
1405bbe418f2SJia Liu         LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1406bbe418f2SJia Liu         check_of64s(dc);
14076597c28dSRichard Henderson         check_r0_write(rd);
1408bbe418f2SJia Liu         gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14094e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1410bbe418f2SJia Liu         break;
1411bbe418f2SJia Liu 
14124e2d3007SRichard Henderson     case 0x14: /* lf.itof.d */
1413bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1414bbe418f2SJia Liu         check_of64s(dc);
14156597c28dSRichard Henderson         check_r0_write(rd);
1416bbe418f2SJia Liu         gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
14174e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1418bbe418f2SJia Liu         break;
1419bbe418f2SJia Liu 
14204e2d3007SRichard Henderson     case 0x15: /* lf.ftoi.d */
1421bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1422bbe418f2SJia Liu         check_of64s(dc);
14236597c28dSRichard Henderson         check_r0_write(rd);
1424bbe418f2SJia Liu         gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
14254e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1426bbe418f2SJia Liu         break;
1427bbe418f2SJia Liu 
14284e2d3007SRichard Henderson     case 0x16: /* lf.rem.d */
1429bbe418f2SJia Liu         LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1430bbe418f2SJia Liu         check_of64s(dc);
14316597c28dSRichard Henderson         check_r0_write(rd);
1432bbe418f2SJia Liu         gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14334e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1434bbe418f2SJia Liu         break;
1435bbe418f2SJia Liu 
14364e2d3007SRichard Henderson     case 0x17: /* lf.madd.d */
1437bbe418f2SJia Liu         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1438bbe418f2SJia Liu         check_of64s(dc);
14396597c28dSRichard Henderson         check_r0_write(rd);
1440762e22edSRichard Henderson         gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
1441762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
14424e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1443bbe418f2SJia Liu         break;
1444bbe418f2SJia Liu 
14454e2d3007SRichard Henderson     case 0x18: /* lf.sfeq.d */
1446bbe418f2SJia Liu         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1447bbe418f2SJia Liu         check_of64s(dc);
144884775c43SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14494e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1450bbe418f2SJia Liu         break;
1451bbe418f2SJia Liu 
14524e2d3007SRichard Henderson     case 0x1a: /* lf.sfgt.d */
1453bbe418f2SJia Liu         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1454bbe418f2SJia Liu         check_of64s(dc);
14554e2d3007SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14564e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1457bbe418f2SJia Liu         break;
1458bbe418f2SJia Liu 
14594e2d3007SRichard Henderson     case 0x1b: /* lf.sfge.d */
1460bbe418f2SJia Liu         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1461bbe418f2SJia Liu         check_of64s(dc);
14624e2d3007SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14634e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1464bbe418f2SJia Liu         break;
1465bbe418f2SJia Liu 
14664e2d3007SRichard Henderson     case 0x19: /* lf.sfne.d */
1467bbe418f2SJia Liu         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1468bbe418f2SJia Liu         check_of64s(dc);
14694e2d3007SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14704e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
14714e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1472bbe418f2SJia Liu         break;
1473bbe418f2SJia Liu 
14744e2d3007SRichard Henderson     case 0x1c: /* lf.sflt.d */
1475bbe418f2SJia Liu         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1476bbe418f2SJia Liu         check_of64s(dc);
147784775c43SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14784e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1479bbe418f2SJia Liu         break;
1480bbe418f2SJia Liu 
14814e2d3007SRichard Henderson     case 0x1d: /* lf.sfle.d */
1482bbe418f2SJia Liu         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1483bbe418f2SJia Liu         check_of64s(dc);
148484775c43SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14854e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1486bbe418f2SJia Liu         break;
14874e2d3007SRichard Henderson #endif
1488bbe418f2SJia Liu 
1489bbe418f2SJia Liu     default:
1490bbe418f2SJia Liu         gen_illegal_exception(dc);
1491bbe418f2SJia Liu         break;
1492bbe418f2SJia Liu     }
1493bbe418f2SJia Liu }
1494bbe418f2SJia Liu 
1495bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1496bbe418f2SJia Liu {
1497bbe418f2SJia Liu     uint32_t op0;
14987de9729fSRichard Henderson     uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next);
1499bbe418f2SJia Liu 
15007de9729fSRichard Henderson     /* Transition to the auto-generated decoder.  */
15017de9729fSRichard Henderson     if (decode(dc, insn)) {
15027de9729fSRichard Henderson         return;
15037de9729fSRichard Henderson     }
15047de9729fSRichard Henderson 
15057de9729fSRichard Henderson     op0 = extract32(insn, 26, 6);
1506bbe418f2SJia Liu     switch (op0) {
1507bbe418f2SJia Liu     case 0x06:
1508bbe418f2SJia Liu         dec_M(dc, insn);
1509bbe418f2SJia Liu         break;
1510bbe418f2SJia Liu 
1511bbe418f2SJia Liu     case 0x2e:
1512bbe418f2SJia Liu         dec_logic(dc, insn);
1513bbe418f2SJia Liu         break;
1514bbe418f2SJia Liu 
1515bbe418f2SJia Liu     case 0x2f:
1516bbe418f2SJia Liu         dec_compi(dc, insn);
1517bbe418f2SJia Liu         break;
1518bbe418f2SJia Liu 
1519bbe418f2SJia Liu     case 0x31:
1520bbe418f2SJia Liu         dec_mac(dc, insn);
1521bbe418f2SJia Liu         break;
1522bbe418f2SJia Liu 
1523bbe418f2SJia Liu     case 0x32:
1524bbe418f2SJia Liu         dec_float(dc, insn);
1525bbe418f2SJia Liu         break;
1526bbe418f2SJia Liu 
1527bbe418f2SJia Liu     case 0x38:
1528bbe418f2SJia Liu         dec_calc(dc, insn);
1529bbe418f2SJia Liu         break;
1530bbe418f2SJia Liu 
1531bbe418f2SJia Liu     case 0x39:
1532bbe418f2SJia Liu         dec_comp(dc, insn);
1533bbe418f2SJia Liu         break;
1534bbe418f2SJia Liu 
1535bbe418f2SJia Liu     default:
1536bbe418f2SJia Liu         dec_misc(dc, insn);
1537bbe418f2SJia Liu         break;
1538bbe418f2SJia Liu     }
1539bbe418f2SJia Liu }
1540bbe418f2SJia Liu 
1541a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
1542e67db06eSJia Liu {
1543a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcb, DisasContext, base);
15449c489ea6SLluís Vilanova     CPUOpenRISCState *env = cs->env_ptr;
1545a4fd3ec3SEmilio G. Cota     int bound;
1546bbe418f2SJia Liu 
1547a4fd3ec3SEmilio G. Cota     dc->mem_idx = cpu_mmu_index(env, false);
15481ffa4bceSEmilio G. Cota     dc->tb_flags = dc->base.tb->flags;
1549a01deb36SRichard Henderson     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
1550a4fd3ec3SEmilio G. Cota     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
1551a4fd3ec3SEmilio G. Cota     dc->base.max_insns = MIN(dc->base.max_insns, bound);
1552190ce7fbSRichard Henderson }
1553bbe418f2SJia Liu 
1554a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
1555a4fd3ec3SEmilio G. Cota {
1556a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(db, DisasContext, base);
1557bbe418f2SJia Liu 
15586597c28dSRichard Henderson     /* Allow the TCG optimizer to see that R0 == 0,
15596597c28dSRichard Henderson        when it's true, which is the common case.  */
15606597c28dSRichard Henderson     if (dc->tb_flags & TB_FLAGS_R0_0) {
15616597c28dSRichard Henderson         cpu_R[0] = tcg_const_tl(0);
15626597c28dSRichard Henderson     } else {
15636597c28dSRichard Henderson         cpu_R[0] = cpu_R0;
15646597c28dSRichard Henderson     }
1565a4fd3ec3SEmilio G. Cota }
15666597c28dSRichard Henderson 
1567a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
1568a4fd3ec3SEmilio G. Cota {
1569a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1570a4fd3ec3SEmilio G. Cota 
15711ffa4bceSEmilio G. Cota     tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
1572a4fd3ec3SEmilio G. Cota                        | (dc->base.num_insns > 1 ? 2 : 0));
1573a4fd3ec3SEmilio G. Cota }
1574bbe418f2SJia Liu 
1575a4fd3ec3SEmilio G. Cota static bool openrisc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
1576a4fd3ec3SEmilio G. Cota                                          const CPUBreakpoint *bp)
1577a4fd3ec3SEmilio G. Cota {
1578a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1579a4fd3ec3SEmilio G. Cota 
15801ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1581b933066aSRichard Henderson     gen_exception(dc, EXCP_DEBUG);
15821ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
1583522a0d4eSRichard Henderson     /* The address covered by the breakpoint must be included in
1584522a0d4eSRichard Henderson        [tb->pc, tb->pc + tb->size) in order to for it to be
1585522a0d4eSRichard Henderson        properly cleared -- thus we increment the PC here so that
1586522a0d4eSRichard Henderson        the logic setting tb->size below does the right thing.  */
15871ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
1588a4fd3ec3SEmilio G. Cota     return true;
1589b933066aSRichard Henderson }
1590b933066aSRichard Henderson 
1591a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
1592a4fd3ec3SEmilio G. Cota {
1593a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1594a4fd3ec3SEmilio G. Cota     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1595a4fd3ec3SEmilio G. Cota 
1596bbe418f2SJia Liu     disas_openrisc_insn(dc, cpu);
15971ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
159824c32852SRichard Henderson 
1599bbe418f2SJia Liu     /* delay slot */
1600bbe418f2SJia Liu     if (dc->delayed_branch) {
1601bbe418f2SJia Liu         dc->delayed_branch--;
1602bbe418f2SJia Liu         if (!dc->delayed_branch) {
1603bbe418f2SJia Liu             tcg_gen_mov_tl(cpu_pc, jmp_pc);
160424c32852SRichard Henderson             tcg_gen_discard_tl(jmp_pc);
16051ffa4bceSEmilio G. Cota             dc->base.is_jmp = DISAS_UPDATE;
1606a4fd3ec3SEmilio G. Cota             return;
1607bbe418f2SJia Liu         }
1608bbe418f2SJia Liu     }
1609a4fd3ec3SEmilio G. Cota }
1610bbe418f2SJia Liu 
1611a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
1612a4fd3ec3SEmilio G. Cota {
1613a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
161424c32852SRichard Henderson 
1615a01deb36SRichard Henderson     if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
1616a01deb36SRichard Henderson         tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
1617a01deb36SRichard Henderson     }
1618a01deb36SRichard Henderson 
16191ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
16201ffa4bceSEmilio G. Cota     if (dc->base.is_jmp == DISAS_NEXT) {
16211ffa4bceSEmilio G. Cota         dc->base.is_jmp = DISAS_UPDATE;
16221ffa4bceSEmilio G. Cota         tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1623bbe418f2SJia Liu     }
16241ffa4bceSEmilio G. Cota     if (unlikely(dc->base.singlestep_enabled)) {
1625bbe418f2SJia Liu         gen_exception(dc, EXCP_DEBUG);
1626bbe418f2SJia Liu     } else {
16271ffa4bceSEmilio G. Cota         switch (dc->base.is_jmp) {
1628a4fd3ec3SEmilio G. Cota         case DISAS_TOO_MANY:
16291ffa4bceSEmilio G. Cota             gen_goto_tb(dc, 0, dc->base.pc_next);
1630bbe418f2SJia Liu             break;
16311ffa4bceSEmilio G. Cota         case DISAS_NORETURN:
1632bbe418f2SJia Liu         case DISAS_JUMP:
16331ffa4bceSEmilio G. Cota         case DISAS_TB_JUMP:
1634bbe418f2SJia Liu             break;
1635bbe418f2SJia Liu         case DISAS_UPDATE:
1636bbe418f2SJia Liu             /* indicate that the hash table must be used
1637bbe418f2SJia Liu                to find the next TB */
1638bbe418f2SJia Liu             tcg_gen_exit_tb(0);
1639bbe418f2SJia Liu             break;
1640a4fd3ec3SEmilio G. Cota         default:
1641a4fd3ec3SEmilio G. Cota             g_assert_not_reached();
1642a4fd3ec3SEmilio G. Cota         }
1643bbe418f2SJia Liu     }
1644bbe418f2SJia Liu }
1645bbe418f2SJia Liu 
1646a4fd3ec3SEmilio G. Cota static void openrisc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
1647a4fd3ec3SEmilio G. Cota {
1648a4fd3ec3SEmilio G. Cota     DisasContext *s = container_of(dcbase, DisasContext, base);
16490a7df5daSRichard Henderson 
1650a4fd3ec3SEmilio G. Cota     qemu_log("IN: %s\n", lookup_symbol(s->base.pc_first));
1651a4fd3ec3SEmilio G. Cota     log_target_disas(cs, s->base.pc_first, s->base.tb->size);
1652bbe418f2SJia Liu }
1653a4fd3ec3SEmilio G. Cota 
1654a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = {
1655a4fd3ec3SEmilio G. Cota     .init_disas_context = openrisc_tr_init_disas_context,
1656a4fd3ec3SEmilio G. Cota     .tb_start           = openrisc_tr_tb_start,
1657a4fd3ec3SEmilio G. Cota     .insn_start         = openrisc_tr_insn_start,
1658a4fd3ec3SEmilio G. Cota     .breakpoint_check   = openrisc_tr_breakpoint_check,
1659a4fd3ec3SEmilio G. Cota     .translate_insn     = openrisc_tr_translate_insn,
1660a4fd3ec3SEmilio G. Cota     .tb_stop            = openrisc_tr_tb_stop,
1661a4fd3ec3SEmilio G. Cota     .disas_log          = openrisc_tr_disas_log,
1662a4fd3ec3SEmilio G. Cota };
1663a4fd3ec3SEmilio G. Cota 
1664a4fd3ec3SEmilio G. Cota void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
1665a4fd3ec3SEmilio G. Cota {
1666a4fd3ec3SEmilio G. Cota     DisasContext ctx;
1667a4fd3ec3SEmilio G. Cota 
1668a4fd3ec3SEmilio G. Cota     translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb);
1669e67db06eSJia Liu }
1670e67db06eSJia Liu 
1671878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
1672e67db06eSJia Liu                              fprintf_function cpu_fprintf,
1673e67db06eSJia Liu                              int flags)
1674e67db06eSJia Liu {
1675878096eeSAndreas Färber     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1676878096eeSAndreas Färber     CPUOpenRISCState *env = &cpu->env;
1677e67db06eSJia Liu     int i;
1678878096eeSAndreas Färber 
1679e67db06eSJia Liu     cpu_fprintf(f, "PC=%08x\n", env->pc);
1680e67db06eSJia Liu     for (i = 0; i < 32; ++i) {
1681d89e71e8SStafford Horne         cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
1682e67db06eSJia Liu                     (i % 4) == 3 ? '\n' : ' ');
1683e67db06eSJia Liu     }
1684e67db06eSJia Liu }
1685e67db06eSJia Liu 
1686e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
1687bad729e2SRichard Henderson                           target_ulong *data)
1688e67db06eSJia Liu {
1689bad729e2SRichard Henderson     env->pc = data[0];
1690a01deb36SRichard Henderson     env->dflag = data[1] & 1;
1691a01deb36SRichard Henderson     if (data[1] & 2) {
169224c32852SRichard Henderson         env->ppc = env->pc - 4;
169324c32852SRichard Henderson     }
1694e67db06eSJia Liu }
1695