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#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'; break;
1182 case 2: return 'w'; break;
1183 case 4: return 'd'; break;
1184 default:
1185 return 'x';
1186 break;
1187 }
1188}
1189#endif
1190
1191static inline unsigned int memsize_z(DisasContext *dc)
1192{
1193 return dc->zsize + 1;
1194}
1195
1196static inline unsigned int memsize_zz(DisasContext *dc)
1197{
1198 switch (dc->zzsize) {
1199 case 0: return 1;
1200 case 1: return 2;
1201 default:
1202 return 4;
1203 }
1204}
1205
1206static inline void do_postinc (DisasContext *dc, int size)
1207{
1208 if (dc->postinc) {
1209 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1210 }
1211}
1212
1213static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1214 int size, int s_ext, TCGv dst)
1215{
1216 if (s_ext) {
1217 t_gen_sext(dst, cpu_R[rs], size);
1218 } else {
1219 t_gen_zext(dst, cpu_R[rs], size);
1220 }
1221}
1222
1223
1224
1225
1226static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1227 int size, int s_ext, TCGv dst, TCGv src)
1228{
1229 dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1230
1231 if (s_ext) {
1232 t_gen_sext(dst, cpu_R[rd], size);
1233 } else {
1234 t_gen_zext(dst, cpu_R[rd], size);
1235 }
1236}
1237
1238static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1239 int s_ext, int memsize, TCGv dst)
1240{
1241 unsigned int rs;
1242 uint32_t imm;
1243 int is_imm;
1244 int insn_len = 2;
1245
1246 rs = dc->op1;
1247 is_imm = rs == 15 && dc->postinc;
1248
1249
1250 if (is_imm) {
1251 insn_len = 2 + memsize;
1252 if (memsize == 1) {
1253 insn_len++;
1254 }
1255
1256 imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1257 tcg_gen_movi_tl(dst, imm);
1258 dc->postinc = 0;
1259 } else {
1260 cris_flush_cc_state(dc);
1261 gen_load(dc, dst, cpu_R[rs], memsize, 0);
1262 if (s_ext) {
1263 t_gen_sext(dst, dst, memsize);
1264 } else {
1265 t_gen_zext(dst, dst, memsize);
1266 }
1267 }
1268 return insn_len;
1269}
1270
1271
1272
1273
1274static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1275 int s_ext, int memsize, TCGv dst, TCGv src)
1276{
1277 int insn_len;
1278
1279 insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1280 tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1281 return insn_len;
1282}
1283
1284#if DISAS_CRIS
1285static const char *cc_name(int cc)
1286{
1287 static const char *cc_names[16] = {
1288 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1289 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1290 };
1291 assert(cc < 16);
1292 return cc_names[cc];
1293}
1294#endif
1295
1296
1297
1298static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1299{
1300 int32_t offset;
1301 int sign;
1302 uint32_t cond = dc->op2;
1303
1304 offset = EXTRACT_FIELD(dc->ir, 1, 7);
1305 sign = EXTRACT_FIELD(dc->ir, 0, 0);
1306
1307 offset *= 2;
1308 offset |= sign << 8;
1309 offset = sign_extend(offset, 8);
1310
1311 LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1312
1313
1314 cris_cc_mask(dc, 0);
1315 cris_prepare_cc_branch(dc, offset, cond);
1316 return 2;
1317}
1318static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1319{
1320 int32_t imm;
1321
1322 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1323 imm = sign_extend(dc->op1, 7);
1324
1325 LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1326 cris_cc_mask(dc, 0);
1327
1328 tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1329
1330 return 2;
1331}
1332static int dec_addq(CPUCRISState *env, DisasContext *dc)
1333{
1334 LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1335
1336 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1337
1338 cris_cc_mask(dc, CC_MASK_NZVC);
1339
1340 cris_alu(dc, CC_OP_ADD,
1341 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1342 return 2;
1343}
1344static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1345{
1346 uint32_t imm;
1347
1348 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1349 imm = sign_extend(dc->op1, 5);
1350 LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1351
1352 tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1353 return 2;
1354}
1355static int dec_subq(CPUCRISState *env, DisasContext *dc)
1356{
1357 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1358
1359 LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1360
1361 cris_cc_mask(dc, CC_MASK_NZVC);
1362 cris_alu(dc, CC_OP_SUB,
1363 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1364 return 2;
1365}
1366static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1367{
1368 uint32_t imm;
1369 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1370 imm = sign_extend(dc->op1, 5);
1371
1372 LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1373 cris_cc_mask(dc, CC_MASK_NZVC);
1374
1375 cris_alu(dc, CC_OP_CMP,
1376 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1377 return 2;
1378}
1379static int dec_andq(CPUCRISState *env, DisasContext *dc)
1380{
1381 uint32_t imm;
1382 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1383 imm = sign_extend(dc->op1, 5);
1384
1385 LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1386 cris_cc_mask(dc, CC_MASK_NZ);
1387
1388 cris_alu(dc, CC_OP_AND,
1389 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1390 return 2;
1391}
1392static int dec_orq(CPUCRISState *env, DisasContext *dc)
1393{
1394 uint32_t imm;
1395 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1396 imm = sign_extend(dc->op1, 5);
1397 LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1398 cris_cc_mask(dc, CC_MASK_NZ);
1399
1400 cris_alu(dc, CC_OP_OR,
1401 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1402 return 2;
1403}
1404static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1405{
1406 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1407 LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1408
1409 cris_cc_mask(dc, CC_MASK_NZ);
1410 cris_evaluate_flags(dc);
1411 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1412 tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1413 cris_alu(dc, CC_OP_MOVE,
1414 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1415 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1416 dc->flags_uptodate = 1;
1417 return 2;
1418}
1419static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1420{
1421 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1422 LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1423 cris_cc_mask(dc, CC_MASK_NZ);
1424
1425 tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1426 cris_alu(dc, CC_OP_MOVE,
1427 cpu_R[dc->op2],
1428 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1429 return 2;
1430}
1431static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1432{
1433 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1434 LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1435
1436 cris_cc_mask(dc, CC_MASK_NZ);
1437
1438 tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1439
1440 cris_alu(dc, CC_OP_MOVE,
1441 cpu_R[dc->op2],
1442 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1443 return 2;
1444}
1445static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1446{
1447 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1448 LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1449
1450 cris_cc_mask(dc, CC_MASK_NZ);
1451
1452 tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1453 cris_alu(dc, CC_OP_MOVE,
1454 cpu_R[dc->op2],
1455 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1456 return 2;
1457}
1458
1459static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1460{
1461 int size = memsize_zz(dc);
1462
1463 LOG_DIS("move.%c $r%u, $r%u\n",
1464 memsize_char(size), dc->op1, dc->op2);
1465
1466 cris_cc_mask(dc, CC_MASK_NZ);
1467 if (size == 4) {
1468 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1469 cris_cc_mask(dc, CC_MASK_NZ);
1470 cris_update_cc_op(dc, CC_OP_MOVE, 4);
1471 cris_update_cc_x(dc);
1472 cris_update_result(dc, cpu_R[dc->op2]);
1473 } else {
1474 TCGv t0;
1475
1476 t0 = tcg_temp_new();
1477 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1478 cris_alu(dc, CC_OP_MOVE,
1479 cpu_R[dc->op2],
1480 cpu_R[dc->op2], t0, size);
1481 tcg_temp_free(t0);
1482 }
1483 return 2;
1484}
1485
1486static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1487{
1488 int cond = dc->op2;
1489
1490 LOG_DIS("s%s $r%u\n",
1491 cc_name(cond), dc->op1);
1492
1493 gen_tst_cc(dc, cpu_R[dc->op1], cond);
1494 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0);
1495
1496 cris_cc_mask(dc, 0);
1497 return 2;
1498}
1499
1500static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1501{
1502 if (size == 4) {
1503 t[0] = cpu_R[dc->op2];
1504 t[1] = cpu_R[dc->op1];
1505 } else {
1506 t[0] = tcg_temp_new();
1507 t[1] = tcg_temp_new();
1508 }
1509}
1510
1511static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1512{
1513 if (size != 4) {
1514 tcg_temp_free(t[0]);
1515 tcg_temp_free(t[1]);
1516 }
1517}
1518
1519static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1520{
1521 TCGv t[2];
1522 int size = memsize_zz(dc);
1523
1524 LOG_DIS("and.%c $r%u, $r%u\n",
1525 memsize_char(size), dc->op1, dc->op2);
1526
1527 cris_cc_mask(dc, CC_MASK_NZ);
1528
1529 cris_alu_alloc_temps(dc, size, t);
1530 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1531 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1532 cris_alu_free_temps(dc, size, t);
1533 return 2;
1534}
1535
1536static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1537{
1538 TCGv t0;
1539 LOG_DIS("lz $r%u, $r%u\n",
1540 dc->op1, dc->op2);
1541 cris_cc_mask(dc, CC_MASK_NZ);
1542 t0 = tcg_temp_new();
1543 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1544 cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1545 tcg_temp_free(t0);
1546 return 2;
1547}
1548
1549static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1550{
1551 TCGv t[2];
1552 int size = memsize_zz(dc);
1553
1554 LOG_DIS("lsl.%c $r%u, $r%u\n",
1555 memsize_char(size), dc->op1, dc->op2);
1556
1557 cris_cc_mask(dc, CC_MASK_NZ);
1558 cris_alu_alloc_temps(dc, size, t);
1559 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1560 tcg_gen_andi_tl(t[1], t[1], 63);
1561 cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1562 cris_alu_alloc_temps(dc, size, t);
1563 return 2;
1564}
1565
1566static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1567{
1568 TCGv t[2];
1569 int size = memsize_zz(dc);
1570
1571 LOG_DIS("lsr.%c $r%u, $r%u\n",
1572 memsize_char(size), dc->op1, dc->op2);
1573
1574 cris_cc_mask(dc, CC_MASK_NZ);
1575 cris_alu_alloc_temps(dc, size, t);
1576 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1577 tcg_gen_andi_tl(t[1], t[1], 63);
1578 cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1579 cris_alu_free_temps(dc, size, t);
1580 return 2;
1581}
1582
1583static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1584{
1585 TCGv t[2];
1586 int size = memsize_zz(dc);
1587
1588 LOG_DIS("asr.%c $r%u, $r%u\n",
1589 memsize_char(size), dc->op1, dc->op2);
1590
1591 cris_cc_mask(dc, CC_MASK_NZ);
1592 cris_alu_alloc_temps(dc, size, t);
1593 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1594 tcg_gen_andi_tl(t[1], t[1], 63);
1595 cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1596 cris_alu_free_temps(dc, size, t);
1597 return 2;
1598}
1599
1600static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1601{
1602 TCGv t[2];
1603 int size = memsize_zz(dc);
1604
1605 LOG_DIS("muls.%c $r%u, $r%u\n",
1606 memsize_char(size), dc->op1, dc->op2);
1607 cris_cc_mask(dc, CC_MASK_NZV);
1608 cris_alu_alloc_temps(dc, size, t);
1609 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1610
1611 cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1612 cris_alu_free_temps(dc, size, t);
1613 return 2;
1614}
1615
1616static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1617{
1618 TCGv t[2];
1619 int size = memsize_zz(dc);
1620
1621 LOG_DIS("mulu.%c $r%u, $r%u\n",
1622 memsize_char(size), dc->op1, dc->op2);
1623 cris_cc_mask(dc, CC_MASK_NZV);
1624 cris_alu_alloc_temps(dc, size, t);
1625 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1626
1627 cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1628 cris_alu_alloc_temps(dc, size, t);
1629 return 2;
1630}
1631
1632
1633static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1634{
1635 LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1636 cris_cc_mask(dc, CC_MASK_NZ);
1637 cris_alu(dc, CC_OP_DSTEP,
1638 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1639 return 2;
1640}
1641
1642static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1643{
1644 TCGv t[2];
1645 int size = memsize_zz(dc);
1646 LOG_DIS("xor.%c $r%u, $r%u\n",
1647 memsize_char(size), dc->op1, dc->op2);
1648 BUG_ON(size != 4);
1649 cris_cc_mask(dc, CC_MASK_NZ);
1650 cris_alu_alloc_temps(dc, size, t);
1651 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1652
1653 cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1654 cris_alu_free_temps(dc, size, t);
1655 return 2;
1656}
1657
1658static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1659{
1660 TCGv l0;
1661 int size = memsize_zz(dc);
1662 LOG_DIS("bound.%c $r%u, $r%u\n",
1663 memsize_char(size), dc->op1, dc->op2);
1664 cris_cc_mask(dc, CC_MASK_NZ);
1665 l0 = tcg_temp_local_new();
1666 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1667 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1668 tcg_temp_free(l0);
1669 return 2;
1670}
1671
1672static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1673{
1674 TCGv t[2];
1675 int size = memsize_zz(dc);
1676 LOG_DIS("cmp.%c $r%u, $r%u\n",
1677 memsize_char(size), dc->op1, dc->op2);
1678 cris_cc_mask(dc, CC_MASK_NZVC);
1679 cris_alu_alloc_temps(dc, size, t);
1680 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1681
1682 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1683 cris_alu_free_temps(dc, size, t);
1684 return 2;
1685}
1686
1687static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1688{
1689 LOG_DIS("abs $r%u, $r%u\n",
1690 dc->op1, dc->op2);
1691 cris_cc_mask(dc, CC_MASK_NZ);
1692
1693 tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
1694 cris_alu(dc, CC_OP_MOVE,
1695 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1696 return 2;
1697}
1698
1699static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1700{
1701 TCGv t[2];
1702 int size = memsize_zz(dc);
1703 LOG_DIS("add.%c $r%u, $r%u\n",
1704 memsize_char(size), dc->op1, dc->op2);
1705 cris_cc_mask(dc, CC_MASK_NZVC);
1706 cris_alu_alloc_temps(dc, size, t);
1707 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1708
1709 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1710 cris_alu_free_temps(dc, size, t);
1711 return 2;
1712}
1713
1714static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1715{
1716 LOG_DIS("addc $r%u, $r%u\n",
1717 dc->op1, dc->op2);
1718 cris_evaluate_flags(dc);
1719
1720 dc->flagx_known = 1;
1721 dc->flags_x = X_FLAG;
1722
1723 cris_cc_mask(dc, CC_MASK_NZVC);
1724 cris_alu(dc, CC_OP_ADDC,
1725 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1726 return 2;
1727}
1728
1729static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1730{
1731 LOG_DIS("mcp $p%u, $r%u\n",
1732 dc->op2, dc->op1);
1733 cris_evaluate_flags(dc);
1734 cris_cc_mask(dc, CC_MASK_RNZV);
1735 cris_alu(dc, CC_OP_MCP,
1736 cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1737 return 2;
1738}
1739
1740#if DISAS_CRIS
1741static char * swapmode_name(int mode, char *modename) {
1742 int i = 0;
1743 if (mode & 8) {
1744 modename[i++] = 'n';
1745 }
1746 if (mode & 4) {
1747 modename[i++] = 'w';
1748 }
1749 if (mode & 2) {
1750 modename[i++] = 'b';
1751 }
1752 if (mode & 1) {
1753 modename[i++] = 'r';
1754 }
1755 modename[i++] = 0;
1756 return modename;
1757}
1758#endif
1759
1760static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1761{
1762 TCGv t0;
1763#if DISAS_CRIS
1764 char modename[4];
1765#endif
1766 LOG_DIS("swap%s $r%u\n",
1767 swapmode_name(dc->op2, modename), dc->op1);
1768
1769 cris_cc_mask(dc, CC_MASK_NZ);
1770 t0 = tcg_temp_new();
1771 tcg_gen_mov_tl(t0, cpu_R[dc->op1]);
1772 if (dc->op2 & 8) {
1773 tcg_gen_not_tl(t0, t0);
1774 }
1775 if (dc->op2 & 4) {
1776 t_gen_swapw(t0, t0);
1777 }
1778 if (dc->op2 & 2) {
1779 t_gen_swapb(t0, t0);
1780 }
1781 if (dc->op2 & 1) {
1782 t_gen_swapr(t0, t0);
1783 }
1784 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1785 tcg_temp_free(t0);
1786 return 2;
1787}
1788
1789static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1790{
1791 TCGv t[2];
1792 int size = memsize_zz(dc);
1793 LOG_DIS("or.%c $r%u, $r%u\n",
1794 memsize_char(size), dc->op1, dc->op2);
1795 cris_cc_mask(dc, CC_MASK_NZ);
1796 cris_alu_alloc_temps(dc, size, t);
1797 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1798 cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1799 cris_alu_free_temps(dc, size, t);
1800 return 2;
1801}
1802
1803static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1804{
1805 TCGv t0;
1806 LOG_DIS("addi.%c $r%u, $r%u\n",
1807 memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1808 cris_cc_mask(dc, 0);
1809 t0 = tcg_temp_new();
1810 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1811 tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1812 tcg_temp_free(t0);
1813 return 2;
1814}
1815
1816static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1817{
1818 TCGv t0;
1819 LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1820 memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1821 cris_cc_mask(dc, 0);
1822 t0 = tcg_temp_new();
1823 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1824 tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1825 tcg_temp_free(t0);
1826 return 2;
1827}
1828
1829static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1830{
1831 TCGv t[2];
1832 int size = memsize_zz(dc);
1833 LOG_DIS("neg.%c $r%u, $r%u\n",
1834 memsize_char(size), dc->op1, dc->op2);
1835 cris_cc_mask(dc, CC_MASK_NZVC);
1836 cris_alu_alloc_temps(dc, size, t);
1837 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1838
1839 cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1840 cris_alu_free_temps(dc, size, t);
1841 return 2;
1842}
1843
1844static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1845{
1846 LOG_DIS("btst $r%u, $r%u\n",
1847 dc->op1, dc->op2);
1848 cris_cc_mask(dc, CC_MASK_NZ);
1849 cris_evaluate_flags(dc);
1850 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1851 cpu_R[dc->op1], cpu_PR[PR_CCS]);
1852 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1853 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1854 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1855 dc->flags_uptodate = 1;
1856 return 2;
1857}
1858
1859static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1860{
1861 TCGv t[2];
1862 int size = memsize_zz(dc);
1863 LOG_DIS("sub.%c $r%u, $r%u\n",
1864 memsize_char(size), dc->op1, dc->op2);
1865 cris_cc_mask(dc, CC_MASK_NZVC);
1866 cris_alu_alloc_temps(dc, size, t);
1867 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1868 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1869 cris_alu_free_temps(dc, size, t);
1870 return 2;
1871}
1872
1873
1874static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1875{
1876 TCGv t0;
1877 int size = memsize_z(dc);
1878 LOG_DIS("movu.%c $r%u, $r%u\n",
1879 memsize_char(size),
1880 dc->op1, dc->op2);
1881
1882 cris_cc_mask(dc, CC_MASK_NZ);
1883 t0 = tcg_temp_new();
1884 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1885 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1886 tcg_temp_free(t0);
1887 return 2;
1888}
1889
1890
1891static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1892{
1893 TCGv t0;
1894 int size = memsize_z(dc);
1895 LOG_DIS("movs.%c $r%u, $r%u\n",
1896 memsize_char(size),
1897 dc->op1, dc->op2);
1898
1899 cris_cc_mask(dc, CC_MASK_NZ);
1900 t0 = tcg_temp_new();
1901
1902 t_gen_sext(t0, cpu_R[dc->op1], size);
1903 cris_alu(dc, CC_OP_MOVE,
1904 cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1905 tcg_temp_free(t0);
1906 return 2;
1907}
1908
1909
1910static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
1911{
1912 TCGv t0;
1913 int size = memsize_z(dc);
1914 LOG_DIS("addu.%c $r%u, $r%u\n",
1915 memsize_char(size),
1916 dc->op1, dc->op2);
1917
1918 cris_cc_mask(dc, CC_MASK_NZVC);
1919 t0 = tcg_temp_new();
1920
1921 t_gen_zext(t0, cpu_R[dc->op1], size);
1922 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1923 tcg_temp_free(t0);
1924 return 2;
1925}
1926
1927
1928static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1929{
1930 TCGv t0;
1931 int size = memsize_z(dc);
1932 LOG_DIS("adds.%c $r%u, $r%u\n",
1933 memsize_char(size),
1934 dc->op1, dc->op2);
1935
1936 cris_cc_mask(dc, CC_MASK_NZVC);
1937 t0 = tcg_temp_new();
1938
1939 t_gen_sext(t0, cpu_R[dc->op1], size);
1940 cris_alu(dc, CC_OP_ADD,
1941 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1942 tcg_temp_free(t0);
1943 return 2;
1944}
1945
1946
1947static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
1948{
1949 TCGv t0;
1950 int size = memsize_z(dc);
1951 LOG_DIS("subu.%c $r%u, $r%u\n",
1952 memsize_char(size),
1953 dc->op1, dc->op2);
1954
1955 cris_cc_mask(dc, CC_MASK_NZVC);
1956 t0 = tcg_temp_new();
1957
1958 t_gen_zext(t0, cpu_R[dc->op1], size);
1959 cris_alu(dc, CC_OP_SUB,
1960 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1961 tcg_temp_free(t0);
1962 return 2;
1963}
1964
1965
1966static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
1967{
1968 TCGv t0;
1969 int size = memsize_z(dc);
1970 LOG_DIS("subs.%c $r%u, $r%u\n",
1971 memsize_char(size),
1972 dc->op1, dc->op2);
1973
1974 cris_cc_mask(dc, CC_MASK_NZVC);
1975 t0 = tcg_temp_new();
1976
1977 t_gen_sext(t0, cpu_R[dc->op1], size);
1978 cris_alu(dc, CC_OP_SUB,
1979 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1980 tcg_temp_free(t0);
1981 return 2;
1982}
1983
1984static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
1985{
1986 uint32_t flags;
1987 int set = (~dc->opcode >> 2) & 1;
1988
1989
1990 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1991 | EXTRACT_FIELD(dc->ir, 0, 3);
1992 if (set && flags == 0) {
1993 LOG_DIS("nop\n");
1994 return 2;
1995 } else if (!set && (flags & 0x20)) {
1996 LOG_DIS("di\n");
1997 } else {
1998 LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
1999 }
2000
2001
2002 if (dc->tb_flags & U_FLAG) {
2003 flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2004 }
2005
2006 if (flags & X_FLAG) {
2007 dc->flagx_known = 1;
2008 if (set) {
2009 dc->flags_x = X_FLAG;
2010 } else {
2011 dc->flags_x = 0;
2012 }
2013 }
2014
2015
2016 if (flags & (P_FLAG | S_FLAG)) {
2017 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2018 dc->is_jmp = DISAS_UPDATE;
2019 dc->cpustate_changed = 1;
2020 }
2021
2022
2023 if ((flags & I_FLAG)) {
2024 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2025 dc->is_jmp = DISAS_UPDATE;
2026 dc->cpustate_changed = 1;
2027 }
2028
2029
2030
2031 cris_evaluate_flags(dc);
2032 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2033 cris_update_cc_x(dc);
2034 tcg_gen_movi_tl(cc_op, dc->cc_op);
2035
2036 if (set) {
2037 if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2038
2039 t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2040 tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2041 dc->cpustate_changed = 1;
2042 }
2043 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2044 } else {
2045 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2046 }
2047
2048 dc->flags_uptodate = 1;
2049 dc->clear_x = 0;
2050 return 2;
2051}
2052
2053static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
2054{
2055 LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2056 cris_cc_mask(dc, 0);
2057 gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
2058 tcg_const_tl(dc->op1));
2059 return 2;
2060}
2061static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
2062{
2063 LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2064 cris_cc_mask(dc, 0);
2065 gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
2066 tcg_const_tl(dc->op2));
2067 return 2;
2068}
2069
2070static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
2071{
2072 TCGv t[2];
2073 LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2074 cris_cc_mask(dc, 0);
2075
2076 t[0] = tcg_temp_new();
2077 if (dc->op2 == PR_CCS) {
2078 cris_evaluate_flags(dc);
2079 tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
2080 if (dc->tb_flags & U_FLAG) {
2081 t[1] = tcg_temp_new();
2082
2083 tcg_gen_andi_tl(t[0], t[0], 0x39f);
2084 tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2085 tcg_gen_or_tl(t[0], t[1], t[0]);
2086 tcg_temp_free(t[1]);
2087 }
2088 } else {
2089 tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
2090 }
2091
2092 t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2093 if (dc->op2 == PR_CCS) {
2094 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2095 dc->flags_uptodate = 1;
2096 }
2097 tcg_temp_free(t[0]);
2098 return 2;
2099}
2100static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
2101{
2102 TCGv t0;
2103 LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2104 cris_cc_mask(dc, 0);
2105
2106 if (dc->op2 == PR_CCS) {
2107 cris_evaluate_flags(dc);
2108 }
2109
2110 if (dc->op2 == PR_DZ) {
2111 tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2112 } else {
2113 t0 = tcg_temp_new();
2114 t_gen_mov_TN_preg(t0, dc->op2);
2115 cris_alu(dc, CC_OP_MOVE,
2116 cpu_R[dc->op1], cpu_R[dc->op1], t0,
2117 preg_sizes[dc->op2]);
2118 tcg_temp_free(t0);
2119 }
2120 return 2;
2121}
2122
2123static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
2124{
2125 int memsize = memsize_zz(dc);
2126 int insn_len;
2127 LOG_DIS("move.%c [$r%u%s, $r%u\n",
2128 memsize_char(memsize),
2129 dc->op1, dc->postinc ? "+]" : "]",
2130 dc->op2);
2131
2132 if (memsize == 4) {
2133 insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2134 cris_cc_mask(dc, CC_MASK_NZ);
2135 cris_update_cc_op(dc, CC_OP_MOVE, 4);
2136 cris_update_cc_x(dc);
2137 cris_update_result(dc, cpu_R[dc->op2]);
2138 } else {
2139 TCGv t0;
2140
2141 t0 = tcg_temp_new();
2142 insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2143 cris_cc_mask(dc, CC_MASK_NZ);
2144 cris_alu(dc, CC_OP_MOVE,
2145 cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2146 tcg_temp_free(t0);
2147 }
2148 do_postinc(dc, memsize);
2149 return insn_len;
2150}
2151
2152static inline void cris_alu_m_alloc_temps(TCGv *t)
2153{
2154 t[0] = tcg_temp_new();
2155 t[1] = tcg_temp_new();
2156}
2157
2158static inline void cris_alu_m_free_temps(TCGv *t)
2159{
2160 tcg_temp_free(t[0]);
2161 tcg_temp_free(t[1]);
2162}
2163
2164static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
2165{
2166 TCGv t[2];
2167 int memsize = memsize_z(dc);
2168 int insn_len;
2169 LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2170 memsize_char(memsize),
2171 dc->op1, dc->postinc ? "+]" : "]",
2172 dc->op2);
2173
2174 cris_alu_m_alloc_temps(t);
2175
2176 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2177 cris_cc_mask(dc, CC_MASK_NZ);
2178 cris_alu(dc, CC_OP_MOVE,
2179 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2180 do_postinc(dc, memsize);
2181 cris_alu_m_free_temps(t);
2182 return insn_len;
2183}
2184
2185static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
2186{
2187 TCGv t[2];
2188 int memsize = memsize_z(dc);
2189 int insn_len;
2190 LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2191 memsize_char(memsize),
2192 dc->op1, dc->postinc ? "+]" : "]",
2193 dc->op2);
2194
2195 cris_alu_m_alloc_temps(t);
2196
2197 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2198 cris_cc_mask(dc, CC_MASK_NZVC);
2199 cris_alu(dc, CC_OP_ADD,
2200 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2201 do_postinc(dc, memsize);
2202 cris_alu_m_free_temps(t);
2203 return insn_len;
2204}
2205
2206static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
2207{
2208 TCGv t[2];
2209 int memsize = memsize_z(dc);
2210 int insn_len;
2211 LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2212 memsize_char(memsize),
2213 dc->op1, dc->postinc ? "+]" : "]",
2214 dc->op2);
2215
2216 cris_alu_m_alloc_temps(t);
2217
2218 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2219 cris_cc_mask(dc, CC_MASK_NZVC);
2220 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2221 do_postinc(dc, memsize);
2222 cris_alu_m_free_temps(t);
2223 return insn_len;
2224}
2225
2226static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
2227{
2228 TCGv t[2];
2229 int memsize = memsize_z(dc);
2230 int insn_len;
2231 LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2232 memsize_char(memsize),
2233 dc->op1, dc->postinc ? "+]" : "]",
2234 dc->op2);
2235
2236 cris_alu_m_alloc_temps(t);
2237
2238 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2239 cris_cc_mask(dc, CC_MASK_NZVC);
2240 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2241 do_postinc(dc, memsize);
2242 cris_alu_m_free_temps(t);
2243 return insn_len;
2244}
2245
2246static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
2247{
2248 TCGv t[2];
2249 int memsize = memsize_z(dc);
2250 int insn_len;
2251 LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2252 memsize_char(memsize),
2253 dc->op1, dc->postinc ? "+]" : "]",
2254 dc->op2);
2255
2256 cris_alu_m_alloc_temps(t);
2257
2258 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2259 cris_cc_mask(dc, CC_MASK_NZVC);
2260 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2261 do_postinc(dc, memsize);
2262 cris_alu_m_free_temps(t);
2263 return insn_len;
2264}
2265
2266static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2267{
2268 TCGv t[2];
2269 int memsize = memsize_z(dc);
2270 int insn_len;
2271
2272 LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2273 memsize_char(memsize),
2274 dc->op1, dc->postinc ? "+]" : "]",
2275 dc->op2);
2276
2277 cris_alu_m_alloc_temps(t);
2278 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2279 cris_cc_mask(dc, CC_MASK_NZ);
2280 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2281 do_postinc(dc, memsize);
2282 cris_alu_m_free_temps(t);
2283 return insn_len;
2284}
2285
2286static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2287{
2288 TCGv t[2];
2289 int memsize = memsize_z(dc);
2290 int insn_len;
2291 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2292 memsize_char(memsize),
2293 dc->op1, dc->postinc ? "+]" : "]",
2294 dc->op2);
2295
2296 cris_alu_m_alloc_temps(t);
2297 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2298 cris_cc_mask(dc, CC_MASK_NZVC);
2299 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2300 do_postinc(dc, memsize);
2301 cris_alu_m_free_temps(t);
2302 return insn_len;
2303}
2304
2305static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
2306{
2307 TCGv t[2];
2308 int memsize = memsize_z(dc);
2309 int insn_len;
2310 LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2311 memsize_char(memsize),
2312 dc->op1, dc->postinc ? "+]" : "]",
2313 dc->op2);
2314
2315 cris_alu_m_alloc_temps(t);
2316 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2317 cris_cc_mask(dc, CC_MASK_NZVC);
2318 cris_alu(dc, CC_OP_CMP,
2319 cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2320 memsize_zz(dc));
2321 do_postinc(dc, memsize);
2322 cris_alu_m_free_temps(t);
2323 return insn_len;
2324}
2325
2326static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
2327{
2328 TCGv t[2];
2329 int memsize = memsize_zz(dc);
2330 int insn_len;
2331 LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2332 memsize_char(memsize),
2333 dc->op1, dc->postinc ? "+]" : "]",
2334 dc->op2);
2335
2336 cris_alu_m_alloc_temps(t);
2337 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2338 cris_cc_mask(dc, CC_MASK_NZVC);
2339 cris_alu(dc, CC_OP_CMP,
2340 cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2341 memsize_zz(dc));
2342 do_postinc(dc, memsize);
2343 cris_alu_m_free_temps(t);
2344 return insn_len;
2345}
2346
2347static int dec_test_m(CPUCRISState *env, DisasContext *dc)
2348{
2349 TCGv t[2];
2350 int memsize = memsize_zz(dc);
2351 int insn_len;
2352 LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2353 memsize_char(memsize),
2354 dc->op1, dc->postinc ? "+]" : "]",
2355 dc->op2);
2356
2357 cris_evaluate_flags(dc);
2358
2359 cris_alu_m_alloc_temps(t);
2360 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2361 cris_cc_mask(dc, CC_MASK_NZ);
2362 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2363
2364 cris_alu(dc, CC_OP_CMP,
2365 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2366 do_postinc(dc, memsize);
2367 cris_alu_m_free_temps(t);
2368 return insn_len;
2369}
2370
2371static int dec_and_m(CPUCRISState *env, DisasContext *dc)
2372{
2373 TCGv t[2];
2374 int memsize = memsize_zz(dc);
2375 int insn_len;
2376 LOG_DIS("and.%c [$r%u%s, $r%u\n",
2377 memsize_char(memsize),
2378 dc->op1, dc->postinc ? "+]" : "]",
2379 dc->op2);
2380
2381 cris_alu_m_alloc_temps(t);
2382 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2383 cris_cc_mask(dc, CC_MASK_NZ);
2384 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2385 do_postinc(dc, memsize);
2386 cris_alu_m_free_temps(t);
2387 return insn_len;
2388}
2389
2390static int dec_add_m(CPUCRISState *env, DisasContext *dc)
2391{
2392 TCGv t[2];
2393 int memsize = memsize_zz(dc);
2394 int insn_len;
2395 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2396 memsize_char(memsize),
2397 dc->op1, dc->postinc ? "+]" : "]",
2398 dc->op2);
2399
2400 cris_alu_m_alloc_temps(t);
2401 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2402 cris_cc_mask(dc, CC_MASK_NZVC);
2403 cris_alu(dc, CC_OP_ADD,
2404 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2405 do_postinc(dc, memsize);
2406 cris_alu_m_free_temps(t);
2407 return insn_len;
2408}
2409
2410static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
2411{
2412 TCGv t[2];
2413 int memsize = memsize_zz(dc);
2414 int insn_len;
2415 LOG_DIS("add.%c [$r%u%s, $r%u\n",
2416 memsize_char(memsize),
2417 dc->op1, dc->postinc ? "+]" : "]",
2418 dc->op2);
2419
2420 cris_alu_m_alloc_temps(t);
2421 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2422 cris_cc_mask(dc, 0);
2423 cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2424 do_postinc(dc, memsize);
2425 cris_alu_m_free_temps(t);
2426 return insn_len;
2427}
2428
2429static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
2430{
2431 TCGv l[2];
2432 int memsize = memsize_zz(dc);
2433 int insn_len;
2434 LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2435 memsize_char(memsize),
2436 dc->op1, dc->postinc ? "+]" : "]",
2437 dc->op2);
2438
2439 l[0] = tcg_temp_local_new();
2440 l[1] = tcg_temp_local_new();
2441 insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2442 cris_cc_mask(dc, CC_MASK_NZ);
2443 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2444 do_postinc(dc, memsize);
2445 tcg_temp_free(l[0]);
2446 tcg_temp_free(l[1]);
2447 return insn_len;
2448}
2449
2450static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2451{
2452 TCGv t[2];
2453 int insn_len = 2;
2454 LOG_DIS("addc [$r%u%s, $r%u\n",
2455 dc->op1, dc->postinc ? "+]" : "]",
2456 dc->op2);
2457
2458 cris_evaluate_flags(dc);
2459
2460
2461 dc->flagx_known = 1;
2462 dc->flags_x = X_FLAG;
2463
2464 cris_alu_m_alloc_temps(t);
2465 insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2466 cris_cc_mask(dc, CC_MASK_NZVC);
2467 cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2468 do_postinc(dc, 4);
2469 cris_alu_m_free_temps(t);
2470 return insn_len;
2471}
2472
2473static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2474{
2475 TCGv t[2];
2476 int memsize = memsize_zz(dc);
2477 int insn_len;
2478 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2479 memsize_char(memsize),
2480 dc->op1, dc->postinc ? "+]" : "]",
2481 dc->op2, dc->ir, dc->zzsize);
2482
2483 cris_alu_m_alloc_temps(t);
2484 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2485 cris_cc_mask(dc, CC_MASK_NZVC);
2486 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2487 do_postinc(dc, memsize);
2488 cris_alu_m_free_temps(t);
2489 return insn_len;
2490}
2491
2492static int dec_or_m(CPUCRISState *env, DisasContext *dc)
2493{
2494 TCGv t[2];
2495 int memsize = memsize_zz(dc);
2496 int insn_len;
2497 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2498 memsize_char(memsize),
2499 dc->op1, dc->postinc ? "+]" : "]",
2500 dc->op2, dc->pc);
2501
2502 cris_alu_m_alloc_temps(t);
2503 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2504 cris_cc_mask(dc, CC_MASK_NZ);
2505 cris_alu(dc, CC_OP_OR,
2506 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2507 do_postinc(dc, memsize);
2508 cris_alu_m_free_temps(t);
2509 return insn_len;
2510}
2511
2512static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2513{
2514 TCGv t[2];
2515 int memsize = memsize_zz(dc);
2516 int insn_len = 2;
2517
2518 LOG_DIS("move.%c [$r%u%s, $p%u\n",
2519 memsize_char(memsize),
2520 dc->op1,
2521 dc->postinc ? "+]" : "]",
2522 dc->op2);
2523
2524 cris_alu_m_alloc_temps(t);
2525 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2526 cris_cc_mask(dc, 0);
2527 if (dc->op2 == PR_CCS) {
2528 cris_evaluate_flags(dc);
2529 if (dc->tb_flags & U_FLAG) {
2530
2531 tcg_gen_andi_tl(t[1], t[1], 0x39f);
2532 tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2533 tcg_gen_or_tl(t[1], t[0], t[1]);
2534 }
2535 }
2536
2537 t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2538
2539 do_postinc(dc, memsize);
2540 cris_alu_m_free_temps(t);
2541 return insn_len;
2542}
2543
2544static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2545{
2546 TCGv t0;
2547 int memsize;
2548
2549 memsize = preg_sizes[dc->op2];
2550
2551 LOG_DIS("move.%c $p%u, [$r%u%s\n",
2552 memsize_char(memsize),
2553 dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2554
2555
2556 if (dc->op2 == PR_CCS) {
2557 cris_evaluate_flags(dc);
2558 }
2559 t0 = tcg_temp_new();
2560 t_gen_mov_TN_preg(t0, dc->op2);
2561 cris_flush_cc_state(dc);
2562 gen_store(dc, cpu_R[dc->op1], t0, memsize);
2563 tcg_temp_free(t0);
2564
2565 cris_cc_mask(dc, 0);
2566 if (dc->postinc) {
2567 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2568 }
2569 return 2;
2570}
2571
2572static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2573{
2574 TCGv_i64 tmp[16];
2575 TCGv tmp32;
2576 TCGv addr;
2577 int i;
2578 int nr = dc->op2 + 1;
2579
2580 LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2581 dc->postinc ? "+]" : "]", dc->op2);
2582
2583 addr = tcg_temp_new();
2584
2585 cris_flush_cc_state(dc);
2586 for (i = 0; i < (nr >> 1); i++) {
2587 tmp[i] = tcg_temp_new_i64();
2588 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2589 gen_load64(dc, tmp[i], addr);
2590 }
2591 if (nr & 1) {
2592 tmp32 = tcg_temp_new_i32();
2593 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2594 gen_load(dc, tmp32, addr, 4, 0);
2595 } else {
2596 tmp32 = NULL;
2597 }
2598 tcg_temp_free(addr);
2599
2600 for (i = 0; i < (nr >> 1); i++) {
2601 tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]);
2602 tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2603 tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2604 tcg_temp_free_i64(tmp[i]);
2605 }
2606 if (nr & 1) {
2607 tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2608 tcg_temp_free(tmp32);
2609 }
2610
2611
2612 if (dc->postinc) {
2613 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2614 }
2615
2616
2617 cris_cc_mask(dc, 0);
2618 return 2;
2619}
2620
2621static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2622{
2623 TCGv tmp;
2624 TCGv addr;
2625 int i;
2626
2627 LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2628 dc->postinc ? "+]" : "]");
2629
2630 cris_flush_cc_state(dc);
2631
2632 tmp = tcg_temp_new();
2633 addr = tcg_temp_new();
2634 tcg_gen_movi_tl(tmp, 4);
2635 tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2636 for (i = 0; i <= dc->op2; i++) {
2637
2638
2639 gen_store(dc, addr, cpu_R[i], 4);
2640 tcg_gen_add_tl(addr, addr, tmp);
2641 }
2642 if (dc->postinc) {
2643 tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2644 }
2645 cris_cc_mask(dc, 0);
2646 tcg_temp_free(tmp);
2647 tcg_temp_free(addr);
2648 return 2;
2649}
2650
2651static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2652{
2653 int memsize;
2654
2655 memsize = memsize_zz(dc);
2656
2657 LOG_DIS("move.%c $r%u, [$r%u]\n",
2658 memsize_char(memsize), dc->op2, dc->op1);
2659
2660
2661 cris_flush_cc_state(dc);
2662 gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2663
2664 if (dc->postinc) {
2665 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2666 }
2667 cris_cc_mask(dc, 0);
2668 return 2;
2669}
2670
2671static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2672{
2673 LOG_DIS("lapcq %x, $r%u\n",
2674 dc->pc + dc->op1*2, dc->op2);
2675 cris_cc_mask(dc, 0);
2676 tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2677 return 2;
2678}
2679
2680static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2681{
2682 unsigned int rd;
2683 int32_t imm;
2684 int32_t pc;
2685
2686 rd = dc->op2;
2687
2688 cris_cc_mask(dc, 0);
2689 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2690 LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2691
2692 pc = dc->pc;
2693 pc += imm;
2694 tcg_gen_movi_tl(cpu_R[rd], pc);
2695 return 6;
2696}
2697
2698
2699static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2700{
2701 LOG_DIS("jump $p%u\n", dc->op2);
2702
2703 if (dc->op2 == PR_CCS) {
2704 cris_evaluate_flags(dc);
2705 }
2706 t_gen_mov_TN_preg(env_btarget, dc->op2);
2707
2708 tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2709 cris_cc_mask(dc, 0);
2710 cris_prepare_jmp(dc, JMP_INDIRECT);
2711 return 2;
2712}
2713
2714
2715static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2716{
2717 LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2718 cris_cc_mask(dc, 0);
2719
2720 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2721 if (dc->op2 > 15) {
2722 abort();
2723 }
2724 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2725
2726 cris_prepare_jmp(dc, JMP_INDIRECT);
2727 return 2;
2728}
2729
2730static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2731{
2732 uint32_t imm;
2733
2734 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2735
2736 LOG_DIS("jas 0x%x\n", imm);
2737 cris_cc_mask(dc, 0);
2738
2739 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2740
2741 dc->jmp_pc = imm;
2742 cris_prepare_jmp(dc, JMP_DIRECT);
2743 return 6;
2744}
2745
2746static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2747{
2748 uint32_t imm;
2749
2750 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2751
2752 LOG_DIS("jasc 0x%x\n", imm);
2753 cris_cc_mask(dc, 0);
2754
2755 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2756
2757 dc->jmp_pc = imm;
2758 cris_prepare_jmp(dc, JMP_DIRECT);
2759 return 6;
2760}
2761
2762static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2763{
2764 LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2765 cris_cc_mask(dc, 0);
2766
2767 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2768 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2769 cris_prepare_jmp(dc, JMP_INDIRECT);
2770 return 2;
2771}
2772
2773static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2774{
2775 int32_t offset;
2776 uint32_t cond = dc->op2;
2777
2778 offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2779
2780 LOG_DIS("b%s %d pc=%x dst=%x\n",
2781 cc_name(cond), offset,
2782 dc->pc, dc->pc + offset);
2783
2784 cris_cc_mask(dc, 0);
2785
2786 cris_prepare_cc_branch(dc, offset, cond);
2787 return 4;
2788}
2789
2790static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2791{
2792 int32_t simm;
2793
2794 simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2795
2796 LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2797 cris_cc_mask(dc, 0);
2798
2799 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2800
2801 dc->jmp_pc = dc->pc + simm;
2802 cris_prepare_jmp(dc, JMP_DIRECT);
2803 return 6;
2804}
2805
2806static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2807{
2808 int32_t simm;
2809 simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2810
2811 LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2812 cris_cc_mask(dc, 0);
2813
2814 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2815
2816 dc->jmp_pc = dc->pc + simm;
2817 cris_prepare_jmp(dc, JMP_DIRECT);
2818 return 6;
2819}
2820
2821static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2822{
2823 cris_cc_mask(dc, 0);
2824
2825 if (dc->op2 == 15) {
2826 tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
2827 -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2828 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2829 t_gen_raise_exception(EXCP_HLT);
2830 return 2;
2831 }
2832
2833 switch (dc->op2 & 7) {
2834 case 2:
2835
2836 LOG_DIS("rfe\n");
2837 cris_evaluate_flags(dc);
2838 gen_helper_rfe(cpu_env);
2839 dc->is_jmp = DISAS_UPDATE;
2840 break;
2841 case 5:
2842
2843 LOG_DIS("rfn\n");
2844 cris_evaluate_flags(dc);
2845 gen_helper_rfn(cpu_env);
2846 dc->is_jmp = DISAS_UPDATE;
2847 break;
2848 case 6:
2849 LOG_DIS("break %d\n", dc->op1);
2850 cris_evaluate_flags(dc);
2851
2852 tcg_gen_movi_tl(env_pc, dc->pc + 2);
2853
2854
2855 t_gen_mov_env_TN(trap_vector,
2856 tcg_const_tl(dc->op1 + 16));
2857 t_gen_raise_exception(EXCP_BREAK);
2858 dc->is_jmp = DISAS_UPDATE;
2859 break;
2860 default:
2861 printf("op2=%x\n", dc->op2);
2862 BUG();
2863 break;
2864
2865 }
2866 return 2;
2867}
2868
2869static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2870{
2871 return 2;
2872}
2873
2874static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2875{
2876 return 2;
2877}
2878
2879static int dec_null(CPUCRISState *env, DisasContext *dc)
2880{
2881 printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2882 dc->pc, dc->opcode, dc->op1, dc->op2);
2883 fflush(NULL);
2884 BUG();
2885 return 2;
2886}
2887
2888static struct decoder_info {
2889 struct {
2890 uint32_t bits;
2891 uint32_t mask;
2892 };
2893 int (*dec)(CPUCRISState *env, DisasContext *dc);
2894} decinfo[] = {
2895
2896 {DEC_MOVEQ, dec_moveq},
2897 {DEC_BTSTQ, dec_btstq},
2898 {DEC_CMPQ, dec_cmpq},
2899 {DEC_ADDOQ, dec_addoq},
2900 {DEC_ADDQ, dec_addq},
2901 {DEC_SUBQ, dec_subq},
2902 {DEC_ANDQ, dec_andq},
2903 {DEC_ORQ, dec_orq},
2904 {DEC_ASRQ, dec_asrq},
2905 {DEC_LSLQ, dec_lslq},
2906 {DEC_LSRQ, dec_lsrq},
2907 {DEC_BCCQ, dec_bccq},
2908
2909 {DEC_BCC_IM, dec_bcc_im},
2910 {DEC_JAS_IM, dec_jas_im},
2911 {DEC_JAS_R, dec_jas_r},
2912 {DEC_JASC_IM, dec_jasc_im},
2913 {DEC_JASC_R, dec_jasc_r},
2914 {DEC_BAS_IM, dec_bas_im},
2915 {DEC_BASC_IM, dec_basc_im},
2916 {DEC_JUMP_P, dec_jump_p},
2917 {DEC_LAPC_IM, dec_lapc_im},
2918 {DEC_LAPCQ, dec_lapcq},
2919
2920 {DEC_RFE_ETC, dec_rfe_etc},
2921 {DEC_ADDC_MR, dec_addc_mr},
2922
2923 {DEC_MOVE_MP, dec_move_mp},
2924 {DEC_MOVE_PM, dec_move_pm},
2925 {DEC_MOVEM_MR, dec_movem_mr},
2926 {DEC_MOVEM_RM, dec_movem_rm},
2927 {DEC_MOVE_PR, dec_move_pr},
2928 {DEC_SCC_R, dec_scc_r},
2929 {DEC_SETF, dec_setclrf},
2930 {DEC_CLEARF, dec_setclrf},
2931
2932 {DEC_MOVE_SR, dec_move_sr},
2933 {DEC_MOVE_RP, dec_move_rp},
2934 {DEC_SWAP_R, dec_swap_r},
2935 {DEC_ABS_R, dec_abs_r},
2936 {DEC_LZ_R, dec_lz_r},
2937 {DEC_MOVE_RS, dec_move_rs},
2938 {DEC_BTST_R, dec_btst_r},
2939 {DEC_ADDC_R, dec_addc_r},
2940
2941 {DEC_DSTEP_R, dec_dstep_r},
2942 {DEC_XOR_R, dec_xor_r},
2943 {DEC_MCP_R, dec_mcp_r},
2944 {DEC_CMP_R, dec_cmp_r},
2945
2946 {DEC_ADDI_R, dec_addi_r},
2947 {DEC_ADDI_ACR, dec_addi_acr},
2948
2949 {DEC_ADD_R, dec_add_r},
2950 {DEC_SUB_R, dec_sub_r},
2951
2952 {DEC_ADDU_R, dec_addu_r},
2953 {DEC_ADDS_R, dec_adds_r},
2954 {DEC_SUBU_R, dec_subu_r},
2955 {DEC_SUBS_R, dec_subs_r},
2956 {DEC_LSL_R, dec_lsl_r},
2957
2958 {DEC_AND_R, dec_and_r},
2959 {DEC_OR_R, dec_or_r},
2960 {DEC_BOUND_R, dec_bound_r},
2961 {DEC_ASR_R, dec_asr_r},
2962 {DEC_LSR_R, dec_lsr_r},
2963
2964 {DEC_MOVU_R, dec_movu_r},
2965 {DEC_MOVS_R, dec_movs_r},
2966 {DEC_NEG_R, dec_neg_r},
2967 {DEC_MOVE_R, dec_move_r},
2968
2969 {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2970 {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2971
2972 {DEC_MULS_R, dec_muls_r},
2973 {DEC_MULU_R, dec_mulu_r},
2974
2975 {DEC_ADDU_M, dec_addu_m},
2976 {DEC_ADDS_M, dec_adds_m},
2977 {DEC_SUBU_M, dec_subu_m},
2978 {DEC_SUBS_M, dec_subs_m},
2979
2980 {DEC_CMPU_M, dec_cmpu_m},
2981 {DEC_CMPS_M, dec_cmps_m},
2982 {DEC_MOVU_M, dec_movu_m},
2983 {DEC_MOVS_M, dec_movs_m},
2984
2985 {DEC_CMP_M, dec_cmp_m},
2986 {DEC_ADDO_M, dec_addo_m},
2987 {DEC_BOUND_M, dec_bound_m},
2988 {DEC_ADD_M, dec_add_m},
2989 {DEC_SUB_M, dec_sub_m},
2990 {DEC_AND_M, dec_and_m},
2991 {DEC_OR_M, dec_or_m},
2992 {DEC_MOVE_RM, dec_move_rm},
2993 {DEC_TEST_M, dec_test_m},
2994 {DEC_MOVE_MR, dec_move_mr},
2995
2996 {{0, 0}, dec_null}
2997};
2998
2999static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
3000{
3001 int insn_len = 2;
3002 int i;
3003
3004
3005 dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
3006
3007
3008 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
3009 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
3010 dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
3011 dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
3012 dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
3013 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
3014
3015
3016 for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3017 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
3018 insn_len = decinfo[i].dec(env, dc);
3019 break;
3020 }
3021 }
3022
3023#if !defined(CONFIG_USER_ONLY)
3024
3025 if (dc->tb_flags & S_FLAG) {
3026 TCGLabel *l1 = gen_new_label();
3027 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3028
3029 cris_evaluate_flags(dc);
3030 t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3031 tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3032 tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3033 t_gen_raise_exception(EXCP_BREAK);
3034 gen_set_label(l1);
3035 }
3036#endif
3037 return insn_len;
3038}
3039
3040#include "translate_v10.inc.c"
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
3076
3077void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
3078{
3079 CPUCRISState *env = cs->env_ptr;
3080 uint32_t pc_start;
3081 unsigned int insn_len;
3082 struct DisasContext ctx;
3083 struct DisasContext *dc = &ctx;
3084 uint32_t page_start;
3085 target_ulong npc;
3086 int num_insns;
3087
3088 if (env->pregs[PR_VR] == 32) {
3089 dc->decoder = crisv32_decoder;
3090 dc->clear_locked_irq = 0;
3091 } else {
3092 dc->decoder = crisv10_decoder;
3093 dc->clear_locked_irq = 1;
3094 }
3095
3096
3097
3098
3099 pc_start = tb->pc & ~1;
3100 dc->cpu = env_archcpu(env);
3101 dc->tb = tb;
3102
3103 dc->is_jmp = DISAS_NEXT;
3104 dc->ppc = pc_start;
3105 dc->pc = pc_start;
3106 dc->singlestep_enabled = cs->singlestep_enabled;
3107 dc->flags_uptodate = 1;
3108 dc->flagx_known = 1;
3109 dc->flags_x = tb->flags & X_FLAG;
3110 dc->cc_x_uptodate = 0;
3111 dc->cc_mask = 0;
3112 dc->update_cc = 0;
3113 dc->clear_prefix = 0;
3114
3115 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3116 dc->cc_size_uptodate = -1;
3117
3118
3119 dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3120 | X_FLAG | PFIX_FLAG);
3121 dc->delayed_branch = !!(tb->flags & 7);
3122 if (dc->delayed_branch) {
3123 dc->jmp = JMP_INDIRECT;
3124 } else {
3125 dc->jmp = JMP_NOJMP;
3126 }
3127
3128 dc->cpustate_changed = 0;
3129
3130 page_start = pc_start & TARGET_PAGE_MASK;
3131 num_insns = 0;
3132
3133 gen_tb_start(tb);
3134 do {
3135 tcg_gen_insn_start(dc->delayed_branch == 1
3136 ? dc->ppc | 1 : dc->pc);
3137 num_insns++;
3138
3139 if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
3140 cris_evaluate_flags(dc);
3141 tcg_gen_movi_tl(env_pc, dc->pc);
3142 t_gen_raise_exception(EXCP_DEBUG);
3143 dc->is_jmp = DISAS_UPDATE;
3144
3145
3146
3147
3148 dc->pc += 2;
3149 break;
3150 }
3151
3152
3153 LOG_DIS("%8.8x:\t", dc->pc);
3154
3155 if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
3156 gen_io_start();
3157 }
3158 dc->clear_x = 1;
3159
3160 insn_len = dc->decoder(env, dc);
3161 dc->ppc = dc->pc;
3162 dc->pc += insn_len;
3163 if (dc->clear_x) {
3164 cris_clear_x_flag(dc);
3165 }
3166
3167
3168
3169
3170 if (dc->delayed_branch) {
3171 dc->delayed_branch--;
3172 if (dc->delayed_branch == 0) {
3173 if (tb->flags & 7) {
3174 t_gen_mov_env_TN(dslot, tcg_const_tl(0));
3175 }
3176 if (dc->cpustate_changed || !dc->flagx_known
3177 || (dc->flags_x != (tb->flags & X_FLAG))) {
3178 cris_store_direct_jmp(dc);
3179 }
3180
3181 if (dc->clear_locked_irq) {
3182 dc->clear_locked_irq = 0;
3183 t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3184 }
3185
3186 if (dc->jmp == JMP_DIRECT_CC) {
3187 TCGLabel *l1 = gen_new_label();
3188 cris_evaluate_flags(dc);
3189
3190
3191 tcg_gen_brcondi_tl(TCG_COND_EQ,
3192 env_btaken, 0, l1);
3193 gen_goto_tb(dc, 1, dc->jmp_pc);
3194 gen_set_label(l1);
3195 gen_goto_tb(dc, 0, dc->pc);
3196 dc->is_jmp = DISAS_TB_JUMP;
3197 dc->jmp = JMP_NOJMP;
3198 } else if (dc->jmp == JMP_DIRECT) {
3199 cris_evaluate_flags(dc);
3200 gen_goto_tb(dc, 0, dc->jmp_pc);
3201 dc->is_jmp = DISAS_TB_JUMP;
3202 dc->jmp = JMP_NOJMP;
3203 } else {
3204 t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
3205 dc->is_jmp = DISAS_JUMP;
3206 }
3207 break;
3208 }
3209 }
3210
3211
3212
3213 if (!(tb->pc & 1) && cs->singlestep_enabled) {
3214 break;
3215 }
3216 } while (!dc->is_jmp && !dc->cpustate_changed
3217 && !tcg_op_buf_full()
3218 && !singlestep
3219 && (dc->pc - page_start < TARGET_PAGE_SIZE)
3220 && num_insns < max_insns);
3221
3222 if (dc->clear_locked_irq) {
3223 t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3224 }
3225
3226 npc = dc->pc;
3227
3228
3229 if (dc->is_jmp == DISAS_NEXT
3230 && (dc->cpustate_changed || !dc->flagx_known
3231 || (dc->flags_x != (tb->flags & X_FLAG)))) {
3232 dc->is_jmp = DISAS_UPDATE;
3233 tcg_gen_movi_tl(env_pc, npc);
3234 }
3235
3236 if (dc->delayed_branch == 1) {
3237
3238 t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3239 cris_store_direct_jmp(dc);
3240 }
3241
3242 cris_evaluate_flags(dc);
3243
3244 if (unlikely(cs->singlestep_enabled)) {
3245 if (dc->is_jmp == DISAS_NEXT) {
3246 tcg_gen_movi_tl(env_pc, npc);
3247 }
3248 t_gen_raise_exception(EXCP_DEBUG);
3249 } else {
3250 switch (dc->is_jmp) {
3251 case DISAS_NEXT:
3252 gen_goto_tb(dc, 1, npc);
3253 break;
3254 default:
3255 case DISAS_JUMP:
3256 case DISAS_UPDATE:
3257
3258
3259 tcg_gen_exit_tb(NULL, 0);
3260 break;
3261 case DISAS_SWI:
3262 case DISAS_TB_JUMP:
3263
3264 break;
3265 }
3266 }
3267 gen_tb_end(tb, num_insns);
3268
3269 tb->size = dc->pc - pc_start;
3270 tb->icount = num_insns;
3271
3272#ifdef DEBUG_DISAS
3273#if !DISAS_CRIS
3274 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
3275 && qemu_log_in_addr_range(pc_start)) {
3276 qemu_log_lock();
3277 qemu_log("--------------\n");
3278 qemu_log("IN: %s\n", lookup_symbol(pc_start));
3279 log_target_disas(cs, pc_start, dc->pc - pc_start);
3280 qemu_log_unlock();
3281 }
3282#endif
3283#endif
3284}
3285
3286void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
3287{
3288 CRISCPU *cpu = CRIS_CPU(cs);
3289 CPUCRISState *env = &cpu->env;
3290 const char **regnames;
3291 const char **pregnames;
3292 int i;
3293
3294 if (!env) {
3295 return;
3296 }
3297 if (env->pregs[PR_VR] < 32) {
3298 pregnames = pregnames_v10;
3299 regnames = regnames_v10;
3300 } else {
3301 pregnames = pregnames_v32;
3302 regnames = regnames_v32;
3303 }
3304
3305 qemu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3306 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3307 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3308 env->cc_op,
3309 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3310
3311
3312 for (i = 0; i < 16; i++) {
3313 qemu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3314 if ((i + 1) % 4 == 0) {
3315 qemu_fprintf(f, "\n");
3316 }
3317 }
3318 qemu_fprintf(f, "\nspecial regs:\n");
3319 for (i = 0; i < 16; i++) {
3320 qemu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3321 if ((i + 1) % 4 == 0) {
3322 qemu_fprintf(f, "\n");
3323 }
3324 }
3325 if (env->pregs[PR_VR] >= 32) {
3326 uint32_t srs = env->pregs[PR_SRS];
3327 qemu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3328 if (srs < ARRAY_SIZE(env->sregs)) {
3329 for (i = 0; i < 16; i++) {
3330 qemu_fprintf(f, "s%2.2d=%8.8x ",
3331 i, env->sregs[srs][i]);
3332 if ((i + 1) % 4 == 0) {
3333 qemu_fprintf(f, "\n");
3334 }
3335 }
3336 }
3337 }
3338 qemu_fprintf(f, "\n\n");
3339
3340}
3341
3342void cris_initialize_tcg(void)
3343{
3344 int i;
3345
3346 cc_x = tcg_global_mem_new(cpu_env,
3347 offsetof(CPUCRISState, cc_x), "cc_x");
3348 cc_src = tcg_global_mem_new(cpu_env,
3349 offsetof(CPUCRISState, cc_src), "cc_src");
3350 cc_dest = tcg_global_mem_new(cpu_env,
3351 offsetof(CPUCRISState, cc_dest),
3352 "cc_dest");
3353 cc_result = tcg_global_mem_new(cpu_env,
3354 offsetof(CPUCRISState, cc_result),
3355 "cc_result");
3356 cc_op = tcg_global_mem_new(cpu_env,
3357 offsetof(CPUCRISState, cc_op), "cc_op");
3358 cc_size = tcg_global_mem_new(cpu_env,
3359 offsetof(CPUCRISState, cc_size),
3360 "cc_size");
3361 cc_mask = tcg_global_mem_new(cpu_env,
3362 offsetof(CPUCRISState, cc_mask),
3363 "cc_mask");
3364
3365 env_pc = tcg_global_mem_new(cpu_env,
3366 offsetof(CPUCRISState, pc),
3367 "pc");
3368 env_btarget = tcg_global_mem_new(cpu_env,
3369 offsetof(CPUCRISState, btarget),
3370 "btarget");
3371 env_btaken = tcg_global_mem_new(cpu_env,
3372 offsetof(CPUCRISState, btaken),
3373 "btaken");
3374 for (i = 0; i < 16; i++) {
3375 cpu_R[i] = tcg_global_mem_new(cpu_env,
3376 offsetof(CPUCRISState, regs[i]),
3377 regnames_v32[i]);
3378 }
3379 for (i = 0; i < 16; i++) {
3380 cpu_PR[i] = tcg_global_mem_new(cpu_env,
3381 offsetof(CPUCRISState, pregs[i]),
3382 pregnames_v32[i]);
3383 }
3384}
3385
3386void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb,
3387 target_ulong *data)
3388{
3389 env->pc = data[0];
3390}
3391