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