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