1e67db06eSJia Liu /* 2e67db06eSJia Liu * OpenRISC translation 3e67db06eSJia Liu * 4e67db06eSJia Liu * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> 5e67db06eSJia Liu * Feng Gao <gf91597@gmail.com> 6e67db06eSJia Liu * 7e67db06eSJia Liu * This library is free software; you can redistribute it and/or 8e67db06eSJia Liu * modify it under the terms of the GNU Lesser General Public 9e67db06eSJia Liu * License as published by the Free Software Foundation; either 10e67db06eSJia Liu * version 2 of the License, or (at your option) any later version. 11e67db06eSJia Liu * 12e67db06eSJia Liu * This library is distributed in the hope that it will be useful, 13e67db06eSJia Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of 14e67db06eSJia Liu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15e67db06eSJia Liu * Lesser General Public License for more details. 16e67db06eSJia Liu * 17e67db06eSJia Liu * You should have received a copy of the GNU Lesser General Public 18e67db06eSJia Liu * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19e67db06eSJia Liu */ 20e67db06eSJia Liu 21ed2decc6SPeter Maydell #include "qemu/osdep.h" 22e67db06eSJia Liu #include "cpu.h" 23022c62cbSPaolo Bonzini #include "exec/exec-all.h" 2476cad711SPaolo Bonzini #include "disas/disas.h" 25e67db06eSJia Liu #include "tcg-op.h" 26e67db06eSJia Liu #include "qemu-common.h" 271de7afc9SPaolo Bonzini #include "qemu/log.h" 281de7afc9SPaolo Bonzini #include "qemu/bitops.h" 29f08b6170SPaolo Bonzini #include "exec/cpu_ldst.h" 3077fc6f5eSLluís Vilanova #include "exec/translator.h" 31bbe418f2SJia Liu 322ef6175aSRichard Henderson #include "exec/helper-proto.h" 332ef6175aSRichard Henderson #include "exec/helper-gen.h" 34e67db06eSJia Liu 35a7e30d84SLluís Vilanova #include "trace-tcg.h" 36508127e2SPaolo Bonzini #include "exec/log.h" 37a7e30d84SLluís Vilanova 38111ece51SRichard Henderson #define LOG_DIS(str, ...) \ 391ffa4bceSEmilio G. Cota qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->base.pc_next, \ 401ffa4bceSEmilio G. Cota ## __VA_ARGS__) 41e67db06eSJia Liu 4277fc6f5eSLluís Vilanova /* is_jmp field values */ 4377fc6f5eSLluís Vilanova #define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */ 4477fc6f5eSLluís Vilanova #define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */ 4577fc6f5eSLluís Vilanova #define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */ 4677fc6f5eSLluís Vilanova 47bbe418f2SJia Liu typedef struct DisasContext { 481ffa4bceSEmilio G. Cota DisasContextBase base; 49bbe418f2SJia Liu uint32_t mem_idx; 50a01deb36SRichard Henderson uint32_t tb_flags; 51bbe418f2SJia Liu uint32_t delayed_branch; 52bbe418f2SJia Liu } DisasContext; 53bbe418f2SJia Liu 54bbe418f2SJia Liu static TCGv cpu_sr; 55bbe418f2SJia Liu static TCGv cpu_R[32]; 566597c28dSRichard Henderson static TCGv cpu_R0; 57bbe418f2SJia Liu static TCGv cpu_pc; 58bbe418f2SJia Liu static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ 59bbe418f2SJia Liu static TCGv cpu_ppc; 6084775c43SRichard Henderson static TCGv cpu_sr_f; /* bf/bnf, F flag taken */ 6197458071SRichard Henderson static TCGv cpu_sr_cy; /* carry (unsigned overflow) */ 6297458071SRichard Henderson static TCGv cpu_sr_ov; /* signed overflow */ 63930c3d00SRichard Henderson static TCGv cpu_lock_addr; 64930c3d00SRichard Henderson static TCGv cpu_lock_value; 65bbe418f2SJia Liu static TCGv_i32 fpcsr; 666f7332baSRichard Henderson static TCGv_i64 cpu_mac; /* MACHI:MACLO */ 67a01deb36SRichard Henderson static TCGv_i32 cpu_dflag; 68022c62cbSPaolo Bonzini #include "exec/gen-icount.h" 69bbe418f2SJia Liu 70e67db06eSJia Liu void openrisc_translate_init(void) 71e67db06eSJia Liu { 72bbe418f2SJia Liu static const char * const regnames[] = { 73bbe418f2SJia Liu "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 74bbe418f2SJia Liu "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 75bbe418f2SJia Liu "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 76bbe418f2SJia Liu "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 77bbe418f2SJia Liu }; 78bbe418f2SJia Liu int i; 79bbe418f2SJia Liu 80e1ccc054SRichard Henderson cpu_sr = tcg_global_mem_new(cpu_env, 81bbe418f2SJia Liu offsetof(CPUOpenRISCState, sr), "sr"); 82a01deb36SRichard Henderson cpu_dflag = tcg_global_mem_new_i32(cpu_env, 83a01deb36SRichard Henderson offsetof(CPUOpenRISCState, dflag), 84a01deb36SRichard Henderson "dflag"); 85e1ccc054SRichard Henderson cpu_pc = tcg_global_mem_new(cpu_env, 86bbe418f2SJia Liu offsetof(CPUOpenRISCState, pc), "pc"); 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"); 9184775c43SRichard Henderson cpu_sr_f = tcg_global_mem_new(cpu_env, 9284775c43SRichard Henderson offsetof(CPUOpenRISCState, sr_f), "sr_f"); 9397458071SRichard Henderson cpu_sr_cy = tcg_global_mem_new(cpu_env, 9497458071SRichard Henderson offsetof(CPUOpenRISCState, sr_cy), "sr_cy"); 9597458071SRichard Henderson cpu_sr_ov = tcg_global_mem_new(cpu_env, 9697458071SRichard Henderson offsetof(CPUOpenRISCState, sr_ov), "sr_ov"); 97930c3d00SRichard Henderson cpu_lock_addr = tcg_global_mem_new(cpu_env, 98930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_addr), 99930c3d00SRichard Henderson "lock_addr"); 100930c3d00SRichard Henderson cpu_lock_value = tcg_global_mem_new(cpu_env, 101930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_value), 102930c3d00SRichard Henderson "lock_value"); 103e1ccc054SRichard Henderson fpcsr = tcg_global_mem_new_i32(cpu_env, 104bbe418f2SJia Liu offsetof(CPUOpenRISCState, fpcsr), 105bbe418f2SJia Liu "fpcsr"); 1066f7332baSRichard Henderson cpu_mac = tcg_global_mem_new_i64(cpu_env, 1076f7332baSRichard Henderson offsetof(CPUOpenRISCState, mac), 1086f7332baSRichard Henderson "mac"); 109bbe418f2SJia Liu for (i = 0; i < 32; i++) { 110e1ccc054SRichard Henderson cpu_R[i] = tcg_global_mem_new(cpu_env, 111d89e71e8SStafford Horne offsetof(CPUOpenRISCState, 112d89e71e8SStafford Horne shadow_gpr[0][i]), 113bbe418f2SJia Liu regnames[i]); 114bbe418f2SJia Liu } 1156597c28dSRichard Henderson cpu_R0 = cpu_R[0]; 116bbe418f2SJia Liu } 117bbe418f2SJia Liu 118bbe418f2SJia Liu static void gen_exception(DisasContext *dc, unsigned int excp) 119bbe418f2SJia Liu { 120bbe418f2SJia Liu TCGv_i32 tmp = tcg_const_i32(excp); 121bbe418f2SJia Liu gen_helper_exception(cpu_env, tmp); 122bbe418f2SJia Liu tcg_temp_free_i32(tmp); 123bbe418f2SJia Liu } 124bbe418f2SJia Liu 125bbe418f2SJia Liu static void gen_illegal_exception(DisasContext *dc) 126bbe418f2SJia Liu { 1271ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 128bbe418f2SJia Liu gen_exception(dc, EXCP_ILLEGAL); 1291ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 130bbe418f2SJia Liu } 131bbe418f2SJia Liu 132bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 133bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 134bbe418f2SJia Liu static void check_ob64s(DisasContext *dc) 135bbe418f2SJia Liu { 136bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OB64S)) { 137bbe418f2SJia Liu gen_illegal_exception(dc); 138bbe418f2SJia Liu } 139bbe418f2SJia Liu } 140bbe418f2SJia Liu 141bbe418f2SJia Liu static void check_of64s(DisasContext *dc) 142bbe418f2SJia Liu { 143bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OF64S)) { 144bbe418f2SJia Liu gen_illegal_exception(dc); 145bbe418f2SJia Liu } 146bbe418f2SJia Liu } 147bbe418f2SJia Liu 148bbe418f2SJia Liu static void check_ov64s(DisasContext *dc) 149bbe418f2SJia Liu { 150bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OV64S)) { 151bbe418f2SJia Liu gen_illegal_exception(dc); 152bbe418f2SJia Liu } 153bbe418f2SJia Liu } 154bbe418f2SJia Liu #endif*/ 155bbe418f2SJia Liu 1566597c28dSRichard Henderson /* We're about to write to REG. On the off-chance that the user is 1576597c28dSRichard Henderson writing to R0, re-instate the architectural register. */ 1586597c28dSRichard Henderson #define check_r0_write(reg) \ 1596597c28dSRichard Henderson do { \ 1606597c28dSRichard Henderson if (unlikely(reg == 0)) { \ 1616597c28dSRichard Henderson cpu_R[0] = cpu_R0; \ 1626597c28dSRichard Henderson } \ 1636597c28dSRichard Henderson } while (0) 1646597c28dSRichard Henderson 16590aa39a1SSergey Fedorov static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) 16690aa39a1SSergey Fedorov { 1671ffa4bceSEmilio G. Cota if (unlikely(dc->base.singlestep_enabled)) { 16890aa39a1SSergey Fedorov return false; 16990aa39a1SSergey Fedorov } 17090aa39a1SSergey Fedorov 17190aa39a1SSergey Fedorov #ifndef CONFIG_USER_ONLY 1721ffa4bceSEmilio G. Cota return (dc->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 17390aa39a1SSergey Fedorov #else 17490aa39a1SSergey Fedorov return true; 17590aa39a1SSergey Fedorov #endif 17690aa39a1SSergey Fedorov } 17790aa39a1SSergey Fedorov 178bbe418f2SJia Liu static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 179bbe418f2SJia Liu { 18090aa39a1SSergey Fedorov if (use_goto_tb(dc, dest)) { 181bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dest); 182bbe418f2SJia Liu tcg_gen_goto_tb(n); 1831ffa4bceSEmilio G. Cota tcg_gen_exit_tb((uintptr_t)dc->base.tb + n); 184bbe418f2SJia Liu } else { 185bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dest); 1861ffa4bceSEmilio G. Cota if (dc->base.singlestep_enabled) { 187bbe418f2SJia Liu gen_exception(dc, EXCP_DEBUG); 188bbe418f2SJia Liu } 189bbe418f2SJia Liu tcg_gen_exit_tb(0); 190bbe418f2SJia Liu } 191bbe418f2SJia Liu } 192bbe418f2SJia Liu 1936da544a6SRichard Henderson static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0) 194bbe418f2SJia Liu { 1951ffa4bceSEmilio G. Cota target_ulong tmp_pc = dc->base.pc_next + n26 * 4; 196bbe418f2SJia Liu 197da1d7759SSebastian Macke switch (op0) { 198da1d7759SSebastian Macke case 0x00: /* l.j */ 199bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, tmp_pc); 200da1d7759SSebastian Macke break; 201da1d7759SSebastian Macke case 0x01: /* l.jal */ 2021ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8); 203a8000cb4SRichard Henderson /* Optimize jal being used to load the PC for PIC. */ 2041ffa4bceSEmilio G. Cota if (tmp_pc == dc->base.pc_next + 8) { 205a8000cb4SRichard Henderson return; 206a8000cb4SRichard Henderson } 207bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, tmp_pc); 208da1d7759SSebastian Macke break; 209da1d7759SSebastian Macke case 0x03: /* l.bnf */ 210da1d7759SSebastian Macke case 0x04: /* l.bf */ 211da1d7759SSebastian Macke { 2121ffa4bceSEmilio G. Cota TCGv t_next = tcg_const_tl(dc->base.pc_next + 8); 213784696d1SRichard Henderson TCGv t_true = tcg_const_tl(tmp_pc); 214784696d1SRichard Henderson TCGv t_zero = tcg_const_tl(0); 215784696d1SRichard Henderson 216784696d1SRichard Henderson tcg_gen_movcond_tl(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, 217784696d1SRichard Henderson jmp_pc, cpu_sr_f, t_zero, t_true, t_next); 218784696d1SRichard Henderson 219784696d1SRichard Henderson tcg_temp_free(t_next); 220784696d1SRichard Henderson tcg_temp_free(t_true); 221784696d1SRichard Henderson tcg_temp_free(t_zero); 222da1d7759SSebastian Macke } 223da1d7759SSebastian Macke break; 224da1d7759SSebastian Macke case 0x11: /* l.jr */ 225bbe418f2SJia Liu tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 226da1d7759SSebastian Macke break; 227da1d7759SSebastian Macke case 0x12: /* l.jalr */ 2281ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_R[9], (dc->base.pc_next + 8)); 229bbe418f2SJia Liu tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 230da1d7759SSebastian Macke break; 231da1d7759SSebastian Macke default: 232bbe418f2SJia Liu gen_illegal_exception(dc); 233da1d7759SSebastian Macke break; 234bbe418f2SJia Liu } 235bbe418f2SJia Liu 236bbe418f2SJia Liu dc->delayed_branch = 2; 237bbe418f2SJia Liu } 238bbe418f2SJia Liu 23997458071SRichard Henderson static void gen_ove_cy(DisasContext *dc) 2409ecaa27eSRichard Henderson { 2410c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 24297458071SRichard Henderson gen_helper_ove_cy(cpu_env); 2439ecaa27eSRichard Henderson } 2440c53d734SRichard Henderson } 2459ecaa27eSRichard Henderson 24697458071SRichard Henderson static void gen_ove_ov(DisasContext *dc) 2479ecaa27eSRichard Henderson { 2480c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 24997458071SRichard Henderson gen_helper_ove_ov(cpu_env); 2509ecaa27eSRichard Henderson } 2510c53d734SRichard Henderson } 2529ecaa27eSRichard Henderson 25397458071SRichard Henderson static void gen_ove_cyov(DisasContext *dc) 2549ecaa27eSRichard Henderson { 2550c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 25697458071SRichard Henderson gen_helper_ove_cyov(cpu_env); 2579ecaa27eSRichard Henderson } 2580c53d734SRichard Henderson } 2599ecaa27eSRichard Henderson 2609ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2619ecaa27eSRichard Henderson { 2629ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 2639ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2649ecaa27eSRichard Henderson 26597458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0); 26697458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb); 2679ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 26897458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov); 2699ecaa27eSRichard Henderson tcg_temp_free(t0); 2709ecaa27eSRichard Henderson 2719ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2729ecaa27eSRichard Henderson tcg_temp_free(res); 2739ecaa27eSRichard Henderson 27497458071SRichard Henderson gen_ove_cyov(dc); 2759ecaa27eSRichard Henderson } 2769ecaa27eSRichard Henderson 2779ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2789ecaa27eSRichard Henderson { 2799ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 2809ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2819ecaa27eSRichard Henderson 28297458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0); 28397458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0); 28497458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb); 2859ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 28697458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov); 2879ecaa27eSRichard Henderson tcg_temp_free(t0); 2889ecaa27eSRichard Henderson 2899ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2909ecaa27eSRichard Henderson tcg_temp_free(res); 2919ecaa27eSRichard Henderson 29297458071SRichard Henderson gen_ove_cyov(dc); 2939ecaa27eSRichard Henderson } 2949ecaa27eSRichard Henderson 2959ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2969ecaa27eSRichard Henderson { 2979ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2989ecaa27eSRichard Henderson 2999ecaa27eSRichard Henderson tcg_gen_sub_tl(res, srca, srcb); 30097458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_cy, srca, srcb); 30197458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, res, srcb); 30297458071SRichard Henderson tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy); 30397458071SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb); 3049ecaa27eSRichard Henderson 3059ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 3069ecaa27eSRichard Henderson tcg_temp_free(res); 3079ecaa27eSRichard Henderson 30897458071SRichard Henderson gen_ove_cyov(dc); 3099ecaa27eSRichard Henderson } 3109ecaa27eSRichard Henderson 3119ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3129ecaa27eSRichard Henderson { 3139ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 3149ecaa27eSRichard Henderson 31597458071SRichard Henderson tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb); 3169ecaa27eSRichard Henderson tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1); 31797458071SRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0); 3189ecaa27eSRichard Henderson tcg_temp_free(t0); 3199ecaa27eSRichard Henderson 32097458071SRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 32197458071SRichard Henderson gen_ove_ov(dc); 3229ecaa27eSRichard Henderson } 3239ecaa27eSRichard Henderson 3249ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3259ecaa27eSRichard Henderson { 32697458071SRichard Henderson tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb); 32797458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0); 3289ecaa27eSRichard Henderson 32997458071SRichard Henderson gen_ove_cy(dc); 3309ecaa27eSRichard Henderson } 3319ecaa27eSRichard Henderson 3329ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3339ecaa27eSRichard Henderson { 3349ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 3359ecaa27eSRichard Henderson 33697458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0); 3379ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 3389ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 33997458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_ov); 3409ecaa27eSRichard Henderson tcg_gen_div_tl(dest, srca, t0); 3419ecaa27eSRichard Henderson tcg_temp_free(t0); 3429ecaa27eSRichard Henderson 34397458071SRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 34497458071SRichard Henderson gen_ove_ov(dc); 3459ecaa27eSRichard Henderson } 3469ecaa27eSRichard Henderson 3479ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 3489ecaa27eSRichard Henderson { 3499ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 3509ecaa27eSRichard Henderson 35197458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0); 3529ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 3539ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 35497458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_cy); 3559ecaa27eSRichard Henderson tcg_gen_divu_tl(dest, srca, t0); 3569ecaa27eSRichard Henderson tcg_temp_free(t0); 3579ecaa27eSRichard Henderson 35897458071SRichard Henderson gen_ove_cy(dc); 3599ecaa27eSRichard Henderson } 360da1d7759SSebastian Macke 361cc5de49eSRichard Henderson static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb) 362cc5de49eSRichard Henderson { 363cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 364cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 365cc5de49eSRichard Henderson 366cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 367cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 368cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) { 369cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2); 370cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_ov, 0); 371cc5de49eSRichard Henderson } else { 372cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64(); 373cc5de49eSRichard Henderson 374cc5de49eSRichard Henderson tcg_gen_muls2_i64(cpu_mac, high, t1, t2); 375cc5de49eSRichard Henderson tcg_gen_sari_i64(t1, cpu_mac, 63); 376cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high); 377cc5de49eSRichard Henderson tcg_temp_free_i64(high); 378cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_ov, t1); 379cc5de49eSRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 380cc5de49eSRichard Henderson 381cc5de49eSRichard Henderson gen_ove_ov(dc); 382cc5de49eSRichard Henderson } 383cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 384cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 385cc5de49eSRichard Henderson } 386cc5de49eSRichard Henderson 387cc5de49eSRichard Henderson static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb) 388cc5de49eSRichard Henderson { 389cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 390cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 391cc5de49eSRichard Henderson 392cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 393cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 394cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) { 395cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2); 396cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_cy, 0); 397cc5de49eSRichard Henderson } else { 398cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64(); 399cc5de49eSRichard Henderson 400cc5de49eSRichard Henderson tcg_gen_mulu2_i64(cpu_mac, high, t1, t2); 401cc5de49eSRichard Henderson tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0); 402cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, high); 403cc5de49eSRichard Henderson tcg_temp_free_i64(high); 404cc5de49eSRichard Henderson 405cc5de49eSRichard Henderson gen_ove_cy(dc); 406cc5de49eSRichard Henderson } 407cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 408cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 409cc5de49eSRichard Henderson } 410cc5de49eSRichard Henderson 4116f7332baSRichard Henderson static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb) 4126f7332baSRichard Henderson { 4136f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 4146f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 4156f7332baSRichard Henderson 4166f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 4176f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 4186f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 4196f7332baSRichard Henderson 4206f7332baSRichard Henderson /* Note that overflow is only computed during addition stage. */ 4216f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1); 4226f7332baSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1); 4236f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac); 4246f7332baSRichard Henderson tcg_gen_andc_i64(t1, t1, t2); 4256f7332baSRichard Henderson tcg_temp_free_i64(t2); 4266f7332baSRichard Henderson 4276f7332baSRichard Henderson #if TARGET_LONG_BITS == 32 4286f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1); 4296f7332baSRichard Henderson #else 4306f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1); 4316f7332baSRichard Henderson #endif 4326f7332baSRichard Henderson tcg_temp_free_i64(t1); 4336f7332baSRichard Henderson 4346f7332baSRichard Henderson gen_ove_ov(dc); 4356f7332baSRichard Henderson } 4366f7332baSRichard Henderson 437cc5de49eSRichard Henderson static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb) 438cc5de49eSRichard Henderson { 439cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 440cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 441cc5de49eSRichard Henderson 442cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 443cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 444cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 445cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 446cc5de49eSRichard Henderson 447cc5de49eSRichard Henderson /* Note that overflow is only computed during addition stage. */ 448cc5de49eSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1); 449cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1); 450cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t1); 451cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 452cc5de49eSRichard Henderson 453cc5de49eSRichard Henderson gen_ove_cy(dc); 454cc5de49eSRichard Henderson } 455cc5de49eSRichard Henderson 4566f7332baSRichard Henderson static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb) 4576f7332baSRichard Henderson { 4586f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 4596f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 4606f7332baSRichard Henderson 4616f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 4626f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 4636f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 4646f7332baSRichard Henderson 4656f7332baSRichard Henderson /* Note that overflow is only computed during subtraction stage. */ 4666f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1); 4676f7332baSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1); 4686f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac); 4696f7332baSRichard Henderson tcg_gen_and_i64(t1, t1, t2); 4706f7332baSRichard Henderson tcg_temp_free_i64(t2); 4716f7332baSRichard Henderson 4726f7332baSRichard Henderson #if TARGET_LONG_BITS == 32 4736f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1); 4746f7332baSRichard Henderson #else 4756f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1); 4766f7332baSRichard Henderson #endif 4776f7332baSRichard Henderson tcg_temp_free_i64(t1); 4786f7332baSRichard Henderson 4796f7332baSRichard Henderson gen_ove_ov(dc); 4806f7332baSRichard Henderson } 4816f7332baSRichard Henderson 482cc5de49eSRichard Henderson static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb) 483cc5de49eSRichard Henderson { 484cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 485cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 486cc5de49eSRichard Henderson 487cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 488cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 489cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 490cc5de49eSRichard Henderson 491cc5de49eSRichard Henderson /* Note that overflow is only computed during subtraction stage. */ 492cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1); 493cc5de49eSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1); 494cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t2); 495cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 496cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 497cc5de49eSRichard Henderson 498cc5de49eSRichard Henderson gen_ove_cy(dc); 499cc5de49eSRichard Henderson } 500cc5de49eSRichard Henderson 501930c3d00SRichard Henderson static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs) 502930c3d00SRichard Henderson { 503930c3d00SRichard Henderson TCGv ea = tcg_temp_new(); 504930c3d00SRichard Henderson 505930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 506930c3d00SRichard Henderson tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL); 507930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_addr, ea); 508930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_value, rd); 509930c3d00SRichard Henderson tcg_temp_free(ea); 510930c3d00SRichard Henderson } 511930c3d00SRichard Henderson 5126597c28dSRichard Henderson static void gen_swa(DisasContext *dc, int b, TCGv ra, int32_t ofs) 513930c3d00SRichard Henderson { 514930c3d00SRichard Henderson TCGv ea, val; 515930c3d00SRichard Henderson TCGLabel *lab_fail, *lab_done; 516930c3d00SRichard Henderson 517930c3d00SRichard Henderson ea = tcg_temp_new(); 518930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 519930c3d00SRichard Henderson 5206597c28dSRichard Henderson /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned 5216597c28dSRichard Henderson to cpu_R[0]. Since l.swa is quite often immediately followed by a 5226597c28dSRichard Henderson branch, don't bother reallocating; finish the TB using the "real" R0. 5236597c28dSRichard Henderson This also takes care of RB input across the branch. */ 5246597c28dSRichard Henderson cpu_R[0] = cpu_R0; 5256597c28dSRichard Henderson 526930c3d00SRichard Henderson lab_fail = gen_new_label(); 527930c3d00SRichard Henderson lab_done = gen_new_label(); 528930c3d00SRichard Henderson tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail); 529930c3d00SRichard Henderson tcg_temp_free(ea); 530930c3d00SRichard Henderson 531930c3d00SRichard Henderson val = tcg_temp_new(); 532930c3d00SRichard Henderson tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value, 5336597c28dSRichard Henderson cpu_R[b], dc->mem_idx, MO_TEUL); 53484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value); 535930c3d00SRichard Henderson tcg_temp_free(val); 536930c3d00SRichard Henderson 537930c3d00SRichard Henderson tcg_gen_br(lab_done); 538930c3d00SRichard Henderson 539930c3d00SRichard Henderson gen_set_label(lab_fail); 54084775c43SRichard Henderson tcg_gen_movi_tl(cpu_sr_f, 0); 541930c3d00SRichard Henderson 542930c3d00SRichard Henderson gen_set_label(lab_done); 543930c3d00SRichard Henderson tcg_gen_movi_tl(cpu_lock_addr, -1); 544930c3d00SRichard Henderson } 545930c3d00SRichard Henderson 546bbe418f2SJia Liu static void dec_calc(DisasContext *dc, uint32_t insn) 547bbe418f2SJia Liu { 548bbe418f2SJia Liu uint32_t op0, op1, op2; 549bbe418f2SJia Liu uint32_t ra, rb, rd; 550bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 551bbe418f2SJia Liu op1 = extract32(insn, 8, 2); 552bbe418f2SJia Liu op2 = extract32(insn, 6, 2); 553bbe418f2SJia Liu ra = extract32(insn, 16, 5); 554bbe418f2SJia Liu rb = extract32(insn, 11, 5); 555bbe418f2SJia Liu rd = extract32(insn, 21, 5); 556bbe418f2SJia Liu 557bbe418f2SJia Liu switch (op1) { 558cf2ae442SRichard Henderson case 0: 559cf2ae442SRichard Henderson switch (op0) { 560cf2ae442SRichard Henderson case 0x0: /* l.add */ 561bbe418f2SJia Liu LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); 5629ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 563cf2ae442SRichard Henderson return; 564bbe418f2SJia Liu 565cf2ae442SRichard Henderson case 0x1: /* l.addc */ 566bbe418f2SJia Liu LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); 5679ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 568cf2ae442SRichard Henderson return; 569bbe418f2SJia Liu 570cf2ae442SRichard Henderson case 0x2: /* l.sub */ 571bbe418f2SJia Liu LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); 5729ecaa27eSRichard Henderson gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 573cf2ae442SRichard Henderson return; 574bbe418f2SJia Liu 575cf2ae442SRichard Henderson case 0x3: /* l.and */ 576bbe418f2SJia Liu LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); 577bbe418f2SJia Liu tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 578cf2ae442SRichard Henderson return; 579bbe418f2SJia Liu 580cf2ae442SRichard Henderson case 0x4: /* l.or */ 581bbe418f2SJia Liu LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); 582bbe418f2SJia Liu tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 583cf2ae442SRichard Henderson return; 584bbe418f2SJia Liu 585cf2ae442SRichard Henderson case 0x5: /* l.xor */ 586bbe418f2SJia Liu LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); 587bbe418f2SJia Liu tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 588cf2ae442SRichard Henderson return; 589cf2ae442SRichard Henderson 590cf2ae442SRichard Henderson case 0x8: 591cf2ae442SRichard Henderson switch (op2) { 592cf2ae442SRichard Henderson case 0: /* l.sll */ 593cf2ae442SRichard Henderson LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb); 594cf2ae442SRichard Henderson tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 595cf2ae442SRichard Henderson return; 596cf2ae442SRichard Henderson case 1: /* l.srl */ 597cf2ae442SRichard Henderson LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb); 598cf2ae442SRichard Henderson tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 599cf2ae442SRichard Henderson return; 600cf2ae442SRichard Henderson case 2: /* l.sra */ 601cf2ae442SRichard Henderson LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb); 602cf2ae442SRichard Henderson tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 603cf2ae442SRichard Henderson return; 604cf2ae442SRichard Henderson case 3: /* l.ror */ 605cf2ae442SRichard Henderson LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb); 606cf2ae442SRichard Henderson tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 607cf2ae442SRichard Henderson return; 608bbe418f2SJia Liu } 609bbe418f2SJia Liu break; 610bbe418f2SJia Liu 611cf2ae442SRichard Henderson case 0xc: 612cf2ae442SRichard Henderson switch (op2) { 613cf2ae442SRichard Henderson case 0: /* l.exths */ 614cf2ae442SRichard Henderson LOG_DIS("l.exths r%d, r%d\n", rd, ra); 615cf2ae442SRichard Henderson tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]); 616cf2ae442SRichard Henderson return; 617cf2ae442SRichard Henderson case 1: /* l.extbs */ 618cf2ae442SRichard Henderson LOG_DIS("l.extbs r%d, r%d\n", rd, ra); 619cf2ae442SRichard Henderson tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]); 620cf2ae442SRichard Henderson return; 621cf2ae442SRichard Henderson case 2: /* l.exthz */ 622cf2ae442SRichard Henderson LOG_DIS("l.exthz r%d, r%d\n", rd, ra); 623cf2ae442SRichard Henderson tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]); 624cf2ae442SRichard Henderson return; 625cf2ae442SRichard Henderson case 3: /* l.extbz */ 626cf2ae442SRichard Henderson LOG_DIS("l.extbz r%d, r%d\n", rd, ra); 627cf2ae442SRichard Henderson tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]); 628cf2ae442SRichard Henderson return; 629bbe418f2SJia Liu } 630bbe418f2SJia Liu break; 631bbe418f2SJia Liu 632cf2ae442SRichard Henderson case 0xd: 633cf2ae442SRichard Henderson switch (op2) { 634cf2ae442SRichard Henderson case 0: /* l.extws */ 635cf2ae442SRichard Henderson LOG_DIS("l.extws r%d, r%d\n", rd, ra); 636cf2ae442SRichard Henderson tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]); 637cf2ae442SRichard Henderson return; 638cf2ae442SRichard Henderson case 1: /* l.extwz */ 639cf2ae442SRichard Henderson LOG_DIS("l.extwz r%d, r%d\n", rd, ra); 640cf2ae442SRichard Henderson tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]); 641cf2ae442SRichard Henderson return; 642bbe418f2SJia Liu } 643bbe418f2SJia Liu break; 644bbe418f2SJia Liu 645cf2ae442SRichard Henderson case 0xe: /* l.cmov */ 646bbe418f2SJia Liu LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); 647bbe418f2SJia Liu { 648784696d1SRichard Henderson TCGv zero = tcg_const_tl(0); 649784696d1SRichard Henderson tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero, 650784696d1SRichard Henderson cpu_R[ra], cpu_R[rb]); 651784696d1SRichard Henderson tcg_temp_free(zero); 652bbe418f2SJia Liu } 653cf2ae442SRichard Henderson return; 654bbe418f2SJia Liu 655cf2ae442SRichard Henderson case 0xf: /* l.ff1 */ 656bbe418f2SJia Liu LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); 657555baef8SRichard Henderson tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1); 658555baef8SRichard Henderson tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1); 659cf2ae442SRichard Henderson return; 660cf2ae442SRichard Henderson } 661bbe418f2SJia Liu break; 662cf2ae442SRichard Henderson 663cf2ae442SRichard Henderson case 1: 664cf2ae442SRichard Henderson switch (op0) { 665cf2ae442SRichard Henderson case 0xf: /* l.fl1 */ 666bbe418f2SJia Liu LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); 667555baef8SRichard Henderson tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS); 668555baef8SRichard Henderson tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]); 669cf2ae442SRichard Henderson return; 670bbe418f2SJia Liu } 671bbe418f2SJia Liu break; 672bbe418f2SJia Liu 673cf2ae442SRichard Henderson case 2: 674bbe418f2SJia Liu break; 675bbe418f2SJia Liu 676cf2ae442SRichard Henderson case 3: 677cf2ae442SRichard Henderson switch (op0) { 678cf2ae442SRichard Henderson case 0x6: /* l.mul */ 679cf2ae442SRichard Henderson LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb); 680cf2ae442SRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 681cf2ae442SRichard Henderson return; 682cf2ae442SRichard Henderson 683cc5de49eSRichard Henderson case 0x7: /* l.muld */ 684cc5de49eSRichard Henderson LOG_DIS("l.muld r%d, r%d\n", ra, rb); 685cc5de49eSRichard Henderson gen_muld(dc, cpu_R[ra], cpu_R[rb]); 686cc5de49eSRichard Henderson break; 687cc5de49eSRichard Henderson 688cf2ae442SRichard Henderson case 0x9: /* l.div */ 689cf2ae442SRichard Henderson LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb); 690cf2ae442SRichard Henderson gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 691cf2ae442SRichard Henderson return; 692cf2ae442SRichard Henderson 693cf2ae442SRichard Henderson case 0xa: /* l.divu */ 694cf2ae442SRichard Henderson LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb); 695cf2ae442SRichard Henderson gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 696cf2ae442SRichard Henderson return; 697cf2ae442SRichard Henderson 698cf2ae442SRichard Henderson case 0xb: /* l.mulu */ 699cf2ae442SRichard Henderson LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb); 700cf2ae442SRichard Henderson gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 701cf2ae442SRichard Henderson return; 702cc5de49eSRichard Henderson 703cc5de49eSRichard Henderson case 0xc: /* l.muldu */ 704cc5de49eSRichard Henderson LOG_DIS("l.muldu r%d, r%d\n", ra, rb); 705cc5de49eSRichard Henderson gen_muldu(dc, cpu_R[ra], cpu_R[rb]); 706cc5de49eSRichard Henderson return; 707bbe418f2SJia Liu } 708bbe418f2SJia Liu break; 709bbe418f2SJia Liu } 710bbe418f2SJia Liu gen_illegal_exception(dc); 711bbe418f2SJia Liu } 712bbe418f2SJia Liu 713bbe418f2SJia Liu static void dec_misc(DisasContext *dc, uint32_t insn) 714bbe418f2SJia Liu { 715bbe418f2SJia Liu uint32_t op0, op1; 716bbe418f2SJia Liu uint32_t ra, rb, rd; 7176da544a6SRichard Henderson uint32_t L6, K5, K16, K5_11; 7186da544a6SRichard Henderson int32_t I16, I5_11, N26; 7195631e69cSRichard Henderson TCGMemOp mop; 7209ecaa27eSRichard Henderson TCGv t0; 7215631e69cSRichard Henderson 722bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 723bbe418f2SJia Liu op1 = extract32(insn, 24, 2); 724bbe418f2SJia Liu ra = extract32(insn, 16, 5); 725bbe418f2SJia Liu rb = extract32(insn, 11, 5); 726bbe418f2SJia Liu rd = extract32(insn, 21, 5); 727bbe418f2SJia Liu L6 = extract32(insn, 5, 6); 728bbe418f2SJia Liu K5 = extract32(insn, 0, 5); 7296da544a6SRichard Henderson K16 = extract32(insn, 0, 16); 7306da544a6SRichard Henderson I16 = (int16_t)K16; 7316da544a6SRichard Henderson N26 = sextract32(insn, 0, 26); 7326da544a6SRichard Henderson K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11); 7336da544a6SRichard Henderson I5_11 = (int16_t)K5_11; 734bbe418f2SJia Liu 735bbe418f2SJia Liu switch (op0) { 736bbe418f2SJia Liu case 0x00: /* l.j */ 737bbe418f2SJia Liu LOG_DIS("l.j %d\n", N26); 738bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 739bbe418f2SJia Liu break; 740bbe418f2SJia Liu 741bbe418f2SJia Liu case 0x01: /* l.jal */ 742bbe418f2SJia Liu LOG_DIS("l.jal %d\n", N26); 743bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 744bbe418f2SJia Liu break; 745bbe418f2SJia Liu 746bbe418f2SJia Liu case 0x03: /* l.bnf */ 747bbe418f2SJia Liu LOG_DIS("l.bnf %d\n", N26); 748bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 749bbe418f2SJia Liu break; 750bbe418f2SJia Liu 751bbe418f2SJia Liu case 0x04: /* l.bf */ 752bbe418f2SJia Liu LOG_DIS("l.bf %d\n", N26); 753bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 754bbe418f2SJia Liu break; 755bbe418f2SJia Liu 756bbe418f2SJia Liu case 0x05: 757bbe418f2SJia Liu switch (op1) { 758bbe418f2SJia Liu case 0x01: /* l.nop */ 759bbe418f2SJia Liu LOG_DIS("l.nop %d\n", I16); 760bbe418f2SJia Liu break; 761bbe418f2SJia Liu 762bbe418f2SJia Liu default: 763bbe418f2SJia Liu gen_illegal_exception(dc); 764bbe418f2SJia Liu break; 765bbe418f2SJia Liu } 766bbe418f2SJia Liu break; 767bbe418f2SJia Liu 768bbe418f2SJia Liu case 0x11: /* l.jr */ 769bbe418f2SJia Liu LOG_DIS("l.jr r%d\n", rb); 770bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 771bbe418f2SJia Liu break; 772bbe418f2SJia Liu 773bbe418f2SJia Liu case 0x12: /* l.jalr */ 774bbe418f2SJia Liu LOG_DIS("l.jalr r%d\n", rb); 775bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 776bbe418f2SJia Liu break; 777bbe418f2SJia Liu 778bbe418f2SJia Liu case 0x13: /* l.maci */ 7796da544a6SRichard Henderson LOG_DIS("l.maci r%d, %d\n", ra, I16); 7806f7332baSRichard Henderson t0 = tcg_const_tl(I16); 7816f7332baSRichard Henderson gen_mac(dc, cpu_R[ra], t0); 7826f7332baSRichard Henderson tcg_temp_free(t0); 783bbe418f2SJia Liu break; 784bbe418f2SJia Liu 785bbe418f2SJia Liu case 0x09: /* l.rfe */ 786bbe418f2SJia Liu LOG_DIS("l.rfe\n"); 787bbe418f2SJia Liu { 788bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 789bbe418f2SJia Liu return; 790bbe418f2SJia Liu #else 791bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 792bbe418f2SJia Liu gen_illegal_exception(dc); 793bbe418f2SJia Liu return; 794bbe418f2SJia Liu } 795bbe418f2SJia Liu gen_helper_rfe(cpu_env); 7961ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_UPDATE; 797bbe418f2SJia Liu #endif 798bbe418f2SJia Liu } 799bbe418f2SJia Liu break; 800bbe418f2SJia Liu 801930c3d00SRichard Henderson case 0x1b: /* l.lwa */ 802930c3d00SRichard Henderson LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16); 8036597c28dSRichard Henderson check_r0_write(rd); 804930c3d00SRichard Henderson gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16); 805930c3d00SRichard Henderson break; 806930c3d00SRichard Henderson 807bbe418f2SJia Liu case 0x1c: /* l.cust1 */ 808bbe418f2SJia Liu LOG_DIS("l.cust1\n"); 809bbe418f2SJia Liu break; 810bbe418f2SJia Liu 811bbe418f2SJia Liu case 0x1d: /* l.cust2 */ 812bbe418f2SJia Liu LOG_DIS("l.cust2\n"); 813bbe418f2SJia Liu break; 814bbe418f2SJia Liu 815bbe418f2SJia Liu case 0x1e: /* l.cust3 */ 816bbe418f2SJia Liu LOG_DIS("l.cust3\n"); 817bbe418f2SJia Liu break; 818bbe418f2SJia Liu 819bbe418f2SJia Liu case 0x1f: /* l.cust4 */ 820bbe418f2SJia Liu LOG_DIS("l.cust4\n"); 821bbe418f2SJia Liu break; 822bbe418f2SJia Liu 823bbe418f2SJia Liu case 0x3c: /* l.cust5 */ 824bbe418f2SJia Liu LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5); 825bbe418f2SJia Liu break; 826bbe418f2SJia Liu 827bbe418f2SJia Liu case 0x3d: /* l.cust6 */ 828bbe418f2SJia Liu LOG_DIS("l.cust6\n"); 829bbe418f2SJia Liu break; 830bbe418f2SJia Liu 831bbe418f2SJia Liu case 0x3e: /* l.cust7 */ 832bbe418f2SJia Liu LOG_DIS("l.cust7\n"); 833bbe418f2SJia Liu break; 834bbe418f2SJia Liu 835bbe418f2SJia Liu case 0x3f: /* l.cust8 */ 836bbe418f2SJia Liu LOG_DIS("l.cust8\n"); 837bbe418f2SJia Liu break; 838bbe418f2SJia Liu 839bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 840bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 841bbe418f2SJia Liu case 0x20: l.ld 842bbe418f2SJia Liu LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); 843bbe418f2SJia Liu check_ob64s(dc); 8445631e69cSRichard Henderson mop = MO_TEQ; 8455631e69cSRichard Henderson goto do_load; 846bbe418f2SJia Liu #endif*/ 847bbe418f2SJia Liu 848bbe418f2SJia Liu case 0x21: /* l.lwz */ 849bbe418f2SJia Liu LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); 8505631e69cSRichard Henderson mop = MO_TEUL; 8515631e69cSRichard Henderson goto do_load; 852bbe418f2SJia Liu 853bbe418f2SJia Liu case 0x22: /* l.lws */ 854bbe418f2SJia Liu LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); 8555631e69cSRichard Henderson mop = MO_TESL; 8565631e69cSRichard Henderson goto do_load; 857bbe418f2SJia Liu 858bbe418f2SJia Liu case 0x23: /* l.lbz */ 859bbe418f2SJia Liu LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); 8605631e69cSRichard Henderson mop = MO_UB; 8615631e69cSRichard Henderson goto do_load; 862bbe418f2SJia Liu 863bbe418f2SJia Liu case 0x24: /* l.lbs */ 864bbe418f2SJia Liu LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); 8655631e69cSRichard Henderson mop = MO_SB; 8665631e69cSRichard Henderson goto do_load; 867bbe418f2SJia Liu 868bbe418f2SJia Liu case 0x25: /* l.lhz */ 869bbe418f2SJia Liu LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); 8705631e69cSRichard Henderson mop = MO_TEUW; 8715631e69cSRichard Henderson goto do_load; 872bbe418f2SJia Liu 873bbe418f2SJia Liu case 0x26: /* l.lhs */ 874bbe418f2SJia Liu LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); 8755631e69cSRichard Henderson mop = MO_TESW; 8765631e69cSRichard Henderson goto do_load; 8775631e69cSRichard Henderson 8785631e69cSRichard Henderson do_load: 8796597c28dSRichard Henderson check_r0_write(rd); 8806597c28dSRichard Henderson t0 = tcg_temp_new(); 8816da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I16); 8825631e69cSRichard Henderson tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); 883bbe418f2SJia Liu tcg_temp_free(t0); 884bbe418f2SJia Liu break; 885bbe418f2SJia Liu 886bbe418f2SJia Liu case 0x27: /* l.addi */ 887bbe418f2SJia Liu LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); 8886597c28dSRichard Henderson check_r0_write(rd); 8899ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 8909ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], t0); 8919ecaa27eSRichard Henderson tcg_temp_free(t0); 892bbe418f2SJia Liu break; 893bbe418f2SJia Liu 894bbe418f2SJia Liu case 0x28: /* l.addic */ 895bbe418f2SJia Liu LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16); 8966597c28dSRichard Henderson check_r0_write(rd); 8979ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 8989ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], t0); 8999ecaa27eSRichard Henderson tcg_temp_free(t0); 900bbe418f2SJia Liu break; 901bbe418f2SJia Liu 902bbe418f2SJia Liu case 0x29: /* l.andi */ 9036da544a6SRichard Henderson LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16); 9046597c28dSRichard Henderson check_r0_write(rd); 9056da544a6SRichard Henderson tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16); 906bbe418f2SJia Liu break; 907bbe418f2SJia Liu 908bbe418f2SJia Liu case 0x2a: /* l.ori */ 9096da544a6SRichard Henderson LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16); 9106597c28dSRichard Henderson check_r0_write(rd); 9116da544a6SRichard Henderson tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16); 912bbe418f2SJia Liu break; 913bbe418f2SJia Liu 914bbe418f2SJia Liu case 0x2b: /* l.xori */ 915bbe418f2SJia Liu LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16); 9166597c28dSRichard Henderson check_r0_write(rd); 9176da544a6SRichard Henderson tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16); 918bbe418f2SJia Liu break; 919bbe418f2SJia Liu 920bbe418f2SJia Liu case 0x2c: /* l.muli */ 921bbe418f2SJia Liu LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16); 9226597c28dSRichard Henderson check_r0_write(rd); 9239ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 9249ecaa27eSRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], t0); 9259ecaa27eSRichard Henderson tcg_temp_free(t0); 926bbe418f2SJia Liu break; 927bbe418f2SJia Liu 928bbe418f2SJia Liu case 0x2d: /* l.mfspr */ 9296da544a6SRichard Henderson LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16); 9306597c28dSRichard Henderson check_r0_write(rd); 9314dd044c6SJia Liu { 9324dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 9334dd044c6SJia Liu return; 9344dd044c6SJia Liu #else 9356da544a6SRichard Henderson TCGv_i32 ti = tcg_const_i32(K16); 9364dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 9374dd044c6SJia Liu gen_illegal_exception(dc); 9384dd044c6SJia Liu return; 9394dd044c6SJia Liu } 9404dd044c6SJia Liu gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); 9414dd044c6SJia Liu tcg_temp_free_i32(ti); 9424dd044c6SJia Liu #endif 9434dd044c6SJia Liu } 944bbe418f2SJia Liu break; 945bbe418f2SJia Liu 946bbe418f2SJia Liu case 0x30: /* l.mtspr */ 9476da544a6SRichard Henderson LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11); 9484dd044c6SJia Liu { 9494dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 9504dd044c6SJia Liu return; 9514dd044c6SJia Liu #else 9526da544a6SRichard Henderson TCGv_i32 im = tcg_const_i32(K5_11); 9534dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 9544dd044c6SJia Liu gen_illegal_exception(dc); 9554dd044c6SJia Liu return; 9564dd044c6SJia Liu } 9574dd044c6SJia Liu gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); 9584dd044c6SJia Liu tcg_temp_free_i32(im); 9594dd044c6SJia Liu #endif 9604dd044c6SJia Liu } 961bbe418f2SJia Liu break; 962bbe418f2SJia Liu 963930c3d00SRichard Henderson case 0x33: /* l.swa */ 9646da544a6SRichard Henderson LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11); 9656597c28dSRichard Henderson gen_swa(dc, rb, cpu_R[ra], I5_11); 966930c3d00SRichard Henderson break; 967930c3d00SRichard Henderson 968bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 969bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 970bbe418f2SJia Liu case 0x34: l.sd 9716da544a6SRichard Henderson LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11); 972bbe418f2SJia Liu check_ob64s(dc); 9735631e69cSRichard Henderson mop = MO_TEQ; 9745631e69cSRichard Henderson goto do_store; 975bbe418f2SJia Liu #endif*/ 976bbe418f2SJia Liu 977bbe418f2SJia Liu case 0x35: /* l.sw */ 9786da544a6SRichard Henderson LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11); 9795631e69cSRichard Henderson mop = MO_TEUL; 9805631e69cSRichard Henderson goto do_store; 981bbe418f2SJia Liu 982bbe418f2SJia Liu case 0x36: /* l.sb */ 9836da544a6SRichard Henderson LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11); 9845631e69cSRichard Henderson mop = MO_UB; 9855631e69cSRichard Henderson goto do_store; 986bbe418f2SJia Liu 987bbe418f2SJia Liu case 0x37: /* l.sh */ 9886da544a6SRichard Henderson LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11); 9895631e69cSRichard Henderson mop = MO_TEUW; 9905631e69cSRichard Henderson goto do_store; 9915631e69cSRichard Henderson 9925631e69cSRichard Henderson do_store: 993bbe418f2SJia Liu { 994bbe418f2SJia Liu TCGv t0 = tcg_temp_new(); 9956da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I5_11); 9965631e69cSRichard Henderson tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); 997bbe418f2SJia Liu tcg_temp_free(t0); 998bbe418f2SJia Liu } 999bbe418f2SJia Liu break; 1000bbe418f2SJia Liu 1001bbe418f2SJia Liu default: 1002bbe418f2SJia Liu gen_illegal_exception(dc); 1003bbe418f2SJia Liu break; 1004bbe418f2SJia Liu } 1005bbe418f2SJia Liu } 1006bbe418f2SJia Liu 1007bbe418f2SJia Liu static void dec_mac(DisasContext *dc, uint32_t insn) 1008bbe418f2SJia Liu { 1009bbe418f2SJia Liu uint32_t op0; 1010bbe418f2SJia Liu uint32_t ra, rb; 1011bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 1012bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1013bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1014bbe418f2SJia Liu 1015bbe418f2SJia Liu switch (op0) { 1016bbe418f2SJia Liu case 0x0001: /* l.mac */ 1017bbe418f2SJia Liu LOG_DIS("l.mac r%d, r%d\n", ra, rb); 10186f7332baSRichard Henderson gen_mac(dc, cpu_R[ra], cpu_R[rb]); 1019bbe418f2SJia Liu break; 1020bbe418f2SJia Liu 1021bbe418f2SJia Liu case 0x0002: /* l.msb */ 1022bbe418f2SJia Liu LOG_DIS("l.msb r%d, r%d\n", ra, rb); 10236f7332baSRichard Henderson gen_msb(dc, cpu_R[ra], cpu_R[rb]); 1024bbe418f2SJia Liu break; 1025bbe418f2SJia Liu 1026cc5de49eSRichard Henderson case 0x0003: /* l.macu */ 1027cc5de49eSRichard Henderson LOG_DIS("l.macu r%d, r%d\n", ra, rb); 1028cc5de49eSRichard Henderson gen_macu(dc, cpu_R[ra], cpu_R[rb]); 1029cc5de49eSRichard Henderson break; 1030cc5de49eSRichard Henderson 1031cc5de49eSRichard Henderson case 0x0004: /* l.msbu */ 1032cc5de49eSRichard Henderson LOG_DIS("l.msbu r%d, r%d\n", ra, rb); 1033cc5de49eSRichard Henderson gen_msbu(dc, cpu_R[ra], cpu_R[rb]); 1034cc5de49eSRichard Henderson break; 1035cc5de49eSRichard Henderson 1036bbe418f2SJia Liu default: 1037bbe418f2SJia Liu gen_illegal_exception(dc); 1038bbe418f2SJia Liu break; 1039bbe418f2SJia Liu } 1040bbe418f2SJia Liu } 1041bbe418f2SJia Liu 1042bbe418f2SJia Liu static void dec_logic(DisasContext *dc, uint32_t insn) 1043bbe418f2SJia Liu { 1044bbe418f2SJia Liu uint32_t op0; 10456da544a6SRichard Henderson uint32_t rd, ra, L6, S6; 1046bbe418f2SJia Liu op0 = extract32(insn, 6, 2); 1047bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1048bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1049bbe418f2SJia Liu L6 = extract32(insn, 0, 6); 10506da544a6SRichard Henderson S6 = L6 & (TARGET_LONG_BITS - 1); 1051bbe418f2SJia Liu 10526597c28dSRichard Henderson check_r0_write(rd); 1053bbe418f2SJia Liu switch (op0) { 1054bbe418f2SJia Liu case 0x00: /* l.slli */ 1055bbe418f2SJia Liu LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6); 10566da544a6SRichard Henderson tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6); 1057bbe418f2SJia Liu break; 1058bbe418f2SJia Liu 1059bbe418f2SJia Liu case 0x01: /* l.srli */ 1060bbe418f2SJia Liu LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6); 10616da544a6SRichard Henderson tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6); 1062bbe418f2SJia Liu break; 1063bbe418f2SJia Liu 1064bbe418f2SJia Liu case 0x02: /* l.srai */ 1065bbe418f2SJia Liu LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6); 10666da544a6SRichard Henderson tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6); 10676da544a6SRichard Henderson break; 1068bbe418f2SJia Liu 1069bbe418f2SJia Liu case 0x03: /* l.rori */ 1070bbe418f2SJia Liu LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6); 10716da544a6SRichard Henderson tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6); 1072bbe418f2SJia Liu break; 1073bbe418f2SJia Liu 1074bbe418f2SJia Liu default: 1075bbe418f2SJia Liu gen_illegal_exception(dc); 1076bbe418f2SJia Liu break; 1077bbe418f2SJia Liu } 1078bbe418f2SJia Liu } 1079bbe418f2SJia Liu 1080bbe418f2SJia Liu static void dec_M(DisasContext *dc, uint32_t insn) 1081bbe418f2SJia Liu { 1082bbe418f2SJia Liu uint32_t op0; 1083bbe418f2SJia Liu uint32_t rd; 1084bbe418f2SJia Liu uint32_t K16; 1085bbe418f2SJia Liu op0 = extract32(insn, 16, 1); 1086bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1087bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1088bbe418f2SJia Liu 10896597c28dSRichard Henderson check_r0_write(rd); 1090bbe418f2SJia Liu switch (op0) { 1091bbe418f2SJia Liu case 0x0: /* l.movhi */ 1092bbe418f2SJia Liu LOG_DIS("l.movhi r%d, %d\n", rd, K16); 1093bbe418f2SJia Liu tcg_gen_movi_tl(cpu_R[rd], (K16 << 16)); 1094bbe418f2SJia Liu break; 1095bbe418f2SJia Liu 1096bbe418f2SJia Liu case 0x1: /* l.macrc */ 1097bbe418f2SJia Liu LOG_DIS("l.macrc r%d\n", rd); 10986f7332baSRichard Henderson tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac); 10996f7332baSRichard Henderson tcg_gen_movi_i64(cpu_mac, 0); 1100bbe418f2SJia Liu break; 1101bbe418f2SJia Liu 1102bbe418f2SJia Liu default: 1103bbe418f2SJia Liu gen_illegal_exception(dc); 1104bbe418f2SJia Liu break; 1105bbe418f2SJia Liu } 1106bbe418f2SJia Liu } 1107bbe418f2SJia Liu 1108bbe418f2SJia Liu static void dec_comp(DisasContext *dc, uint32_t insn) 1109bbe418f2SJia Liu { 1110bbe418f2SJia Liu uint32_t op0; 1111bbe418f2SJia Liu uint32_t ra, rb; 1112bbe418f2SJia Liu 1113bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1114bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1115bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1116bbe418f2SJia Liu 1117bbe418f2SJia Liu /* unsigned integers */ 1118bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); 1119bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); 1120bbe418f2SJia Liu 1121bbe418f2SJia Liu switch (op0) { 1122bbe418f2SJia Liu case 0x0: /* l.sfeq */ 1123bbe418f2SJia Liu LOG_DIS("l.sfeq r%d, r%d\n", ra, rb); 112484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1125bbe418f2SJia Liu break; 1126bbe418f2SJia Liu 1127bbe418f2SJia Liu case 0x1: /* l.sfne */ 1128bbe418f2SJia Liu LOG_DIS("l.sfne r%d, r%d\n", ra, rb); 112984775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1130bbe418f2SJia Liu break; 1131bbe418f2SJia Liu 1132bbe418f2SJia Liu case 0x2: /* l.sfgtu */ 1133bbe418f2SJia Liu LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb); 113484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1135bbe418f2SJia Liu break; 1136bbe418f2SJia Liu 1137bbe418f2SJia Liu case 0x3: /* l.sfgeu */ 1138bbe418f2SJia Liu LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb); 113984775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1140bbe418f2SJia Liu break; 1141bbe418f2SJia Liu 1142bbe418f2SJia Liu case 0x4: /* l.sfltu */ 1143bbe418f2SJia Liu LOG_DIS("l.sfltu r%d, r%d\n", ra, rb); 114484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1145bbe418f2SJia Liu break; 1146bbe418f2SJia Liu 1147bbe418f2SJia Liu case 0x5: /* l.sfleu */ 1148bbe418f2SJia Liu LOG_DIS("l.sfleu r%d, r%d\n", ra, rb); 114984775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1150bbe418f2SJia Liu break; 1151bbe418f2SJia Liu 1152bbe418f2SJia Liu case 0xa: /* l.sfgts */ 1153bbe418f2SJia Liu LOG_DIS("l.sfgts r%d, r%d\n", ra, rb); 115484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1155bbe418f2SJia Liu break; 1156bbe418f2SJia Liu 1157bbe418f2SJia Liu case 0xb: /* l.sfges */ 1158bbe418f2SJia Liu LOG_DIS("l.sfges r%d, r%d\n", ra, rb); 115984775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1160bbe418f2SJia Liu break; 1161bbe418f2SJia Liu 1162bbe418f2SJia Liu case 0xc: /* l.sflts */ 1163bbe418f2SJia Liu LOG_DIS("l.sflts r%d, r%d\n", ra, rb); 116484775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1165bbe418f2SJia Liu break; 1166bbe418f2SJia Liu 1167bbe418f2SJia Liu case 0xd: /* l.sfles */ 1168bbe418f2SJia Liu LOG_DIS("l.sfles r%d, r%d\n", ra, rb); 116984775c43SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); 1170bbe418f2SJia Liu break; 1171bbe418f2SJia Liu 1172bbe418f2SJia Liu default: 1173bbe418f2SJia Liu gen_illegal_exception(dc); 1174bbe418f2SJia Liu break; 1175bbe418f2SJia Liu } 1176bbe418f2SJia Liu } 1177bbe418f2SJia Liu 1178bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn) 1179bbe418f2SJia Liu { 11806da544a6SRichard Henderson uint32_t op0, ra; 11816da544a6SRichard Henderson int32_t I16; 1182bbe418f2SJia Liu 1183bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1184bbe418f2SJia Liu ra = extract32(insn, 16, 5); 11856da544a6SRichard Henderson I16 = sextract32(insn, 0, 16); 1186bbe418f2SJia Liu 1187bbe418f2SJia Liu switch (op0) { 1188bbe418f2SJia Liu case 0x0: /* l.sfeqi */ 1189bbe418f2SJia Liu LOG_DIS("l.sfeqi r%d, %d\n", ra, I16); 119084775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16); 1191bbe418f2SJia Liu break; 1192bbe418f2SJia Liu 1193bbe418f2SJia Liu case 0x1: /* l.sfnei */ 1194bbe418f2SJia Liu LOG_DIS("l.sfnei r%d, %d\n", ra, I16); 119584775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16); 1196bbe418f2SJia Liu break; 1197bbe418f2SJia Liu 1198bbe418f2SJia Liu case 0x2: /* l.sfgtui */ 1199bbe418f2SJia Liu LOG_DIS("l.sfgtui r%d, %d\n", ra, I16); 120084775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16); 1201bbe418f2SJia Liu break; 1202bbe418f2SJia Liu 1203bbe418f2SJia Liu case 0x3: /* l.sfgeui */ 1204bbe418f2SJia Liu LOG_DIS("l.sfgeui r%d, %d\n", ra, I16); 120584775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16); 1206bbe418f2SJia Liu break; 1207bbe418f2SJia Liu 1208bbe418f2SJia Liu case 0x4: /* l.sfltui */ 1209bbe418f2SJia Liu LOG_DIS("l.sfltui r%d, %d\n", ra, I16); 121084775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16); 1211bbe418f2SJia Liu break; 1212bbe418f2SJia Liu 1213bbe418f2SJia Liu case 0x5: /* l.sfleui */ 1214bbe418f2SJia Liu LOG_DIS("l.sfleui r%d, %d\n", ra, I16); 121584775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16); 1216bbe418f2SJia Liu break; 1217bbe418f2SJia Liu 1218bbe418f2SJia Liu case 0xa: /* l.sfgtsi */ 1219bbe418f2SJia Liu LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16); 122084775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16); 1221bbe418f2SJia Liu break; 1222bbe418f2SJia Liu 1223bbe418f2SJia Liu case 0xb: /* l.sfgesi */ 1224bbe418f2SJia Liu LOG_DIS("l.sfgesi r%d, %d\n", ra, I16); 122584775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16); 1226bbe418f2SJia Liu break; 1227bbe418f2SJia Liu 1228bbe418f2SJia Liu case 0xc: /* l.sfltsi */ 1229bbe418f2SJia Liu LOG_DIS("l.sfltsi r%d, %d\n", ra, I16); 123084775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16); 1231bbe418f2SJia Liu break; 1232bbe418f2SJia Liu 1233bbe418f2SJia Liu case 0xd: /* l.sflesi */ 1234bbe418f2SJia Liu LOG_DIS("l.sflesi r%d, %d\n", ra, I16); 123584775c43SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16); 1236bbe418f2SJia Liu break; 1237bbe418f2SJia Liu 1238bbe418f2SJia Liu default: 1239bbe418f2SJia Liu gen_illegal_exception(dc); 1240bbe418f2SJia Liu break; 1241bbe418f2SJia Liu } 1242bbe418f2SJia Liu } 1243bbe418f2SJia Liu 1244bbe418f2SJia Liu static void dec_sys(DisasContext *dc, uint32_t insn) 1245bbe418f2SJia Liu { 1246bbe418f2SJia Liu uint32_t op0; 1247bbe418f2SJia Liu uint32_t K16; 1248111ece51SRichard Henderson 12493d59b680SDavid Morrison op0 = extract32(insn, 16, 10); 1250bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1251bbe418f2SJia Liu 1252bbe418f2SJia Liu switch (op0) { 1253bbe418f2SJia Liu case 0x000: /* l.sys */ 1254bbe418f2SJia Liu LOG_DIS("l.sys %d\n", K16); 12551ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1256bbe418f2SJia Liu gen_exception(dc, EXCP_SYSCALL); 12571ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1258bbe418f2SJia Liu break; 1259bbe418f2SJia Liu 1260bbe418f2SJia Liu case 0x100: /* l.trap */ 1261bbe418f2SJia Liu LOG_DIS("l.trap %d\n", K16); 12621ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1263bbe418f2SJia Liu gen_exception(dc, EXCP_TRAP); 12641ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1265bbe418f2SJia Liu break; 1266bbe418f2SJia Liu 1267bbe418f2SJia Liu case 0x300: /* l.csync */ 1268bbe418f2SJia Liu LOG_DIS("l.csync\n"); 1269bbe418f2SJia Liu break; 1270bbe418f2SJia Liu 1271bbe418f2SJia Liu case 0x200: /* l.msync */ 1272bbe418f2SJia Liu LOG_DIS("l.msync\n"); 127324fc5c0fSRichard Henderson tcg_gen_mb(TCG_MO_ALL); 1274bbe418f2SJia Liu break; 1275bbe418f2SJia Liu 1276bbe418f2SJia Liu case 0x270: /* l.psync */ 1277bbe418f2SJia Liu LOG_DIS("l.psync\n"); 1278bbe418f2SJia Liu break; 1279bbe418f2SJia Liu 1280bbe418f2SJia Liu default: 1281bbe418f2SJia Liu gen_illegal_exception(dc); 1282bbe418f2SJia Liu break; 1283bbe418f2SJia Liu } 1284bbe418f2SJia Liu } 1285bbe418f2SJia Liu 1286bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn) 1287bbe418f2SJia Liu { 1288bbe418f2SJia Liu uint32_t op0; 1289bbe418f2SJia Liu uint32_t ra, rb, rd; 1290bbe418f2SJia Liu op0 = extract32(insn, 0, 8); 1291bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1292bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1293bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1294bbe418f2SJia Liu 1295bbe418f2SJia Liu switch (op0) { 1296bbe418f2SJia Liu case 0x00: /* lf.add.s */ 1297bbe418f2SJia Liu LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb); 12986597c28dSRichard Henderson check_r0_write(rd); 1299bbe418f2SJia Liu gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1300bbe418f2SJia Liu break; 1301bbe418f2SJia Liu 1302bbe418f2SJia Liu case 0x01: /* lf.sub.s */ 1303bbe418f2SJia Liu LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb); 13046597c28dSRichard Henderson check_r0_write(rd); 1305bbe418f2SJia Liu gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1306bbe418f2SJia Liu break; 1307bbe418f2SJia Liu 1308bbe418f2SJia Liu case 0x02: /* lf.mul.s */ 1309bbe418f2SJia Liu LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb); 13106597c28dSRichard Henderson check_r0_write(rd); 1311bbe418f2SJia Liu gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1312bbe418f2SJia Liu break; 1313bbe418f2SJia Liu 1314bbe418f2SJia Liu case 0x03: /* lf.div.s */ 1315bbe418f2SJia Liu LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb); 13166597c28dSRichard Henderson check_r0_write(rd); 1317bbe418f2SJia Liu gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1318bbe418f2SJia Liu break; 1319bbe418f2SJia Liu 1320bbe418f2SJia Liu case 0x04: /* lf.itof.s */ 1321bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 13226597c28dSRichard Henderson check_r0_write(rd); 1323bbe418f2SJia Liu gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]); 1324bbe418f2SJia Liu break; 1325bbe418f2SJia Liu 1326bbe418f2SJia Liu case 0x05: /* lf.ftoi.s */ 1327bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 13286597c28dSRichard Henderson check_r0_write(rd); 1329bbe418f2SJia Liu gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]); 1330bbe418f2SJia Liu break; 1331bbe418f2SJia Liu 1332bbe418f2SJia Liu case 0x06: /* lf.rem.s */ 1333bbe418f2SJia Liu LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb); 13346597c28dSRichard Henderson check_r0_write(rd); 1335bbe418f2SJia Liu gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1336bbe418f2SJia Liu break; 1337bbe418f2SJia Liu 1338bbe418f2SJia Liu case 0x07: /* lf.madd.s */ 1339bbe418f2SJia Liu LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb); 13406597c28dSRichard Henderson check_r0_write(rd); 1341762e22edSRichard Henderson gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd], 1342762e22edSRichard Henderson cpu_R[ra], cpu_R[rb]); 1343bbe418f2SJia Liu break; 1344bbe418f2SJia Liu 1345bbe418f2SJia Liu case 0x08: /* lf.sfeq.s */ 1346bbe418f2SJia Liu LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb); 134784775c43SRichard Henderson gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1348bbe418f2SJia Liu break; 1349bbe418f2SJia Liu 1350bbe418f2SJia Liu case 0x09: /* lf.sfne.s */ 1351bbe418f2SJia Liu LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb); 135284775c43SRichard Henderson gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1353bbe418f2SJia Liu break; 1354bbe418f2SJia Liu 1355bbe418f2SJia Liu case 0x0a: /* lf.sfgt.s */ 1356bbe418f2SJia Liu LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb); 135784775c43SRichard Henderson gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1358bbe418f2SJia Liu break; 1359bbe418f2SJia Liu 1360bbe418f2SJia Liu case 0x0b: /* lf.sfge.s */ 1361bbe418f2SJia Liu LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb); 136284775c43SRichard Henderson gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1363bbe418f2SJia Liu break; 1364bbe418f2SJia Liu 1365bbe418f2SJia Liu case 0x0c: /* lf.sflt.s */ 1366bbe418f2SJia Liu LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb); 136784775c43SRichard Henderson gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1368bbe418f2SJia Liu break; 1369bbe418f2SJia Liu 1370bbe418f2SJia Liu case 0x0d: /* lf.sfle.s */ 1371bbe418f2SJia Liu LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb); 137284775c43SRichard Henderson gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1373bbe418f2SJia Liu break; 1374bbe418f2SJia Liu 1375bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 1376bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 1377bbe418f2SJia Liu case 0x10: lf.add.d 1378bbe418f2SJia Liu LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb); 1379bbe418f2SJia Liu check_of64s(dc); 13806597c28dSRichard Henderson check_r0_write(rd); 1381bbe418f2SJia Liu gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1382bbe418f2SJia Liu break; 1383bbe418f2SJia Liu 1384bbe418f2SJia Liu case 0x11: lf.sub.d 1385bbe418f2SJia Liu LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb); 1386bbe418f2SJia Liu check_of64s(dc); 13876597c28dSRichard Henderson check_r0_write(rd); 1388bbe418f2SJia Liu gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1389bbe418f2SJia Liu break; 1390bbe418f2SJia Liu 1391bbe418f2SJia Liu case 0x12: lf.mul.d 1392bbe418f2SJia Liu LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb); 1393bbe418f2SJia Liu check_of64s(dc); 13946597c28dSRichard Henderson check_r0_write(rd); 1395bbe418f2SJia Liu gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1396bbe418f2SJia Liu break; 1397bbe418f2SJia Liu 1398bbe418f2SJia Liu case 0x13: lf.div.d 1399bbe418f2SJia Liu LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb); 1400bbe418f2SJia Liu check_of64s(dc); 14016597c28dSRichard Henderson check_r0_write(rd); 1402bbe418f2SJia Liu gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1403bbe418f2SJia Liu break; 1404bbe418f2SJia Liu 1405bbe418f2SJia Liu case 0x14: lf.itof.d 1406bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1407bbe418f2SJia Liu check_of64s(dc); 14086597c28dSRichard Henderson check_r0_write(rd); 1409bbe418f2SJia Liu gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]); 1410bbe418f2SJia Liu break; 1411bbe418f2SJia Liu 1412bbe418f2SJia Liu case 0x15: lf.ftoi.d 1413bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1414bbe418f2SJia Liu check_of64s(dc); 14156597c28dSRichard Henderson check_r0_write(rd); 1416bbe418f2SJia Liu gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]); 1417bbe418f2SJia Liu break; 1418bbe418f2SJia Liu 1419bbe418f2SJia Liu case 0x16: lf.rem.d 1420bbe418f2SJia Liu LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb); 1421bbe418f2SJia Liu check_of64s(dc); 14226597c28dSRichard Henderson check_r0_write(rd); 1423bbe418f2SJia Liu gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1424bbe418f2SJia Liu break; 1425bbe418f2SJia Liu 1426bbe418f2SJia Liu case 0x17: lf.madd.d 1427bbe418f2SJia Liu LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); 1428bbe418f2SJia Liu check_of64s(dc); 14296597c28dSRichard Henderson check_r0_write(rd); 1430762e22edSRichard Henderson gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd], 1431762e22edSRichard Henderson cpu_R[ra], cpu_R[rb]); 1432bbe418f2SJia Liu break; 1433bbe418f2SJia Liu 1434bbe418f2SJia Liu case 0x18: lf.sfeq.d 1435bbe418f2SJia Liu LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); 1436bbe418f2SJia Liu check_of64s(dc); 143784775c43SRichard Henderson gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1438bbe418f2SJia Liu break; 1439bbe418f2SJia Liu 1440bbe418f2SJia Liu case 0x1a: lf.sfgt.d 1441bbe418f2SJia Liu LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); 1442bbe418f2SJia Liu check_of64s(dc); 144384775c43SRichard Henderson gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1444bbe418f2SJia Liu break; 1445bbe418f2SJia Liu 1446bbe418f2SJia Liu case 0x1b: lf.sfge.d 1447bbe418f2SJia Liu LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); 1448bbe418f2SJia Liu check_of64s(dc); 144984775c43SRichard Henderson gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1450bbe418f2SJia Liu break; 1451bbe418f2SJia Liu 1452bbe418f2SJia Liu case 0x19: lf.sfne.d 1453bbe418f2SJia Liu LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); 1454bbe418f2SJia Liu check_of64s(dc); 145584775c43SRichard Henderson gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1456bbe418f2SJia Liu break; 1457bbe418f2SJia Liu 1458bbe418f2SJia Liu case 0x1c: lf.sflt.d 1459bbe418f2SJia Liu LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); 1460bbe418f2SJia Liu check_of64s(dc); 146184775c43SRichard Henderson gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1462bbe418f2SJia Liu break; 1463bbe418f2SJia Liu 1464bbe418f2SJia Liu case 0x1d: lf.sfle.d 1465bbe418f2SJia Liu LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); 1466bbe418f2SJia Liu check_of64s(dc); 146784775c43SRichard Henderson gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); 1468bbe418f2SJia Liu break; 1469bbe418f2SJia Liu #endif*/ 1470bbe418f2SJia Liu 1471bbe418f2SJia Liu default: 1472bbe418f2SJia Liu gen_illegal_exception(dc); 1473bbe418f2SJia Liu break; 1474bbe418f2SJia Liu } 1475bbe418f2SJia Liu } 1476bbe418f2SJia Liu 1477bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) 1478bbe418f2SJia Liu { 1479bbe418f2SJia Liu uint32_t op0; 1480bbe418f2SJia Liu uint32_t insn; 14811ffa4bceSEmilio G. Cota insn = cpu_ldl_code(&cpu->env, dc->base.pc_next); 1482bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 1483bbe418f2SJia Liu 1484bbe418f2SJia Liu switch (op0) { 1485bbe418f2SJia Liu case 0x06: 1486bbe418f2SJia Liu dec_M(dc, insn); 1487bbe418f2SJia Liu break; 1488bbe418f2SJia Liu 1489bbe418f2SJia Liu case 0x08: 1490bbe418f2SJia Liu dec_sys(dc, insn); 1491bbe418f2SJia Liu break; 1492bbe418f2SJia Liu 1493bbe418f2SJia Liu case 0x2e: 1494bbe418f2SJia Liu dec_logic(dc, insn); 1495bbe418f2SJia Liu break; 1496bbe418f2SJia Liu 1497bbe418f2SJia Liu case 0x2f: 1498bbe418f2SJia Liu dec_compi(dc, insn); 1499bbe418f2SJia Liu break; 1500bbe418f2SJia Liu 1501bbe418f2SJia Liu case 0x31: 1502bbe418f2SJia Liu dec_mac(dc, insn); 1503bbe418f2SJia Liu break; 1504bbe418f2SJia Liu 1505bbe418f2SJia Liu case 0x32: 1506bbe418f2SJia Liu dec_float(dc, insn); 1507bbe418f2SJia Liu break; 1508bbe418f2SJia Liu 1509bbe418f2SJia Liu case 0x38: 1510bbe418f2SJia Liu dec_calc(dc, insn); 1511bbe418f2SJia Liu break; 1512bbe418f2SJia Liu 1513bbe418f2SJia Liu case 0x39: 1514bbe418f2SJia Liu dec_comp(dc, insn); 1515bbe418f2SJia Liu break; 1516bbe418f2SJia Liu 1517bbe418f2SJia Liu default: 1518bbe418f2SJia Liu dec_misc(dc, insn); 1519bbe418f2SJia Liu break; 1520bbe418f2SJia Liu } 1521bbe418f2SJia Liu } 1522bbe418f2SJia Liu 1523*a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs) 1524e67db06eSJia Liu { 1525*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcb, DisasContext, base); 15269c489ea6SLluís Vilanova CPUOpenRISCState *env = cs->env_ptr; 1527*a4fd3ec3SEmilio G. Cota int bound; 1528bbe418f2SJia Liu 1529*a4fd3ec3SEmilio G. Cota dc->mem_idx = cpu_mmu_index(env, false); 15301ffa4bceSEmilio G. Cota dc->tb_flags = dc->base.tb->flags; 1531a01deb36SRichard Henderson dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0; 1532*a4fd3ec3SEmilio G. Cota bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4; 1533*a4fd3ec3SEmilio G. Cota dc->base.max_insns = MIN(dc->base.max_insns, bound); 1534190ce7fbSRichard Henderson } 1535bbe418f2SJia Liu 1536*a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs) 1537*a4fd3ec3SEmilio G. Cota { 1538*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(db, DisasContext, base); 1539bbe418f2SJia Liu 15406597c28dSRichard Henderson /* Allow the TCG optimizer to see that R0 == 0, 15416597c28dSRichard Henderson when it's true, which is the common case. */ 15426597c28dSRichard Henderson if (dc->tb_flags & TB_FLAGS_R0_0) { 15436597c28dSRichard Henderson cpu_R[0] = tcg_const_tl(0); 15446597c28dSRichard Henderson } else { 15456597c28dSRichard Henderson cpu_R[0] = cpu_R0; 15466597c28dSRichard Henderson } 1547*a4fd3ec3SEmilio G. Cota } 15486597c28dSRichard Henderson 1549*a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 1550*a4fd3ec3SEmilio G. Cota { 1551*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1552*a4fd3ec3SEmilio G. Cota 15531ffa4bceSEmilio G. Cota tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0) 1554*a4fd3ec3SEmilio G. Cota | (dc->base.num_insns > 1 ? 2 : 0)); 1555*a4fd3ec3SEmilio G. Cota } 1556bbe418f2SJia Liu 1557*a4fd3ec3SEmilio G. Cota static bool openrisc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 1558*a4fd3ec3SEmilio G. Cota const CPUBreakpoint *bp) 1559*a4fd3ec3SEmilio G. Cota { 1560*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1561*a4fd3ec3SEmilio G. Cota 15621ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1563b933066aSRichard Henderson gen_exception(dc, EXCP_DEBUG); 15641ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1565522a0d4eSRichard Henderson /* The address covered by the breakpoint must be included in 1566522a0d4eSRichard Henderson [tb->pc, tb->pc + tb->size) in order to for it to be 1567522a0d4eSRichard Henderson properly cleared -- thus we increment the PC here so that 1568522a0d4eSRichard Henderson the logic setting tb->size below does the right thing. */ 15691ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 1570*a4fd3ec3SEmilio G. Cota return true; 1571b933066aSRichard Henderson } 1572b933066aSRichard Henderson 1573*a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 1574*a4fd3ec3SEmilio G. Cota { 1575*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1576*a4fd3ec3SEmilio G. Cota OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1577*a4fd3ec3SEmilio G. Cota 1578bbe418f2SJia Liu disas_openrisc_insn(dc, cpu); 15791ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 158024c32852SRichard Henderson 1581bbe418f2SJia Liu /* delay slot */ 1582bbe418f2SJia Liu if (dc->delayed_branch) { 1583bbe418f2SJia Liu dc->delayed_branch--; 1584bbe418f2SJia Liu if (!dc->delayed_branch) { 1585bbe418f2SJia Liu tcg_gen_mov_tl(cpu_pc, jmp_pc); 158624c32852SRichard Henderson tcg_gen_discard_tl(jmp_pc); 15871ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_UPDATE; 1588*a4fd3ec3SEmilio G. Cota return; 1589bbe418f2SJia Liu } 1590bbe418f2SJia Liu } 1591*a4fd3ec3SEmilio G. Cota } 1592bbe418f2SJia Liu 1593*a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 1594*a4fd3ec3SEmilio G. Cota { 1595*a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 159624c32852SRichard Henderson 1597a01deb36SRichard Henderson if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) { 1598a01deb36SRichard Henderson tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0); 1599a01deb36SRichard Henderson } 1600a01deb36SRichard Henderson 16011ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4); 16021ffa4bceSEmilio G. Cota if (dc->base.is_jmp == DISAS_NEXT) { 16031ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_UPDATE; 16041ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1605bbe418f2SJia Liu } 16061ffa4bceSEmilio G. Cota if (unlikely(dc->base.singlestep_enabled)) { 1607bbe418f2SJia Liu gen_exception(dc, EXCP_DEBUG); 1608bbe418f2SJia Liu } else { 16091ffa4bceSEmilio G. Cota switch (dc->base.is_jmp) { 1610*a4fd3ec3SEmilio G. Cota case DISAS_TOO_MANY: 16111ffa4bceSEmilio G. Cota gen_goto_tb(dc, 0, dc->base.pc_next); 1612bbe418f2SJia Liu break; 16131ffa4bceSEmilio G. Cota case DISAS_NORETURN: 1614bbe418f2SJia Liu case DISAS_JUMP: 16151ffa4bceSEmilio G. Cota case DISAS_TB_JUMP: 1616bbe418f2SJia Liu break; 1617bbe418f2SJia Liu case DISAS_UPDATE: 1618bbe418f2SJia Liu /* indicate that the hash table must be used 1619bbe418f2SJia Liu to find the next TB */ 1620bbe418f2SJia Liu tcg_gen_exit_tb(0); 1621bbe418f2SJia Liu break; 1622*a4fd3ec3SEmilio G. Cota default: 1623*a4fd3ec3SEmilio G. Cota g_assert_not_reached(); 1624*a4fd3ec3SEmilio G. Cota } 1625bbe418f2SJia Liu } 1626bbe418f2SJia Liu } 1627bbe418f2SJia Liu 1628*a4fd3ec3SEmilio G. Cota static void openrisc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 1629*a4fd3ec3SEmilio G. Cota { 1630*a4fd3ec3SEmilio G. Cota DisasContext *s = container_of(dcbase, DisasContext, base); 16310a7df5daSRichard Henderson 1632*a4fd3ec3SEmilio G. Cota qemu_log("IN: %s\n", lookup_symbol(s->base.pc_first)); 1633*a4fd3ec3SEmilio G. Cota log_target_disas(cs, s->base.pc_first, s->base.tb->size); 1634bbe418f2SJia Liu } 1635*a4fd3ec3SEmilio G. Cota 1636*a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = { 1637*a4fd3ec3SEmilio G. Cota .init_disas_context = openrisc_tr_init_disas_context, 1638*a4fd3ec3SEmilio G. Cota .tb_start = openrisc_tr_tb_start, 1639*a4fd3ec3SEmilio G. Cota .insn_start = openrisc_tr_insn_start, 1640*a4fd3ec3SEmilio G. Cota .breakpoint_check = openrisc_tr_breakpoint_check, 1641*a4fd3ec3SEmilio G. Cota .translate_insn = openrisc_tr_translate_insn, 1642*a4fd3ec3SEmilio G. Cota .tb_stop = openrisc_tr_tb_stop, 1643*a4fd3ec3SEmilio G. Cota .disas_log = openrisc_tr_disas_log, 1644*a4fd3ec3SEmilio G. Cota }; 1645*a4fd3ec3SEmilio G. Cota 1646*a4fd3ec3SEmilio G. Cota void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) 1647*a4fd3ec3SEmilio G. Cota { 1648*a4fd3ec3SEmilio G. Cota DisasContext ctx; 1649*a4fd3ec3SEmilio G. Cota 1650*a4fd3ec3SEmilio G. Cota translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb); 1651e67db06eSJia Liu } 1652e67db06eSJia Liu 1653878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f, 1654e67db06eSJia Liu fprintf_function cpu_fprintf, 1655e67db06eSJia Liu int flags) 1656e67db06eSJia Liu { 1657878096eeSAndreas Färber OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1658878096eeSAndreas Färber CPUOpenRISCState *env = &cpu->env; 1659e67db06eSJia Liu int i; 1660878096eeSAndreas Färber 1661e67db06eSJia Liu cpu_fprintf(f, "PC=%08x\n", env->pc); 1662e67db06eSJia Liu for (i = 0; i < 32; ++i) { 1663d89e71e8SStafford Horne cpu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i), 1664e67db06eSJia Liu (i % 4) == 3 ? '\n' : ' '); 1665e67db06eSJia Liu } 1666e67db06eSJia Liu } 1667e67db06eSJia Liu 1668e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1669bad729e2SRichard Henderson target_ulong *data) 1670e67db06eSJia Liu { 1671bad729e2SRichard Henderson env->pc = data[0]; 1672a01deb36SRichard Henderson env->dflag = data[1] & 1; 1673a01deb36SRichard Henderson if (data[1] & 2) { 167424c32852SRichard Henderson env->ppc = env->pc - 4; 167524c32852SRichard Henderson } 1676e67db06eSJia Liu } 1677