1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <stdarg.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <inttypes.h>
31
32#include "cpu.h"
33#include "disas.h"
34#include "tcg-op.h"
35#include "helper.h"
36#include "mmu.h"
37#include "crisv32-decode.h"
38#include "qemu-common.h"
39
40#define GEN_HELPER 1
41#include "helper.h"
42
43#define DISAS_CRIS 0
44#if DISAS_CRIS
45# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46#else
47# define LOG_DIS(...) do { } while (0)
48#endif
49
50#define D(x)
51#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52#define BUG_ON(x) ({if (x) BUG();})
53
54#define DISAS_SWI 5
55
56
57#define EXTRACT_FIELD(src, start, end) \
58 (((src) >> start) & ((1 << (end - start + 1)) - 1))
59
60#define CC_MASK_NZ 0xc
61#define CC_MASK_NZV 0xe
62#define CC_MASK_NZVC 0xf
63#define CC_MASK_RNZV 0x10e
64
65static TCGv_ptr cpu_env;
66static TCGv cpu_R[16];
67static TCGv cpu_PR[16];
68static TCGv cc_x;
69static TCGv cc_src;
70static TCGv cc_dest;
71static TCGv cc_result;
72static TCGv cc_op;
73static TCGv cc_size;
74static TCGv cc_mask;
75
76static TCGv env_btaken;
77static TCGv env_btarget;
78static TCGv env_pc;
79
80#include "gen-icount.h"
81
82
83typedef struct DisasContext {
84 CPUState *env;
85 target_ulong pc, ppc;
86
87
88 unsigned int (*decoder)(struct DisasContext *dc);
89 uint32_t ir;
90 uint32_t opcode;
91 unsigned int op1;
92 unsigned int op2;
93 unsigned int zsize, zzsize;
94 unsigned int mode;
95 unsigned int postinc;
96
97 unsigned int size;
98 unsigned int src;
99 unsigned int dst;
100 unsigned int cond;
101
102 int update_cc;
103 int cc_op;
104 int cc_size;
105 uint32_t cc_mask;
106
107 int cc_size_uptodate;
108
109 int cc_x_uptodate;
110 int flags_uptodate;
111 int flagx_known;
112
113 int flags_x;
114
115 int clear_x;
116 int clear_prefix;
117 int clear_locked_irq;
118 int cpustate_changed;
119 unsigned int tb_flags;
120 int is_jmp;
121
122#define JMP_NOJMP 0
123#define JMP_DIRECT 1
124#define JMP_DIRECT_CC 2
125#define JMP_INDIRECT 3
126 int jmp;
127 uint32_t jmp_pc;
128
129 int delayed_branch;
130
131 struct TranslationBlock *tb;
132 int singlestep_enabled;
133} DisasContext;
134
135static void gen_BUG(DisasContext *dc, const char *file, int line)
136{
137 printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
138 qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
139 cpu_abort(dc->env, "%s:%d\n", file, line);
140}
141
142static const char *regnames[] =
143{
144 "$r0", "$r1", "$r2", "$r3",
145 "$r4", "$r5", "$r6", "$r7",
146 "$r8", "$r9", "$r10", "$r11",
147 "$r12", "$r13", "$sp", "$acr",
148};
149static const char *pregnames[] =
150{
151 "$bz", "$vr", "$pid", "$srs",
152 "$wz", "$exs", "$eda", "$mof",
153 "$dz", "$ebp", "$erp", "$srp",
154 "$nrp", "$ccs", "$usp", "$spc",
155};
156
157
158static int preg_sizes[] = {
159 1,
160 1,
161 4,
162 1,
163 2,
164 4, 4, 4,
165 4, 4, 4, 4,
166 4, 4, 4, 4,
167};
168
169#define t_gen_mov_TN_env(tn, member) \
170 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
171#define t_gen_mov_env_TN(member, tn) \
172 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
173
174static inline void t_gen_mov_TN_reg(TCGv tn, int r)
175{
176 if (r < 0 || r > 15)
177 fprintf(stderr, "wrong register read $r%d\n", r);
178 tcg_gen_mov_tl(tn, cpu_R[r]);
179}
180static inline void t_gen_mov_reg_TN(int r, TCGv tn)
181{
182 if (r < 0 || r > 15)
183 fprintf(stderr, "wrong register write $r%d\n", r);
184 tcg_gen_mov_tl(cpu_R[r], tn);
185}
186
187static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
188{
189 if (offset > sizeof (CPUState))
190 fprintf(stderr, "wrong load from env from off=%d\n", offset);
191 tcg_gen_ld_tl(tn, cpu_env, offset);
192}
193static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
194{
195 if (offset > sizeof (CPUState))
196 fprintf(stderr, "wrong store to env at off=%d\n", offset);
197 tcg_gen_st_tl(tn, cpu_env, offset);
198}
199
200static inline void t_gen_mov_TN_preg(TCGv tn, int r)
201{
202 if (r < 0 || r > 15)
203 fprintf(stderr, "wrong register read $p%d\n", r);
204 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
205 tcg_gen_mov_tl(tn, tcg_const_tl(0));
206 else if (r == PR_VR)
207 tcg_gen_mov_tl(tn, tcg_const_tl(32));
208 else
209 tcg_gen_mov_tl(tn, cpu_PR[r]);
210}
211static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
212{
213 if (r < 0 || r > 15)
214 fprintf(stderr, "wrong register write $p%d\n", r);
215 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
216 return;
217 else if (r == PR_SRS)
218 tcg_gen_andi_tl(cpu_PR[r], tn, 3);
219 else {
220 if (r == PR_PID)
221 gen_helper_tlb_flush_pid(tn);
222 if (dc->tb_flags & S_FLAG && r == PR_SPC)
223 gen_helper_spc_write(tn);
224 else if (r == PR_CCS)
225 dc->cpustate_changed = 1;
226 tcg_gen_mov_tl(cpu_PR[r], tn);
227 }
228}
229
230
231static int sign_extend(unsigned int val, unsigned int width)
232{
233 int sval;
234
235
236 val <<= 31 - width;
237 sval = val;
238
239 sval >>= 31 - width;
240 return sval;
241}
242
243static int cris_fetch(DisasContext *dc, uint32_t addr,
244 unsigned int size, unsigned int sign)
245{
246 int r;
247
248 switch (size) {
249 case 4:
250 {
251 r = ldl_code(addr);
252 break;
253 }
254 case 2:
255 {
256 if (sign) {
257 r = ldsw_code(addr);
258 } else {
259 r = lduw_code(addr);
260 }
261 break;
262 }
263 case 1:
264 {
265 if (sign) {
266 r = ldsb_code(addr);
267 } else {
268 r = ldub_code(addr);
269 }
270 break;
271 }
272 default:
273 cpu_abort(dc->env, "Invalid fetch size %d\n", size);
274 break;
275 }
276 return r;
277}
278
279static void cris_lock_irq(DisasContext *dc)
280{
281 dc->clear_locked_irq = 0;
282 t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
283}
284
285static inline void t_gen_raise_exception(uint32_t index)
286{
287 TCGv_i32 tmp = tcg_const_i32(index);
288 gen_helper_raise_exception(tmp);
289 tcg_temp_free_i32(tmp);
290}
291
292static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
293{
294 TCGv t0, t_31;
295
296 t0 = tcg_temp_new();
297 t_31 = tcg_const_tl(31);
298 tcg_gen_shl_tl(d, a, b);
299
300 tcg_gen_sub_tl(t0, t_31, b);
301 tcg_gen_sar_tl(t0, t0, t_31);
302 tcg_gen_and_tl(t0, t0, d);
303 tcg_gen_xor_tl(d, d, t0);
304 tcg_temp_free(t0);
305 tcg_temp_free(t_31);
306}
307
308static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
309{
310 TCGv t0, t_31;
311
312 t0 = tcg_temp_new();
313 t_31 = tcg_temp_new();
314 tcg_gen_shr_tl(d, a, b);
315
316 tcg_gen_movi_tl(t_31, 31);
317 tcg_gen_sub_tl(t0, t_31, b);
318 tcg_gen_sar_tl(t0, t0, t_31);
319 tcg_gen_and_tl(t0, t0, d);
320 tcg_gen_xor_tl(d, d, t0);
321 tcg_temp_free(t0);
322 tcg_temp_free(t_31);
323}
324
325static void t_gen_asr(TCGv d, TCGv a, TCGv b)
326{
327 TCGv t0, t_31;
328
329 t0 = tcg_temp_new();
330 t_31 = tcg_temp_new();
331 tcg_gen_sar_tl(d, a, b);
332
333 tcg_gen_movi_tl(t_31, 31);
334 tcg_gen_sub_tl(t0, t_31, b);
335 tcg_gen_sar_tl(t0, t0, t_31);
336 tcg_gen_or_tl(d, d, t0);
337 tcg_temp_free(t0);
338 tcg_temp_free(t_31);
339}
340
341
342static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
343{
344 TCGv_i64 t0, t1;
345
346 t0 = tcg_temp_new_i64();
347 t1 = tcg_temp_new_i64();
348
349 tcg_gen_ext_i32_i64(t0, a);
350 tcg_gen_ext_i32_i64(t1, b);
351 tcg_gen_mul_i64(t0, t0, t1);
352
353 tcg_gen_trunc_i64_i32(d, t0);
354 tcg_gen_shri_i64(t0, t0, 32);
355 tcg_gen_trunc_i64_i32(d2, t0);
356
357 tcg_temp_free_i64(t0);
358 tcg_temp_free_i64(t1);
359}
360
361
362static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
363{
364 TCGv_i64 t0, t1;
365
366 t0 = tcg_temp_new_i64();
367 t1 = tcg_temp_new_i64();
368
369 tcg_gen_extu_i32_i64(t0, a);
370 tcg_gen_extu_i32_i64(t1, b);
371 tcg_gen_mul_i64(t0, t0, t1);
372
373 tcg_gen_trunc_i64_i32(d, t0);
374 tcg_gen_shri_i64(t0, t0, 32);
375 tcg_gen_trunc_i64_i32(d2, t0);
376
377 tcg_temp_free_i64(t0);
378 tcg_temp_free_i64(t1);
379}
380
381static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
382{
383 int l1;
384
385 l1 = gen_new_label();
386
387
388
389
390
391
392 tcg_gen_shli_tl(d, a, 1);
393 tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
394 tcg_gen_sub_tl(d, d, b);
395 gen_set_label(l1);
396}
397
398static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
399{
400 TCGv t;
401
402
403
404
405
406
407 t = tcg_temp_new();
408 tcg_gen_shli_tl(d, a, 1);
409 tcg_gen_shli_tl(t, ccs, 31 - 3);
410 tcg_gen_sari_tl(t, t, 31);
411 tcg_gen_and_tl(t, t, b);
412 tcg_gen_add_tl(d, d, t);
413 tcg_temp_free(t);
414}
415
416
417static inline void t_gen_add_flag(TCGv d, int flag)
418{
419 TCGv c;
420
421 c = tcg_temp_new();
422 t_gen_mov_TN_preg(c, PR_CCS);
423
424 tcg_gen_andi_tl(c, c, 1 << flag);
425 if (flag)
426 tcg_gen_shri_tl(c, c, flag);
427 tcg_gen_add_tl(d, d, c);
428 tcg_temp_free(c);
429}
430
431static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
432{
433 if (dc->flagx_known) {
434 if (dc->flags_x) {
435 TCGv c;
436
437 c = tcg_temp_new();
438 t_gen_mov_TN_preg(c, PR_CCS);
439
440 tcg_gen_andi_tl(c, c, C_FLAG);
441 tcg_gen_add_tl(d, d, c);
442 tcg_temp_free(c);
443 }
444 } else {
445 TCGv x, c;
446
447 x = tcg_temp_new();
448 c = tcg_temp_new();
449 t_gen_mov_TN_preg(x, PR_CCS);
450 tcg_gen_mov_tl(c, x);
451
452
453 tcg_gen_andi_tl(c, c, C_FLAG);
454 tcg_gen_andi_tl(x, x, X_FLAG);
455 tcg_gen_shri_tl(x, x, 4);
456
457 tcg_gen_and_tl(x, x, c);
458 tcg_gen_add_tl(d, d, x);
459 tcg_temp_free(x);
460 tcg_temp_free(c);
461 }
462}
463
464static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
465{
466 if (dc->flagx_known) {
467 if (dc->flags_x) {
468 TCGv c;
469
470 c = tcg_temp_new();
471 t_gen_mov_TN_preg(c, PR_CCS);
472
473 tcg_gen_andi_tl(c, c, C_FLAG);
474 tcg_gen_sub_tl(d, d, c);
475 tcg_temp_free(c);
476 }
477 } else {
478 TCGv x, c;
479
480 x = tcg_temp_new();
481 c = tcg_temp_new();
482 t_gen_mov_TN_preg(x, PR_CCS);
483 tcg_gen_mov_tl(c, x);
484
485
486 tcg_gen_andi_tl(c, c, C_FLAG);
487 tcg_gen_andi_tl(x, x, X_FLAG);
488 tcg_gen_shri_tl(x, x, 4);
489
490 tcg_gen_and_tl(x, x, c);
491 tcg_gen_sub_tl(d, d, x);
492 tcg_temp_free(x);
493 tcg_temp_free(c);
494 }
495}
496
497
498
499static inline void t_gen_swapb(TCGv d, TCGv s)
500{
501 TCGv t, org_s;
502
503 t = tcg_temp_new();
504 org_s = tcg_temp_new();
505
506
507 tcg_gen_mov_tl(org_s, s);
508 tcg_gen_shli_tl(t, org_s, 8);
509 tcg_gen_andi_tl(d, t, 0xff00ff00);
510 tcg_gen_shri_tl(t, org_s, 8);
511 tcg_gen_andi_tl(t, t, 0x00ff00ff);
512 tcg_gen_or_tl(d, d, t);
513 tcg_temp_free(t);
514 tcg_temp_free(org_s);
515}
516
517
518static inline void t_gen_swapw(TCGv d, TCGv s)
519{
520 TCGv t;
521
522 t = tcg_temp_new();
523 tcg_gen_mov_tl(t, s);
524 tcg_gen_shli_tl(d, t, 16);
525 tcg_gen_shri_tl(t, t, 16);
526 tcg_gen_or_tl(d, d, t);
527 tcg_temp_free(t);
528}
529
530
531
532
533
534
535
536
537
538
539
540static inline void t_gen_swapr(TCGv d, TCGv s)
541{
542 struct {
543 int shift;
544 uint32_t mask;
545 } bitrev [] = {
546 {7, 0x80808080},
547 {5, 0x40404040},
548 {3, 0x20202020},
549 {1, 0x10101010},
550 {-1, 0x08080808},
551 {-3, 0x04040404},
552 {-5, 0x02020202},
553 {-7, 0x01010101}
554 };
555 int i;
556 TCGv t, org_s;
557
558
559 t = tcg_temp_new();
560 org_s = tcg_temp_new();
561 tcg_gen_mov_tl(org_s, s);
562
563 tcg_gen_shli_tl(t, org_s, bitrev[0].shift);
564 tcg_gen_andi_tl(d, t, bitrev[0].mask);
565 for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
566 if (bitrev[i].shift >= 0) {
567 tcg_gen_shli_tl(t, org_s, bitrev[i].shift);
568 } else {
569 tcg_gen_shri_tl(t, org_s, -bitrev[i].shift);
570 }
571 tcg_gen_andi_tl(t, t, bitrev[i].mask);
572 tcg_gen_or_tl(d, d, t);
573 }
574 tcg_temp_free(t);
575 tcg_temp_free(org_s);
576}
577
578static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
579{
580 int l1;
581
582 l1 = gen_new_label();
583
584
585 tcg_gen_mov_tl(env_pc, pc_false);
586 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
587 tcg_gen_mov_tl(env_pc, pc_true);
588 gen_set_label(l1);
589}
590
591static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
592{
593 TranslationBlock *tb;
594 tb = dc->tb;
595 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
596 tcg_gen_goto_tb(n);
597 tcg_gen_movi_tl(env_pc, dest);
598 tcg_gen_exit_tb((tcg_target_long)tb + n);
599 } else {
600 tcg_gen_movi_tl(env_pc, dest);
601 tcg_gen_exit_tb(0);
602 }
603}
604
605static inline void cris_clear_x_flag(DisasContext *dc)
606{
607 if (dc->flagx_known && dc->flags_x)
608 dc->flags_uptodate = 0;
609
610 dc->flagx_known = 1;
611 dc->flags_x = 0;
612}
613
614static void cris_flush_cc_state(DisasContext *dc)
615{
616 if (dc->cc_size_uptodate != dc->cc_size) {
617 tcg_gen_movi_tl(cc_size, dc->cc_size);
618 dc->cc_size_uptodate = dc->cc_size;
619 }
620 tcg_gen_movi_tl(cc_op, dc->cc_op);
621 tcg_gen_movi_tl(cc_mask, dc->cc_mask);
622}
623
624static void cris_evaluate_flags(DisasContext *dc)
625{
626 if (dc->flags_uptodate)
627 return;
628
629 cris_flush_cc_state(dc);
630
631 switch (dc->cc_op)
632 {
633 case CC_OP_MCP:
634 gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
635 cpu_PR[PR_CCS], cc_src,
636 cc_dest, cc_result);
637 break;
638 case CC_OP_MULS:
639 gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
640 cpu_PR[PR_CCS], cc_result,
641 cpu_PR[PR_MOF]);
642 break;
643 case CC_OP_MULU:
644 gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
645 cpu_PR[PR_CCS], cc_result,
646 cpu_PR[PR_MOF]);
647 break;
648 case CC_OP_MOVE:
649 case CC_OP_AND:
650 case CC_OP_OR:
651 case CC_OP_XOR:
652 case CC_OP_ASR:
653 case CC_OP_LSR:
654 case CC_OP_LSL:
655 switch (dc->cc_size)
656 {
657 case 4:
658 gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
659 cpu_PR[PR_CCS], cc_result);
660 break;
661 case 2:
662 gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
663 cpu_PR[PR_CCS], cc_result);
664 break;
665 default:
666 gen_helper_evaluate_flags();
667 break;
668 }
669 break;
670 case CC_OP_FLAGS:
671
672 break;
673 case CC_OP_SUB:
674 case CC_OP_CMP:
675 if (dc->cc_size == 4)
676 gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
677 cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
678 else
679 gen_helper_evaluate_flags();
680
681 break;
682 default:
683 switch (dc->cc_size)
684 {
685 case 4:
686 gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
687 cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
688 break;
689 default:
690 gen_helper_evaluate_flags();
691 break;
692 }
693 break;
694 }
695
696 if (dc->flagx_known) {
697 if (dc->flags_x)
698 tcg_gen_ori_tl(cpu_PR[PR_CCS],
699 cpu_PR[PR_CCS], X_FLAG);
700 else if (dc->cc_op == CC_OP_FLAGS)
701 tcg_gen_andi_tl(cpu_PR[PR_CCS],
702 cpu_PR[PR_CCS], ~X_FLAG);
703 }
704 dc->flags_uptodate = 1;
705}
706
707static void cris_cc_mask(DisasContext *dc, unsigned int mask)
708{
709 uint32_t ovl;
710
711 if (!mask) {
712 dc->update_cc = 0;
713 return;
714 }
715
716
717
718 ovl = (dc->cc_mask ^ mask) & ~mask;
719 if (ovl) {
720
721 cris_evaluate_flags (dc);
722 }
723 dc->cc_mask = mask;
724 dc->update_cc = 1;
725}
726
727static void cris_update_cc_op(DisasContext *dc, int op, int size)
728{
729 dc->cc_op = op;
730 dc->cc_size = size;
731 dc->flags_uptodate = 0;
732}
733
734static inline void cris_update_cc_x(DisasContext *dc)
735{
736
737 if (dc->flagx_known) {
738 if (dc->cc_x_uptodate == (2 | dc->flags_x))
739 return;
740 tcg_gen_movi_tl(cc_x, dc->flags_x);
741 dc->cc_x_uptodate = 2 | dc->flags_x;
742 }
743 else {
744 tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
745 dc->cc_x_uptodate = 1;
746 }
747}
748
749
750static void cris_pre_alu_update_cc(DisasContext *dc, int op,
751 TCGv dst, TCGv src, int size)
752{
753 if (dc->update_cc) {
754 cris_update_cc_op(dc, op, size);
755 tcg_gen_mov_tl(cc_src, src);
756
757 if (op != CC_OP_MOVE
758 && op != CC_OP_AND
759 && op != CC_OP_OR
760 && op != CC_OP_XOR
761 && op != CC_OP_ASR
762 && op != CC_OP_LSR
763 && op != CC_OP_LSL)
764 tcg_gen_mov_tl(cc_dest, dst);
765
766 cris_update_cc_x(dc);
767 }
768}
769
770
771static inline void cris_update_result(DisasContext *dc, TCGv res)
772{
773 if (dc->update_cc)
774 tcg_gen_mov_tl(cc_result, res);
775}
776
777
778static void cris_alu_op_exec(DisasContext *dc, int op,
779 TCGv dst, TCGv a, TCGv b, int size)
780{
781
782 switch (op)
783 {
784 case CC_OP_ADD:
785 tcg_gen_add_tl(dst, a, b);
786
787 t_gen_addx_carry(dc, dst);
788 break;
789 case CC_OP_ADDC:
790 tcg_gen_add_tl(dst, a, b);
791 t_gen_add_flag(dst, 0);
792 break;
793 case CC_OP_MCP:
794 tcg_gen_add_tl(dst, a, b);
795 t_gen_add_flag(dst, 8);
796 break;
797 case CC_OP_SUB:
798 tcg_gen_sub_tl(dst, a, b);
799
800 t_gen_subx_carry(dc, dst);
801 break;
802 case CC_OP_MOVE:
803 tcg_gen_mov_tl(dst, b);
804 break;
805 case CC_OP_OR:
806 tcg_gen_or_tl(dst, a, b);
807 break;
808 case CC_OP_AND:
809 tcg_gen_and_tl(dst, a, b);
810 break;
811 case CC_OP_XOR:
812 tcg_gen_xor_tl(dst, a, b);
813 break;
814 case CC_OP_LSL:
815 t_gen_lsl(dst, a, b);
816 break;
817 case CC_OP_LSR:
818 t_gen_lsr(dst, a, b);
819 break;
820 case CC_OP_ASR:
821 t_gen_asr(dst, a, b);
822 break;
823 case CC_OP_NEG:
824 tcg_gen_neg_tl(dst, b);
825
826 t_gen_subx_carry(dc, dst);
827 break;
828 case CC_OP_LZ:
829 gen_helper_lz(dst, b);
830 break;
831 case CC_OP_MULS:
832 t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
833 break;
834 case CC_OP_MULU:
835 t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
836 break;
837 case CC_OP_DSTEP:
838 t_gen_cris_dstep(dst, a, b);
839 break;
840 case CC_OP_MSTEP:
841 t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
842 break;
843 case CC_OP_BOUND:
844 {
845 int l1;
846 l1 = gen_new_label();
847 tcg_gen_mov_tl(dst, a);
848 tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
849 tcg_gen_mov_tl(dst, b);
850 gen_set_label(l1);
851 }
852 break;
853 case CC_OP_CMP:
854 tcg_gen_sub_tl(dst, a, b);
855
856 t_gen_subx_carry(dc, dst);
857 break;
858 default:
859 qemu_log("illegal ALU op.\n");
860 BUG();
861 break;
862 }
863
864 if (size == 1)
865 tcg_gen_andi_tl(dst, dst, 0xff);
866 else if (size == 2)
867 tcg_gen_andi_tl(dst, dst, 0xffff);
868}
869
870static void cris_alu(DisasContext *dc, int op,
871 TCGv d, TCGv op_a, TCGv op_b, int size)
872{
873 TCGv tmp;
874 int writeback;
875
876 writeback = 1;
877
878 if (op == CC_OP_CMP) {
879 tmp = tcg_temp_new();
880 writeback = 0;
881 } else if (size == 4) {
882 tmp = d;
883 writeback = 0;
884 } else
885 tmp = tcg_temp_new();
886
887
888 cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
889 cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
890 cris_update_result(dc, tmp);
891
892
893 if (writeback) {
894 if (size == 1)
895 tcg_gen_andi_tl(d, d, ~0xff);
896 else
897 tcg_gen_andi_tl(d, d, ~0xffff);
898 tcg_gen_or_tl(d, d, tmp);
899 }
900 if (!TCGV_EQUAL(tmp, d))
901 tcg_temp_free(tmp);
902}
903
904static int arith_cc(DisasContext *dc)
905{
906 if (dc->update_cc) {
907 switch (dc->cc_op) {
908 case CC_OP_ADDC: return 1;
909 case CC_OP_ADD: return 1;
910 case CC_OP_SUB: return 1;
911 case CC_OP_DSTEP: return 1;
912 case CC_OP_LSL: return 1;
913 case CC_OP_LSR: return 1;
914 case CC_OP_ASR: return 1;
915 case CC_OP_CMP: return 1;
916 case CC_OP_NEG: return 1;
917 case CC_OP_OR: return 1;
918 case CC_OP_AND: return 1;
919 case CC_OP_XOR: return 1;
920 case CC_OP_MULU: return 1;
921 case CC_OP_MULS: return 1;
922 default:
923 return 0;
924 }
925 }
926 return 0;
927}
928
929static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
930{
931 int arith_opt, move_opt;
932
933
934
935
936
937
938
939
940
941
942
943 arith_opt = arith_cc(dc) && !dc->flags_uptodate;
944 move_opt = (dc->cc_op == CC_OP_MOVE);
945 switch (cond) {
946 case CC_EQ:
947 if ((arith_opt || move_opt)
948 && dc->cc_x_uptodate != (2 | X_FLAG)) {
949 tcg_gen_setcond_tl(TCG_COND_EQ, cc,
950 cc_result, tcg_const_tl(0));
951 }
952 else {
953 cris_evaluate_flags(dc);
954 tcg_gen_andi_tl(cc,
955 cpu_PR[PR_CCS], Z_FLAG);
956 }
957 break;
958 case CC_NE:
959 if ((arith_opt || move_opt)
960 && dc->cc_x_uptodate != (2 | X_FLAG)) {
961 tcg_gen_mov_tl(cc, cc_result);
962 } else {
963 cris_evaluate_flags(dc);
964 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
965 Z_FLAG);
966 tcg_gen_andi_tl(cc, cc, Z_FLAG);
967 }
968 break;
969 case CC_CS:
970 cris_evaluate_flags(dc);
971 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
972 break;
973 case CC_CC:
974 cris_evaluate_flags(dc);
975 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
976 tcg_gen_andi_tl(cc, cc, C_FLAG);
977 break;
978 case CC_VS:
979 cris_evaluate_flags(dc);
980 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
981 break;
982 case CC_VC:
983 cris_evaluate_flags(dc);
984 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
985 V_FLAG);
986 tcg_gen_andi_tl(cc, cc, V_FLAG);
987 break;
988 case CC_PL:
989 if (arith_opt || move_opt) {
990 int bits = 31;
991
992 if (dc->cc_size == 1)
993 bits = 7;
994 else if (dc->cc_size == 2)
995 bits = 15;
996
997 tcg_gen_shri_tl(cc, cc_result, bits);
998 tcg_gen_xori_tl(cc, cc, 1);
999 } else {
1000 cris_evaluate_flags(dc);
1001 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
1002 N_FLAG);
1003 tcg_gen_andi_tl(cc, cc, N_FLAG);
1004 }
1005 break;
1006 case CC_MI:
1007 if (arith_opt || move_opt) {
1008 int bits = 31;
1009
1010 if (dc->cc_size == 1)
1011 bits = 7;
1012 else if (dc->cc_size == 2)
1013 bits = 15;
1014
1015 tcg_gen_shri_tl(cc, cc_result, bits);
1016 tcg_gen_andi_tl(cc, cc, 1);
1017 }
1018 else {
1019 cris_evaluate_flags(dc);
1020 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1021 N_FLAG);
1022 }
1023 break;
1024 case CC_LS:
1025 cris_evaluate_flags(dc);
1026 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1027 C_FLAG | Z_FLAG);
1028 break;
1029 case CC_HI:
1030 cris_evaluate_flags(dc);
1031 {
1032 TCGv tmp;
1033
1034 tmp = tcg_temp_new();
1035 tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1036 C_FLAG | Z_FLAG);
1037
1038 tcg_gen_shli_tl(cc, tmp, 2);
1039 tcg_gen_and_tl(cc, tmp, cc);
1040 tcg_gen_andi_tl(cc, cc, Z_FLAG);
1041
1042 tcg_temp_free(tmp);
1043 }
1044 break;
1045 case CC_GE:
1046 cris_evaluate_flags(dc);
1047
1048 tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1049 tcg_gen_xor_tl(cc,
1050 cpu_PR[PR_CCS], cc);
1051 tcg_gen_andi_tl(cc, cc, N_FLAG);
1052 tcg_gen_xori_tl(cc, cc, N_FLAG);
1053 break;
1054 case CC_LT:
1055 cris_evaluate_flags(dc);
1056
1057 tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1058 tcg_gen_xor_tl(cc,
1059 cpu_PR[PR_CCS], cc);
1060 tcg_gen_andi_tl(cc, cc, N_FLAG);
1061 break;
1062 case CC_GT:
1063 cris_evaluate_flags(dc);
1064 {
1065 TCGv n, z;
1066
1067 n = tcg_temp_new();
1068 z = tcg_temp_new();
1069
1070
1071
1072 tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1073 tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1074
1075 tcg_gen_xori_tl(z, z, 2);
1076
1077 tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1078 tcg_gen_xori_tl(n, n, 2);
1079 tcg_gen_and_tl(cc, z, n);
1080 tcg_gen_andi_tl(cc, cc, 2);
1081
1082 tcg_temp_free(n);
1083 tcg_temp_free(z);
1084 }
1085 break;
1086 case CC_LE:
1087 cris_evaluate_flags(dc);
1088 {
1089 TCGv n, z;
1090
1091 n = tcg_temp_new();
1092 z = tcg_temp_new();
1093
1094
1095
1096 tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1097 tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1098
1099 tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1100 tcg_gen_or_tl(cc, z, n);
1101 tcg_gen_andi_tl(cc, cc, 2);
1102
1103 tcg_temp_free(n);
1104 tcg_temp_free(z);
1105 }
1106 break;
1107 case CC_P:
1108 cris_evaluate_flags(dc);
1109 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1110 break;
1111 case CC_A:
1112 tcg_gen_movi_tl(cc, 1);
1113 break;
1114 default:
1115 BUG();
1116 break;
1117 };
1118}
1119
1120static void cris_store_direct_jmp(DisasContext *dc)
1121{
1122
1123 if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1124 if (dc->jmp == JMP_DIRECT) {
1125 tcg_gen_movi_tl(env_btaken, 1);
1126 }
1127 tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1128 dc->jmp = JMP_INDIRECT;
1129 }
1130}
1131
1132static void cris_prepare_cc_branch (DisasContext *dc,
1133 int offset, int cond)
1134{
1135
1136
1137 dc->delayed_branch = 2;
1138 dc->jmp = JMP_DIRECT_CC;
1139 dc->jmp_pc = dc->pc + offset;
1140
1141 gen_tst_cc (dc, env_btaken, cond);
1142 tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1143}
1144
1145
1146
1147
1148static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1149{
1150
1151
1152 dc->delayed_branch = 2;
1153 dc->jmp = type;
1154 if (type == JMP_INDIRECT) {
1155 tcg_gen_movi_tl(env_btaken, 1);
1156 }
1157}
1158
1159static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1160{
1161 int mem_index = cpu_mmu_index(dc->env);
1162
1163
1164
1165 if (dc->delayed_branch == 1)
1166 cris_store_direct_jmp(dc);
1167
1168 tcg_gen_qemu_ld64(dst, addr, mem_index);
1169}
1170
1171static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
1172 unsigned int size, int sign)
1173{
1174 int mem_index = cpu_mmu_index(dc->env);
1175
1176
1177
1178 if (dc->delayed_branch == 1)
1179 cris_store_direct_jmp(dc);
1180
1181 if (size == 1) {
1182 if (sign)
1183 tcg_gen_qemu_ld8s(dst, addr, mem_index);
1184 else
1185 tcg_gen_qemu_ld8u(dst, addr, mem_index);
1186 }
1187 else if (size == 2) {
1188 if (sign)
1189 tcg_gen_qemu_ld16s(dst, addr, mem_index);
1190 else
1191 tcg_gen_qemu_ld16u(dst, addr, mem_index);
1192 }
1193 else if (size == 4) {
1194 tcg_gen_qemu_ld32u(dst, addr, mem_index);
1195 }
1196 else {
1197 abort();
1198 }
1199}
1200
1201static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1202 unsigned int size)
1203{
1204 int mem_index = cpu_mmu_index(dc->env);
1205
1206
1207
1208 if (dc->delayed_branch == 1)
1209 cris_store_direct_jmp(dc);
1210
1211
1212
1213
1214 if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1215 dc->postinc = 0;
1216 cris_evaluate_flags(dc);
1217 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1218 return;
1219 }
1220
1221 if (size == 1)
1222 tcg_gen_qemu_st8(val, addr, mem_index);
1223 else if (size == 2)
1224 tcg_gen_qemu_st16(val, addr, mem_index);
1225 else
1226 tcg_gen_qemu_st32(val, addr, mem_index);
1227
1228 if (dc->flagx_known && dc->flags_x) {
1229 cris_evaluate_flags(dc);
1230 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1231 }
1232}
1233
1234static inline void t_gen_sext(TCGv d, TCGv s, int size)
1235{
1236 if (size == 1)
1237 tcg_gen_ext8s_i32(d, s);
1238 else if (size == 2)
1239 tcg_gen_ext16s_i32(d, s);
1240 else if(!TCGV_EQUAL(d, s))
1241 tcg_gen_mov_tl(d, s);
1242}
1243
1244static inline void t_gen_zext(TCGv d, TCGv s, int size)
1245{
1246 if (size == 1)
1247 tcg_gen_ext8u_i32(d, s);
1248 else if (size == 2)
1249 tcg_gen_ext16u_i32(d, s);
1250 else if (!TCGV_EQUAL(d, s))
1251 tcg_gen_mov_tl(d, s);
1252}
1253
1254#if DISAS_CRIS
1255static char memsize_char(int size)
1256{
1257 switch (size)
1258 {
1259 case 1: return 'b'; break;
1260 case 2: return 'w'; break;
1261 case 4: return 'd'; break;
1262 default:
1263 return 'x';
1264 break;
1265 }
1266}
1267#endif
1268
1269static inline unsigned int memsize_z(DisasContext *dc)
1270{
1271 return dc->zsize + 1;
1272}
1273
1274static inline unsigned int memsize_zz(DisasContext *dc)
1275{
1276 switch (dc->zzsize)
1277 {
1278 case 0: return 1;
1279 case 1: return 2;
1280 default:
1281 return 4;
1282 }
1283}
1284
1285static inline void do_postinc (DisasContext *dc, int size)
1286{
1287 if (dc->postinc)
1288 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1289}
1290
1291static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1292 int size, int s_ext, TCGv dst)
1293{
1294 if (s_ext)
1295 t_gen_sext(dst, cpu_R[rs], size);
1296 else
1297 t_gen_zext(dst, cpu_R[rs], size);
1298}
1299
1300
1301
1302
1303static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1304 int size, int s_ext, TCGv dst, TCGv src)
1305{
1306 dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1307
1308 if (s_ext)
1309 t_gen_sext(dst, cpu_R[rd], size);
1310 else
1311 t_gen_zext(dst, cpu_R[rd], size);
1312}
1313
1314static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1315 TCGv dst)
1316{
1317 unsigned int rs;
1318 uint32_t imm;
1319 int is_imm;
1320 int insn_len = 2;
1321
1322 rs = dc->op1;
1323 is_imm = rs == 15 && dc->postinc;
1324
1325
1326 if (is_imm) {
1327 insn_len = 2 + memsize;
1328 if (memsize == 1)
1329 insn_len++;
1330
1331 imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
1332 tcg_gen_movi_tl(dst, imm);
1333 dc->postinc = 0;
1334 } else {
1335 cris_flush_cc_state(dc);
1336 gen_load(dc, dst, cpu_R[rs], memsize, 0);
1337 if (s_ext)
1338 t_gen_sext(dst, dst, memsize);
1339 else
1340 t_gen_zext(dst, dst, memsize);
1341 }
1342 return insn_len;
1343}
1344
1345
1346
1347
1348static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
1349 TCGv dst, TCGv src)
1350{
1351 int insn_len;
1352
1353 insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
1354 tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1355 return insn_len;
1356}
1357
1358#if DISAS_CRIS
1359static const char *cc_name(int cc)
1360{
1361 static const char *cc_names[16] = {
1362 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1363 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1364 };
1365 assert(cc < 16);
1366 return cc_names[cc];
1367}
1368#endif
1369
1370
1371
1372static int dec_bccq(DisasContext *dc)
1373{
1374 int32_t offset;
1375 int sign;
1376 uint32_t cond = dc->op2;
1377
1378 offset = EXTRACT_FIELD (dc->ir, 1, 7);
1379 sign = EXTRACT_FIELD(dc->ir, 0, 0);
1380
1381 offset *= 2;
1382 offset |= sign << 8;
1383 offset = sign_extend(offset, 8);
1384
1385 LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1386
1387
1388 cris_cc_mask(dc, 0);
1389 cris_prepare_cc_branch (dc, offset, cond);
1390 return 2;
1391}
1392static int dec_addoq(DisasContext *dc)
1393{
1394 int32_t imm;
1395
1396 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1397 imm = sign_extend(dc->op1, 7);
1398
1399 LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1400 cris_cc_mask(dc, 0);
1401
1402 tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1403
1404 return 2;
1405}
1406static int dec_addq(DisasContext *dc)
1407{
1408 LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1409
1410 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1411
1412 cris_cc_mask(dc, CC_MASK_NZVC);
1413
1414 cris_alu(dc, CC_OP_ADD,
1415 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1416 return 2;
1417}
1418static int dec_moveq(DisasContext *dc)
1419{
1420 uint32_t imm;
1421
1422 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1423 imm = sign_extend(dc->op1, 5);
1424 LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1425
1426 tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1427 return 2;
1428}
1429static int dec_subq(DisasContext *dc)
1430{
1431 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1432
1433 LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1434
1435 cris_cc_mask(dc, CC_MASK_NZVC);
1436 cris_alu(dc, CC_OP_SUB,
1437 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1438 return 2;
1439}
1440static int dec_cmpq(DisasContext *dc)
1441{
1442 uint32_t imm;
1443 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1444 imm = sign_extend(dc->op1, 5);
1445
1446 LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1447 cris_cc_mask(dc, CC_MASK_NZVC);
1448
1449 cris_alu(dc, CC_OP_CMP,
1450 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1451 return 2;
1452}
1453static int dec_andq(DisasContext *dc)
1454{
1455 uint32_t imm;
1456 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1457 imm = sign_extend(dc->op1, 5);
1458
1459 LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1460 cris_cc_mask(dc, CC_MASK_NZ);
1461
1462 cris_alu(dc, CC_OP_AND,
1463 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1464 return 2;
1465}
1466static int dec_orq(DisasContext *dc)
1467{
1468 uint32_t imm;
1469 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1470 imm = sign_extend(dc->op1, 5);
1471 LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1472 cris_cc_mask(dc, CC_MASK_NZ);
1473
1474 cris_alu(dc, CC_OP_OR,
1475 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1476 return 2;
1477}
1478static int dec_btstq(DisasContext *dc)
1479{
1480 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1481 LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1482
1483 cris_cc_mask(dc, CC_MASK_NZ);
1484 cris_evaluate_flags(dc);
1485 gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1486 tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1487 cris_alu(dc, CC_OP_MOVE,
1488 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1489 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1490 dc->flags_uptodate = 1;
1491 return 2;
1492}
1493static int dec_asrq(DisasContext *dc)
1494{
1495 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1496 LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1497 cris_cc_mask(dc, CC_MASK_NZ);
1498
1499 tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1500 cris_alu(dc, CC_OP_MOVE,
1501 cpu_R[dc->op2],
1502 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1503 return 2;
1504}
1505static int dec_lslq(DisasContext *dc)
1506{
1507 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1508 LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1509
1510 cris_cc_mask(dc, CC_MASK_NZ);
1511
1512 tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1513
1514 cris_alu(dc, CC_OP_MOVE,
1515 cpu_R[dc->op2],
1516 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1517 return 2;
1518}
1519static int dec_lsrq(DisasContext *dc)
1520{
1521 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1522 LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1523
1524 cris_cc_mask(dc, CC_MASK_NZ);
1525
1526 tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1527 cris_alu(dc, CC_OP_MOVE,
1528 cpu_R[dc->op2],
1529 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1530 return 2;
1531}
1532
1533static int dec_move_r(DisasContext *dc)
1534{
1535 int size = memsize_zz(dc);
1536
1537 LOG_DIS("move.%c $r%u, $r%u\n",
1538 memsize_char(size), dc->op1, dc->op2);
1539
1540 cris_cc_mask(dc, CC_MASK_NZ);
1541 if (size == 4) {
1542 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1543 cris_cc_mask(dc, CC_MASK_NZ);
1544 cris_update_cc_op(dc, CC_OP_MOVE, 4);
1545 cris_update_cc_x(dc);
1546 cris_update_result(dc, cpu_R[dc->op2]);
1547 }
1548 else {
1549 TCGv t0;
1550
1551 t0 = tcg_temp_new();
1552 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1553 cris_alu(dc, CC_OP_MOVE,
1554 cpu_R[dc->op2],
1555 cpu_R[dc->op2], t0, size);
1556 tcg_temp_free(t0);
1557 }
1558 return 2;
1559}
1560
1561static int dec_scc_r(DisasContext *dc)
1562{
1563 int cond = dc->op2;
1564
1565 LOG_DIS("s%s $r%u\n",
1566 cc_name(cond), dc->op1);
1567
1568 if (cond != CC_A)
1569 {
1570 int l1;
1571
1572 gen_tst_cc (dc, cpu_R[dc->op1], cond);
1573 l1 = gen_new_label();
1574 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1575 tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1576 gen_set_label(l1);
1577 }
1578 else
1579 tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1580
1581 cris_cc_mask(dc, 0);
1582 return 2;
1583}
1584
1585static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1586{
1587 if (size == 4) {
1588 t[0] = cpu_R[dc->op2];
1589 t[1] = cpu_R[dc->op1];
1590 } else {
1591 t[0] = tcg_temp_new();
1592 t[1] = tcg_temp_new();
1593 }
1594}
1595
1596static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1597{
1598 if (size != 4) {
1599 tcg_temp_free(t[0]);
1600 tcg_temp_free(t[1]);
1601 }
1602}
1603
1604static int dec_and_r(DisasContext *dc)
1605{
1606 TCGv t[2];
1607 int size = memsize_zz(dc);
1608
1609 LOG_DIS("and.%c $r%u, $r%u\n",
1610 memsize_char(size), dc->op1, dc->op2);
1611
1612 cris_cc_mask(dc, CC_MASK_NZ);
1613
1614 cris_alu_alloc_temps(dc, size, t);
1615 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1616 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1617 cris_alu_free_temps(dc, size, t);
1618 return 2;
1619}
1620
1621static int dec_lz_r(DisasContext *dc)
1622{
1623 TCGv t0;
1624 LOG_DIS("lz $r%u, $r%u\n",
1625 dc->op1, dc->op2);
1626 cris_cc_mask(dc, CC_MASK_NZ);
1627 t0 = tcg_temp_new();
1628 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1629 cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1630 tcg_temp_free(t0);
1631 return 2;
1632}
1633
1634static int dec_lsl_r(DisasContext *dc)
1635{
1636 TCGv t[2];
1637 int size = memsize_zz(dc);
1638
1639 LOG_DIS("lsl.%c $r%u, $r%u\n",
1640 memsize_char(size), dc->op1, dc->op2);
1641
1642 cris_cc_mask(dc, CC_MASK_NZ);
1643 cris_alu_alloc_temps(dc, size, t);
1644 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1645 tcg_gen_andi_tl(t[1], t[1], 63);
1646 cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1647 cris_alu_alloc_temps(dc, size, t);
1648 return 2;
1649}
1650
1651static int dec_lsr_r(DisasContext *dc)
1652{
1653 TCGv t[2];
1654 int size = memsize_zz(dc);
1655
1656 LOG_DIS("lsr.%c $r%u, $r%u\n",
1657 memsize_char(size), dc->op1, dc->op2);
1658
1659 cris_cc_mask(dc, CC_MASK_NZ);
1660 cris_alu_alloc_temps(dc, size, t);
1661 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1662 tcg_gen_andi_tl(t[1], t[1], 63);
1663 cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1664 cris_alu_free_temps(dc, size, t);
1665 return 2;
1666}
1667
1668static int dec_asr_r(DisasContext *dc)
1669{
1670 TCGv t[2];
1671 int size = memsize_zz(dc);
1672
1673 LOG_DIS("asr.%c $r%u, $r%u\n",
1674 memsize_char(size), dc->op1, dc->op2);
1675
1676 cris_cc_mask(dc, CC_MASK_NZ);
1677 cris_alu_alloc_temps(dc, size, t);
1678 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1679 tcg_gen_andi_tl(t[1], t[1], 63);
1680 cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1681 cris_alu_free_temps(dc, size, t);
1682 return 2;
1683}
1684
1685static int dec_muls_r(DisasContext *dc)
1686{
1687 TCGv t[2];
1688 int size = memsize_zz(dc);
1689
1690 LOG_DIS("muls.%c $r%u, $r%u\n",
1691 memsize_char(size), dc->op1, dc->op2);
1692 cris_cc_mask(dc, CC_MASK_NZV);
1693 cris_alu_alloc_temps(dc, size, t);
1694 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1695
1696 cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1697 cris_alu_free_temps(dc, size, t);
1698 return 2;
1699}
1700
1701static int dec_mulu_r(DisasContext *dc)
1702{
1703 TCGv t[2];
1704 int size = memsize_zz(dc);
1705
1706 LOG_DIS("mulu.%c $r%u, $r%u\n",
1707 memsize_char(size), dc->op1, dc->op2);
1708 cris_cc_mask(dc, CC_MASK_NZV);
1709 cris_alu_alloc_temps(dc, size, t);
1710 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1711
1712 cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1713 cris_alu_alloc_temps(dc, size, t);
1714 return 2;
1715}
1716
1717
1718static int dec_dstep_r(DisasContext *dc)
1719{
1720 LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1721 cris_cc_mask(dc, CC_MASK_NZ);
1722 cris_alu(dc, CC_OP_DSTEP,
1723 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1724 return 2;
1725}
1726
1727static int dec_xor_r(DisasContext *dc)
1728{
1729 TCGv t[2];
1730 int size = memsize_zz(dc);
1731 LOG_DIS("xor.%c $r%u, $r%u\n",
1732 memsize_char(size), dc->op1, dc->op2);
1733 BUG_ON(size != 4);
1734 cris_cc_mask(dc, CC_MASK_NZ);
1735 cris_alu_alloc_temps(dc, size, t);
1736 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1737
1738 cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1739 cris_alu_free_temps(dc, size, t);
1740 return 2;
1741}
1742
1743static int dec_bound_r(DisasContext *dc)
1744{
1745 TCGv l0;
1746 int size = memsize_zz(dc);
1747 LOG_DIS("bound.%c $r%u, $r%u\n",
1748 memsize_char(size), dc->op1, dc->op2);
1749 cris_cc_mask(dc, CC_MASK_NZ);
1750 l0 = tcg_temp_local_new();
1751 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1752 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1753 tcg_temp_free(l0);
1754 return 2;
1755}
1756
1757static int dec_cmp_r(DisasContext *dc)
1758{
1759 TCGv t[2];
1760 int size = memsize_zz(dc);
1761 LOG_DIS("cmp.%c $r%u, $r%u\n",
1762 memsize_char(size), dc->op1, dc->op2);
1763 cris_cc_mask(dc, CC_MASK_NZVC);
1764 cris_alu_alloc_temps(dc, size, t);
1765 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1766
1767 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1768 cris_alu_free_temps(dc, size, t);
1769 return 2;
1770}
1771
1772static int dec_abs_r(DisasContext *dc)
1773{
1774 TCGv t0;
1775
1776 LOG_DIS("abs $r%u, $r%u\n",
1777 dc->op1, dc->op2);
1778 cris_cc_mask(dc, CC_MASK_NZ);
1779
1780 t0 = tcg_temp_new();
1781 tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1782 tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1783 tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1784 tcg_temp_free(t0);
1785
1786 cris_alu(dc, CC_OP_MOVE,
1787 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1788 return 2;
1789}
1790
1791static int dec_add_r(DisasContext *dc)
1792{
1793 TCGv t[2];
1794 int size = memsize_zz(dc);
1795 LOG_DIS("add.%c $r%u, $r%u\n",
1796 memsize_char(size), dc->op1, dc->op2);
1797 cris_cc_mask(dc, CC_MASK_NZVC);
1798 cris_alu_alloc_temps(dc, size, t);
1799 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1800
1801 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1802 cris_alu_free_temps(dc, size, t);
1803 return 2;
1804}
1805
1806static int dec_addc_r(DisasContext *dc)
1807{
1808 LOG_DIS("addc $r%u, $r%u\n",
1809 dc->op1, dc->op2);
1810 cris_evaluate_flags(dc);
1811
1812 dc->flagx_known = 1;
1813 dc->flags_x = X_FLAG;
1814
1815 cris_cc_mask(dc, CC_MASK_NZVC);
1816 cris_alu(dc, CC_OP_ADDC,
1817 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1818 return 2;
1819}
1820
1821static int dec_mcp_r(DisasContext *dc)
1822{
1823 LOG_DIS("mcp $p%u, $r%u\n",
1824 dc->op2, dc->op1);
1825 cris_evaluate_flags(dc);
1826 cris_cc_mask(dc, CC_MASK_RNZV);
1827 cris_alu(dc, CC_OP_MCP,
1828 cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1829 return 2;
1830}
1831
1832#if DISAS_CRIS
1833static char * swapmode_name(int mode, char *modename) {
1834 int i = 0;
1835 if (mode & 8)
1836 modename[i++] = 'n';
1837 if (mode & 4)
1838 modename[i++] = 'w';
1839 if (mode & 2)
1840 modename[i++] = 'b';
1841 if (mode & 1)
1842 modename[i++] = 'r';
1843 modename[i++] = 0;
1844 return modename;
1845}
1846#endif
1847
1848static int dec_swap_r(DisasContext *dc)
1849{
1850 TCGv t0;
1851#if DISAS_CRIS
1852 char modename[4];
1853#endif
1854 LOG_DIS("swap%s $r%u\n",
1855 swapmode_name(dc->op2, modename), dc->op1);
1856
1857 cris_cc_mask(dc, CC_MASK_NZ);
1858 t0 = tcg_temp_new();
1859 t_gen_mov_TN_reg(t0, dc->op1);
1860 if (dc->op2 & 8)
1861 tcg_gen_not_tl(t0, t0);
1862 if (dc->op2 & 4)
1863 t_gen_swapw(t0, t0);
1864 if (dc->op2 & 2)
1865 t_gen_swapb(t0, t0);
1866 if (dc->op2 & 1)
1867 t_gen_swapr(t0, t0);
1868 cris_alu(dc, CC_OP_MOVE,
1869 cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1870 tcg_temp_free(t0);
1871 return 2;
1872}
1873
1874static int dec_or_r(DisasContext *dc)
1875{
1876 TCGv t[2];
1877 int size = memsize_zz(dc);
1878 LOG_DIS("or.%c $r%u, $r%u\n",
1879 memsize_char(size), dc->op1, dc->op2);
1880 cris_cc_mask(dc, CC_MASK_NZ);
1881 cris_alu_alloc_temps(dc, size, t);
1882 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1883 cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1884 cris_alu_free_temps(dc, size, t);
1885 return 2;
1886}
1887
1888static int dec_addi_r(DisasContext *dc)
1889{
1890 TCGv t0;
1891 LOG_DIS("addi.%c $r%u, $r%u\n",
1892 memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1893 cris_cc_mask(dc, 0);
1894 t0 = tcg_temp_new();
1895 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1896 tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1897 tcg_temp_free(t0);
1898 return 2;
1899}
1900
1901static int dec_addi_acr(DisasContext *dc)
1902{
1903 TCGv t0;
1904 LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1905 memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1906 cris_cc_mask(dc, 0);
1907 t0 = tcg_temp_new();
1908 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1909 tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1910 tcg_temp_free(t0);
1911 return 2;
1912}
1913
1914static int dec_neg_r(DisasContext *dc)
1915{
1916 TCGv t[2];
1917 int size = memsize_zz(dc);
1918 LOG_DIS("neg.%c $r%u, $r%u\n",
1919 memsize_char(size), dc->op1, dc->op2);
1920 cris_cc_mask(dc, CC_MASK_NZVC);
1921 cris_alu_alloc_temps(dc, size, t);
1922 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1923
1924 cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1925 cris_alu_free_temps(dc, size, t);
1926 return 2;
1927}
1928
1929static int dec_btst_r(DisasContext *dc)
1930{
1931 LOG_DIS("btst $r%u, $r%u\n",
1932 dc->op1, dc->op2);
1933 cris_cc_mask(dc, CC_MASK_NZ);
1934 cris_evaluate_flags(dc);
1935 gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1936 cpu_R[dc->op1], cpu_PR[PR_CCS]);
1937 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1938 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1939 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1940 dc->flags_uptodate = 1;
1941 return 2;
1942}
1943
1944static int dec_sub_r(DisasContext *dc)
1945{
1946 TCGv t[2];
1947 int size = memsize_zz(dc);
1948 LOG_DIS("sub.%c $r%u, $r%u\n",
1949 memsize_char(size), dc->op1, dc->op2);
1950 cris_cc_mask(dc, CC_MASK_NZVC);
1951 cris_alu_alloc_temps(dc, size, t);
1952 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1953 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1954 cris_alu_free_temps(dc, size, t);
1955 return 2;
1956}
1957
1958
1959static int dec_movu_r(DisasContext *dc)
1960{
1961 TCGv t0;
1962 int size = memsize_z(dc);
1963 LOG_DIS("movu.%c $r%u, $r%u\n",
1964 memsize_char(size),
1965 dc->op1, dc->op2);
1966
1967 cris_cc_mask(dc, CC_MASK_NZ);
1968 t0 = tcg_temp_new();
1969 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1970 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1971 tcg_temp_free(t0);
1972 return 2;
1973}
1974
1975
1976static int dec_movs_r(DisasContext *dc)
1977{
1978 TCGv t0;
1979 int size = memsize_z(dc);
1980 LOG_DIS("movs.%c $r%u, $r%u\n",
1981 memsize_char(size),
1982 dc->op1, dc->op2);
1983
1984 cris_cc_mask(dc, CC_MASK_NZ);
1985 t0 = tcg_temp_new();
1986
1987 t_gen_sext(t0, cpu_R[dc->op1], size);
1988 cris_alu(dc, CC_OP_MOVE,
1989 cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1990 tcg_temp_free(t0);
1991 return 2;
1992}
1993
1994
1995static int dec_addu_r(DisasContext *dc)
1996{
1997 TCGv t0;
1998 int size = memsize_z(dc);
1999 LOG_DIS("addu.%c $r%u, $r%u\n",
2000 memsize_char(size),
2001 dc->op1, dc->op2);
2002
2003 cris_cc_mask(dc, CC_MASK_NZVC);
2004 t0 = tcg_temp_new();
2005
2006 t_gen_zext(t0, cpu_R[dc->op1], size);
2007 cris_alu(dc, CC_OP_ADD,
2008 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2009 tcg_temp_free(t0);
2010 return 2;
2011}
2012
2013
2014static int dec_adds_r(DisasContext *dc)
2015{
2016 TCGv t0;
2017 int size = memsize_z(dc);
2018 LOG_DIS("adds.%c $r%u, $r%u\n",
2019 memsize_char(size),
2020 dc->op1, dc->op2);
2021
2022 cris_cc_mask(dc, CC_MASK_NZVC);
2023 t0 = tcg_temp_new();
2024
2025 t_gen_sext(t0, cpu_R[dc->op1], size);
2026 cris_alu(dc, CC_OP_ADD,
2027 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2028 tcg_temp_free(t0);
2029 return 2;
2030}
2031
2032
2033static int dec_subu_r(DisasContext *dc)
2034{
2035 TCGv t0;
2036 int size = memsize_z(dc);
2037 LOG_DIS("subu.%c $r%u, $r%u\n",
2038 memsize_char(size),
2039 dc->op1, dc->op2);
2040
2041 cris_cc_mask(dc, CC_MASK_NZVC);
2042 t0 = tcg_temp_new();
2043
2044 t_gen_zext(t0, cpu_R[dc->op1], size);
2045 cris_alu(dc, CC_OP_SUB,
2046 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2047 tcg_temp_free(t0);
2048 return 2;
2049}
2050
2051
2052static int dec_subs_r(DisasContext *dc)
2053{
2054 TCGv t0;
2055 int size = memsize_z(dc);
2056 LOG_DIS("subs.%c $r%u, $r%u\n",
2057 memsize_char(size),
2058 dc->op1, dc->op2);
2059
2060 cris_cc_mask(dc, CC_MASK_NZVC);
2061 t0 = tcg_temp_new();
2062
2063 t_gen_sext(t0, cpu_R[dc->op1], size);
2064 cris_alu(dc, CC_OP_SUB,
2065 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2066 tcg_temp_free(t0);
2067 return 2;
2068}
2069
2070static int dec_setclrf(DisasContext *dc)
2071{
2072 uint32_t flags;
2073 int set = (~dc->opcode >> 2) & 1;
2074
2075
2076 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2077 | EXTRACT_FIELD(dc->ir, 0, 3);
2078 if (set && flags == 0) {
2079 LOG_DIS("nop\n");
2080 return 2;
2081 } else if (!set && (flags & 0x20)) {
2082 LOG_DIS("di\n");
2083 }
2084 else {
2085 LOG_DIS("%sf %x\n",
2086 set ? "set" : "clr",
2087 flags);
2088 }
2089
2090
2091 if (dc->tb_flags & U_FLAG) {
2092 flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2093 }
2094
2095 if (flags & X_FLAG) {
2096 dc->flagx_known = 1;
2097 if (set)
2098 dc->flags_x = X_FLAG;
2099 else
2100 dc->flags_x = 0;
2101 }
2102
2103
2104 if (flags & (P_FLAG | S_FLAG)) {
2105 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2106 dc->is_jmp = DISAS_UPDATE;
2107 dc->cpustate_changed = 1;
2108 }
2109
2110
2111 if ((flags & I_FLAG)) {
2112 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2113 dc->is_jmp = DISAS_UPDATE;
2114 dc->cpustate_changed = 1;
2115 }
2116
2117
2118
2119 cris_evaluate_flags (dc);
2120 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2121 cris_update_cc_x(dc);
2122 tcg_gen_movi_tl(cc_op, dc->cc_op);
2123
2124 if (set) {
2125 if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2126
2127 t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2128 tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2129 dc->cpustate_changed = 1;
2130 }
2131 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2132 }
2133 else
2134 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2135
2136 dc->flags_uptodate = 1;
2137 dc->clear_x = 0;
2138 return 2;
2139}
2140
2141static int dec_move_rs(DisasContext *dc)
2142{
2143 LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2144 cris_cc_mask(dc, 0);
2145 gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
2146 return 2;
2147}
2148static int dec_move_sr(DisasContext *dc)
2149{
2150 LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2151 cris_cc_mask(dc, 0);
2152 gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
2153 return 2;
2154}
2155
2156static int dec_move_rp(DisasContext *dc)
2157{
2158 TCGv t[2];
2159 LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2160 cris_cc_mask(dc, 0);
2161
2162 t[0] = tcg_temp_new();
2163 if (dc->op2 == PR_CCS) {
2164 cris_evaluate_flags(dc);
2165 t_gen_mov_TN_reg(t[0], dc->op1);
2166 if (dc->tb_flags & U_FLAG) {
2167 t[1] = tcg_temp_new();
2168
2169 tcg_gen_andi_tl(t[0], t[0], 0x39f);
2170 tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2171 tcg_gen_or_tl(t[0], t[1], t[0]);
2172 tcg_temp_free(t[1]);
2173 }
2174 }
2175 else
2176 t_gen_mov_TN_reg(t[0], dc->op1);
2177
2178 t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2179 if (dc->op2 == PR_CCS) {
2180 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2181 dc->flags_uptodate = 1;
2182 }
2183 tcg_temp_free(t[0]);
2184 return 2;
2185}
2186static int dec_move_pr(DisasContext *dc)
2187{
2188 TCGv t0;
2189 LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2190 cris_cc_mask(dc, 0);
2191
2192 if (dc->op2 == PR_CCS)
2193 cris_evaluate_flags(dc);
2194
2195 if (dc->op2 == PR_DZ) {
2196 tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2197 } else {
2198 t0 = tcg_temp_new();
2199 t_gen_mov_TN_preg(t0, dc->op2);
2200 cris_alu(dc, CC_OP_MOVE,
2201 cpu_R[dc->op1], cpu_R[dc->op1], t0,
2202 preg_sizes[dc->op2]);
2203 tcg_temp_free(t0);
2204 }
2205 return 2;
2206}
2207
2208static int dec_move_mr(DisasContext *dc)
2209{
2210 int memsize = memsize_zz(dc);
2211 int insn_len;
2212 LOG_DIS("move.%c [$r%u%s, $r%u\n",
2213 memsize_char(memsize),
2214 dc->op1, dc->postinc ? "+]" : "]",
2215 dc->op2);
2216
2217 if (memsize == 4) {
2218 insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
2219 cris_cc_mask(dc, CC_MASK_NZ);
2220 cris_update_cc_op(dc, CC_OP_MOVE, 4);
2221 cris_update_cc_x(dc);
2222 cris_update_result(dc, cpu_R[dc->op2]);
2223 }
2224 else {
2225 TCGv t0;
2226
2227 t0 = tcg_temp_new();
2228 insn_len = dec_prep_move_m(dc, 0, memsize, t0);
2229 cris_cc_mask(dc, CC_MASK_NZ);
2230 cris_alu(dc, CC_OP_MOVE,
2231 cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2232 tcg_temp_free(t0);
2233 }
2234 do_postinc(dc, memsize);
2235 return insn_len;
2236}
2237
2238static inline void cris_alu_m_alloc_temps(TCGv *t)
2239{
2240 t[0] = tcg_temp_new();
2241 t[1] = tcg_temp_new();
2242}
2243
2244static inline void cris_alu_m_free_temps(TCGv *t)
2245{
2246 tcg_temp_free(t[0]);
2247 tcg_temp_free(t[1]);
2248}
2249
2250static int dec_movs_m(DisasContext *dc)
2251{
2252 TCGv t[2];
2253 int memsize = memsize_z(dc);
2254 int insn_len;
2255 LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2256 memsize_char(memsize),
2257 dc->op1, dc->postinc ? "+]" : "]",
2258 dc->op2);
2259
2260 cris_alu_m_alloc_temps(t);
2261
2262 insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2263 cris_cc_mask(dc, CC_MASK_NZ);
2264 cris_alu(dc, CC_OP_MOVE,
2265 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2266 do_postinc(dc, memsize);
2267 cris_alu_m_free_temps(t);
2268 return insn_len;
2269}
2270
2271static int dec_addu_m(DisasContext *dc)
2272{
2273 TCGv t[2];
2274 int memsize = memsize_z(dc);
2275 int insn_len;
2276 LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2277 memsize_char(memsize),
2278 dc->op1, dc->postinc ? "+]" : "]",
2279 dc->op2);
2280
2281 cris_alu_m_alloc_temps(t);
2282
2283 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2284 cris_cc_mask(dc, CC_MASK_NZVC);
2285 cris_alu(dc, CC_OP_ADD,
2286 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2287 do_postinc(dc, memsize);
2288 cris_alu_m_free_temps(t);
2289 return insn_len;
2290}
2291
2292static int dec_adds_m(DisasContext *dc)
2293{
2294 TCGv t[2];
2295 int memsize = memsize_z(dc);
2296 int insn_len;
2297 LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2298 memsize_char(memsize),
2299 dc->op1, dc->postinc ? "+]" : "]",
2300 dc->op2);
2301
2302 cris_alu_m_alloc_temps(t);
2303
2304 insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2305 cris_cc_mask(dc, CC_MASK_NZVC);
2306 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2307 do_postinc(dc, memsize);
2308 cris_alu_m_free_temps(t);
2309 return insn_len;
2310}
2311
2312static int dec_subu_m(DisasContext *dc)
2313{
2314 TCGv t[2];
2315 int memsize = memsize_z(dc);
2316 int insn_len;
2317 LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2318 memsize_char(memsize),
2319 dc->op1, dc->postinc ? "+]" : "]",
2320 dc->op2);
2321
2322 cris_alu_m_alloc_temps(t);
2323
2324 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2325 cris_cc_mask(dc, CC_MASK_NZVC);
2326 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2327 do_postinc(dc, memsize);
2328 cris_alu_m_free_temps(t);
2329 return insn_len;
2330}
2331
2332static int dec_subs_m(DisasContext *dc)
2333{
2334 TCGv t[2];
2335 int memsize = memsize_z(dc);
2336 int insn_len;
2337 LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2338 memsize_char(memsize),
2339 dc->op1, dc->postinc ? "+]" : "]",
2340 dc->op2);
2341
2342 cris_alu_m_alloc_temps(t);
2343
2344 insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2345 cris_cc_mask(dc, CC_MASK_NZVC);
2346 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2347 do_postinc(dc, memsize);
2348 cris_alu_m_free_temps(t);
2349 return insn_len;
2350}
2351
2352static int dec_movu_m(DisasContext *dc)
2353{
2354 TCGv t[2];
2355 int memsize = memsize_z(dc);
2356 int insn_len;
2357
2358 LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2359 memsize_char(memsize),
2360 dc->op1, dc->postinc ? "+]" : "]",
2361 dc->op2);
2362
2363 cris_alu_m_alloc_temps(t);
2364 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2365 cris_cc_mask(dc, CC_MASK_NZ);
2366 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2367 do_postinc(dc, memsize);
2368 cris_alu_m_free_temps(t);
2369 return insn_len;
2370}
2371
2372static int dec_cmpu_m(DisasContext *dc)
2373{
2374 TCGv t[2];
2375 int memsize = memsize_z(dc);
2376 int insn_len;
2377 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2378 memsize_char(memsize),
2379 dc->op1, dc->postinc ? "+]" : "]",
2380 dc->op2);
2381
2382 cris_alu_m_alloc_temps(t);
2383 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2384 cris_cc_mask(dc, CC_MASK_NZVC);
2385 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2386 do_postinc(dc, memsize);
2387 cris_alu_m_free_temps(t);
2388 return insn_len;
2389}
2390
2391static int dec_cmps_m(DisasContext *dc)
2392{
2393 TCGv t[2];
2394 int memsize = memsize_z(dc);
2395 int insn_len;
2396 LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2397 memsize_char(memsize),
2398 dc->op1, dc->postinc ? "+]" : "]",
2399 dc->op2);
2400
2401 cris_alu_m_alloc_temps(t);
2402 insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2403 cris_cc_mask(dc, CC_MASK_NZVC);
2404 cris_alu(dc, CC_OP_CMP,
2405 cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2406 memsize_zz(dc));
2407 do_postinc(dc, memsize);
2408 cris_alu_m_free_temps(t);
2409 return insn_len;
2410}
2411
2412static int dec_cmp_m(DisasContext *dc)
2413{
2414 TCGv t[2];
2415 int memsize = memsize_zz(dc);
2416 int insn_len;
2417 LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2418 memsize_char(memsize),
2419 dc->op1, dc->postinc ? "+]" : "]",
2420 dc->op2);
2421
2422 cris_alu_m_alloc_temps(t);
2423 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2424 cris_cc_mask(dc, CC_MASK_NZVC);
2425 cris_alu(dc, CC_OP_CMP,
2426 cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2427 memsize_zz(dc));
2428 do_postinc(dc, memsize);
2429 cris_alu_m_free_temps(t);
2430 return insn_len;
2431}
2432
2433static int dec_test_m(DisasContext *dc)
2434{
2435 TCGv t[2];
2436 int memsize = memsize_zz(dc);
2437 int insn_len;
2438 LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2439 memsize_char(memsize),
2440 dc->op1, dc->postinc ? "+]" : "]",
2441 dc->op2);
2442
2443 cris_evaluate_flags(dc);
2444
2445 cris_alu_m_alloc_temps(t);
2446 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2447 cris_cc_mask(dc, CC_MASK_NZ);
2448 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2449
2450 cris_alu(dc, CC_OP_CMP,
2451 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2452 do_postinc(dc, memsize);
2453 cris_alu_m_free_temps(t);
2454 return insn_len;
2455}
2456
2457static int dec_and_m(DisasContext *dc)
2458{
2459 TCGv t[2];
2460 int memsize = memsize_zz(dc);
2461 int insn_len;
2462 LOG_DIS("and.%c [$r%u%s, $r%u\n",
2463 memsize_char(memsize),
2464 dc->op1, dc->postinc ? "+]" : "]",
2465 dc->op2);
2466
2467 cris_alu_m_alloc_temps(t);
2468 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2469 cris_cc_mask(dc, CC_MASK_NZ);
2470 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2471 do_postinc(dc, memsize);
2472 cris_alu_m_free_temps(t);
2473 return insn_len;
2474}
2475
2476static int dec_add_m(DisasContext *dc)
2477{
2478 TCGv t[2];
2479 int memsize = memsize_zz(dc);
2480 int insn_len;
2481 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2482 memsize_char(memsize),
2483 dc->op1, dc->postinc ? "+]" : "]",
2484 dc->op2);
2485
2486 cris_alu_m_alloc_temps(t);
2487 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2488 cris_cc_mask(dc, CC_MASK_NZVC);
2489 cris_alu(dc, CC_OP_ADD,
2490 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2491 do_postinc(dc, memsize);
2492 cris_alu_m_free_temps(t);
2493 return insn_len;
2494}
2495
2496static int dec_addo_m(DisasContext *dc)
2497{
2498 TCGv t[2];
2499 int memsize = memsize_zz(dc);
2500 int insn_len;
2501 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2502 memsize_char(memsize),
2503 dc->op1, dc->postinc ? "+]" : "]",
2504 dc->op2);
2505
2506 cris_alu_m_alloc_temps(t);
2507 insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2508 cris_cc_mask(dc, 0);
2509 cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2510 do_postinc(dc, memsize);
2511 cris_alu_m_free_temps(t);
2512 return insn_len;
2513}
2514
2515static int dec_bound_m(DisasContext *dc)
2516{
2517 TCGv l[2];
2518 int memsize = memsize_zz(dc);
2519 int insn_len;
2520 LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2521 memsize_char(memsize),
2522 dc->op1, dc->postinc ? "+]" : "]",
2523 dc->op2);
2524
2525 l[0] = tcg_temp_local_new();
2526 l[1] = tcg_temp_local_new();
2527 insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
2528 cris_cc_mask(dc, CC_MASK_NZ);
2529 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2530 do_postinc(dc, memsize);
2531 tcg_temp_free(l[0]);
2532 tcg_temp_free(l[1]);
2533 return insn_len;
2534}
2535
2536static int dec_addc_mr(DisasContext *dc)
2537{
2538 TCGv t[2];
2539 int insn_len = 2;
2540 LOG_DIS("addc [$r%u%s, $r%u\n",
2541 dc->op1, dc->postinc ? "+]" : "]",
2542 dc->op2);
2543
2544 cris_evaluate_flags(dc);
2545
2546
2547 dc->flagx_known = 1;
2548 dc->flags_x = X_FLAG;
2549
2550 cris_alu_m_alloc_temps(t);
2551 insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2552 cris_cc_mask(dc, CC_MASK_NZVC);
2553 cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2554 do_postinc(dc, 4);
2555 cris_alu_m_free_temps(t);
2556 return insn_len;
2557}
2558
2559static int dec_sub_m(DisasContext *dc)
2560{
2561 TCGv t[2];
2562 int memsize = memsize_zz(dc);
2563 int insn_len;
2564 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2565 memsize_char(memsize),
2566 dc->op1, dc->postinc ? "+]" : "]",
2567 dc->op2, dc->ir, dc->zzsize);
2568
2569 cris_alu_m_alloc_temps(t);
2570 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2571 cris_cc_mask(dc, CC_MASK_NZVC);
2572 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2573 do_postinc(dc, memsize);
2574 cris_alu_m_free_temps(t);
2575 return insn_len;
2576}
2577
2578static int dec_or_m(DisasContext *dc)
2579{
2580 TCGv t[2];
2581 int memsize = memsize_zz(dc);
2582 int insn_len;
2583 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2584 memsize_char(memsize),
2585 dc->op1, dc->postinc ? "+]" : "]",
2586 dc->op2, dc->pc);
2587
2588 cris_alu_m_alloc_temps(t);
2589 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2590 cris_cc_mask(dc, CC_MASK_NZ);
2591 cris_alu(dc, CC_OP_OR,
2592 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2593 do_postinc(dc, memsize);
2594 cris_alu_m_free_temps(t);
2595 return insn_len;
2596}
2597
2598static int dec_move_mp(DisasContext *dc)
2599{
2600 TCGv t[2];
2601 int memsize = memsize_zz(dc);
2602 int insn_len = 2;
2603
2604 LOG_DIS("move.%c [$r%u%s, $p%u\n",
2605 memsize_char(memsize),
2606 dc->op1,
2607 dc->postinc ? "+]" : "]",
2608 dc->op2);
2609
2610 cris_alu_m_alloc_temps(t);
2611 insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2612 cris_cc_mask(dc, 0);
2613 if (dc->op2 == PR_CCS) {
2614 cris_evaluate_flags(dc);
2615 if (dc->tb_flags & U_FLAG) {
2616
2617 tcg_gen_andi_tl(t[1], t[1], 0x39f);
2618 tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2619 tcg_gen_or_tl(t[1], t[0], t[1]);
2620 }
2621 }
2622
2623 t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2624
2625 do_postinc(dc, memsize);
2626 cris_alu_m_free_temps(t);
2627 return insn_len;
2628}
2629
2630static int dec_move_pm(DisasContext *dc)
2631{
2632 TCGv t0;
2633 int memsize;
2634
2635 memsize = preg_sizes[dc->op2];
2636
2637 LOG_DIS("move.%c $p%u, [$r%u%s\n",
2638 memsize_char(memsize),
2639 dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2640
2641
2642 if (dc->op2 == PR_CCS)
2643 cris_evaluate_flags(dc);
2644 t0 = tcg_temp_new();
2645 t_gen_mov_TN_preg(t0, dc->op2);
2646 cris_flush_cc_state(dc);
2647 gen_store(dc, cpu_R[dc->op1], t0, memsize);
2648 tcg_temp_free(t0);
2649
2650 cris_cc_mask(dc, 0);
2651 if (dc->postinc)
2652 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2653 return 2;
2654}
2655
2656static int dec_movem_mr(DisasContext *dc)
2657{
2658 TCGv_i64 tmp[16];
2659 TCGv tmp32;
2660 TCGv addr;
2661 int i;
2662 int nr = dc->op2 + 1;
2663
2664 LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2665 dc->postinc ? "+]" : "]", dc->op2);
2666
2667 addr = tcg_temp_new();
2668
2669 cris_flush_cc_state(dc);
2670 for (i = 0; i < (nr >> 1); i++) {
2671 tmp[i] = tcg_temp_new_i64();
2672 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2673 gen_load64(dc, tmp[i], addr);
2674 }
2675 if (nr & 1) {
2676 tmp32 = tcg_temp_new_i32();
2677 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2678 gen_load(dc, tmp32, addr, 4, 0);
2679 } else
2680 TCGV_UNUSED(tmp32);
2681 tcg_temp_free(addr);
2682
2683 for (i = 0; i < (nr >> 1); i++) {
2684 tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2685 tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2686 tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2687 tcg_temp_free_i64(tmp[i]);
2688 }
2689 if (nr & 1) {
2690 tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2691 tcg_temp_free(tmp32);
2692 }
2693
2694
2695 if (dc->postinc)
2696 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2697
2698
2699 cris_cc_mask(dc, 0);
2700 return 2;
2701}
2702
2703static int dec_movem_rm(DisasContext *dc)
2704{
2705 TCGv tmp;
2706 TCGv addr;
2707 int i;
2708
2709 LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2710 dc->postinc ? "+]" : "]");
2711
2712 cris_flush_cc_state(dc);
2713
2714 tmp = tcg_temp_new();
2715 addr = tcg_temp_new();
2716 tcg_gen_movi_tl(tmp, 4);
2717 tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2718 for (i = 0; i <= dc->op2; i++) {
2719
2720
2721 gen_store(dc, addr, cpu_R[i], 4);
2722 tcg_gen_add_tl(addr, addr, tmp);
2723 }
2724 if (dc->postinc)
2725 tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2726 cris_cc_mask(dc, 0);
2727 tcg_temp_free(tmp);
2728 tcg_temp_free(addr);
2729 return 2;
2730}
2731
2732static int dec_move_rm(DisasContext *dc)
2733{
2734 int memsize;
2735
2736 memsize = memsize_zz(dc);
2737
2738 LOG_DIS("move.%c $r%u, [$r%u]\n",
2739 memsize_char(memsize), dc->op2, dc->op1);
2740
2741
2742 cris_flush_cc_state(dc);
2743 gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2744
2745 if (dc->postinc)
2746 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2747 cris_cc_mask(dc, 0);
2748 return 2;
2749}
2750
2751static int dec_lapcq(DisasContext *dc)
2752{
2753 LOG_DIS("lapcq %x, $r%u\n",
2754 dc->pc + dc->op1*2, dc->op2);
2755 cris_cc_mask(dc, 0);
2756 tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2757 return 2;
2758}
2759
2760static int dec_lapc_im(DisasContext *dc)
2761{
2762 unsigned int rd;
2763 int32_t imm;
2764 int32_t pc;
2765
2766 rd = dc->op2;
2767
2768 cris_cc_mask(dc, 0);
2769 imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2770 LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2771
2772 pc = dc->pc;
2773 pc += imm;
2774 tcg_gen_movi_tl(cpu_R[rd], pc);
2775 return 6;
2776}
2777
2778
2779static int dec_jump_p(DisasContext *dc)
2780{
2781 LOG_DIS("jump $p%u\n", dc->op2);
2782
2783 if (dc->op2 == PR_CCS)
2784 cris_evaluate_flags(dc);
2785 t_gen_mov_TN_preg(env_btarget, dc->op2);
2786
2787 tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2788 cris_cc_mask(dc, 0);
2789 cris_prepare_jmp(dc, JMP_INDIRECT);
2790 return 2;
2791}
2792
2793
2794static int dec_jas_r(DisasContext *dc)
2795{
2796 LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2797 cris_cc_mask(dc, 0);
2798
2799 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2800 if (dc->op2 > 15)
2801 abort();
2802 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2803
2804 cris_prepare_jmp(dc, JMP_INDIRECT);
2805 return 2;
2806}
2807
2808static int dec_jas_im(DisasContext *dc)
2809{
2810 uint32_t imm;
2811
2812 imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2813
2814 LOG_DIS("jas 0x%x\n", imm);
2815 cris_cc_mask(dc, 0);
2816
2817 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2818
2819 dc->jmp_pc = imm;
2820 cris_prepare_jmp(dc, JMP_DIRECT);
2821 return 6;
2822}
2823
2824static int dec_jasc_im(DisasContext *dc)
2825{
2826 uint32_t imm;
2827
2828 imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2829
2830 LOG_DIS("jasc 0x%x\n", imm);
2831 cris_cc_mask(dc, 0);
2832
2833 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2834
2835 dc->jmp_pc = imm;
2836 cris_prepare_jmp(dc, JMP_DIRECT);
2837 return 6;
2838}
2839
2840static int dec_jasc_r(DisasContext *dc)
2841{
2842 LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2843 cris_cc_mask(dc, 0);
2844
2845 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2846 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2847 cris_prepare_jmp(dc, JMP_INDIRECT);
2848 return 2;
2849}
2850
2851static int dec_bcc_im(DisasContext *dc)
2852{
2853 int32_t offset;
2854 uint32_t cond = dc->op2;
2855
2856 offset = cris_fetch(dc, dc->pc + 2, 2, 1);
2857
2858 LOG_DIS("b%s %d pc=%x dst=%x\n",
2859 cc_name(cond), offset,
2860 dc->pc, dc->pc + offset);
2861
2862 cris_cc_mask(dc, 0);
2863
2864 cris_prepare_cc_branch (dc, offset, cond);
2865 return 4;
2866}
2867
2868static int dec_bas_im(DisasContext *dc)
2869{
2870 int32_t simm;
2871
2872
2873 simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2874
2875 LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2876 cris_cc_mask(dc, 0);
2877
2878 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2879
2880 dc->jmp_pc = dc->pc + simm;
2881 cris_prepare_jmp(dc, JMP_DIRECT);
2882 return 6;
2883}
2884
2885static int dec_basc_im(DisasContext *dc)
2886{
2887 int32_t simm;
2888 simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2889
2890 LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2891 cris_cc_mask(dc, 0);
2892
2893 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2894
2895 dc->jmp_pc = dc->pc + simm;
2896 cris_prepare_jmp(dc, JMP_DIRECT);
2897 return 6;
2898}
2899
2900static int dec_rfe_etc(DisasContext *dc)
2901{
2902 cris_cc_mask(dc, 0);
2903
2904 if (dc->op2 == 15) {
2905 t_gen_mov_env_TN(halted, tcg_const_tl(1));
2906 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2907 t_gen_raise_exception(EXCP_HLT);
2908 return 2;
2909 }
2910
2911 switch (dc->op2 & 7) {
2912 case 2:
2913
2914 LOG_DIS("rfe\n");
2915 cris_evaluate_flags(dc);
2916 gen_helper_rfe();
2917 dc->is_jmp = DISAS_UPDATE;
2918 break;
2919 case 5:
2920
2921 LOG_DIS("rfn\n");
2922 cris_evaluate_flags(dc);
2923 gen_helper_rfn();
2924 dc->is_jmp = DISAS_UPDATE;
2925 break;
2926 case 6:
2927 LOG_DIS("break %d\n", dc->op1);
2928 cris_evaluate_flags (dc);
2929
2930 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2931
2932
2933 t_gen_mov_env_TN(trap_vector,
2934 tcg_const_tl(dc->op1 + 16));
2935 t_gen_raise_exception(EXCP_BREAK);
2936 dc->is_jmp = DISAS_UPDATE;
2937 break;
2938 default:
2939 printf ("op2=%x\n", dc->op2);
2940 BUG();
2941 break;
2942
2943 }
2944 return 2;
2945}
2946
2947static int dec_ftag_fidx_d_m(DisasContext *dc)
2948{
2949 return 2;
2950}
2951
2952static int dec_ftag_fidx_i_m(DisasContext *dc)
2953{
2954 return 2;
2955}
2956
2957static int dec_null(DisasContext *dc)
2958{
2959 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2960 dc->pc, dc->opcode, dc->op1, dc->op2);
2961 fflush(NULL);
2962 BUG();
2963 return 2;
2964}
2965
2966static struct decoder_info {
2967 struct {
2968 uint32_t bits;
2969 uint32_t mask;
2970 };
2971 int (*dec)(DisasContext *dc);
2972} decinfo[] = {
2973
2974 {DEC_MOVEQ, dec_moveq},
2975 {DEC_BTSTQ, dec_btstq},
2976 {DEC_CMPQ, dec_cmpq},
2977 {DEC_ADDOQ, dec_addoq},
2978 {DEC_ADDQ, dec_addq},
2979 {DEC_SUBQ, dec_subq},
2980 {DEC_ANDQ, dec_andq},
2981 {DEC_ORQ, dec_orq},
2982 {DEC_ASRQ, dec_asrq},
2983 {DEC_LSLQ, dec_lslq},
2984 {DEC_LSRQ, dec_lsrq},
2985 {DEC_BCCQ, dec_bccq},
2986
2987 {DEC_BCC_IM, dec_bcc_im},
2988 {DEC_JAS_IM, dec_jas_im},
2989 {DEC_JAS_R, dec_jas_r},
2990 {DEC_JASC_IM, dec_jasc_im},
2991 {DEC_JASC_R, dec_jasc_r},
2992 {DEC_BAS_IM, dec_bas_im},
2993 {DEC_BASC_IM, dec_basc_im},
2994 {DEC_JUMP_P, dec_jump_p},
2995 {DEC_LAPC_IM, dec_lapc_im},
2996 {DEC_LAPCQ, dec_lapcq},
2997
2998 {DEC_RFE_ETC, dec_rfe_etc},
2999 {DEC_ADDC_MR, dec_addc_mr},
3000
3001 {DEC_MOVE_MP, dec_move_mp},
3002 {DEC_MOVE_PM, dec_move_pm},
3003 {DEC_MOVEM_MR, dec_movem_mr},
3004 {DEC_MOVEM_RM, dec_movem_rm},
3005 {DEC_MOVE_PR, dec_move_pr},
3006 {DEC_SCC_R, dec_scc_r},
3007 {DEC_SETF, dec_setclrf},
3008 {DEC_CLEARF, dec_setclrf},
3009
3010 {DEC_MOVE_SR, dec_move_sr},
3011 {DEC_MOVE_RP, dec_move_rp},
3012 {DEC_SWAP_R, dec_swap_r},
3013 {DEC_ABS_R, dec_abs_r},
3014 {DEC_LZ_R, dec_lz_r},
3015 {DEC_MOVE_RS, dec_move_rs},
3016 {DEC_BTST_R, dec_btst_r},
3017 {DEC_ADDC_R, dec_addc_r},
3018
3019 {DEC_DSTEP_R, dec_dstep_r},
3020 {DEC_XOR_R, dec_xor_r},
3021 {DEC_MCP_R, dec_mcp_r},
3022 {DEC_CMP_R, dec_cmp_r},
3023
3024 {DEC_ADDI_R, dec_addi_r},
3025 {DEC_ADDI_ACR, dec_addi_acr},
3026
3027 {DEC_ADD_R, dec_add_r},
3028 {DEC_SUB_R, dec_sub_r},
3029
3030 {DEC_ADDU_R, dec_addu_r},
3031 {DEC_ADDS_R, dec_adds_r},
3032 {DEC_SUBU_R, dec_subu_r},
3033 {DEC_SUBS_R, dec_subs_r},
3034 {DEC_LSL_R, dec_lsl_r},
3035
3036 {DEC_AND_R, dec_and_r},
3037 {DEC_OR_R, dec_or_r},
3038 {DEC_BOUND_R, dec_bound_r},
3039 {DEC_ASR_R, dec_asr_r},
3040 {DEC_LSR_R, dec_lsr_r},
3041
3042 {DEC_MOVU_R, dec_movu_r},
3043 {DEC_MOVS_R, dec_movs_r},
3044 {DEC_NEG_R, dec_neg_r},
3045 {DEC_MOVE_R, dec_move_r},
3046
3047 {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3048 {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3049
3050 {DEC_MULS_R, dec_muls_r},
3051 {DEC_MULU_R, dec_mulu_r},
3052
3053 {DEC_ADDU_M, dec_addu_m},
3054 {DEC_ADDS_M, dec_adds_m},
3055 {DEC_SUBU_M, dec_subu_m},
3056 {DEC_SUBS_M, dec_subs_m},
3057
3058 {DEC_CMPU_M, dec_cmpu_m},
3059 {DEC_CMPS_M, dec_cmps_m},
3060 {DEC_MOVU_M, dec_movu_m},
3061 {DEC_MOVS_M, dec_movs_m},
3062
3063 {DEC_CMP_M, dec_cmp_m},
3064 {DEC_ADDO_M, dec_addo_m},
3065 {DEC_BOUND_M, dec_bound_m},
3066 {DEC_ADD_M, dec_add_m},
3067 {DEC_SUB_M, dec_sub_m},
3068 {DEC_AND_M, dec_and_m},
3069 {DEC_OR_M, dec_or_m},
3070 {DEC_MOVE_RM, dec_move_rm},
3071 {DEC_TEST_M, dec_test_m},
3072 {DEC_MOVE_MR, dec_move_mr},
3073
3074 {{0, 0}, dec_null}
3075};
3076
3077static unsigned int crisv32_decoder(DisasContext *dc)
3078{
3079 int insn_len = 2;
3080 int i;
3081
3082 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
3083 tcg_gen_debug_insn_start(dc->pc);
3084
3085
3086 dc->ir = cris_fetch(dc, dc->pc, 2, 0);
3087
3088
3089 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
3090 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
3091 dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
3092 dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
3093 dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
3094 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
3095
3096
3097 for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3098 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
3099 {
3100 insn_len = decinfo[i].dec(dc);
3101 break;
3102 }
3103 }
3104
3105#if !defined(CONFIG_USER_ONLY)
3106
3107 if (dc->tb_flags & S_FLAG) {
3108 int l1;
3109
3110 l1 = gen_new_label();
3111 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3112
3113 cris_evaluate_flags (dc);
3114 t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3115 tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3116 tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3117 t_gen_raise_exception(EXCP_BREAK);
3118 gen_set_label(l1);
3119 }
3120#endif
3121 return insn_len;
3122}
3123
3124static void check_breakpoint(CPUState *env, DisasContext *dc)
3125{
3126 CPUBreakpoint *bp;
3127
3128 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3129 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3130 if (bp->pc == dc->pc) {
3131 cris_evaluate_flags (dc);
3132 tcg_gen_movi_tl(env_pc, dc->pc);
3133 t_gen_raise_exception(EXCP_DEBUG);
3134 dc->is_jmp = DISAS_UPDATE;
3135 }
3136 }
3137 }
3138}
3139
3140#include "translate_v10.c"
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177static void
3178gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3179 int search_pc)
3180{
3181 uint16_t *gen_opc_end;
3182 uint32_t pc_start;
3183 unsigned int insn_len;
3184 int j, lj;
3185 struct DisasContext ctx;
3186 struct DisasContext *dc = &ctx;
3187 uint32_t next_page_start;
3188 target_ulong npc;
3189 int num_insns;
3190 int max_insns;
3191
3192 qemu_log_try_set_file(stderr);
3193
3194 if (env->pregs[PR_VR] == 32) {
3195 dc->decoder = crisv32_decoder;
3196 dc->clear_locked_irq = 0;
3197 } else {
3198 dc->decoder = crisv10_decoder;
3199 dc->clear_locked_irq = 1;
3200 }
3201
3202
3203
3204
3205 pc_start = tb->pc & ~1;
3206 dc->env = env;
3207 dc->tb = tb;
3208
3209 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3210
3211 dc->is_jmp = DISAS_NEXT;
3212 dc->ppc = pc_start;
3213 dc->pc = pc_start;
3214 dc->singlestep_enabled = env->singlestep_enabled;
3215 dc->flags_uptodate = 1;
3216 dc->flagx_known = 1;
3217 dc->flags_x = tb->flags & X_FLAG;
3218 dc->cc_x_uptodate = 0;
3219 dc->cc_mask = 0;
3220 dc->update_cc = 0;
3221 dc->clear_prefix = 0;
3222
3223 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3224 dc->cc_size_uptodate = -1;
3225
3226
3227 dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3228 | X_FLAG | PFIX_FLAG);
3229 dc->delayed_branch = !!(tb->flags & 7);
3230 if (dc->delayed_branch)
3231 dc->jmp = JMP_INDIRECT;
3232 else
3233 dc->jmp = JMP_NOJMP;
3234
3235 dc->cpustate_changed = 0;
3236
3237 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3238 qemu_log(
3239 "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3240 "pid=%x usp=%x\n"
3241 "%x.%x.%x.%x\n"
3242 "%x.%x.%x.%x\n"
3243 "%x.%x.%x.%x\n"
3244 "%x.%x.%x.%x\n",
3245 search_pc, dc->pc, dc->ppc,
3246 (uint64_t)tb->flags,
3247 env->btarget, (unsigned)tb->flags & 7,
3248 env->pregs[PR_CCS],
3249 env->pregs[PR_PID], env->pregs[PR_USP],
3250 env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3251 env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3252 env->regs[8], env->regs[9],
3253 env->regs[10], env->regs[11],
3254 env->regs[12], env->regs[13],
3255 env->regs[14], env->regs[15]);
3256 qemu_log("--------------\n");
3257 qemu_log("IN: %s\n", lookup_symbol(pc_start));
3258 }
3259
3260 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3261 lj = -1;
3262 num_insns = 0;
3263 max_insns = tb->cflags & CF_COUNT_MASK;
3264 if (max_insns == 0)
3265 max_insns = CF_COUNT_MASK;
3266
3267 gen_icount_start();
3268 do
3269 {
3270 check_breakpoint(env, dc);
3271
3272 if (search_pc) {
3273 j = gen_opc_ptr - gen_opc_buf;
3274 if (lj < j) {
3275 lj++;
3276 while (lj < j)
3277 gen_opc_instr_start[lj++] = 0;
3278 }
3279 if (dc->delayed_branch == 1)
3280 gen_opc_pc[lj] = dc->ppc | 1;
3281 else
3282 gen_opc_pc[lj] = dc->pc;
3283 gen_opc_instr_start[lj] = 1;
3284 gen_opc_icount[lj] = num_insns;
3285 }
3286
3287
3288 LOG_DIS("%8.8x:\t", dc->pc);
3289
3290 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3291 gen_io_start();
3292 dc->clear_x = 1;
3293
3294 insn_len = dc->decoder(dc);
3295 dc->ppc = dc->pc;
3296 dc->pc += insn_len;
3297 if (dc->clear_x)
3298 cris_clear_x_flag(dc);
3299
3300 num_insns++;
3301
3302
3303
3304 if (dc->delayed_branch) {
3305 dc->delayed_branch--;
3306 if (dc->delayed_branch == 0)
3307 {
3308 if (tb->flags & 7)
3309 t_gen_mov_env_TN(dslot,
3310 tcg_const_tl(0));
3311 if (dc->cpustate_changed || !dc->flagx_known
3312 || (dc->flags_x != (tb->flags & X_FLAG))) {
3313 cris_store_direct_jmp(dc);
3314 }
3315
3316 if (dc->clear_locked_irq) {
3317 dc->clear_locked_irq = 0;
3318 t_gen_mov_env_TN(locked_irq,
3319 tcg_const_tl(0));
3320 }
3321
3322 if (dc->jmp == JMP_DIRECT_CC) {
3323 int l1;
3324
3325 l1 = gen_new_label();
3326 cris_evaluate_flags(dc);
3327
3328
3329 tcg_gen_brcondi_tl(TCG_COND_EQ,
3330 env_btaken, 0, l1);
3331 gen_goto_tb(dc, 1, dc->jmp_pc);
3332 gen_set_label(l1);
3333 gen_goto_tb(dc, 0, dc->pc);
3334 dc->is_jmp = DISAS_TB_JUMP;
3335 dc->jmp = JMP_NOJMP;
3336 } else if (dc->jmp == JMP_DIRECT) {
3337 cris_evaluate_flags(dc);
3338 gen_goto_tb(dc, 0, dc->jmp_pc);
3339 dc->is_jmp = DISAS_TB_JUMP;
3340 dc->jmp = JMP_NOJMP;
3341 } else {
3342 t_gen_cc_jmp(env_btarget,
3343 tcg_const_tl(dc->pc));
3344 dc->is_jmp = DISAS_JUMP;
3345 }
3346 break;
3347 }
3348 }
3349
3350
3351
3352 if (!(tb->pc & 1) && env->singlestep_enabled)
3353 break;
3354 } while (!dc->is_jmp && !dc->cpustate_changed
3355 && gen_opc_ptr < gen_opc_end
3356 && !singlestep
3357 && (dc->pc < next_page_start)
3358 && num_insns < max_insns);
3359
3360 if (dc->clear_locked_irq)
3361 t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3362
3363 npc = dc->pc;
3364
3365 if (tb->cflags & CF_LAST_IO)
3366 gen_io_end();
3367
3368 if (dc->is_jmp == DISAS_NEXT
3369 && (dc->cpustate_changed || !dc->flagx_known
3370 || (dc->flags_x != (tb->flags & X_FLAG)))) {
3371 dc->is_jmp = DISAS_UPDATE;
3372 tcg_gen_movi_tl(env_pc, npc);
3373 }
3374
3375 if (dc->delayed_branch == 1) {
3376
3377 t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3378 cris_store_direct_jmp(dc);
3379 }
3380
3381 cris_evaluate_flags (dc);
3382
3383 if (unlikely(env->singlestep_enabled)) {
3384 if (dc->is_jmp == DISAS_NEXT)
3385 tcg_gen_movi_tl(env_pc, npc);
3386 t_gen_raise_exception(EXCP_DEBUG);
3387 } else {
3388 switch(dc->is_jmp) {
3389 case DISAS_NEXT:
3390 gen_goto_tb(dc, 1, npc);
3391 break;
3392 default:
3393 case DISAS_JUMP:
3394 case DISAS_UPDATE:
3395
3396
3397 tcg_gen_exit_tb(0);
3398 break;
3399 case DISAS_SWI:
3400 case DISAS_TB_JUMP:
3401
3402 break;
3403 }
3404 }
3405 gen_icount_end(tb, num_insns);
3406 *gen_opc_ptr = INDEX_op_end;
3407 if (search_pc) {
3408 j = gen_opc_ptr - gen_opc_buf;
3409 lj++;
3410 while (lj <= j)
3411 gen_opc_instr_start[lj++] = 0;
3412 } else {
3413 tb->size = dc->pc - pc_start;
3414 tb->icount = num_insns;
3415 }
3416
3417#ifdef DEBUG_DISAS
3418#if !DISAS_CRIS
3419 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3420 log_target_disas(pc_start, dc->pc - pc_start,
3421 dc->env->pregs[PR_VR]);
3422 qemu_log("\nisize=%d osize=%td\n",
3423 dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3424 }
3425#endif
3426#endif
3427}
3428
3429void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3430{
3431 gen_intermediate_code_internal(env, tb, 0);
3432}
3433
3434void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3435{
3436 gen_intermediate_code_internal(env, tb, 1);
3437}
3438
3439void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
3440 int flags)
3441{
3442 int i;
3443 uint32_t srs;
3444
3445 if (!env || !f)
3446 return;
3447
3448 cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3449 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3450 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3451 env->cc_op,
3452 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3453
3454
3455 for (i = 0; i < 16; i++) {
3456 cpu_fprintf(f, "%s=%8.8x ",regnames[i], env->regs[i]);
3457 if ((i + 1) % 4 == 0)
3458 cpu_fprintf(f, "\n");
3459 }
3460 cpu_fprintf(f, "\nspecial regs:\n");
3461 for (i = 0; i < 16; i++) {
3462 cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3463 if ((i + 1) % 4 == 0)
3464 cpu_fprintf(f, "\n");
3465 }
3466 srs = env->pregs[PR_SRS];
3467 cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3468 if (srs < 256) {
3469 for (i = 0; i < 16; i++) {
3470 cpu_fprintf(f, "s%2.2d=%8.8x ",
3471 i, env->sregs[srs][i]);
3472 if ((i + 1) % 4 == 0)
3473 cpu_fprintf(f, "\n");
3474 }
3475 }
3476 cpu_fprintf(f, "\n\n");
3477
3478}
3479
3480struct
3481{
3482 uint32_t vr;
3483 const char *name;
3484} cris_cores[] = {
3485 {8, "crisv8"},
3486 {9, "crisv9"},
3487 {10, "crisv10"},
3488 {11, "crisv11"},
3489 {32, "crisv32"},
3490};
3491
3492void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
3493{
3494 unsigned int i;
3495
3496 (*cpu_fprintf)(f, "Available CPUs:\n");
3497 for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3498 (*cpu_fprintf)(f, " %s\n", cris_cores[i].name);
3499 }
3500}
3501
3502static uint32_t vr_by_name(const char *name)
3503{
3504 unsigned int i;
3505 for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3506 if (strcmp(name, cris_cores[i].name) == 0) {
3507 return cris_cores[i].vr;
3508 }
3509 }
3510 return 32;
3511}
3512
3513CPUCRISState *cpu_cris_init (const char *cpu_model)
3514{
3515 CPUCRISState *env;
3516 static int tcg_initialized = 0;
3517 int i;
3518
3519 env = qemu_mallocz(sizeof(CPUCRISState));
3520
3521 env->pregs[PR_VR] = vr_by_name(cpu_model);
3522 cpu_exec_init(env);
3523 cpu_reset(env);
3524 qemu_init_vcpu(env);
3525
3526 if (tcg_initialized)
3527 return env;
3528
3529 tcg_initialized = 1;
3530
3531#define GEN_HELPER 2
3532#include "helper.h"
3533
3534 if (env->pregs[PR_VR] < 32) {
3535 cpu_crisv10_init(env);
3536 return env;
3537 }
3538
3539
3540 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3541 cc_x = tcg_global_mem_new(TCG_AREG0,
3542 offsetof(CPUState, cc_x), "cc_x");
3543 cc_src = tcg_global_mem_new(TCG_AREG0,
3544 offsetof(CPUState, cc_src), "cc_src");
3545 cc_dest = tcg_global_mem_new(TCG_AREG0,
3546 offsetof(CPUState, cc_dest),
3547 "cc_dest");
3548 cc_result = tcg_global_mem_new(TCG_AREG0,
3549 offsetof(CPUState, cc_result),
3550 "cc_result");
3551 cc_op = tcg_global_mem_new(TCG_AREG0,
3552 offsetof(CPUState, cc_op), "cc_op");
3553 cc_size = tcg_global_mem_new(TCG_AREG0,
3554 offsetof(CPUState, cc_size),
3555 "cc_size");
3556 cc_mask = tcg_global_mem_new(TCG_AREG0,
3557 offsetof(CPUState, cc_mask),
3558 "cc_mask");
3559
3560 env_pc = tcg_global_mem_new(TCG_AREG0,
3561 offsetof(CPUState, pc),
3562 "pc");
3563 env_btarget = tcg_global_mem_new(TCG_AREG0,
3564 offsetof(CPUState, btarget),
3565 "btarget");
3566 env_btaken = tcg_global_mem_new(TCG_AREG0,
3567 offsetof(CPUState, btaken),
3568 "btaken");
3569 for (i = 0; i < 16; i++) {
3570 cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3571 offsetof(CPUState, regs[i]),
3572 regnames[i]);
3573 }
3574 for (i = 0; i < 16; i++) {
3575 cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3576 offsetof(CPUState, pregs[i]),
3577 pregnames[i]);
3578 }
3579
3580 return env;
3581}
3582
3583void cpu_reset (CPUCRISState *env)
3584{
3585 uint32_t vr;
3586
3587 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3588 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3589 log_cpu_state(env, 0);
3590 }
3591
3592 vr = env->pregs[PR_VR];
3593 memset(env, 0, offsetof(CPUCRISState, breakpoints));
3594 env->pregs[PR_VR] = vr;
3595 tlb_flush(env, 1);
3596
3597#if defined(CONFIG_USER_ONLY)
3598
3599 env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
3600#else
3601 cris_mmu_init(env);
3602 env->pregs[PR_CCS] = 0;
3603#endif
3604}
3605
3606void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
3607{
3608 env->pc = gen_opc_pc[pc_pos];
3609}
3610