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