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