]> git.proxmox.com Git - mirror_qemu.git/blob - target-cris/translate.c
use the TCG code generator
[mirror_qemu.git] / target-cris / translate.c
1 /*
2 * CRIS emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2007 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * This file implements a CRIS decoder-stage in SW. The decoder translates the
24 * guest (CRIS) machine-code into host machine code via dyngen using the
25 * micro-operations described in op.c
26 *
27 * The micro-operations for CRIS translation implement a RISC style ISA.
28 * Note that the micro-operations typically order their operands
29 * starting with the dst. CRIS asm, does the opposite.
30 *
31 * For example the following CRIS code:
32 * add.d [$r0], $r1
33 *
34 * translates into:
35 *
36 * gen_movl_T0_reg(0); // Fetch $r0 into T0
37 * gen_load_T0_T0(); // Load T0, @T0
38 * gen_movl_reg_T0(1); // Writeback T0 into $r1
39 *
40 * The actual names for the micro-code generators vary but the example
41 * illustrates the point.
42 */
43
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <inttypes.h>
49 #include <assert.h>
50
51 #include "cpu.h"
52 #include "exec-all.h"
53 #include "disas.h"
54 #include "tcg-op.h"
55 #include "crisv32-decode.h"
56
57 #define CRIS_STATS 0
58 #if CRIS_STATS
59 #define STATS(x) x
60 #else
61 #define STATS(x)
62 #endif
63
64 #define DISAS_CRIS 0
65 #if DISAS_CRIS
66 #define DIS(x) x
67 #else
68 #define DIS(x)
69 #endif
70
71 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
72 #define BUG_ON(x) ({if (x) BUG();})
73
74 /* Used by the decoder. */
75 #define EXTRACT_FIELD(src, start, end) \
76 (((src) >> start) & ((1 << (end - start + 1)) - 1))
77
78 #define CC_MASK_NZ 0xc
79 #define CC_MASK_NZV 0xe
80 #define CC_MASK_NZVC 0xf
81 #define CC_MASK_RNZV 0x10e
82
83 /* This is the state at translation time. */
84 typedef struct DisasContext {
85 CPUState *env;
86 target_ulong pc, insn_pc;
87
88 /* Decoder. */
89 uint32_t ir;
90 uint32_t opcode;
91 unsigned int op1;
92 unsigned int op2;
93 unsigned int zsize, zzsize;
94 unsigned int mode;
95 unsigned int postinc;
96
97 int update_cc;
98 int cc_op;
99 int cc_size;
100 uint32_t cc_mask;
101 int flags_live;
102 int flagx_live;
103 int flags_x;
104 uint32_t tb_entry_flags;
105
106 int memidx; /* user or kernel mode. */
107 int is_jmp;
108 int dyn_jmp;
109
110 uint32_t delayed_pc;
111 int delayed_branch;
112 int bcc;
113 uint32_t condlabel;
114
115 struct TranslationBlock *tb;
116 int singlestep_enabled;
117 } DisasContext;
118
119 void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
120 static void gen_BUG(DisasContext *dc, char *file, int line)
121 {
122 printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
123 fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
124 cpu_dump_state (dc->env, stdout, fprintf, 0);
125 fflush(NULL);
126 cris_prepare_jmp (dc, 0x70000000 + line);
127 }
128
129 /* Table to generate quick moves from T0 onto any register. */
130 static GenOpFunc *gen_movl_reg_T0[16] =
131 {
132 gen_op_movl_r0_T0, gen_op_movl_r1_T0,
133 gen_op_movl_r2_T0, gen_op_movl_r3_T0,
134 gen_op_movl_r4_T0, gen_op_movl_r5_T0,
135 gen_op_movl_r6_T0, gen_op_movl_r7_T0,
136 gen_op_movl_r8_T0, gen_op_movl_r9_T0,
137 gen_op_movl_r10_T0, gen_op_movl_r11_T0,
138 gen_op_movl_r12_T0, gen_op_movl_r13_T0,
139 gen_op_movl_r14_T0, gen_op_movl_r15_T0,
140 };
141 static GenOpFunc *gen_movl_T0_reg[16] =
142 {
143 gen_op_movl_T0_r0, gen_op_movl_T0_r1,
144 gen_op_movl_T0_r2, gen_op_movl_T0_r3,
145 gen_op_movl_T0_r4, gen_op_movl_T0_r5,
146 gen_op_movl_T0_r6, gen_op_movl_T0_r7,
147 gen_op_movl_T0_r8, gen_op_movl_T0_r9,
148 gen_op_movl_T0_r10, gen_op_movl_T0_r11,
149 gen_op_movl_T0_r12, gen_op_movl_T0_r13,
150 gen_op_movl_T0_r14, gen_op_movl_T0_r15,
151 };
152
153 static void noop_write(void) {
154 /* nop. */
155 }
156
157 static void gen_vr_read(void) {
158 gen_op_movl_T0_im(32);
159 }
160
161 static void gen_movl_T0_p0(void) {
162 gen_op_movl_T0_im(0);
163 }
164
165 static void gen_ccs_read(void) {
166 gen_op_movl_T0_p13();
167 }
168
169 static void gen_ccs_write(void) {
170 gen_op_movl_p13_T0();
171 }
172
173 /* Table to generate quick moves from T0 onto any register. */
174 static GenOpFunc *gen_movl_preg_T0[16] =
175 {
176 noop_write, /* bz, not writeable. */
177 noop_write, /* vr, not writeable. */
178 gen_op_movl_p2_T0, gen_op_movl_p3_T0,
179 noop_write, /* wz, not writeable. */
180 gen_op_movl_p5_T0,
181 gen_op_movl_p6_T0, gen_op_movl_p7_T0,
182 noop_write, /* dz, not writeable. */
183 gen_op_movl_p9_T0,
184 gen_op_movl_p10_T0, gen_op_movl_p11_T0,
185 gen_op_movl_p12_T0,
186 gen_ccs_write, /* ccs needs special treatment. */
187 gen_op_movl_p14_T0, gen_op_movl_p15_T0,
188 };
189 static GenOpFunc *gen_movl_T0_preg[16] =
190 {
191 gen_movl_T0_p0,
192 gen_vr_read,
193 gen_op_movl_T0_p2, gen_op_movl_T0_p3,
194 gen_op_movl_T0_p4, gen_op_movl_T0_p5,
195 gen_op_movl_T0_p6, gen_op_movl_T0_p7,
196 gen_op_movl_T0_p8, gen_op_movl_T0_p9,
197 gen_op_movl_T0_p10, gen_op_movl_T0_p11,
198 gen_op_movl_T0_p12,
199 gen_ccs_read, /* ccs needs special treatment. */
200 gen_op_movl_T0_p14, gen_op_movl_T0_p15,
201 };
202
203 /* We need this table to handle moves with implicit width. */
204 int preg_sizes[] = {
205 1, /* bz. */
206 1, /* vr. */
207 4, /* pid. */
208 1, /* srs. */
209 2, /* wz. */
210 4, 4, 4,
211 4, 4, 4, 4,
212 4, 4, 4, 4,
213 };
214
215 #ifdef CONFIG_USER_ONLY
216 #define GEN_OP_LD(width, reg) \
217 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
218 gen_op_ld##width##_T0_##reg##_raw(); \
219 }
220 #define GEN_OP_ST(width, reg) \
221 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
222 gen_op_st##width##_##reg##_T1_raw(); \
223 }
224 #else
225 #define GEN_OP_LD(width, reg) \
226 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
227 if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
228 else gen_op_ld##width##_T0_##reg##_user();\
229 }
230 #define GEN_OP_ST(width, reg) \
231 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
232 if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
233 else gen_op_st##width##_##reg##_T1_user();\
234 }
235 #endif
236
237 GEN_OP_LD(ub, T0)
238 GEN_OP_LD(b, T0)
239 GEN_OP_ST(b, T0)
240 GEN_OP_LD(uw, T0)
241 GEN_OP_LD(w, T0)
242 GEN_OP_ST(w, T0)
243 GEN_OP_LD(l, T0)
244 GEN_OP_ST(l, T0)
245
246 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
247 {
248 TranslationBlock *tb;
249 tb = dc->tb;
250 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
251 #if 0
252 /* XXX: this code is not finished */
253 tcg_gen_goto_tb(n);
254 #endif
255 tcg_gen_exit_tb(0);
256 } else {
257 tcg_gen_exit_tb(0);
258 }
259 }
260
261 /* Sign extend at translation time. */
262 static int sign_extend(unsigned int val, unsigned int width)
263 {
264 int sval;
265
266 /* LSL. */
267 val <<= 31 - width;
268 sval = val;
269 /* ASR. */
270 sval >>= 31 - width;
271 return sval;
272 }
273
274 static void cris_evaluate_flags(DisasContext *dc)
275 {
276 if (!dc->flags_live) {
277
278 switch (dc->cc_op)
279 {
280 case CC_OP_MCP:
281 gen_op_evaluate_flags_mcp ();
282 break;
283 case CC_OP_MULS:
284 gen_op_evaluate_flags_muls ();
285 break;
286 case CC_OP_MULU:
287 gen_op_evaluate_flags_mulu ();
288 break;
289 case CC_OP_MOVE:
290 switch (dc->cc_size)
291 {
292 case 4:
293 gen_op_evaluate_flags_move_4();
294 break;
295 case 2:
296 gen_op_evaluate_flags_move_2();
297 break;
298 default:
299 gen_op_evaluate_flags ();
300 break;
301 }
302 break;
303
304 default:
305 {
306 switch (dc->cc_size)
307 {
308 case 4:
309 gen_op_evaluate_flags_alu_4 ();
310 break;
311 default:
312 gen_op_evaluate_flags ();
313 break;
314 }
315 }
316 break;
317 }
318 dc->flags_live = 1;
319 }
320 }
321
322 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
323 {
324 uint32_t ovl;
325
326 /* Check if we need to evaluate the condition codes due to
327 CC overlaying. */
328 ovl = (dc->cc_mask ^ mask) & ~mask;
329 if (ovl) {
330 /* TODO: optimize this case. It trigs all the time. */
331 cris_evaluate_flags (dc);
332 }
333 dc->cc_mask = mask;
334
335 dc->update_cc = 1;
336 if (mask == 0)
337 dc->update_cc = 0;
338 else {
339 gen_op_update_cc_mask(mask);
340 dc->flags_live = 0;
341 }
342 }
343
344 static void cris_update_cc_op(DisasContext *dc, int op)
345 {
346 dc->cc_op = op;
347 gen_op_update_cc_op(op);
348 dc->flags_live = 0;
349 }
350 static void cris_update_cc_size(DisasContext *dc, int size)
351 {
352 dc->cc_size = size;
353 gen_op_update_cc_size_im(size);
354 }
355
356 /* op is the operation.
357 T0, T1 are the operands.
358 dst is the destination reg.
359 */
360 static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
361 {
362 int writeback = 1;
363 if (dc->update_cc) {
364 cris_update_cc_op(dc, op);
365 cris_update_cc_size(dc, size);
366 gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
367 gen_op_update_cc_dest_T0();
368 }
369
370 /* Emit the ALU insns. */
371 switch (op)
372 {
373 case CC_OP_ADD:
374 gen_op_addl_T0_T1();
375 /* Extended arithmetics. */
376 if (!dc->flagx_live)
377 gen_op_addxl_T0_C();
378 else if (dc->flags_x)
379 gen_op_addxl_T0_C();
380 break;
381 case CC_OP_ADDC:
382 gen_op_addl_T0_T1();
383 gen_op_addl_T0_C();
384 break;
385 case CC_OP_MCP:
386 gen_op_addl_T0_T1();
387 gen_op_addl_T0_R();
388 break;
389 case CC_OP_SUB:
390 gen_op_negl_T1_T1();
391 gen_op_addl_T0_T1();
392 /* CRIS flag evaluation needs ~src. */
393 gen_op_negl_T1_T1();
394 gen_op_not_T1_T1();
395
396 /* Extended arithmetics. */
397 if (!dc->flagx_live)
398 gen_op_subxl_T0_C();
399 else if (dc->flags_x)
400 gen_op_subxl_T0_C();
401 break;
402 case CC_OP_MOVE:
403 gen_op_movl_T0_T1();
404 break;
405 case CC_OP_OR:
406 gen_op_orl_T0_T1();
407 break;
408 case CC_OP_AND:
409 gen_op_andl_T0_T1();
410 break;
411 case CC_OP_XOR:
412 gen_op_xorl_T0_T1();
413 break;
414 case CC_OP_LSL:
415 gen_op_lsll_T0_T1();
416 break;
417 case CC_OP_LSR:
418 gen_op_lsrl_T0_T1();
419 break;
420 case CC_OP_ASR:
421 gen_op_asrl_T0_T1();
422 break;
423 case CC_OP_NEG:
424 gen_op_negl_T0_T1();
425 /* Extended arithmetics. */
426 gen_op_subxl_T0_C();
427 break;
428 case CC_OP_LZ:
429 gen_op_lz_T0_T1();
430 break;
431 case CC_OP_BTST:
432 gen_op_btst_T0_T1();
433 writeback = 0;
434 break;
435 case CC_OP_MULS:
436 gen_op_muls_T0_T1();
437 break;
438 case CC_OP_MULU:
439 gen_op_mulu_T0_T1();
440 break;
441 case CC_OP_DSTEP:
442 gen_op_dstep_T0_T1();
443 break;
444 case CC_OP_BOUND:
445 gen_op_bound_T0_T1();
446 break;
447 case CC_OP_CMP:
448 gen_op_negl_T1_T1();
449 gen_op_addl_T0_T1();
450 /* CRIS flag evaluation needs ~src. */
451 gen_op_negl_T1_T1();
452 gen_op_not_T1_T1();
453
454 /* Extended arithmetics. */
455 gen_op_subxl_T0_C();
456 writeback = 0;
457 break;
458 default:
459 fprintf (logfile, "illegal ALU op.\n");
460 BUG();
461 break;
462 }
463
464 if (dc->update_cc)
465 gen_op_update_cc_src_T1();
466
467 if (size == 1)
468 gen_op_andl_T0_im(0xff);
469 else if (size == 2)
470 gen_op_andl_T0_im(0xffff);
471 /* Writeback. */
472 if (writeback) {
473 if (size == 4)
474 gen_movl_reg_T0[rd]();
475 else {
476 gen_op_movl_T1_T0();
477 gen_movl_T0_reg[rd]();
478 if (size == 1)
479 gen_op_andl_T0_im(~0xff);
480 else
481 gen_op_andl_T0_im(~0xffff);
482 gen_op_orl_T0_T1();
483 gen_movl_reg_T0[rd]();
484 gen_op_movl_T0_T1();
485 }
486 }
487 if (dc->update_cc)
488 gen_op_update_cc_result_T0();
489
490 {
491 /* TODO: Optimize this. */
492 if (!dc->flagx_live)
493 cris_evaluate_flags(dc);
494 }
495 }
496
497 static int arith_cc(DisasContext *dc)
498 {
499 if (dc->update_cc) {
500 switch (dc->cc_op) {
501 case CC_OP_ADD: return 1;
502 case CC_OP_SUB: return 1;
503 case CC_OP_LSL: return 1;
504 case CC_OP_LSR: return 1;
505 case CC_OP_ASR: return 1;
506 case CC_OP_CMP: return 1;
507 default:
508 return 0;
509 }
510 }
511 return 0;
512 }
513
514 static void gen_tst_cc (DisasContext *dc, int cond)
515 {
516 int arith_opt;
517
518 /* TODO: optimize more condition codes. */
519 arith_opt = arith_cc(dc) && !dc->flags_live;
520 switch (cond) {
521 case CC_EQ:
522 if (arith_opt)
523 gen_op_tst_cc_eq_fast ();
524 else {
525 cris_evaluate_flags(dc);
526 gen_op_tst_cc_eq ();
527 }
528 break;
529 case CC_NE:
530 if (arith_opt)
531 gen_op_tst_cc_ne_fast ();
532 else {
533 cris_evaluate_flags(dc);
534 gen_op_tst_cc_ne ();
535 }
536 break;
537 case CC_CS:
538 cris_evaluate_flags(dc);
539 gen_op_tst_cc_cs ();
540 break;
541 case CC_CC:
542 cris_evaluate_flags(dc);
543 gen_op_tst_cc_cc ();
544 break;
545 case CC_VS:
546 cris_evaluate_flags(dc);
547 gen_op_tst_cc_vs ();
548 break;
549 case CC_VC:
550 cris_evaluate_flags(dc);
551 gen_op_tst_cc_vc ();
552 break;
553 case CC_PL:
554 if (arith_opt)
555 gen_op_tst_cc_pl_fast ();
556 else {
557 cris_evaluate_flags(dc);
558 gen_op_tst_cc_pl ();
559 }
560 break;
561 case CC_MI:
562 if (arith_opt)
563 gen_op_tst_cc_mi_fast ();
564 else {
565 cris_evaluate_flags(dc);
566 gen_op_tst_cc_mi ();
567 }
568 break;
569 case CC_LS:
570 cris_evaluate_flags(dc);
571 gen_op_tst_cc_ls ();
572 break;
573 case CC_HI:
574 cris_evaluate_flags(dc);
575 gen_op_tst_cc_hi ();
576 break;
577 case CC_GE:
578 cris_evaluate_flags(dc);
579 gen_op_tst_cc_ge ();
580 break;
581 case CC_LT:
582 cris_evaluate_flags(dc);
583 gen_op_tst_cc_lt ();
584 break;
585 case CC_GT:
586 cris_evaluate_flags(dc);
587 gen_op_tst_cc_gt ();
588 break;
589 case CC_LE:
590 cris_evaluate_flags(dc);
591 gen_op_tst_cc_le ();
592 break;
593 case CC_P:
594 cris_evaluate_flags(dc);
595 gen_op_tst_cc_p ();
596 break;
597 case CC_A:
598 cris_evaluate_flags(dc);
599 gen_op_movl_T0_im (1);
600 break;
601 default:
602 BUG();
603 break;
604 };
605 }
606
607 static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
608 {
609 /* This helps us re-schedule the micro-code to insns in delay-slots
610 before the actual jump. */
611 dc->delayed_branch = 2;
612 dc->delayed_pc = dc->pc + offset;
613 dc->bcc = cond;
614 if (cond != CC_A)
615 {
616 gen_tst_cc (dc, cond);
617 gen_op_evaluate_bcc ();
618 }
619 gen_op_movl_T0_im (dc->delayed_pc);
620 gen_op_movl_btarget_T0 ();
621 }
622
623 /* Dynamic jumps, when the dest is in a live reg for example. */
624 void cris_prepare_dyn_jmp (DisasContext *dc)
625 {
626 /* This helps us re-schedule the micro-code to insns in delay-slots
627 before the actual jump. */
628 dc->delayed_branch = 2;
629 dc->dyn_jmp = 1;
630 dc->bcc = CC_A;
631 }
632
633 void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
634 {
635 /* This helps us re-schedule the micro-code to insns in delay-slots
636 before the actual jump. */
637 dc->delayed_branch = 2;
638 dc->delayed_pc = dst;
639 dc->dyn_jmp = 0;
640 dc->bcc = CC_A;
641 }
642
643 void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
644 {
645 if (size == 1) {
646 if (sign)
647 gen_op_ldb_T0_T0(dc);
648 else
649 gen_op_ldub_T0_T0(dc);
650 }
651 else if (size == 2) {
652 if (sign)
653 gen_op_ldw_T0_T0(dc);
654 else
655 gen_op_lduw_T0_T0(dc);
656 }
657 else {
658 gen_op_ldl_T0_T0(dc);
659 }
660 }
661
662 void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
663 {
664 /* Remember, operands are flipped. CRIS has reversed order. */
665 if (size == 1) {
666 gen_op_stb_T0_T1(dc);
667 }
668 else if (size == 2) {
669 gen_op_stw_T0_T1(dc);
670 }
671 else
672 gen_op_stl_T0_T1(dc);
673 }
674
675 /* sign extend T1 according to size. */
676 static void gen_sext_T1_T0(int size)
677 {
678 if (size == 1)
679 gen_op_extb_T1_T0();
680 else if (size == 2)
681 gen_op_extw_T1_T0();
682 }
683
684 static void gen_sext_T1_T1(int size)
685 {
686 if (size == 1)
687 gen_op_extb_T1_T1();
688 else if (size == 2)
689 gen_op_extw_T1_T1();
690 }
691
692 static void gen_sext_T0_T0(int size)
693 {
694 if (size == 1)
695 gen_op_extb_T0_T0();
696 else if (size == 2)
697 gen_op_extw_T0_T0();
698 }
699
700 static void gen_zext_T0_T0(int size)
701 {
702 if (size == 1)
703 gen_op_zextb_T0_T0();
704 else if (size == 2)
705 gen_op_zextw_T0_T0();
706 }
707
708 static void gen_zext_T1_T0(int size)
709 {
710 if (size == 1)
711 gen_op_zextb_T1_T0();
712 else if (size == 2)
713 gen_op_zextw_T1_T0();
714 }
715
716 static void gen_zext_T1_T1(int size)
717 {
718 if (size == 1)
719 gen_op_zextb_T1_T1();
720 else if (size == 2)
721 gen_op_zextw_T1_T1();
722 }
723
724 #if DISAS_CRIS
725 static char memsize_char(int size)
726 {
727 switch (size)
728 {
729 case 1: return 'b'; break;
730 case 2: return 'w'; break;
731 case 4: return 'd'; break;
732 default:
733 return 'x';
734 break;
735 }
736 }
737 #endif
738
739 static unsigned int memsize_z(DisasContext *dc)
740 {
741 return dc->zsize + 1;
742 }
743
744 static unsigned int memsize_zz(DisasContext *dc)
745 {
746 switch (dc->zzsize)
747 {
748 case 0: return 1;
749 case 1: return 2;
750 default:
751 return 4;
752 }
753 }
754
755 static void do_postinc (DisasContext *dc, int size)
756 {
757 if (!dc->postinc)
758 return;
759 gen_movl_T0_reg[dc->op1]();
760 gen_op_addl_T0_im(size);
761 gen_movl_reg_T0[dc->op1]();
762 }
763
764
765 static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
766 int size, int s_ext)
767 {
768 gen_movl_T0_reg[rs]();
769 gen_op_movl_T1_T0();
770 if (s_ext)
771 gen_sext_T1_T1(size);
772 else
773 gen_zext_T1_T1(size);
774 }
775
776 /* Prepare T0 and T1 for a register alu operation.
777 s_ext decides if the operand1 should be sign-extended or zero-extended when
778 needed. */
779 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
780 int size, int s_ext)
781 {
782 dec_prep_move_r(dc, rs, rd, size, s_ext);
783
784 gen_movl_T0_reg[rd]();
785 if (s_ext)
786 gen_sext_T0_T0(size);
787 else
788 gen_zext_T0_T0(size);
789 }
790
791 /* Prepare T0 and T1 for a memory + alu operation.
792 s_ext decides if the operand1 should be sign-extended or zero-extended when
793 needed. */
794 static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
795 {
796 unsigned int rs, rd;
797 uint32_t imm;
798 int is_imm;
799 int insn_len = 2;
800
801 rs = dc->op1;
802 rd = dc->op2;
803 is_imm = rs == 15 && dc->postinc;
804
805 /* Load [$rs] onto T1. */
806 if (is_imm) {
807 insn_len = 2 + memsize;
808 if (memsize == 1)
809 insn_len++;
810
811 imm = ldl_code(dc->pc + 2);
812 if (memsize != 4) {
813 if (s_ext) {
814 imm = sign_extend(imm, (memsize * 8) - 1);
815 } else {
816 if (memsize == 1)
817 imm &= 0xff;
818 else
819 imm &= 0xffff;
820 }
821 }
822 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
823 imm, rd, s_ext, memsize));
824 gen_op_movl_T1_im (imm);
825 dc->postinc = 0;
826 } else {
827 gen_movl_T0_reg[rs]();
828 gen_load_T0_T0(dc, memsize, 0);
829 gen_op_movl_T1_T0();
830 if (s_ext)
831 gen_sext_T1_T1(memsize);
832 else
833 gen_zext_T1_T1(memsize);
834 }
835
836 /* put dest in T0. */
837 gen_movl_T0_reg[rd]();
838 return insn_len;
839 }
840
841 #if DISAS_CRIS
842 static const char *cc_name(int cc)
843 {
844 static char *cc_names[16] = {
845 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
846 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
847 };
848 assert(cc < 16);
849 return cc_names[cc];
850 }
851 #endif
852
853 static unsigned int dec_bccq(DisasContext *dc)
854 {
855 int32_t offset;
856 int sign;
857 uint32_t cond = dc->op2;
858 int tmp;
859
860 offset = EXTRACT_FIELD (dc->ir, 1, 7);
861 sign = EXTRACT_FIELD(dc->ir, 0, 0);
862
863 offset *= 2;
864 offset |= sign << 8;
865 tmp = offset;
866 offset = sign_extend(offset, 8);
867
868 /* op2 holds the condition-code. */
869 cris_cc_mask(dc, 0);
870 cris_prepare_cc_branch (dc, offset, cond);
871 return 2;
872 }
873 static unsigned int dec_addoq(DisasContext *dc)
874 {
875 uint32_t imm;
876
877 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
878 imm = sign_extend(dc->op1, 7);
879
880 DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
881 cris_cc_mask(dc, 0);
882 /* Fetch register operand, */
883 gen_movl_T0_reg[dc->op2]();
884 gen_op_movl_T1_im(imm);
885 crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
886 return 2;
887 }
888 static unsigned int dec_addq(DisasContext *dc)
889 {
890 DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
891
892 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
893
894 cris_cc_mask(dc, CC_MASK_NZVC);
895 /* Fetch register operand, */
896 gen_movl_T0_reg[dc->op2]();
897 gen_op_movl_T1_im(dc->op1);
898 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
899 return 2;
900 }
901 static unsigned int dec_moveq(DisasContext *dc)
902 {
903 uint32_t imm;
904
905 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
906 imm = sign_extend(dc->op1, 5);
907 DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
908
909 cris_cc_mask(dc, 0);
910 gen_op_movl_T1_im(imm);
911 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
912
913 return 2;
914 }
915 static unsigned int dec_subq(DisasContext *dc)
916 {
917 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
918
919 DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
920
921 cris_cc_mask(dc, CC_MASK_NZVC);
922 /* Fetch register operand, */
923 gen_movl_T0_reg[dc->op2]();
924 gen_op_movl_T1_im(dc->op1);
925 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
926 return 2;
927 }
928 static unsigned int dec_cmpq(DisasContext *dc)
929 {
930 uint32_t imm;
931 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
932 imm = sign_extend(dc->op1, 5);
933
934 DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
935 cris_cc_mask(dc, CC_MASK_NZVC);
936 gen_movl_T0_reg[dc->op2]();
937 gen_op_movl_T1_im(imm);
938 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
939 return 2;
940 }
941 static unsigned int dec_andq(DisasContext *dc)
942 {
943 uint32_t imm;
944 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
945 imm = sign_extend(dc->op1, 5);
946
947 DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
948 cris_cc_mask(dc, CC_MASK_NZ);
949 gen_movl_T0_reg[dc->op2]();
950 gen_op_movl_T1_im(imm);
951 crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
952 return 2;
953 }
954 static unsigned int dec_orq(DisasContext *dc)
955 {
956 uint32_t imm;
957 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
958 imm = sign_extend(dc->op1, 5);
959 DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
960 cris_cc_mask(dc, CC_MASK_NZ);
961 gen_movl_T0_reg[dc->op2]();
962 gen_op_movl_T1_im(imm);
963 crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
964 return 2;
965 }
966 static unsigned int dec_btstq(DisasContext *dc)
967 {
968 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
969 DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
970 cris_cc_mask(dc, CC_MASK_NZ);
971 gen_movl_T0_reg[dc->op2]();
972 gen_op_movl_T1_im(dc->op1);
973 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
974
975 cris_update_cc_op(dc, CC_OP_FLAGS);
976 gen_op_movl_flags_T0();
977 dc->flags_live = 1;
978 return 2;
979 }
980 static unsigned int dec_asrq(DisasContext *dc)
981 {
982 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
983 DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
984 cris_cc_mask(dc, CC_MASK_NZ);
985 gen_movl_T0_reg[dc->op2]();
986 gen_op_movl_T1_im(dc->op1);
987 crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
988 return 2;
989 }
990 static unsigned int dec_lslq(DisasContext *dc)
991 {
992 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
993 DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
994
995 cris_cc_mask(dc, CC_MASK_NZ);
996 gen_movl_T0_reg[dc->op2]();
997 gen_op_movl_T1_im(dc->op1);
998 crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
999 return 2;
1000 }
1001 static unsigned int dec_lsrq(DisasContext *dc)
1002 {
1003 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1004 DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1005
1006 cris_cc_mask(dc, CC_MASK_NZ);
1007 gen_movl_T0_reg[dc->op2]();
1008 gen_op_movl_T1_im(dc->op1);
1009 crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1010 return 2;
1011 }
1012
1013 static unsigned int dec_move_r(DisasContext *dc)
1014 {
1015 int size = memsize_zz(dc);
1016
1017 DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1018 memsize_char(size), dc->op1, dc->op2));
1019
1020 cris_cc_mask(dc, CC_MASK_NZ);
1021 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1022 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1023 return 2;
1024 }
1025
1026 static unsigned int dec_scc_r(DisasContext *dc)
1027 {
1028 int cond = dc->op2;
1029
1030 DIS(fprintf (logfile, "s%s $r%u\n",
1031 cc_name(cond), dc->op1));
1032
1033 if (cond != CC_A)
1034 {
1035 gen_tst_cc (dc, cond);
1036 gen_op_movl_T1_T0();
1037 }
1038 else
1039 gen_op_movl_T1_im(1);
1040
1041 cris_cc_mask(dc, 0);
1042 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1043 return 2;
1044 }
1045
1046 static unsigned int dec_and_r(DisasContext *dc)
1047 {
1048 int size = memsize_zz(dc);
1049
1050 DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1051 memsize_char(size), dc->op1, dc->op2));
1052 cris_cc_mask(dc, CC_MASK_NZ);
1053 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1054 crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1055 return 2;
1056 }
1057
1058 static unsigned int dec_lz_r(DisasContext *dc)
1059 {
1060 DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1061 dc->op1, dc->op2));
1062 cris_cc_mask(dc, CC_MASK_NZ);
1063 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1064 crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1065 return 2;
1066 }
1067
1068 static unsigned int dec_lsl_r(DisasContext *dc)
1069 {
1070 int size = memsize_zz(dc);
1071
1072 DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1073 memsize_char(size), dc->op1, dc->op2));
1074 cris_cc_mask(dc, CC_MASK_NZ);
1075 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1076 gen_op_andl_T1_im(63);
1077 crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1078 return 2;
1079 }
1080
1081 static unsigned int dec_lsr_r(DisasContext *dc)
1082 {
1083 int size = memsize_zz(dc);
1084
1085 DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1086 memsize_char(size), dc->op1, dc->op2));
1087 cris_cc_mask(dc, CC_MASK_NZ);
1088 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1089 gen_op_andl_T1_im(63);
1090 crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1091 return 2;
1092 }
1093
1094 static unsigned int dec_asr_r(DisasContext *dc)
1095 {
1096 int size = memsize_zz(dc);
1097
1098 DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1099 memsize_char(size), dc->op1, dc->op2));
1100 cris_cc_mask(dc, CC_MASK_NZ);
1101 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1102 gen_op_andl_T1_im(63);
1103 crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1104 return 2;
1105 }
1106
1107 static unsigned int dec_muls_r(DisasContext *dc)
1108 {
1109 int size = memsize_zz(dc);
1110
1111 DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1112 memsize_char(size), dc->op1, dc->op2));
1113 cris_cc_mask(dc, CC_MASK_NZV);
1114 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1115 gen_sext_T0_T0(size);
1116 crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1117 return 2;
1118 }
1119
1120 static unsigned int dec_mulu_r(DisasContext *dc)
1121 {
1122 int size = memsize_zz(dc);
1123
1124 DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1125 memsize_char(size), dc->op1, dc->op2));
1126 cris_cc_mask(dc, CC_MASK_NZV);
1127 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1128 gen_zext_T0_T0(size);
1129 crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1130 return 2;
1131 }
1132
1133
1134 static unsigned int dec_dstep_r(DisasContext *dc)
1135 {
1136 DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1137 cris_cc_mask(dc, CC_MASK_NZ);
1138 gen_movl_T0_reg[dc->op1]();
1139 gen_op_movl_T1_T0();
1140 gen_movl_T0_reg[dc->op2]();
1141 crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1142 return 2;
1143 }
1144
1145 static unsigned int dec_xor_r(DisasContext *dc)
1146 {
1147 int size = memsize_zz(dc);
1148 DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1149 memsize_char(size), dc->op1, dc->op2));
1150 BUG_ON(size != 4); /* xor is dword. */
1151 cris_cc_mask(dc, CC_MASK_NZ);
1152 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1153 crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1154 return 2;
1155 }
1156
1157 static unsigned int dec_bound_r(DisasContext *dc)
1158 {
1159 int size = memsize_zz(dc);
1160 DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1161 memsize_char(size), dc->op1, dc->op2));
1162 cris_cc_mask(dc, CC_MASK_NZ);
1163 /* TODO: needs optmimization. */
1164 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1165 /* rd should be 4. */
1166 gen_movl_T0_reg[dc->op2]();
1167 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1168 return 2;
1169 }
1170
1171 static unsigned int dec_cmp_r(DisasContext *dc)
1172 {
1173 int size = memsize_zz(dc);
1174 DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1175 memsize_char(size), dc->op1, dc->op2));
1176 cris_cc_mask(dc, CC_MASK_NZVC);
1177 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1178 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1179 return 2;
1180 }
1181
1182 static unsigned int dec_abs_r(DisasContext *dc)
1183 {
1184 DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1185 dc->op1, dc->op2));
1186 cris_cc_mask(dc, CC_MASK_NZ);
1187 dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1188 gen_op_absl_T1_T1();
1189 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1190 return 2;
1191 }
1192
1193 static unsigned int dec_add_r(DisasContext *dc)
1194 {
1195 int size = memsize_zz(dc);
1196 DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1197 memsize_char(size), dc->op1, dc->op2));
1198 cris_cc_mask(dc, CC_MASK_NZVC);
1199 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1200 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1201 return 2;
1202 }
1203
1204 static unsigned int dec_addc_r(DisasContext *dc)
1205 {
1206 DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1207 dc->op1, dc->op2));
1208 cris_evaluate_flags(dc);
1209 cris_cc_mask(dc, CC_MASK_NZVC);
1210 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1211 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1212 return 2;
1213 }
1214
1215 static unsigned int dec_mcp_r(DisasContext *dc)
1216 {
1217 DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1218 dc->op2, dc->op1));
1219 cris_evaluate_flags(dc);
1220 cris_cc_mask(dc, CC_MASK_RNZV);
1221 gen_movl_T0_preg[dc->op2]();
1222 gen_op_movl_T1_T0();
1223 gen_movl_T0_reg[dc->op1]();
1224 crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1225 return 2;
1226 }
1227
1228 #if DISAS_CRIS
1229 static char * swapmode_name(int mode, char *modename) {
1230 int i = 0;
1231 if (mode & 8)
1232 modename[i++] = 'n';
1233 if (mode & 4)
1234 modename[i++] = 'w';
1235 if (mode & 2)
1236 modename[i++] = 'b';
1237 if (mode & 1)
1238 modename[i++] = 'r';
1239 modename[i++] = 0;
1240 return modename;
1241 }
1242 #endif
1243
1244 static unsigned int dec_swap_r(DisasContext *dc)
1245 {
1246 DIS(char modename[4]);
1247 DIS(fprintf (logfile, "swap%s $r%u\n",
1248 swapmode_name(dc->op2, modename), dc->op1));
1249
1250 cris_cc_mask(dc, CC_MASK_NZ);
1251 gen_movl_T0_reg[dc->op1]();
1252 if (dc->op2 & 8)
1253 gen_op_not_T0_T0();
1254 if (dc->op2 & 4)
1255 gen_op_swapw_T0_T0();
1256 if (dc->op2 & 2)
1257 gen_op_swapb_T0_T0();
1258 if (dc->op2 & 1)
1259 gen_op_swapr_T0_T0();
1260 gen_op_movl_T1_T0();
1261 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1262 return 2;
1263 }
1264
1265 static unsigned int dec_or_r(DisasContext *dc)
1266 {
1267 int size = memsize_zz(dc);
1268 DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1269 memsize_char(size), dc->op1, dc->op2));
1270 cris_cc_mask(dc, CC_MASK_NZ);
1271 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1272 crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1273 return 2;
1274 }
1275
1276 static unsigned int dec_addi_r(DisasContext *dc)
1277 {
1278 DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1279 memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1280 cris_cc_mask(dc, 0);
1281 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1282 gen_op_lsll_T0_im(dc->zzsize);
1283 gen_op_addl_T0_T1();
1284 gen_movl_reg_T0[dc->op1]();
1285 return 2;
1286 }
1287
1288 static unsigned int dec_addi_acr(DisasContext *dc)
1289 {
1290 DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1291 memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1292 cris_cc_mask(dc, 0);
1293 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1294 gen_op_lsll_T0_im(dc->zzsize);
1295 gen_op_addl_T0_T1();
1296 gen_movl_reg_T0[REG_ACR]();
1297 return 2;
1298 }
1299
1300 static unsigned int dec_neg_r(DisasContext *dc)
1301 {
1302 int size = memsize_zz(dc);
1303 DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1304 memsize_char(size), dc->op1, dc->op2));
1305 cris_cc_mask(dc, CC_MASK_NZVC);
1306 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1307 crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1308 return 2;
1309 }
1310
1311 static unsigned int dec_btst_r(DisasContext *dc)
1312 {
1313 DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1314 dc->op1, dc->op2));
1315 cris_cc_mask(dc, CC_MASK_NZ);
1316 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1317 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1318
1319 cris_update_cc_op(dc, CC_OP_FLAGS);
1320 gen_op_movl_flags_T0();
1321 dc->flags_live = 1;
1322 return 2;
1323 }
1324
1325 static unsigned int dec_sub_r(DisasContext *dc)
1326 {
1327 int size = memsize_zz(dc);
1328 DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1329 memsize_char(size), dc->op1, dc->op2));
1330 cris_cc_mask(dc, CC_MASK_NZVC);
1331 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1332 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1333 return 2;
1334 }
1335
1336 /* Zero extension. From size to dword. */
1337 static unsigned int dec_movu_r(DisasContext *dc)
1338 {
1339 int size = memsize_z(dc);
1340 DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1341 memsize_char(size),
1342 dc->op1, dc->op2));
1343
1344 cris_cc_mask(dc, CC_MASK_NZ);
1345 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1346 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1347 return 2;
1348 }
1349
1350 /* Sign extension. From size to dword. */
1351 static unsigned int dec_movs_r(DisasContext *dc)
1352 {
1353 int size = memsize_z(dc);
1354 DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1355 memsize_char(size),
1356 dc->op1, dc->op2));
1357
1358 cris_cc_mask(dc, CC_MASK_NZ);
1359 gen_movl_T0_reg[dc->op1]();
1360 /* Size can only be qi or hi. */
1361 gen_sext_T1_T0(size);
1362 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1363 return 2;
1364 }
1365
1366 /* zero extension. From size to dword. */
1367 static unsigned int dec_addu_r(DisasContext *dc)
1368 {
1369 int size = memsize_z(dc);
1370 DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1371 memsize_char(size),
1372 dc->op1, dc->op2));
1373
1374 cris_cc_mask(dc, CC_MASK_NZVC);
1375 gen_movl_T0_reg[dc->op1]();
1376 /* Size can only be qi or hi. */
1377 gen_zext_T1_T0(size);
1378 gen_movl_T0_reg[dc->op2]();
1379 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1380 return 2;
1381 }
1382 /* Sign extension. From size to dword. */
1383 static unsigned int dec_adds_r(DisasContext *dc)
1384 {
1385 int size = memsize_z(dc);
1386 DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1387 memsize_char(size),
1388 dc->op1, dc->op2));
1389
1390 cris_cc_mask(dc, CC_MASK_NZVC);
1391 gen_movl_T0_reg[dc->op1]();
1392 /* Size can only be qi or hi. */
1393 gen_sext_T1_T0(size);
1394 gen_movl_T0_reg[dc->op2]();
1395 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1396 return 2;
1397 }
1398
1399 /* Zero extension. From size to dword. */
1400 static unsigned int dec_subu_r(DisasContext *dc)
1401 {
1402 int size = memsize_z(dc);
1403 DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1404 memsize_char(size),
1405 dc->op1, dc->op2));
1406
1407 cris_cc_mask(dc, CC_MASK_NZVC);
1408 gen_movl_T0_reg[dc->op1]();
1409 /* Size can only be qi or hi. */
1410 gen_zext_T1_T0(size);
1411 gen_movl_T0_reg[dc->op2]();
1412 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1413 return 2;
1414 }
1415
1416 /* Sign extension. From size to dword. */
1417 static unsigned int dec_subs_r(DisasContext *dc)
1418 {
1419 int size = memsize_z(dc);
1420 DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1421 memsize_char(size),
1422 dc->op1, dc->op2));
1423
1424 cris_cc_mask(dc, CC_MASK_NZVC);
1425 gen_movl_T0_reg[dc->op1]();
1426 /* Size can only be qi or hi. */
1427 gen_sext_T1_T0(size);
1428 gen_movl_T0_reg[dc->op2]();
1429 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1430 return 2;
1431 }
1432
1433 static unsigned int dec_setclrf(DisasContext *dc)
1434 {
1435 uint32_t flags;
1436 int set = (~dc->opcode >> 2) & 1;
1437
1438 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1439 | EXTRACT_FIELD(dc->ir, 0, 3);
1440 DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1441 if (set && flags == 0)
1442 DIS(fprintf (logfile, "nop\n"));
1443 else if (!set && (flags & 0x20))
1444 DIS(fprintf (logfile, "di\n"));
1445 else
1446 DIS(fprintf (logfile, "%sf %x\n",
1447 set ? "set" : "clr",
1448 flags));
1449
1450 if (set && (flags & X_FLAG)) {
1451 dc->flagx_live = 1;
1452 dc->flags_x = 1;
1453 }
1454
1455 /* Simply decode the flags. */
1456 cris_evaluate_flags (dc);
1457 cris_update_cc_op(dc, CC_OP_FLAGS);
1458 if (set)
1459 gen_op_setf (flags);
1460 else
1461 gen_op_clrf (flags);
1462 dc->flags_live = 1;
1463 return 2;
1464 }
1465
1466 static unsigned int dec_move_rs(DisasContext *dc)
1467 {
1468 DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1469 cris_cc_mask(dc, 0);
1470 gen_movl_T0_reg[dc->op1]();
1471 gen_op_movl_sreg_T0(dc->op2);
1472
1473 if (dc->op2 == 5) /* srs is checked at runtime. */
1474 gen_op_movl_tlb_lo_T0();
1475 return 2;
1476 }
1477 static unsigned int dec_move_sr(DisasContext *dc)
1478 {
1479 DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op1, dc->op2));
1480 cris_cc_mask(dc, 0);
1481 gen_op_movl_T0_sreg(dc->op1);
1482 gen_op_movl_T1_T0();
1483 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1484 return 2;
1485 }
1486 static unsigned int dec_move_rp(DisasContext *dc)
1487 {
1488 DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1489 cris_cc_mask(dc, 0);
1490 gen_movl_T0_reg[dc->op1]();
1491 gen_op_movl_T1_T0();
1492 gen_movl_preg_T0[dc->op2]();
1493 return 2;
1494 }
1495 static unsigned int dec_move_pr(DisasContext *dc)
1496 {
1497 DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1498 cris_cc_mask(dc, 0);
1499 /* Support register 0 is hardwired to zero.
1500 Treat it specially. */
1501 if (dc->op2 == 0)
1502 gen_op_movl_T1_im(0);
1503 else {
1504 gen_movl_T0_preg[dc->op2]();
1505 gen_op_movl_T1_T0();
1506 }
1507 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1508 return 2;
1509 }
1510
1511 static unsigned int dec_move_mr(DisasContext *dc)
1512 {
1513 int memsize = memsize_zz(dc);
1514 int insn_len;
1515 DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1516 memsize_char(memsize),
1517 dc->op1, dc->postinc ? "+]" : "]",
1518 dc->op2));
1519
1520 cris_cc_mask(dc, CC_MASK_NZ);
1521 insn_len = dec_prep_alu_m(dc, 0, memsize);
1522 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1523 do_postinc(dc, memsize);
1524 return insn_len;
1525 }
1526
1527 static unsigned int dec_movs_m(DisasContext *dc)
1528 {
1529 int memsize = memsize_z(dc);
1530 int insn_len;
1531 DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1532 memsize_char(memsize),
1533 dc->op1, dc->postinc ? "+]" : "]",
1534 dc->op2));
1535
1536 /* sign extend. */
1537 cris_cc_mask(dc, CC_MASK_NZ);
1538 insn_len = dec_prep_alu_m(dc, 1, memsize);
1539 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1540 do_postinc(dc, memsize);
1541 return insn_len;
1542 }
1543
1544 static unsigned int dec_addu_m(DisasContext *dc)
1545 {
1546 int memsize = memsize_z(dc);
1547 int insn_len;
1548 DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1549 memsize_char(memsize),
1550 dc->op1, dc->postinc ? "+]" : "]",
1551 dc->op2));
1552
1553 /* sign extend. */
1554 cris_cc_mask(dc, CC_MASK_NZVC);
1555 insn_len = dec_prep_alu_m(dc, 0, memsize);
1556 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1557 do_postinc(dc, memsize);
1558 return insn_len;
1559 }
1560
1561 static unsigned int dec_adds_m(DisasContext *dc)
1562 {
1563 int memsize = memsize_z(dc);
1564 int insn_len;
1565 DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1566 memsize_char(memsize),
1567 dc->op1, dc->postinc ? "+]" : "]",
1568 dc->op2));
1569
1570 /* sign extend. */
1571 cris_cc_mask(dc, CC_MASK_NZVC);
1572 insn_len = dec_prep_alu_m(dc, 1, memsize);
1573 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1574 do_postinc(dc, memsize);
1575 return insn_len;
1576 }
1577
1578 static unsigned int dec_subu_m(DisasContext *dc)
1579 {
1580 int memsize = memsize_z(dc);
1581 int insn_len;
1582 DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1583 memsize_char(memsize),
1584 dc->op1, dc->postinc ? "+]" : "]",
1585 dc->op2));
1586
1587 /* sign extend. */
1588 cris_cc_mask(dc, CC_MASK_NZVC);
1589 insn_len = dec_prep_alu_m(dc, 0, memsize);
1590 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1591 do_postinc(dc, memsize);
1592 return insn_len;
1593 }
1594
1595 static unsigned int dec_subs_m(DisasContext *dc)
1596 {
1597 int memsize = memsize_z(dc);
1598 int insn_len;
1599 DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1600 memsize_char(memsize),
1601 dc->op1, dc->postinc ? "+]" : "]",
1602 dc->op2));
1603
1604 /* sign extend. */
1605 cris_cc_mask(dc, CC_MASK_NZVC);
1606 insn_len = dec_prep_alu_m(dc, 1, memsize);
1607 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1608 do_postinc(dc, memsize);
1609 return insn_len;
1610 }
1611
1612 static unsigned int dec_movu_m(DisasContext *dc)
1613 {
1614 int memsize = memsize_z(dc);
1615 int insn_len;
1616
1617 DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1618 memsize_char(memsize),
1619 dc->op1, dc->postinc ? "+]" : "]",
1620 dc->op2));
1621
1622 cris_cc_mask(dc, CC_MASK_NZ);
1623 insn_len = dec_prep_alu_m(dc, 0, memsize);
1624 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1625 do_postinc(dc, memsize);
1626 return insn_len;
1627 }
1628
1629 static unsigned int dec_cmpu_m(DisasContext *dc)
1630 {
1631 int memsize = memsize_z(dc);
1632 int insn_len;
1633 DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1634 memsize_char(memsize),
1635 dc->op1, dc->postinc ? "+]" : "]",
1636 dc->op2));
1637
1638 cris_cc_mask(dc, CC_MASK_NZVC);
1639 insn_len = dec_prep_alu_m(dc, 0, memsize);
1640 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1641 do_postinc(dc, memsize);
1642 return insn_len;
1643 }
1644
1645 static unsigned int dec_cmps_m(DisasContext *dc)
1646 {
1647 int memsize = memsize_z(dc);
1648 int insn_len;
1649 DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1650 memsize_char(memsize),
1651 dc->op1, dc->postinc ? "+]" : "]",
1652 dc->op2));
1653
1654 cris_cc_mask(dc, CC_MASK_NZVC);
1655 insn_len = dec_prep_alu_m(dc, 1, memsize);
1656 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1657 do_postinc(dc, memsize);
1658 return insn_len;
1659 }
1660
1661 static unsigned int dec_cmp_m(DisasContext *dc)
1662 {
1663 int memsize = memsize_zz(dc);
1664 int insn_len;
1665 DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1666 memsize_char(memsize),
1667 dc->op1, dc->postinc ? "+]" : "]",
1668 dc->op2));
1669
1670 cris_cc_mask(dc, CC_MASK_NZVC);
1671 insn_len = dec_prep_alu_m(dc, 0, memsize);
1672 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1673 do_postinc(dc, memsize);
1674 return insn_len;
1675 }
1676
1677 static unsigned int dec_test_m(DisasContext *dc)
1678 {
1679 int memsize = memsize_zz(dc);
1680 int insn_len;
1681 DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1682 memsize_char(memsize),
1683 dc->op1, dc->postinc ? "+]" : "]",
1684 dc->op2));
1685
1686 cris_cc_mask(dc, CC_MASK_NZ);
1687 gen_op_clrf(3);
1688 insn_len = dec_prep_alu_m(dc, 0, memsize);
1689 gen_op_swp_T0_T1();
1690 gen_op_movl_T1_im(0);
1691 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1692 do_postinc(dc, memsize);
1693 return insn_len;
1694 }
1695
1696 static unsigned int dec_and_m(DisasContext *dc)
1697 {
1698 int memsize = memsize_zz(dc);
1699 int insn_len;
1700 DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1701 memsize_char(memsize),
1702 dc->op1, dc->postinc ? "+]" : "]",
1703 dc->op2));
1704
1705 cris_cc_mask(dc, CC_MASK_NZ);
1706 insn_len = dec_prep_alu_m(dc, 0, memsize);
1707 crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1708 do_postinc(dc, memsize);
1709 return insn_len;
1710 }
1711
1712 static unsigned int dec_add_m(DisasContext *dc)
1713 {
1714 int memsize = memsize_zz(dc);
1715 int insn_len;
1716 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1717 memsize_char(memsize),
1718 dc->op1, dc->postinc ? "+]" : "]",
1719 dc->op2));
1720
1721 cris_cc_mask(dc, CC_MASK_NZVC);
1722 insn_len = dec_prep_alu_m(dc, 0, memsize);
1723 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1724 do_postinc(dc, memsize);
1725 return insn_len;
1726 }
1727
1728 static unsigned int dec_addo_m(DisasContext *dc)
1729 {
1730 int memsize = memsize_zz(dc);
1731 int insn_len;
1732 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1733 memsize_char(memsize),
1734 dc->op1, dc->postinc ? "+]" : "]",
1735 dc->op2));
1736
1737 cris_cc_mask(dc, 0);
1738 insn_len = dec_prep_alu_m(dc, 1, memsize);
1739 crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
1740 do_postinc(dc, memsize);
1741 return insn_len;
1742 }
1743
1744 static unsigned int dec_bound_m(DisasContext *dc)
1745 {
1746 int memsize = memsize_zz(dc);
1747 int insn_len;
1748 DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1749 memsize_char(memsize),
1750 dc->op1, dc->postinc ? "+]" : "]",
1751 dc->op2));
1752
1753 cris_cc_mask(dc, CC_MASK_NZ);
1754 insn_len = dec_prep_alu_m(dc, 0, memsize);
1755 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1756 do_postinc(dc, memsize);
1757 return insn_len;
1758 }
1759
1760 static unsigned int dec_addc_mr(DisasContext *dc)
1761 {
1762 int insn_len = 2;
1763 DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1764 dc->op1, dc->postinc ? "+]" : "]",
1765 dc->op2));
1766
1767 cris_evaluate_flags(dc);
1768 cris_cc_mask(dc, CC_MASK_NZVC);
1769 insn_len = dec_prep_alu_m(dc, 0, 4);
1770 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1771 do_postinc(dc, 4);
1772 return insn_len;
1773 }
1774
1775 static unsigned int dec_sub_m(DisasContext *dc)
1776 {
1777 int memsize = memsize_zz(dc);
1778 int insn_len;
1779 DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1780 memsize_char(memsize),
1781 dc->op1, dc->postinc ? "+]" : "]",
1782 dc->op2, dc->ir, dc->zzsize));
1783
1784 cris_cc_mask(dc, CC_MASK_NZVC);
1785 insn_len = dec_prep_alu_m(dc, 0, memsize);
1786 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1787 do_postinc(dc, memsize);
1788 return insn_len;
1789 }
1790
1791 static unsigned int dec_or_m(DisasContext *dc)
1792 {
1793 int memsize = memsize_zz(dc);
1794 int insn_len;
1795 DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1796 memsize_char(memsize),
1797 dc->op1, dc->postinc ? "+]" : "]",
1798 dc->op2, dc->pc));
1799
1800 cris_cc_mask(dc, CC_MASK_NZ);
1801 insn_len = dec_prep_alu_m(dc, 0, memsize);
1802 crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1803 do_postinc(dc, memsize);
1804 return insn_len;
1805 }
1806
1807 static unsigned int dec_move_mp(DisasContext *dc)
1808 {
1809 int memsize = memsize_zz(dc);
1810 int insn_len = 2;
1811
1812 DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1813 memsize_char(memsize),
1814 dc->op1,
1815 dc->postinc ? "+]" : "]",
1816 dc->op2));
1817
1818 cris_cc_mask(dc, 0);
1819 insn_len = dec_prep_alu_m(dc, 0, memsize);
1820 gen_op_movl_T0_T1();
1821 gen_movl_preg_T0[dc->op2]();
1822
1823 do_postinc(dc, memsize);
1824 return insn_len;
1825 }
1826
1827 static unsigned int dec_move_pm(DisasContext *dc)
1828 {
1829 int memsize;
1830
1831 memsize = preg_sizes[dc->op2];
1832
1833 DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
1834 memsize_char(memsize),
1835 dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
1836
1837 cris_cc_mask(dc, 0);
1838 /* prepare store. Address in T0, value in T1. */
1839 /* Support register 0 is hardwired to zero.
1840 Treat it specially. */
1841 if (dc->op2 == 0)
1842 gen_op_movl_T1_im(0);
1843 else
1844 {
1845 gen_movl_T0_preg[dc->op2]();
1846 gen_op_movl_T1_T0();
1847 }
1848 gen_movl_T0_reg[dc->op1]();
1849 gen_store_T0_T1(dc, memsize);
1850 if (dc->postinc)
1851 {
1852 gen_op_addl_T0_im(memsize);
1853 gen_movl_reg_T0[dc->op1]();
1854 }
1855 return 2;
1856 }
1857
1858 static unsigned int dec_movem_mr(DisasContext *dc)
1859 {
1860 int i;
1861
1862 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
1863 dc->postinc ? "+]" : "]", dc->op2));
1864
1865 cris_cc_mask(dc, 0);
1866 /* fetch the address into T1. */
1867 gen_movl_T0_reg[dc->op1]();
1868 gen_op_movl_T1_T0();
1869 for (i = 0; i <= dc->op2; i++) {
1870 /* Perform the load onto regnum i. Always dword wide. */
1871 gen_load_T0_T0(dc, 4, 0);
1872 gen_movl_reg_T0[i]();
1873 /* Update the address. */
1874 gen_op_addl_T1_im(4);
1875 gen_op_movl_T0_T1();
1876 }
1877 if (dc->postinc) {
1878 /* writeback the updated pointer value. */
1879 gen_movl_reg_T0[dc->op1]();
1880 }
1881 return 2;
1882 }
1883
1884 static unsigned int dec_movem_rm(DisasContext *dc)
1885 {
1886 int i;
1887
1888 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
1889 dc->postinc ? "+]" : "]"));
1890
1891 cris_cc_mask(dc, 0);
1892 for (i = 0; i <= dc->op2; i++) {
1893 /* Fetch register i into T1. */
1894 gen_movl_T0_reg[i]();
1895 gen_op_movl_T1_T0();
1896
1897 /* Fetch the address into T0. */
1898 gen_movl_T0_reg[dc->op1]();
1899 /* Displace it. */
1900 gen_op_addl_T0_im(i * 4);
1901
1902 /* Perform the store. */
1903 gen_store_T0_T1(dc, 4);
1904 }
1905 if (dc->postinc) {
1906 /* Update the address. */
1907 gen_op_addl_T0_im(4);
1908 /* writeback the updated pointer value. */
1909 gen_movl_reg_T0[dc->op1]();
1910 }
1911 return 2;
1912 }
1913
1914 static unsigned int dec_move_rm(DisasContext *dc)
1915 {
1916 int memsize;
1917
1918 memsize = memsize_zz(dc);
1919
1920 DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
1921 memsize, dc->op2, dc->op1));
1922
1923 cris_cc_mask(dc, 0);
1924 /* prepare store. */
1925 gen_movl_T0_reg[dc->op2]();
1926 gen_op_movl_T1_T0();
1927 gen_movl_T0_reg[dc->op1]();
1928 gen_store_T0_T1(dc, memsize);
1929 if (dc->postinc)
1930 {
1931 gen_op_addl_T0_im(memsize);
1932 gen_movl_reg_T0[dc->op1]();
1933 }
1934 return 2;
1935 }
1936
1937
1938 static unsigned int dec_lapcq(DisasContext *dc)
1939 {
1940 DIS(fprintf (logfile, "lapcq %x, $r%u\n",
1941 dc->pc + dc->op1*2, dc->op2));
1942 cris_cc_mask(dc, 0);
1943 gen_op_movl_T1_im(dc->pc + dc->op1*2);
1944 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1945 return 2;
1946 }
1947
1948 static unsigned int dec_lapc_im(DisasContext *dc)
1949 {
1950 unsigned int rd;
1951 int32_t imm;
1952 int insn_len = 6;
1953
1954 rd = dc->op2;
1955
1956 cris_cc_mask(dc, 0);
1957 imm = ldl_code(dc->pc + 2);
1958 DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
1959 gen_op_movl_T0_im (dc->pc + imm);
1960 gen_movl_reg_T0[rd] ();
1961 return insn_len;
1962 }
1963
1964 /* Jump to special reg. */
1965 static unsigned int dec_jump_p(DisasContext *dc)
1966 {
1967 DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
1968 cris_cc_mask(dc, 0);
1969 /* Store the return address in Pd. */
1970 gen_movl_T0_preg[dc->op2]();
1971 gen_op_movl_btarget_T0();
1972 cris_prepare_dyn_jmp(dc);
1973 return 2;
1974 }
1975
1976 /* Jump and save. */
1977 static unsigned int dec_jas_r(DisasContext *dc)
1978 {
1979 DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
1980 cris_cc_mask(dc, 0);
1981 /* Stor the return address in Pd. */
1982 gen_movl_T0_reg[dc->op1]();
1983 gen_op_movl_btarget_T0();
1984 gen_op_movl_T0_im(dc->pc + 4);
1985 gen_movl_preg_T0[dc->op2]();
1986 cris_prepare_dyn_jmp(dc);
1987 return 2;
1988 }
1989
1990 static unsigned int dec_jas_im(DisasContext *dc)
1991 {
1992 uint32_t imm;
1993
1994 imm = ldl_code(dc->pc + 2);
1995
1996 DIS(fprintf (logfile, "jas 0x%x\n", imm));
1997 cris_cc_mask(dc, 0);
1998 /* Stor the return address in Pd. */
1999 gen_op_movl_T0_im(imm);
2000 gen_op_movl_btarget_T0();
2001 gen_op_movl_T0_im(dc->pc + 8);
2002 gen_movl_preg_T0[dc->op2]();
2003 cris_prepare_dyn_jmp(dc);
2004 return 6;
2005 }
2006
2007 static unsigned int dec_jasc_im(DisasContext *dc)
2008 {
2009 uint32_t imm;
2010
2011 imm = ldl_code(dc->pc + 2);
2012
2013 DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2014 cris_cc_mask(dc, 0);
2015 /* Stor the return address in Pd. */
2016 gen_op_movl_T0_im(imm);
2017 gen_op_movl_btarget_T0();
2018 gen_op_movl_T0_im(dc->pc + 8 + 4);
2019 gen_movl_preg_T0[dc->op2]();
2020 cris_prepare_dyn_jmp(dc);
2021 return 6;
2022 }
2023
2024 static unsigned int dec_jasc_r(DisasContext *dc)
2025 {
2026 DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2027 cris_cc_mask(dc, 0);
2028 /* Stor the return address in Pd. */
2029 gen_movl_T0_reg[dc->op1]();
2030 gen_op_movl_btarget_T0();
2031 gen_op_movl_T0_im(dc->pc + 4 + 4);
2032 gen_movl_preg_T0[dc->op2]();
2033 cris_prepare_dyn_jmp(dc);
2034 return 2;
2035 }
2036
2037 static unsigned int dec_bcc_im(DisasContext *dc)
2038 {
2039 int32_t offset;
2040 uint32_t cond = dc->op2;
2041
2042 offset = ldl_code(dc->pc + 2);
2043 offset = sign_extend(offset, 15);
2044
2045 DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2046 cc_name(cond), offset,
2047 dc->pc, dc->pc + offset));
2048
2049 cris_cc_mask(dc, 0);
2050 /* op2 holds the condition-code. */
2051 cris_prepare_cc_branch (dc, offset, cond);
2052 return 4;
2053 }
2054
2055 static unsigned int dec_bas_im(DisasContext *dc)
2056 {
2057 int32_t simm;
2058
2059
2060 simm = ldl_code(dc->pc + 2);
2061
2062 DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2063 cris_cc_mask(dc, 0);
2064 /* Stor the return address in Pd. */
2065 gen_op_movl_T0_im(dc->pc + simm);
2066 gen_op_movl_btarget_T0();
2067 gen_op_movl_T0_im(dc->pc + 8);
2068 gen_movl_preg_T0[dc->op2]();
2069 cris_prepare_dyn_jmp(dc);
2070 return 6;
2071 }
2072
2073 static unsigned int dec_basc_im(DisasContext *dc)
2074 {
2075 int32_t simm;
2076 simm = ldl_code(dc->pc + 2);
2077
2078 DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2079 cris_cc_mask(dc, 0);
2080 /* Stor the return address in Pd. */
2081 gen_op_movl_T0_im(dc->pc + simm);
2082 gen_op_movl_btarget_T0();
2083 gen_op_movl_T0_im(dc->pc + 12);
2084 gen_movl_preg_T0[dc->op2]();
2085 cris_prepare_dyn_jmp(dc);
2086 return 6;
2087 }
2088
2089 static unsigned int dec_rfe_etc(DisasContext *dc)
2090 {
2091 DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2092 dc->opcode, dc->pc, dc->op1, dc->op2));
2093
2094 cris_cc_mask(dc, 0);
2095
2096 if (dc->op2 == 15) /* ignore halt. */
2097 goto done;
2098
2099 switch (dc->op2 & 7) {
2100 case 2:
2101 /* rfe. */
2102 cris_evaluate_flags(dc);
2103 gen_op_ccs_rshift();
2104 break;
2105 case 5:
2106 /* rfn. */
2107 BUG();
2108 break;
2109 case 6:
2110 /* break. */
2111 gen_op_movl_T0_im(dc->pc);
2112 gen_op_movl_pc_T0();
2113 /* Breaks start at 16 in the exception vector. */
2114 gen_op_break_im(dc->op1 + 16);
2115 break;
2116 default:
2117 printf ("op2=%x\n", dc->op2);
2118 BUG();
2119 break;
2120
2121 }
2122 done:
2123 return 2;
2124 }
2125
2126 static unsigned int dec_null(DisasContext *dc)
2127 {
2128 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2129 dc->pc, dc->opcode, dc->op1, dc->op2);
2130 fflush(NULL);
2131 BUG();
2132 return 2;
2133 }
2134
2135 struct decoder_info {
2136 struct {
2137 uint32_t bits;
2138 uint32_t mask;
2139 };
2140 unsigned int (*dec)(DisasContext *dc);
2141 } decinfo[] = {
2142 /* Order matters here. */
2143 {DEC_MOVEQ, dec_moveq},
2144 {DEC_BTSTQ, dec_btstq},
2145 {DEC_CMPQ, dec_cmpq},
2146 {DEC_ADDOQ, dec_addoq},
2147 {DEC_ADDQ, dec_addq},
2148 {DEC_SUBQ, dec_subq},
2149 {DEC_ANDQ, dec_andq},
2150 {DEC_ORQ, dec_orq},
2151 {DEC_ASRQ, dec_asrq},
2152 {DEC_LSLQ, dec_lslq},
2153 {DEC_LSRQ, dec_lsrq},
2154 {DEC_BCCQ, dec_bccq},
2155
2156 {DEC_BCC_IM, dec_bcc_im},
2157 {DEC_JAS_IM, dec_jas_im},
2158 {DEC_JAS_R, dec_jas_r},
2159 {DEC_JASC_IM, dec_jasc_im},
2160 {DEC_JASC_R, dec_jasc_r},
2161 {DEC_BAS_IM, dec_bas_im},
2162 {DEC_BASC_IM, dec_basc_im},
2163 {DEC_JUMP_P, dec_jump_p},
2164 {DEC_LAPC_IM, dec_lapc_im},
2165 {DEC_LAPCQ, dec_lapcq},
2166
2167 {DEC_RFE_ETC, dec_rfe_etc},
2168 {DEC_ADDC_MR, dec_addc_mr},
2169
2170 {DEC_MOVE_MP, dec_move_mp},
2171 {DEC_MOVE_PM, dec_move_pm},
2172 {DEC_MOVEM_MR, dec_movem_mr},
2173 {DEC_MOVEM_RM, dec_movem_rm},
2174 {DEC_MOVE_PR, dec_move_pr},
2175 {DEC_SCC_R, dec_scc_r},
2176 {DEC_SETF, dec_setclrf},
2177 {DEC_CLEARF, dec_setclrf},
2178
2179 {DEC_MOVE_SR, dec_move_sr},
2180 {DEC_MOVE_RP, dec_move_rp},
2181 {DEC_SWAP_R, dec_swap_r},
2182 {DEC_ABS_R, dec_abs_r},
2183 {DEC_LZ_R, dec_lz_r},
2184 {DEC_MOVE_RS, dec_move_rs},
2185 {DEC_BTST_R, dec_btst_r},
2186 {DEC_ADDC_R, dec_addc_r},
2187
2188 {DEC_DSTEP_R, dec_dstep_r},
2189 {DEC_XOR_R, dec_xor_r},
2190 {DEC_MCP_R, dec_mcp_r},
2191 {DEC_CMP_R, dec_cmp_r},
2192
2193 {DEC_ADDI_R, dec_addi_r},
2194 {DEC_ADDI_ACR, dec_addi_acr},
2195
2196 {DEC_ADD_R, dec_add_r},
2197 {DEC_SUB_R, dec_sub_r},
2198
2199 {DEC_ADDU_R, dec_addu_r},
2200 {DEC_ADDS_R, dec_adds_r},
2201 {DEC_SUBU_R, dec_subu_r},
2202 {DEC_SUBS_R, dec_subs_r},
2203 {DEC_LSL_R, dec_lsl_r},
2204
2205 {DEC_AND_R, dec_and_r},
2206 {DEC_OR_R, dec_or_r},
2207 {DEC_BOUND_R, dec_bound_r},
2208 {DEC_ASR_R, dec_asr_r},
2209 {DEC_LSR_R, dec_lsr_r},
2210
2211 {DEC_MOVU_R, dec_movu_r},
2212 {DEC_MOVS_R, dec_movs_r},
2213 {DEC_NEG_R, dec_neg_r},
2214 {DEC_MOVE_R, dec_move_r},
2215
2216 /* ftag_fidx_i_m. */
2217 /* ftag_fidx_d_m. */
2218
2219 {DEC_MULS_R, dec_muls_r},
2220 {DEC_MULU_R, dec_mulu_r},
2221
2222 {DEC_ADDU_M, dec_addu_m},
2223 {DEC_ADDS_M, dec_adds_m},
2224 {DEC_SUBU_M, dec_subu_m},
2225 {DEC_SUBS_M, dec_subs_m},
2226
2227 {DEC_CMPU_M, dec_cmpu_m},
2228 {DEC_CMPS_M, dec_cmps_m},
2229 {DEC_MOVU_M, dec_movu_m},
2230 {DEC_MOVS_M, dec_movs_m},
2231
2232 {DEC_CMP_M, dec_cmp_m},
2233 {DEC_ADDO_M, dec_addo_m},
2234 {DEC_BOUND_M, dec_bound_m},
2235 {DEC_ADD_M, dec_add_m},
2236 {DEC_SUB_M, dec_sub_m},
2237 {DEC_AND_M, dec_and_m},
2238 {DEC_OR_M, dec_or_m},
2239 {DEC_MOVE_RM, dec_move_rm},
2240 {DEC_TEST_M, dec_test_m},
2241 {DEC_MOVE_MR, dec_move_mr},
2242
2243 {{0, 0}, dec_null}
2244 };
2245
2246 static inline unsigned int
2247 cris_decoder(DisasContext *dc)
2248 {
2249 unsigned int insn_len = 2;
2250 uint32_t tmp;
2251 int i;
2252
2253 /* Load a halfword onto the instruction register. */
2254 tmp = ldl_code(dc->pc);
2255 dc->ir = tmp & 0xffff;
2256
2257 /* Now decode it. */
2258 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
2259 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
2260 dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
2261 dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
2262 dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
2263 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
2264
2265 /* Large switch for all insns. */
2266 for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2267 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2268 {
2269 insn_len = decinfo[i].dec(dc);
2270 break;
2271 }
2272 }
2273
2274 return insn_len;
2275 }
2276
2277 static void check_breakpoint(CPUState *env, DisasContext *dc)
2278 {
2279 int j;
2280 if (env->nb_breakpoints > 0) {
2281 for(j = 0; j < env->nb_breakpoints; j++) {
2282 if (env->breakpoints[j] == dc->pc) {
2283 cris_evaluate_flags (dc);
2284 gen_op_movl_T0_im((long)dc->pc);
2285 gen_op_movl_pc_T0();
2286 gen_op_debug();
2287 dc->is_jmp = DISAS_UPDATE;
2288 }
2289 }
2290 }
2291 }
2292
2293
2294 /* generate intermediate code for basic block 'tb'. */
2295 struct DisasContext ctx;
2296 static int
2297 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2298 int search_pc)
2299 {
2300 uint16_t *gen_opc_end;
2301 uint32_t pc_start;
2302 unsigned int insn_len;
2303 int j, lj;
2304 struct DisasContext *dc = &ctx;
2305 uint32_t next_page_start;
2306
2307 pc_start = tb->pc;
2308 dc->env = env;
2309 dc->tb = tb;
2310
2311 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2312
2313 dc->is_jmp = DISAS_NEXT;
2314 dc->pc = pc_start;
2315 dc->singlestep_enabled = env->singlestep_enabled;
2316 dc->flagx_live = 0;
2317 dc->flags_x = 0;
2318 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2319 lj = -1;
2320 do
2321 {
2322 check_breakpoint(env, dc);
2323 if (dc->is_jmp == DISAS_JUMP)
2324 goto done;
2325
2326 if (search_pc) {
2327 j = gen_opc_ptr - gen_opc_buf;
2328 if (lj < j) {
2329 lj++;
2330 while (lj < j)
2331 gen_opc_instr_start[lj++] = 0;
2332 }
2333 gen_opc_pc[lj] = dc->pc;
2334 gen_opc_instr_start[lj] = 1;
2335 }
2336
2337 insn_len = cris_decoder(dc);
2338 STATS(gen_op_exec_insn());
2339 dc->pc += insn_len;
2340 if (!dc->flagx_live
2341 || (dc->flagx_live &&
2342 !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
2343 gen_movl_T0_preg[SR_CCS]();
2344 gen_op_andl_T0_im(~X_FLAG);
2345 gen_movl_preg_T0[SR_CCS]();
2346 dc->flagx_live = 1;
2347 dc->flags_x = 0;
2348 }
2349
2350 /* Check for delayed branches here. If we do it before
2351 actually genereating any host code, the simulator will just
2352 loop doing nothing for on this program location. */
2353 if (dc->delayed_branch) {
2354 dc->delayed_branch--;
2355 if (dc->delayed_branch == 0)
2356 {
2357 if (dc->bcc == CC_A) {
2358 gen_op_jmp1 ();
2359 dc->is_jmp = DISAS_UPDATE;
2360 }
2361 else {
2362 /* Conditional jmp. */
2363 gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2364 dc->is_jmp = DISAS_UPDATE;
2365 }
2366 }
2367 }
2368
2369 if (env->singlestep_enabled)
2370 break;
2371 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2372 && dc->pc < next_page_start);
2373
2374 if (!dc->is_jmp) {
2375 gen_op_movl_T0_im((long)dc->pc);
2376 gen_op_movl_pc_T0();
2377 }
2378
2379 cris_evaluate_flags (dc);
2380 done:
2381 if (__builtin_expect(env->singlestep_enabled, 0)) {
2382 gen_op_debug();
2383 } else {
2384 switch(dc->is_jmp) {
2385 case DISAS_NEXT:
2386 gen_goto_tb(dc, 1, dc->pc);
2387 break;
2388 default:
2389 case DISAS_JUMP:
2390 case DISAS_UPDATE:
2391 /* indicate that the hash table must be used
2392 to find the next TB */
2393 tcg_gen_exit_tb(0);
2394 break;
2395 case DISAS_TB_JUMP:
2396 /* nothing more to generate */
2397 break;
2398 }
2399 }
2400 *gen_opc_ptr = INDEX_op_end;
2401 if (search_pc) {
2402 j = gen_opc_ptr - gen_opc_buf;
2403 lj++;
2404 while (lj <= j)
2405 gen_opc_instr_start[lj++] = 0;
2406 } else {
2407 tb->size = dc->pc - pc_start;
2408 }
2409
2410 #ifdef DEBUG_DISAS
2411 if (loglevel & CPU_LOG_TB_IN_ASM) {
2412 fprintf(logfile, "--------------\n");
2413 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2414 target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2415 fprintf(logfile, "\n");
2416 }
2417 #endif
2418 return 0;
2419 }
2420
2421 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2422 {
2423 return gen_intermediate_code_internal(env, tb, 0);
2424 }
2425
2426 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2427 {
2428 return gen_intermediate_code_internal(env, tb, 1);
2429 }
2430
2431 void cpu_dump_state (CPUState *env, FILE *f,
2432 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2433 int flags)
2434 {
2435 int i;
2436 uint32_t srs;
2437
2438 if (!env || !f)
2439 return;
2440
2441 cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2442 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2443 "debug=%x %x %x\n",
2444 env->pc, env->pregs[SR_CCS], env->btaken, env->btarget,
2445 env->cc_op,
2446 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2447 env->debug1, env->debug2, env->debug3);
2448
2449 for (i = 0; i < 16; i++) {
2450 cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2451 if ((i + 1) % 4 == 0)
2452 cpu_fprintf(f, "\n");
2453 }
2454 cpu_fprintf(f, "\nspecial regs:\n");
2455 for (i = 0; i < 16; i++) {
2456 cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2457 if ((i + 1) % 4 == 0)
2458 cpu_fprintf(f, "\n");
2459 }
2460 srs = env->pregs[SR_SRS];
2461 cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2462 if (srs < 256) {
2463 for (i = 0; i < 16; i++) {
2464 cpu_fprintf(f, "s%2.2d=%8.8x ",
2465 i, env->sregs[srs][i]);
2466 if ((i + 1) % 4 == 0)
2467 cpu_fprintf(f, "\n");
2468 }
2469 }
2470 cpu_fprintf(f, "\n\n");
2471
2472 }
2473
2474 CPUCRISState *cpu_cris_init (const char *cpu_model)
2475 {
2476 CPUCRISState *env;
2477
2478 env = qemu_mallocz(sizeof(CPUCRISState));
2479 if (!env)
2480 return NULL;
2481 cpu_exec_init(env);
2482 cpu_reset(env);
2483 return env;
2484 }
2485
2486 void cpu_reset (CPUCRISState *env)
2487 {
2488 memset(env, 0, offsetof(CPUCRISState, breakpoints));
2489 tlb_flush(env, 1);
2490 }