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