1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth * OpenRISC translation
3fcf5ef2aSThomas Huth *
4fcf5ef2aSThomas Huth * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
5fcf5ef2aSThomas Huth * Feng Gao <gf91597@gmail.com>
6fcf5ef2aSThomas Huth *
7fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or
8fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public
9fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either
10779fc6adSThomas Huth * version 2.1 of the License, or (at your option) any later version.
11fcf5ef2aSThomas Huth *
12fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful,
13fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of
14fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15fcf5ef2aSThomas Huth * Lesser General Public License for more details.
16fcf5ef2aSThomas Huth *
17fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public
18fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19fcf5ef2aSThomas Huth */
20fcf5ef2aSThomas Huth
21fcf5ef2aSThomas Huth #include "qemu/osdep.h"
22fcf5ef2aSThomas Huth #include "cpu.h"
23fcf5ef2aSThomas Huth #include "exec/exec-all.h"
24dcb32f1dSPhilippe Mathieu-Daudé #include "tcg/tcg-op.h"
25fcf5ef2aSThomas Huth #include "qemu/log.h"
26fcf5ef2aSThomas Huth #include "qemu/bitops.h"
2790c84c56SMarkus Armbruster #include "qemu/qemu-print.h"
2877fc6f5eSLluís Vilanova #include "exec/translator.h"
29fcf5ef2aSThomas Huth
30fcf5ef2aSThomas Huth #include "exec/helper-proto.h"
31fcf5ef2aSThomas Huth #include "exec/helper-gen.h"
32fcf5ef2aSThomas Huth
33fcf5ef2aSThomas Huth #include "exec/log.h"
34fcf5ef2aSThomas Huth
35d53106c9SRichard Henderson #define HELPER_H "helper.h"
36d53106c9SRichard Henderson #include "exec/helper-info.c.inc"
37d53106c9SRichard Henderson #undef HELPER_H
38d53106c9SRichard Henderson
39d53106c9SRichard Henderson
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
44fcf5ef2aSThomas Huth typedef struct DisasContext {
451ffa4bceSEmilio G. Cota DisasContextBase base;
46fcf5ef2aSThomas Huth uint32_t mem_idx;
47a01deb36SRichard Henderson uint32_t tb_flags;
48fcf5ef2aSThomas Huth uint32_t delayed_branch;
49fe636d37SRichard Henderson uint32_t cpucfgr;
502b13b4b9SRichard Henderson uint32_t avr;
518000ba56SRichard Henderson
528000ba56SRichard Henderson /* If not -1, jmp_pc contains this value and so is a direct jump. */
538000ba56SRichard Henderson target_ulong jmp_pc_imm;
54d29f4368SRichard Henderson
55d29f4368SRichard Henderson /* The temporary corresponding to register 0 for this compilation. */
56d29f4368SRichard Henderson TCGv R0;
57118671f0SRichard Henderson /* The constant zero. */
58118671f0SRichard Henderson TCGv zero;
59fcf5ef2aSThomas Huth } DisasContext;
60fcf5ef2aSThomas Huth
is_user(DisasContext * dc)612ba65417SRichard Henderson static inline bool is_user(DisasContext *dc)
622ba65417SRichard Henderson {
632ba65417SRichard Henderson #ifdef CONFIG_USER_ONLY
642ba65417SRichard Henderson return true;
652ba65417SRichard Henderson #else
66b9bed1b9SRichard Henderson return !(dc->tb_flags & TB_FLAGS_SM);
672ba65417SRichard Henderson #endif
682ba65417SRichard Henderson }
692ba65417SRichard Henderson
707de9729fSRichard Henderson /* Include the auto-generated decoder. */
71abff1abfSPaolo Bonzini #include "decode-insns.c.inc"
727de9729fSRichard Henderson
73fcf5ef2aSThomas Huth static TCGv cpu_sr;
748bba7619SRichard Henderson static TCGv cpu_regs[32];
75fcf5ef2aSThomas Huth static TCGv cpu_pc;
76fcf5ef2aSThomas Huth static TCGv jmp_pc; /* l.jr/l.jalr temp pc */
77fcf5ef2aSThomas Huth static TCGv cpu_ppc;
7884775c43SRichard Henderson static TCGv cpu_sr_f; /* bf/bnf, F flag taken */
7997458071SRichard Henderson static TCGv cpu_sr_cy; /* carry (unsigned overflow) */
8097458071SRichard Henderson static TCGv cpu_sr_ov; /* signed overflow */
81930c3d00SRichard Henderson static TCGv cpu_lock_addr;
82930c3d00SRichard Henderson static TCGv cpu_lock_value;
83fcf5ef2aSThomas Huth static TCGv_i32 fpcsr;
846f7332baSRichard Henderson static TCGv_i64 cpu_mac; /* MACHI:MACLO */
85a01deb36SRichard Henderson static TCGv_i32 cpu_dflag;
86fcf5ef2aSThomas Huth
openrisc_translate_init(void)87fcf5ef2aSThomas Huth void openrisc_translate_init(void)
88fcf5ef2aSThomas Huth {
89fcf5ef2aSThomas Huth static const char * const regnames[] = {
90fcf5ef2aSThomas Huth "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
91fcf5ef2aSThomas Huth "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
92fcf5ef2aSThomas Huth "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
93fcf5ef2aSThomas Huth "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
94fcf5ef2aSThomas Huth };
95fcf5ef2aSThomas Huth int i;
96fcf5ef2aSThomas Huth
97ad75a51eSRichard Henderson cpu_sr = tcg_global_mem_new(tcg_env,
98fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, sr), "sr");
99ad75a51eSRichard Henderson cpu_dflag = tcg_global_mem_new_i32(tcg_env,
100a01deb36SRichard Henderson offsetof(CPUOpenRISCState, dflag),
101a01deb36SRichard Henderson "dflag");
102ad75a51eSRichard Henderson cpu_pc = tcg_global_mem_new(tcg_env,
103fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, pc), "pc");
104ad75a51eSRichard Henderson cpu_ppc = tcg_global_mem_new(tcg_env,
105fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, ppc), "ppc");
106ad75a51eSRichard Henderson jmp_pc = tcg_global_mem_new(tcg_env,
107fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
108ad75a51eSRichard Henderson cpu_sr_f = tcg_global_mem_new(tcg_env,
10984775c43SRichard Henderson offsetof(CPUOpenRISCState, sr_f), "sr_f");
110ad75a51eSRichard Henderson cpu_sr_cy = tcg_global_mem_new(tcg_env,
11197458071SRichard Henderson offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
112ad75a51eSRichard Henderson cpu_sr_ov = tcg_global_mem_new(tcg_env,
11397458071SRichard Henderson offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
114ad75a51eSRichard Henderson cpu_lock_addr = tcg_global_mem_new(tcg_env,
115930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_addr),
116930c3d00SRichard Henderson "lock_addr");
117ad75a51eSRichard Henderson cpu_lock_value = tcg_global_mem_new(tcg_env,
118930c3d00SRichard Henderson offsetof(CPUOpenRISCState, lock_value),
119930c3d00SRichard Henderson "lock_value");
120ad75a51eSRichard Henderson fpcsr = tcg_global_mem_new_i32(tcg_env,
121fcf5ef2aSThomas Huth offsetof(CPUOpenRISCState, fpcsr),
122fcf5ef2aSThomas Huth "fpcsr");
123ad75a51eSRichard Henderson cpu_mac = tcg_global_mem_new_i64(tcg_env,
1246f7332baSRichard Henderson offsetof(CPUOpenRISCState, mac),
1256f7332baSRichard Henderson "mac");
126fcf5ef2aSThomas Huth for (i = 0; i < 32; i++) {
127ad75a51eSRichard Henderson cpu_regs[i] = tcg_global_mem_new(tcg_env,
128d89e71e8SStafford Horne offsetof(CPUOpenRISCState,
129d89e71e8SStafford Horne shadow_gpr[0][i]),
130fcf5ef2aSThomas Huth regnames[i]);
131fcf5ef2aSThomas Huth }
132fcf5ef2aSThomas Huth }
133fcf5ef2aSThomas Huth
gen_exception(DisasContext * dc,unsigned int excp)134fcf5ef2aSThomas Huth static void gen_exception(DisasContext *dc, unsigned int excp)
135fcf5ef2aSThomas Huth {
136ad75a51eSRichard Henderson gen_helper_exception(tcg_env, tcg_constant_i32(excp));
137fcf5ef2aSThomas Huth }
138fcf5ef2aSThomas Huth
gen_illegal_exception(DisasContext * dc)139fcf5ef2aSThomas Huth static void gen_illegal_exception(DisasContext *dc)
140fcf5ef2aSThomas Huth {
1411ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
142fcf5ef2aSThomas Huth gen_exception(dc, EXCP_ILLEGAL);
1431ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN;
144fcf5ef2aSThomas Huth }
145fcf5ef2aSThomas Huth
check_v1_3(DisasContext * dc)1462b13b4b9SRichard Henderson static bool check_v1_3(DisasContext *dc)
1472b13b4b9SRichard Henderson {
1482b13b4b9SRichard Henderson return dc->avr >= 0x01030000;
1492b13b4b9SRichard Henderson }
1502b13b4b9SRichard Henderson
check_of32s(DisasContext * dc)151fe636d37SRichard Henderson static bool check_of32s(DisasContext *dc)
152fcf5ef2aSThomas Huth {
153fe636d37SRichard Henderson return dc->cpucfgr & CPUCFGR_OF32S;
154fcf5ef2aSThomas Huth }
155fcf5ef2aSThomas Huth
check_of64a32s(DisasContext * dc)15662f2b038SRichard Henderson static bool check_of64a32s(DisasContext *dc)
15762f2b038SRichard Henderson {
15862f2b038SRichard Henderson return dc->cpucfgr & CPUCFGR_OF64A32S;
15962f2b038SRichard Henderson }
16062f2b038SRichard Henderson
cpu_R(DisasContext * dc,int reg)1618bba7619SRichard Henderson static TCGv cpu_R(DisasContext *dc, int reg)
1628bba7619SRichard Henderson {
163d29f4368SRichard Henderson if (reg == 0) {
164d29f4368SRichard Henderson return dc->R0;
165d29f4368SRichard Henderson } else {
1668bba7619SRichard Henderson return cpu_regs[reg];
1678bba7619SRichard Henderson }
168d29f4368SRichard Henderson }
1698bba7619SRichard Henderson
170cdd0f459SRichard Henderson /*
171cdd0f459SRichard Henderson * We're about to write to REG. On the off-chance that the user is
172cdd0f459SRichard Henderson * writing to R0, re-instate the architectural register.
173cdd0f459SRichard Henderson */
check_r0_write(DisasContext * dc,int reg)174cdd0f459SRichard Henderson static void check_r0_write(DisasContext *dc, int reg)
175cdd0f459SRichard Henderson {
176cdd0f459SRichard Henderson if (unlikely(reg == 0)) {
177d29f4368SRichard Henderson dc->R0 = cpu_regs[0];
178cdd0f459SRichard Henderson }
179cdd0f459SRichard Henderson }
1806597c28dSRichard Henderson
gen_ove_cy(DisasContext * dc)18197458071SRichard Henderson static void gen_ove_cy(DisasContext *dc)
1829ecaa27eSRichard Henderson {
1830c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) {
184ad75a51eSRichard Henderson gen_helper_ove_cy(tcg_env);
1859ecaa27eSRichard Henderson }
1860c53d734SRichard Henderson }
1879ecaa27eSRichard Henderson
gen_ove_ov(DisasContext * dc)18897458071SRichard Henderson static void gen_ove_ov(DisasContext *dc)
1899ecaa27eSRichard Henderson {
1900c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) {
191ad75a51eSRichard Henderson gen_helper_ove_ov(tcg_env);
1929ecaa27eSRichard Henderson }
1930c53d734SRichard Henderson }
1949ecaa27eSRichard Henderson
gen_ove_cyov(DisasContext * dc)19597458071SRichard Henderson static void gen_ove_cyov(DisasContext *dc)
1969ecaa27eSRichard Henderson {
1970c53d734SRichard Henderson if (dc->tb_flags & SR_OVE) {
198ad75a51eSRichard Henderson gen_helper_ove_cyov(tcg_env);
1999ecaa27eSRichard Henderson }
2000c53d734SRichard Henderson }
2019ecaa27eSRichard Henderson
gen_add(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2029ecaa27eSRichard Henderson static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2039ecaa27eSRichard Henderson {
204e0efc48fSRichard Henderson TCGv t0 = tcg_temp_new();
2059ecaa27eSRichard Henderson TCGv res = tcg_temp_new();
2069ecaa27eSRichard Henderson
207e0efc48fSRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, srcb, dc->zero);
20897458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2099ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb);
21097458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2119ecaa27eSRichard Henderson
2129ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res);
2139ecaa27eSRichard Henderson
21497458071SRichard Henderson gen_ove_cyov(dc);
2159ecaa27eSRichard Henderson }
2169ecaa27eSRichard Henderson
gen_addc(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2179ecaa27eSRichard Henderson static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2189ecaa27eSRichard Henderson {
219e0efc48fSRichard Henderson TCGv t0 = tcg_temp_new();
2209ecaa27eSRichard Henderson TCGv res = tcg_temp_new();
2219ecaa27eSRichard Henderson
222e0efc48fSRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, cpu_sr_cy, dc->zero);
223e0efc48fSRichard Henderson tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, dc->zero);
22497458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
2259ecaa27eSRichard Henderson tcg_gen_xor_tl(t0, res, srcb);
22697458071SRichard Henderson tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
2279ecaa27eSRichard Henderson
2289ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res);
2299ecaa27eSRichard Henderson
23097458071SRichard Henderson gen_ove_cyov(dc);
2319ecaa27eSRichard Henderson }
2329ecaa27eSRichard Henderson
gen_sub(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2339ecaa27eSRichard Henderson static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2349ecaa27eSRichard Henderson {
2359ecaa27eSRichard Henderson TCGv res = tcg_temp_new();
2369ecaa27eSRichard Henderson
2379ecaa27eSRichard Henderson tcg_gen_sub_tl(res, srca, srcb);
23897458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
23997458071SRichard Henderson tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
24097458071SRichard Henderson tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
24197458071SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
2429ecaa27eSRichard Henderson
2439ecaa27eSRichard Henderson tcg_gen_mov_tl(dest, res);
2449ecaa27eSRichard Henderson
24597458071SRichard Henderson gen_ove_cyov(dc);
2469ecaa27eSRichard Henderson }
2479ecaa27eSRichard Henderson
gen_mul(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)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);
254cfe15887SRichard Henderson tcg_gen_negsetcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
2559ecaa27eSRichard Henderson
25697458071SRichard Henderson gen_ove_ov(dc);
2579ecaa27eSRichard Henderson }
2589ecaa27eSRichard Henderson
gen_mulu(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2599ecaa27eSRichard Henderson static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2609ecaa27eSRichard Henderson {
26197458071SRichard Henderson tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
26297458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
2639ecaa27eSRichard Henderson
26497458071SRichard Henderson gen_ove_cy(dc);
2659ecaa27eSRichard Henderson }
2669ecaa27eSRichard Henderson
gen_div(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2679ecaa27eSRichard Henderson static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2689ecaa27eSRichard Henderson {
2699ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new();
2709ecaa27eSRichard Henderson
27197458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
2729ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined.
2738b81968cSMichael Tokarev Suppress the host-side exception by dividing by 1. */
27497458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
2759ecaa27eSRichard Henderson tcg_gen_div_tl(dest, srca, t0);
2769ecaa27eSRichard Henderson
27797458071SRichard Henderson tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
27897458071SRichard Henderson gen_ove_ov(dc);
2799ecaa27eSRichard Henderson }
2809ecaa27eSRichard Henderson
gen_divu(DisasContext * dc,TCGv dest,TCGv srca,TCGv srcb)2819ecaa27eSRichard Henderson static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
2829ecaa27eSRichard Henderson {
2839ecaa27eSRichard Henderson TCGv t0 = tcg_temp_new();
2849ecaa27eSRichard Henderson
28597458071SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
2869ecaa27eSRichard Henderson /* The result of divide-by-zero is undefined.
2878b81968cSMichael Tokarev Suppress the host-side exception by dividing by 1. */
28897458071SRichard Henderson tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
2899ecaa27eSRichard Henderson tcg_gen_divu_tl(dest, srca, t0);
2909ecaa27eSRichard Henderson
29197458071SRichard Henderson gen_ove_cy(dc);
2929ecaa27eSRichard Henderson }
293fcf5ef2aSThomas Huth
gen_muld(DisasContext * dc,TCGv srca,TCGv srcb)294cc5de49eSRichard Henderson static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
295cc5de49eSRichard Henderson {
296cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
297cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
298cc5de49eSRichard Henderson
299cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t1, srca);
300cc5de49eSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb);
301cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) {
302cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2);
303cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_ov, 0);
304cc5de49eSRichard Henderson } else {
305cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64();
306cc5de49eSRichard Henderson
307cc5de49eSRichard Henderson tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
308cc5de49eSRichard Henderson tcg_gen_sari_i64(t1, cpu_mac, 63);
309cfe15887SRichard Henderson tcg_gen_negsetcond_i64(TCG_COND_NE, t1, t1, high);
310cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
311cc5de49eSRichard Henderson
312cc5de49eSRichard Henderson gen_ove_ov(dc);
313cc5de49eSRichard Henderson }
314cc5de49eSRichard Henderson }
315cc5de49eSRichard Henderson
gen_muldu(DisasContext * dc,TCGv srca,TCGv srcb)316cc5de49eSRichard Henderson static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
317cc5de49eSRichard Henderson {
318cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
319cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
320cc5de49eSRichard Henderson
321cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca);
322cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb);
323cc5de49eSRichard Henderson if (TARGET_LONG_BITS == 32) {
324cc5de49eSRichard Henderson tcg_gen_mul_i64(cpu_mac, t1, t2);
325cc5de49eSRichard Henderson tcg_gen_movi_tl(cpu_sr_cy, 0);
326cc5de49eSRichard Henderson } else {
327cc5de49eSRichard Henderson TCGv_i64 high = tcg_temp_new_i64();
328cc5de49eSRichard Henderson
329cc5de49eSRichard Henderson tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
330cc5de49eSRichard Henderson tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
331cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
332cc5de49eSRichard Henderson
333cc5de49eSRichard Henderson gen_ove_cy(dc);
334cc5de49eSRichard Henderson }
335cc5de49eSRichard Henderson }
336cc5de49eSRichard Henderson
gen_mac(DisasContext * dc,TCGv srca,TCGv srcb)3376f7332baSRichard Henderson static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
3386f7332baSRichard Henderson {
3396f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
3406f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
3416f7332baSRichard Henderson
3426f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca);
3436f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb);
3446f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2);
3456f7332baSRichard Henderson
3466f7332baSRichard Henderson /* Note that overflow is only computed during addition stage. */
3476f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1);
3486f7332baSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
3496f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac);
3506f7332baSRichard Henderson tcg_gen_andc_i64(t1, t1, t2);
3516f7332baSRichard Henderson
3526f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
3536f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
3546f7332baSRichard Henderson #else
3556f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1);
3566f7332baSRichard Henderson #endif
3576f7332baSRichard Henderson
3586f7332baSRichard Henderson gen_ove_ov(dc);
3596f7332baSRichard Henderson }
3606f7332baSRichard Henderson
gen_macu(DisasContext * dc,TCGv srca,TCGv srcb)361cc5de49eSRichard Henderson static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
362cc5de49eSRichard Henderson {
363cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
364cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
365cc5de49eSRichard Henderson
366cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca);
367cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb);
368cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2);
369cc5de49eSRichard Henderson
370cc5de49eSRichard Henderson /* Note that overflow is only computed during addition stage. */
371cc5de49eSRichard Henderson tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
372cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
373cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
374cc5de49eSRichard Henderson
375cc5de49eSRichard Henderson gen_ove_cy(dc);
376cc5de49eSRichard Henderson }
377cc5de49eSRichard Henderson
gen_msb(DisasContext * dc,TCGv srca,TCGv srcb)3786f7332baSRichard Henderson static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
3796f7332baSRichard Henderson {
3806f7332baSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
3816f7332baSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
3826f7332baSRichard Henderson
3836f7332baSRichard Henderson tcg_gen_ext_tl_i64(t1, srca);
3846f7332baSRichard Henderson tcg_gen_ext_tl_i64(t2, srcb);
3856f7332baSRichard Henderson tcg_gen_mul_i64(t1, t1, t2);
3866f7332baSRichard Henderson
3876f7332baSRichard Henderson /* Note that overflow is only computed during subtraction stage. */
3886f7332baSRichard Henderson tcg_gen_xor_i64(t2, cpu_mac, t1);
3896f7332baSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
3906f7332baSRichard Henderson tcg_gen_xor_i64(t1, t1, cpu_mac);
3916f7332baSRichard Henderson tcg_gen_and_i64(t1, t1, t2);
3926f7332baSRichard Henderson
3936f7332baSRichard Henderson #if TARGET_LONG_BITS == 32
3946f7332baSRichard Henderson tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
3956f7332baSRichard Henderson #else
3966f7332baSRichard Henderson tcg_gen_mov_i64(cpu_sr_ov, t1);
3976f7332baSRichard Henderson #endif
3986f7332baSRichard Henderson
3996f7332baSRichard Henderson gen_ove_ov(dc);
4006f7332baSRichard Henderson }
4016f7332baSRichard Henderson
gen_msbu(DisasContext * dc,TCGv srca,TCGv srcb)402cc5de49eSRichard Henderson static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
403cc5de49eSRichard Henderson {
404cc5de49eSRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64();
405cc5de49eSRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64();
406cc5de49eSRichard Henderson
407cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t1, srca);
408cc5de49eSRichard Henderson tcg_gen_extu_tl_i64(t2, srcb);
409cc5de49eSRichard Henderson tcg_gen_mul_i64(t1, t1, t2);
410cc5de49eSRichard Henderson
411cc5de49eSRichard Henderson /* Note that overflow is only computed during subtraction stage. */
412cc5de49eSRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
413cc5de49eSRichard Henderson tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
414cc5de49eSRichard Henderson tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
415cc5de49eSRichard Henderson
416cc5de49eSRichard Henderson gen_ove_cy(dc);
417cc5de49eSRichard Henderson }
418cc5de49eSRichard Henderson
trans_l_add(DisasContext * dc,arg_dab * a)4193a7be554SRichard Henderson static bool trans_l_add(DisasContext *dc, arg_dab *a)
420fcf5ef2aSThomas Huth {
421cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4228bba7619SRichard Henderson gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4236ad216abSRichard Henderson return true;
424fcf5ef2aSThomas Huth }
425fcf5ef2aSThomas Huth
trans_l_addc(DisasContext * dc,arg_dab * a)4263a7be554SRichard Henderson static bool trans_l_addc(DisasContext *dc, arg_dab *a)
427fcf5ef2aSThomas Huth {
428cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4298bba7619SRichard Henderson gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4306ad216abSRichard Henderson return true;
4316ad216abSRichard Henderson }
4326ad216abSRichard Henderson
trans_l_sub(DisasContext * dc,arg_dab * a)4333a7be554SRichard Henderson static bool trans_l_sub(DisasContext *dc, arg_dab *a)
4346ad216abSRichard Henderson {
435cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4368bba7619SRichard Henderson gen_sub(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4376ad216abSRichard Henderson return true;
4386ad216abSRichard Henderson }
4396ad216abSRichard Henderson
trans_l_and(DisasContext * dc,arg_dab * a)4403a7be554SRichard Henderson static bool trans_l_and(DisasContext *dc, arg_dab *a)
4416ad216abSRichard Henderson {
442cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4438bba7619SRichard Henderson tcg_gen_and_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4446ad216abSRichard Henderson return true;
4456ad216abSRichard Henderson }
4466ad216abSRichard Henderson
trans_l_or(DisasContext * dc,arg_dab * a)4473a7be554SRichard Henderson static bool trans_l_or(DisasContext *dc, arg_dab *a)
4486ad216abSRichard Henderson {
449cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4508bba7619SRichard Henderson tcg_gen_or_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4516ad216abSRichard Henderson return true;
4526ad216abSRichard Henderson }
4536ad216abSRichard Henderson
trans_l_xor(DisasContext * dc,arg_dab * a)4543a7be554SRichard Henderson static bool trans_l_xor(DisasContext *dc, arg_dab *a)
4556ad216abSRichard Henderson {
456cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4578bba7619SRichard Henderson tcg_gen_xor_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4586ad216abSRichard Henderson return true;
4596ad216abSRichard Henderson }
4606ad216abSRichard Henderson
trans_l_sll(DisasContext * dc,arg_dab * a)4613a7be554SRichard Henderson static bool trans_l_sll(DisasContext *dc, arg_dab *a)
4626ad216abSRichard Henderson {
463cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4648bba7619SRichard Henderson tcg_gen_shl_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4656ad216abSRichard Henderson return true;
4666ad216abSRichard Henderson }
4676ad216abSRichard Henderson
trans_l_srl(DisasContext * dc,arg_dab * a)4683a7be554SRichard Henderson static bool trans_l_srl(DisasContext *dc, arg_dab *a)
4696ad216abSRichard Henderson {
470cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4718bba7619SRichard Henderson tcg_gen_shr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4726ad216abSRichard Henderson return true;
4736ad216abSRichard Henderson }
4746ad216abSRichard Henderson
trans_l_sra(DisasContext * dc,arg_dab * a)4753a7be554SRichard Henderson static bool trans_l_sra(DisasContext *dc, arg_dab *a)
4766ad216abSRichard Henderson {
477cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4788bba7619SRichard Henderson tcg_gen_sar_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4796ad216abSRichard Henderson return true;
4806ad216abSRichard Henderson }
4816ad216abSRichard Henderson
trans_l_ror(DisasContext * dc,arg_dab * a)4823a7be554SRichard Henderson static bool trans_l_ror(DisasContext *dc, arg_dab *a)
4836ad216abSRichard Henderson {
484cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4858bba7619SRichard Henderson tcg_gen_rotr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
4866ad216abSRichard Henderson return true;
4876ad216abSRichard Henderson }
4886ad216abSRichard Henderson
trans_l_exths(DisasContext * dc,arg_da * a)4893a7be554SRichard Henderson static bool trans_l_exths(DisasContext *dc, arg_da *a)
4906ad216abSRichard Henderson {
491cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4928bba7619SRichard Henderson tcg_gen_ext16s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
4936ad216abSRichard Henderson return true;
4946ad216abSRichard Henderson }
4956ad216abSRichard Henderson
trans_l_extbs(DisasContext * dc,arg_da * a)4963a7be554SRichard Henderson static bool trans_l_extbs(DisasContext *dc, arg_da *a)
4976ad216abSRichard Henderson {
498cdd0f459SRichard Henderson check_r0_write(dc, a->d);
4998bba7619SRichard Henderson tcg_gen_ext8s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
5006ad216abSRichard Henderson return true;
5016ad216abSRichard Henderson }
5026ad216abSRichard Henderson
trans_l_exthz(DisasContext * dc,arg_da * a)5033a7be554SRichard Henderson static bool trans_l_exthz(DisasContext *dc, arg_da *a)
5046ad216abSRichard Henderson {
505cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5068bba7619SRichard Henderson tcg_gen_ext16u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
5076ad216abSRichard Henderson return true;
5086ad216abSRichard Henderson }
5096ad216abSRichard Henderson
trans_l_extbz(DisasContext * dc,arg_da * a)5103a7be554SRichard Henderson static bool trans_l_extbz(DisasContext *dc, arg_da *a)
5116ad216abSRichard Henderson {
512cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5138bba7619SRichard Henderson tcg_gen_ext8u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
5146ad216abSRichard Henderson return true;
5156ad216abSRichard Henderson }
5166ad216abSRichard Henderson
trans_l_cmov(DisasContext * dc,arg_dab * a)5173a7be554SRichard Henderson static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
5186ad216abSRichard Henderson {
519cdd0f459SRichard Henderson check_r0_write(dc, a->d);
520118671f0SRichard Henderson tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, dc->zero,
5218bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
5226ad216abSRichard Henderson return true;
523fcf5ef2aSThomas Huth }
524fcf5ef2aSThomas Huth
trans_l_ff1(DisasContext * dc,arg_da * a)5253a7be554SRichard Henderson static bool trans_l_ff1(DisasContext *dc, arg_da *a)
5266ad216abSRichard Henderson {
527cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5288bba7619SRichard Henderson tcg_gen_ctzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), -1);
5298bba7619SRichard Henderson tcg_gen_addi_tl(cpu_R(dc, a->d), cpu_R(dc, a->d), 1);
5306ad216abSRichard Henderson return true;
531cf2ae442SRichard Henderson }
532cf2ae442SRichard Henderson
trans_l_fl1(DisasContext * dc,arg_da * a)5333a7be554SRichard Henderson static bool trans_l_fl1(DisasContext *dc, arg_da *a)
5346ad216abSRichard Henderson {
535cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5368bba7619SRichard Henderson tcg_gen_clzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), TARGET_LONG_BITS);
5378bba7619SRichard Henderson tcg_gen_subfi_tl(cpu_R(dc, a->d), TARGET_LONG_BITS, cpu_R(dc, a->d));
5386ad216abSRichard Henderson return true;
539fcf5ef2aSThomas Huth }
540fcf5ef2aSThomas Huth
trans_l_mul(DisasContext * dc,arg_dab * a)5413a7be554SRichard Henderson static bool trans_l_mul(DisasContext *dc, arg_dab *a)
5426ad216abSRichard Henderson {
543cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5448bba7619SRichard Henderson gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
5456ad216abSRichard Henderson return true;
546fcf5ef2aSThomas Huth }
5476ad216abSRichard Henderson
trans_l_mulu(DisasContext * dc,arg_dab * a)5483a7be554SRichard Henderson static bool trans_l_mulu(DisasContext *dc, arg_dab *a)
5496ad216abSRichard Henderson {
550cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5518bba7619SRichard Henderson gen_mulu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
5526ad216abSRichard Henderson return true;
553fcf5ef2aSThomas Huth }
5546ad216abSRichard Henderson
trans_l_div(DisasContext * dc,arg_dab * a)5553a7be554SRichard Henderson static bool trans_l_div(DisasContext *dc, arg_dab *a)
5566ad216abSRichard Henderson {
557cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5588bba7619SRichard Henderson gen_div(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
5596ad216abSRichard Henderson return true;
5606ad216abSRichard Henderson }
5616ad216abSRichard Henderson
trans_l_divu(DisasContext * dc,arg_dab * a)5623a7be554SRichard Henderson static bool trans_l_divu(DisasContext *dc, arg_dab *a)
5636ad216abSRichard Henderson {
564cdd0f459SRichard Henderson check_r0_write(dc, a->d);
5658bba7619SRichard Henderson gen_divu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
5666ad216abSRichard Henderson return true;
5676ad216abSRichard Henderson }
5686ad216abSRichard Henderson
trans_l_muld(DisasContext * dc,arg_ab * a)5693a7be554SRichard Henderson static bool trans_l_muld(DisasContext *dc, arg_ab *a)
5706ad216abSRichard Henderson {
5718bba7619SRichard Henderson gen_muld(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
5726ad216abSRichard Henderson return true;
5736ad216abSRichard Henderson }
5746ad216abSRichard Henderson
trans_l_muldu(DisasContext * dc,arg_ab * a)5753a7be554SRichard Henderson static bool trans_l_muldu(DisasContext *dc, arg_ab *a)
5766ad216abSRichard Henderson {
5778bba7619SRichard Henderson gen_muldu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
5786ad216abSRichard Henderson return true;
579fcf5ef2aSThomas Huth }
580fcf5ef2aSThomas Huth
trans_l_j(DisasContext * dc,arg_l_j * a)5813a7be554SRichard Henderson static bool trans_l_j(DisasContext *dc, arg_l_j *a)
582136e13aeSRichard Henderson {
583136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
584136e13aeSRichard Henderson
585136e13aeSRichard Henderson tcg_gen_movi_tl(jmp_pc, tmp_pc);
5868000ba56SRichard Henderson dc->jmp_pc_imm = tmp_pc;
587136e13aeSRichard Henderson dc->delayed_branch = 2;
588136e13aeSRichard Henderson return true;
589136e13aeSRichard Henderson }
590136e13aeSRichard Henderson
trans_l_jal(DisasContext * dc,arg_l_jal * a)5913a7be554SRichard Henderson static bool trans_l_jal(DisasContext *dc, arg_l_jal *a)
592136e13aeSRichard Henderson {
593136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
594136e13aeSRichard Henderson target_ulong ret_pc = dc->base.pc_next + 8;
595136e13aeSRichard Henderson
5968bba7619SRichard Henderson tcg_gen_movi_tl(cpu_regs[9], ret_pc);
597136e13aeSRichard Henderson /* Optimize jal being used to load the PC for PIC. */
598136e13aeSRichard Henderson if (tmp_pc != ret_pc) {
599136e13aeSRichard Henderson tcg_gen_movi_tl(jmp_pc, tmp_pc);
6008000ba56SRichard Henderson dc->jmp_pc_imm = tmp_pc;
601136e13aeSRichard Henderson dc->delayed_branch = 2;
602136e13aeSRichard Henderson }
603136e13aeSRichard Henderson return true;
604136e13aeSRichard Henderson }
605136e13aeSRichard Henderson
do_bf(DisasContext * dc,arg_l_bf * a,TCGCond cond)606136e13aeSRichard Henderson static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
607136e13aeSRichard Henderson {
608136e13aeSRichard Henderson target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
609af42d354SRichard Henderson TCGv t_next = tcg_constant_tl(dc->base.pc_next + 8);
610af42d354SRichard Henderson TCGv t_true = tcg_constant_tl(tmp_pc);
611136e13aeSRichard Henderson
612118671f0SRichard Henderson tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, dc->zero, t_true, t_next);
613136e13aeSRichard Henderson dc->delayed_branch = 2;
614136e13aeSRichard Henderson }
615136e13aeSRichard Henderson
trans_l_bf(DisasContext * dc,arg_l_bf * a)6163a7be554SRichard Henderson static bool trans_l_bf(DisasContext *dc, arg_l_bf *a)
617136e13aeSRichard Henderson {
618136e13aeSRichard Henderson do_bf(dc, a, TCG_COND_NE);
619136e13aeSRichard Henderson return true;
620136e13aeSRichard Henderson }
621136e13aeSRichard Henderson
trans_l_bnf(DisasContext * dc,arg_l_bf * a)6223a7be554SRichard Henderson static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a)
623136e13aeSRichard Henderson {
624136e13aeSRichard Henderson do_bf(dc, a, TCG_COND_EQ);
625136e13aeSRichard Henderson return true;
626136e13aeSRichard Henderson }
627136e13aeSRichard Henderson
trans_l_jr(DisasContext * dc,arg_l_jr * a)6283a7be554SRichard Henderson static bool trans_l_jr(DisasContext *dc, arg_l_jr *a)
629136e13aeSRichard Henderson {
6308bba7619SRichard Henderson tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
631136e13aeSRichard Henderson dc->delayed_branch = 2;
632136e13aeSRichard Henderson return true;
633136e13aeSRichard Henderson }
634136e13aeSRichard Henderson
trans_l_jalr(DisasContext * dc,arg_l_jalr * a)6353a7be554SRichard Henderson static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a)
636136e13aeSRichard Henderson {
6378bba7619SRichard Henderson tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
6388bba7619SRichard Henderson tcg_gen_movi_tl(cpu_regs[9], dc->base.pc_next + 8);
639136e13aeSRichard Henderson dc->delayed_branch = 2;
640136e13aeSRichard Henderson return true;
641136e13aeSRichard Henderson }
642136e13aeSRichard Henderson
trans_l_lwa(DisasContext * dc,arg_load * a)6433a7be554SRichard Henderson static bool trans_l_lwa(DisasContext *dc, arg_load *a)
644d80bff19SRichard Henderson {
645d80bff19SRichard Henderson TCGv ea;
646d80bff19SRichard Henderson
647cdd0f459SRichard Henderson check_r0_write(dc, a->d);
648d80bff19SRichard Henderson ea = tcg_temp_new();
6498bba7619SRichard Henderson tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
6508bba7619SRichard Henderson tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, MO_TEUL);
651d80bff19SRichard Henderson tcg_gen_mov_tl(cpu_lock_addr, ea);
6528bba7619SRichard Henderson tcg_gen_mov_tl(cpu_lock_value, cpu_R(dc, a->d));
653d80bff19SRichard Henderson return true;
654d80bff19SRichard Henderson }
655d80bff19SRichard Henderson
do_load(DisasContext * dc,arg_load * a,MemOp mop)65614776ab5STony Nguyen static void do_load(DisasContext *dc, arg_load *a, MemOp mop)
657d80bff19SRichard Henderson {
658d80bff19SRichard Henderson TCGv ea;
659d80bff19SRichard Henderson
660cdd0f459SRichard Henderson check_r0_write(dc, a->d);
661d80bff19SRichard Henderson ea = tcg_temp_new();
6628bba7619SRichard Henderson tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
6638bba7619SRichard Henderson tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, mop);
664d80bff19SRichard Henderson }
665d80bff19SRichard Henderson
trans_l_lwz(DisasContext * dc,arg_load * a)6663a7be554SRichard Henderson static bool trans_l_lwz(DisasContext *dc, arg_load *a)
667d80bff19SRichard Henderson {
668d80bff19SRichard Henderson do_load(dc, a, MO_TEUL);
669d80bff19SRichard Henderson return true;
670d80bff19SRichard Henderson }
671d80bff19SRichard Henderson
trans_l_lws(DisasContext * dc,arg_load * a)6723a7be554SRichard Henderson static bool trans_l_lws(DisasContext *dc, arg_load *a)
673d80bff19SRichard Henderson {
674d80bff19SRichard Henderson do_load(dc, a, MO_TESL);
675d80bff19SRichard Henderson return true;
676d80bff19SRichard Henderson }
677d80bff19SRichard Henderson
trans_l_lbz(DisasContext * dc,arg_load * a)6783a7be554SRichard Henderson static bool trans_l_lbz(DisasContext *dc, arg_load *a)
679d80bff19SRichard Henderson {
680d80bff19SRichard Henderson do_load(dc, a, MO_UB);
681d80bff19SRichard Henderson return true;
682d80bff19SRichard Henderson }
683d80bff19SRichard Henderson
trans_l_lbs(DisasContext * dc,arg_load * a)6843a7be554SRichard Henderson static bool trans_l_lbs(DisasContext *dc, arg_load *a)
685d80bff19SRichard Henderson {
686d80bff19SRichard Henderson do_load(dc, a, MO_SB);
687d80bff19SRichard Henderson return true;
688d80bff19SRichard Henderson }
689d80bff19SRichard Henderson
trans_l_lhz(DisasContext * dc,arg_load * a)6903a7be554SRichard Henderson static bool trans_l_lhz(DisasContext *dc, arg_load *a)
691d80bff19SRichard Henderson {
692d80bff19SRichard Henderson do_load(dc, a, MO_TEUW);
693d80bff19SRichard Henderson return true;
694d80bff19SRichard Henderson }
695d80bff19SRichard Henderson
trans_l_lhs(DisasContext * dc,arg_load * a)6963a7be554SRichard Henderson static bool trans_l_lhs(DisasContext *dc, arg_load *a)
697d80bff19SRichard Henderson {
698d80bff19SRichard Henderson do_load(dc, a, MO_TESW);
699d80bff19SRichard Henderson return true;
700d80bff19SRichard Henderson }
701d80bff19SRichard Henderson
trans_l_swa(DisasContext * dc,arg_store * a)7023a7be554SRichard Henderson static bool trans_l_swa(DisasContext *dc, arg_store *a)
703d80bff19SRichard Henderson {
704d80bff19SRichard Henderson TCGv ea, val;
705d80bff19SRichard Henderson TCGLabel *lab_fail, *lab_done;
706d80bff19SRichard Henderson
707d80bff19SRichard Henderson ea = tcg_temp_new();
7088bba7619SRichard Henderson tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
709d80bff19SRichard Henderson
710d80bff19SRichard Henderson lab_fail = gen_new_label();
711d80bff19SRichard Henderson lab_done = gen_new_label();
712d80bff19SRichard Henderson tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
713d80bff19SRichard Henderson
714d80bff19SRichard Henderson val = tcg_temp_new();
715d80bff19SRichard Henderson tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
7164d10fa0fSRichard Henderson cpu_R(dc, a->b), dc->mem_idx, MO_TEUL);
717d80bff19SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
718d80bff19SRichard Henderson
719d80bff19SRichard Henderson tcg_gen_br(lab_done);
720d80bff19SRichard Henderson
721d80bff19SRichard Henderson gen_set_label(lab_fail);
722d80bff19SRichard Henderson tcg_gen_movi_tl(cpu_sr_f, 0);
723d80bff19SRichard Henderson
724d80bff19SRichard Henderson gen_set_label(lab_done);
725d80bff19SRichard Henderson tcg_gen_movi_tl(cpu_lock_addr, -1);
726d80bff19SRichard Henderson return true;
727d80bff19SRichard Henderson }
728d80bff19SRichard Henderson
do_store(DisasContext * dc,arg_store * a,MemOp mop)72914776ab5STony Nguyen static void do_store(DisasContext *dc, arg_store *a, MemOp mop)
730d80bff19SRichard Henderson {
731d80bff19SRichard Henderson TCGv t0 = tcg_temp_new();
7328bba7619SRichard Henderson tcg_gen_addi_tl(t0, cpu_R(dc, a->a), a->i);
7338bba7619SRichard Henderson tcg_gen_qemu_st_tl(cpu_R(dc, a->b), t0, dc->mem_idx, mop);
734d80bff19SRichard Henderson }
735d80bff19SRichard Henderson
trans_l_sw(DisasContext * dc,arg_store * a)7363a7be554SRichard Henderson static bool trans_l_sw(DisasContext *dc, arg_store *a)
737d80bff19SRichard Henderson {
738d80bff19SRichard Henderson do_store(dc, a, MO_TEUL);
739d80bff19SRichard Henderson return true;
740d80bff19SRichard Henderson }
741d80bff19SRichard Henderson
trans_l_sb(DisasContext * dc,arg_store * a)7423a7be554SRichard Henderson static bool trans_l_sb(DisasContext *dc, arg_store *a)
743d80bff19SRichard Henderson {
744d80bff19SRichard Henderson do_store(dc, a, MO_UB);
745d80bff19SRichard Henderson return true;
746d80bff19SRichard Henderson }
747d80bff19SRichard Henderson
trans_l_sh(DisasContext * dc,arg_store * a)7483a7be554SRichard Henderson static bool trans_l_sh(DisasContext *dc, arg_store *a)
749d80bff19SRichard Henderson {
750d80bff19SRichard Henderson do_store(dc, a, MO_TEUW);
751d80bff19SRichard Henderson return true;
752d80bff19SRichard Henderson }
753d80bff19SRichard Henderson
trans_l_nop(DisasContext * dc,arg_l_nop * a)7543a7be554SRichard Henderson static bool trans_l_nop(DisasContext *dc, arg_l_nop *a)
755fcf5ef2aSThomas Huth {
7568816f70bSRichard Henderson return true;
7578816f70bSRichard Henderson }
7588816f70bSRichard Henderson
trans_l_adrp(DisasContext * dc,arg_l_adrp * a)7593e0e41efSRichard Henderson static bool trans_l_adrp(DisasContext *dc, arg_l_adrp *a)
7603e0e41efSRichard Henderson {
7613e0e41efSRichard Henderson if (!check_v1_3(dc)) {
7623e0e41efSRichard Henderson return false;
7633e0e41efSRichard Henderson }
7643e0e41efSRichard Henderson check_r0_write(dc, a->d);
7653e0e41efSRichard Henderson
7663e0e41efSRichard Henderson tcg_gen_movi_i32(cpu_R(dc, a->d),
7673e0e41efSRichard Henderson (dc->base.pc_next & TARGET_PAGE_MASK) +
7683e0e41efSRichard Henderson ((target_long)a->i << TARGET_PAGE_BITS));
7693e0e41efSRichard Henderson return true;
7703e0e41efSRichard Henderson }
7713e0e41efSRichard Henderson
trans_l_addi(DisasContext * dc,arg_rri * a)7723a7be554SRichard Henderson static bool trans_l_addi(DisasContext *dc, arg_rri *a)
7738816f70bSRichard Henderson {
774cdd0f459SRichard Henderson check_r0_write(dc, a->d);
775af42d354SRichard Henderson gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
7768816f70bSRichard Henderson return true;
7778816f70bSRichard Henderson }
778fcf5ef2aSThomas Huth
trans_l_addic(DisasContext * dc,arg_rri * a)7793a7be554SRichard Henderson static bool trans_l_addic(DisasContext *dc, arg_rri *a)
780fcf5ef2aSThomas Huth {
781cdd0f459SRichard Henderson check_r0_write(dc, a->d);
782af42d354SRichard Henderson gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
7838816f70bSRichard Henderson return true;
7848816f70bSRichard Henderson }
7858816f70bSRichard Henderson
trans_l_muli(DisasContext * dc,arg_rri * a)7863a7be554SRichard Henderson static bool trans_l_muli(DisasContext *dc, arg_rri *a)
7878816f70bSRichard Henderson {
788cdd0f459SRichard Henderson check_r0_write(dc, a->d);
789af42d354SRichard Henderson gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
7908816f70bSRichard Henderson return true;
7918816f70bSRichard Henderson }
7928816f70bSRichard Henderson
trans_l_maci(DisasContext * dc,arg_l_maci * a)7933a7be554SRichard Henderson static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
7948816f70bSRichard Henderson {
795af42d354SRichard Henderson gen_mac(dc, cpu_R(dc, a->a), tcg_constant_tl(a->i));
7968816f70bSRichard Henderson return true;
7978816f70bSRichard Henderson }
7988816f70bSRichard Henderson
trans_l_andi(DisasContext * dc,arg_rrk * a)7993a7be554SRichard Henderson static bool trans_l_andi(DisasContext *dc, arg_rrk *a)
8008816f70bSRichard Henderson {
801cdd0f459SRichard Henderson check_r0_write(dc, a->d);
8028bba7619SRichard Henderson tcg_gen_andi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
8038816f70bSRichard Henderson return true;
8048816f70bSRichard Henderson }
8058816f70bSRichard Henderson
trans_l_ori(DisasContext * dc,arg_rrk * a)8063a7be554SRichard Henderson static bool trans_l_ori(DisasContext *dc, arg_rrk *a)
8078816f70bSRichard Henderson {
808cdd0f459SRichard Henderson check_r0_write(dc, a->d);
8098bba7619SRichard Henderson tcg_gen_ori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
8108816f70bSRichard Henderson return true;
8118816f70bSRichard Henderson }
8128816f70bSRichard Henderson
trans_l_xori(DisasContext * dc,arg_rri * a)8133a7be554SRichard Henderson static bool trans_l_xori(DisasContext *dc, arg_rri *a)
8148816f70bSRichard Henderson {
815cdd0f459SRichard Henderson check_r0_write(dc, a->d);
8168bba7619SRichard Henderson tcg_gen_xori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->i);
8178816f70bSRichard Henderson return true;
8188816f70bSRichard Henderson }
8198816f70bSRichard Henderson
trans_l_mfspr(DisasContext * dc,arg_l_mfspr * a)8203a7be554SRichard Henderson static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
8218816f70bSRichard Henderson {
822c28fa81fSRichard Henderson TCGv spr = tcg_temp_new();
823b9e40bacSPavel Dovgalyuk
82408f021deSStafford Horne check_r0_write(dc, a->d);
82508f021deSStafford Horne
826dfd1b812SRichard Henderson if (translator_io_start(&dc->base)) {
827b9e40bacSPavel Dovgalyuk if (dc->delayed_branch) {
828b9e40bacSPavel Dovgalyuk tcg_gen_mov_tl(cpu_pc, jmp_pc);
829b9e40bacSPavel Dovgalyuk tcg_gen_discard_tl(jmp_pc);
830b9e40bacSPavel Dovgalyuk } else {
831b9e40bacSPavel Dovgalyuk tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
832b9e40bacSPavel Dovgalyuk }
833b9e40bacSPavel Dovgalyuk dc->base.is_jmp = DISAS_EXIT;
834b9e40bacSPavel Dovgalyuk }
835b9e40bacSPavel Dovgalyuk
8368bba7619SRichard Henderson tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
837ad75a51eSRichard Henderson gen_helper_mfspr(cpu_R(dc, a->d), tcg_env, cpu_R(dc, a->d), spr);
8388816f70bSRichard Henderson return true;
8398816f70bSRichard Henderson }
840fcf5ef2aSThomas Huth
trans_l_mtspr(DisasContext * dc,arg_l_mtspr * a)8413a7be554SRichard Henderson static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
842fcf5ef2aSThomas Huth {
84308f021deSStafford Horne TCGv spr = tcg_temp_new();
84401ec3ec9SRichard Henderson
845dfd1b812SRichard Henderson translator_io_start(&dc->base);
846dfd1b812SRichard Henderson
84708f021deSStafford Horne /*
84808f021deSStafford Horne * For SR, we will need to exit the TB to recognize the new
84901ec3ec9SRichard Henderson * exception state. For NPC, in theory this counts as a branch
85001ec3ec9SRichard Henderson * (although the SPR only exists for use by an ICE). Save all
85101ec3ec9SRichard Henderson * of the cpu state first, allowing it to be overwritten.
85201ec3ec9SRichard Henderson */
85301ec3ec9SRichard Henderson if (dc->delayed_branch) {
85401ec3ec9SRichard Henderson tcg_gen_mov_tl(cpu_pc, jmp_pc);
85501ec3ec9SRichard Henderson tcg_gen_discard_tl(jmp_pc);
85601ec3ec9SRichard Henderson } else {
85701ec3ec9SRichard Henderson tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
85801ec3ec9SRichard Henderson }
85901ec3ec9SRichard Henderson dc->base.is_jmp = DISAS_EXIT;
86001ec3ec9SRichard Henderson
8618bba7619SRichard Henderson tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
862ad75a51eSRichard Henderson gen_helper_mtspr(tcg_env, spr, cpu_R(dc, a->b));
8638816f70bSRichard Henderson return true;
864fcf5ef2aSThomas Huth }
865fcf5ef2aSThomas Huth
trans_l_mac(DisasContext * dc,arg_ab * a)8663a7be554SRichard Henderson static bool trans_l_mac(DisasContext *dc, arg_ab *a)
867fcf5ef2aSThomas Huth {
8688bba7619SRichard Henderson gen_mac(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
86999d863d6SRichard Henderson return true;
870fcf5ef2aSThomas Huth }
87199d863d6SRichard Henderson
trans_l_msb(DisasContext * dc,arg_ab * a)8723a7be554SRichard Henderson static bool trans_l_msb(DisasContext *dc, arg_ab *a)
87399d863d6SRichard Henderson {
8748bba7619SRichard Henderson gen_msb(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
87599d863d6SRichard Henderson return true;
87699d863d6SRichard Henderson }
87799d863d6SRichard Henderson
trans_l_macu(DisasContext * dc,arg_ab * a)8783a7be554SRichard Henderson static bool trans_l_macu(DisasContext *dc, arg_ab *a)
87999d863d6SRichard Henderson {
8808bba7619SRichard Henderson gen_macu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
88199d863d6SRichard Henderson return true;
88299d863d6SRichard Henderson }
88399d863d6SRichard Henderson
trans_l_msbu(DisasContext * dc,arg_ab * a)8843a7be554SRichard Henderson static bool trans_l_msbu(DisasContext *dc, arg_ab *a)
88599d863d6SRichard Henderson {
8868bba7619SRichard Henderson gen_msbu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
88799d863d6SRichard Henderson return true;
888fcf5ef2aSThomas Huth }
889fcf5ef2aSThomas Huth
trans_l_slli(DisasContext * dc,arg_dal * a)8903a7be554SRichard Henderson static bool trans_l_slli(DisasContext *dc, arg_dal *a)
891fcf5ef2aSThomas Huth {
892cdd0f459SRichard Henderson check_r0_write(dc, a->d);
8938bba7619SRichard Henderson tcg_gen_shli_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
8948bba7619SRichard Henderson a->l & (TARGET_LONG_BITS - 1));
895e20c2592SRichard Henderson return true;
896fcf5ef2aSThomas Huth }
897e20c2592SRichard Henderson
trans_l_srli(DisasContext * dc,arg_dal * a)8983a7be554SRichard Henderson static bool trans_l_srli(DisasContext *dc, arg_dal *a)
899e20c2592SRichard Henderson {
900cdd0f459SRichard Henderson check_r0_write(dc, a->d);
9018bba7619SRichard Henderson tcg_gen_shri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
9028bba7619SRichard Henderson a->l & (TARGET_LONG_BITS - 1));
903e20c2592SRichard Henderson return true;
904e20c2592SRichard Henderson }
905e20c2592SRichard Henderson
trans_l_srai(DisasContext * dc,arg_dal * a)9063a7be554SRichard Henderson static bool trans_l_srai(DisasContext *dc, arg_dal *a)
907e20c2592SRichard Henderson {
908cdd0f459SRichard Henderson check_r0_write(dc, a->d);
9098bba7619SRichard Henderson tcg_gen_sari_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
9108bba7619SRichard Henderson a->l & (TARGET_LONG_BITS - 1));
911e20c2592SRichard Henderson return true;
912e20c2592SRichard Henderson }
913e20c2592SRichard Henderson
trans_l_rori(DisasContext * dc,arg_dal * a)9143a7be554SRichard Henderson static bool trans_l_rori(DisasContext *dc, arg_dal *a)
915e20c2592SRichard Henderson {
916cdd0f459SRichard Henderson check_r0_write(dc, a->d);
9178bba7619SRichard Henderson tcg_gen_rotri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
9188bba7619SRichard Henderson a->l & (TARGET_LONG_BITS - 1));
919e20c2592SRichard Henderson return true;
920fcf5ef2aSThomas Huth }
921fcf5ef2aSThomas Huth
trans_l_movhi(DisasContext * dc,arg_l_movhi * a)9223a7be554SRichard Henderson static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a)
923fcf5ef2aSThomas Huth {
924cdd0f459SRichard Henderson check_r0_write(dc, a->d);
9258bba7619SRichard Henderson tcg_gen_movi_tl(cpu_R(dc, a->d), a->k << 16);
926e720a571SRichard Henderson return true;
927fcf5ef2aSThomas Huth }
928e720a571SRichard Henderson
trans_l_macrc(DisasContext * dc,arg_l_macrc * a)9293a7be554SRichard Henderson static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a)
930e720a571SRichard Henderson {
931cdd0f459SRichard Henderson check_r0_write(dc, a->d);
9328bba7619SRichard Henderson tcg_gen_trunc_i64_tl(cpu_R(dc, a->d), cpu_mac);
933e720a571SRichard Henderson tcg_gen_movi_i64(cpu_mac, 0);
934e720a571SRichard Henderson return true;
935fcf5ef2aSThomas Huth }
936fcf5ef2aSThomas Huth
trans_l_sfeq(DisasContext * dc,arg_ab * a)9373a7be554SRichard Henderson static bool trans_l_sfeq(DisasContext *dc, arg_ab *a)
938fcf5ef2aSThomas Huth {
9398bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f,
9408bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
941fbb3e29aSRichard Henderson return true;
942fcf5ef2aSThomas Huth }
943fbb3e29aSRichard Henderson
trans_l_sfne(DisasContext * dc,arg_ab * a)9443a7be554SRichard Henderson static bool trans_l_sfne(DisasContext *dc, arg_ab *a)
945fbb3e29aSRichard Henderson {
9468bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f,
9478bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
948fbb3e29aSRichard Henderson return true;
949fbb3e29aSRichard Henderson }
950fbb3e29aSRichard Henderson
trans_l_sfgtu(DisasContext * dc,arg_ab * a)9513a7be554SRichard Henderson static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a)
952fbb3e29aSRichard Henderson {
9538bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f,
9548bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
955fbb3e29aSRichard Henderson return true;
956fbb3e29aSRichard Henderson }
957fbb3e29aSRichard Henderson
trans_l_sfgeu(DisasContext * dc,arg_ab * a)9583a7be554SRichard Henderson static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a)
959fbb3e29aSRichard Henderson {
9608bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f,
9618bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
962fbb3e29aSRichard Henderson return true;
963fbb3e29aSRichard Henderson }
964fbb3e29aSRichard Henderson
trans_l_sfltu(DisasContext * dc,arg_ab * a)9653a7be554SRichard Henderson static bool trans_l_sfltu(DisasContext *dc, arg_ab *a)
966fbb3e29aSRichard Henderson {
9678bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f,
9688bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
969fbb3e29aSRichard Henderson return true;
970fbb3e29aSRichard Henderson }
971fbb3e29aSRichard Henderson
trans_l_sfleu(DisasContext * dc,arg_ab * a)9723a7be554SRichard Henderson static bool trans_l_sfleu(DisasContext *dc, arg_ab *a)
973fbb3e29aSRichard Henderson {
9748bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f,
9758bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
976fbb3e29aSRichard Henderson return true;
977fbb3e29aSRichard Henderson }
978fbb3e29aSRichard Henderson
trans_l_sfgts(DisasContext * dc,arg_ab * a)9793a7be554SRichard Henderson static bool trans_l_sfgts(DisasContext *dc, arg_ab *a)
980fbb3e29aSRichard Henderson {
9818bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f,
9828bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
983fbb3e29aSRichard Henderson return true;
984fbb3e29aSRichard Henderson }
985fbb3e29aSRichard Henderson
trans_l_sfges(DisasContext * dc,arg_ab * a)9863a7be554SRichard Henderson static bool trans_l_sfges(DisasContext *dc, arg_ab *a)
987fbb3e29aSRichard Henderson {
9888bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f,
9898bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
990fbb3e29aSRichard Henderson return true;
991fbb3e29aSRichard Henderson }
992fbb3e29aSRichard Henderson
trans_l_sflts(DisasContext * dc,arg_ab * a)9933a7be554SRichard Henderson static bool trans_l_sflts(DisasContext *dc, arg_ab *a)
994fbb3e29aSRichard Henderson {
9958bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f,
9968bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
997fbb3e29aSRichard Henderson return true;
998fbb3e29aSRichard Henderson }
999fbb3e29aSRichard Henderson
trans_l_sfles(DisasContext * dc,arg_ab * a)10003a7be554SRichard Henderson static bool trans_l_sfles(DisasContext *dc, arg_ab *a)
1001fbb3e29aSRichard Henderson {
10028bba7619SRichard Henderson tcg_gen_setcond_tl(TCG_COND_LE,
10038bba7619SRichard Henderson cpu_sr_f, cpu_R(dc, a->a), cpu_R(dc, a->b));
1004fbb3e29aSRichard Henderson return true;
1005fcf5ef2aSThomas Huth }
1006fcf5ef2aSThomas Huth
trans_l_sfeqi(DisasContext * dc,arg_ai * a)10073a7be554SRichard Henderson static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a)
1008fcf5ef2aSThomas Huth {
10098bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R(dc, a->a), a->i);
1010032de4fcSRichard Henderson return true;
1011fcf5ef2aSThomas Huth }
1012032de4fcSRichard Henderson
trans_l_sfnei(DisasContext * dc,arg_ai * a)10133a7be554SRichard Henderson static bool trans_l_sfnei(DisasContext *dc, arg_ai *a)
1014032de4fcSRichard Henderson {
10158bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R(dc, a->a), a->i);
1016032de4fcSRichard Henderson return true;
1017032de4fcSRichard Henderson }
1018032de4fcSRichard Henderson
trans_l_sfgtui(DisasContext * dc,arg_ai * a)10193a7be554SRichard Henderson static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a)
1020032de4fcSRichard Henderson {
10218bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
1022032de4fcSRichard Henderson return true;
1023032de4fcSRichard Henderson }
1024032de4fcSRichard Henderson
trans_l_sfgeui(DisasContext * dc,arg_ai * a)10253a7be554SRichard Henderson static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a)
1026032de4fcSRichard Henderson {
10278bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
1028032de4fcSRichard Henderson return true;
1029032de4fcSRichard Henderson }
1030032de4fcSRichard Henderson
trans_l_sfltui(DisasContext * dc,arg_ai * a)10313a7be554SRichard Henderson static bool trans_l_sfltui(DisasContext *dc, arg_ai *a)
1032032de4fcSRichard Henderson {
10338bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
1034032de4fcSRichard Henderson return true;
1035032de4fcSRichard Henderson }
1036032de4fcSRichard Henderson
trans_l_sfleui(DisasContext * dc,arg_ai * a)10373a7be554SRichard Henderson static bool trans_l_sfleui(DisasContext *dc, arg_ai *a)
1038032de4fcSRichard Henderson {
10398bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
1040032de4fcSRichard Henderson return true;
1041032de4fcSRichard Henderson }
1042032de4fcSRichard Henderson
trans_l_sfgtsi(DisasContext * dc,arg_ai * a)10433a7be554SRichard Henderson static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a)
1044032de4fcSRichard Henderson {
10458bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R(dc, a->a), a->i);
1046032de4fcSRichard Henderson return true;
1047032de4fcSRichard Henderson }
1048032de4fcSRichard Henderson
trans_l_sfgesi(DisasContext * dc,arg_ai * a)10493a7be554SRichard Henderson static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a)
1050032de4fcSRichard Henderson {
10518bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R(dc, a->a), a->i);
1052032de4fcSRichard Henderson return true;
1053032de4fcSRichard Henderson }
1054032de4fcSRichard Henderson
trans_l_sfltsi(DisasContext * dc,arg_ai * a)10553a7be554SRichard Henderson static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a)
1056032de4fcSRichard Henderson {
10578bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R(dc, a->a), a->i);
1058032de4fcSRichard Henderson return true;
1059032de4fcSRichard Henderson }
1060032de4fcSRichard Henderson
trans_l_sflesi(DisasContext * dc,arg_ai * a)10613a7be554SRichard Henderson static bool trans_l_sflesi(DisasContext *dc, arg_ai *a)
1062032de4fcSRichard Henderson {
10638bba7619SRichard Henderson tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R(dc, a->a), a->i);
1064032de4fcSRichard Henderson return true;
1065fcf5ef2aSThomas Huth }
1066fcf5ef2aSThomas Huth
trans_l_sys(DisasContext * dc,arg_l_sys * a)10673a7be554SRichard Henderson static bool trans_l_sys(DisasContext *dc, arg_l_sys *a)
1068fcf5ef2aSThomas Huth {
10691ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1070fcf5ef2aSThomas Huth gen_exception(dc, EXCP_SYSCALL);
10711ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN;
10727de9729fSRichard Henderson return true;
10737de9729fSRichard Henderson }
1074fcf5ef2aSThomas Huth
trans_l_trap(DisasContext * dc,arg_l_trap * a)10753a7be554SRichard Henderson static bool trans_l_trap(DisasContext *dc, arg_l_trap *a)
10767de9729fSRichard Henderson {
10771ffa4bceSEmilio G. Cota tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
1078fcf5ef2aSThomas Huth gen_exception(dc, EXCP_TRAP);
10791ffa4bceSEmilio G. Cota dc->base.is_jmp = DISAS_NORETURN;
10807de9729fSRichard Henderson return true;
10817de9729fSRichard Henderson }
1082fcf5ef2aSThomas Huth
trans_l_msync(DisasContext * dc,arg_l_msync * a)10833a7be554SRichard Henderson static bool trans_l_msync(DisasContext *dc, arg_l_msync *a)
10847de9729fSRichard Henderson {
108524fc5c0fSRichard Henderson tcg_gen_mb(TCG_MO_ALL);
10867de9729fSRichard Henderson return true;
1087fcf5ef2aSThomas Huth }
10887de9729fSRichard Henderson
trans_l_psync(DisasContext * dc,arg_l_psync * a)10893a7be554SRichard Henderson static bool trans_l_psync(DisasContext *dc, arg_l_psync *a)
10907de9729fSRichard Henderson {
10917de9729fSRichard Henderson return true;
10927de9729fSRichard Henderson }
10937de9729fSRichard Henderson
trans_l_csync(DisasContext * dc,arg_l_csync * a)10943a7be554SRichard Henderson static bool trans_l_csync(DisasContext *dc, arg_l_csync *a)
10957de9729fSRichard Henderson {
10967de9729fSRichard Henderson return true;
1097fcf5ef2aSThomas Huth }
1098fcf5ef2aSThomas Huth
trans_l_rfe(DisasContext * dc,arg_l_rfe * a)10993a7be554SRichard Henderson static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a)
11008816f70bSRichard Henderson {
11012ba65417SRichard Henderson if (is_user(dc)) {
11028816f70bSRichard Henderson gen_illegal_exception(dc);
11038816f70bSRichard Henderson } else {
1104ad75a51eSRichard Henderson gen_helper_rfe(tcg_env);
110564e46c95SRichard Henderson dc->base.is_jmp = DISAS_EXIT;
11068816f70bSRichard Henderson }
11078816f70bSRichard Henderson return true;
11088816f70bSRichard Henderson }
11098816f70bSRichard Henderson
do_fp2(DisasContext * dc,arg_da * a,void (* fn)(TCGv,TCGv_env,TCGv))1110fe636d37SRichard Henderson static bool do_fp2(DisasContext *dc, arg_da *a,
11116fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv))
1112fcf5ef2aSThomas Huth {
1113fe636d37SRichard Henderson if (!check_of32s(dc)) {
1114fe636d37SRichard Henderson return false;
1115fe636d37SRichard Henderson }
1116cdd0f459SRichard Henderson check_r0_write(dc, a->d);
1117ad75a51eSRichard Henderson fn(cpu_R(dc, a->d), tcg_env, cpu_R(dc, a->a));
1118ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
1119fe636d37SRichard Henderson return true;
1120fcf5ef2aSThomas Huth }
11216fd204a2SRichard Henderson
do_fp3(DisasContext * dc,arg_dab * a,void (* fn)(TCGv,TCGv_env,TCGv,TCGv))1122fe636d37SRichard Henderson static bool do_fp3(DisasContext *dc, arg_dab *a,
11236fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv, TCGv))
11246fd204a2SRichard Henderson {
1125fe636d37SRichard Henderson if (!check_of32s(dc)) {
1126fe636d37SRichard Henderson return false;
1127fe636d37SRichard Henderson }
1128cdd0f459SRichard Henderson check_r0_write(dc, a->d);
1129ad75a51eSRichard Henderson fn(cpu_R(dc, a->d), tcg_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
1130ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
1131fe636d37SRichard Henderson return true;
11326fd204a2SRichard Henderson }
11336fd204a2SRichard Henderson
do_fpcmp(DisasContext * dc,arg_ab * a,void (* fn)(TCGv,TCGv_env,TCGv,TCGv),bool inv,bool swap)1134fe636d37SRichard Henderson static bool do_fpcmp(DisasContext *dc, arg_ab *a,
11356fd204a2SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv, TCGv),
11366fd204a2SRichard Henderson bool inv, bool swap)
11376fd204a2SRichard Henderson {
1138fe636d37SRichard Henderson if (!check_of32s(dc)) {
1139fe636d37SRichard Henderson return false;
1140fe636d37SRichard Henderson }
11416fd204a2SRichard Henderson if (swap) {
1142ad75a51eSRichard Henderson fn(cpu_sr_f, tcg_env, cpu_R(dc, a->b), cpu_R(dc, a->a));
11436fd204a2SRichard Henderson } else {
1144ad75a51eSRichard Henderson fn(cpu_sr_f, tcg_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
11456fd204a2SRichard Henderson }
11466fd204a2SRichard Henderson if (inv) {
11476fd204a2SRichard Henderson tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
11486fd204a2SRichard Henderson }
1149ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
1150fe636d37SRichard Henderson return true;
11516fd204a2SRichard Henderson }
11526fd204a2SRichard Henderson
trans_lf_add_s(DisasContext * dc,arg_dab * a)11533a7be554SRichard Henderson static bool trans_lf_add_s(DisasContext *dc, arg_dab *a)
11546fd204a2SRichard Henderson {
1155fe636d37SRichard Henderson return do_fp3(dc, a, gen_helper_float_add_s);
11566fd204a2SRichard Henderson }
11576fd204a2SRichard Henderson
trans_lf_sub_s(DisasContext * dc,arg_dab * a)11583a7be554SRichard Henderson static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a)
11596fd204a2SRichard Henderson {
1160fe636d37SRichard Henderson return do_fp3(dc, a, gen_helper_float_sub_s);
11616fd204a2SRichard Henderson }
11626fd204a2SRichard Henderson
trans_lf_mul_s(DisasContext * dc,arg_dab * a)11633a7be554SRichard Henderson static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a)
11646fd204a2SRichard Henderson {
1165fe636d37SRichard Henderson return do_fp3(dc, a, gen_helper_float_mul_s);
11666fd204a2SRichard Henderson }
11676fd204a2SRichard Henderson
trans_lf_div_s(DisasContext * dc,arg_dab * a)11683a7be554SRichard Henderson static bool trans_lf_div_s(DisasContext *dc, arg_dab *a)
11696fd204a2SRichard Henderson {
1170fe636d37SRichard Henderson return do_fp3(dc, a, gen_helper_float_div_s);
11716fd204a2SRichard Henderson }
11726fd204a2SRichard Henderson
trans_lf_rem_s(DisasContext * dc,arg_dab * a)11733a7be554SRichard Henderson static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a)
11746fd204a2SRichard Henderson {
1175fe636d37SRichard Henderson return do_fp3(dc, a, gen_helper_float_rem_s);
11766fd204a2SRichard Henderson return true;
11776fd204a2SRichard Henderson }
11786fd204a2SRichard Henderson
trans_lf_itof_s(DisasContext * dc,arg_da * a)11793a7be554SRichard Henderson static bool trans_lf_itof_s(DisasContext *dc, arg_da *a)
11806fd204a2SRichard Henderson {
1181fe636d37SRichard Henderson return do_fp2(dc, a, gen_helper_itofs);
11826fd204a2SRichard Henderson }
11836fd204a2SRichard Henderson
trans_lf_ftoi_s(DisasContext * dc,arg_da * a)11843a7be554SRichard Henderson static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a)
11856fd204a2SRichard Henderson {
1186fe636d37SRichard Henderson return do_fp2(dc, a, gen_helper_ftois);
11876fd204a2SRichard Henderson }
11886fd204a2SRichard Henderson
trans_lf_madd_s(DisasContext * dc,arg_dab * a)11893a7be554SRichard Henderson static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
11906fd204a2SRichard Henderson {
1191fe636d37SRichard Henderson if (!check_of32s(dc)) {
1192fe636d37SRichard Henderson return false;
1193fe636d37SRichard Henderson }
1194cdd0f459SRichard Henderson check_r0_write(dc, a->d);
1195ad75a51eSRichard Henderson gen_helper_float_madd_s(cpu_R(dc, a->d), tcg_env, cpu_R(dc, a->d),
11968bba7619SRichard Henderson cpu_R(dc, a->a), cpu_R(dc, a->b));
1197ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
11986fd204a2SRichard Henderson return true;
11996fd204a2SRichard Henderson }
12006fd204a2SRichard Henderson
trans_lf_sfeq_s(DisasContext * dc,arg_ab * a)12013a7be554SRichard Henderson static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a)
12026fd204a2SRichard Henderson {
1203fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
12046fd204a2SRichard Henderson }
12056fd204a2SRichard Henderson
trans_lf_sfne_s(DisasContext * dc,arg_ab * a)12063a7be554SRichard Henderson static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a)
12076fd204a2SRichard Henderson {
1208fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
12096fd204a2SRichard Henderson }
12106fd204a2SRichard Henderson
trans_lf_sfgt_s(DisasContext * dc,arg_ab * a)12113a7be554SRichard Henderson static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a)
12126fd204a2SRichard Henderson {
1213fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
12146fd204a2SRichard Henderson }
12156fd204a2SRichard Henderson
trans_lf_sfge_s(DisasContext * dc,arg_ab * a)12163a7be554SRichard Henderson static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a)
12176fd204a2SRichard Henderson {
1218fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
12196fd204a2SRichard Henderson }
12206fd204a2SRichard Henderson
trans_lf_sflt_s(DisasContext * dc,arg_ab * a)12213a7be554SRichard Henderson static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a)
12226fd204a2SRichard Henderson {
1223fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
12246fd204a2SRichard Henderson }
12256fd204a2SRichard Henderson
trans_lf_sfle_s(DisasContext * dc,arg_ab * a)12263a7be554SRichard Henderson static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
12276fd204a2SRichard Henderson {
1228fe636d37SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
1229fcf5ef2aSThomas Huth }
1230fcf5ef2aSThomas Huth
trans_lf_sfueq_s(DisasContext * dc,arg_ab * a)12312b13b4b9SRichard Henderson static bool trans_lf_sfueq_s(DisasContext *dc, arg_ab *a)
12322b13b4b9SRichard Henderson {
12332b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12342b13b4b9SRichard Henderson return false;
12352b13b4b9SRichard Henderson }
12362b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_ueq_s, false, false);
12372b13b4b9SRichard Henderson }
12382b13b4b9SRichard Henderson
trans_lf_sfult_s(DisasContext * dc,arg_ab * a)12392b13b4b9SRichard Henderson static bool trans_lf_sfult_s(DisasContext *dc, arg_ab *a)
12402b13b4b9SRichard Henderson {
12412b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12422b13b4b9SRichard Henderson return false;
12432b13b4b9SRichard Henderson }
12442b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_ult_s, false, false);
12452b13b4b9SRichard Henderson }
12462b13b4b9SRichard Henderson
trans_lf_sfugt_s(DisasContext * dc,arg_ab * a)12472b13b4b9SRichard Henderson static bool trans_lf_sfugt_s(DisasContext *dc, arg_ab *a)
12482b13b4b9SRichard Henderson {
12492b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12502b13b4b9SRichard Henderson return false;
12512b13b4b9SRichard Henderson }
12522b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_ult_s, false, true);
12532b13b4b9SRichard Henderson }
12542b13b4b9SRichard Henderson
trans_lf_sfule_s(DisasContext * dc,arg_ab * a)12552b13b4b9SRichard Henderson static bool trans_lf_sfule_s(DisasContext *dc, arg_ab *a)
12562b13b4b9SRichard Henderson {
12572b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12582b13b4b9SRichard Henderson return false;
12592b13b4b9SRichard Henderson }
12602b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_ule_s, false, false);
12612b13b4b9SRichard Henderson }
12622b13b4b9SRichard Henderson
trans_lf_sfuge_s(DisasContext * dc,arg_ab * a)12632b13b4b9SRichard Henderson static bool trans_lf_sfuge_s(DisasContext *dc, arg_ab *a)
12642b13b4b9SRichard Henderson {
12652b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12662b13b4b9SRichard Henderson return false;
12672b13b4b9SRichard Henderson }
12682b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_ule_s, false, true);
12692b13b4b9SRichard Henderson }
12702b13b4b9SRichard Henderson
trans_lf_sfun_s(DisasContext * dc,arg_ab * a)12712b13b4b9SRichard Henderson static bool trans_lf_sfun_s(DisasContext *dc, arg_ab *a)
12722b13b4b9SRichard Henderson {
12732b13b4b9SRichard Henderson if (!check_v1_3(dc)) {
12742b13b4b9SRichard Henderson return false;
12752b13b4b9SRichard Henderson }
12762b13b4b9SRichard Henderson return do_fpcmp(dc, a, gen_helper_float_un_s, false, false);
12772b13b4b9SRichard Henderson }
12782b13b4b9SRichard Henderson
check_pair(DisasContext * dc,int r,int p)127962f2b038SRichard Henderson static bool check_pair(DisasContext *dc, int r, int p)
128062f2b038SRichard Henderson {
128162f2b038SRichard Henderson return r + 1 + p < 32;
128262f2b038SRichard Henderson }
128362f2b038SRichard Henderson
load_pair(DisasContext * dc,TCGv_i64 t,int r,int p)128462f2b038SRichard Henderson static void load_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
128562f2b038SRichard Henderson {
128662f2b038SRichard Henderson tcg_gen_concat_i32_i64(t, cpu_R(dc, r + 1 + p), cpu_R(dc, r));
128762f2b038SRichard Henderson }
128862f2b038SRichard Henderson
save_pair(DisasContext * dc,TCGv_i64 t,int r,int p)128962f2b038SRichard Henderson static void save_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
129062f2b038SRichard Henderson {
129162f2b038SRichard Henderson tcg_gen_extr_i64_i32(cpu_R(dc, r + 1 + p), cpu_R(dc, r), t);
129262f2b038SRichard Henderson }
129362f2b038SRichard Henderson
do_dp3(DisasContext * dc,arg_dab_pair * a,void (* fn)(TCGv_i64,TCGv_env,TCGv_i64,TCGv_i64))129462f2b038SRichard Henderson static bool do_dp3(DisasContext *dc, arg_dab_pair *a,
129562f2b038SRichard Henderson void (*fn)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
129662f2b038SRichard Henderson {
129762f2b038SRichard Henderson TCGv_i64 t0, t1;
129862f2b038SRichard Henderson
129962f2b038SRichard Henderson if (!check_of64a32s(dc) ||
130062f2b038SRichard Henderson !check_pair(dc, a->a, a->ap) ||
130162f2b038SRichard Henderson !check_pair(dc, a->b, a->bp) ||
130262f2b038SRichard Henderson !check_pair(dc, a->d, a->dp)) {
130362f2b038SRichard Henderson return false;
130462f2b038SRichard Henderson }
130562f2b038SRichard Henderson check_r0_write(dc, a->d);
130662f2b038SRichard Henderson
130762f2b038SRichard Henderson t0 = tcg_temp_new_i64();
130862f2b038SRichard Henderson t1 = tcg_temp_new_i64();
130962f2b038SRichard Henderson load_pair(dc, t0, a->a, a->ap);
131062f2b038SRichard Henderson load_pair(dc, t1, a->b, a->bp);
1311ad75a51eSRichard Henderson fn(t0, tcg_env, t0, t1);
131262f2b038SRichard Henderson save_pair(dc, t0, a->d, a->dp);
131362f2b038SRichard Henderson
1314ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
131562f2b038SRichard Henderson return true;
131662f2b038SRichard Henderson }
131762f2b038SRichard Henderson
do_dp2(DisasContext * dc,arg_da_pair * a,void (* fn)(TCGv_i64,TCGv_env,TCGv_i64))131862f2b038SRichard Henderson static bool do_dp2(DisasContext *dc, arg_da_pair *a,
131962f2b038SRichard Henderson void (*fn)(TCGv_i64, TCGv_env, TCGv_i64))
132062f2b038SRichard Henderson {
132162f2b038SRichard Henderson TCGv_i64 t0;
132262f2b038SRichard Henderson
132362f2b038SRichard Henderson if (!check_of64a32s(dc) ||
132462f2b038SRichard Henderson !check_pair(dc, a->a, a->ap) ||
132562f2b038SRichard Henderson !check_pair(dc, a->d, a->dp)) {
132662f2b038SRichard Henderson return false;
132762f2b038SRichard Henderson }
132862f2b038SRichard Henderson check_r0_write(dc, a->d);
132962f2b038SRichard Henderson
133062f2b038SRichard Henderson t0 = tcg_temp_new_i64();
133162f2b038SRichard Henderson load_pair(dc, t0, a->a, a->ap);
1332ad75a51eSRichard Henderson fn(t0, tcg_env, t0);
133362f2b038SRichard Henderson save_pair(dc, t0, a->d, a->dp);
133462f2b038SRichard Henderson
1335ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
133662f2b038SRichard Henderson return true;
133762f2b038SRichard Henderson }
133862f2b038SRichard Henderson
do_dpcmp(DisasContext * dc,arg_ab_pair * a,void (* fn)(TCGv,TCGv_env,TCGv_i64,TCGv_i64),bool inv,bool swap)133962f2b038SRichard Henderson static bool do_dpcmp(DisasContext *dc, arg_ab_pair *a,
134062f2b038SRichard Henderson void (*fn)(TCGv, TCGv_env, TCGv_i64, TCGv_i64),
134162f2b038SRichard Henderson bool inv, bool swap)
134262f2b038SRichard Henderson {
134362f2b038SRichard Henderson TCGv_i64 t0, t1;
134462f2b038SRichard Henderson
134562f2b038SRichard Henderson if (!check_of64a32s(dc) ||
134662f2b038SRichard Henderson !check_pair(dc, a->a, a->ap) ||
134762f2b038SRichard Henderson !check_pair(dc, a->b, a->bp)) {
134862f2b038SRichard Henderson return false;
134962f2b038SRichard Henderson }
135062f2b038SRichard Henderson
135162f2b038SRichard Henderson t0 = tcg_temp_new_i64();
135262f2b038SRichard Henderson t1 = tcg_temp_new_i64();
135362f2b038SRichard Henderson load_pair(dc, t0, a->a, a->ap);
135462f2b038SRichard Henderson load_pair(dc, t1, a->b, a->bp);
135562f2b038SRichard Henderson if (swap) {
1356ad75a51eSRichard Henderson fn(cpu_sr_f, tcg_env, t1, t0);
135762f2b038SRichard Henderson } else {
1358ad75a51eSRichard Henderson fn(cpu_sr_f, tcg_env, t0, t1);
135962f2b038SRichard Henderson }
136062f2b038SRichard Henderson
136162f2b038SRichard Henderson if (inv) {
136262f2b038SRichard Henderson tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
136362f2b038SRichard Henderson }
1364ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
136562f2b038SRichard Henderson return true;
136662f2b038SRichard Henderson }
136762f2b038SRichard Henderson
trans_lf_add_d(DisasContext * dc,arg_dab_pair * a)136862f2b038SRichard Henderson static bool trans_lf_add_d(DisasContext *dc, arg_dab_pair *a)
136962f2b038SRichard Henderson {
137062f2b038SRichard Henderson return do_dp3(dc, a, gen_helper_float_add_d);
137162f2b038SRichard Henderson }
137262f2b038SRichard Henderson
trans_lf_sub_d(DisasContext * dc,arg_dab_pair * a)137362f2b038SRichard Henderson static bool trans_lf_sub_d(DisasContext *dc, arg_dab_pair *a)
137462f2b038SRichard Henderson {
137562f2b038SRichard Henderson return do_dp3(dc, a, gen_helper_float_sub_d);
137662f2b038SRichard Henderson }
137762f2b038SRichard Henderson
trans_lf_mul_d(DisasContext * dc,arg_dab_pair * a)137862f2b038SRichard Henderson static bool trans_lf_mul_d(DisasContext *dc, arg_dab_pair *a)
137962f2b038SRichard Henderson {
138062f2b038SRichard Henderson return do_dp3(dc, a, gen_helper_float_mul_d);
138162f2b038SRichard Henderson }
138262f2b038SRichard Henderson
trans_lf_div_d(DisasContext * dc,arg_dab_pair * a)138362f2b038SRichard Henderson static bool trans_lf_div_d(DisasContext *dc, arg_dab_pair *a)
138462f2b038SRichard Henderson {
138562f2b038SRichard Henderson return do_dp3(dc, a, gen_helper_float_div_d);
138662f2b038SRichard Henderson }
138762f2b038SRichard Henderson
trans_lf_rem_d(DisasContext * dc,arg_dab_pair * a)138862f2b038SRichard Henderson static bool trans_lf_rem_d(DisasContext *dc, arg_dab_pair *a)
138962f2b038SRichard Henderson {
139062f2b038SRichard Henderson return do_dp3(dc, a, gen_helper_float_rem_d);
139162f2b038SRichard Henderson }
139262f2b038SRichard Henderson
trans_lf_itof_d(DisasContext * dc,arg_da_pair * a)139362f2b038SRichard Henderson static bool trans_lf_itof_d(DisasContext *dc, arg_da_pair *a)
139462f2b038SRichard Henderson {
139562f2b038SRichard Henderson return do_dp2(dc, a, gen_helper_itofd);
139662f2b038SRichard Henderson }
139762f2b038SRichard Henderson
trans_lf_ftoi_d(DisasContext * dc,arg_da_pair * a)139862f2b038SRichard Henderson static bool trans_lf_ftoi_d(DisasContext *dc, arg_da_pair *a)
139962f2b038SRichard Henderson {
140062f2b038SRichard Henderson return do_dp2(dc, a, gen_helper_ftoid);
140162f2b038SRichard Henderson }
140262f2b038SRichard Henderson
trans_lf_stod_d(DisasContext * dc,arg_lf_stod_d * a)140362f2b038SRichard Henderson static bool trans_lf_stod_d(DisasContext *dc, arg_lf_stod_d *a)
140462f2b038SRichard Henderson {
140562f2b038SRichard Henderson TCGv_i64 t0;
140662f2b038SRichard Henderson
140762f2b038SRichard Henderson if (!check_of64a32s(dc) ||
140862f2b038SRichard Henderson !check_pair(dc, a->d, a->dp)) {
140962f2b038SRichard Henderson return false;
141062f2b038SRichard Henderson }
141162f2b038SRichard Henderson check_r0_write(dc, a->d);
141262f2b038SRichard Henderson
141362f2b038SRichard Henderson t0 = tcg_temp_new_i64();
1414ad75a51eSRichard Henderson gen_helper_stod(t0, tcg_env, cpu_R(dc, a->a));
141562f2b038SRichard Henderson save_pair(dc, t0, a->d, a->dp);
141662f2b038SRichard Henderson
1417ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
141862f2b038SRichard Henderson return true;
141962f2b038SRichard Henderson }
142062f2b038SRichard Henderson
trans_lf_dtos_d(DisasContext * dc,arg_lf_dtos_d * a)142162f2b038SRichard Henderson static bool trans_lf_dtos_d(DisasContext *dc, arg_lf_dtos_d *a)
142262f2b038SRichard Henderson {
142362f2b038SRichard Henderson TCGv_i64 t0;
142462f2b038SRichard Henderson
142562f2b038SRichard Henderson if (!check_of64a32s(dc) ||
142662f2b038SRichard Henderson !check_pair(dc, a->a, a->ap)) {
142762f2b038SRichard Henderson return false;
142862f2b038SRichard Henderson }
142962f2b038SRichard Henderson check_r0_write(dc, a->d);
143062f2b038SRichard Henderson
143162f2b038SRichard Henderson t0 = tcg_temp_new_i64();
143262f2b038SRichard Henderson load_pair(dc, t0, a->a, a->ap);
1433ad75a51eSRichard Henderson gen_helper_dtos(cpu_R(dc, a->d), tcg_env, t0);
143462f2b038SRichard Henderson
1435ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
143662f2b038SRichard Henderson return true;
143762f2b038SRichard Henderson }
143862f2b038SRichard Henderson
trans_lf_madd_d(DisasContext * dc,arg_dab_pair * a)143962f2b038SRichard Henderson static bool trans_lf_madd_d(DisasContext *dc, arg_dab_pair *a)
144062f2b038SRichard Henderson {
144162f2b038SRichard Henderson TCGv_i64 t0, t1, t2;
144262f2b038SRichard Henderson
144362f2b038SRichard Henderson if (!check_of64a32s(dc) ||
144462f2b038SRichard Henderson !check_pair(dc, a->a, a->ap) ||
144562f2b038SRichard Henderson !check_pair(dc, a->b, a->bp) ||
144662f2b038SRichard Henderson !check_pair(dc, a->d, a->dp)) {
144762f2b038SRichard Henderson return false;
144862f2b038SRichard Henderson }
144962f2b038SRichard Henderson check_r0_write(dc, a->d);
145062f2b038SRichard Henderson
145162f2b038SRichard Henderson t0 = tcg_temp_new_i64();
145262f2b038SRichard Henderson t1 = tcg_temp_new_i64();
145362f2b038SRichard Henderson t2 = tcg_temp_new_i64();
145462f2b038SRichard Henderson load_pair(dc, t0, a->d, a->dp);
145562f2b038SRichard Henderson load_pair(dc, t1, a->a, a->ap);
145662f2b038SRichard Henderson load_pair(dc, t2, a->b, a->bp);
1457ad75a51eSRichard Henderson gen_helper_float_madd_d(t0, tcg_env, t0, t1, t2);
145862f2b038SRichard Henderson save_pair(dc, t0, a->d, a->dp);
145962f2b038SRichard Henderson
1460ad75a51eSRichard Henderson gen_helper_update_fpcsr(tcg_env);
146162f2b038SRichard Henderson return true;
146262f2b038SRichard Henderson }
146362f2b038SRichard Henderson
trans_lf_sfeq_d(DisasContext * dc,arg_ab_pair * a)146462f2b038SRichard Henderson static bool trans_lf_sfeq_d(DisasContext *dc, arg_ab_pair *a)
146562f2b038SRichard Henderson {
146662f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_eq_d, false, false);
146762f2b038SRichard Henderson }
146862f2b038SRichard Henderson
trans_lf_sfne_d(DisasContext * dc,arg_ab_pair * a)146962f2b038SRichard Henderson static bool trans_lf_sfne_d(DisasContext *dc, arg_ab_pair *a)
147062f2b038SRichard Henderson {
147162f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_eq_d, true, false);
147262f2b038SRichard Henderson }
147362f2b038SRichard Henderson
trans_lf_sfgt_d(DisasContext * dc,arg_ab_pair * a)147462f2b038SRichard Henderson static bool trans_lf_sfgt_d(DisasContext *dc, arg_ab_pair *a)
147562f2b038SRichard Henderson {
147662f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_lt_d, false, true);
147762f2b038SRichard Henderson }
147862f2b038SRichard Henderson
trans_lf_sfge_d(DisasContext * dc,arg_ab_pair * a)147962f2b038SRichard Henderson static bool trans_lf_sfge_d(DisasContext *dc, arg_ab_pair *a)
148062f2b038SRichard Henderson {
148162f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_le_d, false, true);
148262f2b038SRichard Henderson }
148362f2b038SRichard Henderson
trans_lf_sflt_d(DisasContext * dc,arg_ab_pair * a)148462f2b038SRichard Henderson static bool trans_lf_sflt_d(DisasContext *dc, arg_ab_pair *a)
148562f2b038SRichard Henderson {
148662f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_lt_d, false, false);
148762f2b038SRichard Henderson }
148862f2b038SRichard Henderson
trans_lf_sfle_d(DisasContext * dc,arg_ab_pair * a)148962f2b038SRichard Henderson static bool trans_lf_sfle_d(DisasContext *dc, arg_ab_pair *a)
149062f2b038SRichard Henderson {
149162f2b038SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_le_d, false, false);
149262f2b038SRichard Henderson }
149362f2b038SRichard Henderson
trans_lf_sfueq_d(DisasContext * dc,arg_ab_pair * a)14942b13b4b9SRichard Henderson static bool trans_lf_sfueq_d(DisasContext *dc, arg_ab_pair *a)
14952b13b4b9SRichard Henderson {
14962b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_ueq_d, false, false);
14972b13b4b9SRichard Henderson }
14982b13b4b9SRichard Henderson
trans_lf_sfule_d(DisasContext * dc,arg_ab_pair * a)14992b13b4b9SRichard Henderson static bool trans_lf_sfule_d(DisasContext *dc, arg_ab_pair *a)
15002b13b4b9SRichard Henderson {
15012b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_ule_d, false, false);
15022b13b4b9SRichard Henderson }
15032b13b4b9SRichard Henderson
trans_lf_sfuge_d(DisasContext * dc,arg_ab_pair * a)15042b13b4b9SRichard Henderson static bool trans_lf_sfuge_d(DisasContext *dc, arg_ab_pair *a)
15052b13b4b9SRichard Henderson {
15062b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_ule_d, false, true);
15072b13b4b9SRichard Henderson }
15082b13b4b9SRichard Henderson
trans_lf_sfult_d(DisasContext * dc,arg_ab_pair * a)15092b13b4b9SRichard Henderson static bool trans_lf_sfult_d(DisasContext *dc, arg_ab_pair *a)
15102b13b4b9SRichard Henderson {
15112b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_ult_d, false, false);
15122b13b4b9SRichard Henderson }
15132b13b4b9SRichard Henderson
trans_lf_sfugt_d(DisasContext * dc,arg_ab_pair * a)15142b13b4b9SRichard Henderson static bool trans_lf_sfugt_d(DisasContext *dc, arg_ab_pair *a)
15152b13b4b9SRichard Henderson {
15162b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_ult_d, false, true);
15172b13b4b9SRichard Henderson }
15182b13b4b9SRichard Henderson
trans_lf_sfun_d(DisasContext * dc,arg_ab_pair * a)15192b13b4b9SRichard Henderson static bool trans_lf_sfun_d(DisasContext *dc, arg_ab_pair *a)
15202b13b4b9SRichard Henderson {
15212b13b4b9SRichard Henderson return do_dpcmp(dc, a, gen_helper_float_un_d, false, false);
15222b13b4b9SRichard Henderson }
15232b13b4b9SRichard Henderson
openrisc_tr_init_disas_context(DisasContextBase * dcb,CPUState * cs)1524a4fd3ec3SEmilio G. Cota static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
1525fcf5ef2aSThomas Huth {
1526a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcb, DisasContext, base);
1527b77af26eSRichard Henderson CPUOpenRISCState *env = cpu_env(cs);
1528a4fd3ec3SEmilio G. Cota int bound;
1529fcf5ef2aSThomas Huth
15303b916140SRichard Henderson dc->mem_idx = cpu_mmu_index(cs, false);
15311ffa4bceSEmilio G. Cota dc->tb_flags = dc->base.tb->flags;
1532a01deb36SRichard Henderson dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
1533fe636d37SRichard Henderson dc->cpucfgr = env->cpucfgr;
15342b13b4b9SRichard Henderson dc->avr = env->avr;
15358000ba56SRichard Henderson dc->jmp_pc_imm = -1;
15368000ba56SRichard Henderson
1537a4fd3ec3SEmilio G. Cota bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
1538a4fd3ec3SEmilio G. Cota dc->base.max_insns = MIN(dc->base.max_insns, bound);
1539fcf5ef2aSThomas Huth }
1540fcf5ef2aSThomas Huth
openrisc_tr_tb_start(DisasContextBase * db,CPUState * cs)1541a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
1542a4fd3ec3SEmilio G. Cota {
1543a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(db, DisasContext, base);
1544fcf5ef2aSThomas Huth
15456597c28dSRichard Henderson /* Allow the TCG optimizer to see that R0 == 0,
15466597c28dSRichard Henderson when it's true, which is the common case. */
1547118671f0SRichard Henderson dc->zero = tcg_constant_tl(0);
15486597c28dSRichard Henderson if (dc->tb_flags & TB_FLAGS_R0_0) {
1549118671f0SRichard Henderson dc->R0 = dc->zero;
15506597c28dSRichard Henderson } else {
1551d29f4368SRichard Henderson dc->R0 = cpu_regs[0];
15526597c28dSRichard Henderson }
1553a4fd3ec3SEmilio G. Cota }
15546597c28dSRichard Henderson
openrisc_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)1555a4fd3ec3SEmilio G. Cota static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
1556a4fd3ec3SEmilio G. Cota {
1557a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base);
1558a4fd3ec3SEmilio G. Cota
15591ffa4bceSEmilio G. Cota tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
1560a4fd3ec3SEmilio G. Cota | (dc->base.num_insns > 1 ? 2 : 0));
1561a4fd3ec3SEmilio G. Cota }
1562fcf5ef2aSThomas Huth
openrisc_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)1563a4fd3ec3SEmilio G. Cota static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
1564a4fd3ec3SEmilio G. Cota {
1565a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base);
1566*074bd799SPhilippe Mathieu-Daudé uint32_t insn = translator_ldl(cpu_env(cs), &dc->base, dc->base.pc_next);
1567a4fd3ec3SEmilio G. Cota
1568c7b6f54bSRichard Henderson if (!decode(dc, insn)) {
1569c7b6f54bSRichard Henderson gen_illegal_exception(dc);
1570c7b6f54bSRichard Henderson }
15711ffa4bceSEmilio G. Cota dc->base.pc_next += 4;
157224c32852SRichard Henderson
15738000ba56SRichard Henderson /* When exiting the delay slot normally, exit via jmp_pc.
15748000ba56SRichard Henderson * For DISAS_NORETURN, we have raised an exception and already exited.
15758000ba56SRichard Henderson * For DISAS_EXIT, we found l.rfe in a delay slot. There's nothing
15768000ba56SRichard Henderson * in the manual saying this is illegal, but it surely it should.
15778000ba56SRichard Henderson * At least or1ksim overrides pcnext and ignores the branch.
15788000ba56SRichard Henderson */
15798000ba56SRichard Henderson if (dc->delayed_branch
15808000ba56SRichard Henderson && --dc->delayed_branch == 0
15818000ba56SRichard Henderson && dc->base.is_jmp == DISAS_NEXT) {
15828000ba56SRichard Henderson dc->base.is_jmp = DISAS_JUMP;
1583fcf5ef2aSThomas Huth }
1584a4fd3ec3SEmilio G. Cota }
1585fcf5ef2aSThomas Huth
openrisc_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)1586a4fd3ec3SEmilio G. Cota static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
1587a4fd3ec3SEmilio G. Cota {
1588a4fd3ec3SEmilio G. Cota DisasContext *dc = container_of(dcbase, DisasContext, base);
15898000ba56SRichard Henderson target_ulong jmp_dest;
159024c32852SRichard Henderson
1591e0a369cfSRichard Henderson /* If we have already exited the TB, nothing following has effect. */
1592e0a369cfSRichard Henderson if (dc->base.is_jmp == DISAS_NORETURN) {
1593e0a369cfSRichard Henderson return;
1594e0a369cfSRichard Henderson }
1595e0a369cfSRichard Henderson
15968000ba56SRichard Henderson /* Adjust the delayed branch state for the next TB. */
1597a01deb36SRichard Henderson if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
1598a01deb36SRichard Henderson tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
1599a01deb36SRichard Henderson }
1600a01deb36SRichard Henderson
16018000ba56SRichard Henderson /* For DISAS_TOO_MANY, jump to the next insn. */
16028000ba56SRichard Henderson jmp_dest = dc->base.pc_next;
16038000ba56SRichard Henderson tcg_gen_movi_tl(cpu_ppc, jmp_dest - 4);
16048000ba56SRichard Henderson
16051ffa4bceSEmilio G. Cota switch (dc->base.is_jmp) {
16068000ba56SRichard Henderson case DISAS_JUMP:
16078000ba56SRichard Henderson jmp_dest = dc->jmp_pc_imm;
16088000ba56SRichard Henderson if (jmp_dest == -1) {
16098000ba56SRichard Henderson /* The jump destination is indirect/computed; use jmp_pc. */
16108000ba56SRichard Henderson tcg_gen_mov_tl(cpu_pc, jmp_pc);
16118000ba56SRichard Henderson tcg_gen_discard_tl(jmp_pc);
16128000ba56SRichard Henderson tcg_gen_lookup_and_goto_ptr();
1613fcf5ef2aSThomas Huth break;
16148000ba56SRichard Henderson }
16158000ba56SRichard Henderson /* The jump destination is direct; use jmp_pc_imm.
16168000ba56SRichard Henderson However, we will have stored into jmp_pc as well;
16178000ba56SRichard Henderson we know now that it wasn't needed. */
16188000ba56SRichard Henderson tcg_gen_discard_tl(jmp_pc);
16198000ba56SRichard Henderson /* fallthru */
16208000ba56SRichard Henderson
16218000ba56SRichard Henderson case DISAS_TOO_MANY:
1622adf1f3deSRichard Henderson if (translator_use_goto_tb(&dc->base, jmp_dest)) {
16238000ba56SRichard Henderson tcg_gen_goto_tb(0);
16248000ba56SRichard Henderson tcg_gen_movi_tl(cpu_pc, jmp_dest);
16258000ba56SRichard Henderson tcg_gen_exit_tb(dc->base.tb, 0);
1626adf1f3deSRichard Henderson break;
1627adf1f3deSRichard Henderson }
1628adf1f3deSRichard Henderson tcg_gen_movi_tl(cpu_pc, jmp_dest);
1629adf1f3deSRichard Henderson tcg_gen_lookup_and_goto_ptr();
16308000ba56SRichard Henderson break;
16318000ba56SRichard Henderson
163264e46c95SRichard Henderson case DISAS_EXIT:
163307ea28b4SRichard Henderson tcg_gen_exit_tb(NULL, 0);
1634fcf5ef2aSThomas Huth break;
1635a4fd3ec3SEmilio G. Cota default:
1636a4fd3ec3SEmilio G. Cota g_assert_not_reached();
1637a4fd3ec3SEmilio G. Cota }
1638fcf5ef2aSThomas Huth }
1639fcf5ef2aSThomas Huth
1640a4fd3ec3SEmilio G. Cota static const TranslatorOps openrisc_tr_ops = {
1641a4fd3ec3SEmilio G. Cota .init_disas_context = openrisc_tr_init_disas_context,
1642a4fd3ec3SEmilio G. Cota .tb_start = openrisc_tr_tb_start,
1643a4fd3ec3SEmilio G. Cota .insn_start = openrisc_tr_insn_start,
1644a4fd3ec3SEmilio G. Cota .translate_insn = openrisc_tr_translate_insn,
1645a4fd3ec3SEmilio G. Cota .tb_stop = openrisc_tr_tb_stop,
1646a4fd3ec3SEmilio G. Cota };
1647a4fd3ec3SEmilio G. Cota
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)1648597f9b2dSRichard Henderson void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
164932f0c394SAnton Johansson vaddr pc, void *host_pc)
1650a4fd3ec3SEmilio G. Cota {
1651a4fd3ec3SEmilio G. Cota DisasContext ctx;
1652a4fd3ec3SEmilio G. Cota
1653306c8721SRichard Henderson translator_loop(cs, tb, max_insns, pc, host_pc,
1654306c8721SRichard Henderson &openrisc_tr_ops, &ctx.base);
1655fcf5ef2aSThomas Huth }
1656fcf5ef2aSThomas Huth
openrisc_cpu_dump_state(CPUState * cs,FILE * f,int flags)165790c84c56SMarkus Armbruster void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1658fcf5ef2aSThomas Huth {
1659*074bd799SPhilippe Mathieu-Daudé CPUOpenRISCState *env = cpu_env(cs);
1660fcf5ef2aSThomas Huth int i;
1661fcf5ef2aSThomas Huth
166290c84c56SMarkus Armbruster qemu_fprintf(f, "PC=%08x\n", env->pc);
1663fcf5ef2aSThomas Huth for (i = 0; i < 32; ++i) {
166490c84c56SMarkus Armbruster qemu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
1665fcf5ef2aSThomas Huth (i % 4) == 3 ? '\n' : ' ');
1666fcf5ef2aSThomas Huth }
1667fcf5ef2aSThomas Huth }
1668