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