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