2 * CRIS emulation for qemu: main translation routines.
4 * Copyright (c) 2008 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
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/>.
23 * The condition code translation is in need of attention.
26 #include "qemu/osdep.h"
28 #include "disas/disas.h"
29 #include "exec/exec-all.h"
30 #include "tcg/tcg-op.h"
31 #include "exec/helper-proto.h"
33 #include "exec/cpu_ldst.h"
34 #include "exec/translator.h"
35 #include "crisv32-decode.h"
36 #include "qemu/qemu-print.h"
37 #include "exec/helper-gen.h"
40 #define HELPER_H "helper.h"
41 #include "exec/helper-info.c.inc"
47 # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
49 # define LOG_DIS(...) do { } while (0)
53 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
54 #define BUG_ON(x) ({if (x) BUG();})
57 * Target-specific is_jmp field values
59 /* Only pc was modified dynamically */
60 #define DISAS_JUMP DISAS_TARGET_0
61 /* Cpu state was modified dynamically, including pc */
62 #define DISAS_UPDATE DISAS_TARGET_1
63 /* Cpu state was modified dynamically, excluding pc -- use npc */
64 #define DISAS_UPDATE_NEXT DISAS_TARGET_2
65 /* PC update for delayed branch, see cpustate_changed otherwise */
66 #define DISAS_DBRANCH DISAS_TARGET_3
68 /* Used by the decoder. */
69 #define EXTRACT_FIELD(src, start, end) \
70 (((src) >> start) & ((1 << (end - start + 1)) - 1))
72 #define CC_MASK_NZ 0xc
73 #define CC_MASK_NZV 0xe
74 #define CC_MASK_NZVC 0xf
75 #define CC_MASK_RNZV 0x10e
77 static TCGv cpu_R
[16];
78 static TCGv cpu_PR
[16];
82 static TCGv cc_result
;
87 static TCGv env_btaken
;
88 static TCGv env_btarget
;
91 /* This is the state at translation time. */
92 typedef struct DisasContext
{
93 DisasContextBase base
;
99 unsigned int (*decoder
)(CPUCRISState
*env
, struct DisasContext
*dc
);
104 unsigned int zsize
, zzsize
;
106 unsigned int postinc
;
118 int cc_size_uptodate
; /* -1 invalid or last written value. */
120 int cc_x_uptodate
; /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date. */
121 int flags_uptodate
; /* Whether or not $ccs is up-to-date. */
124 int clear_x
; /* Clear x after this insn? */
125 int clear_prefix
; /* Clear prefix after this insn? */
126 int clear_locked_irq
; /* Clear the irq lockout. */
127 int cpustate_changed
;
128 unsigned int tb_flags
; /* tb dependent flags. */
132 #define JMP_DIRECT_CC 2
133 #define JMP_INDIRECT 3
134 int jmp
; /* 0=nojmp, 1=direct, 2=indirect. */
140 static void gen_BUG(DisasContext
*dc
, const char *file
, int line
)
142 cpu_abort(CPU(dc
->cpu
), "%s:%d pc=%x\n", file
, line
, dc
->pc
);
145 static const char * const regnames_v32
[] =
147 "$r0", "$r1", "$r2", "$r3",
148 "$r4", "$r5", "$r6", "$r7",
149 "$r8", "$r9", "$r10", "$r11",
150 "$r12", "$r13", "$sp", "$acr",
153 static const char * const pregnames_v32
[] =
155 "$bz", "$vr", "$pid", "$srs",
156 "$wz", "$exs", "$eda", "$mof",
157 "$dz", "$ebp", "$erp", "$srp",
158 "$nrp", "$ccs", "$usp", "$spc",
161 /* We need this table to handle preg-moves with implicit width. */
162 static const int preg_sizes
[] = {
173 #define t_gen_mov_TN_env(tn, member) \
174 tcg_gen_ld_tl(tn, tcg_env, offsetof(CPUCRISState, member))
175 #define t_gen_mov_env_TN(member, tn) \
176 tcg_gen_st_tl(tn, tcg_env, offsetof(CPUCRISState, member))
177 #define t_gen_movi_env_TN(member, c) \
178 t_gen_mov_env_TN(member, tcg_constant_tl(c))
180 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
182 assert(r
>= 0 && r
<= 15);
183 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
184 tcg_gen_movi_tl(tn
, 0);
185 } else if (r
== PR_VR
) {
186 tcg_gen_movi_tl(tn
, 32);
188 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
191 static inline void t_gen_mov_preg_TN(DisasContext
*dc
, int r
, TCGv tn
)
193 assert(r
>= 0 && r
<= 15);
194 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
196 } else if (r
== PR_SRS
) {
197 tcg_gen_andi_tl(cpu_PR
[r
], tn
, 3);
200 gen_helper_tlb_flush_pid(tcg_env
, tn
);
202 if (dc
->tb_flags
& S_FLAG
&& r
== PR_SPC
) {
203 gen_helper_spc_write(tcg_env
, tn
);
204 } else if (r
== PR_CCS
) {
205 dc
->cpustate_changed
= 1;
207 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
211 /* Sign extend at translation time. */
212 static int sign_extend(unsigned int val
, unsigned int width
)
224 static int cris_fetch(CPUCRISState
*env
, DisasContext
*dc
, uint32_t addr
,
225 unsigned int size
, unsigned int sign
)
232 r
= cpu_ldl_code(env
, addr
);
238 r
= cpu_ldsw_code(env
, addr
);
240 r
= cpu_lduw_code(env
, addr
);
247 r
= cpu_ldsb_code(env
, addr
);
249 r
= cpu_ldub_code(env
, addr
);
254 cpu_abort(CPU(dc
->cpu
), "Invalid fetch size %d\n", size
);
260 static void cris_lock_irq(DisasContext
*dc
)
262 dc
->clear_locked_irq
= 0;
263 t_gen_movi_env_TN(locked_irq
, 1);
266 static inline void t_gen_raise_exception(uint32_t index
)
268 gen_helper_raise_exception(tcg_env
, tcg_constant_i32(index
));
271 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
276 t_31
= tcg_constant_tl(31);
277 tcg_gen_shl_tl(d
, a
, b
);
279 tcg_gen_sub_tl(t0
, t_31
, b
);
280 tcg_gen_sar_tl(t0
, t0
, t_31
);
281 tcg_gen_and_tl(t0
, t0
, d
);
282 tcg_gen_xor_tl(d
, d
, t0
);
285 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
290 t_31
= tcg_temp_new();
291 tcg_gen_shr_tl(d
, a
, b
);
293 tcg_gen_movi_tl(t_31
, 31);
294 tcg_gen_sub_tl(t0
, t_31
, b
);
295 tcg_gen_sar_tl(t0
, t0
, t_31
);
296 tcg_gen_and_tl(t0
, t0
, d
);
297 tcg_gen_xor_tl(d
, d
, t0
);
300 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
305 t_31
= tcg_temp_new();
306 tcg_gen_sar_tl(d
, a
, b
);
308 tcg_gen_movi_tl(t_31
, 31);
309 tcg_gen_sub_tl(t0
, t_31
, b
);
310 tcg_gen_sar_tl(t0
, t0
, t_31
);
311 tcg_gen_or_tl(d
, d
, t0
);
314 static void t_gen_cris_dstep(TCGv d
, TCGv a
, TCGv b
)
316 TCGv t
= tcg_temp_new();
323 tcg_gen_shli_tl(d
, a
, 1);
324 tcg_gen_sub_tl(t
, d
, b
);
325 tcg_gen_movcond_tl(TCG_COND_GEU
, d
, d
, b
, t
, d
);
328 static void t_gen_cris_mstep(TCGv d
, TCGv a
, TCGv b
, TCGv ccs
)
338 tcg_gen_shli_tl(d
, a
, 1);
339 tcg_gen_shli_tl(t
, ccs
, 31 - 3);
340 tcg_gen_sari_tl(t
, t
, 31);
341 tcg_gen_and_tl(t
, t
, b
);
342 tcg_gen_add_tl(d
, d
, t
);
345 /* Extended arithmetic on CRIS. */
346 static inline void t_gen_add_flag(TCGv d
, int flag
)
351 t_gen_mov_TN_preg(c
, PR_CCS
);
352 /* Propagate carry into d. */
353 tcg_gen_andi_tl(c
, c
, 1 << flag
);
355 tcg_gen_shri_tl(c
, c
, flag
);
357 tcg_gen_add_tl(d
, d
, c
);
360 static inline void t_gen_addx_carry(DisasContext
*dc
, TCGv d
)
363 TCGv c
= tcg_temp_new();
365 t_gen_mov_TN_preg(c
, PR_CCS
);
366 /* C flag is already at bit 0. */
367 tcg_gen_andi_tl(c
, c
, C_FLAG
);
368 tcg_gen_add_tl(d
, d
, c
);
372 static inline void t_gen_subx_carry(DisasContext
*dc
, TCGv d
)
375 TCGv c
= tcg_temp_new();
377 t_gen_mov_TN_preg(c
, PR_CCS
);
378 /* C flag is already at bit 0. */
379 tcg_gen_andi_tl(c
, c
, C_FLAG
);
380 tcg_gen_sub_tl(d
, d
, c
);
384 /* Swap the two bytes within each half word of the s operand.
385 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
386 static inline void t_gen_swapb(TCGv d
, TCGv s
)
391 org_s
= tcg_temp_new();
393 /* d and s may refer to the same object. */
394 tcg_gen_mov_tl(org_s
, s
);
395 tcg_gen_shli_tl(t
, org_s
, 8);
396 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
397 tcg_gen_shri_tl(t
, org_s
, 8);
398 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
399 tcg_gen_or_tl(d
, d
, t
);
402 /* Swap the halfwords of the s operand. */
403 static inline void t_gen_swapw(TCGv d
, TCGv s
)
406 /* d and s refer the same object. */
408 tcg_gen_mov_tl(t
, s
);
409 tcg_gen_shli_tl(d
, t
, 16);
410 tcg_gen_shri_tl(t
, t
, 16);
411 tcg_gen_or_tl(d
, d
, t
);
415 * Reverse the bits within each byte.
417 * T0 = ((T0 << 7) & 0x80808080)
418 * | ((T0 << 5) & 0x40404040)
419 * | ((T0 << 3) & 0x20202020)
420 * | ((T0 << 1) & 0x10101010)
421 * | ((T0 >> 1) & 0x08080808)
422 * | ((T0 >> 3) & 0x04040404)
423 * | ((T0 >> 5) & 0x02020202)
424 * | ((T0 >> 7) & 0x01010101);
426 static void t_gen_swapr(TCGv d
, TCGv s
)
428 static const struct {
429 int shift
; /* LSL when positive, LSR when negative. */
444 /* d and s refer the same object. */
446 org_s
= tcg_temp_new();
447 tcg_gen_mov_tl(org_s
, s
);
449 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
450 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
451 for (i
= 1; i
< ARRAY_SIZE(bitrev
); i
++) {
452 if (bitrev
[i
].shift
>= 0) {
453 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
455 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
457 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
458 tcg_gen_or_tl(d
, d
, t
);
462 static bool use_goto_tb(DisasContext
*dc
, target_ulong dest
)
464 return translator_use_goto_tb(&dc
->base
, dest
);
467 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
469 if (use_goto_tb(dc
, dest
)) {
471 tcg_gen_movi_tl(env_pc
, dest
);
472 tcg_gen_exit_tb(dc
->base
.tb
, n
);
474 tcg_gen_movi_tl(env_pc
, dest
);
475 tcg_gen_lookup_and_goto_ptr();
479 static inline void cris_clear_x_flag(DisasContext
*dc
)
482 dc
->flags_uptodate
= 0;
487 static void cris_flush_cc_state(DisasContext
*dc
)
489 if (dc
->cc_size_uptodate
!= dc
->cc_size
) {
490 tcg_gen_movi_tl(cc_size
, dc
->cc_size
);
491 dc
->cc_size_uptodate
= dc
->cc_size
;
493 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
494 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
497 static void cris_evaluate_flags(DisasContext
*dc
)
499 if (dc
->flags_uptodate
) {
503 cris_flush_cc_state(dc
);
507 gen_helper_evaluate_flags_mcp(cpu_PR
[PR_CCS
], tcg_env
,
508 cpu_PR
[PR_CCS
], cc_src
,
512 gen_helper_evaluate_flags_muls(cpu_PR
[PR_CCS
], tcg_env
,
513 cpu_PR
[PR_CCS
], cc_result
,
517 gen_helper_evaluate_flags_mulu(cpu_PR
[PR_CCS
], tcg_env
,
518 cpu_PR
[PR_CCS
], cc_result
,
528 switch (dc
->cc_size
) {
530 gen_helper_evaluate_flags_move_4(cpu_PR
[PR_CCS
],
531 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
534 gen_helper_evaluate_flags_move_2(cpu_PR
[PR_CCS
],
535 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
538 gen_helper_evaluate_flags(tcg_env
);
547 if (dc
->cc_size
== 4) {
548 gen_helper_evaluate_flags_sub_4(cpu_PR
[PR_CCS
], tcg_env
,
549 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
551 gen_helper_evaluate_flags(tcg_env
);
556 switch (dc
->cc_size
) {
558 gen_helper_evaluate_flags_alu_4(cpu_PR
[PR_CCS
], tcg_env
,
559 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
562 gen_helper_evaluate_flags(tcg_env
);
569 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], X_FLAG
);
570 } else if (dc
->cc_op
== CC_OP_FLAGS
) {
571 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~X_FLAG
);
573 dc
->flags_uptodate
= 1;
576 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
585 /* Check if we need to evaluate the condition codes due to
587 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
589 /* TODO: optimize this case. It trigs all the time. */
590 cris_evaluate_flags(dc
);
596 static void cris_update_cc_op(DisasContext
*dc
, int op
, int size
)
600 dc
->flags_uptodate
= 0;
603 static inline void cris_update_cc_x(DisasContext
*dc
)
605 /* Save the x flag state at the time of the cc snapshot. */
606 if (dc
->cc_x_uptodate
== (2 | dc
->flags_x
)) {
609 tcg_gen_movi_tl(cc_x
, dc
->flags_x
);
610 dc
->cc_x_uptodate
= 2 | dc
->flags_x
;
613 /* Update cc prior to executing ALU op. Needs source operands untouched. */
614 static void cris_pre_alu_update_cc(DisasContext
*dc
, int op
,
615 TCGv dst
, TCGv src
, int size
)
618 cris_update_cc_op(dc
, op
, size
);
619 tcg_gen_mov_tl(cc_src
, src
);
627 && op
!= CC_OP_LSL
) {
628 tcg_gen_mov_tl(cc_dest
, dst
);
631 cris_update_cc_x(dc
);
635 /* Update cc after executing ALU op. needs the result. */
636 static inline void cris_update_result(DisasContext
*dc
, TCGv res
)
639 tcg_gen_mov_tl(cc_result
, res
);
643 /* Returns one if the write back stage should execute. */
644 static void cris_alu_op_exec(DisasContext
*dc
, int op
,
645 TCGv dst
, TCGv a
, TCGv b
, int size
)
647 /* Emit the ALU insns. */
650 tcg_gen_add_tl(dst
, a
, b
);
651 /* Extended arithmetic. */
652 t_gen_addx_carry(dc
, dst
);
655 tcg_gen_add_tl(dst
, a
, b
);
656 t_gen_add_flag(dst
, 0); /* C_FLAG. */
659 tcg_gen_add_tl(dst
, a
, b
);
660 t_gen_add_flag(dst
, 8); /* R_FLAG. */
663 tcg_gen_sub_tl(dst
, a
, b
);
664 /* Extended arithmetic. */
665 t_gen_subx_carry(dc
, dst
);
668 tcg_gen_mov_tl(dst
, b
);
671 tcg_gen_or_tl(dst
, a
, b
);
674 tcg_gen_and_tl(dst
, a
, b
);
677 tcg_gen_xor_tl(dst
, a
, b
);
680 t_gen_lsl(dst
, a
, b
);
683 t_gen_lsr(dst
, a
, b
);
686 t_gen_asr(dst
, a
, b
);
689 tcg_gen_neg_tl(dst
, b
);
690 /* Extended arithmetic. */
691 t_gen_subx_carry(dc
, dst
);
694 tcg_gen_clzi_tl(dst
, b
, TARGET_LONG_BITS
);
697 tcg_gen_muls2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
700 tcg_gen_mulu2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
703 t_gen_cris_dstep(dst
, a
, b
);
706 t_gen_cris_mstep(dst
, a
, b
, cpu_PR
[PR_CCS
]);
709 tcg_gen_movcond_tl(TCG_COND_LEU
, dst
, a
, b
, a
, b
);
712 tcg_gen_sub_tl(dst
, a
, b
);
713 /* Extended arithmetic. */
714 t_gen_subx_carry(dc
, dst
);
717 qemu_log_mask(LOG_GUEST_ERROR
, "illegal ALU op.\n");
723 tcg_gen_andi_tl(dst
, dst
, 0xff);
724 } else if (size
== 2) {
725 tcg_gen_andi_tl(dst
, dst
, 0xffff);
729 static void cris_alu(DisasContext
*dc
, int op
,
730 TCGv d
, TCGv op_a
, TCGv op_b
, int size
)
737 if (op
== CC_OP_CMP
) {
738 tmp
= tcg_temp_new();
740 } else if (size
== 4) {
744 tmp
= tcg_temp_new();
748 cris_pre_alu_update_cc(dc
, op
, op_a
, op_b
, size
);
749 cris_alu_op_exec(dc
, op
, tmp
, op_a
, op_b
, size
);
750 cris_update_result(dc
, tmp
);
755 tcg_gen_andi_tl(d
, d
, ~0xff);
757 tcg_gen_andi_tl(d
, d
, ~0xffff);
759 tcg_gen_or_tl(d
, d
, tmp
);
763 static int arith_cc(DisasContext
*dc
)
767 case CC_OP_ADDC
: return 1;
768 case CC_OP_ADD
: return 1;
769 case CC_OP_SUB
: return 1;
770 case CC_OP_DSTEP
: return 1;
771 case CC_OP_LSL
: return 1;
772 case CC_OP_LSR
: return 1;
773 case CC_OP_ASR
: return 1;
774 case CC_OP_CMP
: return 1;
775 case CC_OP_NEG
: return 1;
776 case CC_OP_OR
: return 1;
777 case CC_OP_AND
: return 1;
778 case CC_OP_XOR
: return 1;
779 case CC_OP_MULU
: return 1;
780 case CC_OP_MULS
: return 1;
788 static void gen_tst_cc (DisasContext
*dc
, TCGv cc
, int cond
)
790 int arith_opt
, move_opt
;
792 /* TODO: optimize more condition codes. */
795 * If the flags are live, we've gotta look into the bits of CCS.
796 * Otherwise, if we just did an arithmetic operation we try to
797 * evaluate the condition code faster.
799 * When this function is done, T0 should be non-zero if the condition
802 arith_opt
= arith_cc(dc
) && !dc
->flags_uptodate
;
803 move_opt
= (dc
->cc_op
== CC_OP_MOVE
);
806 if ((arith_opt
|| move_opt
)
807 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
808 tcg_gen_setcondi_tl(TCG_COND_EQ
, cc
, cc_result
, 0);
810 cris_evaluate_flags(dc
);
812 cpu_PR
[PR_CCS
], Z_FLAG
);
816 if ((arith_opt
|| move_opt
)
817 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
818 tcg_gen_mov_tl(cc
, cc_result
);
820 cris_evaluate_flags(dc
);
821 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
823 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
827 cris_evaluate_flags(dc
);
828 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
831 cris_evaluate_flags(dc
);
832 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
833 tcg_gen_andi_tl(cc
, cc
, C_FLAG
);
836 cris_evaluate_flags(dc
);
837 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], V_FLAG
);
840 cris_evaluate_flags(dc
);
841 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
843 tcg_gen_andi_tl(cc
, cc
, V_FLAG
);
846 if (arith_opt
|| move_opt
) {
849 if (dc
->cc_size
== 1) {
851 } else if (dc
->cc_size
== 2) {
855 tcg_gen_shri_tl(cc
, cc_result
, bits
);
856 tcg_gen_xori_tl(cc
, cc
, 1);
858 cris_evaluate_flags(dc
);
859 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
861 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
865 if (arith_opt
|| move_opt
) {
868 if (dc
->cc_size
== 1) {
870 } else if (dc
->cc_size
== 2) {
874 tcg_gen_shri_tl(cc
, cc_result
, bits
);
875 tcg_gen_andi_tl(cc
, cc
, 1);
877 cris_evaluate_flags(dc
);
878 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
883 cris_evaluate_flags(dc
);
884 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
888 cris_evaluate_flags(dc
);
892 tmp
= tcg_temp_new();
893 tcg_gen_xori_tl(tmp
, cpu_PR
[PR_CCS
],
895 /* Overlay the C flag on top of the Z. */
896 tcg_gen_shli_tl(cc
, tmp
, 2);
897 tcg_gen_and_tl(cc
, tmp
, cc
);
898 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
902 cris_evaluate_flags(dc
);
903 /* Overlay the V flag on top of the N. */
904 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
907 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
908 tcg_gen_xori_tl(cc
, cc
, N_FLAG
);
911 cris_evaluate_flags(dc
);
912 /* Overlay the V flag on top of the N. */
913 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
916 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
919 cris_evaluate_flags(dc
);
926 /* To avoid a shift we overlay everything on
928 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
929 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
931 tcg_gen_xori_tl(z
, z
, 2);
933 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
934 tcg_gen_xori_tl(n
, n
, 2);
935 tcg_gen_and_tl(cc
, z
, n
);
936 tcg_gen_andi_tl(cc
, cc
, 2);
940 cris_evaluate_flags(dc
);
947 /* To avoid a shift we overlay everything on
949 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
950 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
952 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
953 tcg_gen_or_tl(cc
, z
, n
);
954 tcg_gen_andi_tl(cc
, cc
, 2);
958 cris_evaluate_flags(dc
);
959 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], P_FLAG
);
962 tcg_gen_movi_tl(cc
, 1);
970 static void cris_store_direct_jmp(DisasContext
*dc
)
972 /* Store the direct jmp state into the cpu-state. */
973 if (dc
->jmp
== JMP_DIRECT
|| dc
->jmp
== JMP_DIRECT_CC
) {
974 if (dc
->jmp
== JMP_DIRECT
) {
975 tcg_gen_movi_tl(env_btaken
, 1);
977 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
978 dc
->jmp
= JMP_INDIRECT
;
982 static void cris_prepare_cc_branch (DisasContext
*dc
,
983 int offset
, int cond
)
985 /* This helps us re-schedule the micro-code to insns in delay-slots
986 before the actual jump. */
987 dc
->delayed_branch
= 2;
988 dc
->jmp
= JMP_DIRECT_CC
;
989 dc
->jmp_pc
= dc
->pc
+ offset
;
991 gen_tst_cc(dc
, env_btaken
, cond
);
992 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
996 /* jumps, when the dest is in a live reg for example. Direct should be set
997 when the dest addr is constant to allow tb chaining. */
998 static inline void cris_prepare_jmp (DisasContext
*dc
, unsigned int type
)
1000 /* This helps us re-schedule the micro-code to insns in delay-slots
1001 before the actual jump. */
1002 dc
->delayed_branch
= 2;
1004 if (type
== JMP_INDIRECT
) {
1005 tcg_gen_movi_tl(env_btaken
, 1);
1009 static void gen_load64(DisasContext
*dc
, TCGv_i64 dst
, TCGv addr
)
1011 int mem_index
= cpu_mmu_index(&dc
->cpu
->env
, false);
1013 /* If we get a fault on a delayslot we must keep the jmp state in
1014 the cpu-state to be able to re-execute the jmp. */
1015 if (dc
->delayed_branch
== 1) {
1016 cris_store_direct_jmp(dc
);
1019 tcg_gen_qemu_ld_i64(dst
, addr
, mem_index
, MO_TEUQ
);
1022 static void gen_load(DisasContext
*dc
, TCGv dst
, TCGv addr
,
1023 unsigned int size
, int sign
)
1025 int mem_index
= cpu_mmu_index(&dc
->cpu
->env
, false);
1027 /* If we get a fault on a delayslot we must keep the jmp state in
1028 the cpu-state to be able to re-execute the jmp. */
1029 if (dc
->delayed_branch
== 1) {
1030 cris_store_direct_jmp(dc
);
1033 tcg_gen_qemu_ld_tl(dst
, addr
, mem_index
,
1034 MO_TE
+ ctz32(size
) + (sign
? MO_SIGN
: 0));
1037 static void gen_store (DisasContext
*dc
, TCGv addr
, TCGv val
,
1040 int mem_index
= cpu_mmu_index(&dc
->cpu
->env
, false);
1042 /* If we get a fault on a delayslot we must keep the jmp state in
1043 the cpu-state to be able to re-execute the jmp. */
1044 if (dc
->delayed_branch
== 1) {
1045 cris_store_direct_jmp(dc
);
1049 /* Conditional writes. We only support the kind were X and P are known
1050 at translation time. */
1051 if (dc
->flags_x
&& (dc
->tb_flags
& P_FLAG
)) {
1053 cris_evaluate_flags(dc
);
1054 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], C_FLAG
);
1058 tcg_gen_qemu_st_tl(val
, addr
, mem_index
, MO_TE
+ ctz32(size
));
1061 cris_evaluate_flags(dc
);
1062 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~C_FLAG
);
1066 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
1069 tcg_gen_ext8s_i32(d
, s
);
1070 } else if (size
== 2) {
1071 tcg_gen_ext16s_i32(d
, s
);
1073 tcg_gen_mov_tl(d
, s
);
1077 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
1080 tcg_gen_ext8u_i32(d
, s
);
1081 } else if (size
== 2) {
1082 tcg_gen_ext16u_i32(d
, s
);
1084 tcg_gen_mov_tl(d
, s
);
1089 static char memsize_char(int size
)
1101 static inline unsigned int memsize_z(DisasContext
*dc
)
1103 return dc
->zsize
+ 1;
1106 static inline unsigned int memsize_zz(DisasContext
*dc
)
1108 switch (dc
->zzsize
) {
1116 static inline void do_postinc (DisasContext
*dc
, int size
)
1119 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], size
);
1123 static inline void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
1124 int size
, int s_ext
, TCGv dst
)
1127 t_gen_sext(dst
, cpu_R
[rs
], size
);
1129 t_gen_zext(dst
, cpu_R
[rs
], size
);
1133 /* Prepare T0 and T1 for a register alu operation.
1134 s_ext decides if the operand1 should be sign-extended or zero-extended when
1136 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
1137 int size
, int s_ext
, TCGv dst
, TCGv src
)
1139 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
, src
);
1142 t_gen_sext(dst
, cpu_R
[rd
], size
);
1144 t_gen_zext(dst
, cpu_R
[rd
], size
);
1148 static int dec_prep_move_m(CPUCRISState
*env
, DisasContext
*dc
,
1149 int s_ext
, int memsize
, TCGv dst
)
1157 is_imm
= rs
== 15 && dc
->postinc
;
1159 /* Load [$rs] onto T1. */
1161 insn_len
= 2 + memsize
;
1166 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, memsize
, s_ext
);
1167 tcg_gen_movi_tl(dst
, imm
);
1170 cris_flush_cc_state(dc
);
1171 gen_load(dc
, dst
, cpu_R
[rs
], memsize
, 0);
1173 t_gen_sext(dst
, dst
, memsize
);
1175 t_gen_zext(dst
, dst
, memsize
);
1181 /* Prepare T0 and T1 for a memory + alu operation.
1182 s_ext decides if the operand1 should be sign-extended or zero-extended when
1184 static int dec_prep_alu_m(CPUCRISState
*env
, DisasContext
*dc
,
1185 int s_ext
, int memsize
, TCGv dst
, TCGv src
)
1189 insn_len
= dec_prep_move_m(env
, dc
, s_ext
, memsize
, src
);
1190 tcg_gen_mov_tl(dst
, cpu_R
[dc
->op2
]);
1195 static const char *cc_name(int cc
)
1197 static const char * const cc_names
[16] = {
1198 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1199 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1202 return cc_names
[cc
];
1206 /* Start of insn decoders. */
1208 static int dec_bccq(CPUCRISState
*env
, DisasContext
*dc
)
1212 uint32_t cond
= dc
->op2
;
1214 offset
= EXTRACT_FIELD(dc
->ir
, 1, 7);
1215 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1218 offset
|= sign
<< 8;
1219 offset
= sign_extend(offset
, 8);
1221 LOG_DIS("b%s %x\n", cc_name(cond
), dc
->pc
+ offset
);
1223 /* op2 holds the condition-code. */
1224 cris_cc_mask(dc
, 0);
1225 cris_prepare_cc_branch(dc
, offset
, cond
);
1228 static int dec_addoq(CPUCRISState
*env
, DisasContext
*dc
)
1232 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1233 imm
= sign_extend(dc
->op1
, 7);
1235 LOG_DIS("addoq %d, $r%u\n", imm
, dc
->op2
);
1236 cris_cc_mask(dc
, 0);
1237 /* Fetch register operand, */
1238 tcg_gen_addi_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op2
], imm
);
1242 static int dec_addq(CPUCRISState
*env
, DisasContext
*dc
)
1245 LOG_DIS("addq %u, $r%u\n", dc
->op1
, dc
->op2
);
1247 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1249 cris_cc_mask(dc
, CC_MASK_NZVC
);
1251 c
= tcg_constant_tl(dc
->op1
);
1252 cris_alu(dc
, CC_OP_ADD
,
1253 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1256 static int dec_moveq(CPUCRISState
*env
, DisasContext
*dc
)
1260 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1261 imm
= sign_extend(dc
->op1
, 5);
1262 LOG_DIS("moveq %d, $r%u\n", imm
, dc
->op2
);
1264 tcg_gen_movi_tl(cpu_R
[dc
->op2
], imm
);
1267 static int dec_subq(CPUCRISState
*env
, DisasContext
*dc
)
1270 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1272 LOG_DIS("subq %u, $r%u\n", dc
->op1
, dc
->op2
);
1274 cris_cc_mask(dc
, CC_MASK_NZVC
);
1275 c
= tcg_constant_tl(dc
->op1
);
1276 cris_alu(dc
, CC_OP_SUB
,
1277 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1280 static int dec_cmpq(CPUCRISState
*env
, DisasContext
*dc
)
1284 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1285 imm
= sign_extend(dc
->op1
, 5);
1287 LOG_DIS("cmpq %d, $r%d\n", imm
, dc
->op2
);
1288 cris_cc_mask(dc
, CC_MASK_NZVC
);
1290 c
= tcg_constant_tl(imm
);
1291 cris_alu(dc
, CC_OP_CMP
,
1292 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1295 static int dec_andq(CPUCRISState
*env
, DisasContext
*dc
)
1299 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1300 imm
= sign_extend(dc
->op1
, 5);
1302 LOG_DIS("andq %d, $r%d\n", imm
, dc
->op2
);
1303 cris_cc_mask(dc
, CC_MASK_NZ
);
1305 c
= tcg_constant_tl(imm
);
1306 cris_alu(dc
, CC_OP_AND
,
1307 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1310 static int dec_orq(CPUCRISState
*env
, DisasContext
*dc
)
1314 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1315 imm
= sign_extend(dc
->op1
, 5);
1316 LOG_DIS("orq %d, $r%d\n", imm
, dc
->op2
);
1317 cris_cc_mask(dc
, CC_MASK_NZ
);
1319 c
= tcg_constant_tl(imm
);
1320 cris_alu(dc
, CC_OP_OR
,
1321 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1324 static int dec_btstq(CPUCRISState
*env
, DisasContext
*dc
)
1327 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1328 LOG_DIS("btstq %u, $r%d\n", dc
->op1
, dc
->op2
);
1330 cris_cc_mask(dc
, CC_MASK_NZ
);
1331 c
= tcg_constant_tl(dc
->op1
);
1332 cris_evaluate_flags(dc
);
1333 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1335 cris_alu(dc
, CC_OP_MOVE
,
1336 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1337 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1338 dc
->flags_uptodate
= 1;
1341 static int dec_asrq(CPUCRISState
*env
, DisasContext
*dc
)
1343 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1344 LOG_DIS("asrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1345 cris_cc_mask(dc
, CC_MASK_NZ
);
1347 tcg_gen_sari_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1348 cris_alu(dc
, CC_OP_MOVE
,
1350 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1353 static int dec_lslq(CPUCRISState
*env
, DisasContext
*dc
)
1355 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1356 LOG_DIS("lslq %u, $r%d\n", dc
->op1
, dc
->op2
);
1358 cris_cc_mask(dc
, CC_MASK_NZ
);
1360 tcg_gen_shli_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1362 cris_alu(dc
, CC_OP_MOVE
,
1364 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1367 static int dec_lsrq(CPUCRISState
*env
, DisasContext
*dc
)
1369 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1370 LOG_DIS("lsrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1372 cris_cc_mask(dc
, CC_MASK_NZ
);
1374 tcg_gen_shri_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1375 cris_alu(dc
, CC_OP_MOVE
,
1377 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1381 static int dec_move_r(CPUCRISState
*env
, DisasContext
*dc
)
1383 int size
= memsize_zz(dc
);
1385 LOG_DIS("move.%c $r%u, $r%u\n",
1386 memsize_char(size
), dc
->op1
, dc
->op2
);
1388 cris_cc_mask(dc
, CC_MASK_NZ
);
1390 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, cpu_R
[dc
->op2
]);
1391 cris_cc_mask(dc
, CC_MASK_NZ
);
1392 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
1393 cris_update_cc_x(dc
);
1394 cris_update_result(dc
, cpu_R
[dc
->op2
]);
1398 t0
= tcg_temp_new();
1399 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1400 cris_alu(dc
, CC_OP_MOVE
,
1402 cpu_R
[dc
->op2
], t0
, size
);
1407 static int dec_scc_r(CPUCRISState
*env
, DisasContext
*dc
)
1411 LOG_DIS("s%s $r%u\n",
1412 cc_name(cond
), dc
->op1
);
1414 gen_tst_cc(dc
, cpu_R
[dc
->op1
], cond
);
1415 tcg_gen_setcondi_tl(TCG_COND_NE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], 0);
1417 cris_cc_mask(dc
, 0);
1421 static inline void cris_alu_alloc_temps(DisasContext
*dc
, int size
, TCGv
*t
)
1424 t
[0] = cpu_R
[dc
->op2
];
1425 t
[1] = cpu_R
[dc
->op1
];
1427 t
[0] = tcg_temp_new();
1428 t
[1] = tcg_temp_new();
1432 static int dec_and_r(CPUCRISState
*env
, DisasContext
*dc
)
1435 int size
= memsize_zz(dc
);
1437 LOG_DIS("and.%c $r%u, $r%u\n",
1438 memsize_char(size
), dc
->op1
, dc
->op2
);
1440 cris_cc_mask(dc
, CC_MASK_NZ
);
1442 cris_alu_alloc_temps(dc
, size
, t
);
1443 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1444 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1448 static int dec_lz_r(CPUCRISState
*env
, DisasContext
*dc
)
1451 LOG_DIS("lz $r%u, $r%u\n",
1453 cris_cc_mask(dc
, CC_MASK_NZ
);
1454 t0
= tcg_temp_new();
1455 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0, cpu_R
[dc
->op2
], t0
);
1456 cris_alu(dc
, CC_OP_LZ
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1460 static int dec_lsl_r(CPUCRISState
*env
, DisasContext
*dc
)
1463 int size
= memsize_zz(dc
);
1465 LOG_DIS("lsl.%c $r%u, $r%u\n",
1466 memsize_char(size
), dc
->op1
, dc
->op2
);
1468 cris_cc_mask(dc
, CC_MASK_NZ
);
1469 cris_alu_alloc_temps(dc
, size
, t
);
1470 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1471 tcg_gen_andi_tl(t
[1], t
[1], 63);
1472 cris_alu(dc
, CC_OP_LSL
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1476 static int dec_lsr_r(CPUCRISState
*env
, DisasContext
*dc
)
1479 int size
= memsize_zz(dc
);
1481 LOG_DIS("lsr.%c $r%u, $r%u\n",
1482 memsize_char(size
), dc
->op1
, dc
->op2
);
1484 cris_cc_mask(dc
, CC_MASK_NZ
);
1485 cris_alu_alloc_temps(dc
, size
, t
);
1486 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1487 tcg_gen_andi_tl(t
[1], t
[1], 63);
1488 cris_alu(dc
, CC_OP_LSR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1492 static int dec_asr_r(CPUCRISState
*env
, DisasContext
*dc
)
1495 int size
= memsize_zz(dc
);
1497 LOG_DIS("asr.%c $r%u, $r%u\n",
1498 memsize_char(size
), dc
->op1
, dc
->op2
);
1500 cris_cc_mask(dc
, CC_MASK_NZ
);
1501 cris_alu_alloc_temps(dc
, size
, t
);
1502 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1, t
[0], t
[1]);
1503 tcg_gen_andi_tl(t
[1], t
[1], 63);
1504 cris_alu(dc
, CC_OP_ASR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1508 static int dec_muls_r(CPUCRISState
*env
, DisasContext
*dc
)
1511 int size
= memsize_zz(dc
);
1513 LOG_DIS("muls.%c $r%u, $r%u\n",
1514 memsize_char(size
), dc
->op1
, dc
->op2
);
1515 cris_cc_mask(dc
, CC_MASK_NZV
);
1516 cris_alu_alloc_temps(dc
, size
, t
);
1517 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1, t
[0], t
[1]);
1519 cris_alu(dc
, CC_OP_MULS
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1523 static int dec_mulu_r(CPUCRISState
*env
, DisasContext
*dc
)
1526 int size
= memsize_zz(dc
);
1528 LOG_DIS("mulu.%c $r%u, $r%u\n",
1529 memsize_char(size
), dc
->op1
, dc
->op2
);
1530 cris_cc_mask(dc
, CC_MASK_NZV
);
1531 cris_alu_alloc_temps(dc
, size
, t
);
1532 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1534 cris_alu(dc
, CC_OP_MULU
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1539 static int dec_dstep_r(CPUCRISState
*env
, DisasContext
*dc
)
1541 LOG_DIS("dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
);
1542 cris_cc_mask(dc
, CC_MASK_NZ
);
1543 cris_alu(dc
, CC_OP_DSTEP
,
1544 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1548 static int dec_xor_r(CPUCRISState
*env
, DisasContext
*dc
)
1551 int size
= memsize_zz(dc
);
1552 LOG_DIS("xor.%c $r%u, $r%u\n",
1553 memsize_char(size
), dc
->op1
, dc
->op2
);
1554 BUG_ON(size
!= 4); /* xor is dword. */
1555 cris_cc_mask(dc
, CC_MASK_NZ
);
1556 cris_alu_alloc_temps(dc
, size
, t
);
1557 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1559 cris_alu(dc
, CC_OP_XOR
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1563 static int dec_bound_r(CPUCRISState
*env
, DisasContext
*dc
)
1566 int size
= memsize_zz(dc
);
1567 LOG_DIS("bound.%c $r%u, $r%u\n",
1568 memsize_char(size
), dc
->op1
, dc
->op2
);
1569 cris_cc_mask(dc
, CC_MASK_NZ
);
1570 l0
= tcg_temp_new();
1571 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, l0
);
1572 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], l0
, 4);
1576 static int dec_cmp_r(CPUCRISState
*env
, DisasContext
*dc
)
1579 int size
= memsize_zz(dc
);
1580 LOG_DIS("cmp.%c $r%u, $r%u\n",
1581 memsize_char(size
), dc
->op1
, dc
->op2
);
1582 cris_cc_mask(dc
, CC_MASK_NZVC
);
1583 cris_alu_alloc_temps(dc
, size
, t
);
1584 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1586 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1590 static int dec_abs_r(CPUCRISState
*env
, DisasContext
*dc
)
1592 LOG_DIS("abs $r%u, $r%u\n",
1594 cris_cc_mask(dc
, CC_MASK_NZ
);
1596 tcg_gen_abs_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op1
]);
1597 cris_alu(dc
, CC_OP_MOVE
,
1598 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1602 static int dec_add_r(CPUCRISState
*env
, DisasContext
*dc
)
1605 int size
= memsize_zz(dc
);
1606 LOG_DIS("add.%c $r%u, $r%u\n",
1607 memsize_char(size
), dc
->op1
, dc
->op2
);
1608 cris_cc_mask(dc
, CC_MASK_NZVC
);
1609 cris_alu_alloc_temps(dc
, size
, t
);
1610 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1612 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1616 static int dec_addc_r(CPUCRISState
*env
, DisasContext
*dc
)
1618 LOG_DIS("addc $r%u, $r%u\n",
1620 cris_evaluate_flags(dc
);
1622 /* Set for this insn. */
1623 dc
->flags_x
= X_FLAG
;
1625 cris_cc_mask(dc
, CC_MASK_NZVC
);
1626 cris_alu(dc
, CC_OP_ADDC
,
1627 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1631 static int dec_mcp_r(CPUCRISState
*env
, DisasContext
*dc
)
1633 LOG_DIS("mcp $p%u, $r%u\n",
1635 cris_evaluate_flags(dc
);
1636 cris_cc_mask(dc
, CC_MASK_RNZV
);
1637 cris_alu(dc
, CC_OP_MCP
,
1638 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], cpu_PR
[dc
->op2
], 4);
1643 static char * swapmode_name(int mode
, char *modename
) {
1646 modename
[i
++] = 'n';
1649 modename
[i
++] = 'w';
1652 modename
[i
++] = 'b';
1655 modename
[i
++] = 'r';
1662 static int dec_swap_r(CPUCRISState
*env
, DisasContext
*dc
)
1668 LOG_DIS("swap%s $r%u\n",
1669 swapmode_name(dc
->op2
, modename
), dc
->op1
);
1671 cris_cc_mask(dc
, CC_MASK_NZ
);
1672 t0
= tcg_temp_new();
1673 tcg_gen_mov_tl(t0
, cpu_R
[dc
->op1
]);
1675 tcg_gen_not_tl(t0
, t0
);
1678 t_gen_swapw(t0
, t0
);
1681 t_gen_swapb(t0
, t0
);
1684 t_gen_swapr(t0
, t0
);
1686 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
, 4);
1690 static int dec_or_r(CPUCRISState
*env
, DisasContext
*dc
)
1693 int size
= memsize_zz(dc
);
1694 LOG_DIS("or.%c $r%u, $r%u\n",
1695 memsize_char(size
), dc
->op1
, dc
->op2
);
1696 cris_cc_mask(dc
, CC_MASK_NZ
);
1697 cris_alu_alloc_temps(dc
, size
, t
);
1698 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1699 cris_alu(dc
, CC_OP_OR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1703 static int dec_addi_r(CPUCRISState
*env
, DisasContext
*dc
)
1706 LOG_DIS("addi.%c $r%u, $r%u\n",
1707 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1708 cris_cc_mask(dc
, 0);
1709 t0
= tcg_temp_new();
1710 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1711 tcg_gen_add_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
);
1715 static int dec_addi_acr(CPUCRISState
*env
, DisasContext
*dc
)
1718 LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1719 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1720 cris_cc_mask(dc
, 0);
1721 t0
= tcg_temp_new();
1722 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1723 tcg_gen_add_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op1
], t0
);
1727 static int dec_neg_r(CPUCRISState
*env
, DisasContext
*dc
)
1730 int size
= memsize_zz(dc
);
1731 LOG_DIS("neg.%c $r%u, $r%u\n",
1732 memsize_char(size
), dc
->op1
, dc
->op2
);
1733 cris_cc_mask(dc
, CC_MASK_NZVC
);
1734 cris_alu_alloc_temps(dc
, size
, t
);
1735 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1737 cris_alu(dc
, CC_OP_NEG
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1741 static int dec_btst_r(CPUCRISState
*env
, DisasContext
*dc
)
1743 LOG_DIS("btst $r%u, $r%u\n",
1745 cris_cc_mask(dc
, CC_MASK_NZ
);
1746 cris_evaluate_flags(dc
);
1747 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1748 cpu_R
[dc
->op1
], cpu_PR
[PR_CCS
]);
1749 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
],
1750 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1751 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1752 dc
->flags_uptodate
= 1;
1756 static int dec_sub_r(CPUCRISState
*env
, DisasContext
*dc
)
1759 int size
= memsize_zz(dc
);
1760 LOG_DIS("sub.%c $r%u, $r%u\n",
1761 memsize_char(size
), dc
->op1
, dc
->op2
);
1762 cris_cc_mask(dc
, CC_MASK_NZVC
);
1763 cris_alu_alloc_temps(dc
, size
, t
);
1764 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1765 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1769 /* Zero extension. From size to dword. */
1770 static int dec_movu_r(CPUCRISState
*env
, DisasContext
*dc
)
1773 int size
= memsize_z(dc
);
1774 LOG_DIS("movu.%c $r%u, $r%u\n",
1778 cris_cc_mask(dc
, CC_MASK_NZ
);
1779 t0
= tcg_temp_new();
1780 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1781 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1785 /* Sign extension. From size to dword. */
1786 static int dec_movs_r(CPUCRISState
*env
, DisasContext
*dc
)
1789 int size
= memsize_z(dc
);
1790 LOG_DIS("movs.%c $r%u, $r%u\n",
1794 cris_cc_mask(dc
, CC_MASK_NZ
);
1795 t0
= tcg_temp_new();
1796 /* Size can only be qi or hi. */
1797 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1798 cris_alu(dc
, CC_OP_MOVE
,
1799 cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], t0
, 4);
1803 /* zero extension. From size to dword. */
1804 static int dec_addu_r(CPUCRISState
*env
, DisasContext
*dc
)
1807 int size
= memsize_z(dc
);
1808 LOG_DIS("addu.%c $r%u, $r%u\n",
1812 cris_cc_mask(dc
, CC_MASK_NZVC
);
1813 t0
= tcg_temp_new();
1814 /* Size can only be qi or hi. */
1815 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1816 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1820 /* Sign extension. From size to dword. */
1821 static int dec_adds_r(CPUCRISState
*env
, DisasContext
*dc
)
1824 int size
= memsize_z(dc
);
1825 LOG_DIS("adds.%c $r%u, $r%u\n",
1829 cris_cc_mask(dc
, CC_MASK_NZVC
);
1830 t0
= tcg_temp_new();
1831 /* Size can only be qi or hi. */
1832 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1833 cris_alu(dc
, CC_OP_ADD
,
1834 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1838 /* Zero extension. From size to dword. */
1839 static int dec_subu_r(CPUCRISState
*env
, DisasContext
*dc
)
1842 int size
= memsize_z(dc
);
1843 LOG_DIS("subu.%c $r%u, $r%u\n",
1847 cris_cc_mask(dc
, CC_MASK_NZVC
);
1848 t0
= tcg_temp_new();
1849 /* Size can only be qi or hi. */
1850 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1851 cris_alu(dc
, CC_OP_SUB
,
1852 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1856 /* Sign extension. From size to dword. */
1857 static int dec_subs_r(CPUCRISState
*env
, DisasContext
*dc
)
1860 int size
= memsize_z(dc
);
1861 LOG_DIS("subs.%c $r%u, $r%u\n",
1865 cris_cc_mask(dc
, CC_MASK_NZVC
);
1866 t0
= tcg_temp_new();
1867 /* Size can only be qi or hi. */
1868 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1869 cris_alu(dc
, CC_OP_SUB
,
1870 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1874 static int dec_setclrf(CPUCRISState
*env
, DisasContext
*dc
)
1877 int set
= (~dc
->opcode
>> 2) & 1;
1880 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1881 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1882 if (set
&& flags
== 0) {
1885 } else if (!set
&& (flags
& 0x20)) {
1888 LOG_DIS("%sf %x\n", set
? "set" : "clr", flags
);
1891 /* User space is not allowed to touch these. Silently ignore. */
1892 if (dc
->tb_flags
& U_FLAG
) {
1893 flags
&= ~(S_FLAG
| I_FLAG
| U_FLAG
);
1896 if (flags
& X_FLAG
) {
1898 dc
->flags_x
= X_FLAG
;
1904 /* Break the TB if any of the SPI flag changes. */
1905 if (flags
& (P_FLAG
| S_FLAG
)) {
1906 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1907 dc
->base
.is_jmp
= DISAS_UPDATE
;
1908 dc
->cpustate_changed
= 1;
1911 /* For the I flag, only act on posedge. */
1912 if ((flags
& I_FLAG
)) {
1913 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1914 dc
->base
.is_jmp
= DISAS_UPDATE
;
1915 dc
->cpustate_changed
= 1;
1919 /* Simply decode the flags. */
1920 cris_evaluate_flags(dc
);
1921 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1922 cris_update_cc_x(dc
);
1923 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
1926 if (!(dc
->tb_flags
& U_FLAG
) && (flags
& U_FLAG
)) {
1927 /* Enter user mode. */
1928 t_gen_mov_env_TN(ksp
, cpu_R
[R_SP
]);
1929 tcg_gen_mov_tl(cpu_R
[R_SP
], cpu_PR
[PR_USP
]);
1930 dc
->cpustate_changed
= 1;
1932 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], flags
);
1934 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~flags
);
1937 dc
->flags_uptodate
= 1;
1942 static int dec_move_rs(CPUCRISState
*env
, DisasContext
*dc
)
1945 LOG_DIS("move $r%u, $s%u\n", dc
->op1
, dc
->op2
);
1946 c1
= tcg_constant_tl(dc
->op1
);
1947 c2
= tcg_constant_tl(dc
->op2
);
1948 cris_cc_mask(dc
, 0);
1949 gen_helper_movl_sreg_reg(tcg_env
, c2
, c1
);
1952 static int dec_move_sr(CPUCRISState
*env
, DisasContext
*dc
)
1955 LOG_DIS("move $s%u, $r%u\n", dc
->op2
, dc
->op1
);
1956 c1
= tcg_constant_tl(dc
->op1
);
1957 c2
= tcg_constant_tl(dc
->op2
);
1958 cris_cc_mask(dc
, 0);
1959 gen_helper_movl_reg_sreg(tcg_env
, c1
, c2
);
1963 static int dec_move_rp(CPUCRISState
*env
, DisasContext
*dc
)
1966 LOG_DIS("move $r%u, $p%u\n", dc
->op1
, dc
->op2
);
1967 cris_cc_mask(dc
, 0);
1969 t
[0] = tcg_temp_new();
1970 if (dc
->op2
== PR_CCS
) {
1971 cris_evaluate_flags(dc
);
1972 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1973 if (dc
->tb_flags
& U_FLAG
) {
1974 t
[1] = tcg_temp_new();
1975 /* User space is not allowed to touch all flags. */
1976 tcg_gen_andi_tl(t
[0], t
[0], 0x39f);
1977 tcg_gen_andi_tl(t
[1], cpu_PR
[PR_CCS
], ~0x39f);
1978 tcg_gen_or_tl(t
[0], t
[1], t
[0]);
1981 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1984 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[0]);
1985 if (dc
->op2
== PR_CCS
) {
1986 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1987 dc
->flags_uptodate
= 1;
1991 static int dec_move_pr(CPUCRISState
*env
, DisasContext
*dc
)
1994 LOG_DIS("move $p%u, $r%u\n", dc
->op2
, dc
->op1
);
1995 cris_cc_mask(dc
, 0);
1997 if (dc
->op2
== PR_CCS
) {
1998 cris_evaluate_flags(dc
);
2001 if (dc
->op2
== PR_DZ
) {
2002 tcg_gen_movi_tl(cpu_R
[dc
->op1
], 0);
2004 t0
= tcg_temp_new();
2005 t_gen_mov_TN_preg(t0
, dc
->op2
);
2006 cris_alu(dc
, CC_OP_MOVE
,
2007 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
,
2008 preg_sizes
[dc
->op2
]);
2013 static int dec_move_mr(CPUCRISState
*env
, DisasContext
*dc
)
2015 int memsize
= memsize_zz(dc
);
2017 LOG_DIS("move.%c [$r%u%s, $r%u\n",
2018 memsize_char(memsize
),
2019 dc
->op1
, dc
->postinc
? "+]" : "]",
2023 insn_len
= dec_prep_move_m(env
, dc
, 0, 4, cpu_R
[dc
->op2
]);
2024 cris_cc_mask(dc
, CC_MASK_NZ
);
2025 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
2026 cris_update_cc_x(dc
);
2027 cris_update_result(dc
, cpu_R
[dc
->op2
]);
2031 t0
= tcg_temp_new();
2032 insn_len
= dec_prep_move_m(env
, dc
, 0, memsize
, t0
);
2033 cris_cc_mask(dc
, CC_MASK_NZ
);
2034 cris_alu(dc
, CC_OP_MOVE
,
2035 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, memsize
);
2037 do_postinc(dc
, memsize
);
2041 static inline void cris_alu_m_alloc_temps(TCGv
*t
)
2043 t
[0] = tcg_temp_new();
2044 t
[1] = tcg_temp_new();
2047 static int dec_movs_m(CPUCRISState
*env
, DisasContext
*dc
)
2050 int memsize
= memsize_z(dc
);
2052 LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2053 memsize_char(memsize
),
2054 dc
->op1
, dc
->postinc
? "+]" : "]",
2057 cris_alu_m_alloc_temps(t
);
2059 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2060 cris_cc_mask(dc
, CC_MASK_NZ
);
2061 cris_alu(dc
, CC_OP_MOVE
,
2062 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2063 do_postinc(dc
, memsize
);
2067 static int dec_addu_m(CPUCRISState
*env
, DisasContext
*dc
)
2070 int memsize
= memsize_z(dc
);
2072 LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2073 memsize_char(memsize
),
2074 dc
->op1
, dc
->postinc
? "+]" : "]",
2077 cris_alu_m_alloc_temps(t
);
2079 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2080 cris_cc_mask(dc
, CC_MASK_NZVC
);
2081 cris_alu(dc
, CC_OP_ADD
,
2082 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2083 do_postinc(dc
, memsize
);
2087 static int dec_adds_m(CPUCRISState
*env
, DisasContext
*dc
)
2090 int memsize
= memsize_z(dc
);
2092 LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2093 memsize_char(memsize
),
2094 dc
->op1
, dc
->postinc
? "+]" : "]",
2097 cris_alu_m_alloc_temps(t
);
2099 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2100 cris_cc_mask(dc
, CC_MASK_NZVC
);
2101 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2102 do_postinc(dc
, memsize
);
2106 static int dec_subu_m(CPUCRISState
*env
, DisasContext
*dc
)
2109 int memsize
= memsize_z(dc
);
2111 LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2112 memsize_char(memsize
),
2113 dc
->op1
, dc
->postinc
? "+]" : "]",
2116 cris_alu_m_alloc_temps(t
);
2118 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2119 cris_cc_mask(dc
, CC_MASK_NZVC
);
2120 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2121 do_postinc(dc
, memsize
);
2125 static int dec_subs_m(CPUCRISState
*env
, DisasContext
*dc
)
2128 int memsize
= memsize_z(dc
);
2130 LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2131 memsize_char(memsize
),
2132 dc
->op1
, dc
->postinc
? "+]" : "]",
2135 cris_alu_m_alloc_temps(t
);
2137 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2138 cris_cc_mask(dc
, CC_MASK_NZVC
);
2139 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2140 do_postinc(dc
, memsize
);
2144 static int dec_movu_m(CPUCRISState
*env
, DisasContext
*dc
)
2147 int memsize
= memsize_z(dc
);
2150 LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2151 memsize_char(memsize
),
2152 dc
->op1
, dc
->postinc
? "+]" : "]",
2155 cris_alu_m_alloc_temps(t
);
2156 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2157 cris_cc_mask(dc
, CC_MASK_NZ
);
2158 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2159 do_postinc(dc
, memsize
);
2163 static int dec_cmpu_m(CPUCRISState
*env
, DisasContext
*dc
)
2166 int memsize
= memsize_z(dc
);
2168 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2169 memsize_char(memsize
),
2170 dc
->op1
, dc
->postinc
? "+]" : "]",
2173 cris_alu_m_alloc_temps(t
);
2174 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2175 cris_cc_mask(dc
, CC_MASK_NZVC
);
2176 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2177 do_postinc(dc
, memsize
);
2181 static int dec_cmps_m(CPUCRISState
*env
, DisasContext
*dc
)
2184 int memsize
= memsize_z(dc
);
2186 LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2187 memsize_char(memsize
),
2188 dc
->op1
, dc
->postinc
? "+]" : "]",
2191 cris_alu_m_alloc_temps(t
);
2192 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2193 cris_cc_mask(dc
, CC_MASK_NZVC
);
2194 cris_alu(dc
, CC_OP_CMP
,
2195 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2197 do_postinc(dc
, memsize
);
2201 static int dec_cmp_m(CPUCRISState
*env
, DisasContext
*dc
)
2204 int memsize
= memsize_zz(dc
);
2206 LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2207 memsize_char(memsize
),
2208 dc
->op1
, dc
->postinc
? "+]" : "]",
2211 cris_alu_m_alloc_temps(t
);
2212 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2213 cris_cc_mask(dc
, CC_MASK_NZVC
);
2214 cris_alu(dc
, CC_OP_CMP
,
2215 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2217 do_postinc(dc
, memsize
);
2221 static int dec_test_m(CPUCRISState
*env
, DisasContext
*dc
)
2224 int memsize
= memsize_zz(dc
);
2226 LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2227 memsize_char(memsize
),
2228 dc
->op1
, dc
->postinc
? "+]" : "]",
2231 cris_evaluate_flags(dc
);
2233 cris_alu_m_alloc_temps(t
);
2234 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2235 cris_cc_mask(dc
, CC_MASK_NZ
);
2236 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~3);
2238 c
= tcg_constant_tl(0);
2239 cris_alu(dc
, CC_OP_CMP
,
2240 cpu_R
[dc
->op2
], t
[1], c
, memsize_zz(dc
));
2241 do_postinc(dc
, memsize
);
2245 static int dec_and_m(CPUCRISState
*env
, DisasContext
*dc
)
2248 int memsize
= memsize_zz(dc
);
2250 LOG_DIS("and.%c [$r%u%s, $r%u\n",
2251 memsize_char(memsize
),
2252 dc
->op1
, dc
->postinc
? "+]" : "]",
2255 cris_alu_m_alloc_temps(t
);
2256 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2257 cris_cc_mask(dc
, CC_MASK_NZ
);
2258 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2259 do_postinc(dc
, memsize
);
2263 static int dec_add_m(CPUCRISState
*env
, DisasContext
*dc
)
2266 int memsize
= memsize_zz(dc
);
2268 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2269 memsize_char(memsize
),
2270 dc
->op1
, dc
->postinc
? "+]" : "]",
2273 cris_alu_m_alloc_temps(t
);
2274 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2275 cris_cc_mask(dc
, CC_MASK_NZVC
);
2276 cris_alu(dc
, CC_OP_ADD
,
2277 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2278 do_postinc(dc
, memsize
);
2282 static int dec_addo_m(CPUCRISState
*env
, DisasContext
*dc
)
2285 int memsize
= memsize_zz(dc
);
2287 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2288 memsize_char(memsize
),
2289 dc
->op1
, dc
->postinc
? "+]" : "]",
2292 cris_alu_m_alloc_temps(t
);
2293 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2294 cris_cc_mask(dc
, 0);
2295 cris_alu(dc
, CC_OP_ADD
, cpu_R
[R_ACR
], t
[0], t
[1], 4);
2296 do_postinc(dc
, memsize
);
2300 static int dec_bound_m(CPUCRISState
*env
, DisasContext
*dc
)
2303 int memsize
= memsize_zz(dc
);
2305 LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2306 memsize_char(memsize
),
2307 dc
->op1
, dc
->postinc
? "+]" : "]",
2310 l
[0] = tcg_temp_new();
2311 l
[1] = tcg_temp_new();
2312 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, l
[0], l
[1]);
2313 cris_cc_mask(dc
, CC_MASK_NZ
);
2314 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], l
[0], l
[1], 4);
2315 do_postinc(dc
, memsize
);
2319 static int dec_addc_mr(CPUCRISState
*env
, DisasContext
*dc
)
2323 LOG_DIS("addc [$r%u%s, $r%u\n",
2324 dc
->op1
, dc
->postinc
? "+]" : "]",
2327 cris_evaluate_flags(dc
);
2329 /* Set for this insn. */
2330 dc
->flags_x
= X_FLAG
;
2332 cris_alu_m_alloc_temps(t
);
2333 insn_len
= dec_prep_alu_m(env
, dc
, 0, 4, t
[0], t
[1]);
2334 cris_cc_mask(dc
, CC_MASK_NZVC
);
2335 cris_alu(dc
, CC_OP_ADDC
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
2340 static int dec_sub_m(CPUCRISState
*env
, DisasContext
*dc
)
2343 int memsize
= memsize_zz(dc
);
2345 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2346 memsize_char(memsize
),
2347 dc
->op1
, dc
->postinc
? "+]" : "]",
2348 dc
->op2
, dc
->ir
, dc
->zzsize
);
2350 cris_alu_m_alloc_temps(t
);
2351 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2352 cris_cc_mask(dc
, CC_MASK_NZVC
);
2353 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize
);
2354 do_postinc(dc
, memsize
);
2358 static int dec_or_m(CPUCRISState
*env
, DisasContext
*dc
)
2361 int memsize
= memsize_zz(dc
);
2363 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2364 memsize_char(memsize
),
2365 dc
->op1
, dc
->postinc
? "+]" : "]",
2368 cris_alu_m_alloc_temps(t
);
2369 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2370 cris_cc_mask(dc
, CC_MASK_NZ
);
2371 cris_alu(dc
, CC_OP_OR
,
2372 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2373 do_postinc(dc
, memsize
);
2377 static int dec_move_mp(CPUCRISState
*env
, DisasContext
*dc
)
2380 int memsize
= memsize_zz(dc
);
2383 LOG_DIS("move.%c [$r%u%s, $p%u\n",
2384 memsize_char(memsize
),
2386 dc
->postinc
? "+]" : "]",
2389 cris_alu_m_alloc_temps(t
);
2390 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2391 cris_cc_mask(dc
, 0);
2392 if (dc
->op2
== PR_CCS
) {
2393 cris_evaluate_flags(dc
);
2394 if (dc
->tb_flags
& U_FLAG
) {
2395 /* User space is not allowed to touch all flags. */
2396 tcg_gen_andi_tl(t
[1], t
[1], 0x39f);
2397 tcg_gen_andi_tl(t
[0], cpu_PR
[PR_CCS
], ~0x39f);
2398 tcg_gen_or_tl(t
[1], t
[0], t
[1]);
2402 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[1]);
2404 do_postinc(dc
, memsize
);
2408 static int dec_move_pm(CPUCRISState
*env
, DisasContext
*dc
)
2413 memsize
= preg_sizes
[dc
->op2
];
2415 LOG_DIS("move.%c $p%u, [$r%u%s\n",
2416 memsize_char(memsize
),
2417 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]");
2419 /* prepare store. Address in T0, value in T1. */
2420 if (dc
->op2
== PR_CCS
) {
2421 cris_evaluate_flags(dc
);
2423 t0
= tcg_temp_new();
2424 t_gen_mov_TN_preg(t0
, dc
->op2
);
2425 cris_flush_cc_state(dc
);
2426 gen_store(dc
, cpu_R
[dc
->op1
], t0
, memsize
);
2428 cris_cc_mask(dc
, 0);
2430 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2435 static int dec_movem_mr(CPUCRISState
*env
, DisasContext
*dc
)
2441 int nr
= dc
->op2
+ 1;
2443 LOG_DIS("movem [$r%u%s, $r%u\n", dc
->op1
,
2444 dc
->postinc
? "+]" : "]", dc
->op2
);
2446 addr
= tcg_temp_new();
2447 /* There are probably better ways of doing this. */
2448 cris_flush_cc_state(dc
);
2449 for (i
= 0; i
< (nr
>> 1); i
++) {
2450 tmp
[i
] = tcg_temp_new_i64();
2451 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2452 gen_load64(dc
, tmp
[i
], addr
);
2455 tmp32
= tcg_temp_new_i32();
2456 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2457 gen_load(dc
, tmp32
, addr
, 4, 0);
2462 for (i
= 0; i
< (nr
>> 1); i
++) {
2463 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2], tmp
[i
]);
2464 tcg_gen_shri_i64(tmp
[i
], tmp
[i
], 32);
2465 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2 + 1], tmp
[i
]);
2468 tcg_gen_mov_tl(cpu_R
[dc
->op2
], tmp32
);
2471 /* writeback the updated pointer value. */
2473 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], nr
* 4);
2476 /* gen_load might want to evaluate the previous insns flags. */
2477 cris_cc_mask(dc
, 0);
2481 static int dec_movem_rm(CPUCRISState
*env
, DisasContext
*dc
)
2487 LOG_DIS("movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2488 dc
->postinc
? "+]" : "]");
2490 cris_flush_cc_state(dc
);
2492 tmp
= tcg_temp_new();
2493 addr
= tcg_temp_new();
2494 tcg_gen_movi_tl(tmp
, 4);
2495 tcg_gen_mov_tl(addr
, cpu_R
[dc
->op1
]);
2496 for (i
= 0; i
<= dc
->op2
; i
++) {
2497 /* Displace addr. */
2498 /* Perform the store. */
2499 gen_store(dc
, addr
, cpu_R
[i
], 4);
2500 tcg_gen_add_tl(addr
, addr
, tmp
);
2503 tcg_gen_mov_tl(cpu_R
[dc
->op1
], addr
);
2505 cris_cc_mask(dc
, 0);
2509 static int dec_move_rm(CPUCRISState
*env
, DisasContext
*dc
)
2513 memsize
= memsize_zz(dc
);
2515 LOG_DIS("move.%c $r%u, [$r%u]\n",
2516 memsize_char(memsize
), dc
->op2
, dc
->op1
);
2518 /* prepare store. */
2519 cris_flush_cc_state(dc
);
2520 gen_store(dc
, cpu_R
[dc
->op1
], cpu_R
[dc
->op2
], memsize
);
2523 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2525 cris_cc_mask(dc
, 0);
2529 static int dec_lapcq(CPUCRISState
*env
, DisasContext
*dc
)
2531 LOG_DIS("lapcq %x, $r%u\n",
2532 dc
->pc
+ dc
->op1
*2, dc
->op2
);
2533 cris_cc_mask(dc
, 0);
2534 tcg_gen_movi_tl(cpu_R
[dc
->op2
], dc
->pc
+ dc
->op1
* 2);
2538 static int dec_lapc_im(CPUCRISState
*env
, DisasContext
*dc
)
2546 cris_cc_mask(dc
, 0);
2547 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2548 LOG_DIS("lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
);
2552 tcg_gen_movi_tl(cpu_R
[rd
], pc
);
2556 /* Jump to special reg. */
2557 static int dec_jump_p(CPUCRISState
*env
, DisasContext
*dc
)
2559 LOG_DIS("jump $p%u\n", dc
->op2
);
2561 if (dc
->op2
== PR_CCS
) {
2562 cris_evaluate_flags(dc
);
2564 t_gen_mov_TN_preg(env_btarget
, dc
->op2
);
2565 /* rete will often have low bit set to indicate delayslot. */
2566 tcg_gen_andi_tl(env_btarget
, env_btarget
, ~1);
2567 cris_cc_mask(dc
, 0);
2568 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2572 /* Jump and save. */
2573 static int dec_jas_r(CPUCRISState
*env
, DisasContext
*dc
)
2576 LOG_DIS("jas $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2577 cris_cc_mask(dc
, 0);
2578 /* Store the return address in Pd. */
2579 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2583 c
= tcg_constant_tl(dc
->pc
+ 4);
2584 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2586 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2590 static int dec_jas_im(CPUCRISState
*env
, DisasContext
*dc
)
2595 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2597 LOG_DIS("jas 0x%x\n", imm
);
2598 cris_cc_mask(dc
, 0);
2599 c
= tcg_constant_tl(dc
->pc
+ 8);
2600 /* Store the return address in Pd. */
2601 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2604 cris_prepare_jmp(dc
, JMP_DIRECT
);
2608 static int dec_jasc_im(CPUCRISState
*env
, DisasContext
*dc
)
2613 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2615 LOG_DIS("jasc 0x%x\n", imm
);
2616 cris_cc_mask(dc
, 0);
2617 c
= tcg_constant_tl(dc
->pc
+ 8 + 4);
2618 /* Store the return address in Pd. */
2619 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2622 cris_prepare_jmp(dc
, JMP_DIRECT
);
2626 static int dec_jasc_r(CPUCRISState
*env
, DisasContext
*dc
)
2629 LOG_DIS("jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2630 cris_cc_mask(dc
, 0);
2631 /* Store the return address in Pd. */
2632 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2633 c
= tcg_constant_tl(dc
->pc
+ 4 + 4);
2634 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2635 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2639 static int dec_bcc_im(CPUCRISState
*env
, DisasContext
*dc
)
2642 uint32_t cond
= dc
->op2
;
2644 offset
= cris_fetch(env
, dc
, dc
->pc
+ 2, 2, 1);
2646 LOG_DIS("b%s %d pc=%x dst=%x\n",
2647 cc_name(cond
), offset
,
2648 dc
->pc
, dc
->pc
+ offset
);
2650 cris_cc_mask(dc
, 0);
2651 /* op2 holds the condition-code. */
2652 cris_prepare_cc_branch(dc
, offset
, cond
);
2656 static int dec_bas_im(CPUCRISState
*env
, DisasContext
*dc
)
2661 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2663 LOG_DIS("bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2664 cris_cc_mask(dc
, 0);
2665 c
= tcg_constant_tl(dc
->pc
+ 8);
2666 /* Store the return address in Pd. */
2667 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2669 dc
->jmp_pc
= dc
->pc
+ simm
;
2670 cris_prepare_jmp(dc
, JMP_DIRECT
);
2674 static int dec_basc_im(CPUCRISState
*env
, DisasContext
*dc
)
2678 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2680 LOG_DIS("basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2681 cris_cc_mask(dc
, 0);
2682 c
= tcg_constant_tl(dc
->pc
+ 12);
2683 /* Store the return address in Pd. */
2684 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2686 dc
->jmp_pc
= dc
->pc
+ simm
;
2687 cris_prepare_jmp(dc
, JMP_DIRECT
);
2691 static int dec_rfe_etc(CPUCRISState
*env
, DisasContext
*dc
)
2693 cris_cc_mask(dc
, 0);
2695 if (dc
->op2
== 15) {
2696 tcg_gen_st_i32(tcg_constant_i32(1), tcg_env
,
2697 -offsetof(CRISCPU
, env
) + offsetof(CPUState
, halted
));
2698 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2699 t_gen_raise_exception(EXCP_HLT
);
2700 dc
->base
.is_jmp
= DISAS_NORETURN
;
2704 switch (dc
->op2
& 7) {
2708 cris_evaluate_flags(dc
);
2709 gen_helper_rfe(tcg_env
);
2710 dc
->base
.is_jmp
= DISAS_UPDATE
;
2711 dc
->cpustate_changed
= true;
2716 cris_evaluate_flags(dc
);
2717 gen_helper_rfn(tcg_env
);
2718 dc
->base
.is_jmp
= DISAS_UPDATE
;
2719 dc
->cpustate_changed
= true;
2722 LOG_DIS("break %d\n", dc
->op1
);
2723 cris_evaluate_flags(dc
);
2725 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2727 /* Breaks start at 16 in the exception vector. */
2728 t_gen_movi_env_TN(trap_vector
, dc
->op1
+ 16);
2729 t_gen_raise_exception(EXCP_BREAK
);
2730 dc
->base
.is_jmp
= DISAS_NORETURN
;
2733 printf("op2=%x\n", dc
->op2
);
2741 static int dec_ftag_fidx_d_m(CPUCRISState
*env
, DisasContext
*dc
)
2746 static int dec_ftag_fidx_i_m(CPUCRISState
*env
, DisasContext
*dc
)
2751 static int dec_null(CPUCRISState
*env
, DisasContext
*dc
)
2753 printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2754 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2760 static const struct decoder_info
{
2765 int (*dec
)(CPUCRISState
*env
, DisasContext
*dc
);
2767 /* Order matters here. */
2768 {DEC_MOVEQ
, dec_moveq
},
2769 {DEC_BTSTQ
, dec_btstq
},
2770 {DEC_CMPQ
, dec_cmpq
},
2771 {DEC_ADDOQ
, dec_addoq
},
2772 {DEC_ADDQ
, dec_addq
},
2773 {DEC_SUBQ
, dec_subq
},
2774 {DEC_ANDQ
, dec_andq
},
2776 {DEC_ASRQ
, dec_asrq
},
2777 {DEC_LSLQ
, dec_lslq
},
2778 {DEC_LSRQ
, dec_lsrq
},
2779 {DEC_BCCQ
, dec_bccq
},
2781 {DEC_BCC_IM
, dec_bcc_im
},
2782 {DEC_JAS_IM
, dec_jas_im
},
2783 {DEC_JAS_R
, dec_jas_r
},
2784 {DEC_JASC_IM
, dec_jasc_im
},
2785 {DEC_JASC_R
, dec_jasc_r
},
2786 {DEC_BAS_IM
, dec_bas_im
},
2787 {DEC_BASC_IM
, dec_basc_im
},
2788 {DEC_JUMP_P
, dec_jump_p
},
2789 {DEC_LAPC_IM
, dec_lapc_im
},
2790 {DEC_LAPCQ
, dec_lapcq
},
2792 {DEC_RFE_ETC
, dec_rfe_etc
},
2793 {DEC_ADDC_MR
, dec_addc_mr
},
2795 {DEC_MOVE_MP
, dec_move_mp
},
2796 {DEC_MOVE_PM
, dec_move_pm
},
2797 {DEC_MOVEM_MR
, dec_movem_mr
},
2798 {DEC_MOVEM_RM
, dec_movem_rm
},
2799 {DEC_MOVE_PR
, dec_move_pr
},
2800 {DEC_SCC_R
, dec_scc_r
},
2801 {DEC_SETF
, dec_setclrf
},
2802 {DEC_CLEARF
, dec_setclrf
},
2804 {DEC_MOVE_SR
, dec_move_sr
},
2805 {DEC_MOVE_RP
, dec_move_rp
},
2806 {DEC_SWAP_R
, dec_swap_r
},
2807 {DEC_ABS_R
, dec_abs_r
},
2808 {DEC_LZ_R
, dec_lz_r
},
2809 {DEC_MOVE_RS
, dec_move_rs
},
2810 {DEC_BTST_R
, dec_btst_r
},
2811 {DEC_ADDC_R
, dec_addc_r
},
2813 {DEC_DSTEP_R
, dec_dstep_r
},
2814 {DEC_XOR_R
, dec_xor_r
},
2815 {DEC_MCP_R
, dec_mcp_r
},
2816 {DEC_CMP_R
, dec_cmp_r
},
2818 {DEC_ADDI_R
, dec_addi_r
},
2819 {DEC_ADDI_ACR
, dec_addi_acr
},
2821 {DEC_ADD_R
, dec_add_r
},
2822 {DEC_SUB_R
, dec_sub_r
},
2824 {DEC_ADDU_R
, dec_addu_r
},
2825 {DEC_ADDS_R
, dec_adds_r
},
2826 {DEC_SUBU_R
, dec_subu_r
},
2827 {DEC_SUBS_R
, dec_subs_r
},
2828 {DEC_LSL_R
, dec_lsl_r
},
2830 {DEC_AND_R
, dec_and_r
},
2831 {DEC_OR_R
, dec_or_r
},
2832 {DEC_BOUND_R
, dec_bound_r
},
2833 {DEC_ASR_R
, dec_asr_r
},
2834 {DEC_LSR_R
, dec_lsr_r
},
2836 {DEC_MOVU_R
, dec_movu_r
},
2837 {DEC_MOVS_R
, dec_movs_r
},
2838 {DEC_NEG_R
, dec_neg_r
},
2839 {DEC_MOVE_R
, dec_move_r
},
2841 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2842 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2844 {DEC_MULS_R
, dec_muls_r
},
2845 {DEC_MULU_R
, dec_mulu_r
},
2847 {DEC_ADDU_M
, dec_addu_m
},
2848 {DEC_ADDS_M
, dec_adds_m
},
2849 {DEC_SUBU_M
, dec_subu_m
},
2850 {DEC_SUBS_M
, dec_subs_m
},
2852 {DEC_CMPU_M
, dec_cmpu_m
},
2853 {DEC_CMPS_M
, dec_cmps_m
},
2854 {DEC_MOVU_M
, dec_movu_m
},
2855 {DEC_MOVS_M
, dec_movs_m
},
2857 {DEC_CMP_M
, dec_cmp_m
},
2858 {DEC_ADDO_M
, dec_addo_m
},
2859 {DEC_BOUND_M
, dec_bound_m
},
2860 {DEC_ADD_M
, dec_add_m
},
2861 {DEC_SUB_M
, dec_sub_m
},
2862 {DEC_AND_M
, dec_and_m
},
2863 {DEC_OR_M
, dec_or_m
},
2864 {DEC_MOVE_RM
, dec_move_rm
},
2865 {DEC_TEST_M
, dec_test_m
},
2866 {DEC_MOVE_MR
, dec_move_mr
},
2871 static unsigned int crisv32_decoder(CPUCRISState
*env
, DisasContext
*dc
)
2876 /* Load a halfword onto the instruction register. */
2877 dc
->ir
= cris_fetch(env
, dc
, dc
->pc
, 2, 0);
2879 /* Now decode it. */
2880 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2881 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2882 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2883 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2884 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2885 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2887 /* Large switch for all insns. */
2888 for (i
= 0; i
< ARRAY_SIZE(decinfo
); i
++) {
2889 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
) {
2890 insn_len
= decinfo
[i
].dec(env
, dc
);
2895 #if !defined(CONFIG_USER_ONLY)
2896 /* Single-stepping ? */
2897 if (dc
->tb_flags
& S_FLAG
) {
2898 TCGLabel
*l1
= gen_new_label();
2899 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_PR
[PR_SPC
], dc
->pc
, l1
);
2900 /* We treat SPC as a break with an odd trap vector. */
2901 cris_evaluate_flags(dc
);
2902 t_gen_movi_env_TN(trap_vector
, 3);
2903 tcg_gen_movi_tl(env_pc
, dc
->pc
+ insn_len
);
2904 tcg_gen_movi_tl(cpu_PR
[PR_SPC
], dc
->pc
+ insn_len
);
2905 t_gen_raise_exception(EXCP_BREAK
);
2912 #include "translate_v10.c.inc"
2915 * Delay slots on QEMU/CRIS.
2917 * If an exception hits on a delayslot, the core will let ERP (the Exception
2918 * Return Pointer) point to the branch (the previous) insn and set the lsb to
2919 * to give SW a hint that the exception actually hit on the dslot.
2921 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
2922 * the core and any jmp to an odd addresses will mask off that lsb. It is
2923 * simply there to let sw know there was an exception on a dslot.
2925 * When the software returns from an exception, the branch will re-execute.
2926 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
2927 * and the branch and delayslot don't share pages.
2929 * The TB containing the branch insn will set up env->btarget and evaluate
2930 * env->btaken. When the translation loop exits we will note that the branch
2931 * sequence is broken and let env->dslot be the size of the branch insn (those
2934 * The TB containing the delayslot will have the PC of its real insn (i.e no lsb
2935 * set). It will also expect to have env->dslot setup with the size of the
2936 * delay slot so that env->pc - env->dslot point to the branch insn. This TB
2937 * will execute the dslot and take the branch, either to btarget or just one
2940 * When exceptions occur, we check for env->dslot in do_interrupt to detect
2941 * broken branch sequences and setup $erp accordingly (i.e let it point to the
2942 * branch and set lsb). Then env->dslot gets cleared so that the exception
2943 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
2944 * masked off and we will reexecute the branch insn.
2948 static void cris_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2950 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2951 CPUCRISState
*env
= cpu_env(cs
);
2952 uint32_t tb_flags
= dc
->base
.tb
->flags
;
2955 if (env
->pregs
[PR_VR
] == 32) {
2956 dc
->decoder
= crisv32_decoder
;
2957 dc
->clear_locked_irq
= 0;
2959 dc
->decoder
= crisv10_decoder
;
2960 dc
->clear_locked_irq
= 1;
2964 * Odd PC indicates that branch is rexecuting due to exception in the
2965 * delayslot, like in real hw.
2967 pc_start
= dc
->base
.pc_first
& ~1;
2968 dc
->base
.pc_first
= pc_start
;
2969 dc
->base
.pc_next
= pc_start
;
2971 dc
->cpu
= env_archcpu(env
);
2974 dc
->flags_uptodate
= 1;
2975 dc
->flags_x
= tb_flags
& X_FLAG
;
2976 dc
->cc_x_uptodate
= 0;
2979 dc
->clear_prefix
= 0;
2980 dc
->cpustate_changed
= 0;
2982 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
2983 dc
->cc_size_uptodate
= -1;
2985 /* Decode TB flags. */
2986 dc
->tb_flags
= tb_flags
& (S_FLAG
| P_FLAG
| U_FLAG
| X_FLAG
| PFIX_FLAG
);
2987 dc
->delayed_branch
= !!(tb_flags
& 7);
2988 if (dc
->delayed_branch
) {
2989 dc
->jmp
= JMP_INDIRECT
;
2991 dc
->jmp
= JMP_NOJMP
;
2995 static void cris_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
2999 static void cris_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
3001 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3003 tcg_gen_insn_start(dc
->delayed_branch
== 1 ? dc
->ppc
| 1 : dc
->pc
);
3006 static void cris_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
3008 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3009 CPUCRISState
*env
= cpu_env(cs
);
3010 unsigned int insn_len
;
3013 LOG_DIS("%8.8x:\t", dc
->pc
);
3017 insn_len
= dc
->decoder(env
, dc
);
3020 dc
->base
.pc_next
+= insn_len
;
3022 if (dc
->base
.is_jmp
== DISAS_NORETURN
) {
3027 cris_clear_x_flag(dc
);
3031 * All branches are delayed branches, handled immediately below.
3032 * We don't expect to see odd combinations of exit conditions.
3034 assert(dc
->base
.is_jmp
== DISAS_NEXT
|| dc
->cpustate_changed
);
3036 if (dc
->delayed_branch
&& --dc
->delayed_branch
== 0) {
3037 dc
->base
.is_jmp
= DISAS_DBRANCH
;
3041 if (dc
->base
.is_jmp
!= DISAS_NEXT
) {
3045 /* Force an update if the per-tb cpu state has changed. */
3046 if (dc
->cpustate_changed
) {
3047 dc
->base
.is_jmp
= DISAS_UPDATE_NEXT
;
3052 * FIXME: Only the first insn in the TB should cross a page boundary.
3053 * If we can detect the length of the next insn easily, we should.
3054 * In the meantime, simply stop when we do cross.
3056 if ((dc
->pc
^ dc
->base
.pc_first
) & TARGET_PAGE_MASK
) {
3057 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
3061 static void cris_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
3063 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3064 DisasJumpType is_jmp
= dc
->base
.is_jmp
;
3065 target_ulong npc
= dc
->pc
;
3067 if (is_jmp
== DISAS_NORETURN
) {
3068 /* If we have a broken branch+delayslot sequence, it's too late. */
3069 assert(dc
->delayed_branch
!= 1);
3073 if (dc
->clear_locked_irq
) {
3074 t_gen_movi_env_TN(locked_irq
, 0);
3077 /* Broken branch+delayslot sequence. */
3078 if (dc
->delayed_branch
== 1) {
3079 /* Set env->dslot to the size of the branch insn. */
3080 t_gen_movi_env_TN(dslot
, dc
->pc
- dc
->ppc
);
3081 cris_store_direct_jmp(dc
);
3084 cris_evaluate_flags(dc
);
3086 /* Evaluate delayed branch destination and fold to another is_jmp case. */
3087 if (is_jmp
== DISAS_DBRANCH
) {
3088 if (dc
->base
.tb
->flags
& 7) {
3089 t_gen_movi_env_TN(dslot
, 0);
3095 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE_NEXT
: DISAS_TOO_MANY
;
3100 * Use a conditional branch if either taken or not-taken path
3101 * can use goto_tb. If neither can, then treat it as indirect.
3103 if (likely(!dc
->cpustate_changed
)
3104 && (use_goto_tb(dc
, dc
->jmp_pc
) || use_goto_tb(dc
, npc
))) {
3105 TCGLabel
*not_taken
= gen_new_label();
3107 tcg_gen_brcondi_tl(TCG_COND_EQ
, env_btaken
, 0, not_taken
);
3108 gen_goto_tb(dc
, 1, dc
->jmp_pc
);
3109 gen_set_label(not_taken
);
3111 /* not-taken case handled below. */
3112 is_jmp
= DISAS_TOO_MANY
;
3115 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
3119 tcg_gen_movcond_tl(TCG_COND_NE
, env_pc
,
3120 env_btaken
, tcg_constant_tl(0),
3121 env_btarget
, tcg_constant_tl(npc
));
3122 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE
: DISAS_JUMP
;
3125 * We have now consumed btaken and btarget. Hint to the
3126 * tcg compiler that the writeback to env may be dropped.
3128 tcg_gen_discard_tl(env_btaken
);
3129 tcg_gen_discard_tl(env_btarget
);
3133 g_assert_not_reached();
3138 case DISAS_TOO_MANY
:
3139 gen_goto_tb(dc
, 0, npc
);
3141 case DISAS_UPDATE_NEXT
:
3142 tcg_gen_movi_tl(env_pc
, npc
);
3145 tcg_gen_lookup_and_goto_ptr();
3148 /* Indicate that interrupts must be re-evaluated before the next TB. */
3149 tcg_gen_exit_tb(NULL
, 0);
3152 g_assert_not_reached();
3156 static void cris_tr_disas_log(const DisasContextBase
*dcbase
,
3157 CPUState
*cpu
, FILE *logfile
)
3160 fprintf(logfile
, "IN: %s\n", lookup_symbol(dcbase
->pc_first
));
3161 target_disas(logfile
, cpu
, dcbase
->pc_first
, dcbase
->tb
->size
);
3165 static const TranslatorOps cris_tr_ops
= {
3166 .init_disas_context
= cris_tr_init_disas_context
,
3167 .tb_start
= cris_tr_tb_start
,
3168 .insn_start
= cris_tr_insn_start
,
3169 .translate_insn
= cris_tr_translate_insn
,
3170 .tb_stop
= cris_tr_tb_stop
,
3171 .disas_log
= cris_tr_disas_log
,
3174 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int *max_insns
,
3175 target_ulong pc
, void *host_pc
)
3178 translator_loop(cs
, tb
, max_insns
, pc
, host_pc
, &cris_tr_ops
, &dc
.base
);
3181 void cris_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
3183 CRISCPU
*cpu
= CRIS_CPU(cs
);
3184 CPUCRISState
*env
= &cpu
->env
;
3185 const char * const *regnames
;
3186 const char * const *pregnames
;
3192 if (env
->pregs
[PR_VR
] < 32) {
3193 pregnames
= pregnames_v10
;
3194 regnames
= regnames_v10
;
3196 pregnames
= pregnames_v32
;
3197 regnames
= regnames_v32
;
3200 qemu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3201 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3202 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
3204 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
);
3207 for (i
= 0; i
< 16; i
++) {
3208 qemu_fprintf(f
, "%s=%8.8x ", regnames
[i
], env
->regs
[i
]);
3209 if ((i
+ 1) % 4 == 0) {
3210 qemu_fprintf(f
, "\n");
3213 qemu_fprintf(f
, "\nspecial regs:\n");
3214 for (i
= 0; i
< 16; i
++) {
3215 qemu_fprintf(f
, "%s=%8.8x ", pregnames
[i
], env
->pregs
[i
]);
3216 if ((i
+ 1) % 4 == 0) {
3217 qemu_fprintf(f
, "\n");
3220 if (env
->pregs
[PR_VR
] >= 32) {
3221 uint32_t srs
= env
->pregs
[PR_SRS
];
3222 qemu_fprintf(f
, "\nsupport function regs bank %x:\n", srs
);
3223 if (srs
< ARRAY_SIZE(env
->sregs
)) {
3224 for (i
= 0; i
< 16; i
++) {
3225 qemu_fprintf(f
, "s%2.2d=%8.8x ",
3226 i
, env
->sregs
[srs
][i
]);
3227 if ((i
+ 1) % 4 == 0) {
3228 qemu_fprintf(f
, "\n");
3233 qemu_fprintf(f
, "\n\n");
3237 void cris_initialize_tcg(void)
3241 cc_x
= tcg_global_mem_new(tcg_env
,
3242 offsetof(CPUCRISState
, cc_x
), "cc_x");
3243 cc_src
= tcg_global_mem_new(tcg_env
,
3244 offsetof(CPUCRISState
, cc_src
), "cc_src");
3245 cc_dest
= tcg_global_mem_new(tcg_env
,
3246 offsetof(CPUCRISState
, cc_dest
),
3248 cc_result
= tcg_global_mem_new(tcg_env
,
3249 offsetof(CPUCRISState
, cc_result
),
3251 cc_op
= tcg_global_mem_new(tcg_env
,
3252 offsetof(CPUCRISState
, cc_op
), "cc_op");
3253 cc_size
= tcg_global_mem_new(tcg_env
,
3254 offsetof(CPUCRISState
, cc_size
),
3256 cc_mask
= tcg_global_mem_new(tcg_env
,
3257 offsetof(CPUCRISState
, cc_mask
),
3260 env_pc
= tcg_global_mem_new(tcg_env
,
3261 offsetof(CPUCRISState
, pc
),
3263 env_btarget
= tcg_global_mem_new(tcg_env
,
3264 offsetof(CPUCRISState
, btarget
),
3266 env_btaken
= tcg_global_mem_new(tcg_env
,
3267 offsetof(CPUCRISState
, btaken
),
3269 for (i
= 0; i
< 16; i
++) {
3270 cpu_R
[i
] = tcg_global_mem_new(tcg_env
,
3271 offsetof(CPUCRISState
, regs
[i
]),
3274 for (i
= 0; i
< 16; i
++) {
3275 cpu_PR
[i
] = tcg_global_mem_new(tcg_env
,
3276 offsetof(CPUCRISState
, pregs
[i
]),