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 "exec/exec-all.h"
29 #include "tcg/tcg-op.h"
30 #include "exec/helper-proto.h"
32 #include "exec/translator.h"
33 #include "crisv32-decode.h"
34 #include "qemu/qemu-print.h"
35 #include "exec/helper-gen.h"
38 #define HELPER_H "helper.h"
39 #include "exec/helper-info.c.inc"
45 # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
47 # define LOG_DIS(...) do { } while (0)
51 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52 #define BUG_ON(x) ({if (x) BUG();})
55 * Target-specific is_jmp field values
57 /* Only pc was modified dynamically */
58 #define DISAS_JUMP DISAS_TARGET_0
59 /* Cpu state was modified dynamically, including pc */
60 #define DISAS_UPDATE DISAS_TARGET_1
61 /* Cpu state was modified dynamically, excluding pc -- use npc */
62 #define DISAS_UPDATE_NEXT DISAS_TARGET_2
63 /* PC update for delayed branch, see cpustate_changed otherwise */
64 #define DISAS_DBRANCH DISAS_TARGET_3
66 /* Used by the decoder. */
67 #define EXTRACT_FIELD(src, start, end) \
68 (((src) >> start) & ((1 << (end - start + 1)) - 1))
70 #define CC_MASK_NZ 0xc
71 #define CC_MASK_NZV 0xe
72 #define CC_MASK_NZVC 0xf
73 #define CC_MASK_RNZV 0x10e
75 static TCGv cpu_R
[16];
76 static TCGv cpu_PR
[16];
80 static TCGv cc_result
;
85 static TCGv env_btaken
;
86 static TCGv env_btarget
;
89 /* This is the state at translation time. */
90 typedef struct DisasContext
{
91 DisasContextBase base
;
98 unsigned int (*decoder
)(CPUCRISState
*env
, struct DisasContext
*dc
);
103 unsigned int zsize
, zzsize
;
105 unsigned int postinc
;
117 int cc_size_uptodate
; /* -1 invalid or last written value. */
119 int cc_x_uptodate
; /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date. */
120 int flags_uptodate
; /* Whether or not $ccs is up-to-date. */
123 int clear_x
; /* Clear x after this insn? */
124 int clear_prefix
; /* Clear prefix after this insn? */
125 int clear_locked_irq
; /* Clear the irq lockout. */
126 int cpustate_changed
;
127 unsigned int tb_flags
; /* tb dependent flags. */
131 #define JMP_DIRECT_CC 2
132 #define JMP_INDIRECT 3
133 int jmp
; /* 0=nojmp, 1=direct, 2=indirect. */
139 static void gen_BUG(DisasContext
*dc
, const char *file
, int line
)
141 cpu_abort(CPU(dc
->cpu
), "%s:%d pc=%x\n", file
, line
, dc
->pc
);
144 static const char * const regnames_v32
[] =
146 "$r0", "$r1", "$r2", "$r3",
147 "$r4", "$r5", "$r6", "$r7",
148 "$r8", "$r9", "$r10", "$r11",
149 "$r12", "$r13", "$sp", "$acr",
152 static const char * const pregnames_v32
[] =
154 "$bz", "$vr", "$pid", "$srs",
155 "$wz", "$exs", "$eda", "$mof",
156 "$dz", "$ebp", "$erp", "$srp",
157 "$nrp", "$ccs", "$usp", "$spc",
160 /* We need this table to handle preg-moves with implicit width. */
161 static const int preg_sizes
[] = {
172 #define t_gen_mov_TN_env(tn, member) \
173 tcg_gen_ld_tl(tn, tcg_env, offsetof(CPUCRISState, member))
174 #define t_gen_mov_env_TN(member, tn) \
175 tcg_gen_st_tl(tn, tcg_env, offsetof(CPUCRISState, member))
176 #define t_gen_movi_env_TN(member, c) \
177 t_gen_mov_env_TN(member, tcg_constant_tl(c))
179 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
181 assert(r
>= 0 && r
<= 15);
182 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
183 tcg_gen_movi_tl(tn
, 0);
184 } else if (r
== PR_VR
) {
185 tcg_gen_movi_tl(tn
, 32);
187 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
190 static inline void t_gen_mov_preg_TN(DisasContext
*dc
, int r
, TCGv tn
)
192 assert(r
>= 0 && r
<= 15);
193 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
) {
195 } else if (r
== PR_SRS
) {
196 tcg_gen_andi_tl(cpu_PR
[r
], tn
, 3);
199 gen_helper_tlb_flush_pid(tcg_env
, tn
);
201 if (dc
->tb_flags
& S_FLAG
&& r
== PR_SPC
) {
202 gen_helper_spc_write(tcg_env
, tn
);
203 } else if (r
== PR_CCS
) {
204 dc
->cpustate_changed
= 1;
206 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
210 /* Sign extend at translation time. */
211 static int sign_extend(unsigned int val
, unsigned int width
)
223 static int cris_fetch(CPUCRISState
*env
, DisasContext
*dc
, uint32_t addr
,
224 unsigned int size
, bool sign
)
230 r
= translator_ldl(env
, &dc
->base
, addr
);
233 r
= translator_lduw(env
, &dc
->base
, addr
);
239 r
= translator_ldub(env
, &dc
->base
, addr
);
245 g_assert_not_reached();
250 static void cris_lock_irq(DisasContext
*dc
)
252 dc
->clear_locked_irq
= 0;
253 t_gen_movi_env_TN(locked_irq
, 1);
256 static inline void t_gen_raise_exception(uint32_t index
)
258 gen_helper_raise_exception(tcg_env
, tcg_constant_i32(index
));
261 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
266 t_31
= tcg_constant_tl(31);
267 tcg_gen_shl_tl(d
, a
, b
);
269 tcg_gen_sub_tl(t0
, t_31
, b
);
270 tcg_gen_sar_tl(t0
, t0
, t_31
);
271 tcg_gen_and_tl(t0
, t0
, d
);
272 tcg_gen_xor_tl(d
, d
, t0
);
275 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
280 t_31
= tcg_temp_new();
281 tcg_gen_shr_tl(d
, a
, b
);
283 tcg_gen_movi_tl(t_31
, 31);
284 tcg_gen_sub_tl(t0
, t_31
, b
);
285 tcg_gen_sar_tl(t0
, t0
, t_31
);
286 tcg_gen_and_tl(t0
, t0
, d
);
287 tcg_gen_xor_tl(d
, d
, t0
);
290 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
295 t_31
= tcg_temp_new();
296 tcg_gen_sar_tl(d
, a
, b
);
298 tcg_gen_movi_tl(t_31
, 31);
299 tcg_gen_sub_tl(t0
, t_31
, b
);
300 tcg_gen_sar_tl(t0
, t0
, t_31
);
301 tcg_gen_or_tl(d
, d
, t0
);
304 static void t_gen_cris_dstep(TCGv d
, TCGv a
, TCGv b
)
306 TCGv t
= tcg_temp_new();
313 tcg_gen_shli_tl(d
, a
, 1);
314 tcg_gen_sub_tl(t
, d
, b
);
315 tcg_gen_movcond_tl(TCG_COND_GEU
, d
, d
, b
, t
, d
);
318 static void t_gen_cris_mstep(TCGv d
, TCGv a
, TCGv b
, TCGv ccs
)
328 tcg_gen_shli_tl(d
, a
, 1);
329 tcg_gen_shli_tl(t
, ccs
, 31 - 3);
330 tcg_gen_sari_tl(t
, t
, 31);
331 tcg_gen_and_tl(t
, t
, b
);
332 tcg_gen_add_tl(d
, d
, t
);
335 /* Extended arithmetic on CRIS. */
336 static inline void t_gen_add_flag(TCGv d
, int flag
)
341 t_gen_mov_TN_preg(c
, PR_CCS
);
342 /* Propagate carry into d. */
343 tcg_gen_andi_tl(c
, c
, 1 << flag
);
345 tcg_gen_shri_tl(c
, c
, flag
);
347 tcg_gen_add_tl(d
, d
, c
);
350 static inline void t_gen_addx_carry(DisasContext
*dc
, TCGv d
)
353 TCGv c
= tcg_temp_new();
355 t_gen_mov_TN_preg(c
, PR_CCS
);
356 /* C flag is already at bit 0. */
357 tcg_gen_andi_tl(c
, c
, C_FLAG
);
358 tcg_gen_add_tl(d
, d
, c
);
362 static inline void t_gen_subx_carry(DisasContext
*dc
, TCGv d
)
365 TCGv c
= tcg_temp_new();
367 t_gen_mov_TN_preg(c
, PR_CCS
);
368 /* C flag is already at bit 0. */
369 tcg_gen_andi_tl(c
, c
, C_FLAG
);
370 tcg_gen_sub_tl(d
, d
, c
);
374 /* Swap the two bytes within each half word of the s operand.
375 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
376 static inline void t_gen_swapb(TCGv d
, TCGv s
)
381 org_s
= tcg_temp_new();
383 /* d and s may refer to the same object. */
384 tcg_gen_mov_tl(org_s
, s
);
385 tcg_gen_shli_tl(t
, org_s
, 8);
386 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
387 tcg_gen_shri_tl(t
, org_s
, 8);
388 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
389 tcg_gen_or_tl(d
, d
, t
);
392 /* Swap the halfwords of the s operand. */
393 static inline void t_gen_swapw(TCGv d
, TCGv s
)
396 /* d and s refer the same object. */
398 tcg_gen_mov_tl(t
, s
);
399 tcg_gen_shli_tl(d
, t
, 16);
400 tcg_gen_shri_tl(t
, t
, 16);
401 tcg_gen_or_tl(d
, d
, t
);
405 * Reverse the bits within each byte.
407 * T0 = ((T0 << 7) & 0x80808080)
408 * | ((T0 << 5) & 0x40404040)
409 * | ((T0 << 3) & 0x20202020)
410 * | ((T0 << 1) & 0x10101010)
411 * | ((T0 >> 1) & 0x08080808)
412 * | ((T0 >> 3) & 0x04040404)
413 * | ((T0 >> 5) & 0x02020202)
414 * | ((T0 >> 7) & 0x01010101);
416 static void t_gen_swapr(TCGv d
, TCGv s
)
418 static const struct {
419 int shift
; /* LSL when positive, LSR when negative. */
434 /* d and s refer the same object. */
436 org_s
= tcg_temp_new();
437 tcg_gen_mov_tl(org_s
, s
);
439 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
440 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
441 for (i
= 1; i
< ARRAY_SIZE(bitrev
); i
++) {
442 if (bitrev
[i
].shift
>= 0) {
443 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
445 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
447 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
448 tcg_gen_or_tl(d
, d
, t
);
452 static bool use_goto_tb(DisasContext
*dc
, target_ulong dest
)
454 return translator_use_goto_tb(&dc
->base
, dest
);
457 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
459 if (use_goto_tb(dc
, dest
)) {
461 tcg_gen_movi_tl(env_pc
, dest
);
462 tcg_gen_exit_tb(dc
->base
.tb
, n
);
464 tcg_gen_movi_tl(env_pc
, dest
);
465 tcg_gen_lookup_and_goto_ptr();
469 static inline void cris_clear_x_flag(DisasContext
*dc
)
472 dc
->flags_uptodate
= 0;
477 static void cris_flush_cc_state(DisasContext
*dc
)
479 if (dc
->cc_size_uptodate
!= dc
->cc_size
) {
480 tcg_gen_movi_tl(cc_size
, dc
->cc_size
);
481 dc
->cc_size_uptodate
= dc
->cc_size
;
483 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
484 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
487 static void cris_evaluate_flags(DisasContext
*dc
)
489 if (dc
->flags_uptodate
) {
493 cris_flush_cc_state(dc
);
497 gen_helper_evaluate_flags_mcp(cpu_PR
[PR_CCS
], tcg_env
,
498 cpu_PR
[PR_CCS
], cc_src
,
502 gen_helper_evaluate_flags_muls(cpu_PR
[PR_CCS
], tcg_env
,
503 cpu_PR
[PR_CCS
], cc_result
,
507 gen_helper_evaluate_flags_mulu(cpu_PR
[PR_CCS
], tcg_env
,
508 cpu_PR
[PR_CCS
], cc_result
,
518 switch (dc
->cc_size
) {
520 gen_helper_evaluate_flags_move_4(cpu_PR
[PR_CCS
],
521 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
524 gen_helper_evaluate_flags_move_2(cpu_PR
[PR_CCS
],
525 tcg_env
, cpu_PR
[PR_CCS
], cc_result
);
528 gen_helper_evaluate_flags(tcg_env
);
537 if (dc
->cc_size
== 4) {
538 gen_helper_evaluate_flags_sub_4(cpu_PR
[PR_CCS
], tcg_env
,
539 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
541 gen_helper_evaluate_flags(tcg_env
);
546 switch (dc
->cc_size
) {
548 gen_helper_evaluate_flags_alu_4(cpu_PR
[PR_CCS
], tcg_env
,
549 cpu_PR
[PR_CCS
], cc_src
, cc_dest
, cc_result
);
552 gen_helper_evaluate_flags(tcg_env
);
559 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], X_FLAG
);
560 } else if (dc
->cc_op
== CC_OP_FLAGS
) {
561 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~X_FLAG
);
563 dc
->flags_uptodate
= 1;
566 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
575 /* Check if we need to evaluate the condition codes due to
577 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
579 /* TODO: optimize this case. It trigs all the time. */
580 cris_evaluate_flags(dc
);
586 static void cris_update_cc_op(DisasContext
*dc
, int op
, int size
)
590 dc
->flags_uptodate
= 0;
593 static inline void cris_update_cc_x(DisasContext
*dc
)
595 /* Save the x flag state at the time of the cc snapshot. */
596 if (dc
->cc_x_uptodate
== (2 | dc
->flags_x
)) {
599 tcg_gen_movi_tl(cc_x
, dc
->flags_x
);
600 dc
->cc_x_uptodate
= 2 | dc
->flags_x
;
603 /* Update cc prior to executing ALU op. Needs source operands untouched. */
604 static void cris_pre_alu_update_cc(DisasContext
*dc
, int op
,
605 TCGv dst
, TCGv src
, int size
)
608 cris_update_cc_op(dc
, op
, size
);
609 tcg_gen_mov_tl(cc_src
, src
);
617 && op
!= CC_OP_LSL
) {
618 tcg_gen_mov_tl(cc_dest
, dst
);
621 cris_update_cc_x(dc
);
625 /* Update cc after executing ALU op. needs the result. */
626 static inline void cris_update_result(DisasContext
*dc
, TCGv res
)
629 tcg_gen_mov_tl(cc_result
, res
);
633 /* Returns one if the write back stage should execute. */
634 static void cris_alu_op_exec(DisasContext
*dc
, int op
,
635 TCGv dst
, TCGv a
, TCGv b
, int size
)
637 /* Emit the ALU insns. */
640 tcg_gen_add_tl(dst
, a
, b
);
641 /* Extended arithmetic. */
642 t_gen_addx_carry(dc
, dst
);
645 tcg_gen_add_tl(dst
, a
, b
);
646 t_gen_add_flag(dst
, 0); /* C_FLAG. */
649 tcg_gen_add_tl(dst
, a
, b
);
650 t_gen_add_flag(dst
, 8); /* R_FLAG. */
653 tcg_gen_sub_tl(dst
, a
, b
);
654 /* Extended arithmetic. */
655 t_gen_subx_carry(dc
, dst
);
658 tcg_gen_mov_tl(dst
, b
);
661 tcg_gen_or_tl(dst
, a
, b
);
664 tcg_gen_and_tl(dst
, a
, b
);
667 tcg_gen_xor_tl(dst
, a
, b
);
670 t_gen_lsl(dst
, a
, b
);
673 t_gen_lsr(dst
, a
, b
);
676 t_gen_asr(dst
, a
, b
);
679 tcg_gen_neg_tl(dst
, b
);
680 /* Extended arithmetic. */
681 t_gen_subx_carry(dc
, dst
);
684 tcg_gen_clzi_tl(dst
, b
, TARGET_LONG_BITS
);
687 tcg_gen_muls2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
690 tcg_gen_mulu2_tl(dst
, cpu_PR
[PR_MOF
], a
, b
);
693 t_gen_cris_dstep(dst
, a
, b
);
696 t_gen_cris_mstep(dst
, a
, b
, cpu_PR
[PR_CCS
]);
699 tcg_gen_movcond_tl(TCG_COND_LEU
, dst
, a
, b
, a
, b
);
702 tcg_gen_sub_tl(dst
, a
, b
);
703 /* Extended arithmetic. */
704 t_gen_subx_carry(dc
, dst
);
707 qemu_log_mask(LOG_GUEST_ERROR
, "illegal ALU op.\n");
713 tcg_gen_andi_tl(dst
, dst
, 0xff);
714 } else if (size
== 2) {
715 tcg_gen_andi_tl(dst
, dst
, 0xffff);
719 static void cris_alu(DisasContext
*dc
, int op
,
720 TCGv d
, TCGv op_a
, TCGv op_b
, int size
)
727 if (op
== CC_OP_CMP
) {
728 tmp
= tcg_temp_new();
730 } else if (size
== 4) {
734 tmp
= tcg_temp_new();
738 cris_pre_alu_update_cc(dc
, op
, op_a
, op_b
, size
);
739 cris_alu_op_exec(dc
, op
, tmp
, op_a
, op_b
, size
);
740 cris_update_result(dc
, tmp
);
745 tcg_gen_andi_tl(d
, d
, ~0xff);
747 tcg_gen_andi_tl(d
, d
, ~0xffff);
749 tcg_gen_or_tl(d
, d
, tmp
);
753 static int arith_cc(DisasContext
*dc
)
757 case CC_OP_ADDC
: return 1;
758 case CC_OP_ADD
: return 1;
759 case CC_OP_SUB
: return 1;
760 case CC_OP_DSTEP
: return 1;
761 case CC_OP_LSL
: return 1;
762 case CC_OP_LSR
: return 1;
763 case CC_OP_ASR
: return 1;
764 case CC_OP_CMP
: return 1;
765 case CC_OP_NEG
: return 1;
766 case CC_OP_OR
: return 1;
767 case CC_OP_AND
: return 1;
768 case CC_OP_XOR
: return 1;
769 case CC_OP_MULU
: return 1;
770 case CC_OP_MULS
: return 1;
778 static void gen_tst_cc (DisasContext
*dc
, TCGv cc
, int cond
)
780 int arith_opt
, move_opt
;
782 /* TODO: optimize more condition codes. */
785 * If the flags are live, we've gotta look into the bits of CCS.
786 * Otherwise, if we just did an arithmetic operation we try to
787 * evaluate the condition code faster.
789 * When this function is done, T0 should be non-zero if the condition
792 arith_opt
= arith_cc(dc
) && !dc
->flags_uptodate
;
793 move_opt
= (dc
->cc_op
== CC_OP_MOVE
);
796 if ((arith_opt
|| move_opt
)
797 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
798 tcg_gen_setcondi_tl(TCG_COND_EQ
, cc
, cc_result
, 0);
800 cris_evaluate_flags(dc
);
802 cpu_PR
[PR_CCS
], Z_FLAG
);
806 if ((arith_opt
|| move_opt
)
807 && dc
->cc_x_uptodate
!= (2 | X_FLAG
)) {
808 tcg_gen_mov_tl(cc
, cc_result
);
810 cris_evaluate_flags(dc
);
811 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
813 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
817 cris_evaluate_flags(dc
);
818 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
821 cris_evaluate_flags(dc
);
822 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
], C_FLAG
);
823 tcg_gen_andi_tl(cc
, cc
, C_FLAG
);
826 cris_evaluate_flags(dc
);
827 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], V_FLAG
);
830 cris_evaluate_flags(dc
);
831 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
833 tcg_gen_andi_tl(cc
, cc
, V_FLAG
);
836 if (arith_opt
|| move_opt
) {
839 if (dc
->cc_size
== 1) {
841 } else if (dc
->cc_size
== 2) {
845 tcg_gen_shri_tl(cc
, cc_result
, bits
);
846 tcg_gen_xori_tl(cc
, cc
, 1);
848 cris_evaluate_flags(dc
);
849 tcg_gen_xori_tl(cc
, cpu_PR
[PR_CCS
],
851 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
855 if (arith_opt
|| move_opt
) {
858 if (dc
->cc_size
== 1) {
860 } else if (dc
->cc_size
== 2) {
864 tcg_gen_shri_tl(cc
, cc_result
, bits
);
865 tcg_gen_andi_tl(cc
, cc
, 1);
867 cris_evaluate_flags(dc
);
868 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
873 cris_evaluate_flags(dc
);
874 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
],
878 cris_evaluate_flags(dc
);
882 tmp
= tcg_temp_new();
883 tcg_gen_xori_tl(tmp
, cpu_PR
[PR_CCS
],
885 /* Overlay the C flag on top of the Z. */
886 tcg_gen_shli_tl(cc
, tmp
, 2);
887 tcg_gen_and_tl(cc
, tmp
, cc
);
888 tcg_gen_andi_tl(cc
, cc
, Z_FLAG
);
892 cris_evaluate_flags(dc
);
893 /* Overlay the V flag on top of the N. */
894 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
897 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
898 tcg_gen_xori_tl(cc
, cc
, N_FLAG
);
901 cris_evaluate_flags(dc
);
902 /* Overlay the V flag on top of the N. */
903 tcg_gen_shli_tl(cc
, cpu_PR
[PR_CCS
], 2);
906 tcg_gen_andi_tl(cc
, cc
, N_FLAG
);
909 cris_evaluate_flags(dc
);
916 /* To avoid a shift we overlay everything on
918 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
919 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
921 tcg_gen_xori_tl(z
, z
, 2);
923 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
924 tcg_gen_xori_tl(n
, n
, 2);
925 tcg_gen_and_tl(cc
, z
, n
);
926 tcg_gen_andi_tl(cc
, cc
, 2);
930 cris_evaluate_flags(dc
);
937 /* To avoid a shift we overlay everything on
939 tcg_gen_shri_tl(n
, cpu_PR
[PR_CCS
], 2);
940 tcg_gen_shri_tl(z
, cpu_PR
[PR_CCS
], 1);
942 tcg_gen_xor_tl(n
, n
, cpu_PR
[PR_CCS
]);
943 tcg_gen_or_tl(cc
, z
, n
);
944 tcg_gen_andi_tl(cc
, cc
, 2);
948 cris_evaluate_flags(dc
);
949 tcg_gen_andi_tl(cc
, cpu_PR
[PR_CCS
], P_FLAG
);
952 tcg_gen_movi_tl(cc
, 1);
960 static void cris_store_direct_jmp(DisasContext
*dc
)
962 /* Store the direct jmp state into the cpu-state. */
963 if (dc
->jmp
== JMP_DIRECT
|| dc
->jmp
== JMP_DIRECT_CC
) {
964 if (dc
->jmp
== JMP_DIRECT
) {
965 tcg_gen_movi_tl(env_btaken
, 1);
967 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
968 dc
->jmp
= JMP_INDIRECT
;
972 static void cris_prepare_cc_branch (DisasContext
*dc
,
973 int offset
, int cond
)
975 /* This helps us re-schedule the micro-code to insns in delay-slots
976 before the actual jump. */
977 dc
->delayed_branch
= 2;
978 dc
->jmp
= JMP_DIRECT_CC
;
979 dc
->jmp_pc
= dc
->pc
+ offset
;
981 gen_tst_cc(dc
, env_btaken
, cond
);
982 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
986 /* jumps, when the dest is in a live reg for example. Direct should be set
987 when the dest addr is constant to allow tb chaining. */
988 static inline void cris_prepare_jmp (DisasContext
*dc
, unsigned int type
)
990 /* This helps us re-schedule the micro-code to insns in delay-slots
991 before the actual jump. */
992 dc
->delayed_branch
= 2;
994 if (type
== JMP_INDIRECT
) {
995 tcg_gen_movi_tl(env_btaken
, 1);
999 static void gen_load64(DisasContext
*dc
, TCGv_i64 dst
, TCGv addr
)
1001 /* If we get a fault on a delayslot we must keep the jmp state in
1002 the cpu-state to be able to re-execute the jmp. */
1003 if (dc
->delayed_branch
== 1) {
1004 cris_store_direct_jmp(dc
);
1007 tcg_gen_qemu_ld_i64(dst
, addr
, dc
->mem_index
, MO_TEUQ
);
1010 static void gen_load(DisasContext
*dc
, TCGv dst
, TCGv addr
,
1011 unsigned int size
, int sign
)
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_tl(dst
, addr
, dc
->mem_index
,
1020 MO_TE
+ ctz32(size
) + (sign
? MO_SIGN
: 0));
1023 static void gen_store (DisasContext
*dc
, TCGv addr
, TCGv val
,
1026 /* If we get a fault on a delayslot we must keep the jmp state in
1027 the cpu-state to be able to re-execute the jmp. */
1028 if (dc
->delayed_branch
== 1) {
1029 cris_store_direct_jmp(dc
);
1033 /* Conditional writes. We only support the kind were X and P are known
1034 at translation time. */
1035 if (dc
->flags_x
&& (dc
->tb_flags
& P_FLAG
)) {
1037 cris_evaluate_flags(dc
);
1038 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], C_FLAG
);
1042 tcg_gen_qemu_st_tl(val
, addr
, dc
->mem_index
, MO_TE
+ ctz32(size
));
1045 cris_evaluate_flags(dc
);
1046 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~C_FLAG
);
1050 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
1053 tcg_gen_ext8s_i32(d
, s
);
1054 } else if (size
== 2) {
1055 tcg_gen_ext16s_i32(d
, s
);
1057 tcg_gen_mov_tl(d
, s
);
1061 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
1064 tcg_gen_ext8u_i32(d
, s
);
1065 } else if (size
== 2) {
1066 tcg_gen_ext16u_i32(d
, s
);
1068 tcg_gen_mov_tl(d
, s
);
1073 static char memsize_char(int size
)
1085 static inline unsigned int memsize_z(DisasContext
*dc
)
1087 return dc
->zsize
+ 1;
1090 static inline unsigned int memsize_zz(DisasContext
*dc
)
1092 switch (dc
->zzsize
) {
1100 static inline void do_postinc (DisasContext
*dc
, int size
)
1103 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], size
);
1107 static inline void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
1108 int size
, int s_ext
, TCGv dst
)
1111 t_gen_sext(dst
, cpu_R
[rs
], size
);
1113 t_gen_zext(dst
, cpu_R
[rs
], size
);
1117 /* Prepare T0 and T1 for a register alu operation.
1118 s_ext decides if the operand1 should be sign-extended or zero-extended when
1120 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
1121 int size
, int s_ext
, TCGv dst
, TCGv src
)
1123 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
, src
);
1126 t_gen_sext(dst
, cpu_R
[rd
], size
);
1128 t_gen_zext(dst
, cpu_R
[rd
], size
);
1132 static int dec_prep_move_m(CPUCRISState
*env
, DisasContext
*dc
,
1133 int s_ext
, int memsize
, TCGv dst
)
1141 is_imm
= rs
== 15 && dc
->postinc
;
1143 /* Load [$rs] onto T1. */
1145 insn_len
= 2 + memsize
;
1150 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, memsize
, s_ext
);
1151 tcg_gen_movi_tl(dst
, imm
);
1154 cris_flush_cc_state(dc
);
1155 gen_load(dc
, dst
, cpu_R
[rs
], memsize
, 0);
1157 t_gen_sext(dst
, dst
, memsize
);
1159 t_gen_zext(dst
, dst
, memsize
);
1165 /* Prepare T0 and T1 for a memory + alu operation.
1166 s_ext decides if the operand1 should be sign-extended or zero-extended when
1168 static int dec_prep_alu_m(CPUCRISState
*env
, DisasContext
*dc
,
1169 int s_ext
, int memsize
, TCGv dst
, TCGv src
)
1173 insn_len
= dec_prep_move_m(env
, dc
, s_ext
, memsize
, src
);
1174 tcg_gen_mov_tl(dst
, cpu_R
[dc
->op2
]);
1179 static const char *cc_name(int cc
)
1181 static const char * const cc_names
[16] = {
1182 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1183 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1186 return cc_names
[cc
];
1190 /* Start of insn decoders. */
1192 static int dec_bccq(CPUCRISState
*env
, DisasContext
*dc
)
1196 uint32_t cond
= dc
->op2
;
1198 offset
= EXTRACT_FIELD(dc
->ir
, 1, 7);
1199 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1202 offset
|= sign
<< 8;
1203 offset
= sign_extend(offset
, 8);
1205 LOG_DIS("b%s %x\n", cc_name(cond
), dc
->pc
+ offset
);
1207 /* op2 holds the condition-code. */
1208 cris_cc_mask(dc
, 0);
1209 cris_prepare_cc_branch(dc
, offset
, cond
);
1212 static int dec_addoq(CPUCRISState
*env
, DisasContext
*dc
)
1216 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1217 imm
= sign_extend(dc
->op1
, 7);
1219 LOG_DIS("addoq %d, $r%u\n", imm
, dc
->op2
);
1220 cris_cc_mask(dc
, 0);
1221 /* Fetch register operand, */
1222 tcg_gen_addi_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op2
], imm
);
1226 static int dec_addq(CPUCRISState
*env
, DisasContext
*dc
)
1229 LOG_DIS("addq %u, $r%u\n", dc
->op1
, dc
->op2
);
1231 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1233 cris_cc_mask(dc
, CC_MASK_NZVC
);
1235 c
= tcg_constant_tl(dc
->op1
);
1236 cris_alu(dc
, CC_OP_ADD
,
1237 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1240 static int dec_moveq(CPUCRISState
*env
, DisasContext
*dc
)
1244 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1245 imm
= sign_extend(dc
->op1
, 5);
1246 LOG_DIS("moveq %d, $r%u\n", imm
, dc
->op2
);
1248 tcg_gen_movi_tl(cpu_R
[dc
->op2
], imm
);
1251 static int dec_subq(CPUCRISState
*env
, DisasContext
*dc
)
1254 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1256 LOG_DIS("subq %u, $r%u\n", dc
->op1
, dc
->op2
);
1258 cris_cc_mask(dc
, CC_MASK_NZVC
);
1259 c
= tcg_constant_tl(dc
->op1
);
1260 cris_alu(dc
, CC_OP_SUB
,
1261 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1264 static int dec_cmpq(CPUCRISState
*env
, DisasContext
*dc
)
1268 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1269 imm
= sign_extend(dc
->op1
, 5);
1271 LOG_DIS("cmpq %d, $r%d\n", imm
, dc
->op2
);
1272 cris_cc_mask(dc
, CC_MASK_NZVC
);
1274 c
= tcg_constant_tl(imm
);
1275 cris_alu(dc
, CC_OP_CMP
,
1276 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1279 static int dec_andq(CPUCRISState
*env
, DisasContext
*dc
)
1283 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1284 imm
= sign_extend(dc
->op1
, 5);
1286 LOG_DIS("andq %d, $r%d\n", imm
, dc
->op2
);
1287 cris_cc_mask(dc
, CC_MASK_NZ
);
1289 c
= tcg_constant_tl(imm
);
1290 cris_alu(dc
, CC_OP_AND
,
1291 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1294 static int dec_orq(CPUCRISState
*env
, DisasContext
*dc
)
1298 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1299 imm
= sign_extend(dc
->op1
, 5);
1300 LOG_DIS("orq %d, $r%d\n", imm
, dc
->op2
);
1301 cris_cc_mask(dc
, CC_MASK_NZ
);
1303 c
= tcg_constant_tl(imm
);
1304 cris_alu(dc
, CC_OP_OR
,
1305 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], c
, 4);
1308 static int dec_btstq(CPUCRISState
*env
, DisasContext
*dc
)
1311 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1312 LOG_DIS("btstq %u, $r%d\n", dc
->op1
, dc
->op2
);
1314 cris_cc_mask(dc
, CC_MASK_NZ
);
1315 c
= tcg_constant_tl(dc
->op1
);
1316 cris_evaluate_flags(dc
);
1317 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1319 cris_alu(dc
, CC_OP_MOVE
,
1320 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1321 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1322 dc
->flags_uptodate
= 1;
1325 static int dec_asrq(CPUCRISState
*env
, DisasContext
*dc
)
1327 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1328 LOG_DIS("asrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1329 cris_cc_mask(dc
, CC_MASK_NZ
);
1331 tcg_gen_sari_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1332 cris_alu(dc
, CC_OP_MOVE
,
1334 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1337 static int dec_lslq(CPUCRISState
*env
, DisasContext
*dc
)
1339 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1340 LOG_DIS("lslq %u, $r%d\n", dc
->op1
, dc
->op2
);
1342 cris_cc_mask(dc
, CC_MASK_NZ
);
1344 tcg_gen_shli_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1346 cris_alu(dc
, CC_OP_MOVE
,
1348 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1351 static int dec_lsrq(CPUCRISState
*env
, DisasContext
*dc
)
1353 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1354 LOG_DIS("lsrq %u, $r%d\n", dc
->op1
, dc
->op2
);
1356 cris_cc_mask(dc
, CC_MASK_NZ
);
1358 tcg_gen_shri_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], dc
->op1
);
1359 cris_alu(dc
, CC_OP_MOVE
,
1361 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1365 static int dec_move_r(CPUCRISState
*env
, DisasContext
*dc
)
1367 int size
= memsize_zz(dc
);
1369 LOG_DIS("move.%c $r%u, $r%u\n",
1370 memsize_char(size
), dc
->op1
, dc
->op2
);
1372 cris_cc_mask(dc
, CC_MASK_NZ
);
1374 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, cpu_R
[dc
->op2
]);
1375 cris_cc_mask(dc
, CC_MASK_NZ
);
1376 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
1377 cris_update_cc_x(dc
);
1378 cris_update_result(dc
, cpu_R
[dc
->op2
]);
1382 t0
= tcg_temp_new();
1383 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1384 cris_alu(dc
, CC_OP_MOVE
,
1386 cpu_R
[dc
->op2
], t0
, size
);
1391 static int dec_scc_r(CPUCRISState
*env
, DisasContext
*dc
)
1395 LOG_DIS("s%s $r%u\n",
1396 cc_name(cond
), dc
->op1
);
1398 gen_tst_cc(dc
, cpu_R
[dc
->op1
], cond
);
1399 tcg_gen_setcondi_tl(TCG_COND_NE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], 0);
1401 cris_cc_mask(dc
, 0);
1405 static inline void cris_alu_alloc_temps(DisasContext
*dc
, int size
, TCGv
*t
)
1408 t
[0] = cpu_R
[dc
->op2
];
1409 t
[1] = cpu_R
[dc
->op1
];
1411 t
[0] = tcg_temp_new();
1412 t
[1] = tcg_temp_new();
1416 static int dec_and_r(CPUCRISState
*env
, DisasContext
*dc
)
1419 int size
= memsize_zz(dc
);
1421 LOG_DIS("and.%c $r%u, $r%u\n",
1422 memsize_char(size
), dc
->op1
, dc
->op2
);
1424 cris_cc_mask(dc
, CC_MASK_NZ
);
1426 cris_alu_alloc_temps(dc
, size
, t
);
1427 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1428 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1432 static int dec_lz_r(CPUCRISState
*env
, DisasContext
*dc
)
1435 LOG_DIS("lz $r%u, $r%u\n",
1437 cris_cc_mask(dc
, CC_MASK_NZ
);
1438 t0
= tcg_temp_new();
1439 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0, cpu_R
[dc
->op2
], t0
);
1440 cris_alu(dc
, CC_OP_LZ
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1444 static int dec_lsl_r(CPUCRISState
*env
, DisasContext
*dc
)
1447 int size
= memsize_zz(dc
);
1449 LOG_DIS("lsl.%c $r%u, $r%u\n",
1450 memsize_char(size
), dc
->op1
, dc
->op2
);
1452 cris_cc_mask(dc
, CC_MASK_NZ
);
1453 cris_alu_alloc_temps(dc
, size
, t
);
1454 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1455 tcg_gen_andi_tl(t
[1], t
[1], 63);
1456 cris_alu(dc
, CC_OP_LSL
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1460 static int dec_lsr_r(CPUCRISState
*env
, DisasContext
*dc
)
1463 int size
= memsize_zz(dc
);
1465 LOG_DIS("lsr.%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_LSR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1476 static int dec_asr_r(CPUCRISState
*env
, DisasContext
*dc
)
1479 int size
= memsize_zz(dc
);
1481 LOG_DIS("asr.%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
, 1, t
[0], t
[1]);
1487 tcg_gen_andi_tl(t
[1], t
[1], 63);
1488 cris_alu(dc
, CC_OP_ASR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1492 static int dec_muls_r(CPUCRISState
*env
, DisasContext
*dc
)
1495 int size
= memsize_zz(dc
);
1497 LOG_DIS("muls.%c $r%u, $r%u\n",
1498 memsize_char(size
), dc
->op1
, dc
->op2
);
1499 cris_cc_mask(dc
, CC_MASK_NZV
);
1500 cris_alu_alloc_temps(dc
, size
, t
);
1501 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1, t
[0], t
[1]);
1503 cris_alu(dc
, CC_OP_MULS
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1507 static int dec_mulu_r(CPUCRISState
*env
, DisasContext
*dc
)
1510 int size
= memsize_zz(dc
);
1512 LOG_DIS("mulu.%c $r%u, $r%u\n",
1513 memsize_char(size
), dc
->op1
, dc
->op2
);
1514 cris_cc_mask(dc
, CC_MASK_NZV
);
1515 cris_alu_alloc_temps(dc
, size
, t
);
1516 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1518 cris_alu(dc
, CC_OP_MULU
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1523 static int dec_dstep_r(CPUCRISState
*env
, DisasContext
*dc
)
1525 LOG_DIS("dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
);
1526 cris_cc_mask(dc
, CC_MASK_NZ
);
1527 cris_alu(dc
, CC_OP_DSTEP
,
1528 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1532 static int dec_xor_r(CPUCRISState
*env
, DisasContext
*dc
)
1535 int size
= memsize_zz(dc
);
1536 LOG_DIS("xor.%c $r%u, $r%u\n",
1537 memsize_char(size
), dc
->op1
, dc
->op2
);
1538 BUG_ON(size
!= 4); /* xor is dword. */
1539 cris_cc_mask(dc
, CC_MASK_NZ
);
1540 cris_alu_alloc_temps(dc
, size
, t
);
1541 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1543 cris_alu(dc
, CC_OP_XOR
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
1547 static int dec_bound_r(CPUCRISState
*env
, DisasContext
*dc
)
1550 int size
= memsize_zz(dc
);
1551 LOG_DIS("bound.%c $r%u, $r%u\n",
1552 memsize_char(size
), dc
->op1
, dc
->op2
);
1553 cris_cc_mask(dc
, CC_MASK_NZ
);
1554 l0
= tcg_temp_new();
1555 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, l0
);
1556 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], l0
, 4);
1560 static int dec_cmp_r(CPUCRISState
*env
, DisasContext
*dc
)
1563 int size
= memsize_zz(dc
);
1564 LOG_DIS("cmp.%c $r%u, $r%u\n",
1565 memsize_char(size
), dc
->op1
, dc
->op2
);
1566 cris_cc_mask(dc
, CC_MASK_NZVC
);
1567 cris_alu_alloc_temps(dc
, size
, t
);
1568 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1570 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1574 static int dec_abs_r(CPUCRISState
*env
, DisasContext
*dc
)
1576 LOG_DIS("abs $r%u, $r%u\n",
1578 cris_cc_mask(dc
, CC_MASK_NZ
);
1580 tcg_gen_abs_tl(cpu_R
[dc
->op2
], cpu_R
[dc
->op1
]);
1581 cris_alu(dc
, CC_OP_MOVE
,
1582 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1586 static int dec_add_r(CPUCRISState
*env
, DisasContext
*dc
)
1589 int size
= memsize_zz(dc
);
1590 LOG_DIS("add.%c $r%u, $r%u\n",
1591 memsize_char(size
), dc
->op1
, dc
->op2
);
1592 cris_cc_mask(dc
, CC_MASK_NZVC
);
1593 cris_alu_alloc_temps(dc
, size
, t
);
1594 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1596 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1600 static int dec_addc_r(CPUCRISState
*env
, DisasContext
*dc
)
1602 LOG_DIS("addc $r%u, $r%u\n",
1604 cris_evaluate_flags(dc
);
1606 /* Set for this insn. */
1607 dc
->flags_x
= X_FLAG
;
1609 cris_cc_mask(dc
, CC_MASK_NZVC
);
1610 cris_alu(dc
, CC_OP_ADDC
,
1611 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], 4);
1615 static int dec_mcp_r(CPUCRISState
*env
, DisasContext
*dc
)
1617 LOG_DIS("mcp $p%u, $r%u\n",
1619 cris_evaluate_flags(dc
);
1620 cris_cc_mask(dc
, CC_MASK_RNZV
);
1621 cris_alu(dc
, CC_OP_MCP
,
1622 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], cpu_PR
[dc
->op2
], 4);
1627 static char * swapmode_name(int mode
, char *modename
) {
1630 modename
[i
++] = 'n';
1633 modename
[i
++] = 'w';
1636 modename
[i
++] = 'b';
1639 modename
[i
++] = 'r';
1646 static int dec_swap_r(CPUCRISState
*env
, DisasContext
*dc
)
1652 LOG_DIS("swap%s $r%u\n",
1653 swapmode_name(dc
->op2
, modename
), dc
->op1
);
1655 cris_cc_mask(dc
, CC_MASK_NZ
);
1656 t0
= tcg_temp_new();
1657 tcg_gen_mov_tl(t0
, cpu_R
[dc
->op1
]);
1659 tcg_gen_not_tl(t0
, t0
);
1662 t_gen_swapw(t0
, t0
);
1665 t_gen_swapb(t0
, t0
);
1668 t_gen_swapr(t0
, t0
);
1670 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
, 4);
1674 static int dec_or_r(CPUCRISState
*env
, DisasContext
*dc
)
1677 int size
= memsize_zz(dc
);
1678 LOG_DIS("or.%c $r%u, $r%u\n",
1679 memsize_char(size
), dc
->op1
, dc
->op2
);
1680 cris_cc_mask(dc
, CC_MASK_NZ
);
1681 cris_alu_alloc_temps(dc
, size
, t
);
1682 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1683 cris_alu(dc
, CC_OP_OR
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1687 static int dec_addi_r(CPUCRISState
*env
, DisasContext
*dc
)
1690 LOG_DIS("addi.%c $r%u, $r%u\n",
1691 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1692 cris_cc_mask(dc
, 0);
1693 t0
= tcg_temp_new();
1694 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1695 tcg_gen_add_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
);
1699 static int dec_addi_acr(CPUCRISState
*env
, DisasContext
*dc
)
1702 LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1703 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
);
1704 cris_cc_mask(dc
, 0);
1705 t0
= tcg_temp_new();
1706 tcg_gen_shli_tl(t0
, cpu_R
[dc
->op2
], dc
->zzsize
);
1707 tcg_gen_add_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op1
], t0
);
1711 static int dec_neg_r(CPUCRISState
*env
, DisasContext
*dc
)
1714 int size
= memsize_zz(dc
);
1715 LOG_DIS("neg.%c $r%u, $r%u\n",
1716 memsize_char(size
), dc
->op1
, dc
->op2
);
1717 cris_cc_mask(dc
, CC_MASK_NZVC
);
1718 cris_alu_alloc_temps(dc
, size
, t
);
1719 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1721 cris_alu(dc
, CC_OP_NEG
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1725 static int dec_btst_r(CPUCRISState
*env
, DisasContext
*dc
)
1727 LOG_DIS("btst $r%u, $r%u\n",
1729 cris_cc_mask(dc
, CC_MASK_NZ
);
1730 cris_evaluate_flags(dc
);
1731 gen_helper_btst(cpu_PR
[PR_CCS
], tcg_env
, cpu_R
[dc
->op2
],
1732 cpu_R
[dc
->op1
], cpu_PR
[PR_CCS
]);
1733 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
],
1734 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], 4);
1735 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1736 dc
->flags_uptodate
= 1;
1740 static int dec_sub_r(CPUCRISState
*env
, DisasContext
*dc
)
1743 int size
= memsize_zz(dc
);
1744 LOG_DIS("sub.%c $r%u, $r%u\n",
1745 memsize_char(size
), dc
->op1
, dc
->op2
);
1746 cris_cc_mask(dc
, CC_MASK_NZVC
);
1747 cris_alu_alloc_temps(dc
, size
, t
);
1748 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t
[0], t
[1]);
1749 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], size
);
1753 /* Zero extension. From size to dword. */
1754 static int dec_movu_r(CPUCRISState
*env
, DisasContext
*dc
)
1757 int size
= memsize_z(dc
);
1758 LOG_DIS("movu.%c $r%u, $r%u\n",
1762 cris_cc_mask(dc
, CC_MASK_NZ
);
1763 t0
= tcg_temp_new();
1764 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0, t0
);
1765 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1769 /* Sign extension. From size to dword. */
1770 static int dec_movs_r(CPUCRISState
*env
, DisasContext
*dc
)
1773 int size
= memsize_z(dc
);
1774 LOG_DIS("movs.%c $r%u, $r%u\n",
1778 cris_cc_mask(dc
, CC_MASK_NZ
);
1779 t0
= tcg_temp_new();
1780 /* Size can only be qi or hi. */
1781 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1782 cris_alu(dc
, CC_OP_MOVE
,
1783 cpu_R
[dc
->op2
], cpu_R
[dc
->op1
], t0
, 4);
1787 /* zero extension. From size to dword. */
1788 static int dec_addu_r(CPUCRISState
*env
, DisasContext
*dc
)
1791 int size
= memsize_z(dc
);
1792 LOG_DIS("addu.%c $r%u, $r%u\n",
1796 cris_cc_mask(dc
, CC_MASK_NZVC
);
1797 t0
= tcg_temp_new();
1798 /* Size can only be qi or hi. */
1799 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1800 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1804 /* Sign extension. From size to dword. */
1805 static int dec_adds_r(CPUCRISState
*env
, DisasContext
*dc
)
1808 int size
= memsize_z(dc
);
1809 LOG_DIS("adds.%c $r%u, $r%u\n",
1813 cris_cc_mask(dc
, CC_MASK_NZVC
);
1814 t0
= tcg_temp_new();
1815 /* Size can only be qi or hi. */
1816 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1817 cris_alu(dc
, CC_OP_ADD
,
1818 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1822 /* Zero extension. From size to dword. */
1823 static int dec_subu_r(CPUCRISState
*env
, DisasContext
*dc
)
1826 int size
= memsize_z(dc
);
1827 LOG_DIS("subu.%c $r%u, $r%u\n",
1831 cris_cc_mask(dc
, CC_MASK_NZVC
);
1832 t0
= tcg_temp_new();
1833 /* Size can only be qi or hi. */
1834 t_gen_zext(t0
, cpu_R
[dc
->op1
], size
);
1835 cris_alu(dc
, CC_OP_SUB
,
1836 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1840 /* Sign extension. From size to dword. */
1841 static int dec_subs_r(CPUCRISState
*env
, DisasContext
*dc
)
1844 int size
= memsize_z(dc
);
1845 LOG_DIS("subs.%c $r%u, $r%u\n",
1849 cris_cc_mask(dc
, CC_MASK_NZVC
);
1850 t0
= tcg_temp_new();
1851 /* Size can only be qi or hi. */
1852 t_gen_sext(t0
, cpu_R
[dc
->op1
], size
);
1853 cris_alu(dc
, CC_OP_SUB
,
1854 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, 4);
1858 static int dec_setclrf(CPUCRISState
*env
, DisasContext
*dc
)
1861 int set
= (~dc
->opcode
>> 2) & 1;
1864 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1865 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1866 if (set
&& flags
== 0) {
1869 } else if (!set
&& (flags
& 0x20)) {
1872 LOG_DIS("%sf %x\n", set
? "set" : "clr", flags
);
1875 /* User space is not allowed to touch these. Silently ignore. */
1876 if (dc
->tb_flags
& U_FLAG
) {
1877 flags
&= ~(S_FLAG
| I_FLAG
| U_FLAG
);
1880 if (flags
& X_FLAG
) {
1882 dc
->flags_x
= X_FLAG
;
1888 /* Break the TB if any of the SPI flag changes. */
1889 if (flags
& (P_FLAG
| S_FLAG
)) {
1890 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1891 dc
->base
.is_jmp
= DISAS_UPDATE
;
1892 dc
->cpustate_changed
= 1;
1895 /* For the I flag, only act on posedge. */
1896 if ((flags
& I_FLAG
)) {
1897 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
1898 dc
->base
.is_jmp
= DISAS_UPDATE
;
1899 dc
->cpustate_changed
= 1;
1903 /* Simply decode the flags. */
1904 cris_evaluate_flags(dc
);
1905 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1906 cris_update_cc_x(dc
);
1907 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
1910 if (!(dc
->tb_flags
& U_FLAG
) && (flags
& U_FLAG
)) {
1911 /* Enter user mode. */
1912 t_gen_mov_env_TN(ksp
, cpu_R
[R_SP
]);
1913 tcg_gen_mov_tl(cpu_R
[R_SP
], cpu_PR
[PR_USP
]);
1914 dc
->cpustate_changed
= 1;
1916 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], flags
);
1918 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~flags
);
1921 dc
->flags_uptodate
= 1;
1926 static int dec_move_rs(CPUCRISState
*env
, DisasContext
*dc
)
1929 LOG_DIS("move $r%u, $s%u\n", dc
->op1
, dc
->op2
);
1930 c1
= tcg_constant_tl(dc
->op1
);
1931 c2
= tcg_constant_tl(dc
->op2
);
1932 cris_cc_mask(dc
, 0);
1933 gen_helper_movl_sreg_reg(tcg_env
, c2
, c1
);
1936 static int dec_move_sr(CPUCRISState
*env
, DisasContext
*dc
)
1939 LOG_DIS("move $s%u, $r%u\n", dc
->op2
, dc
->op1
);
1940 c1
= tcg_constant_tl(dc
->op1
);
1941 c2
= tcg_constant_tl(dc
->op2
);
1942 cris_cc_mask(dc
, 0);
1943 gen_helper_movl_reg_sreg(tcg_env
, c1
, c2
);
1947 static int dec_move_rp(CPUCRISState
*env
, DisasContext
*dc
)
1950 LOG_DIS("move $r%u, $p%u\n", dc
->op1
, dc
->op2
);
1951 cris_cc_mask(dc
, 0);
1953 t
[0] = tcg_temp_new();
1954 if (dc
->op2
== PR_CCS
) {
1955 cris_evaluate_flags(dc
);
1956 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1957 if (dc
->tb_flags
& U_FLAG
) {
1958 t
[1] = tcg_temp_new();
1959 /* User space is not allowed to touch all flags. */
1960 tcg_gen_andi_tl(t
[0], t
[0], 0x39f);
1961 tcg_gen_andi_tl(t
[1], cpu_PR
[PR_CCS
], ~0x39f);
1962 tcg_gen_or_tl(t
[0], t
[1], t
[0]);
1965 tcg_gen_mov_tl(t
[0], cpu_R
[dc
->op1
]);
1968 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[0]);
1969 if (dc
->op2
== PR_CCS
) {
1970 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1971 dc
->flags_uptodate
= 1;
1975 static int dec_move_pr(CPUCRISState
*env
, DisasContext
*dc
)
1978 LOG_DIS("move $p%u, $r%u\n", dc
->op2
, dc
->op1
);
1979 cris_cc_mask(dc
, 0);
1981 if (dc
->op2
== PR_CCS
) {
1982 cris_evaluate_flags(dc
);
1985 if (dc
->op2
== PR_DZ
) {
1986 tcg_gen_movi_tl(cpu_R
[dc
->op1
], 0);
1988 t0
= tcg_temp_new();
1989 t_gen_mov_TN_preg(t0
, dc
->op2
);
1990 cris_alu(dc
, CC_OP_MOVE
,
1991 cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], t0
,
1992 preg_sizes
[dc
->op2
]);
1997 static int dec_move_mr(CPUCRISState
*env
, DisasContext
*dc
)
1999 int memsize
= memsize_zz(dc
);
2001 LOG_DIS("move.%c [$r%u%s, $r%u\n",
2002 memsize_char(memsize
),
2003 dc
->op1
, dc
->postinc
? "+]" : "]",
2007 insn_len
= dec_prep_move_m(env
, dc
, 0, 4, cpu_R
[dc
->op2
]);
2008 cris_cc_mask(dc
, CC_MASK_NZ
);
2009 cris_update_cc_op(dc
, CC_OP_MOVE
, 4);
2010 cris_update_cc_x(dc
);
2011 cris_update_result(dc
, cpu_R
[dc
->op2
]);
2015 t0
= tcg_temp_new();
2016 insn_len
= dec_prep_move_m(env
, dc
, 0, memsize
, t0
);
2017 cris_cc_mask(dc
, CC_MASK_NZ
);
2018 cris_alu(dc
, CC_OP_MOVE
,
2019 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t0
, memsize
);
2021 do_postinc(dc
, memsize
);
2025 static inline void cris_alu_m_alloc_temps(TCGv
*t
)
2027 t
[0] = tcg_temp_new();
2028 t
[1] = tcg_temp_new();
2031 static int dec_movs_m(CPUCRISState
*env
, DisasContext
*dc
)
2034 int memsize
= memsize_z(dc
);
2036 LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2037 memsize_char(memsize
),
2038 dc
->op1
, dc
->postinc
? "+]" : "]",
2041 cris_alu_m_alloc_temps(t
);
2043 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2044 cris_cc_mask(dc
, CC_MASK_NZ
);
2045 cris_alu(dc
, CC_OP_MOVE
,
2046 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2047 do_postinc(dc
, memsize
);
2051 static int dec_addu_m(CPUCRISState
*env
, DisasContext
*dc
)
2054 int memsize
= memsize_z(dc
);
2056 LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2057 memsize_char(memsize
),
2058 dc
->op1
, dc
->postinc
? "+]" : "]",
2061 cris_alu_m_alloc_temps(t
);
2063 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2064 cris_cc_mask(dc
, CC_MASK_NZVC
);
2065 cris_alu(dc
, CC_OP_ADD
,
2066 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2067 do_postinc(dc
, memsize
);
2071 static int dec_adds_m(CPUCRISState
*env
, DisasContext
*dc
)
2074 int memsize
= memsize_z(dc
);
2076 LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2077 memsize_char(memsize
),
2078 dc
->op1
, dc
->postinc
? "+]" : "]",
2081 cris_alu_m_alloc_temps(t
);
2083 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2084 cris_cc_mask(dc
, CC_MASK_NZVC
);
2085 cris_alu(dc
, CC_OP_ADD
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2086 do_postinc(dc
, memsize
);
2090 static int dec_subu_m(CPUCRISState
*env
, DisasContext
*dc
)
2093 int memsize
= memsize_z(dc
);
2095 LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2096 memsize_char(memsize
),
2097 dc
->op1
, dc
->postinc
? "+]" : "]",
2100 cris_alu_m_alloc_temps(t
);
2102 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2103 cris_cc_mask(dc
, CC_MASK_NZVC
);
2104 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2105 do_postinc(dc
, memsize
);
2109 static int dec_subs_m(CPUCRISState
*env
, DisasContext
*dc
)
2112 int memsize
= memsize_z(dc
);
2114 LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2115 memsize_char(memsize
),
2116 dc
->op1
, dc
->postinc
? "+]" : "]",
2119 cris_alu_m_alloc_temps(t
);
2121 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2122 cris_cc_mask(dc
, CC_MASK_NZVC
);
2123 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2124 do_postinc(dc
, memsize
);
2128 static int dec_movu_m(CPUCRISState
*env
, DisasContext
*dc
)
2131 int memsize
= memsize_z(dc
);
2134 LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2135 memsize_char(memsize
),
2136 dc
->op1
, dc
->postinc
? "+]" : "]",
2139 cris_alu_m_alloc_temps(t
);
2140 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2141 cris_cc_mask(dc
, CC_MASK_NZ
);
2142 cris_alu(dc
, CC_OP_MOVE
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2143 do_postinc(dc
, memsize
);
2147 static int dec_cmpu_m(CPUCRISState
*env
, DisasContext
*dc
)
2150 int memsize
= memsize_z(dc
);
2152 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2153 memsize_char(memsize
),
2154 dc
->op1
, dc
->postinc
? "+]" : "]",
2157 cris_alu_m_alloc_temps(t
);
2158 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2159 cris_cc_mask(dc
, CC_MASK_NZVC
);
2160 cris_alu(dc
, CC_OP_CMP
, cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1], 4);
2161 do_postinc(dc
, memsize
);
2165 static int dec_cmps_m(CPUCRISState
*env
, DisasContext
*dc
)
2168 int memsize
= memsize_z(dc
);
2170 LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2171 memsize_char(memsize
),
2172 dc
->op1
, dc
->postinc
? "+]" : "]",
2175 cris_alu_m_alloc_temps(t
);
2176 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2177 cris_cc_mask(dc
, CC_MASK_NZVC
);
2178 cris_alu(dc
, CC_OP_CMP
,
2179 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2181 do_postinc(dc
, memsize
);
2185 static int dec_cmp_m(CPUCRISState
*env
, DisasContext
*dc
)
2188 int memsize
= memsize_zz(dc
);
2190 LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2191 memsize_char(memsize
),
2192 dc
->op1
, dc
->postinc
? "+]" : "]",
2195 cris_alu_m_alloc_temps(t
);
2196 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2197 cris_cc_mask(dc
, CC_MASK_NZVC
);
2198 cris_alu(dc
, CC_OP_CMP
,
2199 cpu_R
[dc
->op2
], cpu_R
[dc
->op2
], t
[1],
2201 do_postinc(dc
, memsize
);
2205 static int dec_test_m(CPUCRISState
*env
, DisasContext
*dc
)
2208 int memsize
= memsize_zz(dc
);
2210 LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2211 memsize_char(memsize
),
2212 dc
->op1
, dc
->postinc
? "+]" : "]",
2215 cris_evaluate_flags(dc
);
2217 cris_alu_m_alloc_temps(t
);
2218 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2219 cris_cc_mask(dc
, CC_MASK_NZ
);
2220 tcg_gen_andi_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~3);
2222 c
= tcg_constant_tl(0);
2223 cris_alu(dc
, CC_OP_CMP
,
2224 cpu_R
[dc
->op2
], t
[1], c
, memsize_zz(dc
));
2225 do_postinc(dc
, memsize
);
2229 static int dec_and_m(CPUCRISState
*env
, DisasContext
*dc
)
2232 int memsize
= memsize_zz(dc
);
2234 LOG_DIS("and.%c [$r%u%s, $r%u\n",
2235 memsize_char(memsize
),
2236 dc
->op1
, dc
->postinc
? "+]" : "]",
2239 cris_alu_m_alloc_temps(t
);
2240 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2241 cris_cc_mask(dc
, CC_MASK_NZ
);
2242 cris_alu(dc
, CC_OP_AND
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2243 do_postinc(dc
, memsize
);
2247 static int dec_add_m(CPUCRISState
*env
, DisasContext
*dc
)
2250 int memsize
= memsize_zz(dc
);
2252 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2253 memsize_char(memsize
),
2254 dc
->op1
, dc
->postinc
? "+]" : "]",
2257 cris_alu_m_alloc_temps(t
);
2258 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2259 cris_cc_mask(dc
, CC_MASK_NZVC
);
2260 cris_alu(dc
, CC_OP_ADD
,
2261 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2262 do_postinc(dc
, memsize
);
2266 static int dec_addo_m(CPUCRISState
*env
, DisasContext
*dc
)
2269 int memsize
= memsize_zz(dc
);
2271 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2272 memsize_char(memsize
),
2273 dc
->op1
, dc
->postinc
? "+]" : "]",
2276 cris_alu_m_alloc_temps(t
);
2277 insn_len
= dec_prep_alu_m(env
, dc
, 1, memsize
, t
[0], t
[1]);
2278 cris_cc_mask(dc
, 0);
2279 cris_alu(dc
, CC_OP_ADD
, cpu_R
[R_ACR
], t
[0], t
[1], 4);
2280 do_postinc(dc
, memsize
);
2284 static int dec_bound_m(CPUCRISState
*env
, DisasContext
*dc
)
2287 int memsize
= memsize_zz(dc
);
2289 LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2290 memsize_char(memsize
),
2291 dc
->op1
, dc
->postinc
? "+]" : "]",
2294 l
[0] = tcg_temp_new();
2295 l
[1] = tcg_temp_new();
2296 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, l
[0], l
[1]);
2297 cris_cc_mask(dc
, CC_MASK_NZ
);
2298 cris_alu(dc
, CC_OP_BOUND
, cpu_R
[dc
->op2
], l
[0], l
[1], 4);
2299 do_postinc(dc
, memsize
);
2303 static int dec_addc_mr(CPUCRISState
*env
, DisasContext
*dc
)
2307 LOG_DIS("addc [$r%u%s, $r%u\n",
2308 dc
->op1
, dc
->postinc
? "+]" : "]",
2311 cris_evaluate_flags(dc
);
2313 /* Set for this insn. */
2314 dc
->flags_x
= X_FLAG
;
2316 cris_alu_m_alloc_temps(t
);
2317 insn_len
= dec_prep_alu_m(env
, dc
, 0, 4, t
[0], t
[1]);
2318 cris_cc_mask(dc
, CC_MASK_NZVC
);
2319 cris_alu(dc
, CC_OP_ADDC
, cpu_R
[dc
->op2
], t
[0], t
[1], 4);
2324 static int dec_sub_m(CPUCRISState
*env
, DisasContext
*dc
)
2327 int memsize
= memsize_zz(dc
);
2329 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2330 memsize_char(memsize
),
2331 dc
->op1
, dc
->postinc
? "+]" : "]",
2332 dc
->op2
, dc
->ir
, dc
->zzsize
);
2334 cris_alu_m_alloc_temps(t
);
2335 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2336 cris_cc_mask(dc
, CC_MASK_NZVC
);
2337 cris_alu(dc
, CC_OP_SUB
, cpu_R
[dc
->op2
], t
[0], t
[1], memsize
);
2338 do_postinc(dc
, memsize
);
2342 static int dec_or_m(CPUCRISState
*env
, DisasContext
*dc
)
2345 int memsize
= memsize_zz(dc
);
2347 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2348 memsize_char(memsize
),
2349 dc
->op1
, dc
->postinc
? "+]" : "]",
2352 cris_alu_m_alloc_temps(t
);
2353 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2354 cris_cc_mask(dc
, CC_MASK_NZ
);
2355 cris_alu(dc
, CC_OP_OR
,
2356 cpu_R
[dc
->op2
], t
[0], t
[1], memsize_zz(dc
));
2357 do_postinc(dc
, memsize
);
2361 static int dec_move_mp(CPUCRISState
*env
, DisasContext
*dc
)
2364 int memsize
= memsize_zz(dc
);
2367 LOG_DIS("move.%c [$r%u%s, $p%u\n",
2368 memsize_char(memsize
),
2370 dc
->postinc
? "+]" : "]",
2373 cris_alu_m_alloc_temps(t
);
2374 insn_len
= dec_prep_alu_m(env
, dc
, 0, memsize
, t
[0], t
[1]);
2375 cris_cc_mask(dc
, 0);
2376 if (dc
->op2
== PR_CCS
) {
2377 cris_evaluate_flags(dc
);
2378 if (dc
->tb_flags
& U_FLAG
) {
2379 /* User space is not allowed to touch all flags. */
2380 tcg_gen_andi_tl(t
[1], t
[1], 0x39f);
2381 tcg_gen_andi_tl(t
[0], cpu_PR
[PR_CCS
], ~0x39f);
2382 tcg_gen_or_tl(t
[1], t
[0], t
[1]);
2386 t_gen_mov_preg_TN(dc
, dc
->op2
, t
[1]);
2388 do_postinc(dc
, memsize
);
2392 static int dec_move_pm(CPUCRISState
*env
, DisasContext
*dc
)
2397 memsize
= preg_sizes
[dc
->op2
];
2399 LOG_DIS("move.%c $p%u, [$r%u%s\n",
2400 memsize_char(memsize
),
2401 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]");
2403 /* prepare store. Address in T0, value in T1. */
2404 if (dc
->op2
== PR_CCS
) {
2405 cris_evaluate_flags(dc
);
2407 t0
= tcg_temp_new();
2408 t_gen_mov_TN_preg(t0
, dc
->op2
);
2409 cris_flush_cc_state(dc
);
2410 gen_store(dc
, cpu_R
[dc
->op1
], t0
, memsize
);
2412 cris_cc_mask(dc
, 0);
2414 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2419 static int dec_movem_mr(CPUCRISState
*env
, DisasContext
*dc
)
2425 int nr
= dc
->op2
+ 1;
2427 LOG_DIS("movem [$r%u%s, $r%u\n", dc
->op1
,
2428 dc
->postinc
? "+]" : "]", dc
->op2
);
2430 addr
= tcg_temp_new();
2431 /* There are probably better ways of doing this. */
2432 cris_flush_cc_state(dc
);
2433 for (i
= 0; i
< (nr
>> 1); i
++) {
2434 tmp
[i
] = tcg_temp_new_i64();
2435 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2436 gen_load64(dc
, tmp
[i
], addr
);
2439 tmp32
= tcg_temp_new_i32();
2440 tcg_gen_addi_tl(addr
, cpu_R
[dc
->op1
], i
* 8);
2441 gen_load(dc
, tmp32
, addr
, 4, 0);
2446 for (i
= 0; i
< (nr
>> 1); i
++) {
2447 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2], tmp
[i
]);
2448 tcg_gen_shri_i64(tmp
[i
], tmp
[i
], 32);
2449 tcg_gen_extrl_i64_i32(cpu_R
[i
* 2 + 1], tmp
[i
]);
2452 tcg_gen_mov_tl(cpu_R
[dc
->op2
], tmp32
);
2455 /* writeback the updated pointer value. */
2457 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], nr
* 4);
2460 /* gen_load might want to evaluate the previous insns flags. */
2461 cris_cc_mask(dc
, 0);
2465 static int dec_movem_rm(CPUCRISState
*env
, DisasContext
*dc
)
2471 LOG_DIS("movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2472 dc
->postinc
? "+]" : "]");
2474 cris_flush_cc_state(dc
);
2476 tmp
= tcg_temp_new();
2477 addr
= tcg_temp_new();
2478 tcg_gen_movi_tl(tmp
, 4);
2479 tcg_gen_mov_tl(addr
, cpu_R
[dc
->op1
]);
2480 for (i
= 0; i
<= dc
->op2
; i
++) {
2481 /* Displace addr. */
2482 /* Perform the store. */
2483 gen_store(dc
, addr
, cpu_R
[i
], 4);
2484 tcg_gen_add_tl(addr
, addr
, tmp
);
2487 tcg_gen_mov_tl(cpu_R
[dc
->op1
], addr
);
2489 cris_cc_mask(dc
, 0);
2493 static int dec_move_rm(CPUCRISState
*env
, DisasContext
*dc
)
2497 memsize
= memsize_zz(dc
);
2499 LOG_DIS("move.%c $r%u, [$r%u]\n",
2500 memsize_char(memsize
), dc
->op2
, dc
->op1
);
2502 /* prepare store. */
2503 cris_flush_cc_state(dc
);
2504 gen_store(dc
, cpu_R
[dc
->op1
], cpu_R
[dc
->op2
], memsize
);
2507 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], memsize
);
2509 cris_cc_mask(dc
, 0);
2513 static int dec_lapcq(CPUCRISState
*env
, DisasContext
*dc
)
2515 LOG_DIS("lapcq %x, $r%u\n",
2516 dc
->pc
+ dc
->op1
*2, dc
->op2
);
2517 cris_cc_mask(dc
, 0);
2518 tcg_gen_movi_tl(cpu_R
[dc
->op2
], dc
->pc
+ dc
->op1
* 2);
2522 static int dec_lapc_im(CPUCRISState
*env
, DisasContext
*dc
)
2530 cris_cc_mask(dc
, 0);
2531 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2532 LOG_DIS("lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
);
2536 tcg_gen_movi_tl(cpu_R
[rd
], pc
);
2540 /* Jump to special reg. */
2541 static int dec_jump_p(CPUCRISState
*env
, DisasContext
*dc
)
2543 LOG_DIS("jump $p%u\n", dc
->op2
);
2545 if (dc
->op2
== PR_CCS
) {
2546 cris_evaluate_flags(dc
);
2548 t_gen_mov_TN_preg(env_btarget
, dc
->op2
);
2549 /* rete will often have low bit set to indicate delayslot. */
2550 tcg_gen_andi_tl(env_btarget
, env_btarget
, ~1);
2551 cris_cc_mask(dc
, 0);
2552 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2556 /* Jump and save. */
2557 static int dec_jas_r(CPUCRISState
*env
, DisasContext
*dc
)
2560 LOG_DIS("jas $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2561 cris_cc_mask(dc
, 0);
2562 /* Store the return address in Pd. */
2563 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2567 c
= tcg_constant_tl(dc
->pc
+ 4);
2568 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2570 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2574 static int dec_jas_im(CPUCRISState
*env
, DisasContext
*dc
)
2579 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2581 LOG_DIS("jas 0x%x\n", imm
);
2582 cris_cc_mask(dc
, 0);
2583 c
= tcg_constant_tl(dc
->pc
+ 8);
2584 /* Store the return address in Pd. */
2585 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2588 cris_prepare_jmp(dc
, JMP_DIRECT
);
2592 static int dec_jasc_im(CPUCRISState
*env
, DisasContext
*dc
)
2597 imm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2599 LOG_DIS("jasc 0x%x\n", imm
);
2600 cris_cc_mask(dc
, 0);
2601 c
= tcg_constant_tl(dc
->pc
+ 8 + 4);
2602 /* Store the return address in Pd. */
2603 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2606 cris_prepare_jmp(dc
, JMP_DIRECT
);
2610 static int dec_jasc_r(CPUCRISState
*env
, DisasContext
*dc
)
2613 LOG_DIS("jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
);
2614 cris_cc_mask(dc
, 0);
2615 /* Store the return address in Pd. */
2616 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2617 c
= tcg_constant_tl(dc
->pc
+ 4 + 4);
2618 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2619 cris_prepare_jmp(dc
, JMP_INDIRECT
);
2623 static int dec_bcc_im(CPUCRISState
*env
, DisasContext
*dc
)
2626 uint32_t cond
= dc
->op2
;
2628 offset
= cris_fetch(env
, dc
, dc
->pc
+ 2, 2, 1);
2630 LOG_DIS("b%s %d pc=%x dst=%x\n",
2631 cc_name(cond
), offset
,
2632 dc
->pc
, dc
->pc
+ offset
);
2634 cris_cc_mask(dc
, 0);
2635 /* op2 holds the condition-code. */
2636 cris_prepare_cc_branch(dc
, offset
, cond
);
2640 static int dec_bas_im(CPUCRISState
*env
, DisasContext
*dc
)
2645 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2647 LOG_DIS("bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2648 cris_cc_mask(dc
, 0);
2649 c
= tcg_constant_tl(dc
->pc
+ 8);
2650 /* Store the return address in Pd. */
2651 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2653 dc
->jmp_pc
= dc
->pc
+ simm
;
2654 cris_prepare_jmp(dc
, JMP_DIRECT
);
2658 static int dec_basc_im(CPUCRISState
*env
, DisasContext
*dc
)
2662 simm
= cris_fetch(env
, dc
, dc
->pc
+ 2, 4, 0);
2664 LOG_DIS("basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
);
2665 cris_cc_mask(dc
, 0);
2666 c
= tcg_constant_tl(dc
->pc
+ 12);
2667 /* Store the return address in Pd. */
2668 t_gen_mov_preg_TN(dc
, dc
->op2
, c
);
2670 dc
->jmp_pc
= dc
->pc
+ simm
;
2671 cris_prepare_jmp(dc
, JMP_DIRECT
);
2675 static int dec_rfe_etc(CPUCRISState
*env
, DisasContext
*dc
)
2677 cris_cc_mask(dc
, 0);
2679 if (dc
->op2
== 15) {
2680 tcg_gen_st_i32(tcg_constant_i32(1), tcg_env
,
2681 -offsetof(CRISCPU
, env
) + offsetof(CPUState
, halted
));
2682 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2683 t_gen_raise_exception(EXCP_HLT
);
2684 dc
->base
.is_jmp
= DISAS_NORETURN
;
2688 switch (dc
->op2
& 7) {
2692 cris_evaluate_flags(dc
);
2693 gen_helper_rfe(tcg_env
);
2694 dc
->base
.is_jmp
= DISAS_UPDATE
;
2695 dc
->cpustate_changed
= true;
2700 cris_evaluate_flags(dc
);
2701 gen_helper_rfn(tcg_env
);
2702 dc
->base
.is_jmp
= DISAS_UPDATE
;
2703 dc
->cpustate_changed
= true;
2706 LOG_DIS("break %d\n", dc
->op1
);
2707 cris_evaluate_flags(dc
);
2709 tcg_gen_movi_tl(env_pc
, dc
->pc
+ 2);
2711 /* Breaks start at 16 in the exception vector. */
2712 t_gen_movi_env_TN(trap_vector
, dc
->op1
+ 16);
2713 t_gen_raise_exception(EXCP_BREAK
);
2714 dc
->base
.is_jmp
= DISAS_NORETURN
;
2717 printf("op2=%x\n", dc
->op2
);
2725 static int dec_ftag_fidx_d_m(CPUCRISState
*env
, DisasContext
*dc
)
2730 static int dec_ftag_fidx_i_m(CPUCRISState
*env
, DisasContext
*dc
)
2735 static int dec_null(CPUCRISState
*env
, DisasContext
*dc
)
2737 printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2738 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2744 static const struct decoder_info
{
2749 int (*dec
)(CPUCRISState
*env
, DisasContext
*dc
);
2751 /* Order matters here. */
2752 {DEC_MOVEQ
, dec_moveq
},
2753 {DEC_BTSTQ
, dec_btstq
},
2754 {DEC_CMPQ
, dec_cmpq
},
2755 {DEC_ADDOQ
, dec_addoq
},
2756 {DEC_ADDQ
, dec_addq
},
2757 {DEC_SUBQ
, dec_subq
},
2758 {DEC_ANDQ
, dec_andq
},
2760 {DEC_ASRQ
, dec_asrq
},
2761 {DEC_LSLQ
, dec_lslq
},
2762 {DEC_LSRQ
, dec_lsrq
},
2763 {DEC_BCCQ
, dec_bccq
},
2765 {DEC_BCC_IM
, dec_bcc_im
},
2766 {DEC_JAS_IM
, dec_jas_im
},
2767 {DEC_JAS_R
, dec_jas_r
},
2768 {DEC_JASC_IM
, dec_jasc_im
},
2769 {DEC_JASC_R
, dec_jasc_r
},
2770 {DEC_BAS_IM
, dec_bas_im
},
2771 {DEC_BASC_IM
, dec_basc_im
},
2772 {DEC_JUMP_P
, dec_jump_p
},
2773 {DEC_LAPC_IM
, dec_lapc_im
},
2774 {DEC_LAPCQ
, dec_lapcq
},
2776 {DEC_RFE_ETC
, dec_rfe_etc
},
2777 {DEC_ADDC_MR
, dec_addc_mr
},
2779 {DEC_MOVE_MP
, dec_move_mp
},
2780 {DEC_MOVE_PM
, dec_move_pm
},
2781 {DEC_MOVEM_MR
, dec_movem_mr
},
2782 {DEC_MOVEM_RM
, dec_movem_rm
},
2783 {DEC_MOVE_PR
, dec_move_pr
},
2784 {DEC_SCC_R
, dec_scc_r
},
2785 {DEC_SETF
, dec_setclrf
},
2786 {DEC_CLEARF
, dec_setclrf
},
2788 {DEC_MOVE_SR
, dec_move_sr
},
2789 {DEC_MOVE_RP
, dec_move_rp
},
2790 {DEC_SWAP_R
, dec_swap_r
},
2791 {DEC_ABS_R
, dec_abs_r
},
2792 {DEC_LZ_R
, dec_lz_r
},
2793 {DEC_MOVE_RS
, dec_move_rs
},
2794 {DEC_BTST_R
, dec_btst_r
},
2795 {DEC_ADDC_R
, dec_addc_r
},
2797 {DEC_DSTEP_R
, dec_dstep_r
},
2798 {DEC_XOR_R
, dec_xor_r
},
2799 {DEC_MCP_R
, dec_mcp_r
},
2800 {DEC_CMP_R
, dec_cmp_r
},
2802 {DEC_ADDI_R
, dec_addi_r
},
2803 {DEC_ADDI_ACR
, dec_addi_acr
},
2805 {DEC_ADD_R
, dec_add_r
},
2806 {DEC_SUB_R
, dec_sub_r
},
2808 {DEC_ADDU_R
, dec_addu_r
},
2809 {DEC_ADDS_R
, dec_adds_r
},
2810 {DEC_SUBU_R
, dec_subu_r
},
2811 {DEC_SUBS_R
, dec_subs_r
},
2812 {DEC_LSL_R
, dec_lsl_r
},
2814 {DEC_AND_R
, dec_and_r
},
2815 {DEC_OR_R
, dec_or_r
},
2816 {DEC_BOUND_R
, dec_bound_r
},
2817 {DEC_ASR_R
, dec_asr_r
},
2818 {DEC_LSR_R
, dec_lsr_r
},
2820 {DEC_MOVU_R
, dec_movu_r
},
2821 {DEC_MOVS_R
, dec_movs_r
},
2822 {DEC_NEG_R
, dec_neg_r
},
2823 {DEC_MOVE_R
, dec_move_r
},
2825 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2826 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2828 {DEC_MULS_R
, dec_muls_r
},
2829 {DEC_MULU_R
, dec_mulu_r
},
2831 {DEC_ADDU_M
, dec_addu_m
},
2832 {DEC_ADDS_M
, dec_adds_m
},
2833 {DEC_SUBU_M
, dec_subu_m
},
2834 {DEC_SUBS_M
, dec_subs_m
},
2836 {DEC_CMPU_M
, dec_cmpu_m
},
2837 {DEC_CMPS_M
, dec_cmps_m
},
2838 {DEC_MOVU_M
, dec_movu_m
},
2839 {DEC_MOVS_M
, dec_movs_m
},
2841 {DEC_CMP_M
, dec_cmp_m
},
2842 {DEC_ADDO_M
, dec_addo_m
},
2843 {DEC_BOUND_M
, dec_bound_m
},
2844 {DEC_ADD_M
, dec_add_m
},
2845 {DEC_SUB_M
, dec_sub_m
},
2846 {DEC_AND_M
, dec_and_m
},
2847 {DEC_OR_M
, dec_or_m
},
2848 {DEC_MOVE_RM
, dec_move_rm
},
2849 {DEC_TEST_M
, dec_test_m
},
2850 {DEC_MOVE_MR
, dec_move_mr
},
2855 static unsigned int crisv32_decoder(CPUCRISState
*env
, DisasContext
*dc
)
2860 /* Load a halfword onto the instruction register. */
2861 dc
->ir
= cris_fetch(env
, dc
, dc
->pc
, 2, 0);
2863 /* Now decode it. */
2864 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2865 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2866 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2867 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2868 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2869 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2871 /* Large switch for all insns. */
2872 for (i
= 0; i
< ARRAY_SIZE(decinfo
); i
++) {
2873 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
) {
2874 insn_len
= decinfo
[i
].dec(env
, dc
);
2879 #if !defined(CONFIG_USER_ONLY)
2880 /* Single-stepping ? */
2881 if (dc
->tb_flags
& S_FLAG
) {
2882 TCGLabel
*l1
= gen_new_label();
2883 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_PR
[PR_SPC
], dc
->pc
, l1
);
2884 /* We treat SPC as a break with an odd trap vector. */
2885 cris_evaluate_flags(dc
);
2886 t_gen_movi_env_TN(trap_vector
, 3);
2887 tcg_gen_movi_tl(env_pc
, dc
->pc
+ insn_len
);
2888 tcg_gen_movi_tl(cpu_PR
[PR_SPC
], dc
->pc
+ insn_len
);
2889 t_gen_raise_exception(EXCP_BREAK
);
2896 #include "translate_v10.c.inc"
2899 * Delay slots on QEMU/CRIS.
2901 * If an exception hits on a delayslot, the core will let ERP (the Exception
2902 * Return Pointer) point to the branch (the previous) insn and set the lsb to
2903 * to give SW a hint that the exception actually hit on the dslot.
2905 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
2906 * the core and any jmp to an odd addresses will mask off that lsb. It is
2907 * simply there to let sw know there was an exception on a dslot.
2909 * When the software returns from an exception, the branch will re-execute.
2910 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
2911 * and the branch and delayslot don't share pages.
2913 * The TB containing the branch insn will set up env->btarget and evaluate
2914 * env->btaken. When the translation loop exits we will note that the branch
2915 * sequence is broken and let env->dslot be the size of the branch insn (those
2918 * The TB containing the delayslot will have the PC of its real insn (i.e no lsb
2919 * set). It will also expect to have env->dslot setup with the size of the
2920 * delay slot so that env->pc - env->dslot point to the branch insn. This TB
2921 * will execute the dslot and take the branch, either to btarget or just one
2924 * When exceptions occur, we check for env->dslot in do_interrupt to detect
2925 * broken branch sequences and setup $erp accordingly (i.e let it point to the
2926 * branch and set lsb). Then env->dslot gets cleared so that the exception
2927 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
2928 * masked off and we will reexecute the branch insn.
2932 static void cris_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2934 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2935 CPUCRISState
*env
= cpu_env(cs
);
2936 uint32_t tb_flags
= dc
->base
.tb
->flags
;
2939 if (env
->pregs
[PR_VR
] == 32) {
2940 dc
->decoder
= crisv32_decoder
;
2941 dc
->clear_locked_irq
= 0;
2943 dc
->decoder
= crisv10_decoder
;
2944 dc
->clear_locked_irq
= 1;
2948 * Odd PC indicates that branch is rexecuting due to exception in the
2949 * delayslot, like in real hw.
2951 pc_start
= dc
->base
.pc_first
& ~1;
2952 dc
->base
.pc_first
= pc_start
;
2953 dc
->base
.pc_next
= pc_start
;
2955 dc
->cpu
= env_archcpu(env
);
2958 dc
->mem_index
= cpu_mmu_index(cs
, false);
2959 dc
->flags_uptodate
= 1;
2960 dc
->flags_x
= tb_flags
& X_FLAG
;
2961 dc
->cc_x_uptodate
= 0;
2964 dc
->clear_prefix
= 0;
2965 dc
->cpustate_changed
= 0;
2967 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
2968 dc
->cc_size_uptodate
= -1;
2970 /* Decode TB flags. */
2971 dc
->tb_flags
= tb_flags
& (S_FLAG
| P_FLAG
| U_FLAG
| X_FLAG
| PFIX_FLAG
);
2972 dc
->delayed_branch
= !!(tb_flags
& 7);
2973 if (dc
->delayed_branch
) {
2974 dc
->jmp
= JMP_INDIRECT
;
2976 dc
->jmp
= JMP_NOJMP
;
2980 static void cris_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
2984 static void cris_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
2986 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2988 tcg_gen_insn_start(dc
->delayed_branch
== 1 ? dc
->ppc
| 1 : dc
->pc
);
2991 static void cris_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2993 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
2994 unsigned int insn_len
;
2997 LOG_DIS("%8.8x:\t", dc
->pc
);
3001 insn_len
= dc
->decoder(cpu_env(cs
), dc
);
3004 dc
->base
.pc_next
+= insn_len
;
3006 if (dc
->base
.is_jmp
== DISAS_NORETURN
) {
3011 cris_clear_x_flag(dc
);
3015 * All branches are delayed branches, handled immediately below.
3016 * We don't expect to see odd combinations of exit conditions.
3018 assert(dc
->base
.is_jmp
== DISAS_NEXT
|| dc
->cpustate_changed
);
3020 if (dc
->delayed_branch
&& --dc
->delayed_branch
== 0) {
3021 dc
->base
.is_jmp
= DISAS_DBRANCH
;
3025 if (dc
->base
.is_jmp
!= DISAS_NEXT
) {
3029 /* Force an update if the per-tb cpu state has changed. */
3030 if (dc
->cpustate_changed
) {
3031 dc
->base
.is_jmp
= DISAS_UPDATE_NEXT
;
3036 * FIXME: Only the first insn in the TB should cross a page boundary.
3037 * If we can detect the length of the next insn easily, we should.
3038 * In the meantime, simply stop when we do cross.
3040 if ((dc
->pc
^ dc
->base
.pc_first
) & TARGET_PAGE_MASK
) {
3041 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
3045 static void cris_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
3047 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
3048 DisasJumpType is_jmp
= dc
->base
.is_jmp
;
3049 target_ulong npc
= dc
->pc
;
3051 if (is_jmp
== DISAS_NORETURN
) {
3052 /* If we have a broken branch+delayslot sequence, it's too late. */
3053 assert(dc
->delayed_branch
!= 1);
3057 if (dc
->clear_locked_irq
) {
3058 t_gen_movi_env_TN(locked_irq
, 0);
3061 /* Broken branch+delayslot sequence. */
3062 if (dc
->delayed_branch
== 1) {
3063 /* Set env->dslot to the size of the branch insn. */
3064 t_gen_movi_env_TN(dslot
, dc
->pc
- dc
->ppc
);
3065 cris_store_direct_jmp(dc
);
3068 cris_evaluate_flags(dc
);
3070 /* Evaluate delayed branch destination and fold to another is_jmp case. */
3071 if (is_jmp
== DISAS_DBRANCH
) {
3072 if (dc
->base
.tb
->flags
& 7) {
3073 t_gen_movi_env_TN(dslot
, 0);
3079 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE_NEXT
: DISAS_TOO_MANY
;
3084 * Use a conditional branch if either taken or not-taken path
3085 * can use goto_tb. If neither can, then treat it as indirect.
3087 if (likely(!dc
->cpustate_changed
)
3088 && (use_goto_tb(dc
, dc
->jmp_pc
) || use_goto_tb(dc
, npc
))) {
3089 TCGLabel
*not_taken
= gen_new_label();
3091 tcg_gen_brcondi_tl(TCG_COND_EQ
, env_btaken
, 0, not_taken
);
3092 gen_goto_tb(dc
, 1, dc
->jmp_pc
);
3093 gen_set_label(not_taken
);
3095 /* not-taken case handled below. */
3096 is_jmp
= DISAS_TOO_MANY
;
3099 tcg_gen_movi_tl(env_btarget
, dc
->jmp_pc
);
3103 tcg_gen_movcond_tl(TCG_COND_NE
, env_pc
,
3104 env_btaken
, tcg_constant_tl(0),
3105 env_btarget
, tcg_constant_tl(npc
));
3106 is_jmp
= dc
->cpustate_changed
? DISAS_UPDATE
: DISAS_JUMP
;
3109 * We have now consumed btaken and btarget. Hint to the
3110 * tcg compiler that the writeback to env may be dropped.
3112 tcg_gen_discard_tl(env_btaken
);
3113 tcg_gen_discard_tl(env_btarget
);
3117 g_assert_not_reached();
3122 case DISAS_TOO_MANY
:
3123 gen_goto_tb(dc
, 0, npc
);
3125 case DISAS_UPDATE_NEXT
:
3126 tcg_gen_movi_tl(env_pc
, npc
);
3129 tcg_gen_lookup_and_goto_ptr();
3132 /* Indicate that interrupts must be re-evaluated before the next TB. */
3133 tcg_gen_exit_tb(NULL
, 0);
3136 g_assert_not_reached();
3140 static const TranslatorOps cris_tr_ops
= {
3141 .init_disas_context
= cris_tr_init_disas_context
,
3142 .tb_start
= cris_tr_tb_start
,
3143 .insn_start
= cris_tr_insn_start
,
3144 .translate_insn
= cris_tr_translate_insn
,
3145 .tb_stop
= cris_tr_tb_stop
,
3148 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int *max_insns
,
3149 vaddr pc
, void *host_pc
)
3152 translator_loop(cs
, tb
, max_insns
, pc
, host_pc
, &cris_tr_ops
, &dc
.base
);
3155 void cris_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
3157 CPUCRISState
*env
= cpu_env(cs
);
3158 const char * const *regnames
;
3159 const char * const *pregnames
;
3165 if (env
->pregs
[PR_VR
] < 32) {
3166 pregnames
= pregnames_v10
;
3167 regnames
= regnames_v10
;
3169 pregnames
= pregnames_v32
;
3170 regnames
= regnames_v32
;
3173 qemu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3174 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3175 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
3177 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
);
3180 for (i
= 0; i
< 16; i
++) {
3181 qemu_fprintf(f
, "%s=%8.8x ", regnames
[i
], env
->regs
[i
]);
3182 if ((i
+ 1) % 4 == 0) {
3183 qemu_fprintf(f
, "\n");
3186 qemu_fprintf(f
, "\nspecial regs:\n");
3187 for (i
= 0; i
< 16; i
++) {
3188 qemu_fprintf(f
, "%s=%8.8x ", pregnames
[i
], env
->pregs
[i
]);
3189 if ((i
+ 1) % 4 == 0) {
3190 qemu_fprintf(f
, "\n");
3193 if (env
->pregs
[PR_VR
] >= 32) {
3194 uint32_t srs
= env
->pregs
[PR_SRS
];
3195 qemu_fprintf(f
, "\nsupport function regs bank %x:\n", srs
);
3196 if (srs
< ARRAY_SIZE(env
->sregs
)) {
3197 for (i
= 0; i
< 16; i
++) {
3198 qemu_fprintf(f
, "s%2.2d=%8.8x ",
3199 i
, env
->sregs
[srs
][i
]);
3200 if ((i
+ 1) % 4 == 0) {
3201 qemu_fprintf(f
, "\n");
3206 qemu_fprintf(f
, "\n\n");
3210 void cris_initialize_tcg(void)
3214 cc_x
= tcg_global_mem_new(tcg_env
,
3215 offsetof(CPUCRISState
, cc_x
), "cc_x");
3216 cc_src
= tcg_global_mem_new(tcg_env
,
3217 offsetof(CPUCRISState
, cc_src
), "cc_src");
3218 cc_dest
= tcg_global_mem_new(tcg_env
,
3219 offsetof(CPUCRISState
, cc_dest
),
3221 cc_result
= tcg_global_mem_new(tcg_env
,
3222 offsetof(CPUCRISState
, cc_result
),
3224 cc_op
= tcg_global_mem_new(tcg_env
,
3225 offsetof(CPUCRISState
, cc_op
), "cc_op");
3226 cc_size
= tcg_global_mem_new(tcg_env
,
3227 offsetof(CPUCRISState
, cc_size
),
3229 cc_mask
= tcg_global_mem_new(tcg_env
,
3230 offsetof(CPUCRISState
, cc_mask
),
3233 env_pc
= tcg_global_mem_new(tcg_env
,
3234 offsetof(CPUCRISState
, pc
),
3236 env_btarget
= tcg_global_mem_new(tcg_env
,
3237 offsetof(CPUCRISState
, btarget
),
3239 env_btaken
= tcg_global_mem_new(tcg_env
,
3240 offsetof(CPUCRISState
, btaken
),
3242 for (i
= 0; i
< 16; i
++) {
3243 cpu_R
[i
] = tcg_global_mem_new(tcg_env
,
3244 offsetof(CPUCRISState
, regs
[i
]),
3247 for (i
= 0; i
< 16; i
++) {
3248 cpu_PR
[i
] = tcg_global_mem_new(tcg_env
,
3249 offsetof(CPUCRISState
, pregs
[i
]),