xref: /qemu/target/openrisc/translate.c (revision 7de9729f08043399325e37b26637493313b4543d)
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"
34*7de9729fSRichard 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 
55*7de9729fSRichard Henderson /* Include the auto-generated decoder.  */
56*7de9729fSRichard Henderson #include "decode.inc.c"
57*7de9729fSRichard 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 
1966da544a6SRichard Henderson static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
197bbe418f2SJia Liu {
1981ffa4bceSEmilio G. Cota     target_ulong tmp_pc = dc->base.pc_next + n26 * 4;
199bbe418f2SJia Liu 
200da1d7759SSebastian Macke     switch (op0) {
201da1d7759SSebastian Macke     case 0x00:     /* l.j */
202bbe418f2SJia Liu         tcg_gen_movi_tl(jmp_pc, tmp_pc);
203da1d7759SSebastian Macke         break;
204da1d7759SSebastian Macke     case 0x01:     /* l.jal */
2051ffa4bceSEmilio G. Cota         tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
206a8000cb4SRichard Henderson         /* Optimize jal being used to load the PC for PIC.  */
2071ffa4bceSEmilio G. Cota         if (tmp_pc == dc->base.pc_next + 8) {
208a8000cb4SRichard Henderson             return;
209a8000cb4SRichard Henderson         }
210bbe418f2SJia Liu         tcg_gen_movi_tl(jmp_pc, tmp_pc);
211da1d7759SSebastian Macke         break;
212da1d7759SSebastian Macke     case 0x03:     /* l.bnf */
213da1d7759SSebastian Macke     case 0x04:     /* l.bf  */
214da1d7759SSebastian Macke         {
2151ffa4bceSEmilio G. Cota             TCGv t_next = tcg_const_tl(dc->base.pc_next + 8);
216784696d1SRichard Henderson             TCGv t_true = tcg_const_tl(tmp_pc);
217784696d1SRichard Henderson             TCGv t_zero = tcg_const_tl(0);
218784696d1SRichard Henderson 
219784696d1SRichard Henderson             tcg_gen_movcond_tl(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
220784696d1SRichard Henderson                                jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
221784696d1SRichard Henderson 
222784696d1SRichard Henderson             tcg_temp_free(t_next);
223784696d1SRichard Henderson             tcg_temp_free(t_true);
224784696d1SRichard Henderson             tcg_temp_free(t_zero);
225da1d7759SSebastian Macke         }
226da1d7759SSebastian Macke         break;
227da1d7759SSebastian Macke     case 0x11:     /* l.jr */
228bbe418f2SJia Liu         tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
229da1d7759SSebastian Macke         break;
230da1d7759SSebastian Macke     case 0x12:     /* l.jalr */
2311ffa4bceSEmilio G. Cota         tcg_gen_movi_tl(cpu_R[9], (dc->base.pc_next + 8));
232bbe418f2SJia Liu         tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
233da1d7759SSebastian Macke         break;
234da1d7759SSebastian Macke     default:
235bbe418f2SJia Liu         gen_illegal_exception(dc);
236da1d7759SSebastian Macke         break;
237bbe418f2SJia Liu     }
238bbe418f2SJia Liu 
239bbe418f2SJia Liu     dc->delayed_branch = 2;
240bbe418f2SJia Liu }
241bbe418f2SJia Liu 
24297458071SRichard Henderson static void gen_ove_cy(DisasContext *dc)
2439ecaa27eSRichard Henderson {
2440c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
24597458071SRichard Henderson         gen_helper_ove_cy(cpu_env);
2469ecaa27eSRichard Henderson     }
2470c53d734SRichard Henderson }
2489ecaa27eSRichard Henderson 
24997458071SRichard Henderson static void gen_ove_ov(DisasContext *dc)
2509ecaa27eSRichard Henderson {
2510c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
25297458071SRichard Henderson         gen_helper_ove_ov(cpu_env);
2539ecaa27eSRichard Henderson     }
2540c53d734SRichard Henderson }
2559ecaa27eSRichard Henderson 
25697458071SRichard Henderson static void gen_ove_cyov(DisasContext *dc)
2579ecaa27eSRichard Henderson {
2580c53d734SRichard Henderson     if (dc->tb_flags & SR_OVE) {
25997458071SRichard Henderson         gen_helper_ove_cyov(cpu_env);
2609ecaa27eSRichard Henderson     }
2610c53d734SRichard Henderson }
2629ecaa27eSRichard Henderson 
2639ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2649ecaa27eSRichard Henderson {
2659ecaa27eSRichard Henderson     TCGv t0 = tcg_const_tl(0);
2669ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
2679ecaa27eSRichard Henderson 
26897458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
26997458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2709ecaa27eSRichard Henderson     tcg_gen_xor_tl(t0, res, srcb);
27197458071SRichard Henderson     tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2729ecaa27eSRichard Henderson     tcg_temp_free(t0);
2739ecaa27eSRichard Henderson 
2749ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
2759ecaa27eSRichard Henderson     tcg_temp_free(res);
2769ecaa27eSRichard Henderson 
27797458071SRichard Henderson     gen_ove_cyov(dc);
2789ecaa27eSRichard Henderson }
2799ecaa27eSRichard Henderson 
2809ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2819ecaa27eSRichard Henderson {
2829ecaa27eSRichard Henderson     TCGv t0 = tcg_const_tl(0);
2839ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
2849ecaa27eSRichard Henderson 
28597458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
28697458071SRichard Henderson     tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
28797458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2889ecaa27eSRichard Henderson     tcg_gen_xor_tl(t0, res, srcb);
28997458071SRichard Henderson     tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2909ecaa27eSRichard Henderson     tcg_temp_free(t0);
2919ecaa27eSRichard Henderson 
2929ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
2939ecaa27eSRichard Henderson     tcg_temp_free(res);
2949ecaa27eSRichard Henderson 
29597458071SRichard Henderson     gen_ove_cyov(dc);
2969ecaa27eSRichard Henderson }
2979ecaa27eSRichard Henderson 
2989ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2999ecaa27eSRichard Henderson {
3009ecaa27eSRichard Henderson     TCGv res = tcg_temp_new();
3019ecaa27eSRichard Henderson 
3029ecaa27eSRichard Henderson     tcg_gen_sub_tl(res, srca, srcb);
30397458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
30497458071SRichard Henderson     tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
30597458071SRichard Henderson     tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
30697458071SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
3079ecaa27eSRichard Henderson 
3089ecaa27eSRichard Henderson     tcg_gen_mov_tl(dest, res);
3099ecaa27eSRichard Henderson     tcg_temp_free(res);
3109ecaa27eSRichard Henderson 
31197458071SRichard Henderson     gen_ove_cyov(dc);
3129ecaa27eSRichard Henderson }
3139ecaa27eSRichard Henderson 
3149ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
3159ecaa27eSRichard Henderson {
3169ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
3179ecaa27eSRichard Henderson 
31897458071SRichard Henderson     tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
3199ecaa27eSRichard Henderson     tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
32097458071SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
3219ecaa27eSRichard Henderson     tcg_temp_free(t0);
3229ecaa27eSRichard Henderson 
32397458071SRichard Henderson     tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
32497458071SRichard Henderson     gen_ove_ov(dc);
3259ecaa27eSRichard Henderson }
3269ecaa27eSRichard Henderson 
3279ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
3289ecaa27eSRichard Henderson {
32997458071SRichard Henderson     tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
33097458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
3319ecaa27eSRichard Henderson 
33297458071SRichard Henderson     gen_ove_cy(dc);
3339ecaa27eSRichard Henderson }
3349ecaa27eSRichard Henderson 
3359ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
3369ecaa27eSRichard Henderson {
3379ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
3389ecaa27eSRichard Henderson 
33997458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
3409ecaa27eSRichard Henderson     /* The result of divide-by-zero is undefined.
3419ecaa27eSRichard Henderson        Supress the host-side exception by dividing by 1.  */
34297458071SRichard Henderson     tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
3439ecaa27eSRichard Henderson     tcg_gen_div_tl(dest, srca, t0);
3449ecaa27eSRichard Henderson     tcg_temp_free(t0);
3459ecaa27eSRichard Henderson 
34697458071SRichard Henderson     tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
34797458071SRichard Henderson     gen_ove_ov(dc);
3489ecaa27eSRichard Henderson }
3499ecaa27eSRichard Henderson 
3509ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
3519ecaa27eSRichard Henderson {
3529ecaa27eSRichard Henderson     TCGv t0 = tcg_temp_new();
3539ecaa27eSRichard Henderson 
35497458071SRichard Henderson     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
3559ecaa27eSRichard Henderson     /* The result of divide-by-zero is undefined.
3569ecaa27eSRichard Henderson        Supress the host-side exception by dividing by 1.  */
35797458071SRichard Henderson     tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
3589ecaa27eSRichard Henderson     tcg_gen_divu_tl(dest, srca, t0);
3599ecaa27eSRichard Henderson     tcg_temp_free(t0);
3609ecaa27eSRichard Henderson 
36197458071SRichard Henderson     gen_ove_cy(dc);
3629ecaa27eSRichard Henderson }
363da1d7759SSebastian Macke 
364cc5de49eSRichard Henderson static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
365cc5de49eSRichard Henderson {
366cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
367cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
368cc5de49eSRichard Henderson 
369cc5de49eSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
370cc5de49eSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
371cc5de49eSRichard Henderson     if (TARGET_LONG_BITS == 32) {
372cc5de49eSRichard Henderson         tcg_gen_mul_i64(cpu_mac, t1, t2);
373cc5de49eSRichard Henderson         tcg_gen_movi_tl(cpu_sr_ov, 0);
374cc5de49eSRichard Henderson     } else {
375cc5de49eSRichard Henderson         TCGv_i64 high = tcg_temp_new_i64();
376cc5de49eSRichard Henderson 
377cc5de49eSRichard Henderson         tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
378cc5de49eSRichard Henderson         tcg_gen_sari_i64(t1, cpu_mac, 63);
379cc5de49eSRichard Henderson         tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
380cc5de49eSRichard Henderson         tcg_temp_free_i64(high);
381cc5de49eSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
382cc5de49eSRichard Henderson         tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
383cc5de49eSRichard Henderson 
384cc5de49eSRichard Henderson         gen_ove_ov(dc);
385cc5de49eSRichard Henderson     }
386cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
387cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
388cc5de49eSRichard Henderson }
389cc5de49eSRichard Henderson 
390cc5de49eSRichard Henderson static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
391cc5de49eSRichard Henderson {
392cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
393cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
394cc5de49eSRichard Henderson 
395cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
396cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
397cc5de49eSRichard Henderson     if (TARGET_LONG_BITS == 32) {
398cc5de49eSRichard Henderson         tcg_gen_mul_i64(cpu_mac, t1, t2);
399cc5de49eSRichard Henderson         tcg_gen_movi_tl(cpu_sr_cy, 0);
400cc5de49eSRichard Henderson     } else {
401cc5de49eSRichard Henderson         TCGv_i64 high = tcg_temp_new_i64();
402cc5de49eSRichard Henderson 
403cc5de49eSRichard Henderson         tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
404cc5de49eSRichard Henderson         tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
405cc5de49eSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
406cc5de49eSRichard Henderson         tcg_temp_free_i64(high);
407cc5de49eSRichard Henderson 
408cc5de49eSRichard Henderson         gen_ove_cy(dc);
409cc5de49eSRichard Henderson     }
410cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
411cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
412cc5de49eSRichard Henderson }
413cc5de49eSRichard Henderson 
4146f7332baSRichard Henderson static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
4156f7332baSRichard Henderson {
4166f7332baSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
4176f7332baSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
4186f7332baSRichard Henderson 
4196f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
4206f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
4216f7332baSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
4226f7332baSRichard Henderson 
4236f7332baSRichard Henderson     /* Note that overflow is only computed during addition stage.  */
4246f7332baSRichard Henderson     tcg_gen_xor_i64(t2, cpu_mac, t1);
4256f7332baSRichard Henderson     tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
4266f7332baSRichard Henderson     tcg_gen_xor_i64(t1, t1, cpu_mac);
4276f7332baSRichard Henderson     tcg_gen_andc_i64(t1, t1, t2);
4286f7332baSRichard Henderson     tcg_temp_free_i64(t2);
4296f7332baSRichard Henderson 
4306f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
4316f7332baSRichard Henderson     tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
4326f7332baSRichard Henderson #else
4336f7332baSRichard Henderson     tcg_gen_mov_i64(cpu_sr_ov, t1);
4346f7332baSRichard Henderson #endif
4356f7332baSRichard Henderson     tcg_temp_free_i64(t1);
4366f7332baSRichard Henderson 
4376f7332baSRichard Henderson     gen_ove_ov(dc);
4386f7332baSRichard Henderson }
4396f7332baSRichard Henderson 
440cc5de49eSRichard Henderson static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
441cc5de49eSRichard Henderson {
442cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
443cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
444cc5de49eSRichard Henderson 
445cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
446cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
447cc5de49eSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
448cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
449cc5de49eSRichard Henderson 
450cc5de49eSRichard Henderson     /* Note that overflow is only computed during addition stage.  */
451cc5de49eSRichard Henderson     tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
452cc5de49eSRichard Henderson     tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
453cc5de49eSRichard Henderson     tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
454cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
455cc5de49eSRichard Henderson 
456cc5de49eSRichard Henderson     gen_ove_cy(dc);
457cc5de49eSRichard Henderson }
458cc5de49eSRichard Henderson 
4596f7332baSRichard Henderson static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
4606f7332baSRichard Henderson {
4616f7332baSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
4626f7332baSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
4636f7332baSRichard Henderson 
4646f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t1, srca);
4656f7332baSRichard Henderson     tcg_gen_ext_tl_i64(t2, srcb);
4666f7332baSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
4676f7332baSRichard Henderson 
4686f7332baSRichard Henderson     /* Note that overflow is only computed during subtraction stage.  */
4696f7332baSRichard Henderson     tcg_gen_xor_i64(t2, cpu_mac, t1);
4706f7332baSRichard Henderson     tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
4716f7332baSRichard Henderson     tcg_gen_xor_i64(t1, t1, cpu_mac);
4726f7332baSRichard Henderson     tcg_gen_and_i64(t1, t1, t2);
4736f7332baSRichard Henderson     tcg_temp_free_i64(t2);
4746f7332baSRichard Henderson 
4756f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
4766f7332baSRichard Henderson     tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
4776f7332baSRichard Henderson #else
4786f7332baSRichard Henderson     tcg_gen_mov_i64(cpu_sr_ov, t1);
4796f7332baSRichard Henderson #endif
4806f7332baSRichard Henderson     tcg_temp_free_i64(t1);
4816f7332baSRichard Henderson 
4826f7332baSRichard Henderson     gen_ove_ov(dc);
4836f7332baSRichard Henderson }
4846f7332baSRichard Henderson 
485cc5de49eSRichard Henderson static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
486cc5de49eSRichard Henderson {
487cc5de49eSRichard Henderson     TCGv_i64 t1 = tcg_temp_new_i64();
488cc5de49eSRichard Henderson     TCGv_i64 t2 = tcg_temp_new_i64();
489cc5de49eSRichard Henderson 
490cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t1, srca);
491cc5de49eSRichard Henderson     tcg_gen_extu_tl_i64(t2, srcb);
492cc5de49eSRichard Henderson     tcg_gen_mul_i64(t1, t1, t2);
493cc5de49eSRichard Henderson 
494cc5de49eSRichard Henderson     /* Note that overflow is only computed during subtraction stage.  */
495cc5de49eSRichard Henderson     tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
496cc5de49eSRichard Henderson     tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
497cc5de49eSRichard Henderson     tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
498cc5de49eSRichard Henderson     tcg_temp_free_i64(t2);
499cc5de49eSRichard Henderson     tcg_temp_free_i64(t1);
500cc5de49eSRichard Henderson 
501cc5de49eSRichard Henderson     gen_ove_cy(dc);
502cc5de49eSRichard Henderson }
503cc5de49eSRichard Henderson 
504930c3d00SRichard Henderson static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
505930c3d00SRichard Henderson {
506930c3d00SRichard Henderson     TCGv ea = tcg_temp_new();
507930c3d00SRichard Henderson 
508930c3d00SRichard Henderson     tcg_gen_addi_tl(ea, ra, ofs);
509930c3d00SRichard Henderson     tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL);
510930c3d00SRichard Henderson     tcg_gen_mov_tl(cpu_lock_addr, ea);
511930c3d00SRichard Henderson     tcg_gen_mov_tl(cpu_lock_value, rd);
512930c3d00SRichard Henderson     tcg_temp_free(ea);
513930c3d00SRichard Henderson }
514930c3d00SRichard Henderson 
5156597c28dSRichard Henderson static void gen_swa(DisasContext *dc, int b, TCGv ra, int32_t ofs)
516930c3d00SRichard Henderson {
517930c3d00SRichard Henderson     TCGv ea, val;
518930c3d00SRichard Henderson     TCGLabel *lab_fail, *lab_done;
519930c3d00SRichard Henderson 
520930c3d00SRichard Henderson     ea = tcg_temp_new();
521930c3d00SRichard Henderson     tcg_gen_addi_tl(ea, ra, ofs);
522930c3d00SRichard Henderson 
5236597c28dSRichard Henderson     /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
5246597c28dSRichard Henderson        to cpu_R[0].  Since l.swa is quite often immediately followed by a
5256597c28dSRichard Henderson        branch, don't bother reallocating; finish the TB using the "real" R0.
5266597c28dSRichard Henderson        This also takes care of RB input across the branch.  */
5276597c28dSRichard Henderson     cpu_R[0] = cpu_R0;
5286597c28dSRichard Henderson 
529930c3d00SRichard Henderson     lab_fail = gen_new_label();
530930c3d00SRichard Henderson     lab_done = gen_new_label();
531930c3d00SRichard Henderson     tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
532930c3d00SRichard Henderson     tcg_temp_free(ea);
533930c3d00SRichard Henderson 
534930c3d00SRichard Henderson     val = tcg_temp_new();
535930c3d00SRichard Henderson     tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
5366597c28dSRichard Henderson                               cpu_R[b], dc->mem_idx, MO_TEUL);
53784775c43SRichard Henderson     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
538930c3d00SRichard Henderson     tcg_temp_free(val);
539930c3d00SRichard Henderson 
540930c3d00SRichard Henderson     tcg_gen_br(lab_done);
541930c3d00SRichard Henderson 
542930c3d00SRichard Henderson     gen_set_label(lab_fail);
54384775c43SRichard Henderson     tcg_gen_movi_tl(cpu_sr_f, 0);
544930c3d00SRichard Henderson 
545930c3d00SRichard Henderson     gen_set_label(lab_done);
546930c3d00SRichard Henderson     tcg_gen_movi_tl(cpu_lock_addr, -1);
547930c3d00SRichard Henderson }
548930c3d00SRichard Henderson 
549bbe418f2SJia Liu static void dec_calc(DisasContext *dc, uint32_t insn)
550bbe418f2SJia Liu {
551bbe418f2SJia Liu     uint32_t op0, op1, op2;
552bbe418f2SJia Liu     uint32_t ra, rb, rd;
553bbe418f2SJia Liu     op0 = extract32(insn, 0, 4);
554bbe418f2SJia Liu     op1 = extract32(insn, 8, 2);
555bbe418f2SJia Liu     op2 = extract32(insn, 6, 2);
556bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
557bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
558bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
559bbe418f2SJia Liu 
560bbe418f2SJia Liu     switch (op1) {
561cf2ae442SRichard Henderson     case 0:
562cf2ae442SRichard Henderson         switch (op0) {
563cf2ae442SRichard Henderson         case 0x0: /* l.add */
564bbe418f2SJia Liu             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
5659ecaa27eSRichard Henderson             gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
566cf2ae442SRichard Henderson             return;
567bbe418f2SJia Liu 
568cf2ae442SRichard Henderson         case 0x1: /* l.addc */
569bbe418f2SJia Liu             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
5709ecaa27eSRichard Henderson             gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
571cf2ae442SRichard Henderson             return;
572bbe418f2SJia Liu 
573cf2ae442SRichard Henderson         case 0x2: /* l.sub */
574bbe418f2SJia Liu             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
5759ecaa27eSRichard Henderson             gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
576cf2ae442SRichard Henderson             return;
577bbe418f2SJia Liu 
578cf2ae442SRichard Henderson         case 0x3: /* l.and */
579bbe418f2SJia Liu             LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
580bbe418f2SJia Liu             tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
581cf2ae442SRichard Henderson             return;
582bbe418f2SJia Liu 
583cf2ae442SRichard Henderson         case 0x4: /* l.or */
584bbe418f2SJia Liu             LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
585bbe418f2SJia Liu             tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
586cf2ae442SRichard Henderson             return;
587bbe418f2SJia Liu 
588cf2ae442SRichard Henderson         case 0x5: /* l.xor */
589bbe418f2SJia Liu             LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
590bbe418f2SJia Liu             tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
591cf2ae442SRichard Henderson             return;
592cf2ae442SRichard Henderson 
593cf2ae442SRichard Henderson         case 0x8:
594cf2ae442SRichard Henderson             switch (op2) {
595cf2ae442SRichard Henderson             case 0: /* l.sll */
596cf2ae442SRichard Henderson                 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
597cf2ae442SRichard Henderson                 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
598cf2ae442SRichard Henderson                 return;
599cf2ae442SRichard Henderson             case 1: /* l.srl */
600cf2ae442SRichard Henderson                 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
601cf2ae442SRichard Henderson                 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
602cf2ae442SRichard Henderson                 return;
603cf2ae442SRichard Henderson             case 2: /* l.sra */
604cf2ae442SRichard Henderson                 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
605cf2ae442SRichard Henderson                 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
606cf2ae442SRichard Henderson                 return;
607cf2ae442SRichard Henderson             case 3: /* l.ror */
608cf2ae442SRichard Henderson                 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
609cf2ae442SRichard Henderson                 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
610cf2ae442SRichard Henderson                 return;
611bbe418f2SJia Liu             }
612bbe418f2SJia Liu             break;
613bbe418f2SJia Liu 
614cf2ae442SRichard Henderson         case 0xc:
615cf2ae442SRichard Henderson             switch (op2) {
616cf2ae442SRichard Henderson             case 0: /* l.exths */
617cf2ae442SRichard Henderson                 LOG_DIS("l.exths r%d, r%d\n", rd, ra);
618cf2ae442SRichard Henderson                 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
619cf2ae442SRichard Henderson                 return;
620cf2ae442SRichard Henderson             case 1: /* l.extbs */
621cf2ae442SRichard Henderson                 LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
622cf2ae442SRichard Henderson                 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
623cf2ae442SRichard Henderson                 return;
624cf2ae442SRichard Henderson             case 2: /* l.exthz */
625cf2ae442SRichard Henderson                 LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
626cf2ae442SRichard Henderson                 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
627cf2ae442SRichard Henderson                 return;
628cf2ae442SRichard Henderson             case 3: /* l.extbz */
629cf2ae442SRichard Henderson                 LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
630cf2ae442SRichard Henderson                 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
631cf2ae442SRichard Henderson                 return;
632bbe418f2SJia Liu             }
633bbe418f2SJia Liu             break;
634bbe418f2SJia Liu 
635cf2ae442SRichard Henderson         case 0xd:
636cf2ae442SRichard Henderson             switch (op2) {
637cf2ae442SRichard Henderson             case 0: /* l.extws */
638cf2ae442SRichard Henderson                 LOG_DIS("l.extws r%d, r%d\n", rd, ra);
639cf2ae442SRichard Henderson                 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
640cf2ae442SRichard Henderson                 return;
641cf2ae442SRichard Henderson             case 1: /* l.extwz */
642cf2ae442SRichard Henderson                 LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
643cf2ae442SRichard Henderson                 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
644cf2ae442SRichard Henderson                 return;
645bbe418f2SJia Liu             }
646bbe418f2SJia Liu             break;
647bbe418f2SJia Liu 
648cf2ae442SRichard Henderson         case 0xe: /* l.cmov */
649bbe418f2SJia Liu             LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
650bbe418f2SJia Liu             {
651784696d1SRichard Henderson                 TCGv zero = tcg_const_tl(0);
652784696d1SRichard Henderson                 tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero,
653784696d1SRichard Henderson                                    cpu_R[ra], cpu_R[rb]);
654784696d1SRichard Henderson                 tcg_temp_free(zero);
655bbe418f2SJia Liu             }
656cf2ae442SRichard Henderson             return;
657bbe418f2SJia Liu 
658cf2ae442SRichard Henderson         case 0xf: /* l.ff1 */
659bbe418f2SJia Liu             LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
660555baef8SRichard Henderson             tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);
661555baef8SRichard Henderson             tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);
662cf2ae442SRichard Henderson             return;
663cf2ae442SRichard Henderson         }
664bbe418f2SJia Liu         break;
665cf2ae442SRichard Henderson 
666cf2ae442SRichard Henderson     case 1:
667cf2ae442SRichard Henderson         switch (op0) {
668cf2ae442SRichard Henderson         case 0xf: /* l.fl1 */
669bbe418f2SJia Liu             LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
670555baef8SRichard Henderson             tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);
671555baef8SRichard Henderson             tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);
672cf2ae442SRichard Henderson             return;
673bbe418f2SJia Liu         }
674bbe418f2SJia Liu         break;
675bbe418f2SJia Liu 
676cf2ae442SRichard Henderson     case 2:
677bbe418f2SJia Liu         break;
678bbe418f2SJia Liu 
679cf2ae442SRichard Henderson     case 3:
680cf2ae442SRichard Henderson         switch (op0) {
681cf2ae442SRichard Henderson         case 0x6: /* l.mul */
682cf2ae442SRichard Henderson             LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
683cf2ae442SRichard Henderson             gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
684cf2ae442SRichard Henderson             return;
685cf2ae442SRichard Henderson 
686cc5de49eSRichard Henderson         case 0x7: /* l.muld */
687cc5de49eSRichard Henderson             LOG_DIS("l.muld r%d, r%d\n", ra, rb);
688cc5de49eSRichard Henderson             gen_muld(dc, cpu_R[ra], cpu_R[rb]);
689cc5de49eSRichard Henderson             break;
690cc5de49eSRichard Henderson 
691cf2ae442SRichard Henderson         case 0x9: /* l.div */
692cf2ae442SRichard Henderson             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
693cf2ae442SRichard Henderson             gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
694cf2ae442SRichard Henderson             return;
695cf2ae442SRichard Henderson 
696cf2ae442SRichard Henderson         case 0xa: /* l.divu */
697cf2ae442SRichard Henderson             LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
698cf2ae442SRichard Henderson             gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
699cf2ae442SRichard Henderson             return;
700cf2ae442SRichard Henderson 
701cf2ae442SRichard Henderson         case 0xb: /* l.mulu */
702cf2ae442SRichard Henderson             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
703cf2ae442SRichard Henderson             gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
704cf2ae442SRichard Henderson             return;
705cc5de49eSRichard Henderson 
706cc5de49eSRichard Henderson         case 0xc: /* l.muldu */
707cc5de49eSRichard Henderson             LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
708cc5de49eSRichard Henderson             gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
709cc5de49eSRichard Henderson             return;
710bbe418f2SJia Liu         }
711bbe418f2SJia Liu         break;
712bbe418f2SJia Liu     }
713bbe418f2SJia Liu     gen_illegal_exception(dc);
714bbe418f2SJia Liu }
715bbe418f2SJia Liu 
716bbe418f2SJia Liu static void dec_misc(DisasContext *dc, uint32_t insn)
717bbe418f2SJia Liu {
718bbe418f2SJia Liu     uint32_t op0, op1;
719bbe418f2SJia Liu     uint32_t ra, rb, rd;
7206da544a6SRichard Henderson     uint32_t L6, K5, K16, K5_11;
7216da544a6SRichard Henderson     int32_t I16, I5_11, N26;
7225631e69cSRichard Henderson     TCGMemOp mop;
7239ecaa27eSRichard Henderson     TCGv t0;
7245631e69cSRichard Henderson 
725bbe418f2SJia Liu     op0 = extract32(insn, 26, 6);
726bbe418f2SJia Liu     op1 = extract32(insn, 24, 2);
727bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
728bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
729bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
730bbe418f2SJia Liu     L6 = extract32(insn, 5, 6);
731bbe418f2SJia Liu     K5 = extract32(insn, 0, 5);
7326da544a6SRichard Henderson     K16 = extract32(insn, 0, 16);
7336da544a6SRichard Henderson     I16 = (int16_t)K16;
7346da544a6SRichard Henderson     N26 = sextract32(insn, 0, 26);
7356da544a6SRichard Henderson     K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11);
7366da544a6SRichard Henderson     I5_11 = (int16_t)K5_11;
737bbe418f2SJia Liu 
738bbe418f2SJia Liu     switch (op0) {
739bbe418f2SJia Liu     case 0x00:    /* l.j */
740bbe418f2SJia Liu         LOG_DIS("l.j %d\n", N26);
741bbe418f2SJia Liu         gen_jump(dc, N26, 0, op0);
742bbe418f2SJia Liu         break;
743bbe418f2SJia Liu 
744bbe418f2SJia Liu     case 0x01:    /* l.jal */
745bbe418f2SJia Liu         LOG_DIS("l.jal %d\n", N26);
746bbe418f2SJia Liu         gen_jump(dc, N26, 0, op0);
747bbe418f2SJia Liu         break;
748bbe418f2SJia Liu 
749bbe418f2SJia Liu     case 0x03:    /* l.bnf */
750bbe418f2SJia Liu         LOG_DIS("l.bnf %d\n", N26);
751bbe418f2SJia Liu         gen_jump(dc, N26, 0, op0);
752bbe418f2SJia Liu         break;
753bbe418f2SJia Liu 
754bbe418f2SJia Liu     case 0x04:    /* l.bf */
755bbe418f2SJia Liu         LOG_DIS("l.bf %d\n", N26);
756bbe418f2SJia Liu         gen_jump(dc, N26, 0, op0);
757bbe418f2SJia Liu         break;
758bbe418f2SJia Liu 
759bbe418f2SJia Liu     case 0x05:
760bbe418f2SJia Liu         switch (op1) {
761bbe418f2SJia Liu         case 0x01:    /* l.nop */
762bbe418f2SJia Liu             LOG_DIS("l.nop %d\n", I16);
763bbe418f2SJia Liu             break;
764bbe418f2SJia Liu 
765bbe418f2SJia Liu         default:
766bbe418f2SJia Liu             gen_illegal_exception(dc);
767bbe418f2SJia Liu             break;
768bbe418f2SJia Liu         }
769bbe418f2SJia Liu         break;
770bbe418f2SJia Liu 
771bbe418f2SJia Liu     case 0x11:    /* l.jr */
772bbe418f2SJia Liu         LOG_DIS("l.jr r%d\n", rb);
773bbe418f2SJia Liu          gen_jump(dc, 0, rb, op0);
774bbe418f2SJia Liu          break;
775bbe418f2SJia Liu 
776bbe418f2SJia Liu     case 0x12:    /* l.jalr */
777bbe418f2SJia Liu         LOG_DIS("l.jalr r%d\n", rb);
778bbe418f2SJia Liu         gen_jump(dc, 0, rb, op0);
779bbe418f2SJia Liu         break;
780bbe418f2SJia Liu 
781bbe418f2SJia Liu     case 0x13:    /* l.maci */
7826da544a6SRichard Henderson         LOG_DIS("l.maci r%d, %d\n", ra, I16);
7836f7332baSRichard Henderson         t0 = tcg_const_tl(I16);
7846f7332baSRichard Henderson         gen_mac(dc, cpu_R[ra], t0);
7856f7332baSRichard Henderson         tcg_temp_free(t0);
786bbe418f2SJia Liu         break;
787bbe418f2SJia Liu 
788bbe418f2SJia Liu     case 0x09:    /* l.rfe */
789bbe418f2SJia Liu         LOG_DIS("l.rfe\n");
790bbe418f2SJia Liu         {
791bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY)
792bbe418f2SJia Liu             return;
793bbe418f2SJia Liu #else
794bbe418f2SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
795bbe418f2SJia Liu                 gen_illegal_exception(dc);
796bbe418f2SJia Liu                 return;
797bbe418f2SJia Liu             }
798bbe418f2SJia Liu             gen_helper_rfe(cpu_env);
7991ffa4bceSEmilio G. Cota             dc->base.is_jmp = DISAS_UPDATE;
800bbe418f2SJia Liu #endif
801bbe418f2SJia Liu         }
802bbe418f2SJia Liu         break;
803bbe418f2SJia Liu 
804930c3d00SRichard Henderson     case 0x1b: /* l.lwa */
805930c3d00SRichard Henderson         LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
8066597c28dSRichard Henderson         check_r0_write(rd);
807930c3d00SRichard Henderson         gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16);
808930c3d00SRichard Henderson         break;
809930c3d00SRichard Henderson 
810bbe418f2SJia Liu     case 0x1c:    /* l.cust1 */
811bbe418f2SJia Liu         LOG_DIS("l.cust1\n");
812bbe418f2SJia Liu         break;
813bbe418f2SJia Liu 
814bbe418f2SJia Liu     case 0x1d:    /* l.cust2 */
815bbe418f2SJia Liu         LOG_DIS("l.cust2\n");
816bbe418f2SJia Liu         break;
817bbe418f2SJia Liu 
818bbe418f2SJia Liu     case 0x1e:    /* l.cust3 */
819bbe418f2SJia Liu         LOG_DIS("l.cust3\n");
820bbe418f2SJia Liu         break;
821bbe418f2SJia Liu 
822bbe418f2SJia Liu     case 0x1f:    /* l.cust4 */
823bbe418f2SJia Liu         LOG_DIS("l.cust4\n");
824bbe418f2SJia Liu         break;
825bbe418f2SJia Liu 
826bbe418f2SJia Liu     case 0x3c:    /* l.cust5 */
827bbe418f2SJia Liu         LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5);
828bbe418f2SJia Liu         break;
829bbe418f2SJia Liu 
830bbe418f2SJia Liu     case 0x3d:    /* l.cust6 */
831bbe418f2SJia Liu         LOG_DIS("l.cust6\n");
832bbe418f2SJia Liu         break;
833bbe418f2SJia Liu 
834bbe418f2SJia Liu     case 0x3e:    /* l.cust7 */
835bbe418f2SJia Liu         LOG_DIS("l.cust7\n");
836bbe418f2SJia Liu         break;
837bbe418f2SJia Liu 
838bbe418f2SJia Liu     case 0x3f:    /* l.cust8 */
839bbe418f2SJia Liu         LOG_DIS("l.cust8\n");
840bbe418f2SJia Liu         break;
841bbe418f2SJia Liu 
842bbe418f2SJia Liu /* not used yet, open it when we need or64.  */
843bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64
844bbe418f2SJia Liu     case 0x20:     l.ld
845bbe418f2SJia Liu         LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16);
846bbe418f2SJia Liu         check_ob64s(dc);
8475631e69cSRichard Henderson         mop = MO_TEQ;
8485631e69cSRichard Henderson         goto do_load;
849bbe418f2SJia Liu #endif*/
850bbe418f2SJia Liu 
851bbe418f2SJia Liu     case 0x21:    /* l.lwz */
852bbe418f2SJia Liu         LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16);
8535631e69cSRichard Henderson         mop = MO_TEUL;
8545631e69cSRichard Henderson         goto do_load;
855bbe418f2SJia Liu 
856bbe418f2SJia Liu     case 0x22:    /* l.lws */
857bbe418f2SJia Liu         LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16);
8585631e69cSRichard Henderson         mop = MO_TESL;
8595631e69cSRichard Henderson         goto do_load;
860bbe418f2SJia Liu 
861bbe418f2SJia Liu     case 0x23:    /* l.lbz */
862bbe418f2SJia Liu         LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16);
8635631e69cSRichard Henderson         mop = MO_UB;
8645631e69cSRichard Henderson         goto do_load;
865bbe418f2SJia Liu 
866bbe418f2SJia Liu     case 0x24:    /* l.lbs */
867bbe418f2SJia Liu         LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16);
8685631e69cSRichard Henderson         mop = MO_SB;
8695631e69cSRichard Henderson         goto do_load;
870bbe418f2SJia Liu 
871bbe418f2SJia Liu     case 0x25:    /* l.lhz */
872bbe418f2SJia Liu         LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16);
8735631e69cSRichard Henderson         mop = MO_TEUW;
8745631e69cSRichard Henderson         goto do_load;
875bbe418f2SJia Liu 
876bbe418f2SJia Liu     case 0x26:    /* l.lhs */
877bbe418f2SJia Liu         LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16);
8785631e69cSRichard Henderson         mop = MO_TESW;
8795631e69cSRichard Henderson         goto do_load;
8805631e69cSRichard Henderson 
8815631e69cSRichard Henderson     do_load:
8826597c28dSRichard Henderson         check_r0_write(rd);
8836597c28dSRichard Henderson         t0 = tcg_temp_new();
8846da544a6SRichard Henderson         tcg_gen_addi_tl(t0, cpu_R[ra], I16);
8855631e69cSRichard Henderson         tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop);
886bbe418f2SJia Liu         tcg_temp_free(t0);
887bbe418f2SJia Liu         break;
888bbe418f2SJia Liu 
889bbe418f2SJia Liu     case 0x27:    /* l.addi */
890bbe418f2SJia Liu         LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
8916597c28dSRichard Henderson         check_r0_write(rd);
8929ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
8939ecaa27eSRichard Henderson         gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
8949ecaa27eSRichard Henderson         tcg_temp_free(t0);
895bbe418f2SJia Liu         break;
896bbe418f2SJia Liu 
897bbe418f2SJia Liu     case 0x28:    /* l.addic */
898bbe418f2SJia Liu         LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
8996597c28dSRichard Henderson         check_r0_write(rd);
9009ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
9019ecaa27eSRichard Henderson         gen_addc(dc, cpu_R[rd], cpu_R[ra], t0);
9029ecaa27eSRichard Henderson         tcg_temp_free(t0);
903bbe418f2SJia Liu         break;
904bbe418f2SJia Liu 
905bbe418f2SJia Liu     case 0x29:    /* l.andi */
9066da544a6SRichard Henderson         LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16);
9076597c28dSRichard Henderson         check_r0_write(rd);
9086da544a6SRichard Henderson         tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16);
909bbe418f2SJia Liu         break;
910bbe418f2SJia Liu 
911bbe418f2SJia Liu     case 0x2a:    /* l.ori */
9126da544a6SRichard Henderson         LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16);
9136597c28dSRichard Henderson         check_r0_write(rd);
9146da544a6SRichard Henderson         tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16);
915bbe418f2SJia Liu         break;
916bbe418f2SJia Liu 
917bbe418f2SJia Liu     case 0x2b:    /* l.xori */
918bbe418f2SJia Liu         LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
9196597c28dSRichard Henderson         check_r0_write(rd);
9206da544a6SRichard Henderson         tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16);
921bbe418f2SJia Liu         break;
922bbe418f2SJia Liu 
923bbe418f2SJia Liu     case 0x2c:    /* l.muli */
924bbe418f2SJia Liu         LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
9256597c28dSRichard Henderson         check_r0_write(rd);
9269ecaa27eSRichard Henderson         t0 = tcg_const_tl(I16);
9279ecaa27eSRichard Henderson         gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
9289ecaa27eSRichard Henderson         tcg_temp_free(t0);
929bbe418f2SJia Liu         break;
930bbe418f2SJia Liu 
931bbe418f2SJia Liu     case 0x2d:    /* l.mfspr */
9326da544a6SRichard Henderson         LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
9336597c28dSRichard Henderson         check_r0_write(rd);
9344dd044c6SJia Liu         {
9354dd044c6SJia Liu #if defined(CONFIG_USER_ONLY)
9364dd044c6SJia Liu             return;
9374dd044c6SJia Liu #else
9386da544a6SRichard Henderson             TCGv_i32 ti = tcg_const_i32(K16);
9394dd044c6SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
9404dd044c6SJia Liu                 gen_illegal_exception(dc);
9414dd044c6SJia Liu                 return;
9424dd044c6SJia Liu             }
9434dd044c6SJia Liu             gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
9444dd044c6SJia Liu             tcg_temp_free_i32(ti);
9454dd044c6SJia Liu #endif
9464dd044c6SJia Liu         }
947bbe418f2SJia Liu         break;
948bbe418f2SJia Liu 
949bbe418f2SJia Liu     case 0x30:    /* l.mtspr */
9506da544a6SRichard Henderson         LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
9514dd044c6SJia Liu         {
9524dd044c6SJia Liu #if defined(CONFIG_USER_ONLY)
9534dd044c6SJia Liu             return;
9544dd044c6SJia Liu #else
9556da544a6SRichard Henderson             TCGv_i32 im = tcg_const_i32(K5_11);
9564dd044c6SJia Liu             if (dc->mem_idx == MMU_USER_IDX) {
9574dd044c6SJia Liu                 gen_illegal_exception(dc);
9584dd044c6SJia Liu                 return;
9594dd044c6SJia Liu             }
9604dd044c6SJia Liu             gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
9614dd044c6SJia Liu             tcg_temp_free_i32(im);
9624dd044c6SJia Liu #endif
9634dd044c6SJia Liu         }
964bbe418f2SJia Liu         break;
965bbe418f2SJia Liu 
966930c3d00SRichard Henderson     case 0x33: /* l.swa */
9676da544a6SRichard Henderson         LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11);
9686597c28dSRichard Henderson         gen_swa(dc, rb, cpu_R[ra], I5_11);
969930c3d00SRichard Henderson         break;
970930c3d00SRichard Henderson 
971bbe418f2SJia Liu /* not used yet, open it when we need or64.  */
972bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64
973bbe418f2SJia Liu     case 0x34:     l.sd
9746da544a6SRichard Henderson         LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
975bbe418f2SJia Liu         check_ob64s(dc);
9765631e69cSRichard Henderson         mop = MO_TEQ;
9775631e69cSRichard Henderson         goto do_store;
978bbe418f2SJia Liu #endif*/
979bbe418f2SJia Liu 
980bbe418f2SJia Liu     case 0x35:    /* l.sw */
9816da544a6SRichard Henderson         LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11);
9825631e69cSRichard Henderson         mop = MO_TEUL;
9835631e69cSRichard Henderson         goto do_store;
984bbe418f2SJia Liu 
985bbe418f2SJia Liu     case 0x36:    /* l.sb */
9866da544a6SRichard Henderson         LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11);
9875631e69cSRichard Henderson         mop = MO_UB;
9885631e69cSRichard Henderson         goto do_store;
989bbe418f2SJia Liu 
990bbe418f2SJia Liu     case 0x37:    /* l.sh */
9916da544a6SRichard Henderson         LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11);
9925631e69cSRichard Henderson         mop = MO_TEUW;
9935631e69cSRichard Henderson         goto do_store;
9945631e69cSRichard Henderson 
9955631e69cSRichard Henderson     do_store:
996bbe418f2SJia Liu         {
997bbe418f2SJia Liu             TCGv t0 = tcg_temp_new();
9986da544a6SRichard Henderson             tcg_gen_addi_tl(t0, cpu_R[ra], I5_11);
9995631e69cSRichard Henderson             tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop);
1000bbe418f2SJia Liu             tcg_temp_free(t0);
1001bbe418f2SJia Liu         }
1002bbe418f2SJia Liu         break;
1003bbe418f2SJia Liu 
1004bbe418f2SJia Liu     default:
1005bbe418f2SJia Liu         gen_illegal_exception(dc);
1006bbe418f2SJia Liu         break;
1007bbe418f2SJia Liu     }
1008bbe418f2SJia Liu }
1009bbe418f2SJia Liu 
1010bbe418f2SJia Liu static void dec_mac(DisasContext *dc, uint32_t insn)
1011bbe418f2SJia Liu {
1012bbe418f2SJia Liu     uint32_t op0;
1013bbe418f2SJia Liu     uint32_t ra, rb;
1014bbe418f2SJia Liu     op0 = extract32(insn, 0, 4);
1015bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1016bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1017bbe418f2SJia Liu 
1018bbe418f2SJia Liu     switch (op0) {
1019bbe418f2SJia Liu     case 0x0001:    /* l.mac */
1020bbe418f2SJia Liu         LOG_DIS("l.mac r%d, r%d\n", ra, rb);
10216f7332baSRichard Henderson         gen_mac(dc, cpu_R[ra], cpu_R[rb]);
1022bbe418f2SJia Liu         break;
1023bbe418f2SJia Liu 
1024bbe418f2SJia Liu     case 0x0002:    /* l.msb */
1025bbe418f2SJia Liu         LOG_DIS("l.msb r%d, r%d\n", ra, rb);
10266f7332baSRichard Henderson         gen_msb(dc, cpu_R[ra], cpu_R[rb]);
1027bbe418f2SJia Liu         break;
1028bbe418f2SJia Liu 
1029cc5de49eSRichard Henderson     case 0x0003:    /* l.macu */
1030cc5de49eSRichard Henderson         LOG_DIS("l.macu r%d, r%d\n", ra, rb);
1031cc5de49eSRichard Henderson         gen_macu(dc, cpu_R[ra], cpu_R[rb]);
1032cc5de49eSRichard Henderson         break;
1033cc5de49eSRichard Henderson 
1034cc5de49eSRichard Henderson     case 0x0004:    /* l.msbu */
1035cc5de49eSRichard Henderson         LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
1036cc5de49eSRichard Henderson         gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
1037cc5de49eSRichard Henderson         break;
1038cc5de49eSRichard Henderson 
1039bbe418f2SJia Liu     default:
1040bbe418f2SJia Liu         gen_illegal_exception(dc);
1041bbe418f2SJia Liu         break;
1042bbe418f2SJia Liu    }
1043bbe418f2SJia Liu }
1044bbe418f2SJia Liu 
1045bbe418f2SJia Liu static void dec_logic(DisasContext *dc, uint32_t insn)
1046bbe418f2SJia Liu {
1047bbe418f2SJia Liu     uint32_t op0;
10486da544a6SRichard Henderson     uint32_t rd, ra, L6, S6;
1049bbe418f2SJia Liu     op0 = extract32(insn, 6, 2);
1050bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1051bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1052bbe418f2SJia Liu     L6 = extract32(insn, 0, 6);
10536da544a6SRichard Henderson     S6 = L6 & (TARGET_LONG_BITS - 1);
1054bbe418f2SJia Liu 
10556597c28dSRichard Henderson     check_r0_write(rd);
1056bbe418f2SJia Liu     switch (op0) {
1057bbe418f2SJia Liu     case 0x00:    /* l.slli */
1058bbe418f2SJia Liu         LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
10596da544a6SRichard Henderson         tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6);
1060bbe418f2SJia Liu         break;
1061bbe418f2SJia Liu 
1062bbe418f2SJia Liu     case 0x01:    /* l.srli */
1063bbe418f2SJia Liu         LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
10646da544a6SRichard Henderson         tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6);
1065bbe418f2SJia Liu         break;
1066bbe418f2SJia Liu 
1067bbe418f2SJia Liu     case 0x02:    /* l.srai */
1068bbe418f2SJia Liu         LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
10696da544a6SRichard Henderson         tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6);
10706da544a6SRichard Henderson         break;
1071bbe418f2SJia Liu 
1072bbe418f2SJia Liu     case 0x03:    /* l.rori */
1073bbe418f2SJia Liu         LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
10746da544a6SRichard Henderson         tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6);
1075bbe418f2SJia Liu         break;
1076bbe418f2SJia Liu 
1077bbe418f2SJia Liu     default:
1078bbe418f2SJia Liu         gen_illegal_exception(dc);
1079bbe418f2SJia Liu         break;
1080bbe418f2SJia Liu     }
1081bbe418f2SJia Liu }
1082bbe418f2SJia Liu 
1083bbe418f2SJia Liu static void dec_M(DisasContext *dc, uint32_t insn)
1084bbe418f2SJia Liu {
1085bbe418f2SJia Liu     uint32_t op0;
1086bbe418f2SJia Liu     uint32_t rd;
1087bbe418f2SJia Liu     uint32_t K16;
1088bbe418f2SJia Liu     op0 = extract32(insn, 16, 1);
1089bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1090bbe418f2SJia Liu     K16 = extract32(insn, 0, 16);
1091bbe418f2SJia Liu 
10926597c28dSRichard Henderson     check_r0_write(rd);
1093bbe418f2SJia Liu     switch (op0) {
1094bbe418f2SJia Liu     case 0x0:    /* l.movhi */
1095bbe418f2SJia Liu         LOG_DIS("l.movhi  r%d, %d\n", rd, K16);
1096bbe418f2SJia Liu         tcg_gen_movi_tl(cpu_R[rd], (K16 << 16));
1097bbe418f2SJia Liu         break;
1098bbe418f2SJia Liu 
1099bbe418f2SJia Liu     case 0x1:    /* l.macrc */
1100bbe418f2SJia Liu         LOG_DIS("l.macrc  r%d\n", rd);
11016f7332baSRichard Henderson         tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
11026f7332baSRichard Henderson         tcg_gen_movi_i64(cpu_mac, 0);
1103bbe418f2SJia Liu         break;
1104bbe418f2SJia Liu 
1105bbe418f2SJia Liu     default:
1106bbe418f2SJia Liu         gen_illegal_exception(dc);
1107bbe418f2SJia Liu         break;
1108bbe418f2SJia Liu     }
1109bbe418f2SJia Liu }
1110bbe418f2SJia Liu 
1111bbe418f2SJia Liu static void dec_comp(DisasContext *dc, uint32_t insn)
1112bbe418f2SJia Liu {
1113bbe418f2SJia Liu     uint32_t op0;
1114bbe418f2SJia Liu     uint32_t ra, rb;
1115bbe418f2SJia Liu 
1116bbe418f2SJia Liu     op0 = extract32(insn, 21, 5);
1117bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1118bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1119bbe418f2SJia Liu 
1120bbe418f2SJia Liu     /* unsigned integers  */
1121bbe418f2SJia Liu     tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
1122bbe418f2SJia Liu     tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
1123bbe418f2SJia Liu 
1124bbe418f2SJia Liu     switch (op0) {
1125bbe418f2SJia Liu     case 0x0:    /* l.sfeq */
1126bbe418f2SJia Liu         LOG_DIS("l.sfeq  r%d, r%d\n", ra, rb);
112784775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1128bbe418f2SJia Liu         break;
1129bbe418f2SJia Liu 
1130bbe418f2SJia Liu     case 0x1:    /* l.sfne */
1131bbe418f2SJia Liu         LOG_DIS("l.sfne  r%d, r%d\n", ra, rb);
113284775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1133bbe418f2SJia Liu         break;
1134bbe418f2SJia Liu 
1135bbe418f2SJia Liu     case 0x2:    /* l.sfgtu */
1136bbe418f2SJia Liu         LOG_DIS("l.sfgtu  r%d, r%d\n", ra, rb);
113784775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1138bbe418f2SJia Liu         break;
1139bbe418f2SJia Liu 
1140bbe418f2SJia Liu     case 0x3:    /* l.sfgeu */
1141bbe418f2SJia Liu         LOG_DIS("l.sfgeu  r%d, r%d\n", ra, rb);
114284775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1143bbe418f2SJia Liu         break;
1144bbe418f2SJia Liu 
1145bbe418f2SJia Liu     case 0x4:    /* l.sfltu */
1146bbe418f2SJia Liu         LOG_DIS("l.sfltu  r%d, r%d\n", ra, rb);
114784775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1148bbe418f2SJia Liu         break;
1149bbe418f2SJia Liu 
1150bbe418f2SJia Liu     case 0x5:    /* l.sfleu */
1151bbe418f2SJia Liu         LOG_DIS("l.sfleu  r%d, r%d\n", ra, rb);
115284775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1153bbe418f2SJia Liu         break;
1154bbe418f2SJia Liu 
1155bbe418f2SJia Liu     case 0xa:    /* l.sfgts */
1156bbe418f2SJia Liu         LOG_DIS("l.sfgts  r%d, r%d\n", ra, rb);
115784775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1158bbe418f2SJia Liu         break;
1159bbe418f2SJia Liu 
1160bbe418f2SJia Liu     case 0xb:    /* l.sfges */
1161bbe418f2SJia Liu         LOG_DIS("l.sfges  r%d, r%d\n", ra, rb);
116284775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1163bbe418f2SJia Liu         break;
1164bbe418f2SJia Liu 
1165bbe418f2SJia Liu     case 0xc:    /* l.sflts */
1166bbe418f2SJia Liu         LOG_DIS("l.sflts  r%d, r%d\n", ra, rb);
116784775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1168bbe418f2SJia Liu         break;
1169bbe418f2SJia Liu 
1170bbe418f2SJia Liu     case 0xd:    /* l.sfles */
1171bbe418f2SJia Liu         LOG_DIS("l.sfles  r%d, r%d\n", ra, rb);
117284775c43SRichard Henderson         tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
1173bbe418f2SJia Liu         break;
1174bbe418f2SJia Liu 
1175bbe418f2SJia Liu     default:
1176bbe418f2SJia Liu         gen_illegal_exception(dc);
1177bbe418f2SJia Liu         break;
1178bbe418f2SJia Liu     }
1179bbe418f2SJia Liu }
1180bbe418f2SJia Liu 
1181bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn)
1182bbe418f2SJia Liu {
11836da544a6SRichard Henderson     uint32_t op0, ra;
11846da544a6SRichard Henderson     int32_t I16;
1185bbe418f2SJia Liu 
1186bbe418f2SJia Liu     op0 = extract32(insn, 21, 5);
1187bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
11886da544a6SRichard Henderson     I16 = sextract32(insn, 0, 16);
1189bbe418f2SJia Liu 
1190bbe418f2SJia Liu     switch (op0) {
1191bbe418f2SJia Liu     case 0x0:    /* l.sfeqi */
1192bbe418f2SJia Liu         LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
119384775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
1194bbe418f2SJia Liu         break;
1195bbe418f2SJia Liu 
1196bbe418f2SJia Liu     case 0x1:    /* l.sfnei */
1197bbe418f2SJia Liu         LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
119884775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
1199bbe418f2SJia Liu         break;
1200bbe418f2SJia Liu 
1201bbe418f2SJia Liu     case 0x2:    /* l.sfgtui */
1202bbe418f2SJia Liu         LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
120384775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
1204bbe418f2SJia Liu         break;
1205bbe418f2SJia Liu 
1206bbe418f2SJia Liu     case 0x3:    /* l.sfgeui */
1207bbe418f2SJia Liu         LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
120884775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
1209bbe418f2SJia Liu         break;
1210bbe418f2SJia Liu 
1211bbe418f2SJia Liu     case 0x4:    /* l.sfltui */
1212bbe418f2SJia Liu         LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
121384775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
1214bbe418f2SJia Liu         break;
1215bbe418f2SJia Liu 
1216bbe418f2SJia Liu     case 0x5:    /* l.sfleui */
1217bbe418f2SJia Liu         LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
121884775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
1219bbe418f2SJia Liu         break;
1220bbe418f2SJia Liu 
1221bbe418f2SJia Liu     case 0xa:    /* l.sfgtsi */
1222bbe418f2SJia Liu         LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
122384775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
1224bbe418f2SJia Liu         break;
1225bbe418f2SJia Liu 
1226bbe418f2SJia Liu     case 0xb:    /* l.sfgesi */
1227bbe418f2SJia Liu         LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
122884775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
1229bbe418f2SJia Liu         break;
1230bbe418f2SJia Liu 
1231bbe418f2SJia Liu     case 0xc:    /* l.sfltsi */
1232bbe418f2SJia Liu         LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
123384775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
1234bbe418f2SJia Liu         break;
1235bbe418f2SJia Liu 
1236bbe418f2SJia Liu     case 0xd:    /* l.sflesi */
1237bbe418f2SJia Liu         LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
123884775c43SRichard Henderson         tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
1239bbe418f2SJia Liu         break;
1240bbe418f2SJia Liu 
1241bbe418f2SJia Liu     default:
1242bbe418f2SJia Liu         gen_illegal_exception(dc);
1243bbe418f2SJia Liu         break;
1244bbe418f2SJia Liu     }
1245bbe418f2SJia Liu }
1246bbe418f2SJia Liu 
1247*7de9729fSRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn)
1248bbe418f2SJia Liu {
1249*7de9729fSRichard Henderson     LOG_DIS("l.sys %d\n", a->k);
12501ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1251bbe418f2SJia Liu     gen_exception(dc, EXCP_SYSCALL);
12521ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
1253*7de9729fSRichard Henderson     return true;
1254*7de9729fSRichard Henderson }
1255bbe418f2SJia Liu 
1256*7de9729fSRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a, uint32_t insn)
1257*7de9729fSRichard Henderson {
1258*7de9729fSRichard Henderson     LOG_DIS("l.trap %d\n", a->k);
12591ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1260bbe418f2SJia Liu     gen_exception(dc, EXCP_TRAP);
12611ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
1262*7de9729fSRichard Henderson     return true;
1263*7de9729fSRichard Henderson }
1264bbe418f2SJia Liu 
1265*7de9729fSRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn)
1266*7de9729fSRichard Henderson {
1267bbe418f2SJia Liu     LOG_DIS("l.msync\n");
126824fc5c0fSRichard Henderson     tcg_gen_mb(TCG_MO_ALL);
1269*7de9729fSRichard Henderson     return true;
1270bbe418f2SJia Liu }
1271*7de9729fSRichard Henderson 
1272*7de9729fSRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a, uint32_t insn)
1273*7de9729fSRichard Henderson {
1274*7de9729fSRichard Henderson     LOG_DIS("l.psync\n");
1275*7de9729fSRichard Henderson     return true;
1276*7de9729fSRichard Henderson }
1277*7de9729fSRichard Henderson 
1278*7de9729fSRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a, uint32_t insn)
1279*7de9729fSRichard Henderson {
1280*7de9729fSRichard Henderson     LOG_DIS("l.csync\n");
1281*7de9729fSRichard Henderson     return true;
1282bbe418f2SJia Liu }
1283bbe418f2SJia Liu 
1284bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn)
1285bbe418f2SJia Liu {
1286bbe418f2SJia Liu     uint32_t op0;
1287bbe418f2SJia Liu     uint32_t ra, rb, rd;
1288bbe418f2SJia Liu     op0 = extract32(insn, 0, 8);
1289bbe418f2SJia Liu     ra = extract32(insn, 16, 5);
1290bbe418f2SJia Liu     rb = extract32(insn, 11, 5);
1291bbe418f2SJia Liu     rd = extract32(insn, 21, 5);
1292bbe418f2SJia Liu 
1293bbe418f2SJia Liu     switch (op0) {
1294bbe418f2SJia Liu     case 0x00: /* lf.add.s */
1295bbe418f2SJia Liu         LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
12966597c28dSRichard Henderson         check_r0_write(rd);
1297bbe418f2SJia Liu         gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
12984e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1299bbe418f2SJia Liu         break;
1300bbe418f2SJia Liu 
1301bbe418f2SJia Liu     case 0x01: /* lf.sub.s */
1302bbe418f2SJia Liu         LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
13036597c28dSRichard Henderson         check_r0_write(rd);
1304bbe418f2SJia Liu         gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13054e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1306bbe418f2SJia Liu         break;
1307bbe418f2SJia Liu 
1308bbe418f2SJia Liu     case 0x02:    /* lf.mul.s */
1309bbe418f2SJia Liu         LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
13106597c28dSRichard Henderson         check_r0_write(rd);
1311bbe418f2SJia Liu         gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13124e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1313bbe418f2SJia Liu         break;
1314bbe418f2SJia Liu 
1315bbe418f2SJia Liu     case 0x03: /* lf.div.s */
1316bbe418f2SJia Liu         LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
13176597c28dSRichard Henderson         check_r0_write(rd);
1318bbe418f2SJia Liu         gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13194e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1320bbe418f2SJia Liu         break;
1321bbe418f2SJia Liu 
1322bbe418f2SJia Liu     case 0x04: /* lf.itof.s */
1323bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
13246597c28dSRichard Henderson         check_r0_write(rd);
1325bbe418f2SJia Liu         gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
13264e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1327bbe418f2SJia Liu         break;
1328bbe418f2SJia Liu 
1329bbe418f2SJia Liu     case 0x05: /* lf.ftoi.s */
1330bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
13316597c28dSRichard Henderson         check_r0_write(rd);
1332bbe418f2SJia Liu         gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
13334e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1334bbe418f2SJia Liu         break;
1335bbe418f2SJia Liu 
1336bbe418f2SJia Liu     case 0x06: /* lf.rem.s */
1337bbe418f2SJia Liu         LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
13386597c28dSRichard Henderson         check_r0_write(rd);
1339bbe418f2SJia Liu         gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13404e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1341bbe418f2SJia Liu         break;
1342bbe418f2SJia Liu 
1343bbe418f2SJia Liu     case 0x07: /* lf.madd.s */
1344bbe418f2SJia Liu         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
13456597c28dSRichard Henderson         check_r0_write(rd);
1346762e22edSRichard Henderson         gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
1347762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
13484e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1349bbe418f2SJia Liu         break;
1350bbe418f2SJia Liu 
1351bbe418f2SJia Liu     case 0x08: /* lf.sfeq.s */
1352bbe418f2SJia Liu         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
135384775c43SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13544e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1355bbe418f2SJia Liu         break;
1356bbe418f2SJia Liu 
1357bbe418f2SJia Liu     case 0x09: /* lf.sfne.s */
1358bbe418f2SJia Liu         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
13594e2d3007SRichard Henderson         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13604e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
13614e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1362bbe418f2SJia Liu         break;
1363bbe418f2SJia Liu 
1364bbe418f2SJia Liu     case 0x0a: /* lf.sfgt.s */
1365bbe418f2SJia Liu         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
13664e2d3007SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13674e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1368bbe418f2SJia Liu         break;
1369bbe418f2SJia Liu 
1370bbe418f2SJia Liu     case 0x0b: /* lf.sfge.s */
1371bbe418f2SJia Liu         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
13724e2d3007SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
13734e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1374bbe418f2SJia Liu         break;
1375bbe418f2SJia Liu 
1376bbe418f2SJia Liu     case 0x0c: /* lf.sflt.s */
1377bbe418f2SJia Liu         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
137884775c43SRichard Henderson         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13794e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1380bbe418f2SJia Liu         break;
1381bbe418f2SJia Liu 
1382bbe418f2SJia Liu     case 0x0d: /* lf.sfle.s */
1383bbe418f2SJia Liu         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
138484775c43SRichard Henderson         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
13854e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1386bbe418f2SJia Liu         break;
1387bbe418f2SJia Liu 
13884e2d3007SRichard Henderson #ifdef TARGET_OPENRISC64
13894e2d3007SRichard Henderson     case 0x10: /* lf.add.d */
1390bbe418f2SJia Liu         LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1391bbe418f2SJia Liu         check_of64s(dc);
13926597c28dSRichard Henderson         check_r0_write(rd);
1393bbe418f2SJia Liu         gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
13944e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1395bbe418f2SJia Liu         break;
1396bbe418f2SJia Liu 
13974e2d3007SRichard Henderson     case 0x11: /* lf.sub.d */
1398bbe418f2SJia Liu         LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1399bbe418f2SJia Liu         check_of64s(dc);
14006597c28dSRichard Henderson         check_r0_write(rd);
1401bbe418f2SJia Liu         gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14024e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1403bbe418f2SJia Liu         break;
1404bbe418f2SJia Liu 
14054e2d3007SRichard Henderson     case 0x12: /* lf.mul.d */
1406bbe418f2SJia Liu         LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1407bbe418f2SJia Liu         check_of64s(dc);
14086597c28dSRichard Henderson         check_r0_write(rd);
1409bbe418f2SJia Liu         gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14104e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1411bbe418f2SJia Liu         break;
1412bbe418f2SJia Liu 
14134e2d3007SRichard Henderson     case 0x13: /* lf.div.d */
1414bbe418f2SJia Liu         LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1415bbe418f2SJia Liu         check_of64s(dc);
14166597c28dSRichard Henderson         check_r0_write(rd);
1417bbe418f2SJia Liu         gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14184e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1419bbe418f2SJia Liu         break;
1420bbe418f2SJia Liu 
14214e2d3007SRichard Henderson     case 0x14: /* lf.itof.d */
1422bbe418f2SJia Liu         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1423bbe418f2SJia Liu         check_of64s(dc);
14246597c28dSRichard Henderson         check_r0_write(rd);
1425bbe418f2SJia Liu         gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
14264e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1427bbe418f2SJia Liu         break;
1428bbe418f2SJia Liu 
14294e2d3007SRichard Henderson     case 0x15: /* lf.ftoi.d */
1430bbe418f2SJia Liu         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1431bbe418f2SJia Liu         check_of64s(dc);
14326597c28dSRichard Henderson         check_r0_write(rd);
1433bbe418f2SJia Liu         gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
14344e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1435bbe418f2SJia Liu         break;
1436bbe418f2SJia Liu 
14374e2d3007SRichard Henderson     case 0x16: /* lf.rem.d */
1438bbe418f2SJia Liu         LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1439bbe418f2SJia Liu         check_of64s(dc);
14406597c28dSRichard Henderson         check_r0_write(rd);
1441bbe418f2SJia Liu         gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
14424e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1443bbe418f2SJia Liu         break;
1444bbe418f2SJia Liu 
14454e2d3007SRichard Henderson     case 0x17: /* lf.madd.d */
1446bbe418f2SJia Liu         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1447bbe418f2SJia Liu         check_of64s(dc);
14486597c28dSRichard Henderson         check_r0_write(rd);
1449762e22edSRichard Henderson         gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
1450762e22edSRichard Henderson                                 cpu_R[ra], cpu_R[rb]);
14514e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1452bbe418f2SJia Liu         break;
1453bbe418f2SJia Liu 
14544e2d3007SRichard Henderson     case 0x18: /* lf.sfeq.d */
1455bbe418f2SJia Liu         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1456bbe418f2SJia Liu         check_of64s(dc);
145784775c43SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14584e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1459bbe418f2SJia Liu         break;
1460bbe418f2SJia Liu 
14614e2d3007SRichard Henderson     case 0x1a: /* lf.sfgt.d */
1462bbe418f2SJia Liu         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1463bbe418f2SJia Liu         check_of64s(dc);
14644e2d3007SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14654e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1466bbe418f2SJia Liu         break;
1467bbe418f2SJia Liu 
14684e2d3007SRichard Henderson     case 0x1b: /* lf.sfge.d */
1469bbe418f2SJia Liu         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1470bbe418f2SJia Liu         check_of64s(dc);
14714e2d3007SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
14724e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1473bbe418f2SJia Liu         break;
1474bbe418f2SJia Liu 
14754e2d3007SRichard Henderson     case 0x19: /* lf.sfne.d */
1476bbe418f2SJia Liu         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1477bbe418f2SJia Liu         check_of64s(dc);
14784e2d3007SRichard Henderson         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14794e2d3007SRichard Henderson         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
14804e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1481bbe418f2SJia Liu         break;
1482bbe418f2SJia Liu 
14834e2d3007SRichard Henderson     case 0x1c: /* lf.sflt.d */
1484bbe418f2SJia Liu         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1485bbe418f2SJia Liu         check_of64s(dc);
148684775c43SRichard Henderson         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14874e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1488bbe418f2SJia Liu         break;
1489bbe418f2SJia Liu 
14904e2d3007SRichard Henderson     case 0x1d: /* lf.sfle.d */
1491bbe418f2SJia Liu         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1492bbe418f2SJia Liu         check_of64s(dc);
149384775c43SRichard Henderson         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
14944e2d3007SRichard Henderson         gen_helper_update_fpcsr(cpu_env);
1495bbe418f2SJia Liu         break;
14964e2d3007SRichard Henderson #endif
1497bbe418f2SJia Liu 
1498bbe418f2SJia Liu     default:
1499bbe418f2SJia Liu         gen_illegal_exception(dc);
1500bbe418f2SJia Liu         break;
1501bbe418f2SJia Liu     }
1502bbe418f2SJia Liu }
1503bbe418f2SJia Liu 
1504bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1505bbe418f2SJia Liu {
1506bbe418f2SJia Liu     uint32_t op0;
1507*7de9729fSRichard Henderson     uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next);
1508bbe418f2SJia Liu 
1509*7de9729fSRichard Henderson     /* Transition to the auto-generated decoder.  */
1510*7de9729fSRichard Henderson     if (decode(dc, insn)) {
1511*7de9729fSRichard Henderson         return;
1512*7de9729fSRichard Henderson     }
1513*7de9729fSRichard Henderson 
1514*7de9729fSRichard Henderson     op0 = extract32(insn, 26, 6);
1515bbe418f2SJia Liu     switch (op0) {
1516bbe418f2SJia Liu     case 0x06:
1517bbe418f2SJia Liu         dec_M(dc, insn);
1518bbe418f2SJia Liu         break;
1519bbe418f2SJia Liu 
1520bbe418f2SJia Liu     case 0x2e:
1521bbe418f2SJia Liu         dec_logic(dc, insn);
1522bbe418f2SJia Liu         break;
1523bbe418f2SJia Liu 
1524bbe418f2SJia Liu     case 0x2f:
1525bbe418f2SJia Liu         dec_compi(dc, insn);
1526bbe418f2SJia Liu         break;
1527bbe418f2SJia Liu 
1528bbe418f2SJia Liu     case 0x31:
1529bbe418f2SJia Liu         dec_mac(dc, insn);
1530bbe418f2SJia Liu         break;
1531bbe418f2SJia Liu 
1532bbe418f2SJia Liu     case 0x32:
1533bbe418f2SJia Liu         dec_float(dc, insn);
1534bbe418f2SJia Liu         break;
1535bbe418f2SJia Liu 
1536bbe418f2SJia Liu     case 0x38:
1537bbe418f2SJia Liu         dec_calc(dc, insn);
1538bbe418f2SJia Liu         break;
1539bbe418f2SJia Liu 
1540bbe418f2SJia Liu     case 0x39:
1541bbe418f2SJia Liu         dec_comp(dc, insn);
1542bbe418f2SJia Liu         break;
1543bbe418f2SJia Liu 
1544bbe418f2SJia Liu     default:
1545bbe418f2SJia Liu         dec_misc(dc, insn);
1546bbe418f2SJia Liu         break;
1547bbe418f2SJia Liu     }
1548bbe418f2SJia Liu }
1549bbe418f2SJia Liu 
1550a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
1551e67db06eSJia Liu {
1552a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcb, DisasContext, base);
15539c489ea6SLluís Vilanova     CPUOpenRISCState *env = cs->env_ptr;
1554a4fd3ec3SEmilio G. Cota     int bound;
1555bbe418f2SJia Liu 
1556a4fd3ec3SEmilio G. Cota     dc->mem_idx = cpu_mmu_index(env, false);
15571ffa4bceSEmilio G. Cota     dc->tb_flags = dc->base.tb->flags;
1558a01deb36SRichard Henderson     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
1559a4fd3ec3SEmilio G. Cota     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
1560a4fd3ec3SEmilio G. Cota     dc->base.max_insns = MIN(dc->base.max_insns, bound);
1561190ce7fbSRichard Henderson }
1562bbe418f2SJia Liu 
1563a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
1564a4fd3ec3SEmilio G. Cota {
1565a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(db, DisasContext, base);
1566bbe418f2SJia Liu 
15676597c28dSRichard Henderson     /* Allow the TCG optimizer to see that R0 == 0,
15686597c28dSRichard Henderson        when it's true, which is the common case.  */
15696597c28dSRichard Henderson     if (dc->tb_flags & TB_FLAGS_R0_0) {
15706597c28dSRichard Henderson         cpu_R[0] = tcg_const_tl(0);
15716597c28dSRichard Henderson     } else {
15726597c28dSRichard Henderson         cpu_R[0] = cpu_R0;
15736597c28dSRichard Henderson     }
1574a4fd3ec3SEmilio G. Cota }
15756597c28dSRichard Henderson 
1576a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
1577a4fd3ec3SEmilio G. Cota {
1578a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1579a4fd3ec3SEmilio G. Cota 
15801ffa4bceSEmilio G. Cota     tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
1581a4fd3ec3SEmilio G. Cota                        | (dc->base.num_insns > 1 ? 2 : 0));
1582a4fd3ec3SEmilio G. Cota }
1583bbe418f2SJia Liu 
1584a4fd3ec3SEmilio G. Cota static bool openrisc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
1585a4fd3ec3SEmilio G. Cota                                          const CPUBreakpoint *bp)
1586a4fd3ec3SEmilio G. Cota {
1587a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1588a4fd3ec3SEmilio G. Cota 
15891ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1590b933066aSRichard Henderson     gen_exception(dc, EXCP_DEBUG);
15911ffa4bceSEmilio G. Cota     dc->base.is_jmp = DISAS_NORETURN;
1592522a0d4eSRichard Henderson     /* The address covered by the breakpoint must be included in
1593522a0d4eSRichard Henderson        [tb->pc, tb->pc + tb->size) in order to for it to be
1594522a0d4eSRichard Henderson        properly cleared -- thus we increment the PC here so that
1595522a0d4eSRichard Henderson        the logic setting tb->size below does the right thing.  */
15961ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
1597a4fd3ec3SEmilio G. Cota     return true;
1598b933066aSRichard Henderson }
1599b933066aSRichard Henderson 
1600a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
1601a4fd3ec3SEmilio G. Cota {
1602a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
1603a4fd3ec3SEmilio G. Cota     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1604a4fd3ec3SEmilio G. Cota 
1605bbe418f2SJia Liu     disas_openrisc_insn(dc, cpu);
16061ffa4bceSEmilio G. Cota     dc->base.pc_next += 4;
160724c32852SRichard Henderson 
1608bbe418f2SJia Liu     /* delay slot */
1609bbe418f2SJia Liu     if (dc->delayed_branch) {
1610bbe418f2SJia Liu         dc->delayed_branch--;
1611bbe418f2SJia Liu         if (!dc->delayed_branch) {
1612bbe418f2SJia Liu             tcg_gen_mov_tl(cpu_pc, jmp_pc);
161324c32852SRichard Henderson             tcg_gen_discard_tl(jmp_pc);
16141ffa4bceSEmilio G. Cota             dc->base.is_jmp = DISAS_UPDATE;
1615a4fd3ec3SEmilio G. Cota             return;
1616bbe418f2SJia Liu         }
1617bbe418f2SJia Liu     }
1618a4fd3ec3SEmilio G. Cota }
1619bbe418f2SJia Liu 
1620a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
1621a4fd3ec3SEmilio G. Cota {
1622a4fd3ec3SEmilio G. Cota     DisasContext *dc = container_of(dcbase, DisasContext, base);
162324c32852SRichard Henderson 
1624a01deb36SRichard Henderson     if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
1625a01deb36SRichard Henderson         tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
1626a01deb36SRichard Henderson     }
1627a01deb36SRichard Henderson 
16281ffa4bceSEmilio G. Cota     tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
16291ffa4bceSEmilio G. Cota     if (dc->base.is_jmp == DISAS_NEXT) {
16301ffa4bceSEmilio G. Cota         dc->base.is_jmp = DISAS_UPDATE;
16311ffa4bceSEmilio G. Cota         tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1632bbe418f2SJia Liu     }
16331ffa4bceSEmilio G. Cota     if (unlikely(dc->base.singlestep_enabled)) {
1634bbe418f2SJia Liu         gen_exception(dc, EXCP_DEBUG);
1635bbe418f2SJia Liu     } else {
16361ffa4bceSEmilio G. Cota         switch (dc->base.is_jmp) {
1637a4fd3ec3SEmilio G. Cota         case DISAS_TOO_MANY:
16381ffa4bceSEmilio G. Cota             gen_goto_tb(dc, 0, dc->base.pc_next);
1639bbe418f2SJia Liu             break;
16401ffa4bceSEmilio G. Cota         case DISAS_NORETURN:
1641bbe418f2SJia Liu         case DISAS_JUMP:
16421ffa4bceSEmilio G. Cota         case DISAS_TB_JUMP:
1643bbe418f2SJia Liu             break;
1644bbe418f2SJia Liu         case DISAS_UPDATE:
1645bbe418f2SJia Liu             /* indicate that the hash table must be used
1646bbe418f2SJia Liu                to find the next TB */
1647bbe418f2SJia Liu             tcg_gen_exit_tb(0);
1648bbe418f2SJia Liu             break;
1649a4fd3ec3SEmilio G. Cota         default:
1650a4fd3ec3SEmilio G. Cota             g_assert_not_reached();
1651a4fd3ec3SEmilio G. Cota         }
1652bbe418f2SJia Liu     }
1653bbe418f2SJia Liu }
1654bbe418f2SJia Liu 
1655a4fd3ec3SEmilio G. Cota static void openrisc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
1656a4fd3ec3SEmilio G. Cota {
1657a4fd3ec3SEmilio G. Cota     DisasContext *s = container_of(dcbase, DisasContext, base);
16580a7df5daSRichard Henderson 
1659a4fd3ec3SEmilio G. Cota     qemu_log("IN: %s\n", lookup_symbol(s->base.pc_first));
1660a4fd3ec3SEmilio G. Cota     log_target_disas(cs, s->base.pc_first, s->base.tb->size);
1661bbe418f2SJia Liu }
1662a4fd3ec3SEmilio G. Cota 
1663a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = {
1664a4fd3ec3SEmilio G. Cota     .init_disas_context = openrisc_tr_init_disas_context,
1665a4fd3ec3SEmilio G. Cota     .tb_start           = openrisc_tr_tb_start,
1666a4fd3ec3SEmilio G. Cota     .insn_start         = openrisc_tr_insn_start,
1667a4fd3ec3SEmilio G. Cota     .breakpoint_check   = openrisc_tr_breakpoint_check,
1668a4fd3ec3SEmilio G. Cota     .translate_insn     = openrisc_tr_translate_insn,
1669a4fd3ec3SEmilio G. Cota     .tb_stop            = openrisc_tr_tb_stop,
1670a4fd3ec3SEmilio G. Cota     .disas_log          = openrisc_tr_disas_log,
1671a4fd3ec3SEmilio G. Cota };
1672a4fd3ec3SEmilio G. Cota 
1673a4fd3ec3SEmilio G. Cota void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
1674a4fd3ec3SEmilio G. Cota {
1675a4fd3ec3SEmilio G. Cota     DisasContext ctx;
1676a4fd3ec3SEmilio G. Cota 
1677a4fd3ec3SEmilio G. Cota     translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb);
1678e67db06eSJia Liu }
1679e67db06eSJia Liu 
1680878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
1681e67db06eSJia Liu                              fprintf_function cpu_fprintf,
1682e67db06eSJia Liu                              int flags)
1683e67db06eSJia Liu {
1684878096eeSAndreas Färber     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1685878096eeSAndreas Färber     CPUOpenRISCState *env = &cpu->env;
1686e67db06eSJia Liu     int i;
1687878096eeSAndreas Färber 
1688e67db06eSJia Liu     cpu_fprintf(f, "PC=%08x\n", env->pc);
1689e67db06eSJia Liu     for (i = 0; i < 32; ++i) {
1690d89e71e8SStafford Horne         cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
1691e67db06eSJia Liu                     (i % 4) == 3 ? '\n' : ' ');
1692e67db06eSJia Liu     }
1693e67db06eSJia Liu }
1694e67db06eSJia Liu 
1695e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
1696bad729e2SRichard Henderson                           target_ulong *data)
1697e67db06eSJia Liu {
1698bad729e2SRichard Henderson     env->pc = data[0];
1699a01deb36SRichard Henderson     env->dflag = data[1] & 1;
1700a01deb36SRichard Henderson     if (data[1] & 2) {
170124c32852SRichard Henderson         env->ppc = env->pc - 4;
170224c32852SRichard Henderson     }
1703e67db06eSJia Liu }
1704