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