4 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
5 * Feng Gao <gf91597@gmail.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "exec/exec-all.h"
24 #include "disas/disas.h"
26 #include "qemu-common.h"
28 #include "qemu/bitops.h"
29 #include "exec/cpu_ldst.h"
30 #include "exec/translator.h"
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
34 #include "exec/gen-icount.h"
36 #include "trace-tcg.h"
39 /* is_jmp field values */
40 #define DISAS_EXIT DISAS_TARGET_0 /* force exit to main loop */
41 #define DISAS_JUMP DISAS_TARGET_1 /* exit via jmp_pc/jmp_pc_imm */
43 typedef struct DisasContext
{
44 DisasContextBase base
;
47 uint32_t delayed_branch
;
49 /* If not -1, jmp_pc contains this value and so is a direct jump. */
50 target_ulong jmp_pc_imm
;
53 static inline bool is_user(DisasContext
*dc
)
55 #ifdef CONFIG_USER_ONLY
58 return !(dc
->tb_flags
& TB_FLAGS_SM
);
62 /* Include the auto-generated decoder. */
63 #include "decode.inc.c"
66 static TCGv cpu_R
[32];
69 static TCGv jmp_pc
; /* l.jr/l.jalr temp pc */
71 static TCGv cpu_sr_f
; /* bf/bnf, F flag taken */
72 static TCGv cpu_sr_cy
; /* carry (unsigned overflow) */
73 static TCGv cpu_sr_ov
; /* signed overflow */
74 static TCGv cpu_lock_addr
;
75 static TCGv cpu_lock_value
;
76 static TCGv_i32 fpcsr
;
77 static TCGv_i64 cpu_mac
; /* MACHI:MACLO */
78 static TCGv_i32 cpu_dflag
;
80 void openrisc_translate_init(void)
82 static const char * const regnames
[] = {
83 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
84 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
85 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
86 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
90 cpu_sr
= tcg_global_mem_new(cpu_env
,
91 offsetof(CPUOpenRISCState
, sr
), "sr");
92 cpu_dflag
= tcg_global_mem_new_i32(cpu_env
,
93 offsetof(CPUOpenRISCState
, dflag
),
95 cpu_pc
= tcg_global_mem_new(cpu_env
,
96 offsetof(CPUOpenRISCState
, pc
), "pc");
97 cpu_ppc
= tcg_global_mem_new(cpu_env
,
98 offsetof(CPUOpenRISCState
, ppc
), "ppc");
99 jmp_pc
= tcg_global_mem_new(cpu_env
,
100 offsetof(CPUOpenRISCState
, jmp_pc
), "jmp_pc");
101 cpu_sr_f
= tcg_global_mem_new(cpu_env
,
102 offsetof(CPUOpenRISCState
, sr_f
), "sr_f");
103 cpu_sr_cy
= tcg_global_mem_new(cpu_env
,
104 offsetof(CPUOpenRISCState
, sr_cy
), "sr_cy");
105 cpu_sr_ov
= tcg_global_mem_new(cpu_env
,
106 offsetof(CPUOpenRISCState
, sr_ov
), "sr_ov");
107 cpu_lock_addr
= tcg_global_mem_new(cpu_env
,
108 offsetof(CPUOpenRISCState
, lock_addr
),
110 cpu_lock_value
= tcg_global_mem_new(cpu_env
,
111 offsetof(CPUOpenRISCState
, lock_value
),
113 fpcsr
= tcg_global_mem_new_i32(cpu_env
,
114 offsetof(CPUOpenRISCState
, fpcsr
),
116 cpu_mac
= tcg_global_mem_new_i64(cpu_env
,
117 offsetof(CPUOpenRISCState
, mac
),
119 for (i
= 0; i
< 32; i
++) {
120 cpu_R
[i
] = tcg_global_mem_new(cpu_env
,
121 offsetof(CPUOpenRISCState
,
128 static void gen_exception(DisasContext
*dc
, unsigned int excp
)
130 TCGv_i32 tmp
= tcg_const_i32(excp
);
131 gen_helper_exception(cpu_env
, tmp
);
132 tcg_temp_free_i32(tmp
);
135 static void gen_illegal_exception(DisasContext
*dc
)
137 tcg_gen_movi_tl(cpu_pc
, dc
->base
.pc_next
);
138 gen_exception(dc
, EXCP_ILLEGAL
);
139 dc
->base
.is_jmp
= DISAS_NORETURN
;
142 /* not used yet, open it when we need or64. */
143 /*#ifdef TARGET_OPENRISC64
144 static void check_ob64s(DisasContext *dc)
146 if (!(dc->flags & CPUCFGR_OB64S)) {
147 gen_illegal_exception(dc);
151 static void check_of64s(DisasContext *dc)
153 if (!(dc->flags & CPUCFGR_OF64S)) {
154 gen_illegal_exception(dc);
158 static void check_ov64s(DisasContext *dc)
160 if (!(dc->flags & CPUCFGR_OV64S)) {
161 gen_illegal_exception(dc);
166 /* We're about to write to REG. On the off-chance that the user is
167 writing to R0, re-instate the architectural register. */
168 #define check_r0_write(reg) \
170 if (unlikely(reg == 0)) { \
175 static void gen_ove_cy(DisasContext
*dc
)
177 if (dc
->tb_flags
& SR_OVE
) {
178 gen_helper_ove_cy(cpu_env
);
182 static void gen_ove_ov(DisasContext
*dc
)
184 if (dc
->tb_flags
& SR_OVE
) {
185 gen_helper_ove_ov(cpu_env
);
189 static void gen_ove_cyov(DisasContext
*dc
)
191 if (dc
->tb_flags
& SR_OVE
) {
192 gen_helper_ove_cyov(cpu_env
);
196 static void gen_add(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
198 TCGv t0
= tcg_const_tl(0);
199 TCGv res
= tcg_temp_new();
201 tcg_gen_add2_tl(res
, cpu_sr_cy
, srca
, t0
, srcb
, t0
);
202 tcg_gen_xor_tl(cpu_sr_ov
, srca
, srcb
);
203 tcg_gen_xor_tl(t0
, res
, srcb
);
204 tcg_gen_andc_tl(cpu_sr_ov
, t0
, cpu_sr_ov
);
207 tcg_gen_mov_tl(dest
, res
);
213 static void gen_addc(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
215 TCGv t0
= tcg_const_tl(0);
216 TCGv res
= tcg_temp_new();
218 tcg_gen_add2_tl(res
, cpu_sr_cy
, srca
, t0
, cpu_sr_cy
, t0
);
219 tcg_gen_add2_tl(res
, cpu_sr_cy
, res
, cpu_sr_cy
, srcb
, t0
);
220 tcg_gen_xor_tl(cpu_sr_ov
, srca
, srcb
);
221 tcg_gen_xor_tl(t0
, res
, srcb
);
222 tcg_gen_andc_tl(cpu_sr_ov
, t0
, cpu_sr_ov
);
225 tcg_gen_mov_tl(dest
, res
);
231 static void gen_sub(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
233 TCGv res
= tcg_temp_new();
235 tcg_gen_sub_tl(res
, srca
, srcb
);
236 tcg_gen_xor_tl(cpu_sr_cy
, srca
, srcb
);
237 tcg_gen_xor_tl(cpu_sr_ov
, res
, srcb
);
238 tcg_gen_and_tl(cpu_sr_ov
, cpu_sr_ov
, cpu_sr_cy
);
239 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_sr_cy
, srca
, srcb
);
241 tcg_gen_mov_tl(dest
, res
);
247 static void gen_mul(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
249 TCGv t0
= tcg_temp_new();
251 tcg_gen_muls2_tl(dest
, cpu_sr_ov
, srca
, srcb
);
252 tcg_gen_sari_tl(t0
, dest
, TARGET_LONG_BITS
- 1);
253 tcg_gen_setcond_tl(TCG_COND_NE
, cpu_sr_ov
, cpu_sr_ov
, t0
);
256 tcg_gen_neg_tl(cpu_sr_ov
, cpu_sr_ov
);
260 static void gen_mulu(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
262 tcg_gen_muls2_tl(dest
, cpu_sr_cy
, srca
, srcb
);
263 tcg_gen_setcondi_tl(TCG_COND_NE
, cpu_sr_cy
, cpu_sr_cy
, 0);
268 static void gen_div(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
270 TCGv t0
= tcg_temp_new();
272 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_sr_ov
, srcb
, 0);
273 /* The result of divide-by-zero is undefined.
274 Supress the host-side exception by dividing by 1. */
275 tcg_gen_or_tl(t0
, srcb
, cpu_sr_ov
);
276 tcg_gen_div_tl(dest
, srca
, t0
);
279 tcg_gen_neg_tl(cpu_sr_ov
, cpu_sr_ov
);
283 static void gen_divu(DisasContext
*dc
, TCGv dest
, TCGv srca
, TCGv srcb
)
285 TCGv t0
= tcg_temp_new();
287 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_sr_cy
, srcb
, 0);
288 /* The result of divide-by-zero is undefined.
289 Supress the host-side exception by dividing by 1. */
290 tcg_gen_or_tl(t0
, srcb
, cpu_sr_cy
);
291 tcg_gen_divu_tl(dest
, srca
, t0
);
297 static void gen_muld(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
299 TCGv_i64 t1
= tcg_temp_new_i64();
300 TCGv_i64 t2
= tcg_temp_new_i64();
302 tcg_gen_ext_tl_i64(t1
, srca
);
303 tcg_gen_ext_tl_i64(t2
, srcb
);
304 if (TARGET_LONG_BITS
== 32) {
305 tcg_gen_mul_i64(cpu_mac
, t1
, t2
);
306 tcg_gen_movi_tl(cpu_sr_ov
, 0);
308 TCGv_i64 high
= tcg_temp_new_i64();
310 tcg_gen_muls2_i64(cpu_mac
, high
, t1
, t2
);
311 tcg_gen_sari_i64(t1
, cpu_mac
, 63);
312 tcg_gen_setcond_i64(TCG_COND_NE
, t1
, t1
, high
);
313 tcg_temp_free_i64(high
);
314 tcg_gen_trunc_i64_tl(cpu_sr_ov
, t1
);
315 tcg_gen_neg_tl(cpu_sr_ov
, cpu_sr_ov
);
319 tcg_temp_free_i64(t1
);
320 tcg_temp_free_i64(t2
);
323 static void gen_muldu(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
325 TCGv_i64 t1
= tcg_temp_new_i64();
326 TCGv_i64 t2
= tcg_temp_new_i64();
328 tcg_gen_extu_tl_i64(t1
, srca
);
329 tcg_gen_extu_tl_i64(t2
, srcb
);
330 if (TARGET_LONG_BITS
== 32) {
331 tcg_gen_mul_i64(cpu_mac
, t1
, t2
);
332 tcg_gen_movi_tl(cpu_sr_cy
, 0);
334 TCGv_i64 high
= tcg_temp_new_i64();
336 tcg_gen_mulu2_i64(cpu_mac
, high
, t1
, t2
);
337 tcg_gen_setcondi_i64(TCG_COND_NE
, high
, high
, 0);
338 tcg_gen_trunc_i64_tl(cpu_sr_cy
, high
);
339 tcg_temp_free_i64(high
);
343 tcg_temp_free_i64(t1
);
344 tcg_temp_free_i64(t2
);
347 static void gen_mac(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
349 TCGv_i64 t1
= tcg_temp_new_i64();
350 TCGv_i64 t2
= tcg_temp_new_i64();
352 tcg_gen_ext_tl_i64(t1
, srca
);
353 tcg_gen_ext_tl_i64(t2
, srcb
);
354 tcg_gen_mul_i64(t1
, t1
, t2
);
356 /* Note that overflow is only computed during addition stage. */
357 tcg_gen_xor_i64(t2
, cpu_mac
, t1
);
358 tcg_gen_add_i64(cpu_mac
, cpu_mac
, t1
);
359 tcg_gen_xor_i64(t1
, t1
, cpu_mac
);
360 tcg_gen_andc_i64(t1
, t1
, t2
);
361 tcg_temp_free_i64(t2
);
363 #if TARGET_LONG_BITS == 32
364 tcg_gen_extrh_i64_i32(cpu_sr_ov
, t1
);
366 tcg_gen_mov_i64(cpu_sr_ov
, t1
);
368 tcg_temp_free_i64(t1
);
373 static void gen_macu(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
375 TCGv_i64 t1
= tcg_temp_new_i64();
376 TCGv_i64 t2
= tcg_temp_new_i64();
378 tcg_gen_extu_tl_i64(t1
, srca
);
379 tcg_gen_extu_tl_i64(t2
, srcb
);
380 tcg_gen_mul_i64(t1
, t1
, t2
);
381 tcg_temp_free_i64(t2
);
383 /* Note that overflow is only computed during addition stage. */
384 tcg_gen_add_i64(cpu_mac
, cpu_mac
, t1
);
385 tcg_gen_setcond_i64(TCG_COND_LTU
, t1
, cpu_mac
, t1
);
386 tcg_gen_trunc_i64_tl(cpu_sr_cy
, t1
);
387 tcg_temp_free_i64(t1
);
392 static void gen_msb(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
394 TCGv_i64 t1
= tcg_temp_new_i64();
395 TCGv_i64 t2
= tcg_temp_new_i64();
397 tcg_gen_ext_tl_i64(t1
, srca
);
398 tcg_gen_ext_tl_i64(t2
, srcb
);
399 tcg_gen_mul_i64(t1
, t1
, t2
);
401 /* Note that overflow is only computed during subtraction stage. */
402 tcg_gen_xor_i64(t2
, cpu_mac
, t1
);
403 tcg_gen_sub_i64(cpu_mac
, cpu_mac
, t1
);
404 tcg_gen_xor_i64(t1
, t1
, cpu_mac
);
405 tcg_gen_and_i64(t1
, t1
, t2
);
406 tcg_temp_free_i64(t2
);
408 #if TARGET_LONG_BITS == 32
409 tcg_gen_extrh_i64_i32(cpu_sr_ov
, t1
);
411 tcg_gen_mov_i64(cpu_sr_ov
, t1
);
413 tcg_temp_free_i64(t1
);
418 static void gen_msbu(DisasContext
*dc
, TCGv srca
, TCGv srcb
)
420 TCGv_i64 t1
= tcg_temp_new_i64();
421 TCGv_i64 t2
= tcg_temp_new_i64();
423 tcg_gen_extu_tl_i64(t1
, srca
);
424 tcg_gen_extu_tl_i64(t2
, srcb
);
425 tcg_gen_mul_i64(t1
, t1
, t2
);
427 /* Note that overflow is only computed during subtraction stage. */
428 tcg_gen_setcond_i64(TCG_COND_LTU
, t2
, cpu_mac
, t1
);
429 tcg_gen_sub_i64(cpu_mac
, cpu_mac
, t1
);
430 tcg_gen_trunc_i64_tl(cpu_sr_cy
, t2
);
431 tcg_temp_free_i64(t2
);
432 tcg_temp_free_i64(t1
);
437 static bool trans_l_add(DisasContext
*dc
, arg_dab
*a
)
439 check_r0_write(a
->d
);
440 gen_add(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
444 static bool trans_l_addc(DisasContext
*dc
, arg_dab
*a
)
446 check_r0_write(a
->d
);
447 gen_addc(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
451 static bool trans_l_sub(DisasContext
*dc
, arg_dab
*a
)
453 check_r0_write(a
->d
);
454 gen_sub(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
458 static bool trans_l_and(DisasContext
*dc
, arg_dab
*a
)
460 check_r0_write(a
->d
);
461 tcg_gen_and_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
465 static bool trans_l_or(DisasContext
*dc
, arg_dab
*a
)
467 check_r0_write(a
->d
);
468 tcg_gen_or_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
472 static bool trans_l_xor(DisasContext
*dc
, arg_dab
*a
)
474 check_r0_write(a
->d
);
475 tcg_gen_xor_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
479 static bool trans_l_sll(DisasContext
*dc
, arg_dab
*a
)
481 check_r0_write(a
->d
);
482 tcg_gen_shl_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
486 static bool trans_l_srl(DisasContext
*dc
, arg_dab
*a
)
488 check_r0_write(a
->d
);
489 tcg_gen_shr_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
493 static bool trans_l_sra(DisasContext
*dc
, arg_dab
*a
)
495 check_r0_write(a
->d
);
496 tcg_gen_sar_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
500 static bool trans_l_ror(DisasContext
*dc
, arg_dab
*a
)
502 check_r0_write(a
->d
);
503 tcg_gen_rotr_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
507 static bool trans_l_exths(DisasContext
*dc
, arg_da
*a
)
509 check_r0_write(a
->d
);
510 tcg_gen_ext16s_tl(cpu_R
[a
->d
], cpu_R
[a
->a
]);
514 static bool trans_l_extbs(DisasContext
*dc
, arg_da
*a
)
516 check_r0_write(a
->d
);
517 tcg_gen_ext8s_tl(cpu_R
[a
->d
], cpu_R
[a
->a
]);
521 static bool trans_l_exthz(DisasContext
*dc
, arg_da
*a
)
523 check_r0_write(a
->d
);
524 tcg_gen_ext16u_tl(cpu_R
[a
->d
], cpu_R
[a
->a
]);
528 static bool trans_l_extbz(DisasContext
*dc
, arg_da
*a
)
530 check_r0_write(a
->d
);
531 tcg_gen_ext8u_tl(cpu_R
[a
->d
], cpu_R
[a
->a
]);
535 static bool trans_l_cmov(DisasContext
*dc
, arg_dab
*a
)
539 check_r0_write(a
->d
);
540 zero
= tcg_const_tl(0);
541 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_R
[a
->d
], cpu_sr_f
, zero
,
542 cpu_R
[a
->a
], cpu_R
[a
->b
]);
547 static bool trans_l_ff1(DisasContext
*dc
, arg_da
*a
)
549 check_r0_write(a
->d
);
550 tcg_gen_ctzi_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], -1);
551 tcg_gen_addi_tl(cpu_R
[a
->d
], cpu_R
[a
->d
], 1);
555 static bool trans_l_fl1(DisasContext
*dc
, arg_da
*a
)
557 check_r0_write(a
->d
);
558 tcg_gen_clzi_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], TARGET_LONG_BITS
);
559 tcg_gen_subfi_tl(cpu_R
[a
->d
], TARGET_LONG_BITS
, cpu_R
[a
->d
]);
563 static bool trans_l_mul(DisasContext
*dc
, arg_dab
*a
)
565 check_r0_write(a
->d
);
566 gen_mul(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
570 static bool trans_l_mulu(DisasContext
*dc
, arg_dab
*a
)
572 check_r0_write(a
->d
);
573 gen_mulu(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
577 static bool trans_l_div(DisasContext
*dc
, arg_dab
*a
)
579 check_r0_write(a
->d
);
580 gen_div(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
584 static bool trans_l_divu(DisasContext
*dc
, arg_dab
*a
)
586 check_r0_write(a
->d
);
587 gen_divu(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], cpu_R
[a
->b
]);
591 static bool trans_l_muld(DisasContext
*dc
, arg_ab
*a
)
593 gen_muld(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
597 static bool trans_l_muldu(DisasContext
*dc
, arg_ab
*a
)
599 gen_muldu(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
603 static bool trans_l_j(DisasContext
*dc
, arg_l_j
*a
)
605 target_ulong tmp_pc
= dc
->base
.pc_next
+ a
->n
* 4;
607 tcg_gen_movi_tl(jmp_pc
, tmp_pc
);
608 dc
->jmp_pc_imm
= tmp_pc
;
609 dc
->delayed_branch
= 2;
613 static bool trans_l_jal(DisasContext
*dc
, arg_l_jal
*a
)
615 target_ulong tmp_pc
= dc
->base
.pc_next
+ a
->n
* 4;
616 target_ulong ret_pc
= dc
->base
.pc_next
+ 8;
618 tcg_gen_movi_tl(cpu_R
[9], ret_pc
);
619 /* Optimize jal being used to load the PC for PIC. */
620 if (tmp_pc
!= ret_pc
) {
621 tcg_gen_movi_tl(jmp_pc
, tmp_pc
);
622 dc
->jmp_pc_imm
= tmp_pc
;
623 dc
->delayed_branch
= 2;
628 static void do_bf(DisasContext
*dc
, arg_l_bf
*a
, TCGCond cond
)
630 target_ulong tmp_pc
= dc
->base
.pc_next
+ a
->n
* 4;
631 TCGv t_next
= tcg_const_tl(dc
->base
.pc_next
+ 8);
632 TCGv t_true
= tcg_const_tl(tmp_pc
);
633 TCGv t_zero
= tcg_const_tl(0);
635 tcg_gen_movcond_tl(cond
, jmp_pc
, cpu_sr_f
, t_zero
, t_true
, t_next
);
637 tcg_temp_free(t_next
);
638 tcg_temp_free(t_true
);
639 tcg_temp_free(t_zero
);
640 dc
->delayed_branch
= 2;
643 static bool trans_l_bf(DisasContext
*dc
, arg_l_bf
*a
)
645 do_bf(dc
, a
, TCG_COND_NE
);
649 static bool trans_l_bnf(DisasContext
*dc
, arg_l_bf
*a
)
651 do_bf(dc
, a
, TCG_COND_EQ
);
655 static bool trans_l_jr(DisasContext
*dc
, arg_l_jr
*a
)
657 tcg_gen_mov_tl(jmp_pc
, cpu_R
[a
->b
]);
658 dc
->delayed_branch
= 2;
662 static bool trans_l_jalr(DisasContext
*dc
, arg_l_jalr
*a
)
664 tcg_gen_mov_tl(jmp_pc
, cpu_R
[a
->b
]);
665 tcg_gen_movi_tl(cpu_R
[9], dc
->base
.pc_next
+ 8);
666 dc
->delayed_branch
= 2;
670 static bool trans_l_lwa(DisasContext
*dc
, arg_load
*a
)
674 check_r0_write(a
->d
);
676 tcg_gen_addi_tl(ea
, cpu_R
[a
->a
], a
->i
);
677 tcg_gen_qemu_ld_tl(cpu_R
[a
->d
], ea
, dc
->mem_idx
, MO_TEUL
);
678 tcg_gen_mov_tl(cpu_lock_addr
, ea
);
679 tcg_gen_mov_tl(cpu_lock_value
, cpu_R
[a
->d
]);
684 static void do_load(DisasContext
*dc
, arg_load
*a
, TCGMemOp mop
)
688 check_r0_write(a
->d
);
690 tcg_gen_addi_tl(ea
, cpu_R
[a
->a
], a
->i
);
691 tcg_gen_qemu_ld_tl(cpu_R
[a
->d
], ea
, dc
->mem_idx
, mop
);
695 static bool trans_l_lwz(DisasContext
*dc
, arg_load
*a
)
697 do_load(dc
, a
, MO_TEUL
);
701 static bool trans_l_lws(DisasContext
*dc
, arg_load
*a
)
703 do_load(dc
, a
, MO_TESL
);
707 static bool trans_l_lbz(DisasContext
*dc
, arg_load
*a
)
709 do_load(dc
, a
, MO_UB
);
713 static bool trans_l_lbs(DisasContext
*dc
, arg_load
*a
)
715 do_load(dc
, a
, MO_SB
);
719 static bool trans_l_lhz(DisasContext
*dc
, arg_load
*a
)
721 do_load(dc
, a
, MO_TEUW
);
725 static bool trans_l_lhs(DisasContext
*dc
, arg_load
*a
)
727 do_load(dc
, a
, MO_TESW
);
731 static bool trans_l_swa(DisasContext
*dc
, arg_store
*a
)
734 TCGLabel
*lab_fail
, *lab_done
;
737 tcg_gen_addi_tl(ea
, cpu_R
[a
->a
], a
->i
);
739 /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
740 to cpu_R[0]. Since l.swa is quite often immediately followed by a
741 branch, don't bother reallocating; finish the TB using the "real" R0.
742 This also takes care of RB input across the branch. */
745 lab_fail
= gen_new_label();
746 lab_done
= gen_new_label();
747 tcg_gen_brcond_tl(TCG_COND_NE
, ea
, cpu_lock_addr
, lab_fail
);
750 val
= tcg_temp_new();
751 tcg_gen_atomic_cmpxchg_tl(val
, cpu_lock_addr
, cpu_lock_value
,
752 cpu_R
[a
->b
], dc
->mem_idx
, MO_TEUL
);
753 tcg_gen_setcond_tl(TCG_COND_EQ
, cpu_sr_f
, val
, cpu_lock_value
);
756 tcg_gen_br(lab_done
);
758 gen_set_label(lab_fail
);
759 tcg_gen_movi_tl(cpu_sr_f
, 0);
761 gen_set_label(lab_done
);
762 tcg_gen_movi_tl(cpu_lock_addr
, -1);
766 static void do_store(DisasContext
*dc
, arg_store
*a
, TCGMemOp mop
)
768 TCGv t0
= tcg_temp_new();
769 tcg_gen_addi_tl(t0
, cpu_R
[a
->a
], a
->i
);
770 tcg_gen_qemu_st_tl(cpu_R
[a
->b
], t0
, dc
->mem_idx
, mop
);
774 static bool trans_l_sw(DisasContext
*dc
, arg_store
*a
)
776 do_store(dc
, a
, MO_TEUL
);
780 static bool trans_l_sb(DisasContext
*dc
, arg_store
*a
)
782 do_store(dc
, a
, MO_UB
);
786 static bool trans_l_sh(DisasContext
*dc
, arg_store
*a
)
788 do_store(dc
, a
, MO_TEUW
);
792 static bool trans_l_nop(DisasContext
*dc
, arg_l_nop
*a
)
797 static bool trans_l_addi(DisasContext
*dc
, arg_rri
*a
)
801 check_r0_write(a
->d
);
802 t0
= tcg_const_tl(a
->i
);
803 gen_add(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], t0
);
808 static bool trans_l_addic(DisasContext
*dc
, arg_rri
*a
)
812 check_r0_write(a
->d
);
813 t0
= tcg_const_tl(a
->i
);
814 gen_addc(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], t0
);
819 static bool trans_l_muli(DisasContext
*dc
, arg_rri
*a
)
823 check_r0_write(a
->d
);
824 t0
= tcg_const_tl(a
->i
);
825 gen_mul(dc
, cpu_R
[a
->d
], cpu_R
[a
->a
], t0
);
830 static bool trans_l_maci(DisasContext
*dc
, arg_l_maci
*a
)
834 t0
= tcg_const_tl(a
->i
);
835 gen_mac(dc
, cpu_R
[a
->a
], t0
);
840 static bool trans_l_andi(DisasContext
*dc
, arg_rrk
*a
)
842 check_r0_write(a
->d
);
843 tcg_gen_andi_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->k
);
847 static bool trans_l_ori(DisasContext
*dc
, arg_rrk
*a
)
849 check_r0_write(a
->d
);
850 tcg_gen_ori_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->k
);
854 static bool trans_l_xori(DisasContext
*dc
, arg_rri
*a
)
856 check_r0_write(a
->d
);
857 tcg_gen_xori_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->i
);
861 static bool trans_l_mfspr(DisasContext
*dc
, arg_l_mfspr
*a
)
863 check_r0_write(a
->d
);
866 gen_illegal_exception(dc
);
868 TCGv spr
= tcg_temp_new();
869 tcg_gen_ori_tl(spr
, cpu_R
[a
->a
], a
->k
);
870 gen_helper_mfspr(cpu_R
[a
->d
], cpu_env
, cpu_R
[a
->d
], spr
);
876 static bool trans_l_mtspr(DisasContext
*dc
, arg_l_mtspr
*a
)
879 gen_illegal_exception(dc
);
883 /* For SR, we will need to exit the TB to recognize the new
884 * exception state. For NPC, in theory this counts as a branch
885 * (although the SPR only exists for use by an ICE). Save all
886 * of the cpu state first, allowing it to be overwritten.
888 if (dc
->delayed_branch
) {
889 tcg_gen_mov_tl(cpu_pc
, jmp_pc
);
890 tcg_gen_discard_tl(jmp_pc
);
892 tcg_gen_movi_tl(cpu_pc
, dc
->base
.pc_next
+ 4);
894 dc
->base
.is_jmp
= DISAS_EXIT
;
896 spr
= tcg_temp_new();
897 tcg_gen_ori_tl(spr
, cpu_R
[a
->a
], a
->k
);
898 gen_helper_mtspr(cpu_env
, spr
, cpu_R
[a
->b
]);
904 static bool trans_l_mac(DisasContext
*dc
, arg_ab
*a
)
906 gen_mac(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
910 static bool trans_l_msb(DisasContext
*dc
, arg_ab
*a
)
912 gen_msb(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
916 static bool trans_l_macu(DisasContext
*dc
, arg_ab
*a
)
918 gen_macu(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
922 static bool trans_l_msbu(DisasContext
*dc
, arg_ab
*a
)
924 gen_msbu(dc
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
928 static bool trans_l_slli(DisasContext
*dc
, arg_dal
*a
)
930 check_r0_write(a
->d
);
931 tcg_gen_shli_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->l
& (TARGET_LONG_BITS
- 1));
935 static bool trans_l_srli(DisasContext
*dc
, arg_dal
*a
)
937 check_r0_write(a
->d
);
938 tcg_gen_shri_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->l
& (TARGET_LONG_BITS
- 1));
942 static bool trans_l_srai(DisasContext
*dc
, arg_dal
*a
)
944 check_r0_write(a
->d
);
945 tcg_gen_sari_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->l
& (TARGET_LONG_BITS
- 1));
949 static bool trans_l_rori(DisasContext
*dc
, arg_dal
*a
)
951 check_r0_write(a
->d
);
952 tcg_gen_rotri_tl(cpu_R
[a
->d
], cpu_R
[a
->a
], a
->l
& (TARGET_LONG_BITS
- 1));
956 static bool trans_l_movhi(DisasContext
*dc
, arg_l_movhi
*a
)
958 check_r0_write(a
->d
);
959 tcg_gen_movi_tl(cpu_R
[a
->d
], a
->k
<< 16);
963 static bool trans_l_macrc(DisasContext
*dc
, arg_l_macrc
*a
)
965 check_r0_write(a
->d
);
966 tcg_gen_trunc_i64_tl(cpu_R
[a
->d
], cpu_mac
);
967 tcg_gen_movi_i64(cpu_mac
, 0);
971 static bool trans_l_sfeq(DisasContext
*dc
, arg_ab
*a
)
973 tcg_gen_setcond_tl(TCG_COND_EQ
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
977 static bool trans_l_sfne(DisasContext
*dc
, arg_ab
*a
)
979 tcg_gen_setcond_tl(TCG_COND_NE
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
983 static bool trans_l_sfgtu(DisasContext
*dc
, arg_ab
*a
)
985 tcg_gen_setcond_tl(TCG_COND_GTU
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
989 static bool trans_l_sfgeu(DisasContext
*dc
, arg_ab
*a
)
991 tcg_gen_setcond_tl(TCG_COND_GEU
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
995 static bool trans_l_sfltu(DisasContext
*dc
, arg_ab
*a
)
997 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1001 static bool trans_l_sfleu(DisasContext
*dc
, arg_ab
*a
)
1003 tcg_gen_setcond_tl(TCG_COND_LEU
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1007 static bool trans_l_sfgts(DisasContext
*dc
, arg_ab
*a
)
1009 tcg_gen_setcond_tl(TCG_COND_GT
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1013 static bool trans_l_sfges(DisasContext
*dc
, arg_ab
*a
)
1015 tcg_gen_setcond_tl(TCG_COND_GE
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1019 static bool trans_l_sflts(DisasContext
*dc
, arg_ab
*a
)
1021 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1025 static bool trans_l_sfles(DisasContext
*dc
, arg_ab
*a
)
1027 tcg_gen_setcond_tl(TCG_COND_LE
, cpu_sr_f
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1031 static bool trans_l_sfeqi(DisasContext
*dc
, arg_ai
*a
)
1033 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1037 static bool trans_l_sfnei(DisasContext
*dc
, arg_ai
*a
)
1039 tcg_gen_setcondi_tl(TCG_COND_NE
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1043 static bool trans_l_sfgtui(DisasContext
*dc
, arg_ai
*a
)
1045 tcg_gen_setcondi_tl(TCG_COND_GTU
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1049 static bool trans_l_sfgeui(DisasContext
*dc
, arg_ai
*a
)
1051 tcg_gen_setcondi_tl(TCG_COND_GEU
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1055 static bool trans_l_sfltui(DisasContext
*dc
, arg_ai
*a
)
1057 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1061 static bool trans_l_sfleui(DisasContext
*dc
, arg_ai
*a
)
1063 tcg_gen_setcondi_tl(TCG_COND_LEU
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1067 static bool trans_l_sfgtsi(DisasContext
*dc
, arg_ai
*a
)
1069 tcg_gen_setcondi_tl(TCG_COND_GT
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1073 static bool trans_l_sfgesi(DisasContext
*dc
, arg_ai
*a
)
1075 tcg_gen_setcondi_tl(TCG_COND_GE
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1079 static bool trans_l_sfltsi(DisasContext
*dc
, arg_ai
*a
)
1081 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1085 static bool trans_l_sflesi(DisasContext
*dc
, arg_ai
*a
)
1087 tcg_gen_setcondi_tl(TCG_COND_LE
, cpu_sr_f
, cpu_R
[a
->a
], a
->i
);
1091 static bool trans_l_sys(DisasContext
*dc
, arg_l_sys
*a
)
1093 tcg_gen_movi_tl(cpu_pc
, dc
->base
.pc_next
);
1094 gen_exception(dc
, EXCP_SYSCALL
);
1095 dc
->base
.is_jmp
= DISAS_NORETURN
;
1099 static bool trans_l_trap(DisasContext
*dc
, arg_l_trap
*a
)
1101 tcg_gen_movi_tl(cpu_pc
, dc
->base
.pc_next
);
1102 gen_exception(dc
, EXCP_TRAP
);
1103 dc
->base
.is_jmp
= DISAS_NORETURN
;
1107 static bool trans_l_msync(DisasContext
*dc
, arg_l_msync
*a
)
1109 tcg_gen_mb(TCG_MO_ALL
);
1113 static bool trans_l_psync(DisasContext
*dc
, arg_l_psync
*a
)
1118 static bool trans_l_csync(DisasContext
*dc
, arg_l_csync
*a
)
1123 static bool trans_l_rfe(DisasContext
*dc
, arg_l_rfe
*a
)
1126 gen_illegal_exception(dc
);
1128 gen_helper_rfe(cpu_env
);
1129 dc
->base
.is_jmp
= DISAS_EXIT
;
1134 static void do_fp2(DisasContext
*dc
, arg_da
*a
,
1135 void (*fn
)(TCGv
, TCGv_env
, TCGv
))
1137 check_r0_write(a
->d
);
1138 fn(cpu_R
[a
->d
], cpu_env
, cpu_R
[a
->a
]);
1139 gen_helper_update_fpcsr(cpu_env
);
1142 static void do_fp3(DisasContext
*dc
, arg_dab
*a
,
1143 void (*fn
)(TCGv
, TCGv_env
, TCGv
, TCGv
))
1145 check_r0_write(a
->d
);
1146 fn(cpu_R
[a
->d
], cpu_env
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1147 gen_helper_update_fpcsr(cpu_env
);
1150 static void do_fpcmp(DisasContext
*dc
, arg_ab
*a
,
1151 void (*fn
)(TCGv
, TCGv_env
, TCGv
, TCGv
),
1152 bool inv
, bool swap
)
1155 fn(cpu_sr_f
, cpu_env
, cpu_R
[a
->b
], cpu_R
[a
->a
]);
1157 fn(cpu_sr_f
, cpu_env
, cpu_R
[a
->a
], cpu_R
[a
->b
]);
1160 tcg_gen_xori_tl(cpu_sr_f
, cpu_sr_f
, 1);
1162 gen_helper_update_fpcsr(cpu_env
);
1165 static bool trans_lf_add_s(DisasContext
*dc
, arg_dab
*a
)
1167 do_fp3(dc
, a
, gen_helper_float_add_s
);
1171 static bool trans_lf_sub_s(DisasContext
*dc
, arg_dab
*a
)
1173 do_fp3(dc
, a
, gen_helper_float_sub_s
);
1177 static bool trans_lf_mul_s(DisasContext
*dc
, arg_dab
*a
)
1179 do_fp3(dc
, a
, gen_helper_float_mul_s
);
1183 static bool trans_lf_div_s(DisasContext
*dc
, arg_dab
*a
)
1185 do_fp3(dc
, a
, gen_helper_float_div_s
);
1189 static bool trans_lf_rem_s(DisasContext
*dc
, arg_dab
*a
)
1191 do_fp3(dc
, a
, gen_helper_float_rem_s
);
1195 static bool trans_lf_itof_s(DisasContext
*dc
, arg_da
*a
)
1197 do_fp2(dc
, a
, gen_helper_itofs
);
1201 static bool trans_lf_ftoi_s(DisasContext
*dc
, arg_da
*a
)
1203 do_fp2(dc
, a
, gen_helper_ftois
);
1207 static bool trans_lf_madd_s(DisasContext
*dc
, arg_dab
*a
)
1209 check_r0_write(a
->d
);
1210 gen_helper_float_madd_s(cpu_R
[a
->d
], cpu_env
, cpu_R
[a
->d
],
1211 cpu_R
[a
->a
], cpu_R
[a
->b
]);
1212 gen_helper_update_fpcsr(cpu_env
);
1216 static bool trans_lf_sfeq_s(DisasContext
*dc
, arg_ab
*a
)
1218 do_fpcmp(dc
, a
, gen_helper_float_eq_s
, false, false);
1222 static bool trans_lf_sfne_s(DisasContext
*dc
, arg_ab
*a
)
1224 do_fpcmp(dc
, a
, gen_helper_float_eq_s
, true, false);
1228 static bool trans_lf_sfgt_s(DisasContext
*dc
, arg_ab
*a
)
1230 do_fpcmp(dc
, a
, gen_helper_float_lt_s
, false, true);
1234 static bool trans_lf_sfge_s(DisasContext
*dc
, arg_ab
*a
)
1236 do_fpcmp(dc
, a
, gen_helper_float_le_s
, false, true);
1240 static bool trans_lf_sflt_s(DisasContext
*dc
, arg_ab
*a
)
1242 do_fpcmp(dc
, a
, gen_helper_float_lt_s
, false, false);
1246 static bool trans_lf_sfle_s(DisasContext
*dc
, arg_ab
*a
)
1248 do_fpcmp(dc
, a
, gen_helper_float_le_s
, false, false);
1252 static void openrisc_tr_init_disas_context(DisasContextBase
*dcb
, CPUState
*cs
)
1254 DisasContext
*dc
= container_of(dcb
, DisasContext
, base
);
1255 CPUOpenRISCState
*env
= cs
->env_ptr
;
1258 dc
->mem_idx
= cpu_mmu_index(env
, false);
1259 dc
->tb_flags
= dc
->base
.tb
->flags
;
1260 dc
->delayed_branch
= (dc
->tb_flags
& TB_FLAGS_DFLAG
) != 0;
1261 dc
->jmp_pc_imm
= -1;
1263 bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
1264 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
1267 static void openrisc_tr_tb_start(DisasContextBase
*db
, CPUState
*cs
)
1269 DisasContext
*dc
= container_of(db
, DisasContext
, base
);
1271 /* Allow the TCG optimizer to see that R0 == 0,
1272 when it's true, which is the common case. */
1273 if (dc
->tb_flags
& TB_FLAGS_R0_0
) {
1274 cpu_R
[0] = tcg_const_tl(0);
1280 static void openrisc_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
1282 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
1284 tcg_gen_insn_start(dc
->base
.pc_next
, (dc
->delayed_branch
? 1 : 0)
1285 | (dc
->base
.num_insns
> 1 ? 2 : 0));
1288 static bool openrisc_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
1289 const CPUBreakpoint
*bp
)
1291 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
1293 tcg_gen_movi_tl(cpu_pc
, dc
->base
.pc_next
);
1294 gen_exception(dc
, EXCP_DEBUG
);
1295 dc
->base
.is_jmp
= DISAS_NORETURN
;
1296 /* The address covered by the breakpoint must be included in
1297 [tb->pc, tb->pc + tb->size) in order to for it to be
1298 properly cleared -- thus we increment the PC here so that
1299 the logic setting tb->size below does the right thing. */
1300 dc
->base
.pc_next
+= 4;
1304 static void openrisc_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
1306 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
1307 OpenRISCCPU
*cpu
= OPENRISC_CPU(cs
);
1308 uint32_t insn
= cpu_ldl_code(&cpu
->env
, dc
->base
.pc_next
);
1310 if (!decode(dc
, insn
)) {
1311 gen_illegal_exception(dc
);
1313 dc
->base
.pc_next
+= 4;
1315 /* When exiting the delay slot normally, exit via jmp_pc.
1316 * For DISAS_NORETURN, we have raised an exception and already exited.
1317 * For DISAS_EXIT, we found l.rfe in a delay slot. There's nothing
1318 * in the manual saying this is illegal, but it surely it should.
1319 * At least or1ksim overrides pcnext and ignores the branch.
1321 if (dc
->delayed_branch
1322 && --dc
->delayed_branch
== 0
1323 && dc
->base
.is_jmp
== DISAS_NEXT
) {
1324 dc
->base
.is_jmp
= DISAS_JUMP
;
1328 static void openrisc_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
1330 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
1331 target_ulong jmp_dest
;
1333 /* If we have already exited the TB, nothing following has effect. */
1334 if (dc
->base
.is_jmp
== DISAS_NORETURN
) {
1338 /* Adjust the delayed branch state for the next TB. */
1339 if ((dc
->tb_flags
& TB_FLAGS_DFLAG
? 1 : 0) != (dc
->delayed_branch
!= 0)) {
1340 tcg_gen_movi_i32(cpu_dflag
, dc
->delayed_branch
!= 0);
1343 /* For DISAS_TOO_MANY, jump to the next insn. */
1344 jmp_dest
= dc
->base
.pc_next
;
1345 tcg_gen_movi_tl(cpu_ppc
, jmp_dest
- 4);
1347 switch (dc
->base
.is_jmp
) {
1349 jmp_dest
= dc
->jmp_pc_imm
;
1350 if (jmp_dest
== -1) {
1351 /* The jump destination is indirect/computed; use jmp_pc. */
1352 tcg_gen_mov_tl(cpu_pc
, jmp_pc
);
1353 tcg_gen_discard_tl(jmp_pc
);
1354 if (unlikely(dc
->base
.singlestep_enabled
)) {
1355 gen_exception(dc
, EXCP_DEBUG
);
1357 tcg_gen_lookup_and_goto_ptr();
1361 /* The jump destination is direct; use jmp_pc_imm.
1362 However, we will have stored into jmp_pc as well;
1363 we know now that it wasn't needed. */
1364 tcg_gen_discard_tl(jmp_pc
);
1367 case DISAS_TOO_MANY
:
1368 if (unlikely(dc
->base
.singlestep_enabled
)) {
1369 tcg_gen_movi_tl(cpu_pc
, jmp_dest
);
1370 gen_exception(dc
, EXCP_DEBUG
);
1371 } else if ((dc
->base
.pc_first
^ jmp_dest
) & TARGET_PAGE_MASK
) {
1372 tcg_gen_movi_tl(cpu_pc
, jmp_dest
);
1373 tcg_gen_lookup_and_goto_ptr();
1376 tcg_gen_movi_tl(cpu_pc
, jmp_dest
);
1377 tcg_gen_exit_tb(dc
->base
.tb
, 0);
1382 if (unlikely(dc
->base
.singlestep_enabled
)) {
1383 gen_exception(dc
, EXCP_DEBUG
);
1385 tcg_gen_exit_tb(NULL
, 0);
1389 g_assert_not_reached();
1393 static void openrisc_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
1395 DisasContext
*s
= container_of(dcbase
, DisasContext
, base
);
1397 qemu_log("IN: %s\n", lookup_symbol(s
->base
.pc_first
));
1398 log_target_disas(cs
, s
->base
.pc_first
, s
->base
.tb
->size
);
1401 static const TranslatorOps openrisc_tr_ops
= {
1402 .init_disas_context
= openrisc_tr_init_disas_context
,
1403 .tb_start
= openrisc_tr_tb_start
,
1404 .insn_start
= openrisc_tr_insn_start
,
1405 .breakpoint_check
= openrisc_tr_breakpoint_check
,
1406 .translate_insn
= openrisc_tr_translate_insn
,
1407 .tb_stop
= openrisc_tr_tb_stop
,
1408 .disas_log
= openrisc_tr_disas_log
,
1411 void gen_intermediate_code(CPUState
*cs
, struct TranslationBlock
*tb
)
1415 translator_loop(&openrisc_tr_ops
, &ctx
.base
, cs
, tb
);
1418 void openrisc_cpu_dump_state(CPUState
*cs
, FILE *f
,
1419 fprintf_function cpu_fprintf
,
1422 OpenRISCCPU
*cpu
= OPENRISC_CPU(cs
);
1423 CPUOpenRISCState
*env
= &cpu
->env
;
1426 cpu_fprintf(f
, "PC=%08x\n", env
->pc
);
1427 for (i
= 0; i
< 32; ++i
) {
1428 cpu_fprintf(f
, "R%02d=%08x%c", i
, cpu_get_gpr(env
, i
),
1429 (i
% 4) == 3 ? '\n' : ' ');
1433 void restore_state_to_opc(CPUOpenRISCState
*env
, TranslationBlock
*tb
,
1437 env
->dflag
= data
[1] & 1;
1439 env
->ppc
= env
->pc
- 4;