1fcf5ef2aSThomas Huth /* 2fcf5ef2aSThomas Huth * OpenRISC translation 3fcf5ef2aSThomas Huth * 4fcf5ef2aSThomas Huth * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> 5fcf5ef2aSThomas Huth * Feng Gao <gf91597@gmail.com> 6fcf5ef2aSThomas Huth * 7fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or 8fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public 9fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either 10fcf5ef2aSThomas Huth * version 2 of the License, or (at your option) any later version. 11fcf5ef2aSThomas Huth * 12fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful, 13fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of 14fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15fcf5ef2aSThomas Huth * Lesser General Public License for more details. 16fcf5ef2aSThomas Huth * 17fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public 18fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19fcf5ef2aSThomas Huth */ 20fcf5ef2aSThomas Huth 21fcf5ef2aSThomas Huth #include "qemu/osdep.h" 22fcf5ef2aSThomas Huth #include "cpu.h" 23fcf5ef2aSThomas Huth #include "exec/exec-all.h" 24fcf5ef2aSThomas Huth #include "disas/disas.h" 25fcf5ef2aSThomas Huth #include "tcg-op.h" 26fcf5ef2aSThomas Huth #include "qemu-common.h" 27fcf5ef2aSThomas Huth #include "qemu/log.h" 28fcf5ef2aSThomas Huth #include "qemu/bitops.h" 29fcf5ef2aSThomas Huth #include "exec/cpu_ldst.h" 3077fc6f5eSLluís Vilanova #include "exec/translator.h" 31fcf5ef2aSThomas Huth 32fcf5ef2aSThomas Huth #include "exec/helper-proto.h" 33fcf5ef2aSThomas Huth #include "exec/helper-gen.h" 34*7de9729fSRichard Henderson #include "exec/gen-icount.h" 35fcf5ef2aSThomas Huth 36fcf5ef2aSThomas Huth #include "trace-tcg.h" 37fcf5ef2aSThomas Huth #include "exec/log.h" 38fcf5ef2aSThomas Huth 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__) 42fcf5ef2aSThomas Huth 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 48fcf5ef2aSThomas Huth typedef struct DisasContext { 491ffa4bceSEmilio G. Cota DisasContextBase base; 50fcf5ef2aSThomas Huth uint32_t mem_idx; 51a01deb36SRichard Henderson uint32_t tb_flags; 52fcf5ef2aSThomas Huth uint32_t delayed_branch; 53fcf5ef2aSThomas Huth } DisasContext; 54fcf5ef2aSThomas Huth 55*7de9729fSRichard Henderson /* Include the auto-generated decoder. */ 56*7de9729fSRichard Henderson #include "decode.inc.c" 57*7de9729fSRichard Henderson 58fcf5ef2aSThomas Huth static TCGv cpu_sr; 59fcf5ef2aSThomas Huth static TCGv cpu_R[32]; 606597c28dSRichard Henderson static TCGv cpu_R0; 61fcf5ef2aSThomas Huth static TCGv cpu_pc; 62fcf5ef2aSThomas Huth static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ 63fcf5ef2aSThomas Huth 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; 69fcf5ef2aSThomas Huth static TCGv_i32 fpcsr; 706f7332baSRichard Henderson static TCGv_i64 cpu_mac; /* MACHI:MACLO */ 71a01deb36SRichard Henderson static TCGv_i32 cpu_dflag; 72fcf5ef2aSThomas Huth 73fcf5ef2aSThomas Huth void openrisc_translate_init(void) 74fcf5ef2aSThomas Huth { 75fcf5ef2aSThomas Huth static const char * const regnames[] = { 76fcf5ef2aSThomas Huth "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 77fcf5ef2aSThomas Huth "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 78fcf5ef2aSThomas Huth "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 79fcf5ef2aSThomas Huth "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 80fcf5ef2aSThomas Huth }; 81fcf5ef2aSThomas Huth int i; 82fcf5ef2aSThomas Huth 83fcf5ef2aSThomas Huth cpu_sr = tcg_global_mem_new(cpu_env, 84fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, sr), "sr"); 85a01deb36SRichard Henderson cpu_dflag = tcg_global_mem_new_i32(cpu_env, 86a01deb36SRichard Henderson offsetof(CPUOpenRISCState, dflag), 87a01deb36SRichard Henderson "dflag"); 88fcf5ef2aSThomas Huth cpu_pc = tcg_global_mem_new(cpu_env, 89fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, pc), "pc"); 90fcf5ef2aSThomas Huth cpu_ppc = tcg_global_mem_new(cpu_env, 91fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, ppc), "ppc"); 92fcf5ef2aSThomas Huth jmp_pc = tcg_global_mem_new(cpu_env, 93fcf5ef2aSThomas Huth 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"); 106fcf5ef2aSThomas Huth fpcsr = tcg_global_mem_new_i32(cpu_env, 107fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, fpcsr), 108fcf5ef2aSThomas Huth "fpcsr"); 1096f7332baSRichard Henderson cpu_mac = tcg_global_mem_new_i64(cpu_env, 1106f7332baSRichard Henderson offsetof(CPUOpenRISCState, mac), 1116f7332baSRichard Henderson "mac"); 112fcf5ef2aSThomas Huth for (i = 0; i < 32; i++) { 113fcf5ef2aSThomas Huth cpu_R[i] = tcg_global_mem_new(cpu_env, 114d89e71e8SStafford Horne offsetof(CPUOpenRISCState, 115d89e71e8SStafford Horne shadow_gpr[0][i]), 116fcf5ef2aSThomas Huth regnames[i]); 117fcf5ef2aSThomas Huth } 1186597c28dSRichard Henderson cpu_R0 = cpu_R[0]; 119fcf5ef2aSThomas Huth } 120fcf5ef2aSThomas Huth 121fcf5ef2aSThomas Huth static void gen_exception(DisasContext *dc, unsigned int excp) 122fcf5ef2aSThomas Huth { 123fcf5ef2aSThomas Huth TCGv_i32 tmp = tcg_const_i32(excp); 124fcf5ef2aSThomas Huth gen_helper_exception(cpu_env, tmp); 125fcf5ef2aSThomas Huth tcg_temp_free_i32(tmp); 126fcf5ef2aSThomas Huth } 127fcf5ef2aSThomas Huth 128fcf5ef2aSThomas Huth static void gen_illegal_exception(DisasContext *dc) 129fcf5ef2aSThomas Huth { 1301ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 131fcf5ef2aSThomas Huth gen_exception(dc, EXCP_ILLEGAL); 1321ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 133fcf5ef2aSThomas Huth } 134fcf5ef2aSThomas Huth 135fcf5ef2aSThomas Huth /* not used yet, open it when we need or64. */ 136fcf5ef2aSThomas Huth /*#ifdef TARGET_OPENRISC64 137fcf5ef2aSThomas Huth static void check_ob64s(DisasContext *dc) 138fcf5ef2aSThomas Huth { 139fcf5ef2aSThomas Huth if (!(dc->flags & CPUCFGR_OB64S)) { 140fcf5ef2aSThomas Huth gen_illegal_exception(dc); 141fcf5ef2aSThomas Huth } 142fcf5ef2aSThomas Huth } 143fcf5ef2aSThomas Huth 144fcf5ef2aSThomas Huth static void check_of64s(DisasContext *dc) 145fcf5ef2aSThomas Huth { 146fcf5ef2aSThomas Huth if (!(dc->flags & CPUCFGR_OF64S)) { 147fcf5ef2aSThomas Huth gen_illegal_exception(dc); 148fcf5ef2aSThomas Huth } 149fcf5ef2aSThomas Huth } 150fcf5ef2aSThomas Huth 151fcf5ef2aSThomas Huth static void check_ov64s(DisasContext *dc) 152fcf5ef2aSThomas Huth { 153fcf5ef2aSThomas Huth if (!(dc->flags & CPUCFGR_OV64S)) { 154fcf5ef2aSThomas Huth gen_illegal_exception(dc); 155fcf5ef2aSThomas Huth } 156fcf5ef2aSThomas Huth } 157fcf5ef2aSThomas Huth #endif*/ 158fcf5ef2aSThomas Huth 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 168fcf5ef2aSThomas Huth static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) 169fcf5ef2aSThomas Huth { 1701ffa4bceSEmilio G. Cota if (unlikely(dc->base.singlestep_enabled)) { 171fcf5ef2aSThomas Huth return false; 172fcf5ef2aSThomas Huth } 173fcf5ef2aSThomas Huth 174fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY 1751ffa4bceSEmilio G. Cota return (dc->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 176fcf5ef2aSThomas Huth #else 177fcf5ef2aSThomas Huth return true; 178fcf5ef2aSThomas Huth #endif 179fcf5ef2aSThomas Huth } 180fcf5ef2aSThomas Huth 181fcf5ef2aSThomas Huth static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 182fcf5ef2aSThomas Huth { 183fcf5ef2aSThomas Huth if (use_goto_tb(dc, dest)) { 184fcf5ef2aSThomas Huth tcg_gen_movi_tl(cpu_pc, dest); 185fcf5ef2aSThomas Huth tcg_gen_goto_tb(n); 1861ffa4bceSEmilio G. Cota tcg_gen_exit_tb((uintptr_t)dc->base.tb + n); 187fcf5ef2aSThomas Huth } else { 188fcf5ef2aSThomas Huth tcg_gen_movi_tl(cpu_pc, dest); 1891ffa4bceSEmilio G. Cota if (dc->base.singlestep_enabled) { 190fcf5ef2aSThomas Huth gen_exception(dc, EXCP_DEBUG); 191fcf5ef2aSThomas Huth } 192fcf5ef2aSThomas Huth tcg_gen_exit_tb(0); 193fcf5ef2aSThomas Huth } 194fcf5ef2aSThomas Huth } 195fcf5ef2aSThomas Huth 1966da544a6SRichard Henderson static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0) 197fcf5ef2aSThomas Huth { 1981ffa4bceSEmilio G. Cota target_ulong tmp_pc = dc->base.pc_next + n26 * 4; 199fcf5ef2aSThomas Huth 200fcf5ef2aSThomas Huth switch (op0) { 201fcf5ef2aSThomas Huth case 0x00: /* l.j */ 202fcf5ef2aSThomas Huth tcg_gen_movi_tl(jmp_pc, tmp_pc); 203fcf5ef2aSThomas Huth break; 204fcf5ef2aSThomas Huth 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 } 210fcf5ef2aSThomas Huth tcg_gen_movi_tl(jmp_pc, tmp_pc); 211fcf5ef2aSThomas Huth break; 212fcf5ef2aSThomas Huth case 0x03: /* l.bnf */ 213fcf5ef2aSThomas Huth case 0x04: /* l.bf */ 214fcf5ef2aSThomas Huth { 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); 225fcf5ef2aSThomas Huth } 226fcf5ef2aSThomas Huth break; 227fcf5ef2aSThomas Huth case 0x11: /* l.jr */ 228fcf5ef2aSThomas Huth tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 229fcf5ef2aSThomas Huth break; 230fcf5ef2aSThomas Huth case 0x12: /* l.jalr */ 2311ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_R[9], (dc->base.pc_next + 8)); 232fcf5ef2aSThomas Huth tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 233fcf5ef2aSThomas Huth break; 234fcf5ef2aSThomas Huth default: 235fcf5ef2aSThomas Huth gen_illegal_exception(dc); 236fcf5ef2aSThomas Huth break; 237fcf5ef2aSThomas Huth } 238fcf5ef2aSThomas Huth 239fcf5ef2aSThomas Huth dc->delayed_branch = 2; 240fcf5ef2aSThomas Huth } 241fcf5ef2aSThomas Huth 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 } 363fcf5ef2aSThomas Huth 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 549fcf5ef2aSThomas Huth static void dec_calc(DisasContext *dc, uint32_t insn) 550fcf5ef2aSThomas Huth { 551fcf5ef2aSThomas Huth uint32_t op0, op1, op2; 552fcf5ef2aSThomas Huth uint32_t ra, rb, rd; 553fcf5ef2aSThomas Huth op0 = extract32(insn, 0, 4); 554fcf5ef2aSThomas Huth op1 = extract32(insn, 8, 2); 555fcf5ef2aSThomas Huth op2 = extract32(insn, 6, 2); 556fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 557fcf5ef2aSThomas Huth rb = extract32(insn, 11, 5); 558fcf5ef2aSThomas Huth rd = extract32(insn, 21, 5); 559fcf5ef2aSThomas Huth 560fcf5ef2aSThomas Huth switch (op1) { 561cf2ae442SRichard Henderson case 0: 562cf2ae442SRichard Henderson switch (op0) { 563cf2ae442SRichard Henderson case 0x0: /* l.add */ 564fcf5ef2aSThomas Huth 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; 567fcf5ef2aSThomas Huth 568cf2ae442SRichard Henderson case 0x1: /* l.addc */ 569fcf5ef2aSThomas Huth 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; 572fcf5ef2aSThomas Huth 573cf2ae442SRichard Henderson case 0x2: /* l.sub */ 574fcf5ef2aSThomas Huth 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; 577fcf5ef2aSThomas Huth 578cf2ae442SRichard Henderson case 0x3: /* l.and */ 579fcf5ef2aSThomas Huth LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); 580fcf5ef2aSThomas Huth tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 581cf2ae442SRichard Henderson return; 582fcf5ef2aSThomas Huth 583cf2ae442SRichard Henderson case 0x4: /* l.or */ 584fcf5ef2aSThomas Huth LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); 585fcf5ef2aSThomas Huth tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 586cf2ae442SRichard Henderson return; 587fcf5ef2aSThomas Huth 588cf2ae442SRichard Henderson case 0x5: /* l.xor */ 589fcf5ef2aSThomas Huth LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); 590fcf5ef2aSThomas Huth 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; 611fcf5ef2aSThomas Huth } 612fcf5ef2aSThomas Huth break; 613fcf5ef2aSThomas Huth 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; 632fcf5ef2aSThomas Huth } 633fcf5ef2aSThomas Huth break; 634fcf5ef2aSThomas Huth 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; 645fcf5ef2aSThomas Huth } 646fcf5ef2aSThomas Huth break; 647fcf5ef2aSThomas Huth 648cf2ae442SRichard Henderson case 0xe: /* l.cmov */ 649fcf5ef2aSThomas Huth LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); 650fcf5ef2aSThomas Huth { 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); 655fcf5ef2aSThomas Huth } 656cf2ae442SRichard Henderson return; 657fcf5ef2aSThomas Huth 658cf2ae442SRichard Henderson case 0xf: /* l.ff1 */ 659fcf5ef2aSThomas Huth 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 } 664fcf5ef2aSThomas Huth break; 665cf2ae442SRichard Henderson 666cf2ae442SRichard Henderson case 1: 667cf2ae442SRichard Henderson switch (op0) { 668cf2ae442SRichard Henderson case 0xf: /* l.fl1 */ 669fcf5ef2aSThomas Huth 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; 673fcf5ef2aSThomas Huth } 674fcf5ef2aSThomas Huth break; 675fcf5ef2aSThomas Huth 676cf2ae442SRichard Henderson case 2: 677fcf5ef2aSThomas Huth break; 678fcf5ef2aSThomas Huth 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; 710fcf5ef2aSThomas Huth } 711fcf5ef2aSThomas Huth break; 712fcf5ef2aSThomas Huth } 713fcf5ef2aSThomas Huth gen_illegal_exception(dc); 714fcf5ef2aSThomas Huth } 715fcf5ef2aSThomas Huth 716fcf5ef2aSThomas Huth static void dec_misc(DisasContext *dc, uint32_t insn) 717fcf5ef2aSThomas Huth { 718fcf5ef2aSThomas Huth uint32_t op0, op1; 719fcf5ef2aSThomas Huth uint32_t ra, rb, rd; 7206da544a6SRichard Henderson uint32_t L6, K5, K16, K5_11; 7216da544a6SRichard Henderson int32_t I16, I5_11, N26; 722fcf5ef2aSThomas Huth TCGMemOp mop; 7239ecaa27eSRichard Henderson TCGv t0; 724fcf5ef2aSThomas Huth 725fcf5ef2aSThomas Huth op0 = extract32(insn, 26, 6); 726fcf5ef2aSThomas Huth op1 = extract32(insn, 24, 2); 727fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 728fcf5ef2aSThomas Huth rb = extract32(insn, 11, 5); 729fcf5ef2aSThomas Huth rd = extract32(insn, 21, 5); 730fcf5ef2aSThomas Huth L6 = extract32(insn, 5, 6); 731fcf5ef2aSThomas Huth 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; 737fcf5ef2aSThomas Huth 738fcf5ef2aSThomas Huth switch (op0) { 739fcf5ef2aSThomas Huth case 0x00: /* l.j */ 740fcf5ef2aSThomas Huth LOG_DIS("l.j %d\n", N26); 741fcf5ef2aSThomas Huth gen_jump(dc, N26, 0, op0); 742fcf5ef2aSThomas Huth break; 743fcf5ef2aSThomas Huth 744fcf5ef2aSThomas Huth case 0x01: /* l.jal */ 745fcf5ef2aSThomas Huth LOG_DIS("l.jal %d\n", N26); 746fcf5ef2aSThomas Huth gen_jump(dc, N26, 0, op0); 747fcf5ef2aSThomas Huth break; 748fcf5ef2aSThomas Huth 749fcf5ef2aSThomas Huth case 0x03: /* l.bnf */ 750fcf5ef2aSThomas Huth LOG_DIS("l.bnf %d\n", N26); 751fcf5ef2aSThomas Huth gen_jump(dc, N26, 0, op0); 752fcf5ef2aSThomas Huth break; 753fcf5ef2aSThomas Huth 754fcf5ef2aSThomas Huth case 0x04: /* l.bf */ 755fcf5ef2aSThomas Huth LOG_DIS("l.bf %d\n", N26); 756fcf5ef2aSThomas Huth gen_jump(dc, N26, 0, op0); 757fcf5ef2aSThomas Huth break; 758fcf5ef2aSThomas Huth 759fcf5ef2aSThomas Huth case 0x05: 760fcf5ef2aSThomas Huth switch (op1) { 761fcf5ef2aSThomas Huth case 0x01: /* l.nop */ 762fcf5ef2aSThomas Huth LOG_DIS("l.nop %d\n", I16); 763fcf5ef2aSThomas Huth break; 764fcf5ef2aSThomas Huth 765fcf5ef2aSThomas Huth default: 766fcf5ef2aSThomas Huth gen_illegal_exception(dc); 767fcf5ef2aSThomas Huth break; 768fcf5ef2aSThomas Huth } 769fcf5ef2aSThomas Huth break; 770fcf5ef2aSThomas Huth 771fcf5ef2aSThomas Huth case 0x11: /* l.jr */ 772fcf5ef2aSThomas Huth LOG_DIS("l.jr r%d\n", rb); 773fcf5ef2aSThomas Huth gen_jump(dc, 0, rb, op0); 774fcf5ef2aSThomas Huth break; 775fcf5ef2aSThomas Huth 776fcf5ef2aSThomas Huth case 0x12: /* l.jalr */ 777fcf5ef2aSThomas Huth LOG_DIS("l.jalr r%d\n", rb); 778fcf5ef2aSThomas Huth gen_jump(dc, 0, rb, op0); 779fcf5ef2aSThomas Huth break; 780fcf5ef2aSThomas Huth 781fcf5ef2aSThomas Huth 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); 786fcf5ef2aSThomas Huth break; 787fcf5ef2aSThomas Huth 788fcf5ef2aSThomas Huth case 0x09: /* l.rfe */ 789fcf5ef2aSThomas Huth LOG_DIS("l.rfe\n"); 790fcf5ef2aSThomas Huth { 791fcf5ef2aSThomas Huth #if defined(CONFIG_USER_ONLY) 792fcf5ef2aSThomas Huth return; 793fcf5ef2aSThomas Huth #else 794fcf5ef2aSThomas Huth if (dc->mem_idx == MMU_USER_IDX) { 795fcf5ef2aSThomas Huth gen_illegal_exception(dc); 796fcf5ef2aSThomas Huth return; 797fcf5ef2aSThomas Huth } 798fcf5ef2aSThomas Huth gen_helper_rfe(cpu_env); 7991ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_UPDATE; 800fcf5ef2aSThomas Huth #endif 801fcf5ef2aSThomas Huth } 802fcf5ef2aSThomas Huth break; 803fcf5ef2aSThomas Huth 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 810fcf5ef2aSThomas Huth case 0x1c: /* l.cust1 */ 811fcf5ef2aSThomas Huth LOG_DIS("l.cust1\n"); 812fcf5ef2aSThomas Huth break; 813fcf5ef2aSThomas Huth 814fcf5ef2aSThomas Huth case 0x1d: /* l.cust2 */ 815fcf5ef2aSThomas Huth LOG_DIS("l.cust2\n"); 816fcf5ef2aSThomas Huth break; 817fcf5ef2aSThomas Huth 818fcf5ef2aSThomas Huth case 0x1e: /* l.cust3 */ 819fcf5ef2aSThomas Huth LOG_DIS("l.cust3\n"); 820fcf5ef2aSThomas Huth break; 821fcf5ef2aSThomas Huth 822fcf5ef2aSThomas Huth case 0x1f: /* l.cust4 */ 823fcf5ef2aSThomas Huth LOG_DIS("l.cust4\n"); 824fcf5ef2aSThomas Huth break; 825fcf5ef2aSThomas Huth 826fcf5ef2aSThomas Huth case 0x3c: /* l.cust5 */ 827fcf5ef2aSThomas Huth LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5); 828fcf5ef2aSThomas Huth break; 829fcf5ef2aSThomas Huth 830fcf5ef2aSThomas Huth case 0x3d: /* l.cust6 */ 831fcf5ef2aSThomas Huth LOG_DIS("l.cust6\n"); 832fcf5ef2aSThomas Huth break; 833fcf5ef2aSThomas Huth 834fcf5ef2aSThomas Huth case 0x3e: /* l.cust7 */ 835fcf5ef2aSThomas Huth LOG_DIS("l.cust7\n"); 836fcf5ef2aSThomas Huth break; 837fcf5ef2aSThomas Huth 838fcf5ef2aSThomas Huth case 0x3f: /* l.cust8 */ 839fcf5ef2aSThomas Huth LOG_DIS("l.cust8\n"); 840fcf5ef2aSThomas Huth break; 841fcf5ef2aSThomas Huth 842fcf5ef2aSThomas Huth /* not used yet, open it when we need or64. */ 843fcf5ef2aSThomas Huth /*#ifdef TARGET_OPENRISC64 844fcf5ef2aSThomas Huth case 0x20: l.ld 845fcf5ef2aSThomas Huth LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); 846fcf5ef2aSThomas Huth check_ob64s(dc); 847fcf5ef2aSThomas Huth mop = MO_TEQ; 848fcf5ef2aSThomas Huth goto do_load; 849fcf5ef2aSThomas Huth #endif*/ 850fcf5ef2aSThomas Huth 851fcf5ef2aSThomas Huth case 0x21: /* l.lwz */ 852fcf5ef2aSThomas Huth LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); 853fcf5ef2aSThomas Huth mop = MO_TEUL; 854fcf5ef2aSThomas Huth goto do_load; 855fcf5ef2aSThomas Huth 856fcf5ef2aSThomas Huth case 0x22: /* l.lws */ 857fcf5ef2aSThomas Huth LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); 858fcf5ef2aSThomas Huth mop = MO_TESL; 859fcf5ef2aSThomas Huth goto do_load; 860fcf5ef2aSThomas Huth 861fcf5ef2aSThomas Huth case 0x23: /* l.lbz */ 862fcf5ef2aSThomas Huth LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); 863fcf5ef2aSThomas Huth mop = MO_UB; 864fcf5ef2aSThomas Huth goto do_load; 865fcf5ef2aSThomas Huth 866fcf5ef2aSThomas Huth case 0x24: /* l.lbs */ 867fcf5ef2aSThomas Huth LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); 868fcf5ef2aSThomas Huth mop = MO_SB; 869fcf5ef2aSThomas Huth goto do_load; 870fcf5ef2aSThomas Huth 871fcf5ef2aSThomas Huth case 0x25: /* l.lhz */ 872fcf5ef2aSThomas Huth LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); 873fcf5ef2aSThomas Huth mop = MO_TEUW; 874fcf5ef2aSThomas Huth goto do_load; 875fcf5ef2aSThomas Huth 876fcf5ef2aSThomas Huth case 0x26: /* l.lhs */ 877fcf5ef2aSThomas Huth LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); 878fcf5ef2aSThomas Huth mop = MO_TESW; 879fcf5ef2aSThomas Huth goto do_load; 880fcf5ef2aSThomas Huth 881fcf5ef2aSThomas Huth 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); 885fcf5ef2aSThomas Huth tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); 886fcf5ef2aSThomas Huth tcg_temp_free(t0); 887fcf5ef2aSThomas Huth break; 888fcf5ef2aSThomas Huth 889fcf5ef2aSThomas Huth case 0x27: /* l.addi */ 890fcf5ef2aSThomas Huth 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); 895fcf5ef2aSThomas Huth break; 896fcf5ef2aSThomas Huth 897fcf5ef2aSThomas Huth case 0x28: /* l.addic */ 898fcf5ef2aSThomas Huth 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); 903fcf5ef2aSThomas Huth break; 904fcf5ef2aSThomas Huth 905fcf5ef2aSThomas Huth 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); 909fcf5ef2aSThomas Huth break; 910fcf5ef2aSThomas Huth 911fcf5ef2aSThomas Huth 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); 915fcf5ef2aSThomas Huth break; 916fcf5ef2aSThomas Huth 917fcf5ef2aSThomas Huth case 0x2b: /* l.xori */ 918fcf5ef2aSThomas Huth 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); 921fcf5ef2aSThomas Huth break; 922fcf5ef2aSThomas Huth 923fcf5ef2aSThomas Huth case 0x2c: /* l.muli */ 924fcf5ef2aSThomas Huth 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); 929fcf5ef2aSThomas Huth break; 930fcf5ef2aSThomas Huth 931fcf5ef2aSThomas Huth 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); 934fcf5ef2aSThomas Huth { 935fcf5ef2aSThomas Huth #if defined(CONFIG_USER_ONLY) 936fcf5ef2aSThomas Huth return; 937fcf5ef2aSThomas Huth #else 9386da544a6SRichard Henderson TCGv_i32 ti = tcg_const_i32(K16); 939fcf5ef2aSThomas Huth if (dc->mem_idx == MMU_USER_IDX) { 940fcf5ef2aSThomas Huth gen_illegal_exception(dc); 941fcf5ef2aSThomas Huth return; 942fcf5ef2aSThomas Huth } 943fcf5ef2aSThomas Huth gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); 944fcf5ef2aSThomas Huth tcg_temp_free_i32(ti); 945fcf5ef2aSThomas Huth #endif 946fcf5ef2aSThomas Huth } 947fcf5ef2aSThomas Huth break; 948fcf5ef2aSThomas Huth 949fcf5ef2aSThomas Huth case 0x30: /* l.mtspr */ 9506da544a6SRichard Henderson LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11); 951fcf5ef2aSThomas Huth { 952fcf5ef2aSThomas Huth #if defined(CONFIG_USER_ONLY) 953fcf5ef2aSThomas Huth return; 954fcf5ef2aSThomas Huth #else 9556da544a6SRichard Henderson TCGv_i32 im = tcg_const_i32(K5_11); 956fcf5ef2aSThomas Huth if (dc->mem_idx == MMU_USER_IDX) { 957fcf5ef2aSThomas Huth gen_illegal_exception(dc); 958fcf5ef2aSThomas Huth return; 959fcf5ef2aSThomas Huth } 960fcf5ef2aSThomas Huth gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); 961fcf5ef2aSThomas Huth tcg_temp_free_i32(im); 962fcf5ef2aSThomas Huth #endif 963fcf5ef2aSThomas Huth } 964fcf5ef2aSThomas Huth break; 965fcf5ef2aSThomas Huth 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 971fcf5ef2aSThomas Huth /* not used yet, open it when we need or64. */ 972fcf5ef2aSThomas Huth /*#ifdef TARGET_OPENRISC64 973fcf5ef2aSThomas Huth case 0x34: l.sd 9746da544a6SRichard Henderson LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11); 975fcf5ef2aSThomas Huth check_ob64s(dc); 976fcf5ef2aSThomas Huth mop = MO_TEQ; 977fcf5ef2aSThomas Huth goto do_store; 978fcf5ef2aSThomas Huth #endif*/ 979fcf5ef2aSThomas Huth 980fcf5ef2aSThomas Huth case 0x35: /* l.sw */ 9816da544a6SRichard Henderson LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11); 982fcf5ef2aSThomas Huth mop = MO_TEUL; 983fcf5ef2aSThomas Huth goto do_store; 984fcf5ef2aSThomas Huth 985fcf5ef2aSThomas Huth case 0x36: /* l.sb */ 9866da544a6SRichard Henderson LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11); 987fcf5ef2aSThomas Huth mop = MO_UB; 988fcf5ef2aSThomas Huth goto do_store; 989fcf5ef2aSThomas Huth 990fcf5ef2aSThomas Huth case 0x37: /* l.sh */ 9916da544a6SRichard Henderson LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11); 992fcf5ef2aSThomas Huth mop = MO_TEUW; 993fcf5ef2aSThomas Huth goto do_store; 994fcf5ef2aSThomas Huth 995fcf5ef2aSThomas Huth do_store: 996fcf5ef2aSThomas Huth { 997fcf5ef2aSThomas Huth TCGv t0 = tcg_temp_new(); 9986da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I5_11); 999fcf5ef2aSThomas Huth tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); 1000fcf5ef2aSThomas Huth tcg_temp_free(t0); 1001fcf5ef2aSThomas Huth } 1002fcf5ef2aSThomas Huth break; 1003fcf5ef2aSThomas Huth 1004fcf5ef2aSThomas Huth default: 1005fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1006fcf5ef2aSThomas Huth break; 1007fcf5ef2aSThomas Huth } 1008fcf5ef2aSThomas Huth } 1009fcf5ef2aSThomas Huth 1010fcf5ef2aSThomas Huth static void dec_mac(DisasContext *dc, uint32_t insn) 1011fcf5ef2aSThomas Huth { 1012fcf5ef2aSThomas Huth uint32_t op0; 1013fcf5ef2aSThomas Huth uint32_t ra, rb; 1014fcf5ef2aSThomas Huth op0 = extract32(insn, 0, 4); 1015fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 1016fcf5ef2aSThomas Huth rb = extract32(insn, 11, 5); 1017fcf5ef2aSThomas Huth 1018fcf5ef2aSThomas Huth switch (op0) { 1019fcf5ef2aSThomas Huth case 0x0001: /* l.mac */ 1020fcf5ef2aSThomas Huth LOG_DIS("l.mac r%d, r%d\n", ra, rb); 10216f7332baSRichard Henderson gen_mac(dc, cpu_R[ra], cpu_R[rb]); 1022fcf5ef2aSThomas Huth break; 1023fcf5ef2aSThomas Huth 1024fcf5ef2aSThomas Huth case 0x0002: /* l.msb */ 1025fcf5ef2aSThomas Huth LOG_DIS("l.msb r%d, r%d\n", ra, rb); 10266f7332baSRichard Henderson gen_msb(dc, cpu_R[ra], cpu_R[rb]); 1027fcf5ef2aSThomas Huth break; 1028fcf5ef2aSThomas Huth 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 1039fcf5ef2aSThomas Huth default: 1040fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1041fcf5ef2aSThomas Huth break; 1042fcf5ef2aSThomas Huth } 1043fcf5ef2aSThomas Huth } 1044fcf5ef2aSThomas Huth 1045fcf5ef2aSThomas Huth static void dec_logic(DisasContext *dc, uint32_t insn) 1046fcf5ef2aSThomas Huth { 1047fcf5ef2aSThomas Huth uint32_t op0; 10486da544a6SRichard Henderson uint32_t rd, ra, L6, S6; 1049fcf5ef2aSThomas Huth op0 = extract32(insn, 6, 2); 1050fcf5ef2aSThomas Huth rd = extract32(insn, 21, 5); 1051fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 1052fcf5ef2aSThomas Huth L6 = extract32(insn, 0, 6); 10536da544a6SRichard Henderson S6 = L6 & (TARGET_LONG_BITS - 1); 1054fcf5ef2aSThomas Huth 10556597c28dSRichard Henderson check_r0_write(rd); 1056fcf5ef2aSThomas Huth switch (op0) { 1057fcf5ef2aSThomas Huth case 0x00: /* l.slli */ 1058fcf5ef2aSThomas Huth 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); 1060fcf5ef2aSThomas Huth break; 1061fcf5ef2aSThomas Huth 1062fcf5ef2aSThomas Huth case 0x01: /* l.srli */ 1063fcf5ef2aSThomas Huth 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); 1065fcf5ef2aSThomas Huth break; 1066fcf5ef2aSThomas Huth 1067fcf5ef2aSThomas Huth case 0x02: /* l.srai */ 1068fcf5ef2aSThomas Huth 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; 1071fcf5ef2aSThomas Huth 1072fcf5ef2aSThomas Huth case 0x03: /* l.rori */ 1073fcf5ef2aSThomas Huth 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); 1075fcf5ef2aSThomas Huth break; 1076fcf5ef2aSThomas Huth 1077fcf5ef2aSThomas Huth default: 1078fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1079fcf5ef2aSThomas Huth break; 1080fcf5ef2aSThomas Huth } 1081fcf5ef2aSThomas Huth } 1082fcf5ef2aSThomas Huth 1083fcf5ef2aSThomas Huth static void dec_M(DisasContext *dc, uint32_t insn) 1084fcf5ef2aSThomas Huth { 1085fcf5ef2aSThomas Huth uint32_t op0; 1086fcf5ef2aSThomas Huth uint32_t rd; 1087fcf5ef2aSThomas Huth uint32_t K16; 1088fcf5ef2aSThomas Huth op0 = extract32(insn, 16, 1); 1089fcf5ef2aSThomas Huth rd = extract32(insn, 21, 5); 1090fcf5ef2aSThomas Huth K16 = extract32(insn, 0, 16); 1091fcf5ef2aSThomas Huth 10926597c28dSRichard Henderson check_r0_write(rd); 1093fcf5ef2aSThomas Huth switch (op0) { 1094fcf5ef2aSThomas Huth case 0x0: /* l.movhi */ 1095fcf5ef2aSThomas Huth LOG_DIS("l.movhi r%d, %d\n", rd, K16); 1096fcf5ef2aSThomas Huth tcg_gen_movi_tl(cpu_R[rd], (K16 << 16)); 1097fcf5ef2aSThomas Huth break; 1098fcf5ef2aSThomas Huth 1099fcf5ef2aSThomas Huth case 0x1: /* l.macrc */ 1100fcf5ef2aSThomas Huth 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); 1103fcf5ef2aSThomas Huth break; 1104fcf5ef2aSThomas Huth 1105fcf5ef2aSThomas Huth default: 1106fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1107fcf5ef2aSThomas Huth break; 1108fcf5ef2aSThomas Huth } 1109fcf5ef2aSThomas Huth } 1110fcf5ef2aSThomas Huth 1111fcf5ef2aSThomas Huth static void dec_comp(DisasContext *dc, uint32_t insn) 1112fcf5ef2aSThomas Huth { 1113fcf5ef2aSThomas Huth uint32_t op0; 1114fcf5ef2aSThomas Huth uint32_t ra, rb; 1115fcf5ef2aSThomas Huth 1116fcf5ef2aSThomas Huth op0 = extract32(insn, 21, 5); 1117fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 1118fcf5ef2aSThomas Huth rb = extract32(insn, 11, 5); 1119fcf5ef2aSThomas Huth 1120fcf5ef2aSThomas Huth /* unsigned integers */ 1121fcf5ef2aSThomas Huth tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); 1122fcf5ef2aSThomas Huth tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); 1123fcf5ef2aSThomas Huth 1124fcf5ef2aSThomas Huth switch (op0) { 1125fcf5ef2aSThomas Huth case 0x0: /* l.sfeq */ 1126fcf5ef2aSThomas Huth 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]); 1128fcf5ef2aSThomas Huth break; 1129fcf5ef2aSThomas Huth 1130fcf5ef2aSThomas Huth case 0x1: /* l.sfne */ 1131fcf5ef2aSThomas Huth 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]); 1133fcf5ef2aSThomas Huth break; 1134fcf5ef2aSThomas Huth 1135fcf5ef2aSThomas Huth case 0x2: /* l.sfgtu */ 1136fcf5ef2aSThomas Huth 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]); 1138fcf5ef2aSThomas Huth break; 1139fcf5ef2aSThomas Huth 1140fcf5ef2aSThomas Huth case 0x3: /* l.sfgeu */ 1141fcf5ef2aSThomas Huth 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]); 1143fcf5ef2aSThomas Huth break; 1144fcf5ef2aSThomas Huth 1145fcf5ef2aSThomas Huth case 0x4: /* l.sfltu */ 1146fcf5ef2aSThomas Huth 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]); 1148fcf5ef2aSThomas Huth break; 1149fcf5ef2aSThomas Huth 1150fcf5ef2aSThomas Huth case 0x5: /* l.sfleu */ 1151fcf5ef2aSThomas Huth 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]); 1153fcf5ef2aSThomas Huth break; 1154fcf5ef2aSThomas Huth 1155fcf5ef2aSThomas Huth case 0xa: /* l.sfgts */ 1156fcf5ef2aSThomas Huth 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]); 1158fcf5ef2aSThomas Huth break; 1159fcf5ef2aSThomas Huth 1160fcf5ef2aSThomas Huth case 0xb: /* l.sfges */ 1161fcf5ef2aSThomas Huth 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]); 1163fcf5ef2aSThomas Huth break; 1164fcf5ef2aSThomas Huth 1165fcf5ef2aSThomas Huth case 0xc: /* l.sflts */ 1166fcf5ef2aSThomas Huth 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]); 1168fcf5ef2aSThomas Huth break; 1169fcf5ef2aSThomas Huth 1170fcf5ef2aSThomas Huth case 0xd: /* l.sfles */ 1171fcf5ef2aSThomas Huth 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]); 1173fcf5ef2aSThomas Huth break; 1174fcf5ef2aSThomas Huth 1175fcf5ef2aSThomas Huth default: 1176fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1177fcf5ef2aSThomas Huth break; 1178fcf5ef2aSThomas Huth } 1179fcf5ef2aSThomas Huth } 1180fcf5ef2aSThomas Huth 1181fcf5ef2aSThomas Huth static void dec_compi(DisasContext *dc, uint32_t insn) 1182fcf5ef2aSThomas Huth { 11836da544a6SRichard Henderson uint32_t op0, ra; 11846da544a6SRichard Henderson int32_t I16; 1185fcf5ef2aSThomas Huth 1186fcf5ef2aSThomas Huth op0 = extract32(insn, 21, 5); 1187fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 11886da544a6SRichard Henderson I16 = sextract32(insn, 0, 16); 1189fcf5ef2aSThomas Huth 1190fcf5ef2aSThomas Huth switch (op0) { 1191fcf5ef2aSThomas Huth case 0x0: /* l.sfeqi */ 1192fcf5ef2aSThomas Huth 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); 1194fcf5ef2aSThomas Huth break; 1195fcf5ef2aSThomas Huth 1196fcf5ef2aSThomas Huth case 0x1: /* l.sfnei */ 1197fcf5ef2aSThomas Huth 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); 1199fcf5ef2aSThomas Huth break; 1200fcf5ef2aSThomas Huth 1201fcf5ef2aSThomas Huth case 0x2: /* l.sfgtui */ 1202fcf5ef2aSThomas Huth 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); 1204fcf5ef2aSThomas Huth break; 1205fcf5ef2aSThomas Huth 1206fcf5ef2aSThomas Huth case 0x3: /* l.sfgeui */ 1207fcf5ef2aSThomas Huth 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); 1209fcf5ef2aSThomas Huth break; 1210fcf5ef2aSThomas Huth 1211fcf5ef2aSThomas Huth case 0x4: /* l.sfltui */ 1212fcf5ef2aSThomas Huth 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); 1214fcf5ef2aSThomas Huth break; 1215fcf5ef2aSThomas Huth 1216fcf5ef2aSThomas Huth case 0x5: /* l.sfleui */ 1217fcf5ef2aSThomas Huth 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); 1219fcf5ef2aSThomas Huth break; 1220fcf5ef2aSThomas Huth 1221fcf5ef2aSThomas Huth case 0xa: /* l.sfgtsi */ 1222fcf5ef2aSThomas Huth 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); 1224fcf5ef2aSThomas Huth break; 1225fcf5ef2aSThomas Huth 1226fcf5ef2aSThomas Huth case 0xb: /* l.sfgesi */ 1227fcf5ef2aSThomas Huth 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); 1229fcf5ef2aSThomas Huth break; 1230fcf5ef2aSThomas Huth 1231fcf5ef2aSThomas Huth case 0xc: /* l.sfltsi */ 1232fcf5ef2aSThomas Huth 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); 1234fcf5ef2aSThomas Huth break; 1235fcf5ef2aSThomas Huth 1236fcf5ef2aSThomas Huth case 0xd: /* l.sflesi */ 1237fcf5ef2aSThomas Huth 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); 1239fcf5ef2aSThomas Huth break; 1240fcf5ef2aSThomas Huth 1241fcf5ef2aSThomas Huth default: 1242fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1243fcf5ef2aSThomas Huth break; 1244fcf5ef2aSThomas Huth } 1245fcf5ef2aSThomas Huth } 1246fcf5ef2aSThomas Huth 1247*7de9729fSRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a, uint32_t insn) 1248fcf5ef2aSThomas Huth { 1249*7de9729fSRichard Henderson LOG_DIS("l.sys %d\n", a->k); 12501ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1251fcf5ef2aSThomas Huth gen_exception(dc, EXCP_SYSCALL); 12521ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1253*7de9729fSRichard Henderson return true; 1254*7de9729fSRichard Henderson } 1255fcf5ef2aSThomas Huth 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); 1260fcf5ef2aSThomas Huth gen_exception(dc, EXCP_TRAP); 12611ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1262*7de9729fSRichard Henderson return true; 1263*7de9729fSRichard Henderson } 1264fcf5ef2aSThomas Huth 1265*7de9729fSRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a, uint32_t insn) 1266*7de9729fSRichard Henderson { 1267fcf5ef2aSThomas Huth LOG_DIS("l.msync\n"); 126824fc5c0fSRichard Henderson tcg_gen_mb(TCG_MO_ALL); 1269*7de9729fSRichard Henderson return true; 1270fcf5ef2aSThomas Huth } 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; 1282fcf5ef2aSThomas Huth } 1283fcf5ef2aSThomas Huth 1284fcf5ef2aSThomas Huth static void dec_float(DisasContext *dc, uint32_t insn) 1285fcf5ef2aSThomas Huth { 1286fcf5ef2aSThomas Huth uint32_t op0; 1287fcf5ef2aSThomas Huth uint32_t ra, rb, rd; 1288fcf5ef2aSThomas Huth op0 = extract32(insn, 0, 8); 1289fcf5ef2aSThomas Huth ra = extract32(insn, 16, 5); 1290fcf5ef2aSThomas Huth rb = extract32(insn, 11, 5); 1291fcf5ef2aSThomas Huth rd = extract32(insn, 21, 5); 1292fcf5ef2aSThomas Huth 1293fcf5ef2aSThomas Huth switch (op0) { 1294fcf5ef2aSThomas Huth case 0x00: /* lf.add.s */ 1295fcf5ef2aSThomas Huth LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb); 12966597c28dSRichard Henderson check_r0_write(rd); 1297fcf5ef2aSThomas Huth gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 12984e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1299fcf5ef2aSThomas Huth break; 1300fcf5ef2aSThomas Huth 1301fcf5ef2aSThomas Huth case 0x01: /* lf.sub.s */ 1302fcf5ef2aSThomas Huth LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb); 13036597c28dSRichard Henderson check_r0_write(rd); 1304fcf5ef2aSThomas Huth gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 13054e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1306fcf5ef2aSThomas Huth break; 1307fcf5ef2aSThomas Huth 1308fcf5ef2aSThomas Huth case 0x02: /* lf.mul.s */ 1309fcf5ef2aSThomas Huth LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb); 13106597c28dSRichard Henderson check_r0_write(rd); 1311fcf5ef2aSThomas Huth gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 13124e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1313fcf5ef2aSThomas Huth break; 1314fcf5ef2aSThomas Huth 1315fcf5ef2aSThomas Huth case 0x03: /* lf.div.s */ 1316fcf5ef2aSThomas Huth LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb); 13176597c28dSRichard Henderson check_r0_write(rd); 1318fcf5ef2aSThomas Huth gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 13194e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1320fcf5ef2aSThomas Huth break; 1321fcf5ef2aSThomas Huth 1322fcf5ef2aSThomas Huth case 0x04: /* lf.itof.s */ 1323fcf5ef2aSThomas Huth LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 13246597c28dSRichard Henderson check_r0_write(rd); 1325fcf5ef2aSThomas Huth gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]); 13264e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1327fcf5ef2aSThomas Huth break; 1328fcf5ef2aSThomas Huth 1329fcf5ef2aSThomas Huth case 0x05: /* lf.ftoi.s */ 1330fcf5ef2aSThomas Huth LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 13316597c28dSRichard Henderson check_r0_write(rd); 1332fcf5ef2aSThomas Huth gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]); 13334e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1334fcf5ef2aSThomas Huth break; 1335fcf5ef2aSThomas Huth 1336fcf5ef2aSThomas Huth case 0x06: /* lf.rem.s */ 1337fcf5ef2aSThomas Huth LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb); 13386597c28dSRichard Henderson check_r0_write(rd); 1339fcf5ef2aSThomas Huth gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 13404e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1341fcf5ef2aSThomas Huth break; 1342fcf5ef2aSThomas Huth 1343fcf5ef2aSThomas Huth case 0x07: /* lf.madd.s */ 1344fcf5ef2aSThomas Huth 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); 1349fcf5ef2aSThomas Huth break; 1350fcf5ef2aSThomas Huth 1351fcf5ef2aSThomas Huth case 0x08: /* lf.sfeq.s */ 1352fcf5ef2aSThomas Huth 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); 1355fcf5ef2aSThomas Huth break; 1356fcf5ef2aSThomas Huth 1357fcf5ef2aSThomas Huth case 0x09: /* lf.sfne.s */ 1358fcf5ef2aSThomas Huth 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); 1362fcf5ef2aSThomas Huth break; 1363fcf5ef2aSThomas Huth 1364fcf5ef2aSThomas Huth case 0x0a: /* lf.sfgt.s */ 1365fcf5ef2aSThomas Huth 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); 1368fcf5ef2aSThomas Huth break; 1369fcf5ef2aSThomas Huth 1370fcf5ef2aSThomas Huth case 0x0b: /* lf.sfge.s */ 1371fcf5ef2aSThomas Huth 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); 1374fcf5ef2aSThomas Huth break; 1375fcf5ef2aSThomas Huth 1376fcf5ef2aSThomas Huth case 0x0c: /* lf.sflt.s */ 1377fcf5ef2aSThomas Huth 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); 1380fcf5ef2aSThomas Huth break; 1381fcf5ef2aSThomas Huth 1382fcf5ef2aSThomas Huth case 0x0d: /* lf.sfle.s */ 1383fcf5ef2aSThomas Huth 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); 1386fcf5ef2aSThomas Huth break; 1387fcf5ef2aSThomas Huth 13884e2d3007SRichard Henderson #ifdef TARGET_OPENRISC64 13894e2d3007SRichard Henderson case 0x10: /* lf.add.d */ 1390fcf5ef2aSThomas Huth LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb); 1391fcf5ef2aSThomas Huth check_of64s(dc); 13926597c28dSRichard Henderson check_r0_write(rd); 1393fcf5ef2aSThomas Huth gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 13944e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1395fcf5ef2aSThomas Huth break; 1396fcf5ef2aSThomas Huth 13974e2d3007SRichard Henderson case 0x11: /* lf.sub.d */ 1398fcf5ef2aSThomas Huth LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb); 1399fcf5ef2aSThomas Huth check_of64s(dc); 14006597c28dSRichard Henderson check_r0_write(rd); 1401fcf5ef2aSThomas Huth gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 14024e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1403fcf5ef2aSThomas Huth break; 1404fcf5ef2aSThomas Huth 14054e2d3007SRichard Henderson case 0x12: /* lf.mul.d */ 1406fcf5ef2aSThomas Huth LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb); 1407fcf5ef2aSThomas Huth check_of64s(dc); 14086597c28dSRichard Henderson check_r0_write(rd); 1409fcf5ef2aSThomas Huth gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 14104e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1411fcf5ef2aSThomas Huth break; 1412fcf5ef2aSThomas Huth 14134e2d3007SRichard Henderson case 0x13: /* lf.div.d */ 1414fcf5ef2aSThomas Huth LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb); 1415fcf5ef2aSThomas Huth check_of64s(dc); 14166597c28dSRichard Henderson check_r0_write(rd); 1417fcf5ef2aSThomas Huth gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 14184e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1419fcf5ef2aSThomas Huth break; 1420fcf5ef2aSThomas Huth 14214e2d3007SRichard Henderson case 0x14: /* lf.itof.d */ 1422fcf5ef2aSThomas Huth LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1423fcf5ef2aSThomas Huth check_of64s(dc); 14246597c28dSRichard Henderson check_r0_write(rd); 1425fcf5ef2aSThomas Huth gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]); 14264e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1427fcf5ef2aSThomas Huth break; 1428fcf5ef2aSThomas Huth 14294e2d3007SRichard Henderson case 0x15: /* lf.ftoi.d */ 1430fcf5ef2aSThomas Huth LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1431fcf5ef2aSThomas Huth check_of64s(dc); 14326597c28dSRichard Henderson check_r0_write(rd); 1433fcf5ef2aSThomas Huth gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]); 14344e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1435fcf5ef2aSThomas Huth break; 1436fcf5ef2aSThomas Huth 14374e2d3007SRichard Henderson case 0x16: /* lf.rem.d */ 1438fcf5ef2aSThomas Huth LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb); 1439fcf5ef2aSThomas Huth check_of64s(dc); 14406597c28dSRichard Henderson check_r0_write(rd); 1441fcf5ef2aSThomas Huth gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 14424e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1443fcf5ef2aSThomas Huth break; 1444fcf5ef2aSThomas Huth 14454e2d3007SRichard Henderson case 0x17: /* lf.madd.d */ 1446fcf5ef2aSThomas Huth LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); 1447fcf5ef2aSThomas Huth 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); 1452fcf5ef2aSThomas Huth break; 1453fcf5ef2aSThomas Huth 14544e2d3007SRichard Henderson case 0x18: /* lf.sfeq.d */ 1455fcf5ef2aSThomas Huth LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); 1456fcf5ef2aSThomas Huth 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); 1459fcf5ef2aSThomas Huth break; 1460fcf5ef2aSThomas Huth 14614e2d3007SRichard Henderson case 0x1a: /* lf.sfgt.d */ 1462fcf5ef2aSThomas Huth LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); 1463fcf5ef2aSThomas Huth 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); 1466fcf5ef2aSThomas Huth break; 1467fcf5ef2aSThomas Huth 14684e2d3007SRichard Henderson case 0x1b: /* lf.sfge.d */ 1469fcf5ef2aSThomas Huth LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); 1470fcf5ef2aSThomas Huth 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); 1473fcf5ef2aSThomas Huth break; 1474fcf5ef2aSThomas Huth 14754e2d3007SRichard Henderson case 0x19: /* lf.sfne.d */ 1476fcf5ef2aSThomas Huth LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); 1477fcf5ef2aSThomas Huth 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); 1481fcf5ef2aSThomas Huth break; 1482fcf5ef2aSThomas Huth 14834e2d3007SRichard Henderson case 0x1c: /* lf.sflt.d */ 1484fcf5ef2aSThomas Huth LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); 1485fcf5ef2aSThomas Huth 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); 1488fcf5ef2aSThomas Huth break; 1489fcf5ef2aSThomas Huth 14904e2d3007SRichard Henderson case 0x1d: /* lf.sfle.d */ 1491fcf5ef2aSThomas Huth LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); 1492fcf5ef2aSThomas Huth 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); 1495fcf5ef2aSThomas Huth break; 14964e2d3007SRichard Henderson #endif 1497fcf5ef2aSThomas Huth 1498fcf5ef2aSThomas Huth default: 1499fcf5ef2aSThomas Huth gen_illegal_exception(dc); 1500fcf5ef2aSThomas Huth break; 1501fcf5ef2aSThomas Huth } 1502fcf5ef2aSThomas Huth } 1503fcf5ef2aSThomas Huth 1504fcf5ef2aSThomas Huth static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) 1505fcf5ef2aSThomas Huth { 1506fcf5ef2aSThomas Huth uint32_t op0; 1507*7de9729fSRichard Henderson uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next); 1508fcf5ef2aSThomas Huth 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); 1515fcf5ef2aSThomas Huth switch (op0) { 1516fcf5ef2aSThomas Huth case 0x06: 1517fcf5ef2aSThomas Huth dec_M(dc, insn); 1518fcf5ef2aSThomas Huth break; 1519fcf5ef2aSThomas Huth 1520fcf5ef2aSThomas Huth case 0x2e: 1521fcf5ef2aSThomas Huth dec_logic(dc, insn); 1522fcf5ef2aSThomas Huth break; 1523fcf5ef2aSThomas Huth 1524fcf5ef2aSThomas Huth case 0x2f: 1525fcf5ef2aSThomas Huth dec_compi(dc, insn); 1526fcf5ef2aSThomas Huth break; 1527fcf5ef2aSThomas Huth 1528fcf5ef2aSThomas Huth case 0x31: 1529fcf5ef2aSThomas Huth dec_mac(dc, insn); 1530fcf5ef2aSThomas Huth break; 1531fcf5ef2aSThomas Huth 1532fcf5ef2aSThomas Huth case 0x32: 1533fcf5ef2aSThomas Huth dec_float(dc, insn); 1534fcf5ef2aSThomas Huth break; 1535fcf5ef2aSThomas Huth 1536fcf5ef2aSThomas Huth case 0x38: 1537fcf5ef2aSThomas Huth dec_calc(dc, insn); 1538fcf5ef2aSThomas Huth break; 1539fcf5ef2aSThomas Huth 1540fcf5ef2aSThomas Huth case 0x39: 1541fcf5ef2aSThomas Huth dec_comp(dc, insn); 1542fcf5ef2aSThomas Huth break; 1543fcf5ef2aSThomas Huth 1544fcf5ef2aSThomas Huth default: 1545fcf5ef2aSThomas Huth dec_misc(dc, insn); 1546fcf5ef2aSThomas Huth break; 1547fcf5ef2aSThomas Huth } 1548fcf5ef2aSThomas Huth } 1549fcf5ef2aSThomas Huth 1550a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs) 1551fcf5ef2aSThomas Huth { 1552a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcb, DisasContext, base); 15539c489ea6SLluís Vilanova CPUOpenRISCState *env = cs->env_ptr; 1554a4fd3ec3SEmilio G. Cota int bound; 1555fcf5ef2aSThomas Huth 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); 1561fcf5ef2aSThomas Huth } 1562fcf5ef2aSThomas Huth 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); 1566fcf5ef2aSThomas Huth 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 } 1583fcf5ef2aSThomas Huth 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); 1590fcf5ef2aSThomas Huth gen_exception(dc, EXCP_DEBUG); 15911ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1592fcf5ef2aSThomas Huth /* The address covered by the breakpoint must be included in 1593fcf5ef2aSThomas Huth [tb->pc, tb->pc + tb->size) in order to for it to be 1594fcf5ef2aSThomas Huth properly cleared -- thus we increment the PC here so that 1595fcf5ef2aSThomas Huth the logic setting tb->size below does the right thing. */ 15961ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 1597a4fd3ec3SEmilio G. Cota return true; 1598fcf5ef2aSThomas Huth } 1599fcf5ef2aSThomas Huth 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 1605fcf5ef2aSThomas Huth disas_openrisc_insn(dc, cpu); 16061ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 160724c32852SRichard Henderson 1608fcf5ef2aSThomas Huth /* delay slot */ 1609fcf5ef2aSThomas Huth if (dc->delayed_branch) { 1610fcf5ef2aSThomas Huth dc->delayed_branch--; 1611fcf5ef2aSThomas Huth if (!dc->delayed_branch) { 1612fcf5ef2aSThomas Huth 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; 1616fcf5ef2aSThomas Huth } 1617fcf5ef2aSThomas Huth } 1618a4fd3ec3SEmilio G. Cota } 1619fcf5ef2aSThomas Huth 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); 1632fcf5ef2aSThomas Huth } 16331ffa4bceSEmilio G. Cota if (unlikely(dc->base.singlestep_enabled)) { 1634fcf5ef2aSThomas Huth gen_exception(dc, EXCP_DEBUG); 1635fcf5ef2aSThomas Huth } 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); 1639fcf5ef2aSThomas Huth break; 16401ffa4bceSEmilio G. Cota case DISAS_NORETURN: 1641fcf5ef2aSThomas Huth case DISAS_JUMP: 16421ffa4bceSEmilio G. Cota case DISAS_TB_JUMP: 1643fcf5ef2aSThomas Huth break; 1644fcf5ef2aSThomas Huth case DISAS_UPDATE: 1645fcf5ef2aSThomas Huth /* indicate that the hash table must be used 1646fcf5ef2aSThomas Huth to find the next TB */ 1647fcf5ef2aSThomas Huth tcg_gen_exit_tb(0); 1648fcf5ef2aSThomas Huth break; 1649a4fd3ec3SEmilio G. Cota default: 1650a4fd3ec3SEmilio G. Cota g_assert_not_reached(); 1651a4fd3ec3SEmilio G. Cota } 1652fcf5ef2aSThomas Huth } 1653fcf5ef2aSThomas Huth } 1654fcf5ef2aSThomas Huth 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); 1658fcf5ef2aSThomas Huth 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); 1661fcf5ef2aSThomas Huth } 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); 1678fcf5ef2aSThomas Huth } 1679fcf5ef2aSThomas Huth 1680fcf5ef2aSThomas Huth void openrisc_cpu_dump_state(CPUState *cs, FILE *f, 1681fcf5ef2aSThomas Huth fprintf_function cpu_fprintf, 1682fcf5ef2aSThomas Huth int flags) 1683fcf5ef2aSThomas Huth { 1684fcf5ef2aSThomas Huth OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1685fcf5ef2aSThomas Huth CPUOpenRISCState *env = &cpu->env; 1686fcf5ef2aSThomas Huth int i; 1687fcf5ef2aSThomas Huth 1688fcf5ef2aSThomas Huth cpu_fprintf(f, "PC=%08x\n", env->pc); 1689fcf5ef2aSThomas Huth for (i = 0; i < 32; ++i) { 1690d89e71e8SStafford Horne cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i), 1691fcf5ef2aSThomas Huth (i % 4) == 3 ? '\n' : ' '); 1692fcf5ef2aSThomas Huth } 1693fcf5ef2aSThomas Huth } 1694fcf5ef2aSThomas Huth 1695fcf5ef2aSThomas Huth void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1696fcf5ef2aSThomas Huth target_ulong *data) 1697fcf5ef2aSThomas Huth { 1698fcf5ef2aSThomas Huth 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 } 1703fcf5ef2aSThomas Huth } 1704