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