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