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 10779fc6adSThomas Huth * version 2.1 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" 2990c84c56SMarkus Armbruster #include "qemu/qemu-print.h" 30f08b6170SPaolo Bonzini #include "exec/cpu_ldst.h" 3177fc6f5eSLluís Vilanova #include "exec/translator.h" 32bbe418f2SJia Liu 332ef6175aSRichard Henderson #include "exec/helper-proto.h" 342ef6175aSRichard Henderson #include "exec/helper-gen.h" 357de9729fSRichard Henderson #include "exec/gen-icount.h" 36e67db06eSJia Liu 37a7e30d84SLluís Vilanova #include "trace-tcg.h" 38508127e2SPaolo Bonzini #include "exec/log.h" 39a7e30d84SLluís Vilanova 4077fc6f5eSLluís Vilanova /* is_jmp field values */ 4164e46c95SRichard Henderson #define DISAS_EXIT DISAS_TARGET_0 /* force exit to main loop */ 428000ba56SRichard Henderson #define DISAS_JUMP DISAS_TARGET_1 /* exit via jmp_pc/jmp_pc_imm */ 4377fc6f5eSLluís Vilanova 44bbe418f2SJia Liu typedef struct DisasContext { 451ffa4bceSEmilio G. Cota DisasContextBase base; 46bbe418f2SJia Liu uint32_t mem_idx; 47a01deb36SRichard Henderson uint32_t tb_flags; 48bbe418f2SJia Liu uint32_t delayed_branch; 498000ba56SRichard Henderson 508000ba56SRichard Henderson /* If not -1, jmp_pc contains this value and so is a direct jump. */ 518000ba56SRichard Henderson target_ulong jmp_pc_imm; 52bbe418f2SJia Liu } DisasContext; 53bbe418f2SJia Liu 542ba65417SRichard Henderson static inline bool is_user(DisasContext *dc) 552ba65417SRichard Henderson { 562ba65417SRichard Henderson #ifdef CONFIG_USER_ONLY 572ba65417SRichard Henderson return true; 582ba65417SRichard Henderson #else 59b9bed1b9SRichard Henderson return !(dc->tb_flags & TB_FLAGS_SM); 602ba65417SRichard Henderson #endif 612ba65417SRichard Henderson } 622ba65417SRichard Henderson 637de9729fSRichard Henderson /* Include the auto-generated decoder. */ 647de9729fSRichard Henderson #include "decode.inc.c" 657de9729fSRichard Henderson 66bbe418f2SJia Liu static TCGv cpu_sr; 67bbe418f2SJia Liu static TCGv cpu_R[32]; 686597c28dSRichard Henderson static TCGv cpu_R0; 69bbe418f2SJia Liu static TCGv cpu_pc; 70bbe418f2SJia Liu static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ 71bbe418f2SJia Liu static TCGv cpu_ppc; 7284775c43SRichard Henderson static TCGv cpu_sr_f; /* bf/bnf, F flag taken */ 7397458071SRichard Henderson static TCGv cpu_sr_cy; /* carry (unsigned overflow) */ 7497458071SRichard Henderson static TCGv cpu_sr_ov; /* signed overflow */ 75930c3d00SRichard Henderson static TCGv cpu_lock_addr; 76930c3d00SRichard Henderson static TCGv cpu_lock_value; 77bbe418f2SJia Liu static TCGv_i32 fpcsr; 786f7332baSRichard Henderson static TCGv_i64 cpu_mac; /* MACHI:MACLO */ 79a01deb36SRichard Henderson static TCGv_i32 cpu_dflag; 80bbe418f2SJia Liu 81e67db06eSJia Liu void openrisc_translate_init(void) 82e67db06eSJia Liu { 83bbe418f2SJia Liu static const char * const regnames[] = { 84bbe418f2SJia Liu "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 85bbe418f2SJia Liu "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 86bbe418f2SJia Liu "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 87bbe418f2SJia Liu "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 88bbe418f2SJia Liu }; 89bbe418f2SJia Liu int i; 90bbe418f2SJia Liu 91e1ccc054SRichard Henderson cpu_sr = tcg_global_mem_new(cpu_env, 92bbe418f2SJia Liu offsetof(CPUOpenRISCState, sr), "sr"); 93a01deb36SRichard Henderson cpu_dflag = tcg_global_mem_new_i32(cpu_env, 94a01deb36SRichard Henderson offsetof(CPUOpenRISCState, dflag), 95a01deb36SRichard Henderson "dflag"); 96e1ccc054SRichard Henderson cpu_pc = tcg_global_mem_new(cpu_env, 97bbe418f2SJia Liu offsetof(CPUOpenRISCState, pc), "pc"); 98e1ccc054SRichard Henderson cpu_ppc = tcg_global_mem_new(cpu_env, 99bbe418f2SJia Liu offsetof(CPUOpenRISCState, ppc), "ppc"); 100e1ccc054SRichard Henderson jmp_pc = tcg_global_mem_new(cpu_env, 101bbe418f2SJia Liu offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc"); 10284775c43SRichard Henderson cpu_sr_f = tcg_global_mem_new(cpu_env, 10384775c43SRichard Henderson offsetof(CPUOpenRISCState, sr_f), "sr_f"); 10497458071SRichard Henderson cpu_sr_cy = tcg_global_mem_new(cpu_env, 10597458071SRichard Henderson offsetof(CPUOpenRISCState, sr_cy), "sr_cy"); 10697458071SRichard Henderson cpu_sr_ov = tcg_global_mem_new(cpu_env, 10797458071SRichard Henderson offsetof(CPUOpenRISCState, sr_ov), "sr_ov"); 108930c3d00SRichard Henderson cpu_lock_addr = tcg_global_mem_new(cpu_env, 109930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_addr), 110930c3d00SRichard Henderson "lock_addr"); 111930c3d00SRichard Henderson cpu_lock_value = tcg_global_mem_new(cpu_env, 112930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_value), 113930c3d00SRichard Henderson "lock_value"); 114e1ccc054SRichard Henderson fpcsr = tcg_global_mem_new_i32(cpu_env, 115bbe418f2SJia Liu offsetof(CPUOpenRISCState, fpcsr), 116bbe418f2SJia Liu "fpcsr"); 1176f7332baSRichard Henderson cpu_mac = tcg_global_mem_new_i64(cpu_env, 1186f7332baSRichard Henderson offsetof(CPUOpenRISCState, mac), 1196f7332baSRichard Henderson "mac"); 120bbe418f2SJia Liu for (i = 0; i < 32; i++) { 121e1ccc054SRichard Henderson cpu_R[i] = tcg_global_mem_new(cpu_env, 122d89e71e8SStafford Horne offsetof(CPUOpenRISCState, 123d89e71e8SStafford Horne shadow_gpr[0][i]), 124bbe418f2SJia Liu regnames[i]); 125bbe418f2SJia Liu } 1266597c28dSRichard Henderson cpu_R0 = cpu_R[0]; 127bbe418f2SJia Liu } 128bbe418f2SJia Liu 129bbe418f2SJia Liu static void gen_exception(DisasContext *dc, unsigned int excp) 130bbe418f2SJia Liu { 131bbe418f2SJia Liu TCGv_i32 tmp = tcg_const_i32(excp); 132bbe418f2SJia Liu gen_helper_exception(cpu_env, tmp); 133bbe418f2SJia Liu tcg_temp_free_i32(tmp); 134bbe418f2SJia Liu } 135bbe418f2SJia Liu 136bbe418f2SJia Liu static void gen_illegal_exception(DisasContext *dc) 137bbe418f2SJia Liu { 1381ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 139bbe418f2SJia Liu gen_exception(dc, EXCP_ILLEGAL); 1401ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 141bbe418f2SJia Liu } 142bbe418f2SJia Liu 143bbe418f2SJia Liu /* not used yet, open it when we need or64. */ 144bbe418f2SJia Liu /*#ifdef TARGET_OPENRISC64 145bbe418f2SJia Liu static void check_ob64s(DisasContext *dc) 146bbe418f2SJia Liu { 147bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OB64S)) { 148bbe418f2SJia Liu gen_illegal_exception(dc); 149bbe418f2SJia Liu } 150bbe418f2SJia Liu } 151bbe418f2SJia Liu 152bbe418f2SJia Liu static void check_of64s(DisasContext *dc) 153bbe418f2SJia Liu { 154bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OF64S)) { 155bbe418f2SJia Liu gen_illegal_exception(dc); 156bbe418f2SJia Liu } 157bbe418f2SJia Liu } 158bbe418f2SJia Liu 159bbe418f2SJia Liu static void check_ov64s(DisasContext *dc) 160bbe418f2SJia Liu { 161bbe418f2SJia Liu if (!(dc->flags & CPUCFGR_OV64S)) { 162bbe418f2SJia Liu gen_illegal_exception(dc); 163bbe418f2SJia Liu } 164bbe418f2SJia Liu } 165bbe418f2SJia Liu #endif*/ 166bbe418f2SJia Liu 1676597c28dSRichard Henderson /* We're about to write to REG. On the off-chance that the user is 1686597c28dSRichard Henderson writing to R0, re-instate the architectural register. */ 1696597c28dSRichard Henderson #define check_r0_write(reg) \ 1706597c28dSRichard Henderson do { \ 1716597c28dSRichard Henderson if (unlikely(reg == 0)) { \ 1726597c28dSRichard Henderson cpu_R[0] = cpu_R0; \ 1736597c28dSRichard Henderson } \ 1746597c28dSRichard Henderson } while (0) 1756597c28dSRichard Henderson 17697458071SRichard Henderson static void gen_ove_cy(DisasContext *dc) 1779ecaa27eSRichard Henderson { 1780c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 17997458071SRichard Henderson gen_helper_ove_cy(cpu_env); 1809ecaa27eSRichard Henderson } 1810c53d734SRichard Henderson } 1829ecaa27eSRichard Henderson 18397458071SRichard Henderson static void gen_ove_ov(DisasContext *dc) 1849ecaa27eSRichard Henderson { 1850c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 18697458071SRichard Henderson gen_helper_ove_ov(cpu_env); 1879ecaa27eSRichard Henderson } 1880c53d734SRichard Henderson } 1899ecaa27eSRichard Henderson 19097458071SRichard Henderson static void gen_ove_cyov(DisasContext *dc) 1919ecaa27eSRichard Henderson { 1920c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) { 19397458071SRichard Henderson gen_helper_ove_cyov(cpu_env); 1949ecaa27eSRichard Henderson } 1950c53d734SRichard Henderson } 1969ecaa27eSRichard Henderson 1979ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 1989ecaa27eSRichard Henderson { 1999ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 2009ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2019ecaa27eSRichard Henderson 20297458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0); 20397458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb); 2049ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 20597458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov); 2069ecaa27eSRichard Henderson tcg_temp_free(t0); 2079ecaa27eSRichard Henderson 2089ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2099ecaa27eSRichard Henderson tcg_temp_free(res); 2109ecaa27eSRichard Henderson 21197458071SRichard Henderson gen_ove_cyov(dc); 2129ecaa27eSRichard Henderson } 2139ecaa27eSRichard Henderson 2149ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2159ecaa27eSRichard Henderson { 2169ecaa27eSRichard Henderson TCGv t0 = tcg_const_tl(0); 2179ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2189ecaa27eSRichard Henderson 21997458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0); 22097458071SRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0); 22197458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb); 2229ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb); 22397458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov); 2249ecaa27eSRichard Henderson tcg_temp_free(t0); 2259ecaa27eSRichard Henderson 2269ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2279ecaa27eSRichard Henderson tcg_temp_free(res); 2289ecaa27eSRichard Henderson 22997458071SRichard Henderson gen_ove_cyov(dc); 2309ecaa27eSRichard Henderson } 2319ecaa27eSRichard Henderson 2329ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2339ecaa27eSRichard Henderson { 2349ecaa27eSRichard Henderson TCGv res = tcg_temp_new(); 2359ecaa27eSRichard Henderson 2369ecaa27eSRichard Henderson tcg_gen_sub_tl(res, srca, srcb); 23797458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_cy, srca, srcb); 23897458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, res, srcb); 23997458071SRichard Henderson tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy); 24097458071SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb); 2419ecaa27eSRichard Henderson 2429ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res); 2439ecaa27eSRichard Henderson tcg_temp_free(res); 2449ecaa27eSRichard Henderson 24597458071SRichard Henderson gen_ove_cyov(dc); 2469ecaa27eSRichard Henderson } 2479ecaa27eSRichard Henderson 2489ecaa27eSRichard Henderson static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2499ecaa27eSRichard Henderson { 2509ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 2519ecaa27eSRichard Henderson 25297458071SRichard Henderson tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb); 2539ecaa27eSRichard Henderson tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1); 25497458071SRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0); 2559ecaa27eSRichard Henderson tcg_temp_free(t0); 2569ecaa27eSRichard Henderson 25797458071SRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 25897458071SRichard Henderson gen_ove_ov(dc); 2599ecaa27eSRichard Henderson } 2609ecaa27eSRichard Henderson 2619ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2629ecaa27eSRichard Henderson { 26397458071SRichard Henderson tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb); 26497458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0); 2659ecaa27eSRichard Henderson 26697458071SRichard Henderson gen_ove_cy(dc); 2679ecaa27eSRichard Henderson } 2689ecaa27eSRichard Henderson 2699ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2709ecaa27eSRichard Henderson { 2719ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 2729ecaa27eSRichard Henderson 27397458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0); 2749ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 2759ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 27697458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_ov); 2779ecaa27eSRichard Henderson tcg_gen_div_tl(dest, srca, t0); 2789ecaa27eSRichard Henderson tcg_temp_free(t0); 2799ecaa27eSRichard Henderson 28097458071SRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 28197458071SRichard Henderson gen_ove_ov(dc); 2829ecaa27eSRichard Henderson } 2839ecaa27eSRichard Henderson 2849ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) 2859ecaa27eSRichard Henderson { 2869ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new(); 2879ecaa27eSRichard Henderson 28897458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0); 2899ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined. 2909ecaa27eSRichard Henderson Supress the host-side exception by dividing by 1. */ 29197458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_cy); 2929ecaa27eSRichard Henderson tcg_gen_divu_tl(dest, srca, t0); 2939ecaa27eSRichard Henderson tcg_temp_free(t0); 2949ecaa27eSRichard Henderson 29597458071SRichard Henderson gen_ove_cy(dc); 2969ecaa27eSRichard Henderson } 297da1d7759SSebastian Macke 298cc5de49eSRichard Henderson static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb) 299cc5de49eSRichard Henderson { 300cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 301cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 302cc5de49eSRichard Henderson 303cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 304cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 305cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) { 306cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2); 307cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_ov, 0); 308cc5de49eSRichard Henderson } else { 309cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64(); 310cc5de49eSRichard Henderson 311cc5de49eSRichard Henderson tcg_gen_muls2_i64(cpu_mac, high, t1, t2); 312cc5de49eSRichard Henderson tcg_gen_sari_i64(t1, cpu_mac, 63); 313cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high); 314cc5de49eSRichard Henderson tcg_temp_free_i64(high); 315cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_ov, t1); 316cc5de49eSRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov); 317cc5de49eSRichard Henderson 318cc5de49eSRichard Henderson gen_ove_ov(dc); 319cc5de49eSRichard Henderson } 320cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 321cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 322cc5de49eSRichard Henderson } 323cc5de49eSRichard Henderson 324cc5de49eSRichard Henderson static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb) 325cc5de49eSRichard Henderson { 326cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 327cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 328cc5de49eSRichard Henderson 329cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 330cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 331cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) { 332cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2); 333cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_cy, 0); 334cc5de49eSRichard Henderson } else { 335cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64(); 336cc5de49eSRichard Henderson 337cc5de49eSRichard Henderson tcg_gen_mulu2_i64(cpu_mac, high, t1, t2); 338cc5de49eSRichard Henderson tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0); 339cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, high); 340cc5de49eSRichard Henderson tcg_temp_free_i64(high); 341cc5de49eSRichard Henderson 342cc5de49eSRichard Henderson gen_ove_cy(dc); 343cc5de49eSRichard Henderson } 344cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 345cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 346cc5de49eSRichard Henderson } 347cc5de49eSRichard Henderson 3486f7332baSRichard Henderson static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb) 3496f7332baSRichard Henderson { 3506f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 3516f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 3526f7332baSRichard Henderson 3536f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 3546f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 3556f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 3566f7332baSRichard Henderson 3576f7332baSRichard Henderson /* Note that overflow is only computed during addition stage. */ 3586f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1); 3596f7332baSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1); 3606f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac); 3616f7332baSRichard Henderson tcg_gen_andc_i64(t1, t1, t2); 3626f7332baSRichard Henderson tcg_temp_free_i64(t2); 3636f7332baSRichard Henderson 3646f7332baSRichard Henderson #if TARGET_LONG_BITS == 32 3656f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1); 3666f7332baSRichard Henderson #else 3676f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1); 3686f7332baSRichard Henderson #endif 3696f7332baSRichard Henderson tcg_temp_free_i64(t1); 3706f7332baSRichard Henderson 3716f7332baSRichard Henderson gen_ove_ov(dc); 3726f7332baSRichard Henderson } 3736f7332baSRichard Henderson 374cc5de49eSRichard Henderson static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb) 375cc5de49eSRichard Henderson { 376cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 377cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 378cc5de49eSRichard Henderson 379cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 380cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 381cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 382cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 383cc5de49eSRichard Henderson 384cc5de49eSRichard Henderson /* Note that overflow is only computed during addition stage. */ 385cc5de49eSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1); 386cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1); 387cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t1); 388cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 389cc5de49eSRichard Henderson 390cc5de49eSRichard Henderson gen_ove_cy(dc); 391cc5de49eSRichard Henderson } 392cc5de49eSRichard Henderson 3936f7332baSRichard Henderson static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb) 3946f7332baSRichard Henderson { 3956f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 3966f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 3976f7332baSRichard Henderson 3986f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca); 3996f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb); 4006f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 4016f7332baSRichard Henderson 4026f7332baSRichard Henderson /* Note that overflow is only computed during subtraction stage. */ 4036f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1); 4046f7332baSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1); 4056f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac); 4066f7332baSRichard Henderson tcg_gen_and_i64(t1, t1, t2); 4076f7332baSRichard Henderson tcg_temp_free_i64(t2); 4086f7332baSRichard Henderson 4096f7332baSRichard Henderson #if TARGET_LONG_BITS == 32 4106f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1); 4116f7332baSRichard Henderson #else 4126f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1); 4136f7332baSRichard Henderson #endif 4146f7332baSRichard Henderson tcg_temp_free_i64(t1); 4156f7332baSRichard Henderson 4166f7332baSRichard Henderson gen_ove_ov(dc); 4176f7332baSRichard Henderson } 4186f7332baSRichard Henderson 419cc5de49eSRichard Henderson static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb) 420cc5de49eSRichard Henderson { 421cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 422cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 423cc5de49eSRichard Henderson 424cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca); 425cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb); 426cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2); 427cc5de49eSRichard Henderson 428cc5de49eSRichard Henderson /* Note that overflow is only computed during subtraction stage. */ 429cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1); 430cc5de49eSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1); 431cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t2); 432cc5de49eSRichard Henderson tcg_temp_free_i64(t2); 433cc5de49eSRichard Henderson tcg_temp_free_i64(t1); 434cc5de49eSRichard Henderson 435cc5de49eSRichard Henderson gen_ove_cy(dc); 436cc5de49eSRichard Henderson } 437cc5de49eSRichard Henderson 4383a7be554SRichard Henderson static bool trans_l_add(DisasContext *dc, arg_dab *a) 439bbe418f2SJia Liu { 4406ad216abSRichard Henderson check_r0_write(a->d); 4416ad216abSRichard Henderson gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4426ad216abSRichard Henderson return true; 443bbe418f2SJia Liu } 444bbe418f2SJia Liu 4453a7be554SRichard Henderson static bool trans_l_addc(DisasContext *dc, arg_dab *a) 446bbe418f2SJia Liu { 4476ad216abSRichard Henderson check_r0_write(a->d); 4486ad216abSRichard Henderson gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4496ad216abSRichard Henderson return true; 4506ad216abSRichard Henderson } 4516ad216abSRichard Henderson 4523a7be554SRichard Henderson static bool trans_l_sub(DisasContext *dc, arg_dab *a) 4536ad216abSRichard Henderson { 4546ad216abSRichard Henderson check_r0_write(a->d); 4556ad216abSRichard Henderson gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4566ad216abSRichard Henderson return true; 4576ad216abSRichard Henderson } 4586ad216abSRichard Henderson 4593a7be554SRichard Henderson static bool trans_l_and(DisasContext *dc, arg_dab *a) 4606ad216abSRichard Henderson { 4616ad216abSRichard Henderson check_r0_write(a->d); 4626ad216abSRichard Henderson tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4636ad216abSRichard Henderson return true; 4646ad216abSRichard Henderson } 4656ad216abSRichard Henderson 4663a7be554SRichard Henderson static bool trans_l_or(DisasContext *dc, arg_dab *a) 4676ad216abSRichard Henderson { 4686ad216abSRichard Henderson check_r0_write(a->d); 4696ad216abSRichard Henderson tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4706ad216abSRichard Henderson return true; 4716ad216abSRichard Henderson } 4726ad216abSRichard Henderson 4733a7be554SRichard Henderson static bool trans_l_xor(DisasContext *dc, arg_dab *a) 4746ad216abSRichard Henderson { 4756ad216abSRichard Henderson check_r0_write(a->d); 4766ad216abSRichard Henderson tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4776ad216abSRichard Henderson return true; 4786ad216abSRichard Henderson } 4796ad216abSRichard Henderson 4803a7be554SRichard Henderson static bool trans_l_sll(DisasContext *dc, arg_dab *a) 4816ad216abSRichard Henderson { 4826ad216abSRichard Henderson check_r0_write(a->d); 4836ad216abSRichard Henderson tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4846ad216abSRichard Henderson return true; 4856ad216abSRichard Henderson } 4866ad216abSRichard Henderson 4873a7be554SRichard Henderson static bool trans_l_srl(DisasContext *dc, arg_dab *a) 4886ad216abSRichard Henderson { 4896ad216abSRichard Henderson check_r0_write(a->d); 4906ad216abSRichard Henderson tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4916ad216abSRichard Henderson return true; 4926ad216abSRichard Henderson } 4936ad216abSRichard Henderson 4943a7be554SRichard Henderson static bool trans_l_sra(DisasContext *dc, arg_dab *a) 4956ad216abSRichard Henderson { 4966ad216abSRichard Henderson check_r0_write(a->d); 4976ad216abSRichard Henderson tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 4986ad216abSRichard Henderson return true; 4996ad216abSRichard Henderson } 5006ad216abSRichard Henderson 5013a7be554SRichard Henderson static bool trans_l_ror(DisasContext *dc, arg_dab *a) 5026ad216abSRichard Henderson { 5036ad216abSRichard Henderson check_r0_write(a->d); 5046ad216abSRichard Henderson tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 5056ad216abSRichard Henderson return true; 5066ad216abSRichard Henderson } 5076ad216abSRichard Henderson 5083a7be554SRichard Henderson static bool trans_l_exths(DisasContext *dc, arg_da *a) 5096ad216abSRichard Henderson { 5106ad216abSRichard Henderson check_r0_write(a->d); 5116ad216abSRichard Henderson tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]); 5126ad216abSRichard Henderson return true; 5136ad216abSRichard Henderson } 5146ad216abSRichard Henderson 5153a7be554SRichard Henderson static bool trans_l_extbs(DisasContext *dc, arg_da *a) 5166ad216abSRichard Henderson { 5176ad216abSRichard Henderson check_r0_write(a->d); 5186ad216abSRichard Henderson tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]); 5196ad216abSRichard Henderson return true; 5206ad216abSRichard Henderson } 5216ad216abSRichard Henderson 5223a7be554SRichard Henderson static bool trans_l_exthz(DisasContext *dc, arg_da *a) 5236ad216abSRichard Henderson { 5246ad216abSRichard Henderson check_r0_write(a->d); 5256ad216abSRichard Henderson tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]); 5266ad216abSRichard Henderson return true; 5276ad216abSRichard Henderson } 5286ad216abSRichard Henderson 5293a7be554SRichard Henderson static bool trans_l_extbz(DisasContext *dc, arg_da *a) 5306ad216abSRichard Henderson { 5316ad216abSRichard Henderson check_r0_write(a->d); 5326ad216abSRichard Henderson tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]); 5336ad216abSRichard Henderson return true; 5346ad216abSRichard Henderson } 5356ad216abSRichard Henderson 5363a7be554SRichard Henderson static bool trans_l_cmov(DisasContext *dc, arg_dab *a) 5376ad216abSRichard Henderson { 5386ad216abSRichard Henderson TCGv zero; 5396ad216abSRichard Henderson 5406ad216abSRichard Henderson check_r0_write(a->d); 5416ad216abSRichard Henderson zero = tcg_const_tl(0); 5426ad216abSRichard Henderson tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[a->d], cpu_sr_f, zero, 5436ad216abSRichard Henderson cpu_R[a->a], cpu_R[a->b]); 544784696d1SRichard Henderson tcg_temp_free(zero); 5456ad216abSRichard Henderson return true; 546bbe418f2SJia Liu } 547bbe418f2SJia Liu 5483a7be554SRichard Henderson static bool trans_l_ff1(DisasContext *dc, arg_da *a) 5496ad216abSRichard Henderson { 5506ad216abSRichard Henderson check_r0_write(a->d); 5516ad216abSRichard Henderson tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1); 5526ad216abSRichard Henderson tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1); 5536ad216abSRichard Henderson return true; 554cf2ae442SRichard Henderson } 555cf2ae442SRichard Henderson 5563a7be554SRichard Henderson static bool trans_l_fl1(DisasContext *dc, arg_da *a) 5576ad216abSRichard Henderson { 5586ad216abSRichard Henderson check_r0_write(a->d); 5596ad216abSRichard Henderson tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS); 5606ad216abSRichard Henderson tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]); 5616ad216abSRichard Henderson return true; 562bbe418f2SJia Liu } 563bbe418f2SJia Liu 5643a7be554SRichard Henderson static bool trans_l_mul(DisasContext *dc, arg_dab *a) 5656ad216abSRichard Henderson { 5666ad216abSRichard Henderson check_r0_write(a->d); 5676ad216abSRichard Henderson gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 5686ad216abSRichard Henderson return true; 569bbe418f2SJia Liu } 5706ad216abSRichard Henderson 5713a7be554SRichard Henderson static bool trans_l_mulu(DisasContext *dc, arg_dab *a) 5726ad216abSRichard Henderson { 5736ad216abSRichard Henderson check_r0_write(a->d); 5746ad216abSRichard Henderson gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 5756ad216abSRichard Henderson return true; 576bbe418f2SJia Liu } 5776ad216abSRichard Henderson 5783a7be554SRichard Henderson static bool trans_l_div(DisasContext *dc, arg_dab *a) 5796ad216abSRichard Henderson { 5806ad216abSRichard Henderson check_r0_write(a->d); 5816ad216abSRichard Henderson gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 5826ad216abSRichard Henderson return true; 5836ad216abSRichard Henderson } 5846ad216abSRichard Henderson 5853a7be554SRichard Henderson static bool trans_l_divu(DisasContext *dc, arg_dab *a) 5866ad216abSRichard Henderson { 5876ad216abSRichard Henderson check_r0_write(a->d); 5886ad216abSRichard Henderson gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]); 5896ad216abSRichard Henderson return true; 5906ad216abSRichard Henderson } 5916ad216abSRichard Henderson 5923a7be554SRichard Henderson static bool trans_l_muld(DisasContext *dc, arg_ab *a) 5936ad216abSRichard Henderson { 5946ad216abSRichard Henderson gen_muld(dc, cpu_R[a->a], cpu_R[a->b]); 5956ad216abSRichard Henderson return true; 5966ad216abSRichard Henderson } 5976ad216abSRichard Henderson 5983a7be554SRichard Henderson static bool trans_l_muldu(DisasContext *dc, arg_ab *a) 5996ad216abSRichard Henderson { 6006ad216abSRichard Henderson gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]); 6016ad216abSRichard Henderson return true; 602bbe418f2SJia Liu } 603bbe418f2SJia Liu 6043a7be554SRichard Henderson static bool trans_l_j(DisasContext *dc, arg_l_j *a) 605136e13aeSRichard Henderson { 606136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4; 607136e13aeSRichard Henderson 608136e13aeSRichard Henderson tcg_gen_movi_tl(jmp_pc, tmp_pc); 6098000ba56SRichard Henderson dc->jmp_pc_imm = tmp_pc; 610136e13aeSRichard Henderson dc->delayed_branch = 2; 611136e13aeSRichard Henderson return true; 612136e13aeSRichard Henderson } 613136e13aeSRichard Henderson 6143a7be554SRichard Henderson static bool trans_l_jal(DisasContext *dc, arg_l_jal *a) 615136e13aeSRichard Henderson { 616136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4; 617136e13aeSRichard Henderson target_ulong ret_pc = dc->base.pc_next + 8; 618136e13aeSRichard Henderson 619136e13aeSRichard Henderson tcg_gen_movi_tl(cpu_R[9], ret_pc); 620136e13aeSRichard Henderson /* Optimize jal being used to load the PC for PIC. */ 621136e13aeSRichard Henderson if (tmp_pc != ret_pc) { 622136e13aeSRichard Henderson tcg_gen_movi_tl(jmp_pc, tmp_pc); 6238000ba56SRichard Henderson dc->jmp_pc_imm = tmp_pc; 624136e13aeSRichard Henderson dc->delayed_branch = 2; 625136e13aeSRichard Henderson } 626136e13aeSRichard Henderson return true; 627136e13aeSRichard Henderson } 628136e13aeSRichard Henderson 629136e13aeSRichard Henderson static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond) 630136e13aeSRichard Henderson { 631136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4; 632136e13aeSRichard Henderson TCGv t_next = tcg_const_tl(dc->base.pc_next + 8); 633136e13aeSRichard Henderson TCGv t_true = tcg_const_tl(tmp_pc); 634136e13aeSRichard Henderson TCGv t_zero = tcg_const_tl(0); 635136e13aeSRichard Henderson 636136e13aeSRichard Henderson tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, t_zero, t_true, t_next); 637136e13aeSRichard Henderson 638136e13aeSRichard Henderson tcg_temp_free(t_next); 639136e13aeSRichard Henderson tcg_temp_free(t_true); 640136e13aeSRichard Henderson tcg_temp_free(t_zero); 641136e13aeSRichard Henderson dc->delayed_branch = 2; 642136e13aeSRichard Henderson } 643136e13aeSRichard Henderson 6443a7be554SRichard Henderson static bool trans_l_bf(DisasContext *dc, arg_l_bf *a) 645136e13aeSRichard Henderson { 646136e13aeSRichard Henderson do_bf(dc, a, TCG_COND_NE); 647136e13aeSRichard Henderson return true; 648136e13aeSRichard Henderson } 649136e13aeSRichard Henderson 6503a7be554SRichard Henderson static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a) 651136e13aeSRichard Henderson { 652136e13aeSRichard Henderson do_bf(dc, a, TCG_COND_EQ); 653136e13aeSRichard Henderson return true; 654136e13aeSRichard Henderson } 655136e13aeSRichard Henderson 6563a7be554SRichard Henderson static bool trans_l_jr(DisasContext *dc, arg_l_jr *a) 657136e13aeSRichard Henderson { 658136e13aeSRichard Henderson tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]); 659136e13aeSRichard Henderson dc->delayed_branch = 2; 660136e13aeSRichard Henderson return true; 661136e13aeSRichard Henderson } 662136e13aeSRichard Henderson 6633a7be554SRichard Henderson static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a) 664136e13aeSRichard Henderson { 665136e13aeSRichard Henderson tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]); 666136e13aeSRichard Henderson tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8); 667136e13aeSRichard Henderson dc->delayed_branch = 2; 668136e13aeSRichard Henderson return true; 669136e13aeSRichard Henderson } 670136e13aeSRichard Henderson 6713a7be554SRichard Henderson static bool trans_l_lwa(DisasContext *dc, arg_load *a) 672d80bff19SRichard Henderson { 673d80bff19SRichard Henderson TCGv ea; 674d80bff19SRichard Henderson 675d80bff19SRichard Henderson check_r0_write(a->d); 676d80bff19SRichard Henderson ea = tcg_temp_new(); 677d80bff19SRichard Henderson tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); 678d80bff19SRichard Henderson tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL); 679d80bff19SRichard Henderson tcg_gen_mov_tl(cpu_lock_addr, ea); 680d80bff19SRichard Henderson tcg_gen_mov_tl(cpu_lock_value, cpu_R[a->d]); 681d80bff19SRichard Henderson tcg_temp_free(ea); 682d80bff19SRichard Henderson return true; 683d80bff19SRichard Henderson } 684d80bff19SRichard Henderson 685d80bff19SRichard Henderson static void do_load(DisasContext *dc, arg_load *a, TCGMemOp mop) 686d80bff19SRichard Henderson { 687d80bff19SRichard Henderson TCGv ea; 688d80bff19SRichard Henderson 689d80bff19SRichard Henderson check_r0_write(a->d); 690d80bff19SRichard Henderson ea = tcg_temp_new(); 691d80bff19SRichard Henderson tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); 692d80bff19SRichard Henderson tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop); 693d80bff19SRichard Henderson tcg_temp_free(ea); 694d80bff19SRichard Henderson } 695d80bff19SRichard Henderson 6963a7be554SRichard Henderson static bool trans_l_lwz(DisasContext *dc, arg_load *a) 697d80bff19SRichard Henderson { 698d80bff19SRichard Henderson do_load(dc, a, MO_TEUL); 699d80bff19SRichard Henderson return true; 700d80bff19SRichard Henderson } 701d80bff19SRichard Henderson 7023a7be554SRichard Henderson static bool trans_l_lws(DisasContext *dc, arg_load *a) 703d80bff19SRichard Henderson { 704d80bff19SRichard Henderson do_load(dc, a, MO_TESL); 705d80bff19SRichard Henderson return true; 706d80bff19SRichard Henderson } 707d80bff19SRichard Henderson 7083a7be554SRichard Henderson static bool trans_l_lbz(DisasContext *dc, arg_load *a) 709d80bff19SRichard Henderson { 710d80bff19SRichard Henderson do_load(dc, a, MO_UB); 711d80bff19SRichard Henderson return true; 712d80bff19SRichard Henderson } 713d80bff19SRichard Henderson 7143a7be554SRichard Henderson static bool trans_l_lbs(DisasContext *dc, arg_load *a) 715d80bff19SRichard Henderson { 716d80bff19SRichard Henderson do_load(dc, a, MO_SB); 717d80bff19SRichard Henderson return true; 718d80bff19SRichard Henderson } 719d80bff19SRichard Henderson 7203a7be554SRichard Henderson static bool trans_l_lhz(DisasContext *dc, arg_load *a) 721d80bff19SRichard Henderson { 722d80bff19SRichard Henderson do_load(dc, a, MO_TEUW); 723d80bff19SRichard Henderson return true; 724d80bff19SRichard Henderson } 725d80bff19SRichard Henderson 7263a7be554SRichard Henderson static bool trans_l_lhs(DisasContext *dc, arg_load *a) 727d80bff19SRichard Henderson { 728d80bff19SRichard Henderson do_load(dc, a, MO_TESW); 729d80bff19SRichard Henderson return true; 730d80bff19SRichard Henderson } 731d80bff19SRichard Henderson 7323a7be554SRichard Henderson static bool trans_l_swa(DisasContext *dc, arg_store *a) 733d80bff19SRichard Henderson { 734d80bff19SRichard Henderson TCGv ea, val; 735d80bff19SRichard Henderson TCGLabel *lab_fail, *lab_done; 736d80bff19SRichard Henderson 737d80bff19SRichard Henderson ea = tcg_temp_new(); 738d80bff19SRichard Henderson tcg_gen_addi_tl(ea, cpu_R[a->a], a->i); 739d80bff19SRichard Henderson 740d80bff19SRichard Henderson /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned 741d80bff19SRichard Henderson to cpu_R[0]. Since l.swa is quite often immediately followed by a 742d80bff19SRichard Henderson branch, don't bother reallocating; finish the TB using the "real" R0. 743d80bff19SRichard Henderson This also takes care of RB input across the branch. */ 744d80bff19SRichard Henderson cpu_R[0] = cpu_R0; 745d80bff19SRichard Henderson 746d80bff19SRichard Henderson lab_fail = gen_new_label(); 747d80bff19SRichard Henderson lab_done = gen_new_label(); 748d80bff19SRichard Henderson tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail); 749d80bff19SRichard Henderson tcg_temp_free(ea); 750d80bff19SRichard Henderson 751d80bff19SRichard Henderson val = tcg_temp_new(); 752d80bff19SRichard Henderson tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value, 753d80bff19SRichard Henderson cpu_R[a->b], dc->mem_idx, MO_TEUL); 754d80bff19SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value); 755d80bff19SRichard Henderson tcg_temp_free(val); 756d80bff19SRichard Henderson 757d80bff19SRichard Henderson tcg_gen_br(lab_done); 758d80bff19SRichard Henderson 759d80bff19SRichard Henderson gen_set_label(lab_fail); 760d80bff19SRichard Henderson tcg_gen_movi_tl(cpu_sr_f, 0); 761d80bff19SRichard Henderson 762d80bff19SRichard Henderson gen_set_label(lab_done); 763d80bff19SRichard Henderson tcg_gen_movi_tl(cpu_lock_addr, -1); 764d80bff19SRichard Henderson return true; 765d80bff19SRichard Henderson } 766d80bff19SRichard Henderson 767d80bff19SRichard Henderson static void do_store(DisasContext *dc, arg_store *a, TCGMemOp mop) 768d80bff19SRichard Henderson { 769d80bff19SRichard Henderson TCGv t0 = tcg_temp_new(); 770d80bff19SRichard Henderson tcg_gen_addi_tl(t0, cpu_R[a->a], a->i); 771d80bff19SRichard Henderson tcg_gen_qemu_st_tl(cpu_R[a->b], t0, dc->mem_idx, mop); 772d80bff19SRichard Henderson tcg_temp_free(t0); 773d80bff19SRichard Henderson } 774d80bff19SRichard Henderson 7753a7be554SRichard Henderson static bool trans_l_sw(DisasContext *dc, arg_store *a) 776d80bff19SRichard Henderson { 777d80bff19SRichard Henderson do_store(dc, a, MO_TEUL); 778d80bff19SRichard Henderson return true; 779d80bff19SRichard Henderson } 780d80bff19SRichard Henderson 7813a7be554SRichard Henderson static bool trans_l_sb(DisasContext *dc, arg_store *a) 782d80bff19SRichard Henderson { 783d80bff19SRichard Henderson do_store(dc, a, MO_UB); 784d80bff19SRichard Henderson return true; 785d80bff19SRichard Henderson } 786d80bff19SRichard Henderson 7873a7be554SRichard Henderson static bool trans_l_sh(DisasContext *dc, arg_store *a) 788d80bff19SRichard Henderson { 789d80bff19SRichard Henderson do_store(dc, a, MO_TEUW); 790d80bff19SRichard Henderson return true; 791d80bff19SRichard Henderson } 792d80bff19SRichard Henderson 7933a7be554SRichard Henderson static bool trans_l_nop(DisasContext *dc, arg_l_nop *a) 794bbe418f2SJia Liu { 7958816f70bSRichard Henderson return true; 7968816f70bSRichard Henderson } 7978816f70bSRichard Henderson 7983a7be554SRichard Henderson static bool trans_l_addi(DisasContext *dc, arg_rri *a) 7998816f70bSRichard Henderson { 8009ecaa27eSRichard Henderson TCGv t0; 8015631e69cSRichard Henderson 8028816f70bSRichard Henderson check_r0_write(a->d); 8038816f70bSRichard Henderson t0 = tcg_const_tl(a->i); 8048816f70bSRichard Henderson gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0); 8056f7332baSRichard Henderson tcg_temp_free(t0); 8068816f70bSRichard Henderson return true; 8078816f70bSRichard Henderson } 808bbe418f2SJia Liu 8093a7be554SRichard Henderson static bool trans_l_addic(DisasContext *dc, arg_rri *a) 810bbe418f2SJia Liu { 8118816f70bSRichard Henderson TCGv t0; 8128816f70bSRichard Henderson 8138816f70bSRichard Henderson check_r0_write(a->d); 8148816f70bSRichard Henderson t0 = tcg_const_tl(a->i); 8158816f70bSRichard Henderson gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0); 8168816f70bSRichard Henderson tcg_temp_free(t0); 8178816f70bSRichard Henderson return true; 8188816f70bSRichard Henderson } 8198816f70bSRichard Henderson 8203a7be554SRichard Henderson static bool trans_l_muli(DisasContext *dc, arg_rri *a) 8218816f70bSRichard Henderson { 8228816f70bSRichard Henderson TCGv t0; 8238816f70bSRichard Henderson 8248816f70bSRichard Henderson check_r0_write(a->d); 8258816f70bSRichard Henderson t0 = tcg_const_tl(a->i); 8268816f70bSRichard Henderson gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0); 8278816f70bSRichard Henderson tcg_temp_free(t0); 8288816f70bSRichard Henderson return true; 8298816f70bSRichard Henderson } 8308816f70bSRichard Henderson 8313a7be554SRichard Henderson static bool trans_l_maci(DisasContext *dc, arg_l_maci *a) 8328816f70bSRichard Henderson { 8338816f70bSRichard Henderson TCGv t0; 8348816f70bSRichard Henderson 8358816f70bSRichard Henderson t0 = tcg_const_tl(a->i); 8368816f70bSRichard Henderson gen_mac(dc, cpu_R[a->a], t0); 8378816f70bSRichard Henderson tcg_temp_free(t0); 8388816f70bSRichard Henderson return true; 8398816f70bSRichard Henderson } 8408816f70bSRichard Henderson 8413a7be554SRichard Henderson static bool trans_l_andi(DisasContext *dc, arg_rrk *a) 8428816f70bSRichard Henderson { 8438816f70bSRichard Henderson check_r0_write(a->d); 8448816f70bSRichard Henderson tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k); 8458816f70bSRichard Henderson return true; 8468816f70bSRichard Henderson } 8478816f70bSRichard Henderson 8483a7be554SRichard Henderson static bool trans_l_ori(DisasContext *dc, arg_rrk *a) 8498816f70bSRichard Henderson { 8508816f70bSRichard Henderson check_r0_write(a->d); 8518816f70bSRichard Henderson tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k); 8528816f70bSRichard Henderson return true; 8538816f70bSRichard Henderson } 8548816f70bSRichard Henderson 8553a7be554SRichard Henderson static bool trans_l_xori(DisasContext *dc, arg_rri *a) 8568816f70bSRichard Henderson { 8578816f70bSRichard Henderson check_r0_write(a->d); 8588816f70bSRichard Henderson tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i); 8598816f70bSRichard Henderson return true; 8608816f70bSRichard Henderson } 8618816f70bSRichard Henderson 8623a7be554SRichard Henderson static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a) 8638816f70bSRichard Henderson { 8648816f70bSRichard Henderson check_r0_write(a->d); 8658816f70bSRichard Henderson 8662ba65417SRichard Henderson if (is_user(dc)) { 867bbe418f2SJia Liu gen_illegal_exception(dc); 8688816f70bSRichard Henderson } else { 869c28fa81fSRichard Henderson TCGv spr = tcg_temp_new(); 870c28fa81fSRichard Henderson tcg_gen_ori_tl(spr, cpu_R[a->a], a->k); 871c28fa81fSRichard Henderson gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], spr); 872c28fa81fSRichard Henderson tcg_temp_free(spr); 8734dd044c6SJia Liu } 8748816f70bSRichard Henderson return true; 8758816f70bSRichard Henderson } 876bbe418f2SJia Liu 8773a7be554SRichard Henderson static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a) 8784dd044c6SJia Liu { 8792ba65417SRichard Henderson if (is_user(dc)) { 8804dd044c6SJia Liu gen_illegal_exception(dc); 8818816f70bSRichard Henderson } else { 882c28fa81fSRichard Henderson TCGv spr; 88301ec3ec9SRichard Henderson 88401ec3ec9SRichard Henderson /* For SR, we will need to exit the TB to recognize the new 88501ec3ec9SRichard Henderson * exception state. For NPC, in theory this counts as a branch 88601ec3ec9SRichard Henderson * (although the SPR only exists for use by an ICE). Save all 88701ec3ec9SRichard Henderson * of the cpu state first, allowing it to be overwritten. 88801ec3ec9SRichard Henderson */ 88901ec3ec9SRichard Henderson if (dc->delayed_branch) { 89001ec3ec9SRichard Henderson tcg_gen_mov_tl(cpu_pc, jmp_pc); 89101ec3ec9SRichard Henderson tcg_gen_discard_tl(jmp_pc); 89201ec3ec9SRichard Henderson } else { 89301ec3ec9SRichard Henderson tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4); 89401ec3ec9SRichard Henderson } 89501ec3ec9SRichard Henderson dc->base.is_jmp = DISAS_EXIT; 89601ec3ec9SRichard Henderson 897c28fa81fSRichard Henderson spr = tcg_temp_new(); 898c28fa81fSRichard Henderson tcg_gen_ori_tl(spr, cpu_R[a->a], a->k); 899c28fa81fSRichard Henderson gen_helper_mtspr(cpu_env, spr, cpu_R[a->b]); 900c28fa81fSRichard Henderson tcg_temp_free(spr); 9014dd044c6SJia Liu } 9028816f70bSRichard Henderson return true; 903bbe418f2SJia Liu } 904bbe418f2SJia Liu 9053a7be554SRichard Henderson static bool trans_l_mac(DisasContext *dc, arg_ab *a) 906bbe418f2SJia Liu { 90799d863d6SRichard Henderson gen_mac(dc, cpu_R[a->a], cpu_R[a->b]); 90899d863d6SRichard Henderson return true; 909bbe418f2SJia Liu } 91099d863d6SRichard Henderson 9113a7be554SRichard Henderson static bool trans_l_msb(DisasContext *dc, arg_ab *a) 91299d863d6SRichard Henderson { 91399d863d6SRichard Henderson gen_msb(dc, cpu_R[a->a], cpu_R[a->b]); 91499d863d6SRichard Henderson return true; 91599d863d6SRichard Henderson } 91699d863d6SRichard Henderson 9173a7be554SRichard Henderson static bool trans_l_macu(DisasContext *dc, arg_ab *a) 91899d863d6SRichard Henderson { 91999d863d6SRichard Henderson gen_macu(dc, cpu_R[a->a], cpu_R[a->b]); 92099d863d6SRichard Henderson return true; 92199d863d6SRichard Henderson } 92299d863d6SRichard Henderson 9233a7be554SRichard Henderson static bool trans_l_msbu(DisasContext *dc, arg_ab *a) 92499d863d6SRichard Henderson { 92599d863d6SRichard Henderson gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]); 92699d863d6SRichard Henderson return true; 927bbe418f2SJia Liu } 928bbe418f2SJia Liu 9293a7be554SRichard Henderson static bool trans_l_slli(DisasContext *dc, arg_dal *a) 930bbe418f2SJia Liu { 931e20c2592SRichard Henderson check_r0_write(a->d); 932e20c2592SRichard Henderson tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); 933e20c2592SRichard Henderson return true; 934bbe418f2SJia Liu } 935e20c2592SRichard Henderson 9363a7be554SRichard Henderson static bool trans_l_srli(DisasContext *dc, arg_dal *a) 937e20c2592SRichard Henderson { 938e20c2592SRichard Henderson check_r0_write(a->d); 939e20c2592SRichard Henderson tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); 940e20c2592SRichard Henderson return true; 941e20c2592SRichard Henderson } 942e20c2592SRichard Henderson 9433a7be554SRichard Henderson static bool trans_l_srai(DisasContext *dc, arg_dal *a) 944e20c2592SRichard Henderson { 945e20c2592SRichard Henderson check_r0_write(a->d); 946e20c2592SRichard Henderson tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); 947e20c2592SRichard Henderson return true; 948e20c2592SRichard Henderson } 949e20c2592SRichard Henderson 9503a7be554SRichard Henderson static bool trans_l_rori(DisasContext *dc, arg_dal *a) 951e20c2592SRichard Henderson { 952e20c2592SRichard Henderson check_r0_write(a->d); 953e20c2592SRichard Henderson tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1)); 954e20c2592SRichard Henderson return true; 955bbe418f2SJia Liu } 956bbe418f2SJia Liu 9573a7be554SRichard Henderson static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a) 958bbe418f2SJia Liu { 959e720a571SRichard Henderson check_r0_write(a->d); 960e720a571SRichard Henderson tcg_gen_movi_tl(cpu_R[a->d], a->k << 16); 961e720a571SRichard Henderson return true; 962bbe418f2SJia Liu } 963e720a571SRichard Henderson 9643a7be554SRichard Henderson static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a) 965e720a571SRichard Henderson { 966e720a571SRichard Henderson check_r0_write(a->d); 967e720a571SRichard Henderson tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac); 968e720a571SRichard Henderson tcg_gen_movi_i64(cpu_mac, 0); 969e720a571SRichard Henderson return true; 970bbe418f2SJia Liu } 971bbe418f2SJia Liu 9723a7be554SRichard Henderson static bool trans_l_sfeq(DisasContext *dc, arg_ab *a) 973bbe418f2SJia Liu { 974fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 975fbb3e29aSRichard Henderson return true; 976bbe418f2SJia Liu } 977fbb3e29aSRichard Henderson 9783a7be554SRichard Henderson static bool trans_l_sfne(DisasContext *dc, arg_ab *a) 979fbb3e29aSRichard Henderson { 980fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 981fbb3e29aSRichard Henderson return true; 982fbb3e29aSRichard Henderson } 983fbb3e29aSRichard Henderson 9843a7be554SRichard Henderson static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a) 985fbb3e29aSRichard Henderson { 986fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 987fbb3e29aSRichard Henderson return true; 988fbb3e29aSRichard Henderson } 989fbb3e29aSRichard Henderson 9903a7be554SRichard Henderson static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a) 991fbb3e29aSRichard Henderson { 992fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 993fbb3e29aSRichard Henderson return true; 994fbb3e29aSRichard Henderson } 995fbb3e29aSRichard Henderson 9963a7be554SRichard Henderson static bool trans_l_sfltu(DisasContext *dc, arg_ab *a) 997fbb3e29aSRichard Henderson { 998fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 999fbb3e29aSRichard Henderson return true; 1000fbb3e29aSRichard Henderson } 1001fbb3e29aSRichard Henderson 10023a7be554SRichard Henderson static bool trans_l_sfleu(DisasContext *dc, arg_ab *a) 1003fbb3e29aSRichard Henderson { 1004fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 1005fbb3e29aSRichard Henderson return true; 1006fbb3e29aSRichard Henderson } 1007fbb3e29aSRichard Henderson 10083a7be554SRichard Henderson static bool trans_l_sfgts(DisasContext *dc, arg_ab *a) 1009fbb3e29aSRichard Henderson { 1010fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 1011fbb3e29aSRichard Henderson return true; 1012fbb3e29aSRichard Henderson } 1013fbb3e29aSRichard Henderson 10143a7be554SRichard Henderson static bool trans_l_sfges(DisasContext *dc, arg_ab *a) 1015fbb3e29aSRichard Henderson { 1016fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 1017fbb3e29aSRichard Henderson return true; 1018fbb3e29aSRichard Henderson } 1019fbb3e29aSRichard Henderson 10203a7be554SRichard Henderson static bool trans_l_sflts(DisasContext *dc, arg_ab *a) 1021fbb3e29aSRichard Henderson { 1022fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 1023fbb3e29aSRichard Henderson return true; 1024fbb3e29aSRichard Henderson } 1025fbb3e29aSRichard Henderson 10263a7be554SRichard Henderson static bool trans_l_sfles(DisasContext *dc, arg_ab *a) 1027fbb3e29aSRichard Henderson { 1028fbb3e29aSRichard Henderson tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]); 1029fbb3e29aSRichard Henderson return true; 1030bbe418f2SJia Liu } 1031bbe418f2SJia Liu 10323a7be554SRichard Henderson static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a) 1033bbe418f2SJia Liu { 1034032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i); 1035032de4fcSRichard Henderson return true; 1036bbe418f2SJia Liu } 1037032de4fcSRichard Henderson 10383a7be554SRichard Henderson static bool trans_l_sfnei(DisasContext *dc, arg_ai *a) 1039032de4fcSRichard Henderson { 1040032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i); 1041032de4fcSRichard Henderson return true; 1042032de4fcSRichard Henderson } 1043032de4fcSRichard Henderson 10443a7be554SRichard Henderson static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a) 1045032de4fcSRichard Henderson { 1046032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i); 1047032de4fcSRichard Henderson return true; 1048032de4fcSRichard Henderson } 1049032de4fcSRichard Henderson 10503a7be554SRichard Henderson static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a) 1051032de4fcSRichard Henderson { 1052032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i); 1053032de4fcSRichard Henderson return true; 1054032de4fcSRichard Henderson } 1055032de4fcSRichard Henderson 10563a7be554SRichard Henderson static bool trans_l_sfltui(DisasContext *dc, arg_ai *a) 1057032de4fcSRichard Henderson { 1058032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i); 1059032de4fcSRichard Henderson return true; 1060032de4fcSRichard Henderson } 1061032de4fcSRichard Henderson 10623a7be554SRichard Henderson static bool trans_l_sfleui(DisasContext *dc, arg_ai *a) 1063032de4fcSRichard Henderson { 1064032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i); 1065032de4fcSRichard Henderson return true; 1066032de4fcSRichard Henderson } 1067032de4fcSRichard Henderson 10683a7be554SRichard Henderson static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a) 1069032de4fcSRichard Henderson { 1070032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i); 1071032de4fcSRichard Henderson return true; 1072032de4fcSRichard Henderson } 1073032de4fcSRichard Henderson 10743a7be554SRichard Henderson static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a) 1075032de4fcSRichard Henderson { 1076032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i); 1077032de4fcSRichard Henderson return true; 1078032de4fcSRichard Henderson } 1079032de4fcSRichard Henderson 10803a7be554SRichard Henderson static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a) 1081032de4fcSRichard Henderson { 1082032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i); 1083032de4fcSRichard Henderson return true; 1084032de4fcSRichard Henderson } 1085032de4fcSRichard Henderson 10863a7be554SRichard Henderson static bool trans_l_sflesi(DisasContext *dc, arg_ai *a) 1087032de4fcSRichard Henderson { 1088032de4fcSRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i); 1089032de4fcSRichard Henderson return true; 1090bbe418f2SJia Liu } 1091bbe418f2SJia Liu 10923a7be554SRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a) 1093bbe418f2SJia Liu { 10941ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1095bbe418f2SJia Liu gen_exception(dc, EXCP_SYSCALL); 10961ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 10977de9729fSRichard Henderson return true; 10987de9729fSRichard Henderson } 1099bbe418f2SJia Liu 11003a7be554SRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a) 11017de9729fSRichard Henderson { 11021ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1103bbe418f2SJia Liu gen_exception(dc, EXCP_TRAP); 11041ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 11057de9729fSRichard Henderson return true; 11067de9729fSRichard Henderson } 1107bbe418f2SJia Liu 11083a7be554SRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a) 11097de9729fSRichard Henderson { 111024fc5c0fSRichard Henderson tcg_gen_mb(TCG_MO_ALL); 11117de9729fSRichard Henderson return true; 1112bbe418f2SJia Liu } 11137de9729fSRichard Henderson 11143a7be554SRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a) 11157de9729fSRichard Henderson { 11167de9729fSRichard Henderson return true; 11177de9729fSRichard Henderson } 11187de9729fSRichard Henderson 11193a7be554SRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a) 11207de9729fSRichard Henderson { 11217de9729fSRichard Henderson return true; 1122bbe418f2SJia Liu } 1123bbe418f2SJia Liu 11243a7be554SRichard Henderson static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a) 11258816f70bSRichard Henderson { 11262ba65417SRichard Henderson if (is_user(dc)) { 11278816f70bSRichard Henderson gen_illegal_exception(dc); 11288816f70bSRichard Henderson } else { 11298816f70bSRichard Henderson gen_helper_rfe(cpu_env); 113064e46c95SRichard Henderson dc->base.is_jmp = DISAS_EXIT; 11318816f70bSRichard Henderson } 11328816f70bSRichard Henderson return true; 11338816f70bSRichard Henderson } 11348816f70bSRichard Henderson 11356fd204a2SRichard Henderson static void do_fp2(DisasContext *dc, arg_da *a, 11366fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv)) 1137bbe418f2SJia Liu { 11386fd204a2SRichard Henderson check_r0_write(a->d); 11396fd204a2SRichard Henderson fn(cpu_R[a->d], cpu_env, cpu_R[a->a]); 11404e2d3007SRichard Henderson gen_helper_update_fpcsr(cpu_env); 1141bbe418f2SJia Liu } 11426fd204a2SRichard Henderson 11436fd204a2SRichard Henderson static void do_fp3(DisasContext *dc, arg_dab *a, 11446fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv, TCGv)) 11456fd204a2SRichard Henderson { 11466fd204a2SRichard Henderson check_r0_write(a->d); 11476fd204a2SRichard Henderson fn(cpu_R[a->d], cpu_env, cpu_R[a->a], cpu_R[a->b]); 11486fd204a2SRichard Henderson gen_helper_update_fpcsr(cpu_env); 11496fd204a2SRichard Henderson } 11506fd204a2SRichard Henderson 11516fd204a2SRichard Henderson static void do_fpcmp(DisasContext *dc, arg_ab *a, 11526fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv, TCGv), 11536fd204a2SRichard Henderson bool inv, bool swap) 11546fd204a2SRichard Henderson { 11556fd204a2SRichard Henderson if (swap) { 11566fd204a2SRichard Henderson fn(cpu_sr_f, cpu_env, cpu_R[a->b], cpu_R[a->a]); 11576fd204a2SRichard Henderson } else { 11586fd204a2SRichard Henderson fn(cpu_sr_f, cpu_env, cpu_R[a->a], cpu_R[a->b]); 11596fd204a2SRichard Henderson } 11606fd204a2SRichard Henderson if (inv) { 11616fd204a2SRichard Henderson tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1); 11626fd204a2SRichard Henderson } 11636fd204a2SRichard Henderson gen_helper_update_fpcsr(cpu_env); 11646fd204a2SRichard Henderson } 11656fd204a2SRichard Henderson 11663a7be554SRichard Henderson static bool trans_lf_add_s(DisasContext *dc, arg_dab *a) 11676fd204a2SRichard Henderson { 11686fd204a2SRichard Henderson do_fp3(dc, a, gen_helper_float_add_s); 11696fd204a2SRichard Henderson return true; 11706fd204a2SRichard Henderson } 11716fd204a2SRichard Henderson 11723a7be554SRichard Henderson static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a) 11736fd204a2SRichard Henderson { 11746fd204a2SRichard Henderson do_fp3(dc, a, gen_helper_float_sub_s); 11756fd204a2SRichard Henderson return true; 11766fd204a2SRichard Henderson } 11776fd204a2SRichard Henderson 11783a7be554SRichard Henderson static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a) 11796fd204a2SRichard Henderson { 11806fd204a2SRichard Henderson do_fp3(dc, a, gen_helper_float_mul_s); 11816fd204a2SRichard Henderson return true; 11826fd204a2SRichard Henderson } 11836fd204a2SRichard Henderson 11843a7be554SRichard Henderson static bool trans_lf_div_s(DisasContext *dc, arg_dab *a) 11856fd204a2SRichard Henderson { 11866fd204a2SRichard Henderson do_fp3(dc, a, gen_helper_float_div_s); 11876fd204a2SRichard Henderson return true; 11886fd204a2SRichard Henderson } 11896fd204a2SRichard Henderson 11903a7be554SRichard Henderson static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a) 11916fd204a2SRichard Henderson { 11926fd204a2SRichard Henderson do_fp3(dc, a, gen_helper_float_rem_s); 11936fd204a2SRichard Henderson return true; 11946fd204a2SRichard Henderson } 11956fd204a2SRichard Henderson 11963a7be554SRichard Henderson static bool trans_lf_itof_s(DisasContext *dc, arg_da *a) 11976fd204a2SRichard Henderson { 11986fd204a2SRichard Henderson do_fp2(dc, a, gen_helper_itofs); 11996fd204a2SRichard Henderson return true; 12006fd204a2SRichard Henderson } 12016fd204a2SRichard Henderson 12023a7be554SRichard Henderson static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a) 12036fd204a2SRichard Henderson { 12046fd204a2SRichard Henderson do_fp2(dc, a, gen_helper_ftois); 12056fd204a2SRichard Henderson return true; 12066fd204a2SRichard Henderson } 12076fd204a2SRichard Henderson 12083a7be554SRichard Henderson static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a) 12096fd204a2SRichard Henderson { 12106fd204a2SRichard Henderson check_r0_write(a->d); 12116fd204a2SRichard Henderson gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d], 12126fd204a2SRichard Henderson cpu_R[a->a], cpu_R[a->b]); 12136fd204a2SRichard Henderson gen_helper_update_fpcsr(cpu_env); 12146fd204a2SRichard Henderson return true; 12156fd204a2SRichard Henderson } 12166fd204a2SRichard Henderson 12173a7be554SRichard Henderson static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a) 12186fd204a2SRichard Henderson { 12196fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_eq_s, false, false); 12206fd204a2SRichard Henderson return true; 12216fd204a2SRichard Henderson } 12226fd204a2SRichard Henderson 12233a7be554SRichard Henderson static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a) 12246fd204a2SRichard Henderson { 12256fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_eq_s, true, false); 12266fd204a2SRichard Henderson return true; 12276fd204a2SRichard Henderson } 12286fd204a2SRichard Henderson 12293a7be554SRichard Henderson static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a) 12306fd204a2SRichard Henderson { 12316fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_lt_s, false, true); 12326fd204a2SRichard Henderson return true; 12336fd204a2SRichard Henderson } 12346fd204a2SRichard Henderson 12353a7be554SRichard Henderson static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a) 12366fd204a2SRichard Henderson { 12376fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_le_s, false, true); 12386fd204a2SRichard Henderson return true; 12396fd204a2SRichard Henderson } 12406fd204a2SRichard Henderson 12413a7be554SRichard Henderson static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a) 12426fd204a2SRichard Henderson { 12436fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_lt_s, false, false); 12446fd204a2SRichard Henderson return true; 12456fd204a2SRichard Henderson } 12466fd204a2SRichard Henderson 12473a7be554SRichard Henderson static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a) 12486fd204a2SRichard Henderson { 12496fd204a2SRichard Henderson do_fpcmp(dc, a, gen_helper_float_le_s, false, false); 12506fd204a2SRichard Henderson return true; 1251bbe418f2SJia Liu } 1252bbe418f2SJia Liu 1253a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs) 1254e67db06eSJia Liu { 1255a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcb, DisasContext, base); 12569c489ea6SLluís Vilanova CPUOpenRISCState *env = cs->env_ptr; 1257a4fd3ec3SEmilio G. Cota int bound; 1258bbe418f2SJia Liu 1259a4fd3ec3SEmilio G. Cota dc->mem_idx = cpu_mmu_index(env, false); 12601ffa4bceSEmilio G. Cota dc->tb_flags = dc->base.tb->flags; 1261a01deb36SRichard Henderson dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0; 12628000ba56SRichard Henderson dc->jmp_pc_imm = -1; 12638000ba56SRichard Henderson 1264a4fd3ec3SEmilio G. Cota bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4; 1265a4fd3ec3SEmilio G. Cota dc->base.max_insns = MIN(dc->base.max_insns, bound); 1266190ce7fbSRichard Henderson } 1267bbe418f2SJia Liu 1268a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs) 1269a4fd3ec3SEmilio G. Cota { 1270a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(db, DisasContext, base); 1271bbe418f2SJia Liu 12726597c28dSRichard Henderson /* Allow the TCG optimizer to see that R0 == 0, 12736597c28dSRichard Henderson when it's true, which is the common case. */ 12746597c28dSRichard Henderson if (dc->tb_flags & TB_FLAGS_R0_0) { 12756597c28dSRichard Henderson cpu_R[0] = tcg_const_tl(0); 12766597c28dSRichard Henderson } else { 12776597c28dSRichard Henderson cpu_R[0] = cpu_R0; 12786597c28dSRichard Henderson } 1279a4fd3ec3SEmilio G. Cota } 12806597c28dSRichard Henderson 1281a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 1282a4fd3ec3SEmilio G. Cota { 1283a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1284a4fd3ec3SEmilio G. Cota 12851ffa4bceSEmilio G. Cota tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0) 1286a4fd3ec3SEmilio G. Cota | (dc->base.num_insns > 1 ? 2 : 0)); 1287a4fd3ec3SEmilio G. Cota } 1288bbe418f2SJia Liu 1289a4fd3ec3SEmilio G. Cota static bool openrisc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 1290a4fd3ec3SEmilio G. Cota const CPUBreakpoint *bp) 1291a4fd3ec3SEmilio G. Cota { 1292a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1293a4fd3ec3SEmilio G. Cota 12941ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next); 1295b933066aSRichard Henderson gen_exception(dc, EXCP_DEBUG); 12961ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN; 1297522a0d4eSRichard Henderson /* The address covered by the breakpoint must be included in 1298522a0d4eSRichard Henderson [tb->pc, tb->pc + tb->size) in order to for it to be 1299522a0d4eSRichard Henderson properly cleared -- thus we increment the PC here so that 1300522a0d4eSRichard Henderson the logic setting tb->size below does the right thing. */ 13011ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 1302a4fd3ec3SEmilio G. Cota return true; 1303b933066aSRichard Henderson } 1304b933066aSRichard Henderson 1305a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 1306a4fd3ec3SEmilio G. Cota { 1307a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 1308a4fd3ec3SEmilio G. Cota OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1309c7b6f54bSRichard Henderson uint32_t insn = cpu_ldl_code(&cpu->env, dc->base.pc_next); 1310a4fd3ec3SEmilio G. Cota 1311c7b6f54bSRichard Henderson if (!decode(dc, insn)) { 1312c7b6f54bSRichard Henderson gen_illegal_exception(dc); 1313c7b6f54bSRichard Henderson } 13141ffa4bceSEmilio G. Cota dc->base.pc_next += 4; 131524c32852SRichard Henderson 13168000ba56SRichard Henderson /* When exiting the delay slot normally, exit via jmp_pc. 13178000ba56SRichard Henderson * For DISAS_NORETURN, we have raised an exception and already exited. 13188000ba56SRichard Henderson * For DISAS_EXIT, we found l.rfe in a delay slot. There's nothing 13198000ba56SRichard Henderson * in the manual saying this is illegal, but it surely it should. 13208000ba56SRichard Henderson * At least or1ksim overrides pcnext and ignores the branch. 13218000ba56SRichard Henderson */ 13228000ba56SRichard Henderson if (dc->delayed_branch 13238000ba56SRichard Henderson && --dc->delayed_branch == 0 13248000ba56SRichard Henderson && dc->base.is_jmp == DISAS_NEXT) { 13258000ba56SRichard Henderson dc->base.is_jmp = DISAS_JUMP; 1326bbe418f2SJia Liu } 1327a4fd3ec3SEmilio G. Cota } 1328bbe418f2SJia Liu 1329a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 1330a4fd3ec3SEmilio G. Cota { 1331a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base); 13328000ba56SRichard Henderson target_ulong jmp_dest; 133324c32852SRichard Henderson 1334e0a369cfSRichard Henderson /* If we have already exited the TB, nothing following has effect. */ 1335e0a369cfSRichard Henderson if (dc->base.is_jmp == DISAS_NORETURN) { 1336e0a369cfSRichard Henderson return; 1337e0a369cfSRichard Henderson } 1338e0a369cfSRichard Henderson 13398000ba56SRichard Henderson /* Adjust the delayed branch state for the next TB. */ 1340a01deb36SRichard Henderson if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) { 1341a01deb36SRichard Henderson tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0); 1342a01deb36SRichard Henderson } 1343a01deb36SRichard Henderson 13448000ba56SRichard Henderson /* For DISAS_TOO_MANY, jump to the next insn. */ 13458000ba56SRichard Henderson jmp_dest = dc->base.pc_next; 13468000ba56SRichard Henderson tcg_gen_movi_tl(cpu_ppc, jmp_dest - 4); 13478000ba56SRichard Henderson 13481ffa4bceSEmilio G. Cota switch (dc->base.is_jmp) { 13498000ba56SRichard Henderson case DISAS_JUMP: 13508000ba56SRichard Henderson jmp_dest = dc->jmp_pc_imm; 13518000ba56SRichard Henderson if (jmp_dest == -1) { 13528000ba56SRichard Henderson /* The jump destination is indirect/computed; use jmp_pc. */ 13538000ba56SRichard Henderson tcg_gen_mov_tl(cpu_pc, jmp_pc); 13548000ba56SRichard Henderson tcg_gen_discard_tl(jmp_pc); 13558000ba56SRichard Henderson if (unlikely(dc->base.singlestep_enabled)) { 13568000ba56SRichard Henderson gen_exception(dc, EXCP_DEBUG); 13578000ba56SRichard Henderson } else { 13588000ba56SRichard Henderson tcg_gen_lookup_and_goto_ptr(); 13598000ba56SRichard Henderson } 1360bbe418f2SJia Liu break; 13618000ba56SRichard Henderson } 13628000ba56SRichard Henderson /* The jump destination is direct; use jmp_pc_imm. 13638000ba56SRichard Henderson However, we will have stored into jmp_pc as well; 13648000ba56SRichard Henderson we know now that it wasn't needed. */ 13658000ba56SRichard Henderson tcg_gen_discard_tl(jmp_pc); 13668000ba56SRichard Henderson /* fallthru */ 13678000ba56SRichard Henderson 13688000ba56SRichard Henderson case DISAS_TOO_MANY: 13698000ba56SRichard Henderson if (unlikely(dc->base.singlestep_enabled)) { 13708000ba56SRichard Henderson tcg_gen_movi_tl(cpu_pc, jmp_dest); 13718000ba56SRichard Henderson gen_exception(dc, EXCP_DEBUG); 13728000ba56SRichard Henderson } else if ((dc->base.pc_first ^ jmp_dest) & TARGET_PAGE_MASK) { 13738000ba56SRichard Henderson tcg_gen_movi_tl(cpu_pc, jmp_dest); 13748000ba56SRichard Henderson tcg_gen_lookup_and_goto_ptr(); 13758000ba56SRichard Henderson } else { 13768000ba56SRichard Henderson tcg_gen_goto_tb(0); 13778000ba56SRichard Henderson tcg_gen_movi_tl(cpu_pc, jmp_dest); 13788000ba56SRichard Henderson tcg_gen_exit_tb(dc->base.tb, 0); 13798000ba56SRichard Henderson } 13808000ba56SRichard Henderson break; 13818000ba56SRichard Henderson 138264e46c95SRichard Henderson case DISAS_EXIT: 1383e0a369cfSRichard Henderson if (unlikely(dc->base.singlestep_enabled)) { 1384e0a369cfSRichard Henderson gen_exception(dc, EXCP_DEBUG); 1385e0a369cfSRichard Henderson } else { 138607ea28b4SRichard Henderson tcg_gen_exit_tb(NULL, 0); 1387e0a369cfSRichard Henderson } 1388bbe418f2SJia Liu break; 1389a4fd3ec3SEmilio G. Cota default: 1390a4fd3ec3SEmilio G. Cota g_assert_not_reached(); 1391a4fd3ec3SEmilio G. Cota } 1392bbe418f2SJia Liu } 1393bbe418f2SJia Liu 1394a4fd3ec3SEmilio G. Cota static void openrisc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 1395a4fd3ec3SEmilio G. Cota { 1396a4fd3ec3SEmilio G. Cota DisasContext *s = container_of(dcbase, DisasContext, base); 13970a7df5daSRichard Henderson 1398a4fd3ec3SEmilio G. Cota qemu_log("IN: %s\n", lookup_symbol(s->base.pc_first)); 1399a4fd3ec3SEmilio G. Cota log_target_disas(cs, s->base.pc_first, s->base.tb->size); 1400bbe418f2SJia Liu } 1401a4fd3ec3SEmilio G. Cota 1402a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = { 1403a4fd3ec3SEmilio G. Cota .init_disas_context = openrisc_tr_init_disas_context, 1404a4fd3ec3SEmilio G. Cota .tb_start = openrisc_tr_tb_start, 1405a4fd3ec3SEmilio G. Cota .insn_start = openrisc_tr_insn_start, 1406a4fd3ec3SEmilio G. Cota .breakpoint_check = openrisc_tr_breakpoint_check, 1407a4fd3ec3SEmilio G. Cota .translate_insn = openrisc_tr_translate_insn, 1408a4fd3ec3SEmilio G. Cota .tb_stop = openrisc_tr_tb_stop, 1409a4fd3ec3SEmilio G. Cota .disas_log = openrisc_tr_disas_log, 1410a4fd3ec3SEmilio G. Cota }; 1411a4fd3ec3SEmilio G. Cota 1412*8b86d6d2SRichard Henderson void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 1413a4fd3ec3SEmilio G. Cota { 1414a4fd3ec3SEmilio G. Cota DisasContext ctx; 1415a4fd3ec3SEmilio G. Cota 1416*8b86d6d2SRichard Henderson translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb, max_insns); 1417e67db06eSJia Liu } 1418e67db06eSJia Liu 141990c84c56SMarkus Armbruster void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags) 1420e67db06eSJia Liu { 1421878096eeSAndreas Färber OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1422878096eeSAndreas Färber CPUOpenRISCState *env = &cpu->env; 1423e67db06eSJia Liu int i; 1424878096eeSAndreas Färber 142590c84c56SMarkus Armbruster qemu_fprintf(f, "PC=%08x\n", env->pc); 1426e67db06eSJia Liu for (i = 0; i < 32; ++i) { 142790c84c56SMarkus Armbruster qemu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i), 1428e67db06eSJia Liu (i % 4) == 3 ? '\n' : ' '); 1429e67db06eSJia Liu } 1430e67db06eSJia Liu } 1431e67db06eSJia Liu 1432e67db06eSJia Liu void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1433bad729e2SRichard Henderson target_ulong *data) 1434e67db06eSJia Liu { 1435bad729e2SRichard Henderson env->pc = data[0]; 1436a01deb36SRichard Henderson env->dflag = data[1] & 1; 1437a01deb36SRichard Henderson if (data[1] & 2) { 143824c32852SRichard Henderson env->ppc = env->pc - 4; 143924c32852SRichard Henderson } 1440e67db06eSJia Liu } 1441