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