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 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, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * The condition code translation is in desperate need of attention. It's slow
25 * and for system simulation it seems buggy. It sucks.
40 #include "crisv32-decode.h"
41 #include "qemu-common.h"
58 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
59 #define BUG_ON(x) ({if (x) BUG();})
63 /* Used by the decoder. */
64 #define EXTRACT_FIELD(src, start, end) \
65 (((src) >> start) & ((1 << (end - start + 1)) - 1))
67 #define CC_MASK_NZ 0xc
68 #define CC_MASK_NZV 0xe
69 #define CC_MASK_NZVC 0xf
70 #define CC_MASK_RNZV 0x10e
86 /* This is the state at translation time. */
87 typedef struct DisasContext
{
96 unsigned int zsize
, zzsize
;
104 int flags_live
; /* Wether or not $ccs is uptodate. */
105 int flagx_live
; /* Wether or not flags_x has the x flag known at
108 int clear_x
; /* Clear x after this insn? */
110 int user
; /* user or kernel mode. */
119 struct TranslationBlock
*tb
;
120 int singlestep_enabled
;
123 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
);
124 static void gen_BUG(DisasContext
*dc
, char *file
, int line
)
126 printf ("BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
127 fprintf (logfile
, "BUG: pc=%x %s %d\n", dc
->pc
, file
, line
);
128 cpu_dump_state (dc
->env
, stdout
, fprintf
, 0);
130 cris_prepare_jmp (dc
, 0x70000000 + line
);
133 const char *regnames
[] =
135 "$r0", "$r1", "$r2", "$r3",
136 "$r4", "$r5", "$r6", "$r7",
137 "$r8", "$r9", "$r10", "$r11",
138 "$r12", "$r13", "$sp", "$acr",
140 const char *pregnames
[] =
142 "$bz", "$vr", "$pid", "$srs",
143 "$wz", "$exs", "$eda", "$mof",
144 "$dz", "$ebp", "$erp", "$srp",
145 "$nrp", "$ccs", "$usp", "$spc",
148 /* We need this table to handle preg-moves with implicit width. */
160 #define t_gen_mov_TN_env(tn, member) \
161 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
162 #define t_gen_mov_env_TN(member, tn) \
163 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
165 static inline void t_gen_mov_TN_reg(TCGv tn
, int r
)
168 fprintf(stderr
, "wrong register read $r%d\n", r
);
169 tcg_gen_mov_tl(tn
, cpu_R
[r
]);
171 static inline void t_gen_mov_reg_TN(int r
, TCGv tn
)
174 fprintf(stderr
, "wrong register write $r%d\n", r
);
175 tcg_gen_mov_tl(cpu_R
[r
], tn
);
178 static inline void _t_gen_mov_TN_env(TCGv tn
, int offset
)
180 if (offset
> sizeof (CPUState
))
181 fprintf(stderr
, "wrong load from env from off=%d\n", offset
);
182 tcg_gen_ld_tl(tn
, cpu_env
, offset
);
184 static inline void _t_gen_mov_env_TN(int offset
, TCGv tn
)
186 if (offset
> sizeof (CPUState
))
187 fprintf(stderr
, "wrong store to env at off=%d\n", offset
);
188 tcg_gen_st_tl(tn
, cpu_env
, offset
);
191 static inline void t_gen_mov_TN_preg(TCGv tn
, int r
)
194 fprintf(stderr
, "wrong register read $p%d\n", r
);
195 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
196 tcg_gen_mov_tl(tn
, tcg_const_tl(0));
198 tcg_gen_mov_tl(tn
, tcg_const_tl(32));
199 else if (r
== PR_EXS
) {
200 printf("read from EXS!\n");
201 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
203 else if (r
== PR_EDA
) {
204 printf("read from EDA!\n");
205 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
208 tcg_gen_mov_tl(tn
, cpu_PR
[r
]);
210 static inline void t_gen_mov_preg_TN(int r
, TCGv tn
)
213 fprintf(stderr
, "wrong register write $p%d\n", r
);
214 if (r
== PR_BZ
|| r
== PR_WZ
|| r
== PR_DZ
)
216 else if (r
== PR_SRS
)
217 tcg_gen_andi_tl(cpu_PR
[r
], tn
, 3);
220 tcg_gen_helper_0_0(helper_tlb_flush
);
222 tcg_gen_mov_tl(cpu_PR
[r
], tn
);
226 static inline void t_gen_mov_TN_im(TCGv tn
, int32_t val
)
228 tcg_gen_movi_tl(tn
, val
);
231 static void t_gen_lsl(TCGv d
, TCGv a
, TCGv b
)
235 l1
= gen_new_label();
236 /* Speculative shift. */
237 tcg_gen_shl_tl(d
, a
, b
);
238 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
239 /* Clear dst if shift operands were to large. */
240 tcg_gen_movi_tl(d
, 0);
244 static void t_gen_lsr(TCGv d
, TCGv a
, TCGv b
)
248 l1
= gen_new_label();
249 /* Speculative shift. */
250 tcg_gen_shr_tl(d
, a
, b
);
251 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
252 /* Clear dst if shift operands were to large. */
253 tcg_gen_movi_tl(d
, 0);
257 static void t_gen_asr(TCGv d
, TCGv a
, TCGv b
)
261 l1
= gen_new_label();
262 /* Speculative shift. */
263 tcg_gen_sar_tl(d
, a
, b
);
264 tcg_gen_brcond_tl(TCG_COND_LE
, b
, tcg_const_tl(31), l1
);
265 /* Clear dst if shift operands were to large. */
266 tcg_gen_sar_tl(d
, a
, tcg_const_tl(30));
270 /* 64-bit signed mul, lower result in d and upper in d2. */
271 static void t_gen_muls(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
275 t0
= tcg_temp_new(TCG_TYPE_I64
);
276 t1
= tcg_temp_new(TCG_TYPE_I64
);
278 tcg_gen_ext32s_i64(t0
, a
);
279 tcg_gen_ext32s_i64(t1
, b
);
280 tcg_gen_mul_i64(t0
, t0
, t1
);
282 tcg_gen_trunc_i64_i32(d
, t0
);
283 tcg_gen_shri_i64(t0
, t0
, 32);
284 tcg_gen_trunc_i64_i32(d2
, t0
);
286 tcg_gen_discard_i64(t0
);
287 tcg_gen_discard_i64(t1
);
290 /* 64-bit unsigned muls, lower result in d and upper in d2. */
291 static void t_gen_mulu(TCGv d
, TCGv d2
, TCGv a
, TCGv b
)
295 t0
= tcg_temp_new(TCG_TYPE_I64
);
296 t1
= tcg_temp_new(TCG_TYPE_I64
);
298 tcg_gen_extu_i32_i64(t0
, a
);
299 tcg_gen_extu_i32_i64(t1
, b
);
300 tcg_gen_mul_i64(t0
, t0
, t1
);
302 tcg_gen_trunc_i64_i32(d
, t0
);
303 tcg_gen_shri_i64(t0
, t0
, 32);
304 tcg_gen_trunc_i64_i32(d2
, t0
);
306 tcg_gen_discard_i64(t0
);
307 tcg_gen_discard_i64(t1
);
310 /* 32bit branch-free binary search for counting leading zeros. */
311 static void t_gen_lz_i32(TCGv d
, TCGv x
)
315 y
= tcg_temp_new(TCG_TYPE_I32
);
316 m
= tcg_temp_new(TCG_TYPE_I32
);
317 n
= tcg_temp_new(TCG_TYPE_I32
);
320 tcg_gen_shri_i32(y
, x
, 16);
321 tcg_gen_sub_i32(y
, tcg_const_i32(0), y
);
323 /* m = (y >> 16) & 16 */
324 tcg_gen_sari_i32(m
, y
, 16);
325 tcg_gen_andi_i32(m
, m
, 16);
328 tcg_gen_sub_i32(n
, tcg_const_i32(16), m
);
330 tcg_gen_shr_i32(x
, x
, m
);
333 tcg_gen_subi_i32(y
, x
, 0x100);
334 /* m = (y >> 16) & 8 */
335 tcg_gen_sari_i32(m
, y
, 16);
336 tcg_gen_andi_i32(m
, m
, 8);
338 tcg_gen_add_i32(n
, n
, m
);
340 tcg_gen_shl_i32(x
, x
, m
);
343 tcg_gen_subi_i32(y
, x
, 0x1000);
344 /* m = (y >> 16) & 4 */
345 tcg_gen_sari_i32(m
, y
, 16);
346 tcg_gen_andi_i32(m
, m
, 4);
348 tcg_gen_add_i32(n
, n
, m
);
350 tcg_gen_shl_i32(x
, x
, m
);
353 tcg_gen_subi_i32(y
, x
, 0x4000);
354 /* m = (y >> 16) & 2 */
355 tcg_gen_sari_i32(m
, y
, 16);
356 tcg_gen_andi_i32(m
, m
, 2);
358 tcg_gen_add_i32(n
, n
, m
);
360 tcg_gen_shl_i32(x
, x
, m
);
363 tcg_gen_shri_i32(y
, x
, 14);
364 /* m = y & ~(y >> 1) */
365 tcg_gen_sari_i32(m
, y
, 1);
366 tcg_gen_xori_i32(m
, m
, 0xffffffff);
367 tcg_gen_and_i32(m
, m
, y
);
370 tcg_gen_addi_i32(d
, n
, 2);
371 tcg_gen_sub_i32(d
, d
, m
);
373 tcg_gen_discard_i32(y
);
374 tcg_gen_discard_i32(m
);
375 tcg_gen_discard_i32(n
);
378 static void t_gen_cris_dstep(TCGv d
, TCGv s
)
382 l1
= gen_new_label();
389 tcg_gen_shli_tl(d
, d
, 1);
390 tcg_gen_brcond_tl(TCG_COND_LTU
, d
, s
, l1
);
391 tcg_gen_sub_tl(d
, d
, s
);
395 /* Extended arithmetics on CRIS. */
396 static inline void t_gen_add_flag(TCGv d
, int flag
)
400 c
= tcg_temp_new(TCG_TYPE_TL
);
401 t_gen_mov_TN_preg(c
, PR_CCS
);
402 /* Propagate carry into d. */
403 tcg_gen_andi_tl(c
, c
, 1 << flag
);
405 tcg_gen_shri_tl(c
, c
, flag
);
406 tcg_gen_add_tl(d
, d
, c
);
407 tcg_gen_discard_tl(c
);
410 static inline void t_gen_addx_carry(TCGv d
)
414 x
= tcg_temp_new(TCG_TYPE_TL
);
415 c
= tcg_temp_new(TCG_TYPE_TL
);
416 t_gen_mov_TN_preg(x
, PR_CCS
);
417 tcg_gen_mov_tl(c
, x
);
419 /* Propagate carry into d if X is set. Branch free. */
420 tcg_gen_andi_tl(c
, c
, C_FLAG
);
421 tcg_gen_andi_tl(x
, x
, X_FLAG
);
422 tcg_gen_shri_tl(x
, x
, 4);
424 tcg_gen_and_tl(x
, x
, c
);
425 tcg_gen_add_tl(d
, d
, x
);
426 tcg_gen_discard_tl(x
);
427 tcg_gen_discard_tl(c
);
430 static inline void t_gen_subx_carry(TCGv d
)
434 x
= tcg_temp_new(TCG_TYPE_TL
);
435 c
= tcg_temp_new(TCG_TYPE_TL
);
436 t_gen_mov_TN_preg(x
, PR_CCS
);
437 tcg_gen_mov_tl(c
, x
);
439 /* Propagate carry into d if X is set. Branch free. */
440 tcg_gen_andi_tl(c
, c
, C_FLAG
);
441 tcg_gen_andi_tl(x
, x
, X_FLAG
);
442 tcg_gen_shri_tl(x
, x
, 4);
444 tcg_gen_and_tl(x
, x
, c
);
445 tcg_gen_sub_tl(d
, d
, x
);
446 tcg_gen_discard_tl(x
);
447 tcg_gen_discard_tl(c
);
450 /* Swap the two bytes within each half word of the s operand.
451 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
452 static inline void t_gen_swapb(TCGv d
, TCGv s
)
456 t
= tcg_temp_new(TCG_TYPE_TL
);
457 org_s
= tcg_temp_new(TCG_TYPE_TL
);
459 /* d and s may refer to the same object. */
460 tcg_gen_mov_tl(org_s
, s
);
461 tcg_gen_shli_tl(t
, org_s
, 8);
462 tcg_gen_andi_tl(d
, t
, 0xff00ff00);
463 tcg_gen_shri_tl(t
, org_s
, 8);
464 tcg_gen_andi_tl(t
, t
, 0x00ff00ff);
465 tcg_gen_or_tl(d
, d
, t
);
466 tcg_gen_discard_tl(t
);
467 tcg_gen_discard_tl(org_s
);
470 /* Swap the halfwords of the s operand. */
471 static inline void t_gen_swapw(TCGv d
, TCGv s
)
474 /* d and s refer the same object. */
475 t
= tcg_temp_new(TCG_TYPE_TL
);
476 tcg_gen_mov_tl(t
, s
);
477 tcg_gen_shli_tl(d
, t
, 16);
478 tcg_gen_shri_tl(t
, t
, 16);
479 tcg_gen_or_tl(d
, d
, t
);
480 tcg_gen_discard_tl(t
);
483 /* Reverse the within each byte.
484 T0 = (((T0 << 7) & 0x80808080) |
485 ((T0 << 5) & 0x40404040) |
486 ((T0 << 3) & 0x20202020) |
487 ((T0 << 1) & 0x10101010) |
488 ((T0 >> 1) & 0x08080808) |
489 ((T0 >> 3) & 0x04040404) |
490 ((T0 >> 5) & 0x02020202) |
491 ((T0 >> 7) & 0x01010101));
493 static inline void t_gen_swapr(TCGv d
, TCGv s
)
496 int shift
; /* LSL when positive, LSR when negative. */
511 /* d and s refer the same object. */
512 t
= tcg_temp_new(TCG_TYPE_TL
);
513 org_s
= tcg_temp_new(TCG_TYPE_TL
);
514 tcg_gen_mov_tl(org_s
, s
);
516 tcg_gen_shli_tl(t
, org_s
, bitrev
[0].shift
);
517 tcg_gen_andi_tl(d
, t
, bitrev
[0].mask
);
518 for (i
= 1; i
< sizeof bitrev
/ sizeof bitrev
[0]; i
++) {
519 if (bitrev
[i
].shift
>= 0) {
520 tcg_gen_shli_tl(t
, org_s
, bitrev
[i
].shift
);
522 tcg_gen_shri_tl(t
, org_s
, -bitrev
[i
].shift
);
524 tcg_gen_andi_tl(t
, t
, bitrev
[i
].mask
);
525 tcg_gen_or_tl(d
, d
, t
);
527 tcg_gen_discard_tl(t
);
528 tcg_gen_discard_tl(org_s
);
531 static void gen_goto_tb(DisasContext
*dc
, int n
, target_ulong dest
)
533 TranslationBlock
*tb
;
535 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
537 tcg_gen_movi_tl(env_pc
, dest
);
538 tcg_gen_exit_tb((long)tb
+ n
);
540 tcg_gen_mov_tl(env_pc
, cpu_T
[0]);
545 /* Sign extend at translation time. */
546 static int sign_extend(unsigned int val
, unsigned int width
)
558 static inline void cris_clear_x_flag(DisasContext
*dc
)
561 || (dc
->flagx_live
&& dc
->flags_x
)
562 || dc
->cc_op
!= CC_OP_FLAGS
)
563 tcg_gen_andi_i32(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], ~X_FLAG
);
568 static void cris_evaluate_flags(DisasContext
*dc
)
570 if (!dc
->flags_live
) {
571 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
572 tcg_gen_movi_tl(cc_size
, dc
->cc_size
);
573 tcg_gen_movi_tl(cc_mask
, dc
->cc_mask
);
578 tcg_gen_helper_0_0(helper_evaluate_flags_mcp
);
581 tcg_gen_helper_0_0(helper_evaluate_flags_muls
);
584 tcg_gen_helper_0_0(helper_evaluate_flags_mulu
);
590 tcg_gen_helper_0_0(helper_evaluate_flags_move_4
);
593 tcg_gen_helper_0_0(helper_evaluate_flags_move_2
);
596 tcg_gen_helper_0_0(helper_evaluate_flags
);
608 tcg_gen_helper_0_0(helper_evaluate_flags_alu_4
);
611 tcg_gen_helper_0_0(helper_evaluate_flags
);
621 static void cris_cc_mask(DisasContext
*dc
, unsigned int mask
)
625 /* Check if we need to evaluate the condition codes due to
627 ovl
= (dc
->cc_mask
^ mask
) & ~mask
;
629 /* TODO: optimize this case. It trigs all the time. */
630 cris_evaluate_flags (dc
);
641 static void cris_update_cc_op(DisasContext
*dc
, int op
, int size
)
648 /* op is the operation.
649 T0, T1 are the operands.
650 dst is the destination reg.
652 static void crisv32_alu_op(DisasContext
*dc
, int op
, int rd
, int size
)
656 cris_update_cc_op(dc
, op
, size
);
657 tcg_gen_mov_tl(cc_dest
, cpu_T
[0]);
659 /* FIXME: This shouldn't be needed. But we don't pass the
660 tests without it. Investigate. */
661 t_gen_mov_env_TN(cc_x_live
, tcg_const_tl(dc
->flagx_live
));
662 t_gen_mov_env_TN(cc_x
, tcg_const_tl(dc
->flags_x
));
665 /* Emit the ALU insns. */
669 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
670 /* Extended arithmetics. */
671 t_gen_addx_carry(cpu_T
[0]);
674 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
675 t_gen_add_flag(cpu_T
[0], 0); /* C_FLAG. */
678 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
679 t_gen_add_flag(cpu_T
[0], 8); /* R_FLAG. */
682 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
683 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
684 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
685 /* CRIS flag evaluation needs ~src. */
686 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
688 /* Extended arithmetics. */
689 t_gen_subx_carry(cpu_T
[0]);
692 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
695 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
698 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
701 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
704 t_gen_lsl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
707 t_gen_lsr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
710 t_gen_asr(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
713 /* Hopefully the TCG backend recognizes this pattern
714 and makes a real neg out of it. */
715 tcg_gen_sub_tl(cpu_T
[0], tcg_const_tl(0), cpu_T
[1]);
716 /* Extended arithmetics. */
717 t_gen_subx_carry(cpu_T
[0]);
720 t_gen_lz_i32(cpu_T
[0], cpu_T
[1]);
729 mof
= tcg_temp_new(TCG_TYPE_TL
);
730 t_gen_muls(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
731 t_gen_mov_preg_TN(PR_MOF
, mof
);
732 tcg_gen_discard_tl(mof
);
738 mof
= tcg_temp_new(TCG_TYPE_TL
);
739 t_gen_mulu(cpu_T
[0], mof
, cpu_T
[0], cpu_T
[1]);
740 t_gen_mov_preg_TN(PR_MOF
, mof
);
741 tcg_gen_discard_tl(mof
);
745 t_gen_cris_dstep(cpu_T
[0], cpu_T
[1]);
750 l1
= gen_new_label();
751 tcg_gen_brcond_tl(TCG_COND_LEU
,
752 cpu_T
[0], cpu_T
[1], l1
);
753 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
758 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
759 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
760 /* CRIS flag evaluation needs ~src. */
761 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
762 /* CRIS flag evaluation needs ~src. */
763 tcg_gen_xori_tl(cpu_T
[1], cpu_T
[1], -1);
765 /* Extended arithmetics. */
766 t_gen_subx_carry(cpu_T
[0]);
770 fprintf (logfile
, "illegal ALU op.\n");
776 tcg_gen_mov_tl(cc_src
, cpu_T
[1]);
779 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
781 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
786 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
788 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
789 t_gen_mov_TN_reg(cpu_T
[0], rd
);
791 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xff);
793 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], ~0xffff);
794 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
795 t_gen_mov_reg_TN(rd
, cpu_T
[0]);
796 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
800 tcg_gen_mov_tl(cc_result
, cpu_T
[0]);
803 /* TODO: Optimize this. */
805 cris_evaluate_flags(dc
);
809 static int arith_cc(DisasContext
*dc
)
813 case CC_OP_ADD
: return 1;
814 case CC_OP_SUB
: return 1;
815 case CC_OP_LSL
: return 1;
816 case CC_OP_LSR
: return 1;
817 case CC_OP_ASR
: return 1;
818 case CC_OP_CMP
: return 1;
826 static void gen_tst_cc (DisasContext
*dc
, int cond
)
830 /* TODO: optimize more condition codes. */
831 arith_opt
= arith_cc(dc
) && !dc
->flags_live
;
835 gen_op_tst_cc_eq_fast ();
837 cris_evaluate_flags(dc
);
843 gen_op_tst_cc_ne_fast ();
845 cris_evaluate_flags(dc
);
850 cris_evaluate_flags(dc
);
854 cris_evaluate_flags(dc
);
858 cris_evaluate_flags(dc
);
862 cris_evaluate_flags(dc
);
867 gen_op_tst_cc_pl_fast ();
869 cris_evaluate_flags(dc
);
875 gen_op_tst_cc_mi_fast ();
877 cris_evaluate_flags(dc
);
882 cris_evaluate_flags(dc
);
886 cris_evaluate_flags(dc
);
890 cris_evaluate_flags(dc
);
894 cris_evaluate_flags(dc
);
898 cris_evaluate_flags(dc
);
902 cris_evaluate_flags(dc
);
906 cris_evaluate_flags(dc
);
910 cris_evaluate_flags(dc
);
911 gen_op_movl_T0_im (1);
919 static void cris_prepare_cc_branch (DisasContext
*dc
, int offset
, int cond
)
921 /* This helps us re-schedule the micro-code to insns in delay-slots
922 before the actual jump. */
923 dc
->delayed_branch
= 2;
924 dc
->delayed_pc
= dc
->pc
+ offset
;
928 gen_tst_cc (dc
, cond
);
929 gen_op_evaluate_bcc ();
931 tcg_gen_movi_tl(env_btarget
, dc
->delayed_pc
);
935 /* Dynamic jumps, when the dest is in a live reg for example. */
936 void cris_prepare_dyn_jmp (DisasContext
*dc
)
938 /* This helps us re-schedule the micro-code to insns in delay-slots
939 before the actual jump. */
940 dc
->delayed_branch
= 2;
945 void cris_prepare_jmp (DisasContext
*dc
, uint32_t dst
)
947 /* This helps us re-schedule the micro-code to insns in delay-slots
948 before the actual jump. */
949 dc
->delayed_branch
= 2;
950 dc
->delayed_pc
= dst
;
955 void gen_load(DisasContext
*dc
, TCGv dst
, TCGv addr
,
956 unsigned int size
, int sign
)
958 int mem_index
= cpu_mmu_index(dc
->env
);
960 /* FIXME: qemu_ld does not act as a barrier? */
961 tcg_gen_helper_0_0(helper_dummy
);
962 cris_evaluate_flags(dc
);
965 tcg_gen_qemu_ld8s(dst
, addr
, mem_index
);
967 tcg_gen_qemu_ld8u(dst
, addr
, mem_index
);
969 else if (size
== 2) {
971 tcg_gen_qemu_ld16s(dst
, addr
, mem_index
);
973 tcg_gen_qemu_ld16u(dst
, addr
, mem_index
);
976 tcg_gen_qemu_ld32s(dst
, addr
, mem_index
);
980 void gen_store_T0_T1 (DisasContext
*dc
, unsigned int size
)
982 int mem_index
= cpu_mmu_index(dc
->env
);
984 /* FIXME: qemu_st does not act as a barrier? */
985 tcg_gen_helper_0_0(helper_dummy
);
986 cris_evaluate_flags(dc
);
988 /* Remember, operands are flipped. CRIS has reversed order. */
990 tcg_gen_qemu_st8(cpu_T
[1], cpu_T
[0], mem_index
);
992 tcg_gen_qemu_st16(cpu_T
[1], cpu_T
[0], mem_index
);
994 tcg_gen_qemu_st32(cpu_T
[1], cpu_T
[0], mem_index
);
997 static inline void t_gen_sext(TCGv d
, TCGv s
, int size
)
1000 tcg_gen_ext8s_i32(d
, s
);
1002 tcg_gen_ext16s_i32(d
, s
);
1004 tcg_gen_mov_tl(d
, s
);
1007 static inline void t_gen_zext(TCGv d
, TCGv s
, int size
)
1009 /* TCG-FIXME: this is not optimal. Many archs have fast zext insns. */
1011 tcg_gen_andi_i32(d
, s
, 0xff);
1013 tcg_gen_andi_i32(d
, s
, 0xffff);
1015 tcg_gen_mov_tl(d
, s
);
1019 static char memsize_char(int size
)
1023 case 1: return 'b'; break;
1024 case 2: return 'w'; break;
1025 case 4: return 'd'; break;
1033 static unsigned int memsize_z(DisasContext
*dc
)
1035 return dc
->zsize
+ 1;
1038 static unsigned int memsize_zz(DisasContext
*dc
)
1049 static inline void do_postinc (DisasContext
*dc
, int size
)
1052 tcg_gen_addi_tl(cpu_R
[dc
->op1
], cpu_R
[dc
->op1
], size
);
1056 static void dec_prep_move_r(DisasContext
*dc
, int rs
, int rd
,
1057 int size
, int s_ext
)
1060 t_gen_sext(cpu_T
[1], cpu_R
[rs
], size
);
1062 t_gen_zext(cpu_T
[1], cpu_R
[rs
], size
);
1065 /* Prepare T0 and T1 for a register alu operation.
1066 s_ext decides if the operand1 should be sign-extended or zero-extended when
1068 static void dec_prep_alu_r(DisasContext
*dc
, int rs
, int rd
,
1069 int size
, int s_ext
)
1071 dec_prep_move_r(dc
, rs
, rd
, size
, s_ext
);
1074 t_gen_sext(cpu_T
[0], cpu_R
[rd
], size
);
1076 t_gen_zext(cpu_T
[0], cpu_R
[rd
], size
);
1079 /* Prepare T0 and T1 for a memory + alu operation.
1080 s_ext decides if the operand1 should be sign-extended or zero-extended when
1082 static int dec_prep_alu_m(DisasContext
*dc
, int s_ext
, int memsize
)
1084 unsigned int rs
, rd
;
1091 is_imm
= rs
== 15 && dc
->postinc
;
1093 /* Load [$rs] onto T1. */
1095 insn_len
= 2 + memsize
;
1099 imm
= ldl_code(dc
->pc
+ 2);
1102 imm
= sign_extend(imm
, (memsize
* 8) - 1);
1110 DIS(fprintf (logfile
, "imm=%x rd=%d sext=%d ms=%d\n",
1111 imm
, rd
, s_ext
, memsize
));
1112 tcg_gen_movi_tl(cpu_T
[1], imm
);
1115 gen_load(dc
, cpu_T
[1], cpu_R
[rs
], memsize
, 0);
1117 t_gen_sext(cpu_T
[1], cpu_T
[1], memsize
);
1119 t_gen_zext(cpu_T
[1], cpu_T
[1], memsize
);
1122 /* put dest in T0. */
1123 t_gen_mov_TN_reg(cpu_T
[0], rd
);
1128 static const char *cc_name(int cc
)
1130 static char *cc_names
[16] = {
1131 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1132 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1135 return cc_names
[cc
];
1139 /* Start of insn decoders. */
1141 static unsigned int dec_bccq(DisasContext
*dc
)
1145 uint32_t cond
= dc
->op2
;
1148 offset
= EXTRACT_FIELD (dc
->ir
, 1, 7);
1149 sign
= EXTRACT_FIELD(dc
->ir
, 0, 0);
1152 offset
|= sign
<< 8;
1154 offset
= sign_extend(offset
, 8);
1156 /* op2 holds the condition-code. */
1157 cris_cc_mask(dc
, 0);
1158 cris_prepare_cc_branch (dc
, offset
, cond
);
1161 static unsigned int dec_addoq(DisasContext
*dc
)
1165 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 7);
1166 imm
= sign_extend(dc
->op1
, 7);
1168 DIS(fprintf (logfile
, "addoq %d, $r%u\n", imm
, dc
->op2
));
1169 cris_cc_mask(dc
, 0);
1170 /* Fetch register operand, */
1171 tcg_gen_addi_tl(cpu_R
[R_ACR
], cpu_R
[dc
->op2
], imm
);
1174 static unsigned int dec_addq(DisasContext
*dc
)
1176 DIS(fprintf (logfile
, "addq %u, $r%u\n", dc
->op1
, dc
->op2
));
1178 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1180 cris_cc_mask(dc
, CC_MASK_NZVC
);
1181 /* Fetch register operand, */
1182 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1183 tcg_gen_movi_tl(cpu_T
[1], dc
->op1
);
1184 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1187 static unsigned int dec_moveq(DisasContext
*dc
)
1191 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1192 imm
= sign_extend(dc
->op1
, 5);
1193 DIS(fprintf (logfile
, "moveq %d, $r%u\n", imm
, dc
->op2
));
1195 t_gen_mov_reg_TN(dc
->op2
, tcg_const_tl(imm
));
1198 static unsigned int dec_subq(DisasContext
*dc
)
1200 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1202 DIS(fprintf (logfile
, "subq %u, $r%u\n", dc
->op1
, dc
->op2
));
1204 cris_cc_mask(dc
, CC_MASK_NZVC
);
1205 /* Fetch register operand, */
1206 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1207 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1208 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1211 static unsigned int dec_cmpq(DisasContext
*dc
)
1214 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1215 imm
= sign_extend(dc
->op1
, 5);
1217 DIS(fprintf (logfile
, "cmpq %d, $r%d\n", imm
, dc
->op2
));
1218 cris_cc_mask(dc
, CC_MASK_NZVC
);
1219 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1220 t_gen_mov_TN_im(cpu_T
[1], imm
);
1221 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1224 static unsigned int dec_andq(DisasContext
*dc
)
1227 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1228 imm
= sign_extend(dc
->op1
, 5);
1230 DIS(fprintf (logfile
, "andq %d, $r%d\n", imm
, dc
->op2
));
1231 cris_cc_mask(dc
, CC_MASK_NZ
);
1232 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1233 t_gen_mov_TN_im(cpu_T
[1], imm
);
1234 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, 4);
1237 static unsigned int dec_orq(DisasContext
*dc
)
1240 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 5);
1241 imm
= sign_extend(dc
->op1
, 5);
1242 DIS(fprintf (logfile
, "orq %d, $r%d\n", imm
, dc
->op2
));
1243 cris_cc_mask(dc
, CC_MASK_NZ
);
1244 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1245 t_gen_mov_TN_im(cpu_T
[1], imm
);
1246 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, 4);
1249 static unsigned int dec_btstq(DisasContext
*dc
)
1251 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1252 DIS(fprintf (logfile
, "btstq %u, $r%d\n", dc
->op1
, dc
->op2
));
1253 cris_cc_mask(dc
, CC_MASK_NZ
);
1254 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1255 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1256 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1258 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1259 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1263 static unsigned int dec_asrq(DisasContext
*dc
)
1265 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1266 DIS(fprintf (logfile
, "asrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1267 cris_cc_mask(dc
, CC_MASK_NZ
);
1268 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1269 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1270 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, 4);
1273 static unsigned int dec_lslq(DisasContext
*dc
)
1275 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1276 DIS(fprintf (logfile
, "lslq %u, $r%d\n", dc
->op1
, dc
->op2
));
1278 cris_cc_mask(dc
, CC_MASK_NZ
);
1279 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1280 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1281 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, 4);
1284 static unsigned int dec_lsrq(DisasContext
*dc
)
1286 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 4);
1287 DIS(fprintf (logfile
, "lsrq %u, $r%d\n", dc
->op1
, dc
->op2
));
1289 cris_cc_mask(dc
, CC_MASK_NZ
);
1290 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1291 t_gen_mov_TN_im(cpu_T
[1], dc
->op1
);
1292 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, 4);
1296 static unsigned int dec_move_r(DisasContext
*dc
)
1298 int size
= memsize_zz(dc
);
1300 DIS(fprintf (logfile
, "move.%c $r%u, $r%u\n",
1301 memsize_char(size
), dc
->op1
, dc
->op2
));
1303 cris_cc_mask(dc
, CC_MASK_NZ
);
1304 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1305 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, size
);
1309 static unsigned int dec_scc_r(DisasContext
*dc
)
1313 DIS(fprintf (logfile
, "s%s $r%u\n",
1314 cc_name(cond
), dc
->op1
));
1318 gen_tst_cc (dc
, cond
);
1319 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1322 tcg_gen_movi_tl(cpu_T
[1], 1);
1324 cris_cc_mask(dc
, 0);
1325 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1329 static unsigned int dec_and_r(DisasContext
*dc
)
1331 int size
= memsize_zz(dc
);
1333 DIS(fprintf (logfile
, "and.%c $r%u, $r%u\n",
1334 memsize_char(size
), dc
->op1
, dc
->op2
));
1335 cris_cc_mask(dc
, CC_MASK_NZ
);
1336 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1337 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, size
);
1341 static unsigned int dec_lz_r(DisasContext
*dc
)
1343 DIS(fprintf (logfile
, "lz $r%u, $r%u\n",
1345 cris_cc_mask(dc
, CC_MASK_NZ
);
1346 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1347 crisv32_alu_op(dc
, CC_OP_LZ
, dc
->op2
, 4);
1351 static unsigned int dec_lsl_r(DisasContext
*dc
)
1353 int size
= memsize_zz(dc
);
1355 DIS(fprintf (logfile
, "lsl.%c $r%u, $r%u\n",
1356 memsize_char(size
), dc
->op1
, dc
->op2
));
1357 cris_cc_mask(dc
, CC_MASK_NZ
);
1358 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1359 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1360 crisv32_alu_op(dc
, CC_OP_LSL
, dc
->op2
, size
);
1364 static unsigned int dec_lsr_r(DisasContext
*dc
)
1366 int size
= memsize_zz(dc
);
1368 DIS(fprintf (logfile
, "lsr.%c $r%u, $r%u\n",
1369 memsize_char(size
), dc
->op1
, dc
->op2
));
1370 cris_cc_mask(dc
, CC_MASK_NZ
);
1371 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1372 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1373 crisv32_alu_op(dc
, CC_OP_LSR
, dc
->op2
, size
);
1377 static unsigned int dec_asr_r(DisasContext
*dc
)
1379 int size
= memsize_zz(dc
);
1381 DIS(fprintf (logfile
, "asr.%c $r%u, $r%u\n",
1382 memsize_char(size
), dc
->op1
, dc
->op2
));
1383 cris_cc_mask(dc
, CC_MASK_NZ
);
1384 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1385 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 63);
1386 crisv32_alu_op(dc
, CC_OP_ASR
, dc
->op2
, size
);
1390 static unsigned int dec_muls_r(DisasContext
*dc
)
1392 int size
= memsize_zz(dc
);
1394 DIS(fprintf (logfile
, "muls.%c $r%u, $r%u\n",
1395 memsize_char(size
), dc
->op1
, dc
->op2
));
1396 cris_cc_mask(dc
, CC_MASK_NZV
);
1397 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 1);
1398 t_gen_sext(cpu_T
[0], cpu_T
[0], size
);
1399 crisv32_alu_op(dc
, CC_OP_MULS
, dc
->op2
, 4);
1403 static unsigned int dec_mulu_r(DisasContext
*dc
)
1405 int size
= memsize_zz(dc
);
1407 DIS(fprintf (logfile
, "mulu.%c $r%u, $r%u\n",
1408 memsize_char(size
), dc
->op1
, dc
->op2
));
1409 cris_cc_mask(dc
, CC_MASK_NZV
);
1410 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1411 t_gen_zext(cpu_T
[0], cpu_T
[0], size
);
1412 crisv32_alu_op(dc
, CC_OP_MULU
, dc
->op2
, 4);
1417 static unsigned int dec_dstep_r(DisasContext
*dc
)
1419 DIS(fprintf (logfile
, "dstep $r%u, $r%u\n", dc
->op1
, dc
->op2
));
1420 cris_cc_mask(dc
, CC_MASK_NZ
);
1421 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1422 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1423 crisv32_alu_op(dc
, CC_OP_DSTEP
, dc
->op2
, 4);
1427 static unsigned int dec_xor_r(DisasContext
*dc
)
1429 int size
= memsize_zz(dc
);
1430 DIS(fprintf (logfile
, "xor.%c $r%u, $r%u\n",
1431 memsize_char(size
), dc
->op1
, dc
->op2
));
1432 BUG_ON(size
!= 4); /* xor is dword. */
1433 cris_cc_mask(dc
, CC_MASK_NZ
);
1434 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1435 crisv32_alu_op(dc
, CC_OP_XOR
, dc
->op2
, 4);
1439 static unsigned int dec_bound_r(DisasContext
*dc
)
1441 int size
= memsize_zz(dc
);
1442 DIS(fprintf (logfile
, "bound.%c $r%u, $r%u\n",
1443 memsize_char(size
), dc
->op1
, dc
->op2
));
1444 cris_cc_mask(dc
, CC_MASK_NZ
);
1445 /* TODO: needs optmimization. */
1446 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1447 /* rd should be 4. */
1448 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1449 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
1453 static unsigned int dec_cmp_r(DisasContext
*dc
)
1455 int size
= memsize_zz(dc
);
1456 DIS(fprintf (logfile
, "cmp.%c $r%u, $r%u\n",
1457 memsize_char(size
), dc
->op1
, dc
->op2
));
1458 cris_cc_mask(dc
, CC_MASK_NZVC
);
1459 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1460 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, size
);
1464 static unsigned int dec_abs_r(DisasContext
*dc
)
1468 DIS(fprintf (logfile
, "abs $r%u, $r%u\n",
1470 cris_cc_mask(dc
, CC_MASK_NZ
);
1471 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1473 /* TODO: consider a branch free approach. */
1474 l1
= gen_new_label();
1475 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_T
[1], tcg_const_tl(0), l1
);
1476 tcg_gen_sub_tl(cpu_T
[1], tcg_const_tl(0), cpu_T
[1]);
1478 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1482 static unsigned int dec_add_r(DisasContext
*dc
)
1484 int size
= memsize_zz(dc
);
1485 DIS(fprintf (logfile
, "add.%c $r%u, $r%u\n",
1486 memsize_char(size
), dc
->op1
, dc
->op2
));
1487 cris_cc_mask(dc
, CC_MASK_NZVC
);
1488 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1489 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, size
);
1493 static unsigned int dec_addc_r(DisasContext
*dc
)
1495 DIS(fprintf (logfile
, "addc $r%u, $r%u\n",
1497 cris_evaluate_flags(dc
);
1498 cris_cc_mask(dc
, CC_MASK_NZVC
);
1499 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1500 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
1504 static unsigned int dec_mcp_r(DisasContext
*dc
)
1506 DIS(fprintf (logfile
, "mcp $p%u, $r%u\n",
1508 cris_evaluate_flags(dc
);
1509 cris_cc_mask(dc
, CC_MASK_RNZV
);
1510 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1511 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1512 crisv32_alu_op(dc
, CC_OP_MCP
, dc
->op1
, 4);
1517 static char * swapmode_name(int mode
, char *modename
) {
1520 modename
[i
++] = 'n';
1522 modename
[i
++] = 'w';
1524 modename
[i
++] = 'b';
1526 modename
[i
++] = 'r';
1532 static unsigned int dec_swap_r(DisasContext
*dc
)
1534 DIS(char modename
[4]);
1535 DIS(fprintf (logfile
, "swap%s $r%u\n",
1536 swapmode_name(dc
->op2
, modename
), dc
->op1
));
1538 cris_cc_mask(dc
, CC_MASK_NZ
);
1539 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1541 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], -1);
1543 t_gen_swapw(cpu_T
[0], cpu_T
[0]);
1545 t_gen_swapb(cpu_T
[0], cpu_T
[0]);
1547 t_gen_swapr(cpu_T
[0], cpu_T
[0]);
1548 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1549 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1553 static unsigned int dec_or_r(DisasContext
*dc
)
1555 int size
= memsize_zz(dc
);
1556 DIS(fprintf (logfile
, "or.%c $r%u, $r%u\n",
1557 memsize_char(size
), dc
->op1
, dc
->op2
));
1558 cris_cc_mask(dc
, CC_MASK_NZ
);
1559 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1560 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, size
);
1564 static unsigned int dec_addi_r(DisasContext
*dc
)
1566 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u\n",
1567 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1568 cris_cc_mask(dc
, 0);
1569 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1570 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1571 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1572 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
1576 static unsigned int dec_addi_acr(DisasContext
*dc
)
1578 DIS(fprintf (logfile
, "addi.%c $r%u, $r%u, $acr\n",
1579 memsize_char(memsize_zz(dc
)), dc
->op2
, dc
->op1
));
1580 cris_cc_mask(dc
, 0);
1581 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1582 t_gen_lsl(cpu_T
[0], cpu_T
[0], tcg_const_tl(dc
->zzsize
));
1584 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1585 t_gen_mov_reg_TN(R_ACR
, cpu_T
[0]);
1589 static unsigned int dec_neg_r(DisasContext
*dc
)
1591 int size
= memsize_zz(dc
);
1592 DIS(fprintf (logfile
, "neg.%c $r%u, $r%u\n",
1593 memsize_char(size
), dc
->op1
, dc
->op2
));
1594 cris_cc_mask(dc
, CC_MASK_NZVC
);
1595 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1596 crisv32_alu_op(dc
, CC_OP_NEG
, dc
->op2
, size
);
1600 static unsigned int dec_btst_r(DisasContext
*dc
)
1602 DIS(fprintf (logfile
, "btst $r%u, $r%u\n",
1604 cris_cc_mask(dc
, CC_MASK_NZ
);
1605 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, 4, 0);
1606 crisv32_alu_op(dc
, CC_OP_BTST
, dc
->op2
, 4);
1608 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1609 t_gen_mov_preg_TN(PR_CCS
, cpu_T
[0]);
1614 static unsigned int dec_sub_r(DisasContext
*dc
)
1616 int size
= memsize_zz(dc
);
1617 DIS(fprintf (logfile
, "sub.%c $r%u, $r%u\n",
1618 memsize_char(size
), dc
->op1
, dc
->op2
));
1619 cris_cc_mask(dc
, CC_MASK_NZVC
);
1620 dec_prep_alu_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1621 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, size
);
1625 /* Zero extension. From size to dword. */
1626 static unsigned int dec_movu_r(DisasContext
*dc
)
1628 int size
= memsize_z(dc
);
1629 DIS(fprintf (logfile
, "movu.%c $r%u, $r%u\n",
1633 cris_cc_mask(dc
, CC_MASK_NZ
);
1634 dec_prep_move_r(dc
, dc
->op1
, dc
->op2
, size
, 0);
1635 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1639 /* Sign extension. From size to dword. */
1640 static unsigned int dec_movs_r(DisasContext
*dc
)
1642 int size
= memsize_z(dc
);
1643 DIS(fprintf (logfile
, "movs.%c $r%u, $r%u\n",
1647 cris_cc_mask(dc
, CC_MASK_NZ
);
1648 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1649 /* Size can only be qi or hi. */
1650 t_gen_sext(cpu_T
[1], cpu_T
[0], size
);
1651 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1655 /* zero extension. From size to dword. */
1656 static unsigned int dec_addu_r(DisasContext
*dc
)
1658 int size
= memsize_z(dc
);
1659 DIS(fprintf (logfile
, "addu.%c $r%u, $r%u\n",
1663 cris_cc_mask(dc
, CC_MASK_NZVC
);
1664 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1665 /* Size can only be qi or hi. */
1666 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1667 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1668 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1672 /* Sign extension. From size to dword. */
1673 static unsigned int dec_adds_r(DisasContext
*dc
)
1675 int size
= memsize_z(dc
);
1676 DIS(fprintf (logfile
, "adds.%c $r%u, $r%u\n",
1680 cris_cc_mask(dc
, CC_MASK_NZVC
);
1681 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1682 /* Size can only be qi or hi. */
1683 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1684 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1686 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1690 /* Zero extension. From size to dword. */
1691 static unsigned int dec_subu_r(DisasContext
*dc
)
1693 int size
= memsize_z(dc
);
1694 DIS(fprintf (logfile
, "subu.%c $r%u, $r%u\n",
1698 cris_cc_mask(dc
, CC_MASK_NZVC
);
1699 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1700 /* Size can only be qi or hi. */
1701 t_gen_zext(cpu_T
[1], cpu_T
[1], size
);
1702 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1703 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1707 /* Sign extension. From size to dword. */
1708 static unsigned int dec_subs_r(DisasContext
*dc
)
1710 int size
= memsize_z(dc
);
1711 DIS(fprintf (logfile
, "subs.%c $r%u, $r%u\n",
1715 cris_cc_mask(dc
, CC_MASK_NZVC
);
1716 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
1717 /* Size can only be qi or hi. */
1718 t_gen_sext(cpu_T
[1], cpu_T
[1], size
);
1719 t_gen_mov_TN_reg(cpu_T
[0], dc
->op2
);
1720 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1724 static unsigned int dec_setclrf(DisasContext
*dc
)
1727 int set
= (~dc
->opcode
>> 2) & 1;
1729 flags
= (EXTRACT_FIELD(dc
->ir
, 12, 15) << 4)
1730 | EXTRACT_FIELD(dc
->ir
, 0, 3);
1731 DIS(fprintf (logfile
, "set=%d flags=%x\n", set
, flags
));
1732 if (set
&& flags
== 0)
1733 DIS(fprintf (logfile
, "nop\n"));
1734 else if (!set
&& (flags
& 0x20))
1735 DIS(fprintf (logfile
, "di\n"));
1737 DIS(fprintf (logfile
, "%sf %x\n",
1738 set
? "set" : "clr",
1741 if (set
&& (flags
& X_FLAG
)) {
1746 /* Simply decode the flags. */
1747 cris_evaluate_flags (dc
);
1748 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1749 tcg_gen_movi_tl(cc_op
, dc
->cc_op
);
1760 static unsigned int dec_move_rs(DisasContext
*dc
)
1762 DIS(fprintf (logfile
, "move $r%u, $s%u\n", dc
->op1
, dc
->op2
));
1763 cris_cc_mask(dc
, 0);
1764 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1765 gen_op_movl_sreg_T0(dc
->op2
);
1767 #if !defined(CONFIG_USER_ONLY)
1769 gen_op_movl_tlb_hi_T0();
1770 else if (dc
->op2
== 5) { /* srs is checked at runtime. */
1771 tcg_gen_helper_0_1(helper_tlb_update
, cpu_T
[0]);
1772 gen_op_movl_tlb_lo_T0();
1777 static unsigned int dec_move_sr(DisasContext
*dc
)
1779 DIS(fprintf (logfile
, "move $s%u, $r%u\n", dc
->op2
, dc
->op1
));
1780 cris_cc_mask(dc
, 0);
1781 gen_op_movl_T0_sreg(dc
->op2
);
1782 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1783 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, 4);
1786 static unsigned int dec_move_rp(DisasContext
*dc
)
1788 DIS(fprintf (logfile
, "move $r%u, $p%u\n", dc
->op1
, dc
->op2
));
1789 cris_cc_mask(dc
, 0);
1791 if (dc
->op2
== PR_CCS
) {
1792 cris_evaluate_flags(dc
);
1793 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1795 /* User space is not allowed to touch all flags. */
1796 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0x39f);
1797 tcg_gen_andi_tl(cpu_T
[1], cpu_PR
[PR_CCS
], ~0x39f);
1798 tcg_gen_or_tl(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1802 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
1804 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
1805 if (dc
->op2
== PR_CCS
) {
1806 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
1811 static unsigned int dec_move_pr(DisasContext
*dc
)
1813 DIS(fprintf (logfile
, "move $p%u, $r%u\n", dc
->op1
, dc
->op2
));
1814 cris_cc_mask(dc
, 0);
1815 /* Support register 0 is hardwired to zero.
1816 Treat it specially. */
1818 tcg_gen_movi_tl(cpu_T
[1], 0);
1819 else if (dc
->op2
== PR_CCS
) {
1820 cris_evaluate_flags(dc
);
1821 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1823 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
1824 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op1
, preg_sizes
[dc
->op2
]);
1828 static unsigned int dec_move_mr(DisasContext
*dc
)
1830 int memsize
= memsize_zz(dc
);
1832 DIS(fprintf (logfile
, "move.%c [$r%u%s, $r%u\n",
1833 memsize_char(memsize
),
1834 dc
->op1
, dc
->postinc
? "+]" : "]",
1837 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1838 cris_cc_mask(dc
, CC_MASK_NZ
);
1839 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, memsize
);
1840 do_postinc(dc
, memsize
);
1844 static unsigned int dec_movs_m(DisasContext
*dc
)
1846 int memsize
= memsize_z(dc
);
1848 DIS(fprintf (logfile
, "movs.%c [$r%u%s, $r%u\n",
1849 memsize_char(memsize
),
1850 dc
->op1
, dc
->postinc
? "+]" : "]",
1854 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1855 cris_cc_mask(dc
, CC_MASK_NZ
);
1856 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1857 do_postinc(dc
, memsize
);
1861 static unsigned int dec_addu_m(DisasContext
*dc
)
1863 int memsize
= memsize_z(dc
);
1865 DIS(fprintf (logfile
, "addu.%c [$r%u%s, $r%u\n",
1866 memsize_char(memsize
),
1867 dc
->op1
, dc
->postinc
? "+]" : "]",
1871 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1872 cris_cc_mask(dc
, CC_MASK_NZVC
);
1873 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1874 do_postinc(dc
, memsize
);
1878 static unsigned int dec_adds_m(DisasContext
*dc
)
1880 int memsize
= memsize_z(dc
);
1882 DIS(fprintf (logfile
, "adds.%c [$r%u%s, $r%u\n",
1883 memsize_char(memsize
),
1884 dc
->op1
, dc
->postinc
? "+]" : "]",
1888 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1889 cris_cc_mask(dc
, CC_MASK_NZVC
);
1890 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, 4);
1891 do_postinc(dc
, memsize
);
1895 static unsigned int dec_subu_m(DisasContext
*dc
)
1897 int memsize
= memsize_z(dc
);
1899 DIS(fprintf (logfile
, "subu.%c [$r%u%s, $r%u\n",
1900 memsize_char(memsize
),
1901 dc
->op1
, dc
->postinc
? "+]" : "]",
1905 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1906 cris_cc_mask(dc
, CC_MASK_NZVC
);
1907 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1908 do_postinc(dc
, memsize
);
1912 static unsigned int dec_subs_m(DisasContext
*dc
)
1914 int memsize
= memsize_z(dc
);
1916 DIS(fprintf (logfile
, "subs.%c [$r%u%s, $r%u\n",
1917 memsize_char(memsize
),
1918 dc
->op1
, dc
->postinc
? "+]" : "]",
1922 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1923 cris_cc_mask(dc
, CC_MASK_NZVC
);
1924 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, 4);
1925 do_postinc(dc
, memsize
);
1929 static unsigned int dec_movu_m(DisasContext
*dc
)
1931 int memsize
= memsize_z(dc
);
1934 DIS(fprintf (logfile
, "movu.%c [$r%u%s, $r%u\n",
1935 memsize_char(memsize
),
1936 dc
->op1
, dc
->postinc
? "+]" : "]",
1939 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1940 cris_cc_mask(dc
, CC_MASK_NZ
);
1941 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
1942 do_postinc(dc
, memsize
);
1946 static unsigned int dec_cmpu_m(DisasContext
*dc
)
1948 int memsize
= memsize_z(dc
);
1950 DIS(fprintf (logfile
, "cmpu.%c [$r%u%s, $r%u\n",
1951 memsize_char(memsize
),
1952 dc
->op1
, dc
->postinc
? "+]" : "]",
1955 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1956 cris_cc_mask(dc
, CC_MASK_NZVC
);
1957 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, 4);
1958 do_postinc(dc
, memsize
);
1962 static unsigned int dec_cmps_m(DisasContext
*dc
)
1964 int memsize
= memsize_z(dc
);
1966 DIS(fprintf (logfile
, "cmps.%c [$r%u%s, $r%u\n",
1967 memsize_char(memsize
),
1968 dc
->op1
, dc
->postinc
? "+]" : "]",
1971 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
1972 cris_cc_mask(dc
, CC_MASK_NZVC
);
1973 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1974 do_postinc(dc
, memsize
);
1978 static unsigned int dec_cmp_m(DisasContext
*dc
)
1980 int memsize
= memsize_zz(dc
);
1982 DIS(fprintf (logfile
, "cmp.%c [$r%u%s, $r%u\n",
1983 memsize_char(memsize
),
1984 dc
->op1
, dc
->postinc
? "+]" : "]",
1987 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
1988 cris_cc_mask(dc
, CC_MASK_NZVC
);
1989 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
1990 do_postinc(dc
, memsize
);
1994 static unsigned int dec_test_m(DisasContext
*dc
)
1996 int memsize
= memsize_zz(dc
);
1998 DIS(fprintf (logfile
, "test.%d [$r%u%s] op2=%x\n",
1999 memsize_char(memsize
),
2000 dc
->op1
, dc
->postinc
? "+]" : "]",
2003 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2004 cris_cc_mask(dc
, CC_MASK_NZ
);
2007 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
2008 tcg_gen_movi_tl(cpu_T
[1], 0);
2009 crisv32_alu_op(dc
, CC_OP_CMP
, dc
->op2
, memsize_zz(dc
));
2010 do_postinc(dc
, memsize
);
2014 static unsigned int dec_and_m(DisasContext
*dc
)
2016 int memsize
= memsize_zz(dc
);
2018 DIS(fprintf (logfile
, "and.%d [$r%u%s, $r%u\n",
2019 memsize_char(memsize
),
2020 dc
->op1
, dc
->postinc
? "+]" : "]",
2023 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2024 cris_cc_mask(dc
, CC_MASK_NZ
);
2025 crisv32_alu_op(dc
, CC_OP_AND
, dc
->op2
, memsize_zz(dc
));
2026 do_postinc(dc
, memsize
);
2030 static unsigned int dec_add_m(DisasContext
*dc
)
2032 int memsize
= memsize_zz(dc
);
2034 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
2035 memsize_char(memsize
),
2036 dc
->op1
, dc
->postinc
? "+]" : "]",
2039 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2040 cris_cc_mask(dc
, CC_MASK_NZVC
);
2041 crisv32_alu_op(dc
, CC_OP_ADD
, dc
->op2
, memsize_zz(dc
));
2042 do_postinc(dc
, memsize
);
2046 static unsigned int dec_addo_m(DisasContext
*dc
)
2048 int memsize
= memsize_zz(dc
);
2050 DIS(fprintf (logfile
, "add.%d [$r%u%s, $r%u\n",
2051 memsize_char(memsize
),
2052 dc
->op1
, dc
->postinc
? "+]" : "]",
2055 insn_len
= dec_prep_alu_m(dc
, 1, memsize
);
2056 cris_cc_mask(dc
, 0);
2057 crisv32_alu_op(dc
, CC_OP_ADD
, R_ACR
, 4);
2058 do_postinc(dc
, memsize
);
2062 static unsigned int dec_bound_m(DisasContext
*dc
)
2064 int memsize
= memsize_zz(dc
);
2066 DIS(fprintf (logfile
, "bound.%d [$r%u%s, $r%u\n",
2067 memsize_char(memsize
),
2068 dc
->op1
, dc
->postinc
? "+]" : "]",
2071 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2072 cris_cc_mask(dc
, CC_MASK_NZ
);
2073 crisv32_alu_op(dc
, CC_OP_BOUND
, dc
->op2
, 4);
2074 do_postinc(dc
, memsize
);
2078 static unsigned int dec_addc_mr(DisasContext
*dc
)
2081 DIS(fprintf (logfile
, "addc [$r%u%s, $r%u\n",
2082 dc
->op1
, dc
->postinc
? "+]" : "]",
2085 cris_evaluate_flags(dc
);
2086 insn_len
= dec_prep_alu_m(dc
, 0, 4);
2087 cris_cc_mask(dc
, CC_MASK_NZVC
);
2088 crisv32_alu_op(dc
, CC_OP_ADDC
, dc
->op2
, 4);
2093 static unsigned int dec_sub_m(DisasContext
*dc
)
2095 int memsize
= memsize_zz(dc
);
2097 DIS(fprintf (logfile
, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2098 memsize_char(memsize
),
2099 dc
->op1
, dc
->postinc
? "+]" : "]",
2100 dc
->op2
, dc
->ir
, dc
->zzsize
));
2102 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2103 cris_cc_mask(dc
, CC_MASK_NZVC
);
2104 crisv32_alu_op(dc
, CC_OP_SUB
, dc
->op2
, memsize
);
2105 do_postinc(dc
, memsize
);
2109 static unsigned int dec_or_m(DisasContext
*dc
)
2111 int memsize
= memsize_zz(dc
);
2113 DIS(fprintf (logfile
, "or.%d [$r%u%s, $r%u pc=%x\n",
2114 memsize_char(memsize
),
2115 dc
->op1
, dc
->postinc
? "+]" : "]",
2118 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2119 cris_cc_mask(dc
, CC_MASK_NZ
);
2120 crisv32_alu_op(dc
, CC_OP_OR
, dc
->op2
, memsize_zz(dc
));
2121 do_postinc(dc
, memsize
);
2125 static unsigned int dec_move_mp(DisasContext
*dc
)
2127 int memsize
= memsize_zz(dc
);
2130 DIS(fprintf (logfile
, "move.%c [$r%u%s, $p%u\n",
2131 memsize_char(memsize
),
2133 dc
->postinc
? "+]" : "]",
2136 insn_len
= dec_prep_alu_m(dc
, 0, memsize
);
2137 cris_cc_mask(dc
, 0);
2138 if (dc
->op2
== PR_CCS
) {
2139 cris_evaluate_flags(dc
);
2141 /* User space is not allowed to touch all flags. */
2142 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], 0x39f);
2143 tcg_gen_andi_tl(cpu_T
[0], cpu_PR
[PR_CCS
], ~0x39f);
2144 tcg_gen_or_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1]);
2148 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[1]);
2150 do_postinc(dc
, memsize
);
2154 static unsigned int dec_move_pm(DisasContext
*dc
)
2158 memsize
= preg_sizes
[dc
->op2
];
2160 DIS(fprintf (logfile
, "move.%c $p%u, [$r%u%s\n",
2161 memsize_char(memsize
),
2162 dc
->op2
, dc
->op1
, dc
->postinc
? "+]" : "]"));
2164 /* prepare store. Address in T0, value in T1. */
2165 t_gen_mov_TN_preg(cpu_T
[1], dc
->op2
);
2166 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2167 gen_store_T0_T1(dc
, memsize
);
2168 cris_cc_mask(dc
, 0);
2171 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2172 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2177 static unsigned int dec_movem_mr(DisasContext
*dc
)
2181 DIS(fprintf (logfile
, "movem [$r%u%s, $r%u\n", dc
->op1
,
2182 dc
->postinc
? "+]" : "]", dc
->op2
));
2184 /* fetch the address into T0 and T1. */
2185 t_gen_mov_TN_reg(cpu_T
[1], dc
->op1
);
2186 for (i
= 0; i
<= dc
->op2
; i
++) {
2187 /* Perform the load onto regnum i. Always dword wide. */
2188 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
2189 gen_load(dc
, cpu_R
[i
], cpu_T
[1], 4, 0);
2190 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 4);
2192 /* writeback the updated pointer value. */
2194 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[1]);
2196 /* gen_load might want to evaluate the previous insns flags. */
2197 cris_cc_mask(dc
, 0);
2201 static unsigned int dec_movem_rm(DisasContext
*dc
)
2205 DIS(fprintf (logfile
, "movem $r%u, [$r%u%s\n", dc
->op2
, dc
->op1
,
2206 dc
->postinc
? "+]" : "]"));
2208 for (i
= 0; i
<= dc
->op2
; i
++) {
2209 /* Fetch register i into T1. */
2210 t_gen_mov_TN_reg(cpu_T
[1], i
);
2211 /* Fetch the address into T0. */
2212 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2214 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], i
* 4);
2215 /* Perform the store. */
2216 gen_store_T0_T1(dc
, 4);
2219 /* T0 should point to the last written addr, advance one more
2221 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 4);
2222 /* writeback the updated pointer value. */
2223 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2225 cris_cc_mask(dc
, 0);
2229 static unsigned int dec_move_rm(DisasContext
*dc
)
2233 memsize
= memsize_zz(dc
);
2235 DIS(fprintf (logfile
, "move.%d $r%u, [$r%u]\n",
2236 memsize
, dc
->op2
, dc
->op1
));
2238 /* prepare store. */
2239 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2240 t_gen_mov_TN_reg(cpu_T
[1], dc
->op2
);
2241 gen_store_T0_T1(dc
, memsize
);
2244 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], memsize
);
2245 t_gen_mov_reg_TN(dc
->op1
, cpu_T
[0]);
2247 cris_cc_mask(dc
, 0);
2251 static unsigned int dec_lapcq(DisasContext
*dc
)
2253 DIS(fprintf (logfile
, "lapcq %x, $r%u\n",
2254 dc
->pc
+ dc
->op1
*2, dc
->op2
));
2255 cris_cc_mask(dc
, 0);
2256 tcg_gen_movi_tl(cpu_T
[1], dc
->pc
+ dc
->op1
* 2);
2257 crisv32_alu_op(dc
, CC_OP_MOVE
, dc
->op2
, 4);
2261 static unsigned int dec_lapc_im(DisasContext
*dc
)
2269 cris_cc_mask(dc
, 0);
2270 imm
= ldl_code(dc
->pc
+ 2);
2271 DIS(fprintf (logfile
, "lapc 0x%x, $r%u\n", imm
+ dc
->pc
, dc
->op2
));
2275 t_gen_mov_reg_TN(rd
, tcg_const_tl(pc
));
2279 /* Jump to special reg. */
2280 static unsigned int dec_jump_p(DisasContext
*dc
)
2282 DIS(fprintf (logfile
, "jump $p%u\n", dc
->op2
));
2283 cris_cc_mask(dc
, 0);
2285 t_gen_mov_TN_preg(cpu_T
[0], dc
->op2
);
2286 /* rete will often have low bit set to indicate delayslot. */
2287 tcg_gen_andi_tl(env_btarget
, cpu_T
[0], ~1);
2288 cris_prepare_dyn_jmp(dc
);
2292 /* Jump and save. */
2293 static unsigned int dec_jas_r(DisasContext
*dc
)
2295 DIS(fprintf (logfile
, "jas $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2296 cris_cc_mask(dc
, 0);
2297 /* Store the return address in Pd. */
2298 tcg_gen_mov_tl(env_btarget
, cpu_R
[dc
->op1
]);
2301 tcg_gen_movi_tl(cpu_PR
[dc
->op2
], dc
->pc
+ 4);
2303 cris_prepare_dyn_jmp(dc
);
2307 static unsigned int dec_jas_im(DisasContext
*dc
)
2311 imm
= ldl_code(dc
->pc
+ 2);
2313 DIS(fprintf (logfile
, "jas 0x%x\n", imm
));
2314 cris_cc_mask(dc
, 0);
2315 /* Stor the return address in Pd. */
2316 tcg_gen_movi_tl(env_btarget
, imm
);
2317 t_gen_mov_preg_TN(dc
->op2
, tcg_const_tl(dc
->pc
+ 8));
2318 cris_prepare_dyn_jmp(dc
);
2322 static unsigned int dec_jasc_im(DisasContext
*dc
)
2326 imm
= ldl_code(dc
->pc
+ 2);
2328 DIS(fprintf (logfile
, "jasc 0x%x\n", imm
));
2329 cris_cc_mask(dc
, 0);
2330 /* Stor the return address in Pd. */
2331 tcg_gen_movi_tl(cpu_T
[0], imm
);
2332 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2333 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8 + 4);
2334 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2335 cris_prepare_dyn_jmp(dc
);
2339 static unsigned int dec_jasc_r(DisasContext
*dc
)
2341 DIS(fprintf (logfile
, "jasc_r $r%u, $p%u\n", dc
->op1
, dc
->op2
));
2342 cris_cc_mask(dc
, 0);
2343 /* Stor the return address in Pd. */
2344 t_gen_mov_TN_reg(cpu_T
[0], dc
->op1
);
2345 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2346 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 4 + 4);
2347 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2348 cris_prepare_dyn_jmp(dc
);
2352 static unsigned int dec_bcc_im(DisasContext
*dc
)
2355 uint32_t cond
= dc
->op2
;
2357 offset
= ldl_code(dc
->pc
+ 2);
2358 offset
= sign_extend(offset
, 15);
2360 DIS(fprintf (logfile
, "b%s %d pc=%x dst=%x\n",
2361 cc_name(cond
), offset
,
2362 dc
->pc
, dc
->pc
+ offset
));
2364 cris_cc_mask(dc
, 0);
2365 /* op2 holds the condition-code. */
2366 cris_prepare_cc_branch (dc
, offset
, cond
);
2370 static unsigned int dec_bas_im(DisasContext
*dc
)
2375 simm
= ldl_code(dc
->pc
+ 2);
2377 DIS(fprintf (logfile
, "bas 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2378 cris_cc_mask(dc
, 0);
2379 /* Stor the return address in Pd. */
2380 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2381 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2382 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 8);
2383 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2384 cris_prepare_dyn_jmp(dc
);
2388 static unsigned int dec_basc_im(DisasContext
*dc
)
2391 simm
= ldl_code(dc
->pc
+ 2);
2393 DIS(fprintf (logfile
, "basc 0x%x, $p%u\n", dc
->pc
+ simm
, dc
->op2
));
2394 cris_cc_mask(dc
, 0);
2395 /* Stor the return address in Pd. */
2396 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ simm
);
2397 t_gen_mov_env_TN(btarget
, cpu_T
[0]);
2398 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
+ 12);
2399 t_gen_mov_preg_TN(dc
->op2
, cpu_T
[0]);
2400 cris_prepare_dyn_jmp(dc
);
2404 static unsigned int dec_rfe_etc(DisasContext
*dc
)
2406 DIS(fprintf (logfile
, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2407 dc
->opcode
, dc
->pc
, dc
->op1
, dc
->op2
));
2409 cris_cc_mask(dc
, 0);
2411 if (dc
->op2
== 15) /* ignore halt. */
2414 switch (dc
->op2
& 7) {
2417 cris_evaluate_flags(dc
);
2418 gen_op_ccs_rshift();
2419 /* FIXME: don't set the P-FLAG if R is set. */
2420 tcg_gen_ori_tl(cpu_PR
[PR_CCS
], cpu_PR
[PR_CCS
], P_FLAG
);
2422 tcg_gen_helper_0_0(helper_rfe
);
2423 dc
->is_jmp
= DISAS_UPDATE
;
2431 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2432 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2433 /* Breaks start at 16 in the exception vector. */
2434 gen_op_break_im(dc
->op1
+ 16);
2435 dc
->is_jmp
= DISAS_UPDATE
;
2438 printf ("op2=%x\n", dc
->op2
);
2446 static unsigned int dec_ftag_fidx_d_m(DisasContext
*dc
)
2448 /* Ignore D-cache flushes. */
2452 static unsigned int dec_ftag_fidx_i_m(DisasContext
*dc
)
2454 /* Ignore I-cache flushes. */
2458 static unsigned int dec_null(DisasContext
*dc
)
2460 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2461 dc
->pc
, dc
->opcode
, dc
->op1
, dc
->op2
);
2467 struct decoder_info
{
2472 unsigned int (*dec
)(DisasContext
*dc
);
2474 /* Order matters here. */
2475 {DEC_MOVEQ
, dec_moveq
},
2476 {DEC_BTSTQ
, dec_btstq
},
2477 {DEC_CMPQ
, dec_cmpq
},
2478 {DEC_ADDOQ
, dec_addoq
},
2479 {DEC_ADDQ
, dec_addq
},
2480 {DEC_SUBQ
, dec_subq
},
2481 {DEC_ANDQ
, dec_andq
},
2483 {DEC_ASRQ
, dec_asrq
},
2484 {DEC_LSLQ
, dec_lslq
},
2485 {DEC_LSRQ
, dec_lsrq
},
2486 {DEC_BCCQ
, dec_bccq
},
2488 {DEC_BCC_IM
, dec_bcc_im
},
2489 {DEC_JAS_IM
, dec_jas_im
},
2490 {DEC_JAS_R
, dec_jas_r
},
2491 {DEC_JASC_IM
, dec_jasc_im
},
2492 {DEC_JASC_R
, dec_jasc_r
},
2493 {DEC_BAS_IM
, dec_bas_im
},
2494 {DEC_BASC_IM
, dec_basc_im
},
2495 {DEC_JUMP_P
, dec_jump_p
},
2496 {DEC_LAPC_IM
, dec_lapc_im
},
2497 {DEC_LAPCQ
, dec_lapcq
},
2499 {DEC_RFE_ETC
, dec_rfe_etc
},
2500 {DEC_ADDC_MR
, dec_addc_mr
},
2502 {DEC_MOVE_MP
, dec_move_mp
},
2503 {DEC_MOVE_PM
, dec_move_pm
},
2504 {DEC_MOVEM_MR
, dec_movem_mr
},
2505 {DEC_MOVEM_RM
, dec_movem_rm
},
2506 {DEC_MOVE_PR
, dec_move_pr
},
2507 {DEC_SCC_R
, dec_scc_r
},
2508 {DEC_SETF
, dec_setclrf
},
2509 {DEC_CLEARF
, dec_setclrf
},
2511 {DEC_MOVE_SR
, dec_move_sr
},
2512 {DEC_MOVE_RP
, dec_move_rp
},
2513 {DEC_SWAP_R
, dec_swap_r
},
2514 {DEC_ABS_R
, dec_abs_r
},
2515 {DEC_LZ_R
, dec_lz_r
},
2516 {DEC_MOVE_RS
, dec_move_rs
},
2517 {DEC_BTST_R
, dec_btst_r
},
2518 {DEC_ADDC_R
, dec_addc_r
},
2520 {DEC_DSTEP_R
, dec_dstep_r
},
2521 {DEC_XOR_R
, dec_xor_r
},
2522 {DEC_MCP_R
, dec_mcp_r
},
2523 {DEC_CMP_R
, dec_cmp_r
},
2525 {DEC_ADDI_R
, dec_addi_r
},
2526 {DEC_ADDI_ACR
, dec_addi_acr
},
2528 {DEC_ADD_R
, dec_add_r
},
2529 {DEC_SUB_R
, dec_sub_r
},
2531 {DEC_ADDU_R
, dec_addu_r
},
2532 {DEC_ADDS_R
, dec_adds_r
},
2533 {DEC_SUBU_R
, dec_subu_r
},
2534 {DEC_SUBS_R
, dec_subs_r
},
2535 {DEC_LSL_R
, dec_lsl_r
},
2537 {DEC_AND_R
, dec_and_r
},
2538 {DEC_OR_R
, dec_or_r
},
2539 {DEC_BOUND_R
, dec_bound_r
},
2540 {DEC_ASR_R
, dec_asr_r
},
2541 {DEC_LSR_R
, dec_lsr_r
},
2543 {DEC_MOVU_R
, dec_movu_r
},
2544 {DEC_MOVS_R
, dec_movs_r
},
2545 {DEC_NEG_R
, dec_neg_r
},
2546 {DEC_MOVE_R
, dec_move_r
},
2548 {DEC_FTAG_FIDX_I_M
, dec_ftag_fidx_i_m
},
2549 {DEC_FTAG_FIDX_D_M
, dec_ftag_fidx_d_m
},
2551 {DEC_MULS_R
, dec_muls_r
},
2552 {DEC_MULU_R
, dec_mulu_r
},
2554 {DEC_ADDU_M
, dec_addu_m
},
2555 {DEC_ADDS_M
, dec_adds_m
},
2556 {DEC_SUBU_M
, dec_subu_m
},
2557 {DEC_SUBS_M
, dec_subs_m
},
2559 {DEC_CMPU_M
, dec_cmpu_m
},
2560 {DEC_CMPS_M
, dec_cmps_m
},
2561 {DEC_MOVU_M
, dec_movu_m
},
2562 {DEC_MOVS_M
, dec_movs_m
},
2564 {DEC_CMP_M
, dec_cmp_m
},
2565 {DEC_ADDO_M
, dec_addo_m
},
2566 {DEC_BOUND_M
, dec_bound_m
},
2567 {DEC_ADD_M
, dec_add_m
},
2568 {DEC_SUB_M
, dec_sub_m
},
2569 {DEC_AND_M
, dec_and_m
},
2570 {DEC_OR_M
, dec_or_m
},
2571 {DEC_MOVE_RM
, dec_move_rm
},
2572 {DEC_TEST_M
, dec_test_m
},
2573 {DEC_MOVE_MR
, dec_move_mr
},
2578 static inline unsigned int
2579 cris_decoder(DisasContext
*dc
)
2581 unsigned int insn_len
= 2;
2585 /* Load a halfword onto the instruction register. */
2586 tmp
= ldl_code(dc
->pc
);
2587 dc
->ir
= tmp
& 0xffff;
2589 /* Now decode it. */
2590 dc
->opcode
= EXTRACT_FIELD(dc
->ir
, 4, 11);
2591 dc
->op1
= EXTRACT_FIELD(dc
->ir
, 0, 3);
2592 dc
->op2
= EXTRACT_FIELD(dc
->ir
, 12, 15);
2593 dc
->zsize
= EXTRACT_FIELD(dc
->ir
, 4, 4);
2594 dc
->zzsize
= EXTRACT_FIELD(dc
->ir
, 4, 5);
2595 dc
->postinc
= EXTRACT_FIELD(dc
->ir
, 10, 10);
2597 /* Large switch for all insns. */
2598 for (i
= 0; i
< sizeof decinfo
/ sizeof decinfo
[0]; i
++) {
2599 if ((dc
->opcode
& decinfo
[i
].mask
) == decinfo
[i
].bits
)
2601 insn_len
= decinfo
[i
].dec(dc
);
2609 static void check_breakpoint(CPUState
*env
, DisasContext
*dc
)
2612 if (env
->nb_breakpoints
> 0) {
2613 for(j
= 0; j
< env
->nb_breakpoints
; j
++) {
2614 if (env
->breakpoints
[j
] == dc
->pc
) {
2615 cris_evaluate_flags (dc
);
2616 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2617 t_gen_mov_env_TN(pc
, cpu_T
[0]);
2619 dc
->is_jmp
= DISAS_UPDATE
;
2625 /* generate intermediate code for basic block 'tb'. */
2626 struct DisasContext ctx
;
2628 gen_intermediate_code_internal(CPUState
*env
, TranslationBlock
*tb
,
2631 uint16_t *gen_opc_end
;
2633 unsigned int insn_len
;
2635 struct DisasContext
*dc
= &ctx
;
2636 uint32_t next_page_start
;
2642 cpu_abort(env
, "unaligned pc=%x erp=%x\n",
2643 env
->pc
, env
->pregs
[PR_ERP
]);
2648 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
2650 dc
->is_jmp
= DISAS_NEXT
;
2653 dc
->singlestep_enabled
= env
->singlestep_enabled
;
2658 cris_update_cc_op(dc
, CC_OP_FLAGS
, 4);
2660 dc
->user
= env
->pregs
[PR_CCS
] & U_FLAG
;
2661 dc
->delayed_branch
= 0;
2663 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
2665 "search=%d pc=%x ccs=%x pid=%x usp=%x\n"
2670 search_pc
, env
->pc
, env
->pregs
[PR_CCS
],
2671 env
->pregs
[PR_PID
], env
->pregs
[PR_USP
],
2672 env
->regs
[0], env
->regs
[1], env
->regs
[2], env
->regs
[3],
2673 env
->regs
[4], env
->regs
[5], env
->regs
[6], env
->regs
[7],
2674 env
->regs
[8], env
->regs
[9],
2675 env
->regs
[10], env
->regs
[11],
2676 env
->regs
[12], env
->regs
[13],
2677 env
->regs
[14], env
->regs
[15]);
2681 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
2685 check_breakpoint(env
, dc
);
2686 if (dc
->is_jmp
== DISAS_JUMP
2687 || dc
->is_jmp
== DISAS_SWI
)
2691 j
= gen_opc_ptr
- gen_opc_buf
;
2695 gen_opc_instr_start
[lj
++] = 0;
2697 if (dc
->delayed_branch
== 1) {
2698 gen_opc_pc
[lj
] = dc
->ppc
| 1;
2699 gen_opc_instr_start
[lj
] = 0;
2702 gen_opc_pc
[lj
] = dc
->pc
;
2703 gen_opc_instr_start
[lj
] = 1;
2708 insn_len
= cris_decoder(dc
);
2709 STATS(gen_op_exec_insn());
2713 cris_clear_x_flag(dc
);
2715 /* Check for delayed branches here. If we do it before
2716 actually genereating any host code, the simulator will just
2717 loop doing nothing for on this program location. */
2718 if (dc
->delayed_branch
) {
2719 dc
->delayed_branch
--;
2720 if (dc
->delayed_branch
== 0)
2722 if (dc
->bcc
== CC_A
) {
2724 dc
->is_jmp
= DISAS_JUMP
;
2727 /* Conditional jmp. */
2728 gen_op_cc_jmp (dc
->delayed_pc
, dc
->pc
);
2729 dc
->is_jmp
= DISAS_JUMP
;
2734 if (env
->singlestep_enabled
)
2736 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
2737 && ((dc
->pc
< next_page_start
) || dc
->delayed_branch
));
2739 if (dc
->delayed_branch
== 1) {
2740 /* Reexecute the last insn. */
2745 D(printf("!jmp pc=%x jmp=%d db=%d\n", dc
->pc
,
2746 dc
->is_jmp
, dc
->delayed_branch
));
2747 /* T0 and env_pc should hold the new pc. */
2748 tcg_gen_movi_tl(cpu_T
[0], dc
->pc
);
2749 tcg_gen_mov_tl(env_pc
, cpu_T
[0]);
2752 cris_evaluate_flags (dc
);
2754 if (__builtin_expect(env
->singlestep_enabled
, 0)) {
2757 switch(dc
->is_jmp
) {
2759 gen_goto_tb(dc
, 1, dc
->pc
);
2764 /* indicate that the hash table must be used
2765 to find the next TB */
2770 /* nothing more to generate */
2774 *gen_opc_ptr
= INDEX_op_end
;
2776 j
= gen_opc_ptr
- gen_opc_buf
;
2779 gen_opc_instr_start
[lj
++] = 0;
2781 tb
->size
= dc
->pc
- pc_start
;
2785 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
2786 fprintf(logfile
, "--------------\n");
2787 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
2788 target_disas(logfile
, pc_start
, dc
->pc
+ 4 - pc_start
, 0);
2789 fprintf(logfile
, "\nisize=%d osize=%d\n",
2790 dc
->pc
- pc_start
, gen_opc_ptr
- gen_opc_buf
);
2796 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
2798 return gen_intermediate_code_internal(env
, tb
, 0);
2801 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
2803 return gen_intermediate_code_internal(env
, tb
, 1);
2806 void cpu_dump_state (CPUState
*env
, FILE *f
,
2807 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
2816 cpu_fprintf(f
, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2817 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2819 env
->pc
, env
->pregs
[PR_CCS
], env
->btaken
, env
->btarget
,
2821 env
->cc_src
, env
->cc_dest
, env
->cc_result
, env
->cc_mask
,
2822 env
->debug1
, env
->debug2
, env
->debug3
);
2824 for (i
= 0; i
< 16; i
++) {
2825 cpu_fprintf(f
, "r%2.2d=%8.8x ", i
, env
->regs
[i
]);
2826 if ((i
+ 1) % 4 == 0)
2827 cpu_fprintf(f
, "\n");
2829 cpu_fprintf(f
, "\nspecial regs:\n");
2830 for (i
= 0; i
< 16; i
++) {
2831 cpu_fprintf(f
, "p%2.2d=%8.8x ", i
, env
->pregs
[i
]);
2832 if ((i
+ 1) % 4 == 0)
2833 cpu_fprintf(f
, "\n");
2835 srs
= env
->pregs
[PR_SRS
];
2836 cpu_fprintf(f
, "\nsupport function regs bank %x:\n", srs
);
2838 for (i
= 0; i
< 16; i
++) {
2839 cpu_fprintf(f
, "s%2.2d=%8.8x ",
2840 i
, env
->sregs
[srs
][i
]);
2841 if ((i
+ 1) % 4 == 0)
2842 cpu_fprintf(f
, "\n");
2845 cpu_fprintf(f
, "\n\n");
2849 static void tcg_macro_func(TCGContext
*s
, int macro_id
, const int *dead_args
)
2853 CPUCRISState
*cpu_cris_init (const char *cpu_model
)
2858 env
= qemu_mallocz(sizeof(CPUCRISState
));
2863 tcg_set_macro_func(&tcg_ctx
, tcg_macro_func
);
2864 cpu_env
= tcg_global_reg_new(TCG_TYPE_PTR
, TCG_AREG0
, "env");
2865 #if TARGET_LONG_BITS > HOST_LONG_BITS
2866 cpu_T
[0] = tcg_global_mem_new(TCG_TYPE_TL
,
2867 TCG_AREG0
, offsetof(CPUState
, t0
), "T0");
2868 cpu_T
[1] = tcg_global_mem_new(TCG_TYPE_TL
,
2869 TCG_AREG0
, offsetof(CPUState
, t1
), "T1");
2871 cpu_T
[0] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG1
, "T0");
2872 cpu_T
[1] = tcg_global_reg_new(TCG_TYPE_TL
, TCG_AREG2
, "T1");
2875 cc_src
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2876 offsetof(CPUState
, cc_src
), "cc_src");
2877 cc_dest
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2878 offsetof(CPUState
, cc_dest
),
2880 cc_result
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2881 offsetof(CPUState
, cc_result
),
2883 cc_op
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2884 offsetof(CPUState
, cc_op
), "cc_op");
2885 cc_size
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2886 offsetof(CPUState
, cc_size
),
2888 cc_mask
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2889 offsetof(CPUState
, cc_mask
),
2892 env_pc
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2893 offsetof(CPUState
, pc
),
2895 env_btarget
= tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2896 offsetof(CPUState
, btarget
),
2899 for (i
= 0; i
< 16; i
++) {
2900 cpu_R
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2901 offsetof(CPUState
, regs
[i
]),
2904 for (i
= 0; i
< 16; i
++) {
2905 cpu_PR
[i
] = tcg_global_mem_new(TCG_TYPE_PTR
, TCG_AREG0
,
2906 offsetof(CPUState
, pregs
[i
]),
2910 TCG_HELPER(helper_tlb_update
);
2911 TCG_HELPER(helper_tlb_flush
);
2912 TCG_HELPER(helper_rfe
);
2913 TCG_HELPER(helper_store
);
2914 TCG_HELPER(helper_dump
);
2915 TCG_HELPER(helper_dummy
);
2917 TCG_HELPER(helper_evaluate_flags_muls
);
2918 TCG_HELPER(helper_evaluate_flags_mulu
);
2919 TCG_HELPER(helper_evaluate_flags_mcp
);
2920 TCG_HELPER(helper_evaluate_flags_alu_4
);
2921 TCG_HELPER(helper_evaluate_flags_move_4
);
2922 TCG_HELPER(helper_evaluate_flags_move_2
);
2923 TCG_HELPER(helper_evaluate_flags
);
2929 void cpu_reset (CPUCRISState
*env
)
2931 memset(env
, 0, offsetof(CPUCRISState
, breakpoints
));
2934 #if defined(CONFIG_USER_ONLY)
2935 /* start in user mode with interrupts enabled. */
2936 env
->pregs
[PR_CCS
] |= U_FLAG
| I_FLAG
;
2938 env
->pregs
[PR_CCS
] = 0;
2942 void gen_pc_load(CPUState
*env
, struct TranslationBlock
*tb
,
2943 unsigned long searched_pc
, int pc_pos
, void *puc
)
2945 env
->pc
= gen_opc_pc
[pc_pos
];