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. */ 135bbe418f2SJia Liu if (dc->tb_flags != dc->synced_flags) { 136bbe418f2SJia Liu tcg_gen_movi_tl(env_flags, dc->tb_flags); 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 250*9ecaa27eSRichard Henderson static void gen_ove_cy(DisasContext *dc, TCGv cy) 251*9ecaa27eSRichard Henderson { 252*9ecaa27eSRichard Henderson gen_helper_ove(cpu_env, cy); 253*9ecaa27eSRichard Henderson } 254*9ecaa27eSRichard Henderson 255*9ecaa27eSRichard Henderson static void gen_ove_ov(DisasContext *dc, TCGv ov) 256*9ecaa27eSRichard Henderson { 257*9ecaa27eSRichard Henderson gen_helper_ove(cpu_env, ov); 258*9ecaa27eSRichard Henderson } 259*9ecaa27eSRichard Henderson 260*9ecaa27eSRichard Henderson static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov) 261*9ecaa27eSRichard Henderson { 262*9ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 263*9ecaa27eSRichard Henderson tcg_gen_or_tl(t0, cy, ov); 264*9ecaa27eSRichard Henderson gen_helper_ove(cpu_env, t0); 265*9ecaa27eSRichard Henderson tcg_temp_free(t0); 266*9ecaa27eSRichard Henderson } 267*9ecaa27eSRichard Henderson 268*9ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 269*9ecaa27eSRichard Henderson { 270*9ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 271*9ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 272*9ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 273*9ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 274*9ecaa27eSRichard Henderson 275*9ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0); 276*9ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, srca, srcb); 277*9ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 278*9ecaa27eSRichard Henderson tcg_gen_andc_tl(sr_ov, t0, sr_ov); 279*9ecaa27eSRichard Henderson tcg_temp_free(t0); 280*9ecaa27eSRichard Henderson 281*9ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 282*9ecaa27eSRichard Henderson tcg_temp_free(res); 283*9ecaa27eSRichard Henderson 284*9ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 285*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 286*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 287*9ecaa27eSRichard Henderson 288*9ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 289*9ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 290*9ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 291*9ecaa27eSRichard Henderson } 292*9ecaa27eSRichard Henderson 293*9ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 294*9ecaa27eSRichard Henderson { 295*9ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 296*9ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 297*9ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 298*9ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 299*9ecaa27eSRichard Henderson 300*9ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY)); 301*9ecaa27eSRichard Henderson tcg_gen_andi_tl(sr_cy, sr_cy, 1); 302*9ecaa27eSRichard Henderson 303*9ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0); 304*9ecaa27eSRichard Henderson tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0); 305*9ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, srca, srcb); 306*9ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 307*9ecaa27eSRichard Henderson tcg_gen_andc_tl(sr_ov, t0, sr_ov); 308*9ecaa27eSRichard Henderson tcg_temp_free(t0); 309*9ecaa27eSRichard Henderson 310*9ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 311*9ecaa27eSRichard Henderson tcg_temp_free(res); 312*9ecaa27eSRichard Henderson 313*9ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 314*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 315*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 316*9ecaa27eSRichard Henderson 317*9ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 318*9ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 319*9ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 320*9ecaa27eSRichard Henderson } 321*9ecaa27eSRichard Henderson 322*9ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 323*9ecaa27eSRichard Henderson { 324*9ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 325*9ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 326*9ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 327*9ecaa27eSRichard Henderson 328*9ecaa27eSRichard Henderson tcg_gen_sub_tl(res, srca, srcb); 329*9ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_cy, srca, srcb); 330*9ecaa27eSRichard Henderson tcg_gen_xor_tl(sr_ov, res, srcb); 331*9ecaa27eSRichard Henderson tcg_gen_and_tl(sr_ov, sr_ov, sr_cy); 332*9ecaa27eSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb); 333*9ecaa27eSRichard Henderson 334*9ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 335*9ecaa27eSRichard Henderson tcg_temp_free(res); 336*9ecaa27eSRichard Henderson 337*9ecaa27eSRichard Henderson tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1); 338*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 339*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 340*9ecaa27eSRichard Henderson 341*9ecaa27eSRichard Henderson gen_ove_cyov(dc, sr_ov, sr_cy); 342*9ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 343*9ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 344*9ecaa27eSRichard Henderson } 345*9ecaa27eSRichard Henderson 346*9ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 347*9ecaa27eSRichard Henderson { 348*9ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 349*9ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 350*9ecaa27eSRichard Henderson 351*9ecaa27eSRichard Henderson tcg_gen_muls2_tl(dest, sr_ov, srca, srcb); 352*9ecaa27eSRichard Henderson tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1); 353*9ecaa27eSRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0); 354*9ecaa27eSRichard Henderson tcg_temp_free(t0); 355*9ecaa27eSRichard Henderson 356*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 357*9ecaa27eSRichard Henderson 358*9ecaa27eSRichard Henderson gen_ove_ov(dc, sr_ov); 359*9ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 360*9ecaa27eSRichard Henderson } 361*9ecaa27eSRichard Henderson 362*9ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 363*9ecaa27eSRichard Henderson { 364*9ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 365*9ecaa27eSRichard Henderson 366*9ecaa27eSRichard Henderson tcg_gen_muls2_tl(dest, sr_cy, srca, srcb); 367*9ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0); 368*9ecaa27eSRichard Henderson 369*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 370*9ecaa27eSRichard Henderson 371*9ecaa27eSRichard Henderson gen_ove_cy(dc, sr_cy); 372*9ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 373*9ecaa27eSRichard Henderson } 374*9ecaa27eSRichard Henderson 375*9ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 376*9ecaa27eSRichard Henderson { 377*9ecaa27eSRichard Henderson TCGv sr_ov = tcg_temp_new(); 378*9ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 379*9ecaa27eSRichard Henderson 380*9ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0); 381*9ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 382*9ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 383*9ecaa27eSRichard Henderson tcg_gen_or_tl(t0, srcb, sr_ov); 384*9ecaa27eSRichard Henderson tcg_gen_div_tl(dest, srca, t0); 385*9ecaa27eSRichard Henderson tcg_temp_free(t0); 386*9ecaa27eSRichard Henderson 387*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); 388*9ecaa27eSRichard Henderson 389*9ecaa27eSRichard Henderson gen_ove_ov(dc, sr_ov); 390*9ecaa27eSRichard Henderson tcg_temp_free(sr_ov); 391*9ecaa27eSRichard Henderson } 392*9ecaa27eSRichard Henderson 393*9ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 394*9ecaa27eSRichard Henderson { 395*9ecaa27eSRichard Henderson TCGv sr_cy = tcg_temp_new(); 396*9ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 397*9ecaa27eSRichard Henderson 398*9ecaa27eSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0); 399*9ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 400*9ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 401*9ecaa27eSRichard Henderson tcg_gen_or_tl(t0, srcb, sr_cy); 402*9ecaa27eSRichard Henderson tcg_gen_divu_tl(dest, srca, t0); 403*9ecaa27eSRichard Henderson tcg_temp_free(t0); 404*9ecaa27eSRichard Henderson 405*9ecaa27eSRichard Henderson tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1); 406*9ecaa27eSRichard Henderson 407*9ecaa27eSRichard Henderson gen_ove_cy(dc, sr_cy); 408*9ecaa27eSRichard Henderson tcg_temp_free(sr_cy); 409*9ecaa27eSRichard Henderson } 410da1d7759SSebastian Macke 411930c3d00SRichard Henderson static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs) 412930c3d00SRichard Henderson { 413930c3d00SRichard Henderson TCGv ea = tcg_temp_new(); 414930c3d00SRichard Henderson 415930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 416930c3d00SRichard Henderson tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL); 417930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_addr, ea); 418930c3d00SRichard Henderson tcg_gen_mov_tl(cpu_lock_value, rd); 419930c3d00SRichard Henderson tcg_temp_free(ea); 420930c3d00SRichard Henderson } 421930c3d00SRichard Henderson 422930c3d00SRichard Henderson static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs) 423930c3d00SRichard Henderson { 424930c3d00SRichard Henderson TCGv ea, val; 425930c3d00SRichard Henderson TCGLabel *lab_fail, *lab_done; 426930c3d00SRichard Henderson 427930c3d00SRichard Henderson ea = tcg_temp_new(); 428930c3d00SRichard Henderson tcg_gen_addi_tl(ea, ra, ofs); 429930c3d00SRichard Henderson 430930c3d00SRichard Henderson lab_fail = gen_new_label(); 431930c3d00SRichard Henderson lab_done = gen_new_label(); 432930c3d00SRichard Henderson tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail); 433930c3d00SRichard Henderson tcg_temp_free(ea); 434930c3d00SRichard Henderson 435930c3d00SRichard Henderson val = tcg_temp_new(); 436930c3d00SRichard Henderson tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value, 437930c3d00SRichard Henderson rb, dc->mem_idx, MO_TEUL); 438930c3d00SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, val, cpu_lock_value); 439930c3d00SRichard Henderson tcg_temp_free(val); 440930c3d00SRichard Henderson 441930c3d00SRichard Henderson tcg_gen_br(lab_done); 442930c3d00SRichard Henderson 443930c3d00SRichard Henderson gen_set_label(lab_fail); 444930c3d00SRichard Henderson tcg_gen_movi_tl(env_btaken, 0); 445930c3d00SRichard Henderson 446930c3d00SRichard Henderson gen_set_label(lab_done); 447930c3d00SRichard Henderson tcg_gen_movi_tl(cpu_lock_addr, -1); 448930c3d00SRichard Henderson wb_SR_F(); 449930c3d00SRichard Henderson } 450930c3d00SRichard Henderson 451bbe418f2SJia Liu static void dec_calc(DisasContext *dc, uint32_t insn) 452bbe418f2SJia Liu { 453bbe418f2SJia Liu uint32_t op0, op1, op2; 454bbe418f2SJia Liu uint32_t ra, rb, rd; 455bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 456bbe418f2SJia Liu op1 = extract32(insn, 8, 2); 457bbe418f2SJia Liu op2 = extract32(insn, 6, 2); 458bbe418f2SJia Liu ra = extract32(insn, 16, 5); 459bbe418f2SJia Liu rb = extract32(insn, 11, 5); 460bbe418f2SJia Liu rd = extract32(insn, 21, 5); 461bbe418f2SJia Liu 462bbe418f2SJia Liu switch (op0) { 463bbe418f2SJia Liu case 0x0000: 464bbe418f2SJia Liu switch (op1) { 465bbe418f2SJia Liu case 0x00: /* l.add */ 466bbe418f2SJia Liu LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); 467*9ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 468bbe418f2SJia Liu break; 469bbe418f2SJia Liu default: 470bbe418f2SJia Liu gen_illegal_exception(dc); 471bbe418f2SJia Liu break; 472bbe418f2SJia Liu } 473bbe418f2SJia Liu break; 474bbe418f2SJia Liu 475bbe418f2SJia Liu case 0x0001: /* l.addc */ 476bbe418f2SJia Liu switch (op1) { 477bbe418f2SJia Liu case 0x00: 478bbe418f2SJia Liu LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); 479*9ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 480bbe418f2SJia Liu break; 481bbe418f2SJia Liu default: 482bbe418f2SJia Liu gen_illegal_exception(dc); 483bbe418f2SJia Liu break; 484bbe418f2SJia Liu } 485bbe418f2SJia Liu break; 486bbe418f2SJia Liu 487bbe418f2SJia Liu case 0x0002: /* l.sub */ 488bbe418f2SJia Liu switch (op1) { 489bbe418f2SJia Liu case 0x00: 490bbe418f2SJia Liu LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); 491*9ecaa27eSRichard Henderson gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 492bbe418f2SJia Liu break; 493bbe418f2SJia Liu default: 494bbe418f2SJia Liu gen_illegal_exception(dc); 495bbe418f2SJia Liu break; 496bbe418f2SJia Liu } 497bbe418f2SJia Liu break; 498bbe418f2SJia Liu 499bbe418f2SJia Liu case 0x0003: /* l.and */ 500bbe418f2SJia Liu switch (op1) { 501bbe418f2SJia Liu case 0x00: 502bbe418f2SJia Liu LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); 503bbe418f2SJia Liu tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 504bbe418f2SJia Liu break; 505bbe418f2SJia Liu default: 506bbe418f2SJia Liu gen_illegal_exception(dc); 507bbe418f2SJia Liu break; 508bbe418f2SJia Liu } 509bbe418f2SJia Liu break; 510bbe418f2SJia Liu 511bbe418f2SJia Liu case 0x0004: /* l.or */ 512bbe418f2SJia Liu switch (op1) { 513bbe418f2SJia Liu case 0x00: 514bbe418f2SJia Liu LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); 515bbe418f2SJia Liu tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 516bbe418f2SJia Liu break; 517bbe418f2SJia Liu default: 518bbe418f2SJia Liu gen_illegal_exception(dc); 519bbe418f2SJia Liu break; 520bbe418f2SJia Liu } 521bbe418f2SJia Liu break; 522bbe418f2SJia Liu 523bbe418f2SJia Liu case 0x0005: 524bbe418f2SJia Liu switch (op1) { 525bbe418f2SJia Liu case 0x00: /* l.xor */ 526bbe418f2SJia Liu LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); 527bbe418f2SJia Liu tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 528bbe418f2SJia Liu break; 529bbe418f2SJia Liu default: 530bbe418f2SJia Liu gen_illegal_exception(dc); 531bbe418f2SJia Liu break; 532bbe418f2SJia Liu } 533bbe418f2SJia Liu break; 534bbe418f2SJia Liu 535bbe418f2SJia Liu case 0x0006: 536bbe418f2SJia Liu switch (op1) { 537bbe418f2SJia Liu case 0x03: /* l.mul */ 538bbe418f2SJia Liu LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb); 539*9ecaa27eSRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 540bbe418f2SJia Liu break; 541bbe418f2SJia Liu default: 542bbe418f2SJia Liu gen_illegal_exception(dc); 543bbe418f2SJia Liu break; 544bbe418f2SJia Liu } 545bbe418f2SJia Liu break; 546bbe418f2SJia Liu 547bbe418f2SJia Liu case 0x0009: 548bbe418f2SJia Liu switch (op1) { 549bbe418f2SJia Liu case 0x03: /* l.div */ 550bbe418f2SJia Liu LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb); 551*9ecaa27eSRichard Henderson gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 552bbe418f2SJia Liu break; 553bbe418f2SJia Liu 554bbe418f2SJia Liu default: 555bbe418f2SJia Liu gen_illegal_exception(dc); 556bbe418f2SJia Liu break; 557bbe418f2SJia Liu } 558bbe418f2SJia Liu break; 559bbe418f2SJia Liu 560bbe418f2SJia Liu case 0x000a: 561bbe418f2SJia Liu switch (op1) { 562bbe418f2SJia Liu case 0x03: /* l.divu */ 563bbe418f2SJia Liu LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb); 564*9ecaa27eSRichard Henderson gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 565bbe418f2SJia Liu break; 566bbe418f2SJia Liu 567bbe418f2SJia Liu default: 568bbe418f2SJia Liu gen_illegal_exception(dc); 569bbe418f2SJia Liu break; 570bbe418f2SJia Liu } 571bbe418f2SJia Liu break; 572bbe418f2SJia Liu 573bbe418f2SJia Liu case 0x000b: 574bbe418f2SJia Liu switch (op1) { 575bbe418f2SJia Liu case 0x03: /* l.mulu */ 576bbe418f2SJia Liu LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb); 577*9ecaa27eSRichard Henderson gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]); 578bbe418f2SJia Liu break; 579bbe418f2SJia Liu 580bbe418f2SJia Liu default: 581bbe418f2SJia Liu gen_illegal_exception(dc); 582bbe418f2SJia Liu break; 583bbe418f2SJia Liu } 584bbe418f2SJia Liu break; 585bbe418f2SJia Liu 586bbe418f2SJia Liu case 0x000e: 587bbe418f2SJia Liu switch (op1) { 588bbe418f2SJia Liu case 0x00: /* l.cmov */ 589bbe418f2SJia Liu LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); 590bbe418f2SJia Liu { 59142a268c2SRichard Henderson TCGLabel *lab = gen_new_label(); 592bbe418f2SJia Liu TCGv res = tcg_temp_local_new(); 593bbe418f2SJia Liu TCGv sr_f = tcg_temp_new(); 594bbe418f2SJia Liu tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); 595bbe418f2SJia Liu tcg_gen_mov_tl(res, cpu_R[rb]); 596bbe418f2SJia Liu tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab); 597bbe418f2SJia Liu tcg_gen_mov_tl(res, cpu_R[ra]); 598bbe418f2SJia Liu gen_set_label(lab); 599bbe418f2SJia Liu tcg_gen_mov_tl(cpu_R[rd], res); 600bbe418f2SJia Liu tcg_temp_free(sr_f); 601bbe418f2SJia Liu tcg_temp_free(res); 602bbe418f2SJia Liu } 603bbe418f2SJia Liu break; 604bbe418f2SJia Liu 605bbe418f2SJia Liu default: 606bbe418f2SJia Liu gen_illegal_exception(dc); 607bbe418f2SJia Liu break; 608bbe418f2SJia Liu } 609bbe418f2SJia Liu break; 610bbe418f2SJia Liu 611bbe418f2SJia Liu case 0x000f: 612bbe418f2SJia Liu switch (op1) { 613bbe418f2SJia Liu case 0x00: /* l.ff1 */ 614bbe418f2SJia Liu LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); 615555baef8SRichard Henderson tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1); 616555baef8SRichard Henderson tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1); 617bbe418f2SJia Liu break; 618bbe418f2SJia Liu case 0x01: /* l.fl1 */ 619bbe418f2SJia Liu LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); 620555baef8SRichard Henderson tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS); 621555baef8SRichard Henderson tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]); 622bbe418f2SJia Liu break; 623bbe418f2SJia Liu 624bbe418f2SJia Liu default: 625bbe418f2SJia Liu gen_illegal_exception(dc); 626bbe418f2SJia Liu break; 627bbe418f2SJia Liu } 628bbe418f2SJia Liu break; 629bbe418f2SJia Liu 630bbe418f2SJia Liu case 0x0008: 631bbe418f2SJia Liu switch (op1) { 632bbe418f2SJia Liu case 0x00: 633bbe418f2SJia Liu switch (op2) { 634bbe418f2SJia Liu case 0x00: /* l.sll */ 635bbe418f2SJia Liu LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb); 636bbe418f2SJia Liu tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 637bbe418f2SJia Liu break; 638bbe418f2SJia Liu case 0x01: /* l.srl */ 639bbe418f2SJia Liu LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb); 640bbe418f2SJia Liu tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 641bbe418f2SJia Liu break; 642bbe418f2SJia Liu case 0x02: /* l.sra */ 643bbe418f2SJia Liu LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb); 644bbe418f2SJia Liu tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 645bbe418f2SJia Liu break; 646bbe418f2SJia Liu case 0x03: /* l.ror */ 647bbe418f2SJia Liu LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb); 648bbe418f2SJia Liu tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 649bbe418f2SJia Liu break; 650bbe418f2SJia Liu 651bbe418f2SJia Liu default: 652bbe418f2SJia Liu gen_illegal_exception(dc); 653bbe418f2SJia Liu break; 654bbe418f2SJia Liu } 655bbe418f2SJia Liu break; 656bbe418f2SJia Liu 657bbe418f2SJia Liu default: 658bbe418f2SJia Liu gen_illegal_exception(dc); 659bbe418f2SJia Liu break; 660bbe418f2SJia Liu } 661bbe418f2SJia Liu break; 662bbe418f2SJia Liu 663bbe418f2SJia Liu case 0x000c: 664bbe418f2SJia Liu switch (op1) { 665bbe418f2SJia Liu case 0x00: 666bbe418f2SJia Liu switch (op2) { 667bbe418f2SJia Liu case 0x00: /* l.exths */ 668bbe418f2SJia Liu LOG_DIS("l.exths r%d, r%d\n", rd, ra); 669bbe418f2SJia Liu tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]); 670bbe418f2SJia Liu break; 671bbe418f2SJia Liu case 0x01: /* l.extbs */ 672bbe418f2SJia Liu LOG_DIS("l.extbs r%d, r%d\n", rd, ra); 673bbe418f2SJia Liu tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]); 674bbe418f2SJia Liu break; 675bbe418f2SJia Liu case 0x02: /* l.exthz */ 676bbe418f2SJia Liu LOG_DIS("l.exthz r%d, r%d\n", rd, ra); 677bbe418f2SJia Liu tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]); 678bbe418f2SJia Liu break; 679bbe418f2SJia Liu case 0x03: /* l.extbz */ 680bbe418f2SJia Liu LOG_DIS("l.extbz r%d, r%d\n", rd, ra); 681bbe418f2SJia Liu tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]); 682bbe418f2SJia Liu break; 683bbe418f2SJia Liu 684bbe418f2SJia Liu default: 685bbe418f2SJia Liu gen_illegal_exception(dc); 686bbe418f2SJia Liu break; 687bbe418f2SJia Liu } 688bbe418f2SJia Liu break; 689bbe418f2SJia Liu 690bbe418f2SJia Liu default: 691bbe418f2SJia Liu gen_illegal_exception(dc); 692bbe418f2SJia Liu break; 693bbe418f2SJia Liu } 694bbe418f2SJia Liu break; 695bbe418f2SJia Liu 696bbe418f2SJia Liu case 0x000d: 697bbe418f2SJia Liu switch (op1) { 698bbe418f2SJia Liu case 0x00: 699bbe418f2SJia Liu switch (op2) { 700bbe418f2SJia Liu case 0x00: /* l.extws */ 701bbe418f2SJia Liu LOG_DIS("l.extws r%d, r%d\n", rd, ra); 702bbe418f2SJia Liu tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]); 703bbe418f2SJia Liu break; 704bbe418f2SJia Liu case 0x01: /* l.extwz */ 705bbe418f2SJia Liu LOG_DIS("l.extwz r%d, r%d\n", rd, ra); 706bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]); 707bbe418f2SJia Liu break; 708bbe418f2SJia Liu 709bbe418f2SJia Liu default: 710bbe418f2SJia Liu gen_illegal_exception(dc); 711bbe418f2SJia Liu break; 712bbe418f2SJia Liu } 713bbe418f2SJia Liu break; 714bbe418f2SJia Liu 715bbe418f2SJia Liu default: 716bbe418f2SJia Liu gen_illegal_exception(dc); 717bbe418f2SJia Liu break; 718bbe418f2SJia Liu } 719bbe418f2SJia Liu break; 720bbe418f2SJia Liu 721bbe418f2SJia Liu default: 722bbe418f2SJia Liu gen_illegal_exception(dc); 723bbe418f2SJia Liu break; 724bbe418f2SJia Liu } 725bbe418f2SJia Liu } 726bbe418f2SJia Liu 727bbe418f2SJia Liu static void dec_misc(DisasContext *dc, uint32_t insn) 728bbe418f2SJia Liu { 729bbe418f2SJia Liu uint32_t op0, op1; 730bbe418f2SJia Liu uint32_t ra, rb, rd; 7316da544a6SRichard Henderson uint32_t L6, K5, K16, K5_11; 7326da544a6SRichard Henderson int32_t I16, I5_11, N26; 7335631e69cSRichard Henderson TCGMemOp mop; 734*9ecaa27eSRichard Henderson TCGv t0; 7355631e69cSRichard Henderson 736bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 737bbe418f2SJia Liu op1 = extract32(insn, 24, 2); 738bbe418f2SJia Liu ra = extract32(insn, 16, 5); 739bbe418f2SJia Liu rb = extract32(insn, 11, 5); 740bbe418f2SJia Liu rd = extract32(insn, 21, 5); 741bbe418f2SJia Liu L6 = extract32(insn, 5, 6); 742bbe418f2SJia Liu K5 = extract32(insn, 0, 5); 7436da544a6SRichard Henderson K16 = extract32(insn, 0, 16); 7446da544a6SRichard Henderson I16 = (int16_t)K16; 7456da544a6SRichard Henderson N26 = sextract32(insn, 0, 26); 7466da544a6SRichard Henderson K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11); 7476da544a6SRichard Henderson I5_11 = (int16_t)K5_11; 748bbe418f2SJia Liu 749bbe418f2SJia Liu switch (op0) { 750bbe418f2SJia Liu case 0x00: /* l.j */ 751bbe418f2SJia Liu LOG_DIS("l.j %d\n", N26); 752bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 753bbe418f2SJia Liu break; 754bbe418f2SJia Liu 755bbe418f2SJia Liu case 0x01: /* l.jal */ 756bbe418f2SJia Liu LOG_DIS("l.jal %d\n", N26); 757bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 758bbe418f2SJia Liu break; 759bbe418f2SJia Liu 760bbe418f2SJia Liu case 0x03: /* l.bnf */ 761bbe418f2SJia Liu LOG_DIS("l.bnf %d\n", N26); 762bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 763bbe418f2SJia Liu break; 764bbe418f2SJia Liu 765bbe418f2SJia Liu case 0x04: /* l.bf */ 766bbe418f2SJia Liu LOG_DIS("l.bf %d\n", N26); 767bbe418f2SJia Liu gen_jump(dc, N26, 0, op0); 768bbe418f2SJia Liu break; 769bbe418f2SJia Liu 770bbe418f2SJia Liu case 0x05: 771bbe418f2SJia Liu switch (op1) { 772bbe418f2SJia Liu case 0x01: /* l.nop */ 773bbe418f2SJia Liu LOG_DIS("l.nop %d\n", I16); 774bbe418f2SJia Liu break; 775bbe418f2SJia Liu 776bbe418f2SJia Liu default: 777bbe418f2SJia Liu gen_illegal_exception(dc); 778bbe418f2SJia Liu break; 779bbe418f2SJia Liu } 780bbe418f2SJia Liu break; 781bbe418f2SJia Liu 782bbe418f2SJia Liu case 0x11: /* l.jr */ 783bbe418f2SJia Liu LOG_DIS("l.jr r%d\n", rb); 784bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 785bbe418f2SJia Liu break; 786bbe418f2SJia Liu 787bbe418f2SJia Liu case 0x12: /* l.jalr */ 788bbe418f2SJia Liu LOG_DIS("l.jalr r%d\n", rb); 789bbe418f2SJia Liu gen_jump(dc, 0, rb, op0); 790bbe418f2SJia Liu break; 791bbe418f2SJia Liu 792bbe418f2SJia Liu case 0x13: /* l.maci */ 7936da544a6SRichard Henderson LOG_DIS("l.maci r%d, %d\n", ra, I16); 794bbe418f2SJia Liu { 795bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 796bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 797bbe418f2SJia Liu TCGv_i32 dst = tcg_temp_new_i32(); 7986da544a6SRichard Henderson TCGv ttmp = tcg_const_tl(I16); 799bbe418f2SJia Liu tcg_gen_mul_tl(dst, cpu_R[ra], ttmp); 800bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, dst); 801bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 802bbe418f2SJia Liu tcg_gen_add_i64(t2, t2, t1); 803ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 804bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 805ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 806bbe418f2SJia Liu tcg_temp_free_i32(dst); 807bbe418f2SJia Liu tcg_temp_free(ttmp); 808bbe418f2SJia Liu tcg_temp_free_i64(t1); 809bbe418f2SJia Liu tcg_temp_free_i64(t2); 810bbe418f2SJia Liu } 811bbe418f2SJia Liu break; 812bbe418f2SJia Liu 813bbe418f2SJia Liu case 0x09: /* l.rfe */ 814bbe418f2SJia Liu LOG_DIS("l.rfe\n"); 815bbe418f2SJia Liu { 816bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 817bbe418f2SJia Liu return; 818bbe418f2SJia Liu #else 819bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 820bbe418f2SJia Liu gen_illegal_exception(dc); 821bbe418f2SJia Liu return; 822bbe418f2SJia Liu } 823bbe418f2SJia Liu gen_helper_rfe(cpu_env); 824bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 825bbe418f2SJia Liu #endif 826bbe418f2SJia Liu } 827bbe418f2SJia Liu break; 828bbe418f2SJia Liu 829930c3d00SRichard Henderson case 0x1b: /* l.lwa */ 830930c3d00SRichard Henderson LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16); 831930c3d00SRichard Henderson gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16); 832930c3d00SRichard Henderson break; 833930c3d00SRichard Henderson 834bbe418f2SJia Liu case 0x1c: /* l.cust1 */ 835bbe418f2SJia Liu LOG_DIS("l.cust1\n"); 836bbe418f2SJia Liu break; 837bbe418f2SJia Liu 838bbe418f2SJia Liu case 0x1d: /* l.cust2 */ 839bbe418f2SJia Liu LOG_DIS("l.cust2\n"); 840bbe418f2SJia Liu break; 841bbe418f2SJia Liu 842bbe418f2SJia Liu case 0x1e: /* l.cust3 */ 843bbe418f2SJia Liu LOG_DIS("l.cust3\n"); 844bbe418f2SJia Liu break; 845bbe418f2SJia Liu 846bbe418f2SJia Liu case 0x1f: /* l.cust4 */ 847bbe418f2SJia Liu LOG_DIS("l.cust4\n"); 848bbe418f2SJia Liu break; 849bbe418f2SJia Liu 850bbe418f2SJia Liu case 0x3c: /* l.cust5 */ 851bbe418f2SJia Liu LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5); 852bbe418f2SJia Liu break; 853bbe418f2SJia Liu 854bbe418f2SJia Liu case 0x3d: /* l.cust6 */ 855bbe418f2SJia Liu LOG_DIS("l.cust6\n"); 856bbe418f2SJia Liu break; 857bbe418f2SJia Liu 858bbe418f2SJia Liu case 0x3e: /* l.cust7 */ 859bbe418f2SJia Liu LOG_DIS("l.cust7\n"); 860bbe418f2SJia Liu break; 861bbe418f2SJia Liu 862bbe418f2SJia Liu case 0x3f: /* l.cust8 */ 863bbe418f2SJia Liu LOG_DIS("l.cust8\n"); 864bbe418f2SJia Liu break; 865bbe418f2SJia Liu 866bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 867bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 868bbe418f2SJia Liu case 0x20: l.ld 869bbe418f2SJia Liu LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); 870bbe418f2SJia Liu check_ob64s(dc); 8715631e69cSRichard Henderson mop = MO_TEQ; 8725631e69cSRichard Henderson goto do_load; 873bbe418f2SJia Liu #endif*/ 874bbe418f2SJia Liu 875bbe418f2SJia Liu case 0x21: /* l.lwz */ 876bbe418f2SJia Liu LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); 8775631e69cSRichard Henderson mop = MO_TEUL; 8785631e69cSRichard Henderson goto do_load; 879bbe418f2SJia Liu 880bbe418f2SJia Liu case 0x22: /* l.lws */ 881bbe418f2SJia Liu LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); 8825631e69cSRichard Henderson mop = MO_TESL; 8835631e69cSRichard Henderson goto do_load; 884bbe418f2SJia Liu 885bbe418f2SJia Liu case 0x23: /* l.lbz */ 886bbe418f2SJia Liu LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); 8875631e69cSRichard Henderson mop = MO_UB; 8885631e69cSRichard Henderson goto do_load; 889bbe418f2SJia Liu 890bbe418f2SJia Liu case 0x24: /* l.lbs */ 891bbe418f2SJia Liu LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); 8925631e69cSRichard Henderson mop = MO_SB; 8935631e69cSRichard Henderson goto do_load; 894bbe418f2SJia Liu 895bbe418f2SJia Liu case 0x25: /* l.lhz */ 896bbe418f2SJia Liu LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); 8975631e69cSRichard Henderson mop = MO_TEUW; 8985631e69cSRichard Henderson goto do_load; 899bbe418f2SJia Liu 900bbe418f2SJia Liu case 0x26: /* l.lhs */ 901bbe418f2SJia Liu LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); 9025631e69cSRichard Henderson mop = MO_TESW; 9035631e69cSRichard Henderson goto do_load; 9045631e69cSRichard Henderson 9055631e69cSRichard Henderson do_load: 906bbe418f2SJia Liu { 907bbe418f2SJia Liu TCGv t0 = tcg_temp_new(); 9086da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I16); 9095631e69cSRichard Henderson tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); 910bbe418f2SJia Liu tcg_temp_free(t0); 911bbe418f2SJia Liu } 912bbe418f2SJia Liu break; 913bbe418f2SJia Liu 914bbe418f2SJia Liu case 0x27: /* l.addi */ 915bbe418f2SJia Liu LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); 916*9ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 917*9ecaa27eSRichard Henderson gen_add(dc, cpu_R[rd], cpu_R[ra], t0); 918*9ecaa27eSRichard Henderson tcg_temp_free(t0); 919bbe418f2SJia Liu break; 920bbe418f2SJia Liu 921bbe418f2SJia Liu case 0x28: /* l.addic */ 922bbe418f2SJia Liu LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16); 923*9ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 924*9ecaa27eSRichard Henderson gen_addc(dc, cpu_R[rd], cpu_R[ra], t0); 925*9ecaa27eSRichard Henderson tcg_temp_free(t0); 926bbe418f2SJia Liu break; 927bbe418f2SJia Liu 928bbe418f2SJia Liu case 0x29: /* l.andi */ 9296da544a6SRichard Henderson LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16); 9306da544a6SRichard Henderson tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16); 931bbe418f2SJia Liu break; 932bbe418f2SJia Liu 933bbe418f2SJia Liu case 0x2a: /* l.ori */ 9346da544a6SRichard Henderson LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16); 9356da544a6SRichard Henderson tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16); 936bbe418f2SJia Liu break; 937bbe418f2SJia Liu 938bbe418f2SJia Liu case 0x2b: /* l.xori */ 939bbe418f2SJia Liu LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16); 9406da544a6SRichard Henderson tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16); 941bbe418f2SJia Liu break; 942bbe418f2SJia Liu 943bbe418f2SJia Liu case 0x2c: /* l.muli */ 944bbe418f2SJia Liu LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16); 945*9ecaa27eSRichard Henderson t0 = tcg_const_tl(I16); 946*9ecaa27eSRichard Henderson gen_mul(dc, cpu_R[rd], cpu_R[ra], t0); 947*9ecaa27eSRichard Henderson tcg_temp_free(t0); 948bbe418f2SJia Liu break; 949bbe418f2SJia Liu 950bbe418f2SJia Liu case 0x2d: /* l.mfspr */ 9516da544a6SRichard Henderson LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16); 9524dd044c6SJia Liu { 9534dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 9544dd044c6SJia Liu return; 9554dd044c6SJia Liu #else 9566da544a6SRichard Henderson TCGv_i32 ti = tcg_const_i32(K16); 9574dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 9584dd044c6SJia Liu gen_illegal_exception(dc); 9594dd044c6SJia Liu return; 9604dd044c6SJia Liu } 9614dd044c6SJia Liu gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); 9624dd044c6SJia Liu tcg_temp_free_i32(ti); 9634dd044c6SJia Liu #endif 9644dd044c6SJia Liu } 965bbe418f2SJia Liu break; 966bbe418f2SJia Liu 967bbe418f2SJia Liu case 0x30: /* l.mtspr */ 9686da544a6SRichard Henderson LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11); 9694dd044c6SJia Liu { 9704dd044c6SJia Liu #if defined(CONFIG_USER_ONLY) 9714dd044c6SJia Liu return; 9724dd044c6SJia Liu #else 9736da544a6SRichard Henderson TCGv_i32 im = tcg_const_i32(K5_11); 9744dd044c6SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 9754dd044c6SJia Liu gen_illegal_exception(dc); 9764dd044c6SJia Liu return; 9774dd044c6SJia Liu } 9784dd044c6SJia Liu gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); 9794dd044c6SJia Liu tcg_temp_free_i32(im); 9804dd044c6SJia Liu #endif 9814dd044c6SJia Liu } 982bbe418f2SJia Liu break; 983bbe418f2SJia Liu 984930c3d00SRichard Henderson case 0x33: /* l.swa */ 9856da544a6SRichard Henderson LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11); 9866da544a6SRichard Henderson gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11); 987930c3d00SRichard Henderson break; 988930c3d00SRichard Henderson 989bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 990bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 991bbe418f2SJia Liu case 0x34: l.sd 9926da544a6SRichard Henderson LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11); 993bbe418f2SJia Liu check_ob64s(dc); 9945631e69cSRichard Henderson mop = MO_TEQ; 9955631e69cSRichard Henderson goto do_store; 996bbe418f2SJia Liu #endif*/ 997bbe418f2SJia Liu 998bbe418f2SJia Liu case 0x35: /* l.sw */ 9996da544a6SRichard Henderson LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11); 10005631e69cSRichard Henderson mop = MO_TEUL; 10015631e69cSRichard Henderson goto do_store; 1002bbe418f2SJia Liu 1003bbe418f2SJia Liu case 0x36: /* l.sb */ 10046da544a6SRichard Henderson LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11); 10055631e69cSRichard Henderson mop = MO_UB; 10065631e69cSRichard Henderson goto do_store; 1007bbe418f2SJia Liu 1008bbe418f2SJia Liu case 0x37: /* l.sh */ 10096da544a6SRichard Henderson LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11); 10105631e69cSRichard Henderson mop = MO_TEUW; 10115631e69cSRichard Henderson goto do_store; 10125631e69cSRichard Henderson 10135631e69cSRichard Henderson do_store: 1014bbe418f2SJia Liu { 1015bbe418f2SJia Liu TCGv t0 = tcg_temp_new(); 10166da544a6SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[ra], I5_11); 10175631e69cSRichard Henderson tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); 1018bbe418f2SJia Liu tcg_temp_free(t0); 1019bbe418f2SJia Liu } 1020bbe418f2SJia Liu break; 1021bbe418f2SJia Liu 1022bbe418f2SJia Liu default: 1023bbe418f2SJia Liu gen_illegal_exception(dc); 1024bbe418f2SJia Liu break; 1025bbe418f2SJia Liu } 1026bbe418f2SJia Liu } 1027bbe418f2SJia Liu 1028bbe418f2SJia Liu static void dec_mac(DisasContext *dc, uint32_t insn) 1029bbe418f2SJia Liu { 1030bbe418f2SJia Liu uint32_t op0; 1031bbe418f2SJia Liu uint32_t ra, rb; 1032bbe418f2SJia Liu op0 = extract32(insn, 0, 4); 1033bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1034bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1035bbe418f2SJia Liu 1036bbe418f2SJia Liu switch (op0) { 1037bbe418f2SJia Liu case 0x0001: /* l.mac */ 1038bbe418f2SJia Liu LOG_DIS("l.mac r%d, r%d\n", ra, rb); 1039bbe418f2SJia Liu { 1040bbe418f2SJia Liu TCGv_i32 t0 = tcg_temp_new_i32(); 1041bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 1042bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 1043bbe418f2SJia Liu tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 1044bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, t0); 1045bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 1046bbe418f2SJia Liu tcg_gen_add_i64(t2, t2, t1); 1047ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 1048bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 1049ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 1050bbe418f2SJia Liu tcg_temp_free_i32(t0); 1051bbe418f2SJia Liu tcg_temp_free_i64(t1); 1052bbe418f2SJia Liu tcg_temp_free_i64(t2); 1053bbe418f2SJia Liu } 1054bbe418f2SJia Liu break; 1055bbe418f2SJia Liu 1056bbe418f2SJia Liu case 0x0002: /* l.msb */ 1057bbe418f2SJia Liu LOG_DIS("l.msb r%d, r%d\n", ra, rb); 1058bbe418f2SJia Liu { 1059bbe418f2SJia Liu TCGv_i32 t0 = tcg_temp_new_i32(); 1060bbe418f2SJia Liu TCGv_i64 t1 = tcg_temp_new_i64(); 1061bbe418f2SJia Liu TCGv_i64 t2 = tcg_temp_new_i64(); 1062bbe418f2SJia Liu tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 1063bbe418f2SJia Liu tcg_gen_ext_i32_i64(t1, t0); 1064bbe418f2SJia Liu tcg_gen_concat_i32_i64(t2, maclo, machi); 1065bbe418f2SJia Liu tcg_gen_sub_i64(t2, t2, t1); 1066ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(maclo, t2); 1067bbe418f2SJia Liu tcg_gen_shri_i64(t2, t2, 32); 1068ecc7b3aaSRichard Henderson tcg_gen_extrl_i64_i32(machi, t2); 1069bbe418f2SJia Liu tcg_temp_free_i32(t0); 1070bbe418f2SJia Liu tcg_temp_free_i64(t1); 1071bbe418f2SJia Liu tcg_temp_free_i64(t2); 1072bbe418f2SJia Liu } 1073bbe418f2SJia Liu break; 1074bbe418f2SJia Liu 1075bbe418f2SJia Liu default: 1076bbe418f2SJia Liu gen_illegal_exception(dc); 1077bbe418f2SJia Liu break; 1078bbe418f2SJia Liu } 1079bbe418f2SJia Liu } 1080bbe418f2SJia Liu 1081bbe418f2SJia Liu static void dec_logic(DisasContext *dc, uint32_t insn) 1082bbe418f2SJia Liu { 1083bbe418f2SJia Liu uint32_t op0; 10846da544a6SRichard Henderson uint32_t rd, ra, L6, S6; 1085bbe418f2SJia Liu op0 = extract32(insn, 6, 2); 1086bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1087bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1088bbe418f2SJia Liu L6 = extract32(insn, 0, 6); 10896da544a6SRichard Henderson S6 = L6 & (TARGET_LONG_BITS - 1); 1090bbe418f2SJia Liu 1091bbe418f2SJia Liu switch (op0) { 1092bbe418f2SJia Liu case 0x00: /* l.slli */ 1093bbe418f2SJia Liu LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6); 10946da544a6SRichard Henderson tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6); 1095bbe418f2SJia Liu break; 1096bbe418f2SJia Liu 1097bbe418f2SJia Liu case 0x01: /* l.srli */ 1098bbe418f2SJia Liu LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6); 10996da544a6SRichard Henderson tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6); 1100bbe418f2SJia Liu break; 1101bbe418f2SJia Liu 1102bbe418f2SJia Liu case 0x02: /* l.srai */ 1103bbe418f2SJia Liu LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6); 11046da544a6SRichard Henderson tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6); 11056da544a6SRichard Henderson break; 1106bbe418f2SJia Liu 1107bbe418f2SJia Liu case 0x03: /* l.rori */ 1108bbe418f2SJia Liu LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6); 11096da544a6SRichard Henderson tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6); 1110bbe418f2SJia Liu break; 1111bbe418f2SJia Liu 1112bbe418f2SJia Liu default: 1113bbe418f2SJia Liu gen_illegal_exception(dc); 1114bbe418f2SJia Liu break; 1115bbe418f2SJia Liu } 1116bbe418f2SJia Liu } 1117bbe418f2SJia Liu 1118bbe418f2SJia Liu static void dec_M(DisasContext *dc, uint32_t insn) 1119bbe418f2SJia Liu { 1120bbe418f2SJia Liu uint32_t op0; 1121bbe418f2SJia Liu uint32_t rd; 1122bbe418f2SJia Liu uint32_t K16; 1123bbe418f2SJia Liu op0 = extract32(insn, 16, 1); 1124bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1125bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1126bbe418f2SJia Liu 1127bbe418f2SJia Liu switch (op0) { 1128bbe418f2SJia Liu case 0x0: /* l.movhi */ 1129bbe418f2SJia Liu LOG_DIS("l.movhi r%d, %d\n", rd, K16); 1130bbe418f2SJia Liu tcg_gen_movi_tl(cpu_R[rd], (K16 << 16)); 1131bbe418f2SJia Liu break; 1132bbe418f2SJia Liu 1133bbe418f2SJia Liu case 0x1: /* l.macrc */ 1134bbe418f2SJia Liu LOG_DIS("l.macrc r%d\n", rd); 1135bbe418f2SJia Liu tcg_gen_mov_tl(cpu_R[rd], maclo); 1136bbe418f2SJia Liu tcg_gen_movi_tl(maclo, 0x0); 1137bbe418f2SJia Liu tcg_gen_movi_tl(machi, 0x0); 1138bbe418f2SJia Liu break; 1139bbe418f2SJia Liu 1140bbe418f2SJia Liu default: 1141bbe418f2SJia Liu gen_illegal_exception(dc); 1142bbe418f2SJia Liu break; 1143bbe418f2SJia Liu } 1144bbe418f2SJia Liu } 1145bbe418f2SJia Liu 1146bbe418f2SJia Liu static void dec_comp(DisasContext *dc, uint32_t insn) 1147bbe418f2SJia Liu { 1148bbe418f2SJia Liu uint32_t op0; 1149bbe418f2SJia Liu uint32_t ra, rb; 1150bbe418f2SJia Liu 1151bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1152bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1153bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1154bbe418f2SJia Liu 1155bbe418f2SJia Liu tcg_gen_movi_i32(env_btaken, 0x0); 1156bbe418f2SJia Liu /* unsigned integers */ 1157bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); 1158bbe418f2SJia Liu tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); 1159bbe418f2SJia Liu 1160bbe418f2SJia Liu switch (op0) { 1161bbe418f2SJia Liu case 0x0: /* l.sfeq */ 1162bbe418f2SJia Liu LOG_DIS("l.sfeq r%d, r%d\n", ra, rb); 1163bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]); 1164bbe418f2SJia Liu break; 1165bbe418f2SJia Liu 1166bbe418f2SJia Liu case 0x1: /* l.sfne */ 1167bbe418f2SJia Liu LOG_DIS("l.sfne r%d, r%d\n", ra, rb); 1168bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]); 1169bbe418f2SJia Liu break; 1170bbe418f2SJia Liu 1171bbe418f2SJia Liu case 0x2: /* l.sfgtu */ 1172bbe418f2SJia Liu LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb); 1173bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1174bbe418f2SJia Liu break; 1175bbe418f2SJia Liu 1176bbe418f2SJia Liu case 0x3: /* l.sfgeu */ 1177bbe418f2SJia Liu LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb); 1178bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1179bbe418f2SJia Liu break; 1180bbe418f2SJia Liu 1181bbe418f2SJia Liu case 0x4: /* l.sfltu */ 1182bbe418f2SJia Liu LOG_DIS("l.sfltu r%d, r%d\n", ra, rb); 1183bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1184bbe418f2SJia Liu break; 1185bbe418f2SJia Liu 1186bbe418f2SJia Liu case 0x5: /* l.sfleu */ 1187bbe418f2SJia Liu LOG_DIS("l.sfleu r%d, r%d\n", ra, rb); 1188bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1189bbe418f2SJia Liu break; 1190bbe418f2SJia Liu 1191bbe418f2SJia Liu case 0xa: /* l.sfgts */ 1192bbe418f2SJia Liu LOG_DIS("l.sfgts r%d, r%d\n", ra, rb); 1193bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]); 1194bbe418f2SJia Liu break; 1195bbe418f2SJia Liu 1196bbe418f2SJia Liu case 0xb: /* l.sfges */ 1197bbe418f2SJia Liu LOG_DIS("l.sfges r%d, r%d\n", ra, rb); 1198bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]); 1199bbe418f2SJia Liu break; 1200bbe418f2SJia Liu 1201bbe418f2SJia Liu case 0xc: /* l.sflts */ 1202bbe418f2SJia Liu LOG_DIS("l.sflts r%d, r%d\n", ra, rb); 1203bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]); 1204bbe418f2SJia Liu break; 1205bbe418f2SJia Liu 1206bbe418f2SJia Liu case 0xd: /* l.sfles */ 1207bbe418f2SJia Liu LOG_DIS("l.sfles r%d, r%d\n", ra, rb); 1208bbe418f2SJia Liu tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]); 1209bbe418f2SJia Liu break; 1210bbe418f2SJia Liu 1211bbe418f2SJia Liu default: 1212bbe418f2SJia Liu gen_illegal_exception(dc); 1213bbe418f2SJia Liu break; 1214bbe418f2SJia Liu } 1215bbe418f2SJia Liu wb_SR_F(); 1216bbe418f2SJia Liu } 1217bbe418f2SJia Liu 1218bbe418f2SJia Liu static void dec_compi(DisasContext *dc, uint32_t insn) 1219bbe418f2SJia Liu { 12206da544a6SRichard Henderson uint32_t op0, ra; 12216da544a6SRichard Henderson int32_t I16; 1222bbe418f2SJia Liu 1223bbe418f2SJia Liu op0 = extract32(insn, 21, 5); 1224bbe418f2SJia Liu ra = extract32(insn, 16, 5); 12256da544a6SRichard Henderson I16 = sextract32(insn, 0, 16); 1226bbe418f2SJia Liu 1227bbe418f2SJia Liu tcg_gen_movi_i32(env_btaken, 0x0); 1228bbe418f2SJia Liu 1229bbe418f2SJia Liu switch (op0) { 1230bbe418f2SJia Liu case 0x0: /* l.sfeqi */ 1231bbe418f2SJia Liu LOG_DIS("l.sfeqi r%d, %d\n", ra, I16); 1232bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16); 1233bbe418f2SJia Liu break; 1234bbe418f2SJia Liu 1235bbe418f2SJia Liu case 0x1: /* l.sfnei */ 1236bbe418f2SJia Liu LOG_DIS("l.sfnei r%d, %d\n", ra, I16); 1237bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16); 1238bbe418f2SJia Liu break; 1239bbe418f2SJia Liu 1240bbe418f2SJia Liu case 0x2: /* l.sfgtui */ 1241bbe418f2SJia Liu LOG_DIS("l.sfgtui r%d, %d\n", ra, I16); 1242bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16); 1243bbe418f2SJia Liu break; 1244bbe418f2SJia Liu 1245bbe418f2SJia Liu case 0x3: /* l.sfgeui */ 1246bbe418f2SJia Liu LOG_DIS("l.sfgeui r%d, %d\n", ra, I16); 1247bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16); 1248bbe418f2SJia Liu break; 1249bbe418f2SJia Liu 1250bbe418f2SJia Liu case 0x4: /* l.sfltui */ 1251bbe418f2SJia Liu LOG_DIS("l.sfltui r%d, %d\n", ra, I16); 1252bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16); 1253bbe418f2SJia Liu break; 1254bbe418f2SJia Liu 1255bbe418f2SJia Liu case 0x5: /* l.sfleui */ 1256bbe418f2SJia Liu LOG_DIS("l.sfleui r%d, %d\n", ra, I16); 1257bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16); 1258bbe418f2SJia Liu break; 1259bbe418f2SJia Liu 1260bbe418f2SJia Liu case 0xa: /* l.sfgtsi */ 1261bbe418f2SJia Liu LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16); 1262bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16); 1263bbe418f2SJia Liu break; 1264bbe418f2SJia Liu 1265bbe418f2SJia Liu case 0xb: /* l.sfgesi */ 1266bbe418f2SJia Liu LOG_DIS("l.sfgesi r%d, %d\n", ra, I16); 1267bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16); 1268bbe418f2SJia Liu break; 1269bbe418f2SJia Liu 1270bbe418f2SJia Liu case 0xc: /* l.sfltsi */ 1271bbe418f2SJia Liu LOG_DIS("l.sfltsi r%d, %d\n", ra, I16); 1272bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16); 1273bbe418f2SJia Liu break; 1274bbe418f2SJia Liu 1275bbe418f2SJia Liu case 0xd: /* l.sflesi */ 1276bbe418f2SJia Liu LOG_DIS("l.sflesi r%d, %d\n", ra, I16); 1277bbe418f2SJia Liu tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16); 1278bbe418f2SJia Liu break; 1279bbe418f2SJia Liu 1280bbe418f2SJia Liu default: 1281bbe418f2SJia Liu gen_illegal_exception(dc); 1282bbe418f2SJia Liu break; 1283bbe418f2SJia Liu } 1284bbe418f2SJia Liu wb_SR_F(); 1285bbe418f2SJia Liu } 1286bbe418f2SJia Liu 1287bbe418f2SJia Liu static void dec_sys(DisasContext *dc, uint32_t insn) 1288bbe418f2SJia Liu { 1289bbe418f2SJia Liu uint32_t op0; 1290bbe418f2SJia Liu uint32_t K16; 1291111ece51SRichard Henderson 12923d59b680SDavid Morrison op0 = extract32(insn, 16, 10); 1293bbe418f2SJia Liu K16 = extract32(insn, 0, 16); 1294bbe418f2SJia Liu 1295bbe418f2SJia Liu switch (op0) { 1296bbe418f2SJia Liu case 0x000: /* l.sys */ 1297bbe418f2SJia Liu LOG_DIS("l.sys %d\n", K16); 1298bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1299bbe418f2SJia Liu gen_exception(dc, EXCP_SYSCALL); 1300bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 1301bbe418f2SJia Liu break; 1302bbe418f2SJia Liu 1303bbe418f2SJia Liu case 0x100: /* l.trap */ 1304bbe418f2SJia Liu LOG_DIS("l.trap %d\n", K16); 1305bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1306bbe418f2SJia Liu return; 1307bbe418f2SJia Liu #else 1308bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1309bbe418f2SJia Liu gen_illegal_exception(dc); 1310bbe418f2SJia Liu return; 1311bbe418f2SJia Liu } 1312bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1313bbe418f2SJia Liu gen_exception(dc, EXCP_TRAP); 1314bbe418f2SJia Liu #endif 1315bbe418f2SJia Liu break; 1316bbe418f2SJia Liu 1317bbe418f2SJia Liu case 0x300: /* l.csync */ 1318bbe418f2SJia Liu LOG_DIS("l.csync\n"); 1319bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1320bbe418f2SJia Liu return; 1321bbe418f2SJia Liu #else 1322bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1323bbe418f2SJia Liu gen_illegal_exception(dc); 1324bbe418f2SJia Liu return; 1325bbe418f2SJia Liu } 1326bbe418f2SJia Liu #endif 1327bbe418f2SJia Liu break; 1328bbe418f2SJia Liu 1329bbe418f2SJia Liu case 0x200: /* l.msync */ 1330bbe418f2SJia Liu LOG_DIS("l.msync\n"); 1331bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1332bbe418f2SJia Liu return; 1333bbe418f2SJia Liu #else 1334bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1335bbe418f2SJia Liu gen_illegal_exception(dc); 1336bbe418f2SJia Liu return; 1337bbe418f2SJia Liu } 1338bbe418f2SJia Liu #endif 1339bbe418f2SJia Liu break; 1340bbe418f2SJia Liu 1341bbe418f2SJia Liu case 0x270: /* l.psync */ 1342bbe418f2SJia Liu LOG_DIS("l.psync\n"); 1343bbe418f2SJia Liu #if defined(CONFIG_USER_ONLY) 1344bbe418f2SJia Liu return; 1345bbe418f2SJia Liu #else 1346bbe418f2SJia Liu if (dc->mem_idx == MMU_USER_IDX) { 1347bbe418f2SJia Liu gen_illegal_exception(dc); 1348bbe418f2SJia Liu return; 1349bbe418f2SJia Liu } 1350bbe418f2SJia Liu #endif 1351bbe418f2SJia Liu break; 1352bbe418f2SJia Liu 1353bbe418f2SJia Liu default: 1354bbe418f2SJia Liu gen_illegal_exception(dc); 1355bbe418f2SJia Liu break; 1356bbe418f2SJia Liu } 1357bbe418f2SJia Liu } 1358bbe418f2SJia Liu 1359bbe418f2SJia Liu static void dec_float(DisasContext *dc, uint32_t insn) 1360bbe418f2SJia Liu { 1361bbe418f2SJia Liu uint32_t op0; 1362bbe418f2SJia Liu uint32_t ra, rb, rd; 1363bbe418f2SJia Liu op0 = extract32(insn, 0, 8); 1364bbe418f2SJia Liu ra = extract32(insn, 16, 5); 1365bbe418f2SJia Liu rb = extract32(insn, 11, 5); 1366bbe418f2SJia Liu rd = extract32(insn, 21, 5); 1367bbe418f2SJia Liu 1368bbe418f2SJia Liu switch (op0) { 1369bbe418f2SJia Liu case 0x00: /* lf.add.s */ 1370bbe418f2SJia Liu LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb); 1371bbe418f2SJia Liu gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1372bbe418f2SJia Liu break; 1373bbe418f2SJia Liu 1374bbe418f2SJia Liu case 0x01: /* lf.sub.s */ 1375bbe418f2SJia Liu LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb); 1376bbe418f2SJia Liu gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1377bbe418f2SJia Liu break; 1378bbe418f2SJia Liu 1379bbe418f2SJia Liu 1380bbe418f2SJia Liu case 0x02: /* lf.mul.s */ 1381bbe418f2SJia Liu LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb); 1382bbe418f2SJia Liu if (ra != 0 && rb != 0) { 1383bbe418f2SJia Liu gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1384bbe418f2SJia Liu } else { 1385bbe418f2SJia Liu tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1386bbe418f2SJia Liu tcg_gen_movi_i32(cpu_R[rd], 0x0); 1387bbe418f2SJia Liu } 1388bbe418f2SJia Liu break; 1389bbe418f2SJia Liu 1390bbe418f2SJia Liu case 0x03: /* lf.div.s */ 1391bbe418f2SJia Liu LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb); 1392bbe418f2SJia Liu gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1393bbe418f2SJia Liu break; 1394bbe418f2SJia Liu 1395bbe418f2SJia Liu case 0x04: /* lf.itof.s */ 1396bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1397bbe418f2SJia Liu gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]); 1398bbe418f2SJia Liu break; 1399bbe418f2SJia Liu 1400bbe418f2SJia Liu case 0x05: /* lf.ftoi.s */ 1401bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1402bbe418f2SJia Liu gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]); 1403bbe418f2SJia Liu break; 1404bbe418f2SJia Liu 1405bbe418f2SJia Liu case 0x06: /* lf.rem.s */ 1406bbe418f2SJia Liu LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb); 1407bbe418f2SJia Liu gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1408bbe418f2SJia Liu break; 1409bbe418f2SJia Liu 1410bbe418f2SJia Liu case 0x07: /* lf.madd.s */ 1411bbe418f2SJia Liu LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb); 1412bbe418f2SJia Liu gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1413bbe418f2SJia Liu break; 1414bbe418f2SJia Liu 1415bbe418f2SJia Liu case 0x08: /* lf.sfeq.s */ 1416bbe418f2SJia Liu LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb); 1417bbe418f2SJia Liu gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1418bbe418f2SJia Liu break; 1419bbe418f2SJia Liu 1420bbe418f2SJia Liu case 0x09: /* lf.sfne.s */ 1421bbe418f2SJia Liu LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb); 1422bbe418f2SJia Liu gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1423bbe418f2SJia Liu break; 1424bbe418f2SJia Liu 1425bbe418f2SJia Liu case 0x0a: /* lf.sfgt.s */ 1426bbe418f2SJia Liu LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb); 1427bbe418f2SJia Liu gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1428bbe418f2SJia Liu break; 1429bbe418f2SJia Liu 1430bbe418f2SJia Liu case 0x0b: /* lf.sfge.s */ 1431bbe418f2SJia Liu LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb); 1432bbe418f2SJia Liu gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1433bbe418f2SJia Liu break; 1434bbe418f2SJia Liu 1435bbe418f2SJia Liu case 0x0c: /* lf.sflt.s */ 1436bbe418f2SJia Liu LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb); 1437bbe418f2SJia Liu gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1438bbe418f2SJia Liu break; 1439bbe418f2SJia Liu 1440bbe418f2SJia Liu case 0x0d: /* lf.sfle.s */ 1441bbe418f2SJia Liu LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb); 1442bbe418f2SJia Liu gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1443bbe418f2SJia Liu break; 1444bbe418f2SJia Liu 1445bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 1446bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 1447bbe418f2SJia Liu case 0x10: lf.add.d 1448bbe418f2SJia Liu LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb); 1449bbe418f2SJia Liu check_of64s(dc); 1450bbe418f2SJia Liu gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1451bbe418f2SJia Liu break; 1452bbe418f2SJia Liu 1453bbe418f2SJia Liu case 0x11: lf.sub.d 1454bbe418f2SJia Liu LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb); 1455bbe418f2SJia Liu check_of64s(dc); 1456bbe418f2SJia Liu gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1457bbe418f2SJia Liu break; 1458bbe418f2SJia Liu 1459bbe418f2SJia Liu case 0x12: lf.mul.d 1460bbe418f2SJia Liu LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb); 1461bbe418f2SJia Liu check_of64s(dc); 1462bbe418f2SJia Liu if (ra != 0 && rb != 0) { 1463bbe418f2SJia Liu gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1464bbe418f2SJia Liu } else { 1465bbe418f2SJia Liu tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1466bbe418f2SJia Liu tcg_gen_movi_i64(cpu_R[rd], 0x0); 1467bbe418f2SJia Liu } 1468bbe418f2SJia Liu break; 1469bbe418f2SJia Liu 1470bbe418f2SJia Liu case 0x13: lf.div.d 1471bbe418f2SJia Liu LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb); 1472bbe418f2SJia Liu check_of64s(dc); 1473bbe418f2SJia Liu gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1474bbe418f2SJia Liu break; 1475bbe418f2SJia Liu 1476bbe418f2SJia Liu case 0x14: lf.itof.d 1477bbe418f2SJia Liu LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1478bbe418f2SJia Liu check_of64s(dc); 1479bbe418f2SJia Liu gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]); 1480bbe418f2SJia Liu break; 1481bbe418f2SJia Liu 1482bbe418f2SJia Liu case 0x15: lf.ftoi.d 1483bbe418f2SJia Liu LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1484bbe418f2SJia Liu check_of64s(dc); 1485bbe418f2SJia Liu gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]); 1486bbe418f2SJia Liu break; 1487bbe418f2SJia Liu 1488bbe418f2SJia Liu case 0x16: lf.rem.d 1489bbe418f2SJia Liu LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb); 1490bbe418f2SJia Liu check_of64s(dc); 1491bbe418f2SJia Liu gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1492bbe418f2SJia Liu break; 1493bbe418f2SJia Liu 1494bbe418f2SJia Liu case 0x17: lf.madd.d 1495bbe418f2SJia Liu LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); 1496bbe418f2SJia Liu check_of64s(dc); 1497bbe418f2SJia Liu gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1498bbe418f2SJia Liu break; 1499bbe418f2SJia Liu 1500bbe418f2SJia Liu case 0x18: lf.sfeq.d 1501bbe418f2SJia Liu LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); 1502bbe418f2SJia Liu check_of64s(dc); 1503bbe418f2SJia Liu gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1504bbe418f2SJia Liu break; 1505bbe418f2SJia Liu 1506bbe418f2SJia Liu case 0x1a: lf.sfgt.d 1507bbe418f2SJia Liu LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); 1508bbe418f2SJia Liu check_of64s(dc); 1509bbe418f2SJia Liu gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1510bbe418f2SJia Liu break; 1511bbe418f2SJia Liu 1512bbe418f2SJia Liu case 0x1b: lf.sfge.d 1513bbe418f2SJia Liu LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); 1514bbe418f2SJia Liu check_of64s(dc); 1515bbe418f2SJia Liu gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1516bbe418f2SJia Liu break; 1517bbe418f2SJia Liu 1518bbe418f2SJia Liu case 0x19: lf.sfne.d 1519bbe418f2SJia Liu LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); 1520bbe418f2SJia Liu check_of64s(dc); 1521bbe418f2SJia Liu gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1522bbe418f2SJia Liu break; 1523bbe418f2SJia Liu 1524bbe418f2SJia Liu case 0x1c: lf.sflt.d 1525bbe418f2SJia Liu LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); 1526bbe418f2SJia Liu check_of64s(dc); 1527bbe418f2SJia Liu gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1528bbe418f2SJia Liu break; 1529bbe418f2SJia Liu 1530bbe418f2SJia Liu case 0x1d: lf.sfle.d 1531bbe418f2SJia Liu LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); 1532bbe418f2SJia Liu check_of64s(dc); 1533bbe418f2SJia Liu gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1534bbe418f2SJia Liu break; 1535bbe418f2SJia Liu #endif*/ 1536bbe418f2SJia Liu 1537bbe418f2SJia Liu default: 1538bbe418f2SJia Liu gen_illegal_exception(dc); 1539bbe418f2SJia Liu break; 1540bbe418f2SJia Liu } 1541bbe418f2SJia Liu wb_SR_F(); 1542bbe418f2SJia Liu } 1543bbe418f2SJia Liu 1544bbe418f2SJia Liu static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) 1545bbe418f2SJia Liu { 1546bbe418f2SJia Liu uint32_t op0; 1547bbe418f2SJia Liu uint32_t insn; 1548bbe418f2SJia Liu insn = cpu_ldl_code(&cpu->env, dc->pc); 1549bbe418f2SJia Liu op0 = extract32(insn, 26, 6); 1550bbe418f2SJia Liu 1551bbe418f2SJia Liu switch (op0) { 1552bbe418f2SJia Liu case 0x06: 1553bbe418f2SJia Liu dec_M(dc, insn); 1554bbe418f2SJia Liu break; 1555bbe418f2SJia Liu 1556bbe418f2SJia Liu case 0x08: 1557bbe418f2SJia Liu dec_sys(dc, insn); 1558bbe418f2SJia Liu break; 1559bbe418f2SJia Liu 1560bbe418f2SJia Liu case 0x2e: 1561bbe418f2SJia Liu dec_logic(dc, insn); 1562bbe418f2SJia Liu break; 1563bbe418f2SJia Liu 1564bbe418f2SJia Liu case 0x2f: 1565bbe418f2SJia Liu dec_compi(dc, insn); 1566bbe418f2SJia Liu break; 1567bbe418f2SJia Liu 1568bbe418f2SJia Liu case 0x31: 1569bbe418f2SJia Liu dec_mac(dc, insn); 1570bbe418f2SJia Liu break; 1571bbe418f2SJia Liu 1572bbe418f2SJia Liu case 0x32: 1573bbe418f2SJia Liu dec_float(dc, insn); 1574bbe418f2SJia Liu break; 1575bbe418f2SJia Liu 1576bbe418f2SJia Liu case 0x38: 1577bbe418f2SJia Liu dec_calc(dc, insn); 1578bbe418f2SJia Liu break; 1579bbe418f2SJia Liu 1580bbe418f2SJia Liu case 0x39: 1581bbe418f2SJia Liu dec_comp(dc, insn); 1582bbe418f2SJia Liu break; 1583bbe418f2SJia Liu 1584bbe418f2SJia Liu default: 1585bbe418f2SJia Liu dec_misc(dc, insn); 1586bbe418f2SJia Liu break; 1587bbe418f2SJia Liu } 1588bbe418f2SJia Liu } 1589bbe418f2SJia Liu 15904e5e1215SRichard Henderson void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) 1591e67db06eSJia Liu { 15924e5e1215SRichard Henderson OpenRISCCPU *cpu = openrisc_env_get_cpu(env); 1593ed2803daSAndreas Färber CPUState *cs = CPU(cpu); 1594bbe418f2SJia Liu struct DisasContext ctx, *dc = &ctx; 1595bbe418f2SJia Liu uint32_t pc_start; 1596bbe418f2SJia Liu uint32_t next_page_start; 1597bbe418f2SJia Liu int num_insns; 1598bbe418f2SJia Liu int max_insns; 1599bbe418f2SJia Liu 1600bbe418f2SJia Liu pc_start = tb->pc; 1601bbe418f2SJia Liu dc->tb = tb; 1602bbe418f2SJia Liu 1603bbe418f2SJia Liu dc->is_jmp = DISAS_NEXT; 1604bbe418f2SJia Liu dc->ppc = pc_start; 1605bbe418f2SJia Liu dc->pc = pc_start; 1606bbe418f2SJia Liu dc->flags = cpu->env.cpucfgr; 160797ed5ccdSBenjamin Herrenschmidt dc->mem_idx = cpu_mmu_index(&cpu->env, false); 1608bbe418f2SJia Liu dc->synced_flags = dc->tb_flags = tb->flags; 1609bbe418f2SJia Liu dc->delayed_branch = !!(dc->tb_flags & D_FLAG); 1610ed2803daSAndreas Färber dc->singlestep_enabled = cs->singlestep_enabled; 1611bbe418f2SJia Liu 1612bbe418f2SJia Liu next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 1613bbe418f2SJia Liu num_insns = 0; 1614bbe418f2SJia Liu max_insns = tb->cflags & CF_COUNT_MASK; 1615bbe418f2SJia Liu 1616bbe418f2SJia Liu if (max_insns == 0) { 1617bbe418f2SJia Liu max_insns = CF_COUNT_MASK; 1618bbe418f2SJia Liu } 1619190ce7fbSRichard Henderson if (max_insns > TCG_MAX_INSNS) { 1620190ce7fbSRichard Henderson max_insns = TCG_MAX_INSNS; 1621190ce7fbSRichard Henderson } 1622bbe418f2SJia Liu 1623111ece51SRichard Henderson if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 1624111ece51SRichard Henderson && qemu_log_in_addr_range(pc_start)) { 1625111ece51SRichard Henderson qemu_log_lock(); 1626111ece51SRichard Henderson qemu_log("----------------\n"); 1627111ece51SRichard Henderson qemu_log("IN: %s\n", lookup_symbol(pc_start)); 1628111ece51SRichard Henderson } 1629111ece51SRichard Henderson 1630cd42d5b2SPaolo Bonzini gen_tb_start(tb); 1631bbe418f2SJia Liu 1632bbe418f2SJia Liu do { 1633765b842aSRichard Henderson tcg_gen_insn_start(dc->pc); 1634959082fcSRichard Henderson num_insns++; 1635bbe418f2SJia Liu 1636b933066aSRichard Henderson if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { 1637b933066aSRichard Henderson tcg_gen_movi_tl(cpu_pc, dc->pc); 1638b933066aSRichard Henderson gen_exception(dc, EXCP_DEBUG); 1639b933066aSRichard Henderson dc->is_jmp = DISAS_UPDATE; 1640522a0d4eSRichard Henderson /* The address covered by the breakpoint must be included in 1641522a0d4eSRichard Henderson [tb->pc, tb->pc + tb->size) in order to for it to be 1642522a0d4eSRichard Henderson properly cleared -- thus we increment the PC here so that 1643522a0d4eSRichard Henderson the logic setting tb->size below does the right thing. */ 1644522a0d4eSRichard Henderson dc->pc += 4; 1645b933066aSRichard Henderson break; 1646b933066aSRichard Henderson } 1647b933066aSRichard Henderson 1648959082fcSRichard Henderson if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { 1649bbe418f2SJia Liu gen_io_start(); 1650bbe418f2SJia Liu } 1651bbe418f2SJia Liu dc->ppc = dc->pc - 4; 1652bbe418f2SJia Liu dc->npc = dc->pc + 4; 1653bbe418f2SJia Liu tcg_gen_movi_tl(cpu_ppc, dc->ppc); 1654bbe418f2SJia Liu tcg_gen_movi_tl(cpu_npc, dc->npc); 1655bbe418f2SJia Liu disas_openrisc_insn(dc, cpu); 1656bbe418f2SJia Liu dc->pc = dc->npc; 1657bbe418f2SJia Liu /* delay slot */ 1658bbe418f2SJia Liu if (dc->delayed_branch) { 1659bbe418f2SJia Liu dc->delayed_branch--; 1660bbe418f2SJia Liu if (!dc->delayed_branch) { 1661bbe418f2SJia Liu dc->tb_flags &= ~D_FLAG; 1662bbe418f2SJia Liu gen_sync_flags(dc); 1663bbe418f2SJia Liu tcg_gen_mov_tl(cpu_pc, jmp_pc); 1664bbe418f2SJia Liu tcg_gen_mov_tl(cpu_npc, jmp_pc); 1665bbe418f2SJia Liu tcg_gen_movi_tl(jmp_pc, 0); 1666bbe418f2SJia Liu tcg_gen_exit_tb(0); 1667bbe418f2SJia Liu dc->is_jmp = DISAS_JUMP; 1668bbe418f2SJia Liu break; 1669bbe418f2SJia Liu } 1670bbe418f2SJia Liu } 1671bbe418f2SJia Liu } while (!dc->is_jmp 1672fe700adbSRichard Henderson && !tcg_op_buf_full() 1673ed2803daSAndreas Färber && !cs->singlestep_enabled 1674bbe418f2SJia Liu && !singlestep 1675bbe418f2SJia Liu && (dc->pc < next_page_start) 1676bbe418f2SJia Liu && num_insns < max_insns); 1677bbe418f2SJia Liu 1678bbe418f2SJia Liu if (tb->cflags & CF_LAST_IO) { 1679bbe418f2SJia Liu gen_io_end(); 1680bbe418f2SJia Liu } 1681bbe418f2SJia Liu if (dc->is_jmp == DISAS_NEXT) { 1682bbe418f2SJia Liu dc->is_jmp = DISAS_UPDATE; 1683bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1684bbe418f2SJia Liu } 1685ed2803daSAndreas Färber if (unlikely(cs->singlestep_enabled)) { 1686bbe418f2SJia Liu if (dc->is_jmp == DISAS_NEXT) { 1687bbe418f2SJia Liu tcg_gen_movi_tl(cpu_pc, dc->pc); 1688bbe418f2SJia Liu } 1689bbe418f2SJia Liu gen_exception(dc, EXCP_DEBUG); 1690bbe418f2SJia Liu } else { 1691bbe418f2SJia Liu switch (dc->is_jmp) { 1692bbe418f2SJia Liu case DISAS_NEXT: 1693bbe418f2SJia Liu gen_goto_tb(dc, 0, dc->pc); 1694bbe418f2SJia Liu break; 1695bbe418f2SJia Liu default: 1696bbe418f2SJia Liu case DISAS_JUMP: 1697bbe418f2SJia Liu break; 1698bbe418f2SJia Liu case DISAS_UPDATE: 1699bbe418f2SJia Liu /* indicate that the hash table must be used 1700bbe418f2SJia Liu to find the next TB */ 1701bbe418f2SJia Liu tcg_gen_exit_tb(0); 1702bbe418f2SJia Liu break; 1703bbe418f2SJia Liu case DISAS_TB_JUMP: 1704bbe418f2SJia Liu /* nothing more to generate */ 1705bbe418f2SJia Liu break; 1706bbe418f2SJia Liu } 1707bbe418f2SJia Liu } 1708bbe418f2SJia Liu 1709806f352dSPeter Maydell gen_tb_end(tb, num_insns); 17100a7df5daSRichard Henderson 1711bbe418f2SJia Liu tb->size = dc->pc - pc_start; 1712bbe418f2SJia Liu tb->icount = num_insns; 1713bbe418f2SJia Liu 17144910e6e4SRichard Henderson if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 17154910e6e4SRichard Henderson && qemu_log_in_addr_range(pc_start)) { 1716111ece51SRichard Henderson log_target_disas(cs, pc_start, tb->size, 0); 1717111ece51SRichard Henderson qemu_log("\n"); 17181ee73216SRichard Henderson qemu_log_unlock(); 1719bbe418f2SJia Liu } 1720e67db06eSJia Liu } 1721e67db06eSJia Liu 1722878096eeSAndreas Färber void openrisc_cpu_dump_state(CPUState *cs, FILE *f, 1723e67db06eSJia Liu fprintf_function cpu_fprintf, 1724e67db06eSJia Liu int flags) 1725e67db06eSJia Liu { 1726878096eeSAndreas Färber OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1727878096eeSAndreas Färber CPUOpenRISCState *env = &cpu->env; 1728e67db06eSJia Liu int i; 1729878096eeSAndreas Färber 1730e67db06eSJia Liu cpu_fprintf(f, "PC=%08x\n", env->pc); 1731e67db06eSJia Liu for (i = 0; i < 32; ++i) { 1732878096eeSAndreas Färber cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i], 1733e67db06eSJia Liu (i % 4) == 3 ? '\n' : ' '); 1734e67db06eSJia Liu } 1735e67db06eSJia Liu } 1736e67db06eSJia Liu 1737e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1738bad729e2SRichard Henderson target_ulong *data) 1739e67db06eSJia Liu { 1740bad729e2SRichard Henderson env->pc = data[0]; 1741e67db06eSJia Liu } 1742