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