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