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
;
100 unsigned int (*decoder
)(CPUCRISState
*env
, struct DisasContext
*dc
);
105 unsigned int zsize
, zzsize
;
107 unsigned int postinc
;
119 int cc_size_uptodate
; /* -1 invalid or last written value. */
121 int cc_x_uptodate
; /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date. */
122 int flags_uptodate
; /* Whether or not $ccs is up-to-date. */
125 int clear_x
; /* Clear x after this insn? */
126 int clear_prefix
; /* Clear prefix after this insn? */
127 int clear_locked_irq
; /* Clear the irq lockout. */
128 int cpustate_changed
;
129 unsigned int tb_flags
; /* tb dependent flags. */
133 #define JMP_DIRECT_CC 2
134 #define JMP_INDIRECT 3
135 int jmp
; /* 0=nojmp, 1=direct, 2=indirect. */
141 static void gen_BUG(DisasContext
*dc
, const char *file
, int line
)
143 cpu_abort(CPU(dc
->cpu
), "%s:%d pc=%x\n", file
, line
, dc
->pc
);
146 static const char * const regnames_v32
[] =
148 "$r0", "$r1", "$r2", "$r3",
149 "$r4", "$r5", "$r6", "$r7",
150 "$r8", "$r9", "$r10", "$r11",
151 "$r12", "$r13", "$sp", "$acr",
154 static const char * const pregnames_v32
[] =
156 "$bz", "$vr", "$pid", "$srs",
157 "$wz", "$exs", "$eda", "$mof",
158 "$dz", "$ebp", "$erp", "$srp",
159 "$nrp", "$ccs", "$usp", "$spc",
162 /* We need this table to handle preg-moves with implicit width. */
163 static const int preg_sizes
[] = {
174 #define t_gen_mov_TN_env(tn, member) \
175 tcg_gen_ld_tl(tn, tcg_env, offsetof(CPUCRISState, member))
176 #define t_gen_mov_env_TN(member, tn) \
177 tcg_gen_st_tl(tn, tcg_env, offsetof(CPUCRISState, member))
178 #define t_gen_movi_env_TN(member, c) \
179 t_gen_mov_env_TN(member, tcg_constant_tl(c))
181 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
183 assert(r
>= 0 && r
<= 15);
184 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
185 tcg_gen_movi_tl(tn
, 0);
186 } else if (r
== PR_VR
) {
187 tcg_gen_movi_tl(tn
, 32);
189 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
192 static inline void t_gen_mov_preg_TN(DisasContext
*dc
, int r
, TCGv tn
)
194 assert(r
>= 0 && r
<= 15);
195 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
197 } else if (r
== PR_SRS
) {
198 tcg_gen_andi_tl(cpu_PR
[r
], tn
, 3);
201 gen_helper_tlb_flush_pid(tcg_env
, tn
);
203 if (dc
->tb_flags
& S_FLAG
&& r
== PR_SPC
) {
204 gen_helper_spc_write(tcg_env
, tn
);
205 } else if (r
== PR_CCS
) {
206 dc
->cpustate_changed
= 1;
208 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
212 /* Sign extend at translation time. */
213 static int sign_extend(unsigned int val
, unsigned int width
)
225 static int cris_fetch(CPUCRISState
*env
, DisasContext
*dc
, uint32_t addr
,
226 unsigned int size
, unsigned int sign
)
233 r
= cpu_ldl_code(env
, addr
);
239 r
= cpu_ldsw_code(env
, addr
);
241 r
= cpu_lduw_code(env
, addr
);
248 r
= cpu_ldsb_code(env
, addr
);
250 r
= cpu_ldub_code(env
, addr
);
255 cpu_abort(CPU(dc
->cpu
), "Invalid fetch size %d\n", size
);
261 static void cris_lock_irq(DisasContext
*dc
)
263 dc
->clear_locked_irq
= 0;
264 t_gen_movi_env_TN(locked_irq
, 1);
267 static inline void t_gen_raise_exception(uint32_t index
)
269 gen_helper_raise_exception(tcg_env
, tcg_constant_i32(index
));
272 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
277 t_31
= tcg_constant_tl(31);
278 tcg_gen_shl_tl(d
, a
, b
);
280 tcg_gen_sub_tl(t0
, t_31
, b
);
281 tcg_gen_sar_tl(t0
, t0
, t_31
);
282 tcg_gen_and_tl(t0
, t0
, d
);
283 tcg_gen_xor_tl(d
, d
, t0
);
286 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
291 t_31
= tcg_temp_new();
292 tcg_gen_shr_tl(d
, a
, b
);
294 tcg_gen_movi_tl(t_31
, 31);
295 tcg_gen_sub_tl(t0
, t_31
, b
);
296 tcg_gen_sar_tl(t0
, t0
, t_31
);
297 tcg_gen_and_tl(t0
, t0
, d
);
298 tcg_gen_xor_tl(d
, d
, t0
);
301 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
306 t_31
= tcg_temp_new();
307 tcg_gen_sar_tl(d
, a
, b
);
309 tcg_gen_movi_tl(t_31
, 31);
310 tcg_gen_sub_tl(t0
, t_31
, b
);
311 tcg_gen_sar_tl(t0
, t0
, t_31
);
312 tcg_gen_or_tl(d
, d
, t0
);
315 static void t_gen_cris_dstep(TCGv d
, TCGv a
, TCGv b
)
317 TCGv t
= tcg_temp_new();
324 tcg_gen_shli_tl(d
, a
, 1);
325 tcg_gen_sub_tl(t
, d
, b
);
326 tcg_gen_movcond_tl(TCG_COND_GEU
, d
, d
, b
, t
, d
);
329 static void t_gen_cris_mstep(TCGv d
, TCGv a
, TCGv b
, TCGv ccs
)
339 tcg_gen_shli_tl(d
, a
, 1);
340 tcg_gen_shli_tl(t
, ccs
, 31 - 3);
341 tcg_gen_sari_tl(t
, t
, 31);
342 tcg_gen_and_tl(t
, t
, b
);
343 tcg_gen_add_tl(d
, d
, t
);
346 /* Extended arithmetic on CRIS. */
347 static inline void t_gen_add_flag(TCGv d
, int flag
)
352 t_gen_mov_TN_preg(c
, PR_CCS
);
353 /* Propagate carry into d. */
354 tcg_gen_andi_tl(c
, c
, 1 << flag
);
356 tcg_gen_shri_tl(c
, c
, flag
);
358 tcg_gen_add_tl(d
, d
, c
);
361 static inline void t_gen_addx_carry(DisasContext
*dc
, TCGv d
)
364 TCGv c
= tcg_temp_new();
366 t_gen_mov_TN_preg(c
, PR_CCS
);
367 /* C flag is already at bit 0. */
368 tcg_gen_andi_tl(c
, c
, C_FLAG
);
369 tcg_gen_add_tl(d
, d
, c
);
373 static inline void t_gen_subx_carry(DisasContext
*dc
, TCGv d
)
376 TCGv c
= tcg_temp_new();
378 t_gen_mov_TN_preg(c
, PR_CCS
);
379 /* C flag is already at bit 0. */
380 tcg_gen_andi_tl(c
, c
, C_FLAG
);
381 tcg_gen_sub_tl(d
, d
, c
);
385 /* Swap the two bytes within each half word of the s operand.
386 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
387 static inline void t_gen_swapb(TCGv d
, TCGv s
)
392 org_s
= tcg_temp_new();
394 /* d and s may refer to the same object. */
395 tcg_gen_mov_tl(org_s
, s
);
396 tcg_gen_shli_tl(t
, org_s
, 8);
397 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
398 tcg_gen_shri_tl(t
, org_s
, 8);
399 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
400 tcg_gen_or_tl(d
, d
, t
);
403 /* Swap the halfwords of the s operand. */
404 static inline void t_gen_swapw(TCGv d
, TCGv s
)
407 /* d and s refer the same object. */
409 tcg_gen_mov_tl(t
, s
);
410 tcg_gen_shli_tl(d
, t
, 16);
411 tcg_gen_shri_tl(t
, t
, 16);
412 tcg_gen_or_tl(d
, d
, t
);
416 * Reverse the bits within each byte.
418 * T0 = ((T0 << 7) & 0x80808080)
419 * | ((T0 << 5) & 0x40404040)
420 * | ((T0 << 3) & 0x20202020)
421 * | ((T0 << 1) & 0x10101010)
422 * | ((T0 >> 1) & 0x08080808)
423 * | ((T0 >> 3) & 0x04040404)
424 * | ((T0 >> 5) & 0x02020202)
425 * | ((T0 >> 7) & 0x01010101);
427 static void t_gen_swapr(TCGv d
, TCGv s
)
429 static const struct {
430 int shift
; /* LSL when positive, LSR when negative. */
445 /* d and s refer the same object. */
447 org_s
= tcg_temp_new();
448 tcg_gen_mov_tl(org_s
, s
);
450 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
451 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
452 for (i
= 1; i
< ARRAY_SIZE(bitrev
); i
++) {
453 if (bitrev
[i
].shift
>= 0) {
454 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
456 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
458 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
459 tcg_gen_or_tl(d
, d
, t
);
463 static bool use_goto_tb(DisasContext
*dc
, target_ulong dest
)
465 return translator_use_goto_tb(&dc
->base
, dest
);
468 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
470 if (use_goto_tb(dc
, dest
)) {
472 tcg_gen_movi_tl(env_pc
, dest
);
473 tcg_gen_exit_tb(dc
->base
.tb
, n
);
475 tcg_gen_movi_tl(env_pc
, dest
);
476 tcg_gen_lookup_and_goto_ptr();
480 static inline void cris_clear_x_flag(DisasContext
*dc
)
483 dc
->flags_uptodate
= 0;
488 static void cris_flush_cc_state(DisasContext
*dc
)
490 if (dc
->cc_size_uptodate
!= dc
->cc_size
) {
491 tcg_gen_movi_tl(cc_size
, dc
->cc_size
);
492 dc
->cc_size_uptodate
= dc
->cc_size
;
494 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
495 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
498 static void cris_evaluate_flags(DisasContext
*dc
)
500 if (dc
->flags_uptodate
) {
504 cris_flush_cc_state(dc
);
508 gen_helper_evaluate_flags_mcp(cpu_PR
[PR_CCS
], tcg_env
,
509 cpu_PR
[PR_CCS
], cc_src
,
513 gen_helper_evaluate_flags_muls(cpu_PR
[PR_CCS
], tcg_env
,
514 cpu_PR
[PR_CCS
], cc_result
,
518 gen_helper_evaluate_flags_mulu(cpu_PR
[PR_CCS
], tcg_env
,
519 cpu_PR
[PR_CCS
], cc_result
,
529 switch (dc
->cc_size
) {
531 gen_helper_evaluate_flags_move_4(cpu_PR
[PR_CCS
],
532 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
535 gen_helper_evaluate_flags_move_2(cpu_PR
[PR_CCS
],
536 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
539 gen_helper_evaluate_flags(tcg_env
);
548 if (dc
->cc_size
== 4) {
549 gen_helper_evaluate_flags_sub_4(cpu_PR
[PR_CCS
], tcg_env
,
550 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
552 gen_helper_evaluate_flags(tcg_env
);
557 switch (dc
->cc_size
) {
559 gen_helper_evaluate_flags_alu_4(cpu_PR
[PR_CCS
], tcg_env
,
560 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
563 gen_helper_evaluate_flags(tcg_env
);
570 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], X_FLAG
);
571 } else if (dc
->cc_op
== CC_OP_FLAGS
) {
572 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~X_FLAG
);
574 dc
->flags_uptodate
= 1;
577 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
586 /* Check if we need to evaluate the condition codes due to
588 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
590 /* TODO: optimize this case. It trigs all the time. */
591 cris_evaluate_flags(dc
);
597 static void cris_update_cc_op(DisasContext
*dc
, int op
, int size
)
601 dc
->flags_uptodate
= 0;
604 static inline void cris_update_cc_x(DisasContext
*dc
)
606 /* Save the x flag state at the time of the cc snapshot. */
607 if (dc
->cc_x_uptodate
== (2 | dc
->flags_x
)) {
610 tcg_gen_movi_tl(cc_x
, dc
->flags_x
);
611 dc
->cc_x_uptodate
= 2 | dc
->flags_x
;
614 /* Update cc prior to executing ALU op. Needs source operands untouched. */
615 static void cris_pre_alu_update_cc(DisasContext
*dc
, int op
,
616 TCGv dst
, TCGv src
, int size
)
619 cris_update_cc_op(dc
, op
, size
);
620 tcg_gen_mov_tl(cc_src
, src
);
628 && op
!= CC_OP_LSL
) {
629 tcg_gen_mov_tl(cc_dest
, dst
);
632 cris_update_cc_x(dc
);
636 /* Update cc after executing ALU op. needs the result. */
637 static inline void cris_update_result(DisasContext
*dc
, TCGv res
)
640 tcg_gen_mov_tl(cc_result
, res
);
644 /* Returns one if the write back stage should execute. */
645 static void cris_alu_op_exec(DisasContext
*dc
, int op
,
646 TCGv dst
, TCGv a
, TCGv b
, int size
)
648 /* Emit the ALU insns. */
651 tcg_gen_add_tl(dst
, a
, b
);
652 /* Extended arithmetic. */
653 t_gen_addx_carry(dc
, dst
);
656 tcg_gen_add_tl(dst
, a
, b
);
657 t_gen_add_flag(dst
, 0); /* C_FLAG. */
660 tcg_gen_add_tl(dst
, a
, b
);
661 t_gen_add_flag(dst
, 8); /* R_FLAG. */
664 tcg_gen_sub_tl(dst
, a
, b
);
665 /* Extended arithmetic. */
666 t_gen_subx_carry(dc
, dst
);
669 tcg_gen_mov_tl(dst
, b
);
672 tcg_gen_or_tl(dst
, a
, b
);
675 tcg_gen_and_tl(dst
, a
, b
);
678 tcg_gen_xor_tl(dst
, a
, b
);
681 t_gen_lsl(dst
, a
, b
);
684 t_gen_lsr(dst
, a
, b
);
687 t_gen_asr(dst
, a
, b
);
690 tcg_gen_neg_tl(dst
, b
);
691 /* Extended arithmetic. */
692 t_gen_subx_carry(dc
, dst
);
695 tcg_gen_clzi_tl(dst
, b
, TARGET_LONG_BITS
);
698 tcg_gen_muls2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
701 tcg_gen_mulu2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
704 t_gen_cris_dstep(dst
, a
, b
);
707 t_gen_cris_mstep(dst
, a
, b
, cpu_PR
[PR_CCS
]);
710 tcg_gen_movcond_tl(TCG_COND_LEU
, dst
, a
, b
, a
, b
);
713 tcg_gen_sub_tl(dst
, a
, b
);
714 /* Extended arithmetic. */
715 t_gen_subx_carry(dc
, dst
);
718 qemu_log_mask(LOG_GUEST_ERROR
, "illegal ALU op.\n");
724 tcg_gen_andi_tl(dst
, dst
, 0xff);
725 } else if (size
== 2) {
726 tcg_gen_andi_tl(dst
, dst
, 0xffff);
730 static void cris_alu(DisasContext
*dc
, int op
,
731 TCGv d
, TCGv op_a
, TCGv op_b
, int size
)
738 if (op
== CC_OP_CMP
) {
739 tmp
= tcg_temp_new();
741 } else if (size
== 4) {
745 tmp
= tcg_temp_new();
749 cris_pre_alu_update_cc(dc
, op
, op_a
, op_b
, size
);
750 cris_alu_op_exec(dc
, op
, tmp
, op_a
, op_b
, size
);
751 cris_update_result(dc
, tmp
);
756 tcg_gen_andi_tl(d
, d
, ~0xff);
758 tcg_gen_andi_tl(d
, d
, ~0xffff);
760 tcg_gen_or_tl(d
, d
, tmp
);
764 static int arith_cc(DisasContext
*dc
)
768 case CC_OP_ADDC
: return 1;
769 case CC_OP_ADD
: return 1;
770 case CC_OP_SUB
: return 1;
771 case CC_OP_DSTEP
: return 1;
772 case CC_OP_LSL
: return 1;
773 case CC_OP_LSR
: return 1;
774 case CC_OP_ASR
: return 1;
775 case CC_OP_CMP
: return 1;
776 case CC_OP_NEG
: return 1;
777 case CC_OP_OR
: return 1;
778 case CC_OP_AND
: return 1;
779 case CC_OP_XOR
: return 1;
780 case CC_OP_MULU
: return 1;
781 case CC_OP_MULS
: return 1;
789 static void gen_tst_cc (DisasContext
*dc
, TCGv cc
, int cond
)
791 int arith_opt
, move_opt
;
793 /* TODO: optimize more condition codes. */
796 * If the flags are live, we've gotta look into the bits of CCS.
797 * Otherwise, if we just did an arithmetic operation we try to
798 * evaluate the condition code faster.
800 * When this function is done, T0 should be non-zero if the condition
803 arith_opt
= arith_cc(dc
) && !dc
->flags_uptodate
;
804 move_opt
= (dc
->cc_op
== CC_OP_MOVE
);
807 if ((arith_opt
|| move_opt
)
808 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
809 tcg_gen_setcondi_tl(TCG_COND_EQ
, cc
, cc_result
, 0);
811 cris_evaluate_flags(dc
);
813 cpu_PR
[PR_CCS
], Z_FLAG
);
817 if ((arith_opt
|| move_opt
)
818 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
819 tcg_gen_mov_tl(cc
, cc_result
);
821 cris_evaluate_flags(dc
);
822 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
824 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
828 cris_evaluate_flags(dc
);
829 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
832 cris_evaluate_flags(dc
);
833 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
834 tcg_gen_andi_tl(cc
, cc
, C_FLAG
);
837 cris_evaluate_flags(dc
);
838 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], V_FLAG
);
841 cris_evaluate_flags(dc
);
842 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
844 tcg_gen_andi_tl(cc
, cc
, V_FLAG
);
847 if (arith_opt
|| move_opt
) {
850 if (dc
->cc_size
== 1) {
852 } else if (dc
->cc_size
== 2) {
856 tcg_gen_shri_tl(cc
, cc_result
, bits
);
857 tcg_gen_xori_tl(cc
, cc
, 1);
859 cris_evaluate_flags(dc
);
860 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
862 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
866 if (arith_opt
|| move_opt
) {
869 if (dc
->cc_size
== 1) {
871 } else if (dc
->cc_size
== 2) {
875 tcg_gen_shri_tl(cc
, cc_result
, bits
);
876 tcg_gen_andi_tl(cc
, cc
, 1);
878 cris_evaluate_flags(dc
);
879 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
884 cris_evaluate_flags(dc
);
885 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
889 cris_evaluate_flags(dc
);
893 tmp
= tcg_temp_new();
894 tcg_gen_xori_tl(tmp
, cpu_PR
[PR_CCS
],
896 /* Overlay the C flag on top of the Z. */
897 tcg_gen_shli_tl(cc
, tmp
, 2);
898 tcg_gen_and_tl(cc
, tmp
, cc
);
899 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
903 cris_evaluate_flags(dc
);
904 /* Overlay the V flag on top of the N. */
905 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
908 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
909 tcg_gen_xori_tl(cc
, cc
, N_FLAG
);
912 cris_evaluate_flags(dc
);
913 /* Overlay the V flag on top of the N. */
914 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
917 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
920 cris_evaluate_flags(dc
);
927 /* To avoid a shift we overlay everything on
929 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
930 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
932 tcg_gen_xori_tl(z
, z
, 2);
934 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
935 tcg_gen_xori_tl(n
, n
, 2);
936 tcg_gen_and_tl(cc
, z
, n
);
937 tcg_gen_andi_tl(cc
, cc
, 2);
941 cris_evaluate_flags(dc
);
948 /* To avoid a shift we overlay everything on
950 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
951 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
953 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
954 tcg_gen_or_tl(cc
, z
, n
);
955 tcg_gen_andi_tl(cc
, cc
, 2);
959 cris_evaluate_flags(dc
);
960 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], P_FLAG
);
963 tcg_gen_movi_tl(cc
, 1);
971 static void cris_store_direct_jmp(DisasContext
*dc
)
973 /* Store the direct jmp state into the cpu-state. */
974 if (dc
->jmp
== JMP_DIRECT
|| dc
->jmp
== JMP_DIRECT_CC
) {
975 if (dc
->jmp
== JMP_DIRECT
) {
976 tcg_gen_movi_tl(env_btaken
, 1);
978 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
979 dc
->jmp
= JMP_INDIRECT
;
983 static void cris_prepare_cc_branch (DisasContext
*dc
,
984 int offset
, int cond
)
986 /* This helps us re-schedule the micro-code to insns in delay-slots
987 before the actual jump. */
988 dc
->delayed_branch
= 2;
989 dc
->jmp
= JMP_DIRECT_CC
;
990 dc
->jmp_pc
= dc
->pc
+ offset
;
992 gen_tst_cc(dc
, env_btaken
, cond
);
993 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
997 /* jumps, when the dest is in a live reg for example. Direct should be set
998 when the dest addr is constant to allow tb chaining. */
999 static inline void cris_prepare_jmp (DisasContext
*dc
, unsigned int type
)
1001 /* This helps us re-schedule the micro-code to insns in delay-slots
1002 before the actual jump. */
1003 dc
->delayed_branch
= 2;
1005 if (type
== JMP_INDIRECT
) {
1006 tcg_gen_movi_tl(env_btaken
, 1);
1010 static void gen_load64(DisasContext
*dc
, TCGv_i64 dst
, TCGv addr
)
1012 /* If we get a fault on a delayslot we must keep the jmp state in
1013 the cpu-state to be able to re-execute the jmp. */
1014 if (dc
->delayed_branch
== 1) {
1015 cris_store_direct_jmp(dc
);
1018 tcg_gen_qemu_ld_i64(dst
, addr
, dc
->mem_index
, MO_TEUQ
);
1021 static void gen_load(DisasContext
*dc
, TCGv dst
, TCGv addr
,
1022 unsigned int size
, int sign
)
1024 /* If we get a fault on a delayslot we must keep the jmp state in
1025 the cpu-state to be able to re-execute the jmp. */
1026 if (dc
->delayed_branch
== 1) {
1027 cris_store_direct_jmp(dc
);
1030 tcg_gen_qemu_ld_tl(dst
, addr
, dc
->mem_index
,
1031 MO_TE
+ ctz32(size
) + (sign
? MO_SIGN
: 0));
1034 static void gen_store (DisasContext
*dc
, TCGv addr
, TCGv val
,
1037 /* If we get a fault on a delayslot we must keep the jmp state in
1038 the cpu-state to be able to re-execute the jmp. */
1039 if (dc
->delayed_branch
== 1) {
1040 cris_store_direct_jmp(dc
);
1044 /* Conditional writes. We only support the kind were X and P are known
1045 at translation time. */
1046 if (dc
->flags_x
&& (dc
->tb_flags
& P_FLAG
)) {
1048 cris_evaluate_flags(dc
);
1049 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], C_FLAG
);
1053 tcg_gen_qemu_st_tl(val
, addr
, dc
->mem_index
, MO_TE
+ ctz32(size
));
1056 cris_evaluate_flags(dc
);
1057 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~C_FLAG
);
1061 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
1064 tcg_gen_ext8s_i32(d
, s
);
1065 } else if (size
== 2) {
1066 tcg_gen_ext16s_i32(d
, s
);
1068 tcg_gen_mov_tl(d
, s
);
1072 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
1075 tcg_gen_ext8u_i32(d
, s
);
1076 } else if (size
== 2) {
1077 tcg_gen_ext16u_i32(d
, s
);
1079 tcg_gen_mov_tl(d
, s
);
1084 static char memsize_char(int size
)
1096 static inline unsigned int memsize_z(DisasContext
*dc
)
1098 return dc
->zsize
+ 1;
1101 static inline unsigned int memsize_zz(DisasContext
*dc
)
1103 switch (dc
->zzsize
) {
1111 static inline void do_postinc (DisasContext
*dc
, int size
)
1114 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], size
);
1118 static inline void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
1119 int size
, int s_ext
, TCGv dst
)
1122 t_gen_sext(dst
, cpu_R
[rs
], size
);
1124 t_gen_zext(dst
, cpu_R
[rs
], size
);
1128 /* Prepare T0 and T1 for a register alu operation.
1129 s_ext decides if the operand1 should be sign-extended or zero-extended when
1131 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
1132 int size
, int s_ext
, TCGv dst
, TCGv src
)
1134 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
, src
);
1137 t_gen_sext(dst
, cpu_R
[rd
], size
);
1139 t_gen_zext(dst
, cpu_R
[rd
], size
);
1143 static int dec_prep_move_m(CPUCRISState
*env
, DisasContext
*dc
,
1144 int s_ext
, int memsize
, TCGv dst
)
1152 is_imm
= rs
== 15 && dc
->postinc
;
1154 /* Load [$rs] onto T1. */
1156 insn_len
= 2 + memsize
;
1161 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, memsize
, s_ext
);
1162 tcg_gen_movi_tl(dst
, imm
);
1165 cris_flush_cc_state(dc
);
1166 gen_load(dc
, dst
, cpu_R
[rs
], memsize
, 0);
1168 t_gen_sext(dst
, dst
, memsize
);
1170 t_gen_zext(dst
, dst
, memsize
);
1176 /* Prepare T0 and T1 for a memory + alu operation.
1177 s_ext decides if the operand1 should be sign-extended or zero-extended when
1179 static int dec_prep_alu_m(CPUCRISState
*env
, DisasContext
*dc
,
1180 int s_ext
, int memsize
, TCGv dst
, TCGv src
)
1184 insn_len
= dec_prep_move_m(env
, dc
, s_ext
, memsize
, src
);
1185 tcg_gen_mov_tl(dst
, cpu_R
[dc
->op2
]);
1190 static const char *cc_name(int cc
)
1192 static const char * const cc_names
[16] = {
1193 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1194 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1197 return cc_names
[cc
];
1201 /* Start of insn decoders. */
1203 static int dec_bccq(CPUCRISState
*env
, DisasContext
*dc
)
1207 uint32_t cond
= dc
->op2
;
1209 offset
= EXTRACT_FIELD(dc
->ir
, 1, 7);
1210 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1213 offset
|= sign
<< 8;
1214 offset
= sign_extend(offset
, 8);
1216 LOG_DIS("b%s %x\n", cc_name(cond
), dc
->pc
+ offset
);
1218 /* op2 holds the condition-code. */
1219 cris_cc_mask(dc
, 0);
1220 cris_prepare_cc_branch(dc
, offset
, cond
);
1223 static int dec_addoq(CPUCRISState
*env
, DisasContext
*dc
)
1227 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1228 imm
= sign_extend(dc
->op1
, 7);
1230 LOG_DIS("addoq %d, $r%u\n", imm
, dc
->op2
);
1231 cris_cc_mask(dc
, 0);
1232 /* Fetch register operand, */
1233 tcg_gen_addi_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op2
], imm
);
1237 static int dec_addq(CPUCRISState
*env
, DisasContext
*dc
)
1240 LOG_DIS("addq %u, $r%u\n", dc
->op1
, dc
->op2
);
1242 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1244 cris_cc_mask(dc
, CC_MASK_NZVC
);
1246 c
= tcg_constant_tl(dc
->op1
);
1247 cris_alu(dc
, CC_OP_ADD
,
1248 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1251 static int dec_moveq(CPUCRISState
*env
, DisasContext
*dc
)
1255 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1256 imm
= sign_extend(dc
->op1
, 5);
1257 LOG_DIS("moveq %d, $r%u\n", imm
, dc
->op2
);
1259 tcg_gen_movi_tl(cpu_R
[dc
->op2
], imm
);
1262 static int dec_subq(CPUCRISState
*env
, DisasContext
*dc
)
1265 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1267 LOG_DIS("subq %u, $r%u\n", dc
->op1
, dc
->op2
);
1269 cris_cc_mask(dc
, CC_MASK_NZVC
);
1270 c
= tcg_constant_tl(dc
->op1
);
1271 cris_alu(dc
, CC_OP_SUB
,
1272 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1275 static int dec_cmpq(CPUCRISState
*env
, DisasContext
*dc
)
1279 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1280 imm
= sign_extend(dc
->op1
, 5);
1282 LOG_DIS("cmpq %d, $r%d\n", imm
, dc
->op2
);
1283 cris_cc_mask(dc
, CC_MASK_NZVC
);
1285 c
= tcg_constant_tl(imm
);
1286 cris_alu(dc
, CC_OP_CMP
,
1287 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1290 static int dec_andq(CPUCRISState
*env
, DisasContext
*dc
)
1294 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1295 imm
= sign_extend(dc
->op1
, 5);
1297 LOG_DIS("andq %d, $r%d\n", imm
, dc
->op2
);
1298 cris_cc_mask(dc
, CC_MASK_NZ
);
1300 c
= tcg_constant_tl(imm
);
1301 cris_alu(dc
, CC_OP_AND
,
1302 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1305 static int dec_orq(CPUCRISState
*env
, DisasContext
*dc
)
1309 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1310 imm
= sign_extend(dc
->op1
, 5);
1311 LOG_DIS("orq %d, $r%d\n", imm
, dc
->op2
);
1312 cris_cc_mask(dc
, CC_MASK_NZ
);
1314 c
= tcg_constant_tl(imm
);
1315 cris_alu(dc
, CC_OP_OR
,
1316 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1319 static int dec_btstq(CPUCRISState
*env
, DisasContext
*dc
)
1322 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1323 LOG_DIS("btstq %u, $r%d\n", dc
->op1
, dc
->op2
);
1325 cris_cc_mask(dc
, CC_MASK_NZ
);
1326 c
= tcg_constant_tl(dc
->op1
);
1327 cris_evaluate_flags(dc
);
1328 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1330 cris_alu(dc
, CC_OP_MOVE
,
1331 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1332 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1333 dc
->flags_uptodate
= 1;
1336 static int dec_asrq(CPUCRISState
*env
, DisasContext
*dc
)
1338 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1339 LOG_DIS("asrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1340 cris_cc_mask(dc
, CC_MASK_NZ
);
1342 tcg_gen_sari_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1343 cris_alu(dc
, CC_OP_MOVE
,
1345 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1348 static int dec_lslq(CPUCRISState
*env
, DisasContext
*dc
)
1350 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1351 LOG_DIS("lslq %u, $r%d\n", dc
->op1
, dc
->op2
);
1353 cris_cc_mask(dc
, CC_MASK_NZ
);
1355 tcg_gen_shli_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1357 cris_alu(dc
, CC_OP_MOVE
,
1359 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1362 static int dec_lsrq(CPUCRISState
*env
, DisasContext
*dc
)
1364 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1365 LOG_DIS("lsrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1367 cris_cc_mask(dc
, CC_MASK_NZ
);
1369 tcg_gen_shri_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1370 cris_alu(dc
, CC_OP_MOVE
,
1372 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1376 static int dec_move_r(CPUCRISState
*env
, DisasContext
*dc
)
1378 int size
= memsize_zz(dc
);
1380 LOG_DIS("move.%c $r%u, $r%u\n",
1381 memsize_char(size
), dc
->op1
, dc
->op2
);
1383 cris_cc_mask(dc
, CC_MASK_NZ
);
1385 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, cpu_R
[dc
->op2
]);
1386 cris_cc_mask(dc
, CC_MASK_NZ
);
1387 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
1388 cris_update_cc_x(dc
);
1389 cris_update_result(dc
, cpu_R
[dc
->op2
]);
1393 t0
= tcg_temp_new();
1394 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1395 cris_alu(dc
, CC_OP_MOVE
,
1397 cpu_R
[dc
->op2
], t0
, size
);
1402 static int dec_scc_r(CPUCRISState
*env
, DisasContext
*dc
)
1406 LOG_DIS("s%s $r%u\n",
1407 cc_name(cond
), dc
->op1
);
1409 gen_tst_cc(dc
, cpu_R
[dc
->op1
], cond
);
1410 tcg_gen_setcondi_tl(TCG_COND_NE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], 0);
1412 cris_cc_mask(dc
, 0);
1416 static inline void cris_alu_alloc_temps(DisasContext
*dc
, int size
, TCGv
*t
)
1419 t
[0] = cpu_R
[dc
->op2
];
1420 t
[1] = cpu_R
[dc
->op1
];
1422 t
[0] = tcg_temp_new();
1423 t
[1] = tcg_temp_new();
1427 static int dec_and_r(CPUCRISState
*env
, DisasContext
*dc
)
1430 int size
= memsize_zz(dc
);
1432 LOG_DIS("and.%c $r%u, $r%u\n",
1433 memsize_char(size
), dc
->op1
, dc
->op2
);
1435 cris_cc_mask(dc
, CC_MASK_NZ
);
1437 cris_alu_alloc_temps(dc
, size
, t
);
1438 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1439 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1443 static int dec_lz_r(CPUCRISState
*env
, DisasContext
*dc
)
1446 LOG_DIS("lz $r%u, $r%u\n",
1448 cris_cc_mask(dc
, CC_MASK_NZ
);
1449 t0
= tcg_temp_new();
1450 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0, cpu_R
[dc
->op2
], t0
);
1451 cris_alu(dc
, CC_OP_LZ
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1455 static int dec_lsl_r(CPUCRISState
*env
, DisasContext
*dc
)
1458 int size
= memsize_zz(dc
);
1460 LOG_DIS("lsl.%c $r%u, $r%u\n",
1461 memsize_char(size
), dc
->op1
, dc
->op2
);
1463 cris_cc_mask(dc
, CC_MASK_NZ
);
1464 cris_alu_alloc_temps(dc
, size
, t
);
1465 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1466 tcg_gen_andi_tl(t
[1], t
[1], 63);
1467 cris_alu(dc
, CC_OP_LSL
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1471 static int dec_lsr_r(CPUCRISState
*env
, DisasContext
*dc
)
1474 int size
= memsize_zz(dc
);
1476 LOG_DIS("lsr.%c $r%u, $r%u\n",
1477 memsize_char(size
), dc
->op1
, dc
->op2
);
1479 cris_cc_mask(dc
, CC_MASK_NZ
);
1480 cris_alu_alloc_temps(dc
, size
, t
);
1481 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1482 tcg_gen_andi_tl(t
[1], t
[1], 63);
1483 cris_alu(dc
, CC_OP_LSR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1487 static int dec_asr_r(CPUCRISState
*env
, DisasContext
*dc
)
1490 int size
= memsize_zz(dc
);
1492 LOG_DIS("asr.%c $r%u, $r%u\n",
1493 memsize_char(size
), dc
->op1
, dc
->op2
);
1495 cris_cc_mask(dc
, CC_MASK_NZ
);
1496 cris_alu_alloc_temps(dc
, size
, t
);
1497 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1, t
[0], t
[1]);
1498 tcg_gen_andi_tl(t
[1], t
[1], 63);
1499 cris_alu(dc
, CC_OP_ASR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1503 static int dec_muls_r(CPUCRISState
*env
, DisasContext
*dc
)
1506 int size
= memsize_zz(dc
);
1508 LOG_DIS("muls.%c $r%u, $r%u\n",
1509 memsize_char(size
), dc
->op1
, dc
->op2
);
1510 cris_cc_mask(dc
, CC_MASK_NZV
);
1511 cris_alu_alloc_temps(dc
, size
, t
);
1512 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1, t
[0], t
[1]);
1514 cris_alu(dc
, CC_OP_MULS
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1518 static int dec_mulu_r(CPUCRISState
*env
, DisasContext
*dc
)
1521 int size
= memsize_zz(dc
);
1523 LOG_DIS("mulu.%c $r%u, $r%u\n",
1524 memsize_char(size
), dc
->op1
, dc
->op2
);
1525 cris_cc_mask(dc
, CC_MASK_NZV
);
1526 cris_alu_alloc_temps(dc
, size
, t
);
1527 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1529 cris_alu(dc
, CC_OP_MULU
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1534 static int dec_dstep_r(CPUCRISState
*env
, DisasContext
*dc
)
1536 LOG_DIS("dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
);
1537 cris_cc_mask(dc
, CC_MASK_NZ
);
1538 cris_alu(dc
, CC_OP_DSTEP
,
1539 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1543 static int dec_xor_r(CPUCRISState
*env
, DisasContext
*dc
)
1546 int size
= memsize_zz(dc
);
1547 LOG_DIS("xor.%c $r%u, $r%u\n",
1548 memsize_char(size
), dc
->op1
, dc
->op2
);
1549 BUG_ON(size
!= 4); /* xor is dword. */
1550 cris_cc_mask(dc
, CC_MASK_NZ
);
1551 cris_alu_alloc_temps(dc
, size
, t
);
1552 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1554 cris_alu(dc
, CC_OP_XOR
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1558 static int dec_bound_r(CPUCRISState
*env
, DisasContext
*dc
)
1561 int size
= memsize_zz(dc
);
1562 LOG_DIS("bound.%c $r%u, $r%u\n",
1563 memsize_char(size
), dc
->op1
, dc
->op2
);
1564 cris_cc_mask(dc
, CC_MASK_NZ
);
1565 l0
= tcg_temp_new();
1566 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, l0
);
1567 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], l0
, 4);
1571 static int dec_cmp_r(CPUCRISState
*env
, DisasContext
*dc
)
1574 int size
= memsize_zz(dc
);
1575 LOG_DIS("cmp.%c $r%u, $r%u\n",
1576 memsize_char(size
), dc
->op1
, dc
->op2
);
1577 cris_cc_mask(dc
, CC_MASK_NZVC
);
1578 cris_alu_alloc_temps(dc
, size
, t
);
1579 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1581 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1585 static int dec_abs_r(CPUCRISState
*env
, DisasContext
*dc
)
1587 LOG_DIS("abs $r%u, $r%u\n",
1589 cris_cc_mask(dc
, CC_MASK_NZ
);
1591 tcg_gen_abs_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op1
]);
1592 cris_alu(dc
, CC_OP_MOVE
,
1593 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1597 static int dec_add_r(CPUCRISState
*env
, DisasContext
*dc
)
1600 int size
= memsize_zz(dc
);
1601 LOG_DIS("add.%c $r%u, $r%u\n",
1602 memsize_char(size
), dc
->op1
, dc
->op2
);
1603 cris_cc_mask(dc
, CC_MASK_NZVC
);
1604 cris_alu_alloc_temps(dc
, size
, t
);
1605 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1607 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1611 static int dec_addc_r(CPUCRISState
*env
, DisasContext
*dc
)
1613 LOG_DIS("addc $r%u, $r%u\n",
1615 cris_evaluate_flags(dc
);
1617 /* Set for this insn. */
1618 dc
->flags_x
= X_FLAG
;
1620 cris_cc_mask(dc
, CC_MASK_NZVC
);
1621 cris_alu(dc
, CC_OP_ADDC
,
1622 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1626 static int dec_mcp_r(CPUCRISState
*env
, DisasContext
*dc
)
1628 LOG_DIS("mcp $p%u, $r%u\n",
1630 cris_evaluate_flags(dc
);
1631 cris_cc_mask(dc
, CC_MASK_RNZV
);
1632 cris_alu(dc
, CC_OP_MCP
,
1633 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], cpu_PR
[dc
->op2
], 4);
1638 static char * swapmode_name(int mode
, char *modename
) {
1641 modename
[i
++] = 'n';
1644 modename
[i
++] = 'w';
1647 modename
[i
++] = 'b';
1650 modename
[i
++] = 'r';
1657 static int dec_swap_r(CPUCRISState
*env
, DisasContext
*dc
)
1663 LOG_DIS("swap%s $r%u\n",
1664 swapmode_name(dc
->op2
, modename
), dc
->op1
);
1666 cris_cc_mask(dc
, CC_MASK_NZ
);
1667 t0
= tcg_temp_new();
1668 tcg_gen_mov_tl(t0
, cpu_R
[dc
->op1
]);
1670 tcg_gen_not_tl(t0
, t0
);
1673 t_gen_swapw(t0
, t0
);
1676 t_gen_swapb(t0
, t0
);
1679 t_gen_swapr(t0
, t0
);
1681 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
, 4);
1685 static int dec_or_r(CPUCRISState
*env
, DisasContext
*dc
)
1688 int size
= memsize_zz(dc
);
1689 LOG_DIS("or.%c $r%u, $r%u\n",
1690 memsize_char(size
), dc
->op1
, dc
->op2
);
1691 cris_cc_mask(dc
, CC_MASK_NZ
);
1692 cris_alu_alloc_temps(dc
, size
, t
);
1693 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1694 cris_alu(dc
, CC_OP_OR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1698 static int dec_addi_r(CPUCRISState
*env
, DisasContext
*dc
)
1701 LOG_DIS("addi.%c $r%u, $r%u\n",
1702 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1703 cris_cc_mask(dc
, 0);
1704 t0
= tcg_temp_new();
1705 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1706 tcg_gen_add_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
);
1710 static int dec_addi_acr(CPUCRISState
*env
, DisasContext
*dc
)
1713 LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1714 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1715 cris_cc_mask(dc
, 0);
1716 t0
= tcg_temp_new();
1717 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1718 tcg_gen_add_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op1
], t0
);
1722 static int dec_neg_r(CPUCRISState
*env
, DisasContext
*dc
)
1725 int size
= memsize_zz(dc
);
1726 LOG_DIS("neg.%c $r%u, $r%u\n",
1727 memsize_char(size
), dc
->op1
, dc
->op2
);
1728 cris_cc_mask(dc
, CC_MASK_NZVC
);
1729 cris_alu_alloc_temps(dc
, size
, t
);
1730 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1732 cris_alu(dc
, CC_OP_NEG
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1736 static int dec_btst_r(CPUCRISState
*env
, DisasContext
*dc
)
1738 LOG_DIS("btst $r%u, $r%u\n",
1740 cris_cc_mask(dc
, CC_MASK_NZ
);
1741 cris_evaluate_flags(dc
);
1742 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1743 cpu_R
[dc
->op1
], cpu_PR
[PR_CCS
]);
1744 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
],
1745 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1746 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1747 dc
->flags_uptodate
= 1;
1751 static int dec_sub_r(CPUCRISState
*env
, DisasContext
*dc
)
1754 int size
= memsize_zz(dc
);
1755 LOG_DIS("sub.%c $r%u, $r%u\n",
1756 memsize_char(size
), dc
->op1
, dc
->op2
);
1757 cris_cc_mask(dc
, CC_MASK_NZVC
);
1758 cris_alu_alloc_temps(dc
, size
, t
);
1759 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1760 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1764 /* Zero extension. From size to dword. */
1765 static int dec_movu_r(CPUCRISState
*env
, DisasContext
*dc
)
1768 int size
= memsize_z(dc
);
1769 LOG_DIS("movu.%c $r%u, $r%u\n",
1773 cris_cc_mask(dc
, CC_MASK_NZ
);
1774 t0
= tcg_temp_new();
1775 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1776 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1780 /* Sign extension. From size to dword. */
1781 static int dec_movs_r(CPUCRISState
*env
, DisasContext
*dc
)
1784 int size
= memsize_z(dc
);
1785 LOG_DIS("movs.%c $r%u, $r%u\n",
1789 cris_cc_mask(dc
, CC_MASK_NZ
);
1790 t0
= tcg_temp_new();
1791 /* Size can only be qi or hi. */
1792 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1793 cris_alu(dc
, CC_OP_MOVE
,
1794 cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], t0
, 4);
1798 /* zero extension. From size to dword. */
1799 static int dec_addu_r(CPUCRISState
*env
, DisasContext
*dc
)
1802 int size
= memsize_z(dc
);
1803 LOG_DIS("addu.%c $r%u, $r%u\n",
1807 cris_cc_mask(dc
, CC_MASK_NZVC
);
1808 t0
= tcg_temp_new();
1809 /* Size can only be qi or hi. */
1810 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1811 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1815 /* Sign extension. From size to dword. */
1816 static int dec_adds_r(CPUCRISState
*env
, DisasContext
*dc
)
1819 int size
= memsize_z(dc
);
1820 LOG_DIS("adds.%c $r%u, $r%u\n",
1824 cris_cc_mask(dc
, CC_MASK_NZVC
);
1825 t0
= tcg_temp_new();
1826 /* Size can only be qi or hi. */
1827 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1828 cris_alu(dc
, CC_OP_ADD
,
1829 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1833 /* Zero extension. From size to dword. */
1834 static int dec_subu_r(CPUCRISState
*env
, DisasContext
*dc
)
1837 int size
= memsize_z(dc
);
1838 LOG_DIS("subu.%c $r%u, $r%u\n",
1842 cris_cc_mask(dc
, CC_MASK_NZVC
);
1843 t0
= tcg_temp_new();
1844 /* Size can only be qi or hi. */
1845 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1846 cris_alu(dc
, CC_OP_SUB
,
1847 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1851 /* Sign extension. From size to dword. */
1852 static int dec_subs_r(CPUCRISState
*env
, DisasContext
*dc
)
1855 int size
= memsize_z(dc
);
1856 LOG_DIS("subs.%c $r%u, $r%u\n",
1860 cris_cc_mask(dc
, CC_MASK_NZVC
);
1861 t0
= tcg_temp_new();
1862 /* Size can only be qi or hi. */
1863 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1864 cris_alu(dc
, CC_OP_SUB
,
1865 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1869 static int dec_setclrf(CPUCRISState
*env
, DisasContext
*dc
)
1872 int set
= (~dc
->opcode
>> 2) & 1;
1875 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1876 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1877 if (set
&& flags
== 0) {
1880 } else if (!set
&& (flags
& 0x20)) {
1883 LOG_DIS("%sf %x\n", set
? "set" : "clr", flags
);
1886 /* User space is not allowed to touch these. Silently ignore. */
1887 if (dc
->tb_flags
& U_FLAG
) {
1888 flags
&= ~(S_FLAG
| I_FLAG
| U_FLAG
);
1891 if (flags
& X_FLAG
) {
1893 dc
->flags_x
= X_FLAG
;
1899 /* Break the TB if any of the SPI flag changes. */
1900 if (flags
& (P_FLAG
| S_FLAG
)) {
1901 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1902 dc
->base
.is_jmp
= DISAS_UPDATE
;
1903 dc
->cpustate_changed
= 1;
1906 /* For the I flag, only act on posedge. */
1907 if ((flags
& I_FLAG
)) {
1908 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1909 dc
->base
.is_jmp
= DISAS_UPDATE
;
1910 dc
->cpustate_changed
= 1;
1914 /* Simply decode the flags. */
1915 cris_evaluate_flags(dc
);
1916 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1917 cris_update_cc_x(dc
);
1918 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
1921 if (!(dc
->tb_flags
& U_FLAG
) && (flags
& U_FLAG
)) {
1922 /* Enter user mode. */
1923 t_gen_mov_env_TN(ksp
, cpu_R
[R_SP
]);
1924 tcg_gen_mov_tl(cpu_R
[R_SP
], cpu_PR
[PR_USP
]);
1925 dc
->cpustate_changed
= 1;
1927 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], flags
);
1929 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~flags
);
1932 dc
->flags_uptodate
= 1;
1937 static int dec_move_rs(CPUCRISState
*env
, DisasContext
*dc
)
1940 LOG_DIS("move $r%u, $s%u\n", dc
->op1
, dc
->op2
);
1941 c1
= tcg_constant_tl(dc
->op1
);
1942 c2
= tcg_constant_tl(dc
->op2
);
1943 cris_cc_mask(dc
, 0);
1944 gen_helper_movl_sreg_reg(tcg_env
, c2
, c1
);
1947 static int dec_move_sr(CPUCRISState
*env
, DisasContext
*dc
)
1950 LOG_DIS("move $s%u, $r%u\n", dc
->op2
, dc
->op1
);
1951 c1
= tcg_constant_tl(dc
->op1
);
1952 c2
= tcg_constant_tl(dc
->op2
);
1953 cris_cc_mask(dc
, 0);
1954 gen_helper_movl_reg_sreg(tcg_env
, c1
, c2
);
1958 static int dec_move_rp(CPUCRISState
*env
, DisasContext
*dc
)
1961 LOG_DIS("move $r%u, $p%u\n", dc
->op1
, dc
->op2
);
1962 cris_cc_mask(dc
, 0);
1964 t
[0] = tcg_temp_new();
1965 if (dc
->op2
== PR_CCS
) {
1966 cris_evaluate_flags(dc
);
1967 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1968 if (dc
->tb_flags
& U_FLAG
) {
1969 t
[1] = tcg_temp_new();
1970 /* User space is not allowed to touch all flags. */
1971 tcg_gen_andi_tl(t
[0], t
[0], 0x39f);
1972 tcg_gen_andi_tl(t
[1], cpu_PR
[PR_CCS
], ~0x39f);
1973 tcg_gen_or_tl(t
[0], t
[1], t
[0]);
1976 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1979 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[0]);
1980 if (dc
->op2
== PR_CCS
) {
1981 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1982 dc
->flags_uptodate
= 1;
1986 static int dec_move_pr(CPUCRISState
*env
, DisasContext
*dc
)
1989 LOG_DIS("move $p%u, $r%u\n", dc
->op2
, dc
->op1
);
1990 cris_cc_mask(dc
, 0);
1992 if (dc
->op2
== PR_CCS
) {
1993 cris_evaluate_flags(dc
);
1996 if (dc
->op2
== PR_DZ
) {
1997 tcg_gen_movi_tl(cpu_R
[dc
->op1
], 0);
1999 t0
= tcg_temp_new();
2000 t_gen_mov_TN_preg(t0
, dc
->op2
);
2001 cris_alu(dc
, CC_OP_MOVE
,
2002 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
,
2003 preg_sizes
[dc
->op2
]);
2008 static int dec_move_mr(CPUCRISState
*env
, DisasContext
*dc
)
2010 int memsize
= memsize_zz(dc
);
2012 LOG_DIS("move.%c [$r%u%s, $r%u\n",
2013 memsize_char(memsize
),
2014 dc
->op1
, dc
->postinc
? "+]" : "]",
2018 insn_len
= dec_prep_move_m(env
, dc
, 0, 4, cpu_R
[dc
->op2
]);
2019 cris_cc_mask(dc
, CC_MASK_NZ
);
2020 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
2021 cris_update_cc_x(dc
);
2022 cris_update_result(dc
, cpu_R
[dc
->op2
]);
2026 t0
= tcg_temp_new();
2027 insn_len
= dec_prep_move_m(env
, dc
, 0, memsize
, t0
);
2028 cris_cc_mask(dc
, CC_MASK_NZ
);
2029 cris_alu(dc
, CC_OP_MOVE
,
2030 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, memsize
);
2032 do_postinc(dc
, memsize
);
2036 static inline void cris_alu_m_alloc_temps(TCGv
*t
)
2038 t
[0] = tcg_temp_new();
2039 t
[1] = tcg_temp_new();
2042 static int dec_movs_m(CPUCRISState
*env
, DisasContext
*dc
)
2045 int memsize
= memsize_z(dc
);
2047 LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2048 memsize_char(memsize
),
2049 dc
->op1
, dc
->postinc
? "+]" : "]",
2052 cris_alu_m_alloc_temps(t
);
2054 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2055 cris_cc_mask(dc
, CC_MASK_NZ
);
2056 cris_alu(dc
, CC_OP_MOVE
,
2057 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2058 do_postinc(dc
, memsize
);
2062 static int dec_addu_m(CPUCRISState
*env
, DisasContext
*dc
)
2065 int memsize
= memsize_z(dc
);
2067 LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2068 memsize_char(memsize
),
2069 dc
->op1
, dc
->postinc
? "+]" : "]",
2072 cris_alu_m_alloc_temps(t
);
2074 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2075 cris_cc_mask(dc
, CC_MASK_NZVC
);
2076 cris_alu(dc
, CC_OP_ADD
,
2077 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2078 do_postinc(dc
, memsize
);
2082 static int dec_adds_m(CPUCRISState
*env
, DisasContext
*dc
)
2085 int memsize
= memsize_z(dc
);
2087 LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2088 memsize_char(memsize
),
2089 dc
->op1
, dc
->postinc
? "+]" : "]",
2092 cris_alu_m_alloc_temps(t
);
2094 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2095 cris_cc_mask(dc
, CC_MASK_NZVC
);
2096 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2097 do_postinc(dc
, memsize
);
2101 static int dec_subu_m(CPUCRISState
*env
, DisasContext
*dc
)
2104 int memsize
= memsize_z(dc
);
2106 LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2107 memsize_char(memsize
),
2108 dc
->op1
, dc
->postinc
? "+]" : "]",
2111 cris_alu_m_alloc_temps(t
);
2113 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2114 cris_cc_mask(dc
, CC_MASK_NZVC
);
2115 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2116 do_postinc(dc
, memsize
);
2120 static int dec_subs_m(CPUCRISState
*env
, DisasContext
*dc
)
2123 int memsize
= memsize_z(dc
);
2125 LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2126 memsize_char(memsize
),
2127 dc
->op1
, dc
->postinc
? "+]" : "]",
2130 cris_alu_m_alloc_temps(t
);
2132 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2133 cris_cc_mask(dc
, CC_MASK_NZVC
);
2134 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2135 do_postinc(dc
, memsize
);
2139 static int dec_movu_m(CPUCRISState
*env
, DisasContext
*dc
)
2142 int memsize
= memsize_z(dc
);
2145 LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2146 memsize_char(memsize
),
2147 dc
->op1
, dc
->postinc
? "+]" : "]",
2150 cris_alu_m_alloc_temps(t
);
2151 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2152 cris_cc_mask(dc
, CC_MASK_NZ
);
2153 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2154 do_postinc(dc
, memsize
);
2158 static int dec_cmpu_m(CPUCRISState
*env
, DisasContext
*dc
)
2161 int memsize
= memsize_z(dc
);
2163 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2164 memsize_char(memsize
),
2165 dc
->op1
, dc
->postinc
? "+]" : "]",
2168 cris_alu_m_alloc_temps(t
);
2169 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2170 cris_cc_mask(dc
, CC_MASK_NZVC
);
2171 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2172 do_postinc(dc
, memsize
);
2176 static int dec_cmps_m(CPUCRISState
*env
, DisasContext
*dc
)
2179 int memsize
= memsize_z(dc
);
2181 LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2182 memsize_char(memsize
),
2183 dc
->op1
, dc
->postinc
? "+]" : "]",
2186 cris_alu_m_alloc_temps(t
);
2187 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2188 cris_cc_mask(dc
, CC_MASK_NZVC
);
2189 cris_alu(dc
, CC_OP_CMP
,
2190 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2192 do_postinc(dc
, memsize
);
2196 static int dec_cmp_m(CPUCRISState
*env
, DisasContext
*dc
)
2199 int memsize
= memsize_zz(dc
);
2201 LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2202 memsize_char(memsize
),
2203 dc
->op1
, dc
->postinc
? "+]" : "]",
2206 cris_alu_m_alloc_temps(t
);
2207 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2208 cris_cc_mask(dc
, CC_MASK_NZVC
);
2209 cris_alu(dc
, CC_OP_CMP
,
2210 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2212 do_postinc(dc
, memsize
);
2216 static int dec_test_m(CPUCRISState
*env
, DisasContext
*dc
)
2219 int memsize
= memsize_zz(dc
);
2221 LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2222 memsize_char(memsize
),
2223 dc
->op1
, dc
->postinc
? "+]" : "]",
2226 cris_evaluate_flags(dc
);
2228 cris_alu_m_alloc_temps(t
);
2229 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2230 cris_cc_mask(dc
, CC_MASK_NZ
);
2231 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~3);
2233 c
= tcg_constant_tl(0);
2234 cris_alu(dc
, CC_OP_CMP
,
2235 cpu_R
[dc
->op2
], t
[1], c
, memsize_zz(dc
));
2236 do_postinc(dc
, memsize
);
2240 static int dec_and_m(CPUCRISState
*env
, DisasContext
*dc
)
2243 int memsize
= memsize_zz(dc
);
2245 LOG_DIS("and.%c [$r%u%s, $r%u\n",
2246 memsize_char(memsize
),
2247 dc
->op1
, dc
->postinc
? "+]" : "]",
2250 cris_alu_m_alloc_temps(t
);
2251 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2252 cris_cc_mask(dc
, CC_MASK_NZ
);
2253 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2254 do_postinc(dc
, memsize
);
2258 static int dec_add_m(CPUCRISState
*env
, DisasContext
*dc
)
2261 int memsize
= memsize_zz(dc
);
2263 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2264 memsize_char(memsize
),
2265 dc
->op1
, dc
->postinc
? "+]" : "]",
2268 cris_alu_m_alloc_temps(t
);
2269 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2270 cris_cc_mask(dc
, CC_MASK_NZVC
);
2271 cris_alu(dc
, CC_OP_ADD
,
2272 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2273 do_postinc(dc
, memsize
);
2277 static int dec_addo_m(CPUCRISState
*env
, DisasContext
*dc
)
2280 int memsize
= memsize_zz(dc
);
2282 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2283 memsize_char(memsize
),
2284 dc
->op1
, dc
->postinc
? "+]" : "]",
2287 cris_alu_m_alloc_temps(t
);
2288 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2289 cris_cc_mask(dc
, 0);
2290 cris_alu(dc
, CC_OP_ADD
, cpu_R
[R_ACR
], t
[0], t
[1], 4);
2291 do_postinc(dc
, memsize
);
2295 static int dec_bound_m(CPUCRISState
*env
, DisasContext
*dc
)
2298 int memsize
= memsize_zz(dc
);
2300 LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2301 memsize_char(memsize
),
2302 dc
->op1
, dc
->postinc
? "+]" : "]",
2305 l
[0] = tcg_temp_new();
2306 l
[1] = tcg_temp_new();
2307 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, l
[0], l
[1]);
2308 cris_cc_mask(dc
, CC_MASK_NZ
);
2309 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], l
[0], l
[1], 4);
2310 do_postinc(dc
, memsize
);
2314 static int dec_addc_mr(CPUCRISState
*env
, DisasContext
*dc
)
2318 LOG_DIS("addc [$r%u%s, $r%u\n",
2319 dc
->op1
, dc
->postinc
? "+]" : "]",
2322 cris_evaluate_flags(dc
);
2324 /* Set for this insn. */
2325 dc
->flags_x
= X_FLAG
;
2327 cris_alu_m_alloc_temps(t
);
2328 insn_len
= dec_prep_alu_m(env
, dc
, 0, 4, t
[0], t
[1]);
2329 cris_cc_mask(dc
, CC_MASK_NZVC
);
2330 cris_alu(dc
, CC_OP_ADDC
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
2335 static int dec_sub_m(CPUCRISState
*env
, DisasContext
*dc
)
2338 int memsize
= memsize_zz(dc
);
2340 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2341 memsize_char(memsize
),
2342 dc
->op1
, dc
->postinc
? "+]" : "]",
2343 dc
->op2
, dc
->ir
, dc
->zzsize
);
2345 cris_alu_m_alloc_temps(t
);
2346 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2347 cris_cc_mask(dc
, CC_MASK_NZVC
);
2348 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize
);
2349 do_postinc(dc
, memsize
);
2353 static int dec_or_m(CPUCRISState
*env
, DisasContext
*dc
)
2356 int memsize
= memsize_zz(dc
);
2358 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2359 memsize_char(memsize
),
2360 dc
->op1
, dc
->postinc
? "+]" : "]",
2363 cris_alu_m_alloc_temps(t
);
2364 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2365 cris_cc_mask(dc
, CC_MASK_NZ
);
2366 cris_alu(dc
, CC_OP_OR
,
2367 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2368 do_postinc(dc
, memsize
);
2372 static int dec_move_mp(CPUCRISState
*env
, DisasContext
*dc
)
2375 int memsize
= memsize_zz(dc
);
2378 LOG_DIS("move.%c [$r%u%s, $p%u\n",
2379 memsize_char(memsize
),
2381 dc
->postinc
? "+]" : "]",
2384 cris_alu_m_alloc_temps(t
);
2385 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2386 cris_cc_mask(dc
, 0);
2387 if (dc
->op2
== PR_CCS
) {
2388 cris_evaluate_flags(dc
);
2389 if (dc
->tb_flags
& U_FLAG
) {
2390 /* User space is not allowed to touch all flags. */
2391 tcg_gen_andi_tl(t
[1], t
[1], 0x39f);
2392 tcg_gen_andi_tl(t
[0], cpu_PR
[PR_CCS
], ~0x39f);
2393 tcg_gen_or_tl(t
[1], t
[0], t
[1]);
2397 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[1]);
2399 do_postinc(dc
, memsize
);
2403 static int dec_move_pm(CPUCRISState
*env
, DisasContext
*dc
)
2408 memsize
= preg_sizes
[dc
->op2
];
2410 LOG_DIS("move.%c $p%u, [$r%u%s\n",
2411 memsize_char(memsize
),
2412 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]");
2414 /* prepare store. Address in T0, value in T1. */
2415 if (dc
->op2
== PR_CCS
) {
2416 cris_evaluate_flags(dc
);
2418 t0
= tcg_temp_new();
2419 t_gen_mov_TN_preg(t0
, dc
->op2
);
2420 cris_flush_cc_state(dc
);
2421 gen_store(dc
, cpu_R
[dc
->op1
], t0
, memsize
);
2423 cris_cc_mask(dc
, 0);
2425 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2430 static int dec_movem_mr(CPUCRISState
*env
, DisasContext
*dc
)
2436 int nr
= dc
->op2
+ 1;
2438 LOG_DIS("movem [$r%u%s, $r%u\n", dc
->op1
,
2439 dc
->postinc
? "+]" : "]", dc
->op2
);
2441 addr
= tcg_temp_new();
2442 /* There are probably better ways of doing this. */
2443 cris_flush_cc_state(dc
);
2444 for (i
= 0; i
< (nr
>> 1); i
++) {
2445 tmp
[i
] = tcg_temp_new_i64();
2446 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2447 gen_load64(dc
, tmp
[i
], addr
);
2450 tmp32
= tcg_temp_new_i32();
2451 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2452 gen_load(dc
, tmp32
, addr
, 4, 0);
2457 for (i
= 0; i
< (nr
>> 1); i
++) {
2458 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2], tmp
[i
]);
2459 tcg_gen_shri_i64(tmp
[i
], tmp
[i
], 32);
2460 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2 + 1], tmp
[i
]);
2463 tcg_gen_mov_tl(cpu_R
[dc
->op2
], tmp32
);
2466 /* writeback the updated pointer value. */
2468 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], nr
* 4);
2471 /* gen_load might want to evaluate the previous insns flags. */
2472 cris_cc_mask(dc
, 0);
2476 static int dec_movem_rm(CPUCRISState
*env
, DisasContext
*dc
)
2482 LOG_DIS("movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2483 dc
->postinc
? "+]" : "]");
2485 cris_flush_cc_state(dc
);
2487 tmp
= tcg_temp_new();
2488 addr
= tcg_temp_new();
2489 tcg_gen_movi_tl(tmp
, 4);
2490 tcg_gen_mov_tl(addr
, cpu_R
[dc
->op1
]);
2491 for (i
= 0; i
<= dc
->op2
; i
++) {
2492 /* Displace addr. */
2493 /* Perform the store. */
2494 gen_store(dc
, addr
, cpu_R
[i
], 4);
2495 tcg_gen_add_tl(addr
, addr
, tmp
);
2498 tcg_gen_mov_tl(cpu_R
[dc
->op1
], addr
);
2500 cris_cc_mask(dc
, 0);
2504 static int dec_move_rm(CPUCRISState
*env
, DisasContext
*dc
)
2508 memsize
= memsize_zz(dc
);
2510 LOG_DIS("move.%c $r%u, [$r%u]\n",
2511 memsize_char(memsize
), dc
->op2
, dc
->op1
);
2513 /* prepare store. */
2514 cris_flush_cc_state(dc
);
2515 gen_store(dc
, cpu_R
[dc
->op1
], cpu_R
[dc
->op2
], memsize
);
2518 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2520 cris_cc_mask(dc
, 0);
2524 static int dec_lapcq(CPUCRISState
*env
, DisasContext
*dc
)
2526 LOG_DIS("lapcq %x, $r%u\n",
2527 dc
->pc
+ dc
->op1
*2, dc
->op2
);
2528 cris_cc_mask(dc
, 0);
2529 tcg_gen_movi_tl(cpu_R
[dc
->op2
], dc
->pc
+ dc
->op1
* 2);
2533 static int dec_lapc_im(CPUCRISState
*env
, DisasContext
*dc
)
2541 cris_cc_mask(dc
, 0);
2542 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2543 LOG_DIS("lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
);
2547 tcg_gen_movi_tl(cpu_R
[rd
], pc
);
2551 /* Jump to special reg. */
2552 static int dec_jump_p(CPUCRISState
*env
, DisasContext
*dc
)
2554 LOG_DIS("jump $p%u\n", dc
->op2
);
2556 if (dc
->op2
== PR_CCS
) {
2557 cris_evaluate_flags(dc
);
2559 t_gen_mov_TN_preg(env_btarget
, dc
->op2
);
2560 /* rete will often have low bit set to indicate delayslot. */
2561 tcg_gen_andi_tl(env_btarget
, env_btarget
, ~1);
2562 cris_cc_mask(dc
, 0);
2563 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2567 /* Jump and save. */
2568 static int dec_jas_r(CPUCRISState
*env
, DisasContext
*dc
)
2571 LOG_DIS("jas $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2572 cris_cc_mask(dc
, 0);
2573 /* Store the return address in Pd. */
2574 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2578 c
= tcg_constant_tl(dc
->pc
+ 4);
2579 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2581 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2585 static int dec_jas_im(CPUCRISState
*env
, DisasContext
*dc
)
2590 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2592 LOG_DIS("jas 0x%x\n", imm
);
2593 cris_cc_mask(dc
, 0);
2594 c
= tcg_constant_tl(dc
->pc
+ 8);
2595 /* Store the return address in Pd. */
2596 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2599 cris_prepare_jmp(dc
, JMP_DIRECT
);
2603 static int dec_jasc_im(CPUCRISState
*env
, DisasContext
*dc
)
2608 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2610 LOG_DIS("jasc 0x%x\n", imm
);
2611 cris_cc_mask(dc
, 0);
2612 c
= tcg_constant_tl(dc
->pc
+ 8 + 4);
2613 /* Store the return address in Pd. */
2614 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2617 cris_prepare_jmp(dc
, JMP_DIRECT
);
2621 static int dec_jasc_r(CPUCRISState
*env
, DisasContext
*dc
)
2624 LOG_DIS("jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2625 cris_cc_mask(dc
, 0);
2626 /* Store the return address in Pd. */
2627 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2628 c
= tcg_constant_tl(dc
->pc
+ 4 + 4);
2629 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2630 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2634 static int dec_bcc_im(CPUCRISState
*env
, DisasContext
*dc
)
2637 uint32_t cond
= dc
->op2
;
2639 offset
= cris_fetch(env
, dc
, dc
->pc
+ 2, 2, 1);
2641 LOG_DIS("b%s %d pc=%x dst=%x\n",
2642 cc_name(cond
), offset
,
2643 dc
->pc
, dc
->pc
+ offset
);
2645 cris_cc_mask(dc
, 0);
2646 /* op2 holds the condition-code. */
2647 cris_prepare_cc_branch(dc
, offset
, cond
);
2651 static int dec_bas_im(CPUCRISState
*env
, DisasContext
*dc
)
2656 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2658 LOG_DIS("bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2659 cris_cc_mask(dc
, 0);
2660 c
= tcg_constant_tl(dc
->pc
+ 8);
2661 /* Store the return address in Pd. */
2662 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2664 dc
->jmp_pc
= dc
->pc
+ simm
;
2665 cris_prepare_jmp(dc
, JMP_DIRECT
);
2669 static int dec_basc_im(CPUCRISState
*env
, DisasContext
*dc
)
2673 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2675 LOG_DIS("basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2676 cris_cc_mask(dc
, 0);
2677 c
= tcg_constant_tl(dc
->pc
+ 12);
2678 /* Store the return address in Pd. */
2679 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2681 dc
->jmp_pc
= dc
->pc
+ simm
;
2682 cris_prepare_jmp(dc
, JMP_DIRECT
);
2686 static int dec_rfe_etc(CPUCRISState
*env
, DisasContext
*dc
)
2688 cris_cc_mask(dc
, 0);
2690 if (dc
->op2
== 15) {
2691 tcg_gen_st_i32(tcg_constant_i32(1), tcg_env
,
2692 -offsetof(CRISCPU
, env
) + offsetof(CPUState
, halted
));
2693 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2694 t_gen_raise_exception(EXCP_HLT
);
2695 dc
->base
.is_jmp
= DISAS_NORETURN
;
2699 switch (dc
->op2
& 7) {
2703 cris_evaluate_flags(dc
);
2704 gen_helper_rfe(tcg_env
);
2705 dc
->base
.is_jmp
= DISAS_UPDATE
;
2706 dc
->cpustate_changed
= true;
2711 cris_evaluate_flags(dc
);
2712 gen_helper_rfn(tcg_env
);
2713 dc
->base
.is_jmp
= DISAS_UPDATE
;
2714 dc
->cpustate_changed
= true;
2717 LOG_DIS("break %d\n", dc
->op1
);
2718 cris_evaluate_flags(dc
);
2720 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2722 /* Breaks start at 16 in the exception vector. */
2723 t_gen_movi_env_TN(trap_vector
, dc
->op1
+ 16);
2724 t_gen_raise_exception(EXCP_BREAK
);
2725 dc
->base
.is_jmp
= DISAS_NORETURN
;
2728 printf("op2=%x\n", dc
->op2
);
2736 static int dec_ftag_fidx_d_m(CPUCRISState
*env
, DisasContext
*dc
)
2741 static int dec_ftag_fidx_i_m(CPUCRISState
*env
, DisasContext
*dc
)
2746 static int dec_null(CPUCRISState
*env
, DisasContext
*dc
)
2748 printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2749 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2755 static const struct decoder_info
{
2760 int (*dec
)(CPUCRISState
*env
, DisasContext
*dc
);
2762 /* Order matters here. */
2763 {DEC_MOVEQ
, dec_moveq
},
2764 {DEC_BTSTQ
, dec_btstq
},
2765 {DEC_CMPQ
, dec_cmpq
},
2766 {DEC_ADDOQ
, dec_addoq
},
2767 {DEC_ADDQ
, dec_addq
},
2768 {DEC_SUBQ
, dec_subq
},
2769 {DEC_ANDQ
, dec_andq
},
2771 {DEC_ASRQ
, dec_asrq
},
2772 {DEC_LSLQ
, dec_lslq
},
2773 {DEC_LSRQ
, dec_lsrq
},
2774 {DEC_BCCQ
, dec_bccq
},
2776 {DEC_BCC_IM
, dec_bcc_im
},
2777 {DEC_JAS_IM
, dec_jas_im
},
2778 {DEC_JAS_R
, dec_jas_r
},
2779 {DEC_JASC_IM
, dec_jasc_im
},
2780 {DEC_JASC_R
, dec_jasc_r
},
2781 {DEC_BAS_IM
, dec_bas_im
},
2782 {DEC_BASC_IM
, dec_basc_im
},
2783 {DEC_JUMP_P
, dec_jump_p
},
2784 {DEC_LAPC_IM
, dec_lapc_im
},
2785 {DEC_LAPCQ
, dec_lapcq
},
2787 {DEC_RFE_ETC
, dec_rfe_etc
},
2788 {DEC_ADDC_MR
, dec_addc_mr
},
2790 {DEC_MOVE_MP
, dec_move_mp
},
2791 {DEC_MOVE_PM
, dec_move_pm
},
2792 {DEC_MOVEM_MR
, dec_movem_mr
},
2793 {DEC_MOVEM_RM
, dec_movem_rm
},
2794 {DEC_MOVE_PR
, dec_move_pr
},
2795 {DEC_SCC_R
, dec_scc_r
},
2796 {DEC_SETF
, dec_setclrf
},
2797 {DEC_CLEARF
, dec_setclrf
},
2799 {DEC_MOVE_SR
, dec_move_sr
},
2800 {DEC_MOVE_RP
, dec_move_rp
},
2801 {DEC_SWAP_R
, dec_swap_r
},
2802 {DEC_ABS_R
, dec_abs_r
},
2803 {DEC_LZ_R
, dec_lz_r
},
2804 {DEC_MOVE_RS
, dec_move_rs
},
2805 {DEC_BTST_R
, dec_btst_r
},
2806 {DEC_ADDC_R
, dec_addc_r
},
2808 {DEC_DSTEP_R
, dec_dstep_r
},
2809 {DEC_XOR_R
, dec_xor_r
},
2810 {DEC_MCP_R
, dec_mcp_r
},
2811 {DEC_CMP_R
, dec_cmp_r
},
2813 {DEC_ADDI_R
, dec_addi_r
},
2814 {DEC_ADDI_ACR
, dec_addi_acr
},
2816 {DEC_ADD_R
, dec_add_r
},
2817 {DEC_SUB_R
, dec_sub_r
},
2819 {DEC_ADDU_R
, dec_addu_r
},
2820 {DEC_ADDS_R
, dec_adds_r
},
2821 {DEC_SUBU_R
, dec_subu_r
},
2822 {DEC_SUBS_R
, dec_subs_r
},
2823 {DEC_LSL_R
, dec_lsl_r
},
2825 {DEC_AND_R
, dec_and_r
},
2826 {DEC_OR_R
, dec_or_r
},
2827 {DEC_BOUND_R
, dec_bound_r
},
2828 {DEC_ASR_R
, dec_asr_r
},
2829 {DEC_LSR_R
, dec_lsr_r
},
2831 {DEC_MOVU_R
, dec_movu_r
},
2832 {DEC_MOVS_R
, dec_movs_r
},
2833 {DEC_NEG_R
, dec_neg_r
},
2834 {DEC_MOVE_R
, dec_move_r
},
2836 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2837 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2839 {DEC_MULS_R
, dec_muls_r
},
2840 {DEC_MULU_R
, dec_mulu_r
},
2842 {DEC_ADDU_M
, dec_addu_m
},
2843 {DEC_ADDS_M
, dec_adds_m
},
2844 {DEC_SUBU_M
, dec_subu_m
},
2845 {DEC_SUBS_M
, dec_subs_m
},
2847 {DEC_CMPU_M
, dec_cmpu_m
},
2848 {DEC_CMPS_M
, dec_cmps_m
},
2849 {DEC_MOVU_M
, dec_movu_m
},
2850 {DEC_MOVS_M
, dec_movs_m
},
2852 {DEC_CMP_M
, dec_cmp_m
},
2853 {DEC_ADDO_M
, dec_addo_m
},
2854 {DEC_BOUND_M
, dec_bound_m
},
2855 {DEC_ADD_M
, dec_add_m
},
2856 {DEC_SUB_M
, dec_sub_m
},
2857 {DEC_AND_M
, dec_and_m
},
2858 {DEC_OR_M
, dec_or_m
},
2859 {DEC_MOVE_RM
, dec_move_rm
},
2860 {DEC_TEST_M
, dec_test_m
},
2861 {DEC_MOVE_MR
, dec_move_mr
},
2866 static unsigned int crisv32_decoder(CPUCRISState
*env
, DisasContext
*dc
)
2871 /* Load a halfword onto the instruction register. */
2872 dc
->ir
= cris_fetch(env
, dc
, dc
->pc
, 2, 0);
2874 /* Now decode it. */
2875 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2876 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2877 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2878 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2879 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2880 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2882 /* Large switch for all insns. */
2883 for (i
= 0; i
< ARRAY_SIZE(decinfo
); i
++) {
2884 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
) {
2885 insn_len
= decinfo
[i
].dec(env
, dc
);
2890 #if !defined(CONFIG_USER_ONLY)
2891 /* Single-stepping ? */
2892 if (dc
->tb_flags
& S_FLAG
) {
2893 TCGLabel
*l1
= gen_new_label();
2894 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_PR
[PR_SPC
], dc
->pc
, l1
);
2895 /* We treat SPC as a break with an odd trap vector. */
2896 cris_evaluate_flags(dc
);
2897 t_gen_movi_env_TN(trap_vector
, 3);
2898 tcg_gen_movi_tl(env_pc
, dc
->pc
+ insn_len
);
2899 tcg_gen_movi_tl(cpu_PR
[PR_SPC
], dc
->pc
+ insn_len
);
2900 t_gen_raise_exception(EXCP_BREAK
);
2907 #include "translate_v10.c.inc"
2910 * Delay slots on QEMU/CRIS.
2912 * If an exception hits on a delayslot, the core will let ERP (the Exception
2913 * Return Pointer) point to the branch (the previous) insn and set the lsb to
2914 * to give SW a hint that the exception actually hit on the dslot.
2916 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
2917 * the core and any jmp to an odd addresses will mask off that lsb. It is
2918 * simply there to let sw know there was an exception on a dslot.
2920 * When the software returns from an exception, the branch will re-execute.
2921 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
2922 * and the branch and delayslot don't share pages.
2924 * The TB containing the branch insn will set up env->btarget and evaluate
2925 * env->btaken. When the translation loop exits we will note that the branch
2926 * sequence is broken and let env->dslot be the size of the branch insn (those
2929 * The TB containing the delayslot will have the PC of its real insn (i.e no lsb
2930 * set). It will also expect to have env->dslot setup with the size of the
2931 * delay slot so that env->pc - env->dslot point to the branch insn. This TB
2932 * will execute the dslot and take the branch, either to btarget or just one
2935 * When exceptions occur, we check for env->dslot in do_interrupt to detect
2936 * broken branch sequences and setup $erp accordingly (i.e let it point to the
2937 * branch and set lsb). Then env->dslot gets cleared so that the exception
2938 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
2939 * masked off and we will reexecute the branch insn.
2943 static void cris_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2945 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2946 CPUCRISState
*env
= cpu_env(cs
);
2947 uint32_t tb_flags
= dc
->base
.tb
->flags
;
2950 if (env
->pregs
[PR_VR
] == 32) {
2951 dc
->decoder
= crisv32_decoder
;
2952 dc
->clear_locked_irq
= 0;
2954 dc
->decoder
= crisv10_decoder
;
2955 dc
->clear_locked_irq
= 1;
2959 * Odd PC indicates that branch is rexecuting due to exception in the
2960 * delayslot, like in real hw.
2962 pc_start
= dc
->base
.pc_first
& ~1;
2963 dc
->base
.pc_first
= pc_start
;
2964 dc
->base
.pc_next
= pc_start
;
2966 dc
->cpu
= env_archcpu(env
);
2969 dc
->mem_index
= cpu_mmu_index(cs
, false);
2970 dc
->flags_uptodate
= 1;
2971 dc
->flags_x
= tb_flags
& X_FLAG
;
2972 dc
->cc_x_uptodate
= 0;
2975 dc
->clear_prefix
= 0;
2976 dc
->cpustate_changed
= 0;
2978 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
2979 dc
->cc_size_uptodate
= -1;
2981 /* Decode TB flags. */
2982 dc
->tb_flags
= tb_flags
& (S_FLAG
| P_FLAG
| U_FLAG
| X_FLAG
| PFIX_FLAG
);
2983 dc
->delayed_branch
= !!(tb_flags
& 7);
2984 if (dc
->delayed_branch
) {
2985 dc
->jmp
= JMP_INDIRECT
;
2987 dc
->jmp
= JMP_NOJMP
;
2991 static void cris_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
2995 static void cris_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
2997 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2999 tcg_gen_insn_start(dc
->delayed_branch
== 1 ? dc
->ppc
| 1 : dc
->pc
);
3002 static void cris_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
3004 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3005 unsigned int insn_len
;
3008 LOG_DIS("%8.8x:\t", dc
->pc
);
3012 insn_len
= dc
->decoder(cpu_env(cs
), dc
);
3015 dc
->base
.pc_next
+= insn_len
;
3017 if (dc
->base
.is_jmp
== DISAS_NORETURN
) {
3022 cris_clear_x_flag(dc
);
3026 * All branches are delayed branches, handled immediately below.
3027 * We don't expect to see odd combinations of exit conditions.
3029 assert(dc
->base
.is_jmp
== DISAS_NEXT
|| dc
->cpustate_changed
);
3031 if (dc
->delayed_branch
&& --dc
->delayed_branch
== 0) {
3032 dc
->base
.is_jmp
= DISAS_DBRANCH
;
3036 if (dc
->base
.is_jmp
!= DISAS_NEXT
) {
3040 /* Force an update if the per-tb cpu state has changed. */
3041 if (dc
->cpustate_changed
) {
3042 dc
->base
.is_jmp
= DISAS_UPDATE_NEXT
;
3047 * FIXME: Only the first insn in the TB should cross a page boundary.
3048 * If we can detect the length of the next insn easily, we should.
3049 * In the meantime, simply stop when we do cross.
3051 if ((dc
->pc
^ dc
->base
.pc_first
) & TARGET_PAGE_MASK
) {
3052 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
3056 static void cris_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
3058 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3059 DisasJumpType is_jmp
= dc
->base
.is_jmp
;
3060 target_ulong npc
= dc
->pc
;
3062 if (is_jmp
== DISAS_NORETURN
) {
3063 /* If we have a broken branch+delayslot sequence, it's too late. */
3064 assert(dc
->delayed_branch
!= 1);
3068 if (dc
->clear_locked_irq
) {
3069 t_gen_movi_env_TN(locked_irq
, 0);
3072 /* Broken branch+delayslot sequence. */
3073 if (dc
->delayed_branch
== 1) {
3074 /* Set env->dslot to the size of the branch insn. */
3075 t_gen_movi_env_TN(dslot
, dc
->pc
- dc
->ppc
);
3076 cris_store_direct_jmp(dc
);
3079 cris_evaluate_flags(dc
);
3081 /* Evaluate delayed branch destination and fold to another is_jmp case. */
3082 if (is_jmp
== DISAS_DBRANCH
) {
3083 if (dc
->base
.tb
->flags
& 7) {
3084 t_gen_movi_env_TN(dslot
, 0);
3090 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE_NEXT
: DISAS_TOO_MANY
;
3095 * Use a conditional branch if either taken or not-taken path
3096 * can use goto_tb. If neither can, then treat it as indirect.
3098 if (likely(!dc
->cpustate_changed
)
3099 && (use_goto_tb(dc
, dc
->jmp_pc
) || use_goto_tb(dc
, npc
))) {
3100 TCGLabel
*not_taken
= gen_new_label();
3102 tcg_gen_brcondi_tl(TCG_COND_EQ
, env_btaken
, 0, not_taken
);
3103 gen_goto_tb(dc
, 1, dc
->jmp_pc
);
3104 gen_set_label(not_taken
);
3106 /* not-taken case handled below. */
3107 is_jmp
= DISAS_TOO_MANY
;
3110 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
3114 tcg_gen_movcond_tl(TCG_COND_NE
, env_pc
,
3115 env_btaken
, tcg_constant_tl(0),
3116 env_btarget
, tcg_constant_tl(npc
));
3117 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE
: DISAS_JUMP
;
3120 * We have now consumed btaken and btarget. Hint to the
3121 * tcg compiler that the writeback to env may be dropped.
3123 tcg_gen_discard_tl(env_btaken
);
3124 tcg_gen_discard_tl(env_btarget
);
3128 g_assert_not_reached();
3133 case DISAS_TOO_MANY
:
3134 gen_goto_tb(dc
, 0, npc
);
3136 case DISAS_UPDATE_NEXT
:
3137 tcg_gen_movi_tl(env_pc
, npc
);
3140 tcg_gen_lookup_and_goto_ptr();
3143 /* Indicate that interrupts must be re-evaluated before the next TB. */
3144 tcg_gen_exit_tb(NULL
, 0);
3147 g_assert_not_reached();
3151 static void cris_tr_disas_log(const DisasContextBase
*dcbase
,
3152 CPUState
*cpu
, FILE *logfile
)
3155 fprintf(logfile
, "IN: %s\n", lookup_symbol(dcbase
->pc_first
));
3156 target_disas(logfile
, cpu
, dcbase
->pc_first
, dcbase
->tb
->size
);
3160 static const TranslatorOps cris_tr_ops
= {
3161 .init_disas_context
= cris_tr_init_disas_context
,
3162 .tb_start
= cris_tr_tb_start
,
3163 .insn_start
= cris_tr_insn_start
,
3164 .translate_insn
= cris_tr_translate_insn
,
3165 .tb_stop
= cris_tr_tb_stop
,
3166 .disas_log
= cris_tr_disas_log
,
3169 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int *max_insns
,
3170 vaddr pc
, void *host_pc
)
3173 translator_loop(cs
, tb
, max_insns
, pc
, host_pc
, &cris_tr_ops
, &dc
.base
);
3176 void cris_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
3178 CPUCRISState
*env
= cpu_env(cs
);
3179 const char * const *regnames
;
3180 const char * const *pregnames
;
3186 if (env
->pregs
[PR_VR
] < 32) {
3187 pregnames
= pregnames_v10
;
3188 regnames
= regnames_v10
;
3190 pregnames
= pregnames_v32
;
3191 regnames
= regnames_v32
;
3194 qemu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3195 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3196 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
3198 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
);
3201 for (i
= 0; i
< 16; i
++) {
3202 qemu_fprintf(f
, "%s=%8.8x ", regnames
[i
], env
->regs
[i
]);
3203 if ((i
+ 1) % 4 == 0) {
3204 qemu_fprintf(f
, "\n");
3207 qemu_fprintf(f
, "\nspecial regs:\n");
3208 for (i
= 0; i
< 16; i
++) {
3209 qemu_fprintf(f
, "%s=%8.8x ", pregnames
[i
], env
->pregs
[i
]);
3210 if ((i
+ 1) % 4 == 0) {
3211 qemu_fprintf(f
, "\n");
3214 if (env
->pregs
[PR_VR
] >= 32) {
3215 uint32_t srs
= env
->pregs
[PR_SRS
];
3216 qemu_fprintf(f
, "\nsupport function regs bank %x:\n", srs
);
3217 if (srs
< ARRAY_SIZE(env
->sregs
)) {
3218 for (i
= 0; i
< 16; i
++) {
3219 qemu_fprintf(f
, "s%2.2d=%8.8x ",
3220 i
, env
->sregs
[srs
][i
]);
3221 if ((i
+ 1) % 4 == 0) {
3222 qemu_fprintf(f
, "\n");
3227 qemu_fprintf(f
, "\n\n");
3231 void cris_initialize_tcg(void)
3235 cc_x
= tcg_global_mem_new(tcg_env
,
3236 offsetof(CPUCRISState
, cc_x
), "cc_x");
3237 cc_src
= tcg_global_mem_new(tcg_env
,
3238 offsetof(CPUCRISState
, cc_src
), "cc_src");
3239 cc_dest
= tcg_global_mem_new(tcg_env
,
3240 offsetof(CPUCRISState
, cc_dest
),
3242 cc_result
= tcg_global_mem_new(tcg_env
,
3243 offsetof(CPUCRISState
, cc_result
),
3245 cc_op
= tcg_global_mem_new(tcg_env
,
3246 offsetof(CPUCRISState
, cc_op
), "cc_op");
3247 cc_size
= tcg_global_mem_new(tcg_env
,
3248 offsetof(CPUCRISState
, cc_size
),
3250 cc_mask
= tcg_global_mem_new(tcg_env
,
3251 offsetof(CPUCRISState
, cc_mask
),
3254 env_pc
= tcg_global_mem_new(tcg_env
,
3255 offsetof(CPUCRISState
, pc
),
3257 env_btarget
= tcg_global_mem_new(tcg_env
,
3258 offsetof(CPUCRISState
, btarget
),
3260 env_btaken
= tcg_global_mem_new(tcg_env
,
3261 offsetof(CPUCRISState
, btaken
),
3263 for (i
= 0; i
< 16; i
++) {
3264 cpu_R
[i
] = tcg_global_mem_new(tcg_env
,
3265 offsetof(CPUCRISState
, regs
[i
]),
3268 for (i
= 0; i
< 16; i
++) {
3269 cpu_PR
[i
] = tcg_global_mem_new(tcg_env
,
3270 offsetof(CPUCRISState
, pregs
[i
]),