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" 30bbe418f2SJia Liu 312ef6175aSRichard Henderson #include "exec/helper-proto.h" 322ef6175aSRichard Henderson #include "exec/helper-gen.h" 33e67db06eSJia Liu 34a7e30d84SLluís Vilanova #include "trace-tcg.h" 35508127e2SPaolo Bonzini #include "exec/log.h" 36a7e30d84SLluís Vilanova 37111ece51SRichard Henderson #define LOG_DIS(str, ...) \ 38111ece51SRichard Henderson qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->pc, ## __VA_ARGS__) 39e67db06eSJia Liu 40bbe418f2SJia Liu typedef struct DisasContext { 41bbe418f2SJia Liu TranslationBlock *tb; 42bbe418f2SJia Liu target_ulong pc, ppc, npc; 43bbe418f2SJia Liu uint32_t tb_flags, synced_flags, flags; 44bbe418f2SJia Liu uint32_t is_jmp; 45bbe418f2SJia Liu uint32_t mem_idx; 46bbe418f2SJia Liu int singlestep_enabled; 47bbe418f2SJia Liu uint32_t delayed_branch; 48bbe418f2SJia Liu } DisasContext; 49bbe418f2SJia Liu 501bcea73eSLluís Vilanova static TCGv_env cpu_env; 51bbe418f2SJia Liu static TCGv cpu_sr; 52bbe418f2SJia Liu static TCGv cpu_R[32]; 53bbe418f2SJia Liu static TCGv cpu_pc; 54bbe418f2SJia Liu static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ 55bbe418f2SJia Liu static TCGv cpu_npc; 56bbe418f2SJia Liu static TCGv cpu_ppc; 57bbe418f2SJia Liu static TCGv_i32 env_btaken; /* bf/bnf , F flag taken */ 58930c3d00SRichard Henderson static TCGv cpu_lock_addr; 59930c3d00SRichard Henderson static TCGv cpu_lock_value; 60bbe418f2SJia Liu static TCGv_i32 fpcsr; 61bbe418f2SJia Liu static TCGv machi, maclo; 62bbe418f2SJia Liu static TCGv fpmaddhi, fpmaddlo; 63bbe418f2SJia Liu static TCGv_i32 env_flags; 64022c62cbSPaolo Bonzini #include "exec/gen-icount.h" 65bbe418f2SJia Liu 66e67db06eSJia Liu void openrisc_translate_init(void) 67e67db06eSJia Liu { 68bbe418f2SJia Liu static const char * const regnames[] = { 69bbe418f2SJia Liu "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 70bbe418f2SJia Liu "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 71bbe418f2SJia Liu "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 72bbe418f2SJia Liu "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 73bbe418f2SJia Liu }; 74bbe418f2SJia Liu int i; 75bbe418f2SJia Liu 76bbe418f2SJia Liu cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 777c255043SLluís Vilanova tcg_ctx.tcg_env = cpu_env; 78e1ccc054SRichard Henderson cpu_sr = tcg_global_mem_new(cpu_env, 79bbe418f2SJia Liu offsetof(CPUOpenRISCState, sr), "sr"); 80e1ccc054SRichard Henderson env_flags = tcg_global_mem_new_i32(cpu_env, 81bbe418f2SJia Liu offsetof(CPUOpenRISCState, flags), 82bbe418f2SJia Liu "flags"); 83e1ccc054SRichard Henderson cpu_pc = tcg_global_mem_new(cpu_env, 84bbe418f2SJia Liu offsetof(CPUOpenRISCState, pc), "pc"); 85e1ccc054SRichard Henderson cpu_npc = tcg_global_mem_new(cpu_env, 86bbe418f2SJia Liu offsetof(CPUOpenRISCState, npc), "npc"); 87e1ccc054SRichard Henderson cpu_ppc = tcg_global_mem_new(cpu_env, 88bbe418f2SJia Liu offsetof(CPUOpenRISCState, ppc), "ppc"); 89e1ccc054SRichard Henderson jmp_pc = tcg_global_mem_new(cpu_env, 90bbe418f2SJia Liu offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc"); 91e1ccc054SRichard Henderson env_btaken = tcg_global_mem_new_i32(cpu_env, 92bbe418f2SJia Liu offsetof(CPUOpenRISCState, btaken), 93bbe418f2SJia Liu "btaken"); 94930c3d00SRichard Henderson cpu_lock_addr = tcg_global_mem_new(cpu_env, 95930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_addr), 96930c3d00SRichard Henderson "lock_addr"); 97930c3d00SRichard Henderson cpu_lock_value = tcg_global_mem_new(cpu_env, 98930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_value), 99930c3d00SRichard Henderson "lock_value"); 100e1ccc054SRichard Henderson fpcsr = tcg_global_mem_new_i32(cpu_env, 101bbe418f2SJia Liu offsetof(CPUOpenRISCState, fpcsr), 102bbe418f2SJia Liu "fpcsr"); 103e1ccc054SRichard Henderson machi = tcg_global_mem_new(cpu_env, 104bbe418f2SJia Liu offsetof(CPUOpenRISCState, machi), 105bbe418f2SJia Liu "machi"); 106e1ccc054SRichard Henderson maclo = tcg_global_mem_new(cpu_env, 107bbe418f2SJia Liu offsetof(CPUOpenRISCState, maclo), 108bbe418f2SJia Liu "maclo"); 109e1ccc054SRichard Henderson fpmaddhi = tcg_global_mem_new(cpu_env, 110bbe418f2SJia Liu offsetof(CPUOpenRISCState, fpmaddhi), 111bbe418f2SJia Liu "fpmaddhi"); 112e1ccc054SRichard Henderson fpmaddlo = tcg_global_mem_new(cpu_env, 113bbe418f2SJia Liu offsetof(CPUOpenRISCState, fpmaddlo), 114bbe418f2SJia Liu "fpmaddlo"); 115bbe418f2SJia Liu for (i = 0; i < 32; i++) { 116e1ccc054SRichard Henderson cpu_R[i] = tcg_global_mem_new(cpu_env, 117bbe418f2SJia Liu offsetof(CPUOpenRISCState, gpr[i]), 118bbe418f2SJia Liu regnames[i]); 119bbe418f2SJia Liu } 120bbe418f2SJia Liu } 121bbe418f2SJia Liu 1222e0fc3a4SStefan Weil /* Writeback SR_F translation space to execution space. */ 123bbe418f2SJia Liu static inline void wb_SR_F(void) 124bbe418f2SJia Liu { 12542a268c2SRichard Henderson TCGLabel *label = gen_new_label(); 126bbe418f2SJia Liu tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F); 127bbe418f2SJia Liu tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label); 128bbe418f2SJia Liu tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F); 129bbe418f2SJia Liu gen_set_label(label); 130bbe418f2SJia Liu } 131bbe418f2SJia Liu 132bbe418f2SJia Liu static inline void gen_sync_flags(DisasContext *dc) 133bbe418f2SJia Liu { 134bbe418f2SJia Liu /* Sync the tb dependent flag between translate and runtime. */ 1350c53d734SRichard Henderson if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) { 1360c53d734SRichard Henderson tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG); 137bbe418f2SJia Liu dc->synced_flags = dc->tb_flags; 138bbe418f2SJia Liu } 139bbe418f2SJia Liu } 140bbe418f2SJia Liu 141bbe418f2SJia Liu static void gen_exception(DisasContext *dc, unsigned int excp) 142bbe418f2SJia Liu { 143bbe418f2SJia Liu TCGv_i32 tmp = tcg_const_i32(excp); 144bbe418f2SJia Liu gen_helper_exception(cpu_env, tmp); 145bbe418f2SJia Liu tcg_temp_free_i32(tmp); 146bbe418f2SJia Liu } 147bbe418f2SJia Liu 148bbe418f2SJia Liu static void gen_illegal_exception(DisasContext *dc) 149bbe418f2SJia Liu { 150bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 151bbe418f2SJia Liu gen_exception(dc, EXCP_ILLEGAL); 152bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 153bbe418f2SJia Liu } 154bbe418f2SJia Liu 155bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 156bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 157bbe418f2SJia Liu static void check_ob64s(DisasContext *dc) 158bbe418f2SJia Liu { 159bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OB64S)) { 160bbe418f2SJia Liu gen_illegal_exception(dc); 161bbe418f2SJia Liu } 162bbe418f2SJia Liu } 163bbe418f2SJia Liu 164bbe418f2SJia Liu static void check_of64s(DisasContext *dc) 165bbe418f2SJia Liu { 166bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OF64S)) { 167bbe418f2SJia Liu gen_illegal_exception(dc); 168bbe418f2SJia Liu } 169bbe418f2SJia Liu } 170bbe418f2SJia Liu 171bbe418f2SJia Liu static void check_ov64s(DisasContext *dc) 172bbe418f2SJia Liu { 173bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OV64S)) { 174bbe418f2SJia Liu gen_illegal_exception(dc); 175bbe418f2SJia Liu } 176bbe418f2SJia Liu } 177bbe418f2SJia Liu #endif*/ 178bbe418f2SJia Liu 17990aa39a1SSergey Fedorov static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) 18090aa39a1SSergey Fedorov { 18190aa39a1SSergey Fedorov if (unlikely(dc->singlestep_enabled)) { 18290aa39a1SSergey Fedorov return false; 18390aa39a1SSergey Fedorov } 18490aa39a1SSergey Fedorov 18590aa39a1SSergey Fedorov #ifndef CONFIG_USER_ONLY 18690aa39a1SSergey Fedorov return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 18790aa39a1SSergey Fedorov #else 18890aa39a1SSergey Fedorov return true; 18990aa39a1SSergey Fedorov #endif 19090aa39a1SSergey Fedorov } 19190aa39a1SSergey Fedorov 192bbe418f2SJia Liu static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 193bbe418f2SJia Liu { 19490aa39a1SSergey Fedorov if (use_goto_tb(dc, dest)) { 195bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dest); 196bbe418f2SJia Liu tcg_gen_goto_tb(n); 19790aa39a1SSergey Fedorov tcg_gen_exit_tb((uintptr_t)dc->tb + n); 198bbe418f2SJia Liu } else { 199bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dest); 200bbe418f2SJia Liu if (dc->singlestep_enabled) { 201bbe418f2SJia Liu gen_exception(dc, EXCP_DEBUG); 202bbe418f2SJia Liu } 203bbe418f2SJia Liu tcg_gen_exit_tb(0); 204bbe418f2SJia Liu } 205bbe418f2SJia Liu } 206bbe418f2SJia Liu 2076da544a6SRichard Henderson static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0) 208bbe418f2SJia Liu { 2096da544a6SRichard Henderson target_ulong tmp_pc = dc->pc + n26 * 4; 210bbe418f2SJia Liu 211da1d7759SSebastian Macke switch (op0) { 212da1d7759SSebastian Macke case 0x00: /* l.j */ 213bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, tmp_pc); 214da1d7759SSebastian Macke break; 215da1d7759SSebastian Macke case 0x01: /* l.jal */ 216bbe418f2SJia Liu tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); 217bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, tmp_pc); 218da1d7759SSebastian Macke break; 219da1d7759SSebastian Macke case 0x03: /* l.bnf */ 220da1d7759SSebastian Macke case 0x04: /* l.bf */ 221da1d7759SSebastian Macke { 22242a268c2SRichard Henderson TCGLabel *lab = gen_new_label(); 223da1d7759SSebastian Macke TCGv sr_f = tcg_temp_new(); 224bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, dc->pc+8); 225da1d7759SSebastian Macke tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); 226da1d7759SSebastian Macke tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, 227da1d7759SSebastian Macke sr_f, SR_F, lab); 228bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, tmp_pc); 229bbe418f2SJia Liu gen_set_label(lab); 230da1d7759SSebastian Macke tcg_temp_free(sr_f); 231da1d7759SSebastian Macke } 232da1d7759SSebastian Macke break; 233da1d7759SSebastian Macke case 0x11: /* l.jr */ 234bbe418f2SJia Liu tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 235da1d7759SSebastian Macke break; 236da1d7759SSebastian Macke case 0x12: /* l.jalr */ 237bbe418f2SJia Liu tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); 238bbe418f2SJia Liu tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 239da1d7759SSebastian Macke break; 240da1d7759SSebastian Macke default: 241bbe418f2SJia Liu gen_illegal_exception(dc); 242da1d7759SSebastian Macke break; 243bbe418f2SJia Liu } 244bbe418f2SJia Liu 245bbe418f2SJia Liu dc->delayed_branch = 2; 246bbe418f2SJia Liu dc->tb_flags |= D_FLAG; 247bbe418f2SJia Liu gen_sync_flags(dc); 248bbe418f2SJia Liu } 249bbe418f2SJia Liu 2509ecaa27eSRichard Henderson static void gen_ove_cy(DisasContext *dc, TCGv cy) 2519ecaa27eSRichard Henderson { 2520c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 2539ecaa27eSRichard Henderson gen_helper_ove(cpu_env, cy); 2549ecaa27eSRichard Henderson } 2550c53d734SRichard Henderson } 2569ecaa27eSRichard Henderson 2579ecaa27eSRichard Henderson static void gen_ove_ov(DisasContext *dc, TCGv ov) 2589ecaa27eSRichard Henderson { 2590c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 2609ecaa27eSRichard Henderson gen_helper_ove(cpu_env, ov); 2619ecaa27eSRichard Henderson } 2620c53d734SRichard Henderson } 2639ecaa27eSRichard Henderson 2649ecaa27eSRichard Henderson static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov) 2659ecaa27eSRichard Henderson { 2660c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 2679ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 2689ecaa27eSRichard Henderson tcg_gen_or_tl(t0, cy, ov); 2699ecaa27eSRichard Henderson gen_helper_ove(cpu_env, t0); 2709ecaa27eSRichard Henderson tcg_temp_free(t0); 2719ecaa27eSRichard Henderson } 2720c53d734SRichard Henderson } 2739ecaa27eSRichard Henderson 2749ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2759ecaa27eSRichard Henderson { 2769ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 2779ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2789ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 2799ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 2809ecaa27eSRichard Henderson 2819ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0); 2829ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, srca, srcb); 2839ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 2849ecaa27eSRichard Henderson tcg_gen_andc_tl(sr_ov, t0, sr_ov); 2859ecaa27eSRichard Henderson tcg_temp_free(t0); 2869ecaa27eSRichard Henderson 2879ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2889ecaa27eSRichard Henderson tcg_temp_free(res); 2899ecaa27eSRichard Henderson 2909ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 2919ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 2929ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 2939ecaa27eSRichard Henderson 2949ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 2959ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 2969ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 2979ecaa27eSRichard Henderson } 2989ecaa27eSRichard Henderson 2999ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3009ecaa27eSRichard Henderson { 3019ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 3029ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 3039ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 3049ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 3059ecaa27eSRichard Henderson 3069ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY)); 3079ecaa27eSRichard Henderson tcg_gen_andi_tl(sr_cy, sr_cy, 1); 3089ecaa27eSRichard Henderson 3099ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0); 3109ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0); 3119ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, srca, srcb); 3129ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 3139ecaa27eSRichard Henderson tcg_gen_andc_tl(sr_ov, t0, sr_ov); 3149ecaa27eSRichard Henderson tcg_temp_free(t0); 3159ecaa27eSRichard Henderson 3169ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 3179ecaa27eSRichard Henderson tcg_temp_free(res); 3189ecaa27eSRichard Henderson 3199ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 3209ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 3219ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 3229ecaa27eSRichard Henderson 3239ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 3249ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 3259ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 3269ecaa27eSRichard Henderson } 3279ecaa27eSRichard Henderson 3289ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3299ecaa27eSRichard Henderson { 3309ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 3319ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 3329ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 3339ecaa27eSRichard Henderson 3349ecaa27eSRichard Henderson tcg_gen_sub_tl(res, srca, srcb); 3359ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_cy, srca, srcb); 3369ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, res, srcb); 3379ecaa27eSRichard Henderson tcg_gen_and_tl(sr_ov, sr_ov, sr_cy); 3389ecaa27eSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb); 3399ecaa27eSRichard Henderson 3409ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 3419ecaa27eSRichard Henderson tcg_temp_free(res); 3429ecaa27eSRichard Henderson 3439ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 3449ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 3459ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 3469ecaa27eSRichard Henderson 3479ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 3489ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 3499ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 3509ecaa27eSRichard Henderson } 3519ecaa27eSRichard Henderson 3529ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3539ecaa27eSRichard Henderson { 3549ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 3559ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 3569ecaa27eSRichard Henderson 3579ecaa27eSRichard Henderson tcg_gen_muls2_tl(dest, sr_ov, srca, srcb); 3589ecaa27eSRichard Henderson tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1); 3599ecaa27eSRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0); 3609ecaa27eSRichard Henderson tcg_temp_free(t0); 3619ecaa27eSRichard Henderson 3629ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 3639ecaa27eSRichard Henderson 3649ecaa27eSRichard Henderson gen_ove_ov(dc, sr_ov); 3659ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 3669ecaa27eSRichard Henderson } 3679ecaa27eSRichard Henderson 3689ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3699ecaa27eSRichard Henderson { 3709ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 3719ecaa27eSRichard Henderson 3729ecaa27eSRichard Henderson tcg_gen_muls2_tl(dest, sr_cy, srca, srcb); 3739ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0); 3749ecaa27eSRichard Henderson 3759ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 3769ecaa27eSRichard Henderson 3779ecaa27eSRichard Henderson gen_ove_cy(dc, sr_cy); 3789ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 3799ecaa27eSRichard Henderson } 3809ecaa27eSRichard Henderson 3819ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3829ecaa27eSRichard Henderson { 3839ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 3849ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 3859ecaa27eSRichard Henderson 3869ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0); 3879ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 3889ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 3899ecaa27eSRichard Henderson tcg_gen_or_tl(t0, srcb, sr_ov); 3909ecaa27eSRichard Henderson tcg_gen_div_tl(dest, srca, t0); 3919ecaa27eSRichard Henderson tcg_temp_free(t0); 3929ecaa27eSRichard Henderson 3939ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 3949ecaa27eSRichard Henderson 3959ecaa27eSRichard Henderson gen_ove_ov(dc, sr_ov); 3969ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 3979ecaa27eSRichard Henderson } 3989ecaa27eSRichard Henderson 3999ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 4009ecaa27eSRichard Henderson { 4019ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 4029ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 4039ecaa27eSRichard Henderson 4049ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0); 4059ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 4069ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 4079ecaa27eSRichard Henderson tcg_gen_or_tl(t0, srcb, sr_cy); 4089ecaa27eSRichard Henderson tcg_gen_divu_tl(dest, srca, t0); 4099ecaa27eSRichard Henderson tcg_temp_free(t0); 4109ecaa27eSRichard Henderson 4119ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 4129ecaa27eSRichard Henderson 4139ecaa27eSRichard Henderson gen_ove_cy(dc, sr_cy); 4149ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 4159ecaa27eSRichard Henderson } 416da1d7759SSebastian Macke 417930c3d00SRichard Henderson static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs) 418930c3d00SRichard Henderson { 419930c3d00SRichard Henderson TCGv ea = tcg_temp_new(); 420930c3d00SRichard Henderson 421930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 422930c3d00SRichard Henderson tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL); 423930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_addr, ea); 424930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_value, rd); 425930c3d00SRichard Henderson tcg_temp_free(ea); 426930c3d00SRichard Henderson } 427930c3d00SRichard Henderson 428930c3d00SRichard Henderson static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs) 429930c3d00SRichard Henderson { 430930c3d00SRichard Henderson TCGv ea, val; 431930c3d00SRichard Henderson TCGLabel *lab_fail, *lab_done; 432930c3d00SRichard Henderson 433930c3d00SRichard Henderson ea = tcg_temp_new(); 434930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 435930c3d00SRichard Henderson 436930c3d00SRichard Henderson lab_fail = gen_new_label(); 437930c3d00SRichard Henderson lab_done = gen_new_label(); 438930c3d00SRichard Henderson tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail); 439930c3d00SRichard Henderson tcg_temp_free(ea); 440930c3d00SRichard Henderson 441930c3d00SRichard Henderson val = tcg_temp_new(); 442930c3d00SRichard Henderson tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value, 443930c3d00SRichard Henderson rb, dc->mem_idx, MO_TEUL); 444930c3d00SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, val, cpu_lock_value); 445930c3d00SRichard Henderson tcg_temp_free(val); 446930c3d00SRichard Henderson 447930c3d00SRichard Henderson tcg_gen_br(lab_done); 448930c3d00SRichard Henderson 449930c3d00SRichard Henderson gen_set_label(lab_fail); 450930c3d00SRichard Henderson tcg_gen_movi_tl(env_btaken, 0); 451930c3d00SRichard Henderson 452930c3d00SRichard Henderson gen_set_label(lab_done); 453930c3d00SRichard Henderson tcg_gen_movi_tl(cpu_lock_addr, -1); 454930c3d00SRichard Henderson wb_SR_F(); 455930c3d00SRichard Henderson } 456930c3d00SRichard Henderson 457bbe418f2SJia Liu static void dec_calc(DisasContext *dc, uint32_t insn) 458bbe418f2SJia Liu { 459bbe418f2SJia Liu uint32_t op0, op1, op2; 460bbe418f2SJia Liu uint32_t ra, rb, rd; 461bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 462bbe418f2SJia Liu op1 = extract32(insn, 8, 2); 463bbe418f2SJia Liu op2 = extract32(insn, 6, 2); 464bbe418f2SJia Liu ra = extract32(insn, 16, 5); 465bbe418f2SJia Liu rb = extract32(insn, 11, 5); 466bbe418f2SJia Liu rd = extract32(insn, 21, 5); 467bbe418f2SJia Liu 468bbe418f2SJia Liu switch (op1) { 469*cf2ae442SRichard Henderson case 0: 470*cf2ae442SRichard Henderson switch (op0) { 471*cf2ae442SRichard Henderson case 0x0: /* l.add */ 472bbe418f2SJia Liu LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); 4739ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 474*cf2ae442SRichard Henderson return; 475bbe418f2SJia Liu 476*cf2ae442SRichard Henderson case 0x1: /* l.addc */ 477bbe418f2SJia Liu LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); 4789ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 479*cf2ae442SRichard Henderson return; 480bbe418f2SJia Liu 481*cf2ae442SRichard Henderson case 0x2: /* l.sub */ 482bbe418f2SJia Liu LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); 4839ecaa27eSRichard Henderson gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 484*cf2ae442SRichard Henderson return; 485bbe418f2SJia Liu 486*cf2ae442SRichard Henderson case 0x3: /* l.and */ 487bbe418f2SJia Liu LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); 488bbe418f2SJia Liu tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 489*cf2ae442SRichard Henderson return; 490bbe418f2SJia Liu 491*cf2ae442SRichard Henderson case 0x4: /* l.or */ 492bbe418f2SJia Liu LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); 493bbe418f2SJia Liu tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 494*cf2ae442SRichard Henderson return; 495bbe418f2SJia Liu 496*cf2ae442SRichard Henderson case 0x5: /* l.xor */ 497bbe418f2SJia Liu LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); 498bbe418f2SJia Liu tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 499*cf2ae442SRichard Henderson return; 500*cf2ae442SRichard Henderson 501*cf2ae442SRichard Henderson case 0x8: 502*cf2ae442SRichard Henderson switch (op2) { 503*cf2ae442SRichard Henderson case 0: /* l.sll */ 504*cf2ae442SRichard Henderson LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb); 505*cf2ae442SRichard Henderson tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 506*cf2ae442SRichard Henderson return; 507*cf2ae442SRichard Henderson case 1: /* l.srl */ 508*cf2ae442SRichard Henderson LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb); 509*cf2ae442SRichard Henderson tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 510*cf2ae442SRichard Henderson return; 511*cf2ae442SRichard Henderson case 2: /* l.sra */ 512*cf2ae442SRichard Henderson LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb); 513*cf2ae442SRichard Henderson tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 514*cf2ae442SRichard Henderson return; 515*cf2ae442SRichard Henderson case 3: /* l.ror */ 516*cf2ae442SRichard Henderson LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb); 517*cf2ae442SRichard Henderson tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 518*cf2ae442SRichard Henderson return; 519bbe418f2SJia Liu } 520bbe418f2SJia Liu break; 521bbe418f2SJia Liu 522*cf2ae442SRichard Henderson case 0xc: 523*cf2ae442SRichard Henderson switch (op2) { 524*cf2ae442SRichard Henderson case 0: /* l.exths */ 525*cf2ae442SRichard Henderson LOG_DIS("l.exths r%d, r%d\n", rd, ra); 526*cf2ae442SRichard Henderson tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]); 527*cf2ae442SRichard Henderson return; 528*cf2ae442SRichard Henderson case 1: /* l.extbs */ 529*cf2ae442SRichard Henderson LOG_DIS("l.extbs r%d, r%d\n", rd, ra); 530*cf2ae442SRichard Henderson tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]); 531*cf2ae442SRichard Henderson return; 532*cf2ae442SRichard Henderson case 2: /* l.exthz */ 533*cf2ae442SRichard Henderson LOG_DIS("l.exthz r%d, r%d\n", rd, ra); 534*cf2ae442SRichard Henderson tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]); 535*cf2ae442SRichard Henderson return; 536*cf2ae442SRichard Henderson case 3: /* l.extbz */ 537*cf2ae442SRichard Henderson LOG_DIS("l.extbz r%d, r%d\n", rd, ra); 538*cf2ae442SRichard Henderson tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]); 539*cf2ae442SRichard Henderson return; 540bbe418f2SJia Liu } 541bbe418f2SJia Liu break; 542bbe418f2SJia Liu 543*cf2ae442SRichard Henderson case 0xd: 544*cf2ae442SRichard Henderson switch (op2) { 545*cf2ae442SRichard Henderson case 0: /* l.extws */ 546*cf2ae442SRichard Henderson LOG_DIS("l.extws r%d, r%d\n", rd, ra); 547*cf2ae442SRichard Henderson tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]); 548*cf2ae442SRichard Henderson return; 549*cf2ae442SRichard Henderson case 1: /* l.extwz */ 550*cf2ae442SRichard Henderson LOG_DIS("l.extwz r%d, r%d\n", rd, ra); 551*cf2ae442SRichard Henderson tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]); 552*cf2ae442SRichard Henderson return; 553bbe418f2SJia Liu } 554bbe418f2SJia Liu break; 555bbe418f2SJia Liu 556*cf2ae442SRichard Henderson case 0xe: /* l.cmov */ 557bbe418f2SJia Liu LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); 558bbe418f2SJia Liu { 55942a268c2SRichard Henderson TCGLabel *lab = gen_new_label(); 560bbe418f2SJia Liu TCGv res = tcg_temp_local_new(); 561bbe418f2SJia Liu TCGv sr_f = tcg_temp_new(); 562bbe418f2SJia Liu tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); 563bbe418f2SJia Liu tcg_gen_mov_tl(res, cpu_R[rb]); 564bbe418f2SJia Liu tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab); 565bbe418f2SJia Liu tcg_gen_mov_tl(res, cpu_R[ra]); 566bbe418f2SJia Liu gen_set_label(lab); 567bbe418f2SJia Liu tcg_gen_mov_tl(cpu_R[rd], res); 568bbe418f2SJia Liu tcg_temp_free(sr_f); 569bbe418f2SJia Liu tcg_temp_free(res); 570bbe418f2SJia Liu } 571*cf2ae442SRichard Henderson return; 572bbe418f2SJia Liu 573*cf2ae442SRichard Henderson case 0xf: /* l.ff1 */ 574bbe418f2SJia Liu LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); 575555baef8SRichard Henderson tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1); 576555baef8SRichard Henderson tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1); 577*cf2ae442SRichard Henderson return; 578*cf2ae442SRichard Henderson } 579bbe418f2SJia Liu break; 580*cf2ae442SRichard Henderson 581*cf2ae442SRichard Henderson case 1: 582*cf2ae442SRichard Henderson switch (op0) { 583*cf2ae442SRichard Henderson case 0xf: /* l.fl1 */ 584bbe418f2SJia Liu LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); 585555baef8SRichard Henderson tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS); 586555baef8SRichard Henderson tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]); 587*cf2ae442SRichard Henderson return; 588bbe418f2SJia Liu } 589bbe418f2SJia Liu break; 590bbe418f2SJia Liu 591*cf2ae442SRichard Henderson case 2: 592bbe418f2SJia Liu break; 593bbe418f2SJia Liu 594*cf2ae442SRichard Henderson case 3: 595*cf2ae442SRichard Henderson switch (op0) { 596*cf2ae442SRichard Henderson case 0x6: /* l.mul */ 597*cf2ae442SRichard Henderson LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb); 598*cf2ae442SRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 599*cf2ae442SRichard Henderson return; 600*cf2ae442SRichard Henderson 601*cf2ae442SRichard Henderson case 0x9: /* l.div */ 602*cf2ae442SRichard Henderson LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb); 603*cf2ae442SRichard Henderson gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 604*cf2ae442SRichard Henderson return; 605*cf2ae442SRichard Henderson 606*cf2ae442SRichard Henderson case 0xa: /* l.divu */ 607*cf2ae442SRichard Henderson LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb); 608*cf2ae442SRichard Henderson gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 609*cf2ae442SRichard Henderson return; 610*cf2ae442SRichard Henderson 611*cf2ae442SRichard Henderson case 0xb: /* l.mulu */ 612*cf2ae442SRichard Henderson LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb); 613*cf2ae442SRichard Henderson gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 614*cf2ae442SRichard Henderson return; 615bbe418f2SJia Liu } 616bbe418f2SJia Liu break; 617bbe418f2SJia Liu } 618bbe418f2SJia Liu gen_illegal_exception(dc); 619bbe418f2SJia Liu } 620bbe418f2SJia Liu 621bbe418f2SJia Liu static void dec_misc(DisasContext *dc, uint32_t insn) 622bbe418f2SJia Liu { 623bbe418f2SJia Liu uint32_t op0, op1; 624bbe418f2SJia Liu uint32_t ra, rb, rd; 6256da544a6SRichard Henderson uint32_t L6, K5, K16, K5_11; 6266da544a6SRichard Henderson int32_t I16, I5_11, N26; 6275631e69cSRichard Henderson TCGMemOp mop; 6289ecaa27eSRichard Henderson TCGv t0; 6295631e69cSRichard Henderson 630bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 631bbe418f2SJia Liu op1 = extract32(insn, 24, 2); 632bbe418f2SJia Liu ra = extract32(insn, 16, 5); 633bbe418f2SJia Liu rb = extract32(insn, 11, 5); 634bbe418f2SJia Liu rd = extract32(insn, 21, 5); 635bbe418f2SJia Liu L6 = extract32(insn, 5, 6); 636bbe418f2SJia Liu K5 = extract32(insn, 0, 5); 6376da544a6SRichard Henderson K16 = extract32(insn, 0, 16); 6386da544a6SRichard Henderson I16 = (int16_t)K16; 6396da544a6SRichard Henderson N26 = sextract32(insn, 0, 26); 6406da544a6SRichard Henderson K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11); 6416da544a6SRichard Henderson I5_11 = (int16_t)K5_11; 642bbe418f2SJia Liu 643bbe418f2SJia Liu switch (op0) { 644bbe418f2SJia Liu case 0x00: /* l.j */ 645bbe418f2SJia Liu LOG_DIS("l.j %d\n", N26); 646bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 647bbe418f2SJia Liu break; 648bbe418f2SJia Liu 649bbe418f2SJia Liu case 0x01: /* l.jal */ 650bbe418f2SJia Liu LOG_DIS("l.jal %d\n", N26); 651bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 652bbe418f2SJia Liu break; 653bbe418f2SJia Liu 654bbe418f2SJia Liu case 0x03: /* l.bnf */ 655bbe418f2SJia Liu LOG_DIS("l.bnf %d\n", N26); 656bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 657bbe418f2SJia Liu break; 658bbe418f2SJia Liu 659bbe418f2SJia Liu case 0x04: /* l.bf */ 660bbe418f2SJia Liu LOG_DIS("l.bf %d\n", N26); 661bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 662bbe418f2SJia Liu break; 663bbe418f2SJia Liu 664bbe418f2SJia Liu case 0x05: 665bbe418f2SJia Liu switch (op1) { 666bbe418f2SJia Liu case 0x01: /* l.nop */ 667bbe418f2SJia Liu LOG_DIS("l.nop %d\n", I16); 668bbe418f2SJia Liu break; 669bbe418f2SJia Liu 670bbe418f2SJia Liu default: 671bbe418f2SJia Liu gen_illegal_exception(dc); 672bbe418f2SJia Liu break; 673bbe418f2SJia Liu } 674bbe418f2SJia Liu break; 675bbe418f2SJia Liu 676bbe418f2SJia Liu case 0x11: /* l.jr */ 677bbe418f2SJia Liu LOG_DIS("l.jr r%d\n", rb); 678bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 679bbe418f2SJia Liu break; 680bbe418f2SJia Liu 681bbe418f2SJia Liu case 0x12: /* l.jalr */ 682bbe418f2SJia Liu LOG_DIS("l.jalr r%d\n", rb); 683bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 684bbe418f2SJia Liu break; 685bbe418f2SJia Liu 686bbe418f2SJia Liu case 0x13: /* l.maci */ 6876da544a6SRichard Henderson LOG_DIS("l.maci r%d, %d\n", ra, I16); 688bbe418f2SJia Liu { 689bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 690bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 691bbe418f2SJia Liu TCGv_i32 dst = tcg_temp_new_i32(); 6926da544a6SRichard Henderson TCGv ttmp = tcg_const_tl(I16); 693bbe418f2SJia Liu tcg_gen_mul_tl(dst, cpu_R[ra], ttmp); 694bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, dst); 695bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 696bbe418f2SJia Liu tcg_gen_add_i64(t2, t2, t1); 697ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 698bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 699ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 700bbe418f2SJia Liu tcg_temp_free_i32(dst); 701bbe418f2SJia Liu tcg_temp_free(ttmp); 702bbe418f2SJia Liu tcg_temp_free_i64(t1); 703bbe418f2SJia Liu tcg_temp_free_i64(t2); 704bbe418f2SJia Liu } 705bbe418f2SJia Liu break; 706bbe418f2SJia Liu 707bbe418f2SJia Liu case 0x09: /* l.rfe */ 708bbe418f2SJia Liu LOG_DIS("l.rfe\n"); 709bbe418f2SJia Liu { 710bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 711bbe418f2SJia Liu return; 712bbe418f2SJia Liu #else 713bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 714bbe418f2SJia Liu gen_illegal_exception(dc); 715bbe418f2SJia Liu return; 716bbe418f2SJia Liu } 717bbe418f2SJia Liu gen_helper_rfe(cpu_env); 718bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 719bbe418f2SJia Liu #endif 720bbe418f2SJia Liu } 721bbe418f2SJia Liu break; 722bbe418f2SJia Liu 723930c3d00SRichard Henderson case 0x1b: /* l.lwa */ 724930c3d00SRichard Henderson LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16); 725930c3d00SRichard Henderson gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16); 726930c3d00SRichard Henderson break; 727930c3d00SRichard Henderson 728bbe418f2SJia Liu case 0x1c: /* l.cust1 */ 729bbe418f2SJia Liu LOG_DIS("l.cust1\n"); 730bbe418f2SJia Liu break; 731bbe418f2SJia Liu 732bbe418f2SJia Liu case 0x1d: /* l.cust2 */ 733bbe418f2SJia Liu LOG_DIS("l.cust2\n"); 734bbe418f2SJia Liu break; 735bbe418f2SJia Liu 736bbe418f2SJia Liu case 0x1e: /* l.cust3 */ 737bbe418f2SJia Liu LOG_DIS("l.cust3\n"); 738bbe418f2SJia Liu break; 739bbe418f2SJia Liu 740bbe418f2SJia Liu case 0x1f: /* l.cust4 */ 741bbe418f2SJia Liu LOG_DIS("l.cust4\n"); 742bbe418f2SJia Liu break; 743bbe418f2SJia Liu 744bbe418f2SJia Liu case 0x3c: /* l.cust5 */ 745bbe418f2SJia Liu LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5); 746bbe418f2SJia Liu break; 747bbe418f2SJia Liu 748bbe418f2SJia Liu case 0x3d: /* l.cust6 */ 749bbe418f2SJia Liu LOG_DIS("l.cust6\n"); 750bbe418f2SJia Liu break; 751bbe418f2SJia Liu 752bbe418f2SJia Liu case 0x3e: /* l.cust7 */ 753bbe418f2SJia Liu LOG_DIS("l.cust7\n"); 754bbe418f2SJia Liu break; 755bbe418f2SJia Liu 756bbe418f2SJia Liu case 0x3f: /* l.cust8 */ 757bbe418f2SJia Liu LOG_DIS("l.cust8\n"); 758bbe418f2SJia Liu break; 759bbe418f2SJia Liu 760bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 761bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 762bbe418f2SJia Liu case 0x20: l.ld 763bbe418f2SJia Liu LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); 764bbe418f2SJia Liu check_ob64s(dc); 7655631e69cSRichard Henderson mop = MO_TEQ; 7665631e69cSRichard Henderson goto do_load; 767bbe418f2SJia Liu #endif*/ 768bbe418f2SJia Liu 769bbe418f2SJia Liu case 0x21: /* l.lwz */ 770bbe418f2SJia Liu LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); 7715631e69cSRichard Henderson mop = MO_TEUL; 7725631e69cSRichard Henderson goto do_load; 773bbe418f2SJia Liu 774bbe418f2SJia Liu case 0x22: /* l.lws */ 775bbe418f2SJia Liu LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); 7765631e69cSRichard Henderson mop = MO_TESL; 7775631e69cSRichard Henderson goto do_load; 778bbe418f2SJia Liu 779bbe418f2SJia Liu case 0x23: /* l.lbz */ 780bbe418f2SJia Liu LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); 7815631e69cSRichard Henderson mop = MO_UB; 7825631e69cSRichard Henderson goto do_load; 783bbe418f2SJia Liu 784bbe418f2SJia Liu case 0x24: /* l.lbs */ 785bbe418f2SJia Liu LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); 7865631e69cSRichard Henderson mop = MO_SB; 7875631e69cSRichard Henderson goto do_load; 788bbe418f2SJia Liu 789bbe418f2SJia Liu case 0x25: /* l.lhz */ 790bbe418f2SJia Liu LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); 7915631e69cSRichard Henderson mop = MO_TEUW; 7925631e69cSRichard Henderson goto do_load; 793bbe418f2SJia Liu 794bbe418f2SJia Liu case 0x26: /* l.lhs */ 795bbe418f2SJia Liu LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); 7965631e69cSRichard Henderson mop = MO_TESW; 7975631e69cSRichard Henderson goto do_load; 7985631e69cSRichard Henderson 7995631e69cSRichard Henderson do_load: 800bbe418f2SJia Liu { 801bbe418f2SJia Liu TCGv t0 = tcg_temp_new(); 8026da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I16); 8035631e69cSRichard Henderson tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); 804bbe418f2SJia Liu tcg_temp_free(t0); 805bbe418f2SJia Liu } 806bbe418f2SJia Liu break; 807bbe418f2SJia Liu 808bbe418f2SJia Liu case 0x27: /* l.addi */ 809bbe418f2SJia Liu LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); 8109ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 8119ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], t0); 8129ecaa27eSRichard Henderson tcg_temp_free(t0); 813bbe418f2SJia Liu break; 814bbe418f2SJia Liu 815bbe418f2SJia Liu case 0x28: /* l.addic */ 816bbe418f2SJia Liu LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16); 8179ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 8189ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], t0); 8199ecaa27eSRichard Henderson tcg_temp_free(t0); 820bbe418f2SJia Liu break; 821bbe418f2SJia Liu 822bbe418f2SJia Liu case 0x29: /* l.andi */ 8236da544a6SRichard Henderson LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16); 8246da544a6SRichard Henderson tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16); 825bbe418f2SJia Liu break; 826bbe418f2SJia Liu 827bbe418f2SJia Liu case 0x2a: /* l.ori */ 8286da544a6SRichard Henderson LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16); 8296da544a6SRichard Henderson tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16); 830bbe418f2SJia Liu break; 831bbe418f2SJia Liu 832bbe418f2SJia Liu case 0x2b: /* l.xori */ 833bbe418f2SJia Liu LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16); 8346da544a6SRichard Henderson tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16); 835bbe418f2SJia Liu break; 836bbe418f2SJia Liu 837bbe418f2SJia Liu case 0x2c: /* l.muli */ 838bbe418f2SJia Liu LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16); 8399ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 8409ecaa27eSRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], t0); 8419ecaa27eSRichard Henderson tcg_temp_free(t0); 842bbe418f2SJia Liu break; 843bbe418f2SJia Liu 844bbe418f2SJia Liu case 0x2d: /* l.mfspr */ 8456da544a6SRichard Henderson LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16); 8464dd044c6SJia Liu { 8474dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 8484dd044c6SJia Liu return; 8494dd044c6SJia Liu #else 8506da544a6SRichard Henderson TCGv_i32 ti = tcg_const_i32(K16); 8514dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 8524dd044c6SJia Liu gen_illegal_exception(dc); 8534dd044c6SJia Liu return; 8544dd044c6SJia Liu } 8554dd044c6SJia Liu gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); 8564dd044c6SJia Liu tcg_temp_free_i32(ti); 8574dd044c6SJia Liu #endif 8584dd044c6SJia Liu } 859bbe418f2SJia Liu break; 860bbe418f2SJia Liu 861bbe418f2SJia Liu case 0x30: /* l.mtspr */ 8626da544a6SRichard Henderson LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11); 8634dd044c6SJia Liu { 8644dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 8654dd044c6SJia Liu return; 8664dd044c6SJia Liu #else 8676da544a6SRichard Henderson TCGv_i32 im = tcg_const_i32(K5_11); 8684dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 8694dd044c6SJia Liu gen_illegal_exception(dc); 8704dd044c6SJia Liu return; 8714dd044c6SJia Liu } 8724dd044c6SJia Liu gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); 8734dd044c6SJia Liu tcg_temp_free_i32(im); 8744dd044c6SJia Liu #endif 8754dd044c6SJia Liu } 876bbe418f2SJia Liu break; 877bbe418f2SJia Liu 878930c3d00SRichard Henderson case 0x33: /* l.swa */ 8796da544a6SRichard Henderson LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11); 8806da544a6SRichard Henderson gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11); 881930c3d00SRichard Henderson break; 882930c3d00SRichard Henderson 883bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 884bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 885bbe418f2SJia Liu case 0x34: l.sd 8866da544a6SRichard Henderson LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11); 887bbe418f2SJia Liu check_ob64s(dc); 8885631e69cSRichard Henderson mop = MO_TEQ; 8895631e69cSRichard Henderson goto do_store; 890bbe418f2SJia Liu #endif*/ 891bbe418f2SJia Liu 892bbe418f2SJia Liu case 0x35: /* l.sw */ 8936da544a6SRichard Henderson LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11); 8945631e69cSRichard Henderson mop = MO_TEUL; 8955631e69cSRichard Henderson goto do_store; 896bbe418f2SJia Liu 897bbe418f2SJia Liu case 0x36: /* l.sb */ 8986da544a6SRichard Henderson LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11); 8995631e69cSRichard Henderson mop = MO_UB; 9005631e69cSRichard Henderson goto do_store; 901bbe418f2SJia Liu 902bbe418f2SJia Liu case 0x37: /* l.sh */ 9036da544a6SRichard Henderson LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11); 9045631e69cSRichard Henderson mop = MO_TEUW; 9055631e69cSRichard Henderson goto do_store; 9065631e69cSRichard Henderson 9075631e69cSRichard Henderson do_store: 908bbe418f2SJia Liu { 909bbe418f2SJia Liu TCGv t0 = tcg_temp_new(); 9106da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I5_11); 9115631e69cSRichard Henderson tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); 912bbe418f2SJia Liu tcg_temp_free(t0); 913bbe418f2SJia Liu } 914bbe418f2SJia Liu break; 915bbe418f2SJia Liu 916bbe418f2SJia Liu default: 917bbe418f2SJia Liu gen_illegal_exception(dc); 918bbe418f2SJia Liu break; 919bbe418f2SJia Liu } 920bbe418f2SJia Liu } 921bbe418f2SJia Liu 922bbe418f2SJia Liu static void dec_mac(DisasContext *dc, uint32_t insn) 923bbe418f2SJia Liu { 924bbe418f2SJia Liu uint32_t op0; 925bbe418f2SJia Liu uint32_t ra, rb; 926bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 927bbe418f2SJia Liu ra = extract32(insn, 16, 5); 928bbe418f2SJia Liu rb = extract32(insn, 11, 5); 929bbe418f2SJia Liu 930bbe418f2SJia Liu switch (op0) { 931bbe418f2SJia Liu case 0x0001: /* l.mac */ 932bbe418f2SJia Liu LOG_DIS("l.mac r%d, r%d\n", ra, rb); 933bbe418f2SJia Liu { 934bbe418f2SJia Liu TCGv_i32 t0 = tcg_temp_new_i32(); 935bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 936bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 937bbe418f2SJia Liu tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 938bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, t0); 939bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 940bbe418f2SJia Liu tcg_gen_add_i64(t2, t2, t1); 941ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 942bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 943ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 944bbe418f2SJia Liu tcg_temp_free_i32(t0); 945bbe418f2SJia Liu tcg_temp_free_i64(t1); 946bbe418f2SJia Liu tcg_temp_free_i64(t2); 947bbe418f2SJia Liu } 948bbe418f2SJia Liu break; 949bbe418f2SJia Liu 950bbe418f2SJia Liu case 0x0002: /* l.msb */ 951bbe418f2SJia Liu LOG_DIS("l.msb r%d, r%d\n", ra, rb); 952bbe418f2SJia Liu { 953bbe418f2SJia Liu TCGv_i32 t0 = tcg_temp_new_i32(); 954bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 955bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 956bbe418f2SJia Liu tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 957bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, t0); 958bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 959bbe418f2SJia Liu tcg_gen_sub_i64(t2, t2, t1); 960ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 961bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 962ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 963bbe418f2SJia Liu tcg_temp_free_i32(t0); 964bbe418f2SJia Liu tcg_temp_free_i64(t1); 965bbe418f2SJia Liu tcg_temp_free_i64(t2); 966bbe418f2SJia Liu } 967bbe418f2SJia Liu break; 968bbe418f2SJia Liu 969bbe418f2SJia Liu default: 970bbe418f2SJia Liu gen_illegal_exception(dc); 971bbe418f2SJia Liu break; 972bbe418f2SJia Liu } 973bbe418f2SJia Liu } 974bbe418f2SJia Liu 975bbe418f2SJia Liu static void dec_logic(DisasContext *dc, uint32_t insn) 976bbe418f2SJia Liu { 977bbe418f2SJia Liu uint32_t op0; 9786da544a6SRichard Henderson uint32_t rd, ra, L6, S6; 979bbe418f2SJia Liu op0 = extract32(insn, 6, 2); 980bbe418f2SJia Liu rd = extract32(insn, 21, 5); 981bbe418f2SJia Liu ra = extract32(insn, 16, 5); 982bbe418f2SJia Liu L6 = extract32(insn, 0, 6); 9836da544a6SRichard Henderson S6 = L6 & (TARGET_LONG_BITS - 1); 984bbe418f2SJia Liu 985bbe418f2SJia Liu switch (op0) { 986bbe418f2SJia Liu case 0x00: /* l.slli */ 987bbe418f2SJia Liu LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6); 9886da544a6SRichard Henderson tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6); 989bbe418f2SJia Liu break; 990bbe418f2SJia Liu 991bbe418f2SJia Liu case 0x01: /* l.srli */ 992bbe418f2SJia Liu LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6); 9936da544a6SRichard Henderson tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6); 994bbe418f2SJia Liu break; 995bbe418f2SJia Liu 996bbe418f2SJia Liu case 0x02: /* l.srai */ 997bbe418f2SJia Liu LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6); 9986da544a6SRichard Henderson tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6); 9996da544a6SRichard Henderson break; 1000bbe418f2SJia Liu 1001bbe418f2SJia Liu case 0x03: /* l.rori */ 1002bbe418f2SJia Liu LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6); 10036da544a6SRichard Henderson tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6); 1004bbe418f2SJia Liu break; 1005bbe418f2SJia Liu 1006bbe418f2SJia Liu default: 1007bbe418f2SJia Liu gen_illegal_exception(dc); 1008bbe418f2SJia Liu break; 1009bbe418f2SJia Liu } 1010bbe418f2SJia Liu } 1011bbe418f2SJia Liu 1012bbe418f2SJia Liu static void dec_M(DisasContext *dc, uint32_t insn) 1013bbe418f2SJia Liu { 1014bbe418f2SJia Liu uint32_t op0; 1015bbe418f2SJia Liu uint32_t rd; 1016bbe418f2SJia Liu uint32_t K16; 1017bbe418f2SJia Liu op0 = extract32(insn, 16, 1); 1018bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1019bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1020bbe418f2SJia Liu 1021bbe418f2SJia Liu switch (op0) { 1022bbe418f2SJia Liu case 0x0: /* l.movhi */ 1023bbe418f2SJia Liu LOG_DIS("l.movhi r%d, %d\n", rd, K16); 1024bbe418f2SJia Liu tcg_gen_movi_tl(cpu_R[rd], (K16 << 16)); 1025bbe418f2SJia Liu break; 1026bbe418f2SJia Liu 1027bbe418f2SJia Liu case 0x1: /* l.macrc */ 1028bbe418f2SJia Liu LOG_DIS("l.macrc r%d\n", rd); 1029bbe418f2SJia Liu tcg_gen_mov_tl(cpu_R[rd], maclo); 1030bbe418f2SJia Liu tcg_gen_movi_tl(maclo, 0x0); 1031bbe418f2SJia Liu tcg_gen_movi_tl(machi, 0x0); 1032bbe418f2SJia Liu break; 1033bbe418f2SJia Liu 1034bbe418f2SJia Liu default: 1035bbe418f2SJia Liu gen_illegal_exception(dc); 1036bbe418f2SJia Liu break; 1037bbe418f2SJia Liu } 1038bbe418f2SJia Liu } 1039bbe418f2SJia Liu 1040bbe418f2SJia Liu static void dec_comp(DisasContext *dc, uint32_t insn) 1041bbe418f2SJia Liu { 1042bbe418f2SJia Liu uint32_t op0; 1043bbe418f2SJia Liu uint32_t ra, rb; 1044bbe418f2SJia Liu 1045bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1046bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1047bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1048bbe418f2SJia Liu 1049bbe418f2SJia Liu tcg_gen_movi_i32(env_btaken, 0x0); 1050bbe418f2SJia Liu /* unsigned integers */ 1051bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); 1052bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); 1053bbe418f2SJia Liu 1054bbe418f2SJia Liu switch (op0) { 1055bbe418f2SJia Liu case 0x0: /* l.sfeq */ 1056bbe418f2SJia Liu LOG_DIS("l.sfeq r%d, r%d\n", ra, rb); 1057bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]); 1058bbe418f2SJia Liu break; 1059bbe418f2SJia Liu 1060bbe418f2SJia Liu case 0x1: /* l.sfne */ 1061bbe418f2SJia Liu LOG_DIS("l.sfne r%d, r%d\n", ra, rb); 1062bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]); 1063bbe418f2SJia Liu break; 1064bbe418f2SJia Liu 1065bbe418f2SJia Liu case 0x2: /* l.sfgtu */ 1066bbe418f2SJia Liu LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb); 1067bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1068bbe418f2SJia Liu break; 1069bbe418f2SJia Liu 1070bbe418f2SJia Liu case 0x3: /* l.sfgeu */ 1071bbe418f2SJia Liu LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb); 1072bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1073bbe418f2SJia Liu break; 1074bbe418f2SJia Liu 1075bbe418f2SJia Liu case 0x4: /* l.sfltu */ 1076bbe418f2SJia Liu LOG_DIS("l.sfltu r%d, r%d\n", ra, rb); 1077bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1078bbe418f2SJia Liu break; 1079bbe418f2SJia Liu 1080bbe418f2SJia Liu case 0x5: /* l.sfleu */ 1081bbe418f2SJia Liu LOG_DIS("l.sfleu r%d, r%d\n", ra, rb); 1082bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1083bbe418f2SJia Liu break; 1084bbe418f2SJia Liu 1085bbe418f2SJia Liu case 0xa: /* l.sfgts */ 1086bbe418f2SJia Liu LOG_DIS("l.sfgts r%d, r%d\n", ra, rb); 1087bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]); 1088bbe418f2SJia Liu break; 1089bbe418f2SJia Liu 1090bbe418f2SJia Liu case 0xb: /* l.sfges */ 1091bbe418f2SJia Liu LOG_DIS("l.sfges r%d, r%d\n", ra, rb); 1092bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]); 1093bbe418f2SJia Liu break; 1094bbe418f2SJia Liu 1095bbe418f2SJia Liu case 0xc: /* l.sflts */ 1096bbe418f2SJia Liu LOG_DIS("l.sflts r%d, r%d\n", ra, rb); 1097bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]); 1098bbe418f2SJia Liu break; 1099bbe418f2SJia Liu 1100bbe418f2SJia Liu case 0xd: /* l.sfles */ 1101bbe418f2SJia Liu LOG_DIS("l.sfles r%d, r%d\n", ra, rb); 1102bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]); 1103bbe418f2SJia Liu break; 1104bbe418f2SJia Liu 1105bbe418f2SJia Liu default: 1106bbe418f2SJia Liu gen_illegal_exception(dc); 1107bbe418f2SJia Liu break; 1108bbe418f2SJia Liu } 1109bbe418f2SJia Liu wb_SR_F(); 1110bbe418f2SJia Liu } 1111bbe418f2SJia Liu 1112bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn) 1113bbe418f2SJia Liu { 11146da544a6SRichard Henderson uint32_t op0, ra; 11156da544a6SRichard Henderson int32_t I16; 1116bbe418f2SJia Liu 1117bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1118bbe418f2SJia Liu ra = extract32(insn, 16, 5); 11196da544a6SRichard Henderson I16 = sextract32(insn, 0, 16); 1120bbe418f2SJia Liu 1121bbe418f2SJia Liu tcg_gen_movi_i32(env_btaken, 0x0); 1122bbe418f2SJia Liu 1123bbe418f2SJia Liu switch (op0) { 1124bbe418f2SJia Liu case 0x0: /* l.sfeqi */ 1125bbe418f2SJia Liu LOG_DIS("l.sfeqi r%d, %d\n", ra, I16); 1126bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16); 1127bbe418f2SJia Liu break; 1128bbe418f2SJia Liu 1129bbe418f2SJia Liu case 0x1: /* l.sfnei */ 1130bbe418f2SJia Liu LOG_DIS("l.sfnei r%d, %d\n", ra, I16); 1131bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16); 1132bbe418f2SJia Liu break; 1133bbe418f2SJia Liu 1134bbe418f2SJia Liu case 0x2: /* l.sfgtui */ 1135bbe418f2SJia Liu LOG_DIS("l.sfgtui r%d, %d\n", ra, I16); 1136bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16); 1137bbe418f2SJia Liu break; 1138bbe418f2SJia Liu 1139bbe418f2SJia Liu case 0x3: /* l.sfgeui */ 1140bbe418f2SJia Liu LOG_DIS("l.sfgeui r%d, %d\n", ra, I16); 1141bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16); 1142bbe418f2SJia Liu break; 1143bbe418f2SJia Liu 1144bbe418f2SJia Liu case 0x4: /* l.sfltui */ 1145bbe418f2SJia Liu LOG_DIS("l.sfltui r%d, %d\n", ra, I16); 1146bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16); 1147bbe418f2SJia Liu break; 1148bbe418f2SJia Liu 1149bbe418f2SJia Liu case 0x5: /* l.sfleui */ 1150bbe418f2SJia Liu LOG_DIS("l.sfleui r%d, %d\n", ra, I16); 1151bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16); 1152bbe418f2SJia Liu break; 1153bbe418f2SJia Liu 1154bbe418f2SJia Liu case 0xa: /* l.sfgtsi */ 1155bbe418f2SJia Liu LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16); 1156bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16); 1157bbe418f2SJia Liu break; 1158bbe418f2SJia Liu 1159bbe418f2SJia Liu case 0xb: /* l.sfgesi */ 1160bbe418f2SJia Liu LOG_DIS("l.sfgesi r%d, %d\n", ra, I16); 1161bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16); 1162bbe418f2SJia Liu break; 1163bbe418f2SJia Liu 1164bbe418f2SJia Liu case 0xc: /* l.sfltsi */ 1165bbe418f2SJia Liu LOG_DIS("l.sfltsi r%d, %d\n", ra, I16); 1166bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16); 1167bbe418f2SJia Liu break; 1168bbe418f2SJia Liu 1169bbe418f2SJia Liu case 0xd: /* l.sflesi */ 1170bbe418f2SJia Liu LOG_DIS("l.sflesi r%d, %d\n", ra, I16); 1171bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16); 1172bbe418f2SJia Liu break; 1173bbe418f2SJia Liu 1174bbe418f2SJia Liu default: 1175bbe418f2SJia Liu gen_illegal_exception(dc); 1176bbe418f2SJia Liu break; 1177bbe418f2SJia Liu } 1178bbe418f2SJia Liu wb_SR_F(); 1179bbe418f2SJia Liu } 1180bbe418f2SJia Liu 1181bbe418f2SJia Liu static void dec_sys(DisasContext *dc, uint32_t insn) 1182bbe418f2SJia Liu { 1183bbe418f2SJia Liu uint32_t op0; 1184bbe418f2SJia Liu uint32_t K16; 1185111ece51SRichard Henderson 11863d59b680SDavid Morrison op0 = extract32(insn, 16, 10); 1187bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1188bbe418f2SJia Liu 1189bbe418f2SJia Liu switch (op0) { 1190bbe418f2SJia Liu case 0x000: /* l.sys */ 1191bbe418f2SJia Liu LOG_DIS("l.sys %d\n", K16); 1192bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1193bbe418f2SJia Liu gen_exception(dc, EXCP_SYSCALL); 1194bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 1195bbe418f2SJia Liu break; 1196bbe418f2SJia Liu 1197bbe418f2SJia Liu case 0x100: /* l.trap */ 1198bbe418f2SJia Liu LOG_DIS("l.trap %d\n", K16); 1199bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1200bbe418f2SJia Liu return; 1201bbe418f2SJia Liu #else 1202bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1203bbe418f2SJia Liu gen_illegal_exception(dc); 1204bbe418f2SJia Liu return; 1205bbe418f2SJia Liu } 1206bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1207bbe418f2SJia Liu gen_exception(dc, EXCP_TRAP); 1208bbe418f2SJia Liu #endif 1209bbe418f2SJia Liu break; 1210bbe418f2SJia Liu 1211bbe418f2SJia Liu case 0x300: /* l.csync */ 1212bbe418f2SJia Liu LOG_DIS("l.csync\n"); 1213bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1214bbe418f2SJia Liu return; 1215bbe418f2SJia Liu #else 1216bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1217bbe418f2SJia Liu gen_illegal_exception(dc); 1218bbe418f2SJia Liu return; 1219bbe418f2SJia Liu } 1220bbe418f2SJia Liu #endif 1221bbe418f2SJia Liu break; 1222bbe418f2SJia Liu 1223bbe418f2SJia Liu case 0x200: /* l.msync */ 1224bbe418f2SJia Liu LOG_DIS("l.msync\n"); 1225bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1226bbe418f2SJia Liu return; 1227bbe418f2SJia Liu #else 1228bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1229bbe418f2SJia Liu gen_illegal_exception(dc); 1230bbe418f2SJia Liu return; 1231bbe418f2SJia Liu } 1232bbe418f2SJia Liu #endif 1233bbe418f2SJia Liu break; 1234bbe418f2SJia Liu 1235bbe418f2SJia Liu case 0x270: /* l.psync */ 1236bbe418f2SJia Liu LOG_DIS("l.psync\n"); 1237bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1238bbe418f2SJia Liu return; 1239bbe418f2SJia Liu #else 1240bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1241bbe418f2SJia Liu gen_illegal_exception(dc); 1242bbe418f2SJia Liu return; 1243bbe418f2SJia Liu } 1244bbe418f2SJia Liu #endif 1245bbe418f2SJia Liu break; 1246bbe418f2SJia Liu 1247bbe418f2SJia Liu default: 1248bbe418f2SJia Liu gen_illegal_exception(dc); 1249bbe418f2SJia Liu break; 1250bbe418f2SJia Liu } 1251bbe418f2SJia Liu } 1252bbe418f2SJia Liu 1253bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn) 1254bbe418f2SJia Liu { 1255bbe418f2SJia Liu uint32_t op0; 1256bbe418f2SJia Liu uint32_t ra, rb, rd; 1257bbe418f2SJia Liu op0 = extract32(insn, 0, 8); 1258bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1259bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1260bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1261bbe418f2SJia Liu 1262bbe418f2SJia Liu switch (op0) { 1263bbe418f2SJia Liu case 0x00: /* lf.add.s */ 1264bbe418f2SJia Liu LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb); 1265bbe418f2SJia Liu gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1266bbe418f2SJia Liu break; 1267bbe418f2SJia Liu 1268bbe418f2SJia Liu case 0x01: /* lf.sub.s */ 1269bbe418f2SJia Liu LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb); 1270bbe418f2SJia Liu gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1271bbe418f2SJia Liu break; 1272bbe418f2SJia Liu 1273bbe418f2SJia Liu 1274bbe418f2SJia Liu case 0x02: /* lf.mul.s */ 1275bbe418f2SJia Liu LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb); 1276bbe418f2SJia Liu if (ra != 0 && rb != 0) { 1277bbe418f2SJia Liu gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1278bbe418f2SJia Liu } else { 1279bbe418f2SJia Liu tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1280bbe418f2SJia Liu tcg_gen_movi_i32(cpu_R[rd], 0x0); 1281bbe418f2SJia Liu } 1282bbe418f2SJia Liu break; 1283bbe418f2SJia Liu 1284bbe418f2SJia Liu case 0x03: /* lf.div.s */ 1285bbe418f2SJia Liu LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb); 1286bbe418f2SJia Liu gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1287bbe418f2SJia Liu break; 1288bbe418f2SJia Liu 1289bbe418f2SJia Liu case 0x04: /* lf.itof.s */ 1290bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1291bbe418f2SJia Liu gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]); 1292bbe418f2SJia Liu break; 1293bbe418f2SJia Liu 1294bbe418f2SJia Liu case 0x05: /* lf.ftoi.s */ 1295bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1296bbe418f2SJia Liu gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]); 1297bbe418f2SJia Liu break; 1298bbe418f2SJia Liu 1299bbe418f2SJia Liu case 0x06: /* lf.rem.s */ 1300bbe418f2SJia Liu LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb); 1301bbe418f2SJia Liu gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1302bbe418f2SJia Liu break; 1303bbe418f2SJia Liu 1304bbe418f2SJia Liu case 0x07: /* lf.madd.s */ 1305bbe418f2SJia Liu LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb); 1306bbe418f2SJia Liu gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1307bbe418f2SJia Liu break; 1308bbe418f2SJia Liu 1309bbe418f2SJia Liu case 0x08: /* lf.sfeq.s */ 1310bbe418f2SJia Liu LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb); 1311bbe418f2SJia Liu gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1312bbe418f2SJia Liu break; 1313bbe418f2SJia Liu 1314bbe418f2SJia Liu case 0x09: /* lf.sfne.s */ 1315bbe418f2SJia Liu LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb); 1316bbe418f2SJia Liu gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1317bbe418f2SJia Liu break; 1318bbe418f2SJia Liu 1319bbe418f2SJia Liu case 0x0a: /* lf.sfgt.s */ 1320bbe418f2SJia Liu LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb); 1321bbe418f2SJia Liu gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1322bbe418f2SJia Liu break; 1323bbe418f2SJia Liu 1324bbe418f2SJia Liu case 0x0b: /* lf.sfge.s */ 1325bbe418f2SJia Liu LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb); 1326bbe418f2SJia Liu gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1327bbe418f2SJia Liu break; 1328bbe418f2SJia Liu 1329bbe418f2SJia Liu case 0x0c: /* lf.sflt.s */ 1330bbe418f2SJia Liu LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb); 1331bbe418f2SJia Liu gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1332bbe418f2SJia Liu break; 1333bbe418f2SJia Liu 1334bbe418f2SJia Liu case 0x0d: /* lf.sfle.s */ 1335bbe418f2SJia Liu LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb); 1336bbe418f2SJia Liu gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1337bbe418f2SJia Liu break; 1338bbe418f2SJia Liu 1339bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 1340bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 1341bbe418f2SJia Liu case 0x10: lf.add.d 1342bbe418f2SJia Liu LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb); 1343bbe418f2SJia Liu check_of64s(dc); 1344bbe418f2SJia Liu gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1345bbe418f2SJia Liu break; 1346bbe418f2SJia Liu 1347bbe418f2SJia Liu case 0x11: lf.sub.d 1348bbe418f2SJia Liu LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb); 1349bbe418f2SJia Liu check_of64s(dc); 1350bbe418f2SJia Liu gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1351bbe418f2SJia Liu break; 1352bbe418f2SJia Liu 1353bbe418f2SJia Liu case 0x12: lf.mul.d 1354bbe418f2SJia Liu LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb); 1355bbe418f2SJia Liu check_of64s(dc); 1356bbe418f2SJia Liu if (ra != 0 && rb != 0) { 1357bbe418f2SJia Liu gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1358bbe418f2SJia Liu } else { 1359bbe418f2SJia Liu tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1360bbe418f2SJia Liu tcg_gen_movi_i64(cpu_R[rd], 0x0); 1361bbe418f2SJia Liu } 1362bbe418f2SJia Liu break; 1363bbe418f2SJia Liu 1364bbe418f2SJia Liu case 0x13: lf.div.d 1365bbe418f2SJia Liu LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb); 1366bbe418f2SJia Liu check_of64s(dc); 1367bbe418f2SJia Liu gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1368bbe418f2SJia Liu break; 1369bbe418f2SJia Liu 1370bbe418f2SJia Liu case 0x14: lf.itof.d 1371bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1372bbe418f2SJia Liu check_of64s(dc); 1373bbe418f2SJia Liu gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]); 1374bbe418f2SJia Liu break; 1375bbe418f2SJia Liu 1376bbe418f2SJia Liu case 0x15: lf.ftoi.d 1377bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1378bbe418f2SJia Liu check_of64s(dc); 1379bbe418f2SJia Liu gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]); 1380bbe418f2SJia Liu break; 1381bbe418f2SJia Liu 1382bbe418f2SJia Liu case 0x16: lf.rem.d 1383bbe418f2SJia Liu LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb); 1384bbe418f2SJia Liu check_of64s(dc); 1385bbe418f2SJia Liu gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1386bbe418f2SJia Liu break; 1387bbe418f2SJia Liu 1388bbe418f2SJia Liu case 0x17: lf.madd.d 1389bbe418f2SJia Liu LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); 1390bbe418f2SJia Liu check_of64s(dc); 1391bbe418f2SJia Liu gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1392bbe418f2SJia Liu break; 1393bbe418f2SJia Liu 1394bbe418f2SJia Liu case 0x18: lf.sfeq.d 1395bbe418f2SJia Liu LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); 1396bbe418f2SJia Liu check_of64s(dc); 1397bbe418f2SJia Liu gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1398bbe418f2SJia Liu break; 1399bbe418f2SJia Liu 1400bbe418f2SJia Liu case 0x1a: lf.sfgt.d 1401bbe418f2SJia Liu LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); 1402bbe418f2SJia Liu check_of64s(dc); 1403bbe418f2SJia Liu gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1404bbe418f2SJia Liu break; 1405bbe418f2SJia Liu 1406bbe418f2SJia Liu case 0x1b: lf.sfge.d 1407bbe418f2SJia Liu LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); 1408bbe418f2SJia Liu check_of64s(dc); 1409bbe418f2SJia Liu gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1410bbe418f2SJia Liu break; 1411bbe418f2SJia Liu 1412bbe418f2SJia Liu case 0x19: lf.sfne.d 1413bbe418f2SJia Liu LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); 1414bbe418f2SJia Liu check_of64s(dc); 1415bbe418f2SJia Liu gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1416bbe418f2SJia Liu break; 1417bbe418f2SJia Liu 1418bbe418f2SJia Liu case 0x1c: lf.sflt.d 1419bbe418f2SJia Liu LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); 1420bbe418f2SJia Liu check_of64s(dc); 1421bbe418f2SJia Liu gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1422bbe418f2SJia Liu break; 1423bbe418f2SJia Liu 1424bbe418f2SJia Liu case 0x1d: lf.sfle.d 1425bbe418f2SJia Liu LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); 1426bbe418f2SJia Liu check_of64s(dc); 1427bbe418f2SJia Liu gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1428bbe418f2SJia Liu break; 1429bbe418f2SJia Liu #endif*/ 1430bbe418f2SJia Liu 1431bbe418f2SJia Liu default: 1432bbe418f2SJia Liu gen_illegal_exception(dc); 1433bbe418f2SJia Liu break; 1434bbe418f2SJia Liu } 1435bbe418f2SJia Liu wb_SR_F(); 1436bbe418f2SJia Liu } 1437bbe418f2SJia Liu 1438bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) 1439bbe418f2SJia Liu { 1440bbe418f2SJia Liu uint32_t op0; 1441bbe418f2SJia Liu uint32_t insn; 1442bbe418f2SJia Liu insn = cpu_ldl_code(&cpu->env, dc->pc); 1443bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 1444bbe418f2SJia Liu 1445bbe418f2SJia Liu switch (op0) { 1446bbe418f2SJia Liu case 0x06: 1447bbe418f2SJia Liu dec_M(dc, insn); 1448bbe418f2SJia Liu break; 1449bbe418f2SJia Liu 1450bbe418f2SJia Liu case 0x08: 1451bbe418f2SJia Liu dec_sys(dc, insn); 1452bbe418f2SJia Liu break; 1453bbe418f2SJia Liu 1454bbe418f2SJia Liu case 0x2e: 1455bbe418f2SJia Liu dec_logic(dc, insn); 1456bbe418f2SJia Liu break; 1457bbe418f2SJia Liu 1458bbe418f2SJia Liu case 0x2f: 1459bbe418f2SJia Liu dec_compi(dc, insn); 1460bbe418f2SJia Liu break; 1461bbe418f2SJia Liu 1462bbe418f2SJia Liu case 0x31: 1463bbe418f2SJia Liu dec_mac(dc, insn); 1464bbe418f2SJia Liu break; 1465bbe418f2SJia Liu 1466bbe418f2SJia Liu case 0x32: 1467bbe418f2SJia Liu dec_float(dc, insn); 1468bbe418f2SJia Liu break; 1469bbe418f2SJia Liu 1470bbe418f2SJia Liu case 0x38: 1471bbe418f2SJia Liu dec_calc(dc, insn); 1472bbe418f2SJia Liu break; 1473bbe418f2SJia Liu 1474bbe418f2SJia Liu case 0x39: 1475bbe418f2SJia Liu dec_comp(dc, insn); 1476bbe418f2SJia Liu break; 1477bbe418f2SJia Liu 1478bbe418f2SJia Liu default: 1479bbe418f2SJia Liu dec_misc(dc, insn); 1480bbe418f2SJia Liu break; 1481bbe418f2SJia Liu } 1482bbe418f2SJia Liu } 1483bbe418f2SJia Liu 14844e5e1215SRichard Henderson void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) 1485e67db06eSJia Liu { 14864e5e1215SRichard Henderson OpenRISCCPU *cpu = openrisc_env_get_cpu(env); 1487ed2803daSAndreas Färber CPUState *cs = CPU(cpu); 1488bbe418f2SJia Liu struct DisasContext ctx, *dc = &ctx; 1489bbe418f2SJia Liu uint32_t pc_start; 1490bbe418f2SJia Liu uint32_t next_page_start; 1491bbe418f2SJia Liu int num_insns; 1492bbe418f2SJia Liu int max_insns; 1493bbe418f2SJia Liu 1494bbe418f2SJia Liu pc_start = tb->pc; 1495bbe418f2SJia Liu dc->tb = tb; 1496bbe418f2SJia Liu 1497bbe418f2SJia Liu dc->is_jmp = DISAS_NEXT; 1498bbe418f2SJia Liu dc->ppc = pc_start; 1499bbe418f2SJia Liu dc->pc = pc_start; 1500bbe418f2SJia Liu dc->flags = cpu->env.cpucfgr; 150197ed5ccdSBenjamin Herrenschmidt dc->mem_idx = cpu_mmu_index(&cpu->env, false); 1502bbe418f2SJia Liu dc->synced_flags = dc->tb_flags = tb->flags; 15030c53d734SRichard Henderson dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0; 1504ed2803daSAndreas Färber dc->singlestep_enabled = cs->singlestep_enabled; 1505bbe418f2SJia Liu 1506bbe418f2SJia Liu next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 1507bbe418f2SJia Liu num_insns = 0; 1508bbe418f2SJia Liu max_insns = tb->cflags & CF_COUNT_MASK; 1509bbe418f2SJia Liu 1510bbe418f2SJia Liu if (max_insns == 0) { 1511bbe418f2SJia Liu max_insns = CF_COUNT_MASK; 1512bbe418f2SJia Liu } 1513190ce7fbSRichard Henderson if (max_insns > TCG_MAX_INSNS) { 1514190ce7fbSRichard Henderson max_insns = TCG_MAX_INSNS; 1515190ce7fbSRichard Henderson } 1516bbe418f2SJia Liu 1517111ece51SRichard Henderson if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 1518111ece51SRichard Henderson && qemu_log_in_addr_range(pc_start)) { 1519111ece51SRichard Henderson qemu_log_lock(); 1520111ece51SRichard Henderson qemu_log("----------------\n"); 1521111ece51SRichard Henderson qemu_log("IN: %s\n", lookup_symbol(pc_start)); 1522111ece51SRichard Henderson } 1523111ece51SRichard Henderson 1524cd42d5b2SPaolo Bonzini gen_tb_start(tb); 1525bbe418f2SJia Liu 1526bbe418f2SJia Liu do { 1527765b842aSRichard Henderson tcg_gen_insn_start(dc->pc); 1528959082fcSRichard Henderson num_insns++; 1529bbe418f2SJia Liu 1530b933066aSRichard Henderson if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { 1531b933066aSRichard Henderson tcg_gen_movi_tl(cpu_pc, dc->pc); 1532b933066aSRichard Henderson gen_exception(dc, EXCP_DEBUG); 1533b933066aSRichard Henderson dc->is_jmp = DISAS_UPDATE; 1534522a0d4eSRichard Henderson /* The address covered by the breakpoint must be included in 1535522a0d4eSRichard Henderson [tb->pc, tb->pc + tb->size) in order to for it to be 1536522a0d4eSRichard Henderson properly cleared -- thus we increment the PC here so that 1537522a0d4eSRichard Henderson the logic setting tb->size below does the right thing. */ 1538522a0d4eSRichard Henderson dc->pc += 4; 1539b933066aSRichard Henderson break; 1540b933066aSRichard Henderson } 1541b933066aSRichard Henderson 1542959082fcSRichard Henderson if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { 1543bbe418f2SJia Liu gen_io_start(); 1544bbe418f2SJia Liu } 1545bbe418f2SJia Liu dc->ppc = dc->pc - 4; 1546bbe418f2SJia Liu dc->npc = dc->pc + 4; 1547bbe418f2SJia Liu tcg_gen_movi_tl(cpu_ppc, dc->ppc); 1548bbe418f2SJia Liu tcg_gen_movi_tl(cpu_npc, dc->npc); 1549bbe418f2SJia Liu disas_openrisc_insn(dc, cpu); 1550bbe418f2SJia Liu dc->pc = dc->npc; 1551bbe418f2SJia Liu /* delay slot */ 1552bbe418f2SJia Liu if (dc->delayed_branch) { 1553bbe418f2SJia Liu dc->delayed_branch--; 1554bbe418f2SJia Liu if (!dc->delayed_branch) { 1555bbe418f2SJia Liu dc->tb_flags &= ~D_FLAG; 1556bbe418f2SJia Liu gen_sync_flags(dc); 1557bbe418f2SJia Liu tcg_gen_mov_tl(cpu_pc, jmp_pc); 1558bbe418f2SJia Liu tcg_gen_mov_tl(cpu_npc, jmp_pc); 1559bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, 0); 1560bbe418f2SJia Liu tcg_gen_exit_tb(0); 1561bbe418f2SJia Liu dc->is_jmp = DISAS_JUMP; 1562bbe418f2SJia Liu break; 1563bbe418f2SJia Liu } 1564bbe418f2SJia Liu } 1565bbe418f2SJia Liu } while (!dc->is_jmp 1566fe700adbSRichard Henderson && !tcg_op_buf_full() 1567ed2803daSAndreas Färber && !cs->singlestep_enabled 1568bbe418f2SJia Liu && !singlestep 1569bbe418f2SJia Liu && (dc->pc < next_page_start) 1570bbe418f2SJia Liu && num_insns < max_insns); 1571bbe418f2SJia Liu 1572bbe418f2SJia Liu if (tb->cflags & CF_LAST_IO) { 1573bbe418f2SJia Liu gen_io_end(); 1574bbe418f2SJia Liu } 1575bbe418f2SJia Liu if (dc->is_jmp == DISAS_NEXT) { 1576bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 1577bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1578bbe418f2SJia Liu } 1579ed2803daSAndreas Färber if (unlikely(cs->singlestep_enabled)) { 1580bbe418f2SJia Liu if (dc->is_jmp == DISAS_NEXT) { 1581bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1582bbe418f2SJia Liu } 1583bbe418f2SJia Liu gen_exception(dc, EXCP_DEBUG); 1584bbe418f2SJia Liu } else { 1585bbe418f2SJia Liu switch (dc->is_jmp) { 1586bbe418f2SJia Liu case DISAS_NEXT: 1587bbe418f2SJia Liu gen_goto_tb(dc, 0, dc->pc); 1588bbe418f2SJia Liu break; 1589bbe418f2SJia Liu default: 1590bbe418f2SJia Liu case DISAS_JUMP: 1591bbe418f2SJia Liu break; 1592bbe418f2SJia Liu case DISAS_UPDATE: 1593bbe418f2SJia Liu /* indicate that the hash table must be used 1594bbe418f2SJia Liu to find the next TB */ 1595bbe418f2SJia Liu tcg_gen_exit_tb(0); 1596bbe418f2SJia Liu break; 1597bbe418f2SJia Liu case DISAS_TB_JUMP: 1598bbe418f2SJia Liu /* nothing more to generate */ 1599bbe418f2SJia Liu break; 1600bbe418f2SJia Liu } 1601bbe418f2SJia Liu } 1602bbe418f2SJia Liu 1603806f352dSPeter Maydell gen_tb_end(tb, num_insns); 16040a7df5daSRichard Henderson 1605bbe418f2SJia Liu tb->size = dc->pc - pc_start; 1606bbe418f2SJia Liu tb->icount = num_insns; 1607bbe418f2SJia Liu 16084910e6e4SRichard Henderson if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 16094910e6e4SRichard Henderson && qemu_log_in_addr_range(pc_start)) { 1610111ece51SRichard Henderson log_target_disas(cs, pc_start, tb->size, 0); 1611111ece51SRichard Henderson qemu_log("\n"); 16121ee73216SRichard Henderson qemu_log_unlock(); 1613bbe418f2SJia Liu } 1614e67db06eSJia Liu } 1615e67db06eSJia Liu 1616878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f, 1617e67db06eSJia Liu fprintf_function cpu_fprintf, 1618e67db06eSJia Liu int flags) 1619e67db06eSJia Liu { 1620878096eeSAndreas Färber OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1621878096eeSAndreas Färber CPUOpenRISCState *env = &cpu->env; 1622e67db06eSJia Liu int i; 1623878096eeSAndreas Färber 1624e67db06eSJia Liu cpu_fprintf(f, "PC=%08x\n", env->pc); 1625e67db06eSJia Liu for (i = 0; i < 32; ++i) { 1626878096eeSAndreas Färber cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i], 1627e67db06eSJia Liu (i % 4) == 3 ? '\n' : ' '); 1628e67db06eSJia Liu } 1629e67db06eSJia Liu } 1630e67db06eSJia Liu 1631e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1632bad729e2SRichard Henderson target_ulong *data) 1633e67db06eSJia Liu { 1634bad729e2SRichard Henderson env->pc = data[0]; 1635e67db06eSJia Liu } 1636