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