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