]> git.proxmox.com Git - mirror_qemu.git/blame - target-cris/translate.c
Use a TCG global for fsr
[mirror_qemu.git] / target-cris / translate.c
CommitLineData
8170028d
TS
1/*
2 * CRIS emulation for qemu: main translation routines.
3 *
05ba7d5f 4 * Copyright (c) 2008 AXIS Communications AB
8170028d
TS
5 * Written by Edgar E. Iglesias.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
8170028d
TS
22#include <stdarg.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <inttypes.h>
27#include <assert.h>
28
29#include "cpu.h"
30#include "exec-all.h"
31#include "disas.h"
57fec1fe 32#include "tcg-op.h"
05ba7d5f 33#include "helper.h"
8170028d
TS
34#include "crisv32-decode.h"
35
36#define CRIS_STATS 0
37#if CRIS_STATS
38#define STATS(x) x
39#else
40#define STATS(x)
41#endif
42
43#define DISAS_CRIS 0
44#if DISAS_CRIS
45#define DIS(x) x
46#else
47#define DIS(x)
48#endif
49
8170028d
TS
50#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
51#define BUG_ON(x) ({if (x) BUG();})
52
4f400ab5
EI
53#define DISAS_SWI 5
54
8170028d
TS
55/* Used by the decoder. */
56#define EXTRACT_FIELD(src, start, end) \
57 (((src) >> start) & ((1 << (end - start + 1)) - 1))
58
59#define CC_MASK_NZ 0xc
60#define CC_MASK_NZV 0xe
61#define CC_MASK_NZVC 0xf
62#define CC_MASK_RNZV 0x10e
63
05ba7d5f
EI
64TCGv cpu_env, cpu_T[2];
65
8170028d
TS
66/* This is the state at translation time. */
67typedef struct DisasContext {
68 CPUState *env;
69 target_ulong pc, insn_pc;
70
71 /* Decoder. */
72 uint32_t ir;
73 uint32_t opcode;
74 unsigned int op1;
75 unsigned int op2;
76 unsigned int zsize, zzsize;
77 unsigned int mode;
78 unsigned int postinc;
79
8170028d
TS
80 int update_cc;
81 int cc_op;
82 int cc_size;
83 uint32_t cc_mask;
84 int flags_live;
85 int flagx_live;
86 int flags_x;
87 uint32_t tb_entry_flags;
88
89 int memidx; /* user or kernel mode. */
90 int is_jmp;
91 int dyn_jmp;
92
93 uint32_t delayed_pc;
94 int delayed_branch;
95 int bcc;
96 uint32_t condlabel;
97
98 struct TranslationBlock *tb;
99 int singlestep_enabled;
100} DisasContext;
101
102void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
103static void gen_BUG(DisasContext *dc, char *file, int line)
104{
105 printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
106 fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
107 cpu_dump_state (dc->env, stdout, fprintf, 0);
108 fflush(NULL);
109 cris_prepare_jmp (dc, 0x70000000 + line);
110}
111
8170028d
TS
112#ifdef CONFIG_USER_ONLY
113#define GEN_OP_LD(width, reg) \
114 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
115 gen_op_ld##width##_T0_##reg##_raw(); \
116 }
117#define GEN_OP_ST(width, reg) \
118 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
119 gen_op_st##width##_##reg##_T1_raw(); \
120 }
121#else
122#define GEN_OP_LD(width, reg) \
123 void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
124 if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
125 else gen_op_ld##width##_T0_##reg##_user();\
126 }
127#define GEN_OP_ST(width, reg) \
128 void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
129 if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
130 else gen_op_st##width##_##reg##_T1_user();\
131 }
132#endif
133
134GEN_OP_LD(ub, T0)
135GEN_OP_LD(b, T0)
136GEN_OP_ST(b, T0)
137GEN_OP_LD(uw, T0)
138GEN_OP_LD(w, T0)
139GEN_OP_ST(w, T0)
140GEN_OP_LD(l, T0)
141GEN_OP_ST(l, T0)
142
05ba7d5f
EI
143/* We need this table to handle preg-moves with implicit width. */
144int preg_sizes[] = {
145 1, /* bz. */
146 1, /* vr. */
147 4, /* pid. */
148 1, /* srs. */
149 2, /* wz. */
150 4, 4, 4,
151 4, 4, 4, 4,
152 4, 4, 4, 4,
153};
154
155#define t_gen_mov_TN_env(tn, member) \
156 _t_gen_mov_TN_env((tn), offsetof(CPUState, (member)))
157#define t_gen_mov_env_TN(member, tn) \
158 _t_gen_mov_env_TN(offsetof(CPUState, (member)), (tn))
159
160#define t_gen_mov_TN_reg(tn, regno) \
161 _t_gen_mov_TN_env((tn), offsetof(CPUState, regs[regno]))
162#define t_gen_mov_reg_TN(regno, tn) \
163 _t_gen_mov_env_TN(offsetof(CPUState, regs[regno]), (tn))
164
165static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
166{
167 tcg_gen_ld_tl(tn, cpu_env, offset);
168}
169static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
170{
171 tcg_gen_st_tl(tn, cpu_env, offset);
172}
173
174static inline void t_gen_mov_TN_preg(TCGv tn, int r)
175{
176 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
177 tcg_gen_mov_tl(tn, tcg_const_i32(0));
178 else if (r == PR_VR)
179 tcg_gen_mov_tl(tn, tcg_const_i32(32));
180 else
181 tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, pregs[r]));
182}
183static inline void t_gen_mov_preg_TN(int r, TCGv tn)
184{
185 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
186 return;
187 else
188 tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, pregs[r]));
189}
190
191static inline void t_gen_mov_TN_im(TCGv tn, int32_t val)
192{
193 tcg_gen_movi_tl(tn, val);
194}
195
196static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
197{
198 int l1;
199
200 l1 = gen_new_label();
201 /* Speculative shift. */
202 tcg_gen_shl_tl(d, a, b);
203 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_i32(31), l1);
204 /* Clear dst if shift operands were to large. */
205 tcg_gen_movi_tl(d, 0);
206 gen_set_label(l1);
207}
208
209static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
210{
211 int l1;
212
213 l1 = gen_new_label();
214 /* Speculative shift. */
215 tcg_gen_shr_tl(d, a, b);
216 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_i32(31), l1);
217 /* Clear dst if shift operands were to large. */
218 tcg_gen_movi_tl(d, 0);
219 gen_set_label(l1);
220}
221
222static void t_gen_asr(TCGv d, TCGv a, TCGv b)
223{
224 int l1;
225
226 l1 = gen_new_label();
227 /* Speculative shift. */
228 tcg_gen_sar_tl(d, a, b);
229 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_i32(31), l1);
230 /* Clear dst if shift operands were to large. */
231 tcg_gen_movi_tl(d, 0);
232 tcg_gen_brcond_tl(TCG_COND_LT, b, tcg_const_i32(0x80000000), l1);
233 tcg_gen_movi_tl(d, 0xffffffff);
234 gen_set_label(l1);
235}
236
8170028d
TS
237static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
238{
239 TranslationBlock *tb;
240 tb = dc->tb;
241 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
05ba7d5f
EI
242 tcg_gen_goto_tb(n);
243 tcg_gen_movi_tl(cpu_T[0], dest);
244 gen_op_movl_pc_T0();
245 tcg_gen_exit_tb((long)tb + n);
8170028d 246 } else {
05ba7d5f
EI
247 gen_op_movl_pc_T0();
248 tcg_gen_exit_tb(0);
8170028d 249 }
8170028d
TS
250}
251
252/* Sign extend at translation time. */
253static int sign_extend(unsigned int val, unsigned int width)
254{
255 int sval;
256
257 /* LSL. */
258 val <<= 31 - width;
259 sval = val;
260 /* ASR. */
261 sval >>= 31 - width;
262 return sval;
263}
264
05ba7d5f
EI
265static inline void cris_clear_x_flag(DisasContext *dc)
266{
267 TCGv ccs;
268
269 ccs = tcg_temp_new(TCG_TYPE_TL);
270
271 t_gen_mov_TN_preg(ccs, PR_CCS);
272 tcg_gen_andi_i32(ccs, ccs, ~X_FLAG);
273 t_gen_mov_preg_TN(PR_CCS, ccs);
274 dc->flagx_live = 1;
275 dc->flags_x = 0;
276}
277
8170028d
TS
278static void cris_evaluate_flags(DisasContext *dc)
279{
280 if (!dc->flags_live) {
8170028d
TS
281 switch (dc->cc_op)
282 {
283 case CC_OP_MCP:
284 gen_op_evaluate_flags_mcp ();
285 break;
286 case CC_OP_MULS:
287 gen_op_evaluate_flags_muls ();
288 break;
289 case CC_OP_MULU:
290 gen_op_evaluate_flags_mulu ();
291 break;
292 case CC_OP_MOVE:
293 switch (dc->cc_size)
294 {
295 case 4:
296 gen_op_evaluate_flags_move_4();
297 break;
298 case 2:
299 gen_op_evaluate_flags_move_2();
300 break;
301 default:
302 gen_op_evaluate_flags ();
303 break;
304 }
305 break;
306
307 default:
308 {
309 switch (dc->cc_size)
310 {
311 case 4:
312 gen_op_evaluate_flags_alu_4 ();
313 break;
314 default:
315 gen_op_evaluate_flags ();
316 break;
317 }
318 }
319 break;
320 }
321 dc->flags_live = 1;
322 }
323}
324
325static void cris_cc_mask(DisasContext *dc, unsigned int mask)
326{
327 uint32_t ovl;
328
fd56059f
AZ
329 /* Check if we need to evaluate the condition codes due to
330 CC overlaying. */
8170028d
TS
331 ovl = (dc->cc_mask ^ mask) & ~mask;
332 if (ovl) {
333 /* TODO: optimize this case. It trigs all the time. */
334 cris_evaluate_flags (dc);
335 }
336 dc->cc_mask = mask;
337
338 dc->update_cc = 1;
339 if (mask == 0)
340 dc->update_cc = 0;
341 else {
342 gen_op_update_cc_mask(mask);
343 dc->flags_live = 0;
344 }
345}
346
347static void cris_update_cc_op(DisasContext *dc, int op)
348{
349 dc->cc_op = op;
350 gen_op_update_cc_op(op);
351 dc->flags_live = 0;
352}
353static void cris_update_cc_size(DisasContext *dc, int size)
354{
355 dc->cc_size = size;
356 gen_op_update_cc_size_im(size);
357}
358
359/* op is the operation.
360 T0, T1 are the operands.
361 dst is the destination reg.
362*/
363static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
364{
365 int writeback = 1;
366 if (dc->update_cc) {
367 cris_update_cc_op(dc, op);
368 cris_update_cc_size(dc, size);
369 gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
370 gen_op_update_cc_dest_T0();
371 }
372
373 /* Emit the ALU insns. */
374 switch (op)
375 {
376 case CC_OP_ADD:
05ba7d5f 377 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d 378 /* Extended arithmetics. */
54728ac6 379 gen_op_addxl_T0_C();
8170028d
TS
380 break;
381 case CC_OP_ADDC:
05ba7d5f 382 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
383 gen_op_addl_T0_C();
384 break;
385 case CC_OP_MCP:
05ba7d5f 386 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
387 gen_op_addl_T0_R();
388 break;
389 case CC_OP_SUB:
05ba7d5f
EI
390 tcg_gen_sub_tl(cpu_T[1], tcg_const_i32(0), cpu_T[1]);
391 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d 392 /* CRIS flag evaluation needs ~src. */
05ba7d5f 393 tcg_gen_sub_tl(cpu_T[1], tcg_const_i32(0), cpu_T[1]);
8170028d
TS
394 gen_op_not_T1_T1();
395
396 /* Extended arithmetics. */
54728ac6 397 gen_op_subxl_T0_C();
8170028d
TS
398 break;
399 case CC_OP_MOVE:
05ba7d5f 400 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
8170028d
TS
401 break;
402 case CC_OP_OR:
05ba7d5f 403 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
404 break;
405 case CC_OP_AND:
05ba7d5f 406 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
407 break;
408 case CC_OP_XOR:
05ba7d5f 409 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
410 break;
411 case CC_OP_LSL:
05ba7d5f 412 t_gen_lsl(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
413 break;
414 case CC_OP_LSR:
05ba7d5f 415 t_gen_lsr(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
416 break;
417 case CC_OP_ASR:
05ba7d5f 418 t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
8170028d
TS
419 break;
420 case CC_OP_NEG:
05ba7d5f
EI
421 /* TCG-FIXME: this is not optimal. Many archs have
422 fast neg insns. */
423 tcg_gen_sub_tl(cpu_T[0], tcg_const_i32(0), cpu_T[1]);
8170028d
TS
424 /* Extended arithmetics. */
425 gen_op_subxl_T0_C();
426 break;
427 case CC_OP_LZ:
428 gen_op_lz_T0_T1();
429 break;
430 case CC_OP_BTST:
431 gen_op_btst_T0_T1();
432 writeback = 0;
433 break;
434 case CC_OP_MULS:
435 gen_op_muls_T0_T1();
436 break;
437 case CC_OP_MULU:
438 gen_op_mulu_T0_T1();
439 break;
440 case CC_OP_DSTEP:
441 gen_op_dstep_T0_T1();
442 break;
443 case CC_OP_BOUND:
444 gen_op_bound_T0_T1();
445 break;
446 case CC_OP_CMP:
05ba7d5f
EI
447 tcg_gen_sub_tl(cpu_T[1], tcg_const_i32(0), cpu_T[1]);
448 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
449 /* CRIS flag evaluation needs ~src. */
450 tcg_gen_sub_tl(cpu_T[1], tcg_const_i32(0), cpu_T[1]);
8170028d 451 /* CRIS flag evaluation needs ~src. */
8170028d
TS
452 gen_op_not_T1_T1();
453
454 /* Extended arithmetics. */
455 gen_op_subxl_T0_C();
456 writeback = 0;
457 break;
458 default:
459 fprintf (logfile, "illegal ALU op.\n");
460 BUG();
461 break;
462 }
463
464 if (dc->update_cc)
465 gen_op_update_cc_src_T1();
466
467 if (size == 1)
05ba7d5f 468 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
8170028d 469 else if (size == 2)
05ba7d5f
EI
470 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
471
8170028d
TS
472 /* Writeback. */
473 if (writeback) {
474 if (size == 4)
05ba7d5f 475 t_gen_mov_reg_TN(rd, cpu_T[0]);
8170028d 476 else {
05ba7d5f
EI
477 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
478 t_gen_mov_TN_reg(cpu_T[0], rd);
8170028d 479 if (size == 1)
05ba7d5f 480 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xff);
8170028d 481 else
05ba7d5f
EI
482 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xffff);
483 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
484 t_gen_mov_reg_TN(rd, cpu_T[0]);
485 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
8170028d
TS
486 }
487 }
488 if (dc->update_cc)
489 gen_op_update_cc_result_T0();
490
491 {
492 /* TODO: Optimize this. */
493 if (!dc->flagx_live)
494 cris_evaluate_flags(dc);
495 }
496}
497
498static int arith_cc(DisasContext *dc)
499{
500 if (dc->update_cc) {
501 switch (dc->cc_op) {
502 case CC_OP_ADD: return 1;
503 case CC_OP_SUB: return 1;
504 case CC_OP_LSL: return 1;
505 case CC_OP_LSR: return 1;
506 case CC_OP_ASR: return 1;
507 case CC_OP_CMP: return 1;
508 default:
509 return 0;
510 }
511 }
512 return 0;
513}
514
515static void gen_tst_cc (DisasContext *dc, int cond)
516{
517 int arith_opt;
518
519 /* TODO: optimize more condition codes. */
520 arith_opt = arith_cc(dc) && !dc->flags_live;
521 switch (cond) {
522 case CC_EQ:
523 if (arith_opt)
524 gen_op_tst_cc_eq_fast ();
525 else {
526 cris_evaluate_flags(dc);
527 gen_op_tst_cc_eq ();
528 }
529 break;
530 case CC_NE:
531 if (arith_opt)
532 gen_op_tst_cc_ne_fast ();
533 else {
534 cris_evaluate_flags(dc);
535 gen_op_tst_cc_ne ();
536 }
537 break;
538 case CC_CS:
539 cris_evaluate_flags(dc);
540 gen_op_tst_cc_cs ();
541 break;
542 case CC_CC:
543 cris_evaluate_flags(dc);
544 gen_op_tst_cc_cc ();
545 break;
546 case CC_VS:
547 cris_evaluate_flags(dc);
548 gen_op_tst_cc_vs ();
549 break;
550 case CC_VC:
551 cris_evaluate_flags(dc);
552 gen_op_tst_cc_vc ();
553 break;
554 case CC_PL:
555 if (arith_opt)
556 gen_op_tst_cc_pl_fast ();
557 else {
558 cris_evaluate_flags(dc);
559 gen_op_tst_cc_pl ();
560 }
561 break;
562 case CC_MI:
563 if (arith_opt)
564 gen_op_tst_cc_mi_fast ();
565 else {
566 cris_evaluate_flags(dc);
567 gen_op_tst_cc_mi ();
568 }
569 break;
570 case CC_LS:
571 cris_evaluate_flags(dc);
572 gen_op_tst_cc_ls ();
573 break;
574 case CC_HI:
575 cris_evaluate_flags(dc);
576 gen_op_tst_cc_hi ();
577 break;
578 case CC_GE:
579 cris_evaluate_flags(dc);
580 gen_op_tst_cc_ge ();
581 break;
582 case CC_LT:
583 cris_evaluate_flags(dc);
584 gen_op_tst_cc_lt ();
585 break;
586 case CC_GT:
587 cris_evaluate_flags(dc);
588 gen_op_tst_cc_gt ();
589 break;
590 case CC_LE:
591 cris_evaluate_flags(dc);
592 gen_op_tst_cc_le ();
593 break;
594 case CC_P:
595 cris_evaluate_flags(dc);
596 gen_op_tst_cc_p ();
597 break;
598 case CC_A:
599 cris_evaluate_flags(dc);
600 gen_op_movl_T0_im (1);
601 break;
602 default:
603 BUG();
604 break;
605 };
606}
607
608static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
609{
610 /* This helps us re-schedule the micro-code to insns in delay-slots
611 before the actual jump. */
612 dc->delayed_branch = 2;
613 dc->delayed_pc = dc->pc + offset;
614 dc->bcc = cond;
615 if (cond != CC_A)
616 {
617 gen_tst_cc (dc, cond);
618 gen_op_evaluate_bcc ();
619 }
620 gen_op_movl_T0_im (dc->delayed_pc);
621 gen_op_movl_btarget_T0 ();
622}
623
624/* Dynamic jumps, when the dest is in a live reg for example. */
625void cris_prepare_dyn_jmp (DisasContext *dc)
626{
627 /* This helps us re-schedule the micro-code to insns in delay-slots
628 before the actual jump. */
629 dc->delayed_branch = 2;
630 dc->dyn_jmp = 1;
631 dc->bcc = CC_A;
632}
633
634void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
635{
636 /* This helps us re-schedule the micro-code to insns in delay-slots
637 before the actual jump. */
638 dc->delayed_branch = 2;
639 dc->delayed_pc = dst;
640 dc->dyn_jmp = 0;
641 dc->bcc = CC_A;
642}
643
644void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
645{
646 if (size == 1) {
647 if (sign)
648 gen_op_ldb_T0_T0(dc);
649 else
650 gen_op_ldub_T0_T0(dc);
651 }
652 else if (size == 2) {
653 if (sign)
654 gen_op_ldw_T0_T0(dc);
655 else
656 gen_op_lduw_T0_T0(dc);
657 }
658 else {
659 gen_op_ldl_T0_T0(dc);
660 }
661}
662
663void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
664{
665 /* Remember, operands are flipped. CRIS has reversed order. */
666 if (size == 1) {
667 gen_op_stb_T0_T1(dc);
668 }
669 else if (size == 2) {
670 gen_op_stw_T0_T1(dc);
671 }
672 else
673 gen_op_stl_T0_T1(dc);
674}
675
05ba7d5f 676static inline void t_gen_sext(TCGv d, TCGv s, int size)
8170028d
TS
677{
678 if (size == 1)
05ba7d5f 679 tcg_gen_ext8s_i32(d, s);
8170028d 680 else if (size == 2)
05ba7d5f 681 tcg_gen_ext16s_i32(d, s);
8170028d
TS
682}
683
05ba7d5f 684static inline void t_gen_zext(TCGv d, TCGv s, int size)
8170028d 685{
05ba7d5f 686 /* TCG-FIXME: this is not optimal. Many archs have fast zext insns. */
8170028d 687 if (size == 1)
05ba7d5f 688 tcg_gen_andi_i32(d, s, 0xff);
8170028d 689 else if (size == 2)
05ba7d5f 690 tcg_gen_andi_i32(d, s, 0xffff);
8170028d
TS
691}
692
693#if DISAS_CRIS
694static char memsize_char(int size)
695{
696 switch (size)
697 {
698 case 1: return 'b'; break;
699 case 2: return 'w'; break;
700 case 4: return 'd'; break;
701 default:
702 return 'x';
703 break;
704 }
705}
706#endif
707
708static unsigned int memsize_z(DisasContext *dc)
709{
710 return dc->zsize + 1;
711}
712
713static unsigned int memsize_zz(DisasContext *dc)
714{
715 switch (dc->zzsize)
716 {
717 case 0: return 1;
718 case 1: return 2;
719 default:
720 return 4;
721 }
722}
723
724static void do_postinc (DisasContext *dc, int size)
725{
726 if (!dc->postinc)
727 return;
05ba7d5f 728 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d 729 gen_op_addl_T0_im(size);
05ba7d5f 730 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
8170028d
TS
731}
732
733
734static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
735 int size, int s_ext)
736{
05ba7d5f 737 t_gen_mov_TN_reg(cpu_T[1], rs);
8170028d 738 if (s_ext)
05ba7d5f 739 t_gen_sext(cpu_T[1], cpu_T[1], size);
8170028d 740 else
05ba7d5f 741 t_gen_zext(cpu_T[1], cpu_T[1], size);
8170028d
TS
742}
743
744/* Prepare T0 and T1 for a register alu operation.
745 s_ext decides if the operand1 should be sign-extended or zero-extended when
746 needed. */
747static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
748 int size, int s_ext)
749{
750 dec_prep_move_r(dc, rs, rd, size, s_ext);
751
05ba7d5f 752 t_gen_mov_TN_reg(cpu_T[0], rd);
8170028d 753 if (s_ext)
05ba7d5f 754 t_gen_sext(cpu_T[0], cpu_T[0], size);
8170028d 755 else
05ba7d5f 756 t_gen_zext(cpu_T[0], cpu_T[0], size);
8170028d
TS
757}
758
759/* Prepare T0 and T1 for a memory + alu operation.
760 s_ext decides if the operand1 should be sign-extended or zero-extended when
761 needed. */
762static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
763{
764 unsigned int rs, rd;
765 uint32_t imm;
766 int is_imm;
767 int insn_len = 2;
768
769 rs = dc->op1;
770 rd = dc->op2;
771 is_imm = rs == 15 && dc->postinc;
772
773 /* Load [$rs] onto T1. */
774 if (is_imm) {
775 insn_len = 2 + memsize;
776 if (memsize == 1)
777 insn_len++;
778
779 imm = ldl_code(dc->pc + 2);
780 if (memsize != 4) {
781 if (s_ext) {
782 imm = sign_extend(imm, (memsize * 8) - 1);
783 } else {
784 if (memsize == 1)
785 imm &= 0xff;
786 else
787 imm &= 0xffff;
788 }
789 }
790 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
791 imm, rd, s_ext, memsize));
05ba7d5f 792 tcg_gen_movi_tl(cpu_T[1], imm);
8170028d
TS
793 dc->postinc = 0;
794 } else {
05ba7d5f 795 t_gen_mov_TN_reg(cpu_T[0], rs);
8170028d 796 gen_load_T0_T0(dc, memsize, 0);
05ba7d5f 797 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
8170028d 798 if (s_ext)
05ba7d5f 799 t_gen_sext(cpu_T[1], cpu_T[1], memsize);
8170028d 800 else
05ba7d5f 801 t_gen_zext(cpu_T[1], cpu_T[1], memsize);
8170028d
TS
802 }
803
804 /* put dest in T0. */
05ba7d5f 805 t_gen_mov_TN_reg(cpu_T[0], rd);
8170028d
TS
806 return insn_len;
807}
808
809#if DISAS_CRIS
810static const char *cc_name(int cc)
811{
812 static char *cc_names[16] = {
813 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
814 "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
815 };
816 assert(cc < 16);
817 return cc_names[cc];
818}
819#endif
820
821static unsigned int dec_bccq(DisasContext *dc)
822{
823 int32_t offset;
824 int sign;
825 uint32_t cond = dc->op2;
826 int tmp;
827
828 offset = EXTRACT_FIELD (dc->ir, 1, 7);
829 sign = EXTRACT_FIELD(dc->ir, 0, 0);
830
831 offset *= 2;
832 offset |= sign << 8;
833 tmp = offset;
834 offset = sign_extend(offset, 8);
835
836 /* op2 holds the condition-code. */
837 cris_cc_mask(dc, 0);
838 cris_prepare_cc_branch (dc, offset, cond);
839 return 2;
840}
841static unsigned int dec_addoq(DisasContext *dc)
842{
843 uint32_t imm;
844
845 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
846 imm = sign_extend(dc->op1, 7);
847
848 DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
849 cris_cc_mask(dc, 0);
850 /* Fetch register operand, */
05ba7d5f
EI
851 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
852 tcg_gen_movi_tl(cpu_T[1], imm);
9004627f 853 crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
8170028d
TS
854 return 2;
855}
856static unsigned int dec_addq(DisasContext *dc)
857{
858 DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
859
860 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
861
862 cris_cc_mask(dc, CC_MASK_NZVC);
863 /* Fetch register operand, */
05ba7d5f
EI
864 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
865 tcg_gen_movi_tl(cpu_T[1], dc->op1);
8170028d
TS
866 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
867 return 2;
868}
869static unsigned int dec_moveq(DisasContext *dc)
870{
871 uint32_t imm;
872
873 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
874 imm = sign_extend(dc->op1, 5);
875 DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
876
05ba7d5f
EI
877 t_gen_mov_reg_TN(dc->op2, tcg_const_i32(imm));
878 if (!dc->flagx_live || dc->flags_x)
879 cris_clear_x_flag(dc);
8170028d
TS
880 return 2;
881}
882static unsigned int dec_subq(DisasContext *dc)
883{
884 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
885
886 DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
887
888 cris_cc_mask(dc, CC_MASK_NZVC);
889 /* Fetch register operand, */
05ba7d5f
EI
890 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
891 t_gen_mov_TN_im(cpu_T[1], dc->op1);
8170028d
TS
892 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
893 return 2;
894}
895static unsigned int dec_cmpq(DisasContext *dc)
896{
897 uint32_t imm;
898 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
899 imm = sign_extend(dc->op1, 5);
900
901 DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
902 cris_cc_mask(dc, CC_MASK_NZVC);
05ba7d5f
EI
903 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
904 t_gen_mov_TN_im(cpu_T[1], imm);
8170028d
TS
905 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
906 return 2;
907}
908static unsigned int dec_andq(DisasContext *dc)
909{
910 uint32_t imm;
911 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
912 imm = sign_extend(dc->op1, 5);
913
914 DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
915 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
916 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
917 t_gen_mov_TN_im(cpu_T[1], imm);
8170028d
TS
918 crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
919 return 2;
920}
921static unsigned int dec_orq(DisasContext *dc)
922{
923 uint32_t imm;
924 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
925 imm = sign_extend(dc->op1, 5);
926 DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
927 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
928 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
929 t_gen_mov_TN_im(cpu_T[1], imm);
8170028d
TS
930 crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
931 return 2;
932}
933static unsigned int dec_btstq(DisasContext *dc)
934{
935 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
936 DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
8170028d 937 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
938 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
939 t_gen_mov_TN_im(cpu_T[1], dc->op1);
8170028d
TS
940 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
941
942 cris_update_cc_op(dc, CC_OP_FLAGS);
943 gen_op_movl_flags_T0();
944 dc->flags_live = 1;
945 return 2;
946}
947static unsigned int dec_asrq(DisasContext *dc)
948{
949 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
950 DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
951 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
952 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
953 t_gen_mov_TN_im(cpu_T[1], dc->op1);
8170028d
TS
954 crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
955 return 2;
956}
957static unsigned int dec_lslq(DisasContext *dc)
958{
959 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
960 DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
961
962 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
963 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
964 t_gen_mov_TN_im(cpu_T[1], dc->op1);
8170028d
TS
965 crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
966 return 2;
967}
968static unsigned int dec_lsrq(DisasContext *dc)
969{
970 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
971 DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
972
973 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
974 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
975 t_gen_mov_TN_im(cpu_T[1], dc->op1);
8170028d
TS
976 crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
977 return 2;
978}
979
980static unsigned int dec_move_r(DisasContext *dc)
981{
982 int size = memsize_zz(dc);
983
984 DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
985 memsize_char(size), dc->op1, dc->op2));
986
987 cris_cc_mask(dc, CC_MASK_NZ);
988 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
989 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
990 return 2;
991}
992
993static unsigned int dec_scc_r(DisasContext *dc)
994{
995 int cond = dc->op2;
996
997 DIS(fprintf (logfile, "s%s $r%u\n",
998 cc_name(cond), dc->op1));
999
1000 if (cond != CC_A)
1001 {
1002 gen_tst_cc (dc, cond);
1003 gen_op_movl_T1_T0();
1004 }
1005 else
1006 gen_op_movl_T1_im(1);
1007
1008 cris_cc_mask(dc, 0);
1009 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1010 return 2;
1011}
1012
1013static unsigned int dec_and_r(DisasContext *dc)
1014{
1015 int size = memsize_zz(dc);
1016
1017 DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1018 memsize_char(size), dc->op1, dc->op2));
1019 cris_cc_mask(dc, CC_MASK_NZ);
1020 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1021 crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1022 return 2;
1023}
1024
1025static unsigned int dec_lz_r(DisasContext *dc)
1026{
1027 DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1028 dc->op1, dc->op2));
1029 cris_cc_mask(dc, CC_MASK_NZ);
1030 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1031 crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1032 return 2;
1033}
1034
1035static unsigned int dec_lsl_r(DisasContext *dc)
1036{
1037 int size = memsize_zz(dc);
1038
1039 DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1040 memsize_char(size), dc->op1, dc->op2));
1041 cris_cc_mask(dc, CC_MASK_NZ);
1042 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
05ba7d5f 1043 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
8170028d
TS
1044 crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1045 return 2;
1046}
1047
1048static unsigned int dec_lsr_r(DisasContext *dc)
1049{
1050 int size = memsize_zz(dc);
1051
1052 DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1053 memsize_char(size), dc->op1, dc->op2));
1054 cris_cc_mask(dc, CC_MASK_NZ);
1055 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
05ba7d5f 1056 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
8170028d
TS
1057 crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1058 return 2;
1059}
1060
1061static unsigned int dec_asr_r(DisasContext *dc)
1062{
1063 int size = memsize_zz(dc);
1064
1065 DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1066 memsize_char(size), dc->op1, dc->op2));
1067 cris_cc_mask(dc, CC_MASK_NZ);
1068 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
05ba7d5f 1069 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
8170028d
TS
1070 crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1071 return 2;
1072}
1073
1074static unsigned int dec_muls_r(DisasContext *dc)
1075{
1076 int size = memsize_zz(dc);
1077
1078 DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1079 memsize_char(size), dc->op1, dc->op2));
1080 cris_cc_mask(dc, CC_MASK_NZV);
1081 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
05ba7d5f 1082 t_gen_sext(cpu_T[0], cpu_T[0], size);
8170028d
TS
1083 crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1084 return 2;
1085}
1086
1087static unsigned int dec_mulu_r(DisasContext *dc)
1088{
1089 int size = memsize_zz(dc);
1090
1091 DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1092 memsize_char(size), dc->op1, dc->op2));
1093 cris_cc_mask(dc, CC_MASK_NZV);
1094 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
05ba7d5f 1095 t_gen_zext(cpu_T[0], cpu_T[0], size);
8170028d
TS
1096 crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1097 return 2;
1098}
1099
1100
1101static unsigned int dec_dstep_r(DisasContext *dc)
1102{
1103 DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1104 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f
EI
1105 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1106 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
8170028d
TS
1107 crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1108 return 2;
1109}
1110
1111static unsigned int dec_xor_r(DisasContext *dc)
1112{
1113 int size = memsize_zz(dc);
1114 DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1115 memsize_char(size), dc->op1, dc->op2));
1116 BUG_ON(size != 4); /* xor is dword. */
1117 cris_cc_mask(dc, CC_MASK_NZ);
1118 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1119 crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1120 return 2;
1121}
1122
1123static unsigned int dec_bound_r(DisasContext *dc)
1124{
1125 int size = memsize_zz(dc);
1126 DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1127 memsize_char(size), dc->op1, dc->op2));
1128 cris_cc_mask(dc, CC_MASK_NZ);
1129 /* TODO: needs optmimization. */
1130 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1131 /* rd should be 4. */
05ba7d5f 1132 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
8170028d
TS
1133 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1134 return 2;
1135}
1136
1137static unsigned int dec_cmp_r(DisasContext *dc)
1138{
1139 int size = memsize_zz(dc);
1140 DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1141 memsize_char(size), dc->op1, dc->op2));
1142 cris_cc_mask(dc, CC_MASK_NZVC);
1143 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1144 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1145 return 2;
1146}
1147
1148static unsigned int dec_abs_r(DisasContext *dc)
1149{
1150 DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1151 dc->op1, dc->op2));
1152 cris_cc_mask(dc, CC_MASK_NZ);
1153 dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1154 gen_op_absl_T1_T1();
1155 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1156 return 2;
1157}
1158
1159static unsigned int dec_add_r(DisasContext *dc)
1160{
1161 int size = memsize_zz(dc);
1162 DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1163 memsize_char(size), dc->op1, dc->op2));
1164 cris_cc_mask(dc, CC_MASK_NZVC);
1165 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1166 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1167 return 2;
1168}
1169
1170static unsigned int dec_addc_r(DisasContext *dc)
1171{
1172 DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1173 dc->op1, dc->op2));
1174 cris_evaluate_flags(dc);
1175 cris_cc_mask(dc, CC_MASK_NZVC);
1176 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1177 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1178 return 2;
1179}
1180
1181static unsigned int dec_mcp_r(DisasContext *dc)
1182{
1183 DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1184 dc->op2, dc->op1));
1185 cris_evaluate_flags(dc);
1186 cris_cc_mask(dc, CC_MASK_RNZV);
05ba7d5f
EI
1187 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1188 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
8170028d
TS
1189 crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1190 return 2;
1191}
1192
1193#if DISAS_CRIS
1194static char * swapmode_name(int mode, char *modename) {
1195 int i = 0;
1196 if (mode & 8)
1197 modename[i++] = 'n';
1198 if (mode & 4)
1199 modename[i++] = 'w';
1200 if (mode & 2)
1201 modename[i++] = 'b';
1202 if (mode & 1)
1203 modename[i++] = 'r';
1204 modename[i++] = 0;
1205 return modename;
1206}
1207#endif
1208
1209static unsigned int dec_swap_r(DisasContext *dc)
1210{
1211 DIS(char modename[4]);
1212 DIS(fprintf (logfile, "swap%s $r%u\n",
1213 swapmode_name(dc->op2, modename), dc->op1));
1214
1215 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f 1216 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d
TS
1217 if (dc->op2 & 8)
1218 gen_op_not_T0_T0();
1219 if (dc->op2 & 4)
1220 gen_op_swapw_T0_T0();
1221 if (dc->op2 & 2)
1222 gen_op_swapb_T0_T0();
1223 if (dc->op2 & 1)
1224 gen_op_swapr_T0_T0();
1225 gen_op_movl_T1_T0();
1226 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1227 return 2;
1228}
1229
1230static unsigned int dec_or_r(DisasContext *dc)
1231{
1232 int size = memsize_zz(dc);
1233 DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1234 memsize_char(size), dc->op1, dc->op2));
1235 cris_cc_mask(dc, CC_MASK_NZ);
1236 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1237 crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1238 return 2;
1239}
1240
1241static unsigned int dec_addi_r(DisasContext *dc)
1242{
1243 DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1244 memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1245 cris_cc_mask(dc, 0);
1246 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
05ba7d5f
EI
1247 t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_i32(dc->zzsize));
1248 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1249 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
8170028d
TS
1250 return 2;
1251}
1252
1253static unsigned int dec_addi_acr(DisasContext *dc)
1254{
1255 DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1256 memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1257 cris_cc_mask(dc, 0);
1258 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
05ba7d5f
EI
1259 t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_i32(dc->zzsize));
1260
1261 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1262 t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
8170028d
TS
1263 return 2;
1264}
1265
1266static unsigned int dec_neg_r(DisasContext *dc)
1267{
1268 int size = memsize_zz(dc);
1269 DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1270 memsize_char(size), dc->op1, dc->op2));
1271 cris_cc_mask(dc, CC_MASK_NZVC);
1272 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1273 crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1274 return 2;
1275}
1276
1277static unsigned int dec_btst_r(DisasContext *dc)
1278{
1279 DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1280 dc->op1, dc->op2));
8170028d
TS
1281 cris_cc_mask(dc, CC_MASK_NZ);
1282 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1283 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1284
1285 cris_update_cc_op(dc, CC_OP_FLAGS);
1286 gen_op_movl_flags_T0();
1287 dc->flags_live = 1;
1288 return 2;
1289}
1290
1291static unsigned int dec_sub_r(DisasContext *dc)
1292{
1293 int size = memsize_zz(dc);
1294 DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1295 memsize_char(size), dc->op1, dc->op2));
1296 cris_cc_mask(dc, CC_MASK_NZVC);
1297 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1298 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1299 return 2;
1300}
1301
1302/* Zero extension. From size to dword. */
1303static unsigned int dec_movu_r(DisasContext *dc)
1304{
1305 int size = memsize_z(dc);
1306 DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1307 memsize_char(size),
1308 dc->op1, dc->op2));
1309
1310 cris_cc_mask(dc, CC_MASK_NZ);
1311 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1312 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1313 return 2;
1314}
1315
1316/* Sign extension. From size to dword. */
1317static unsigned int dec_movs_r(DisasContext *dc)
1318{
1319 int size = memsize_z(dc);
1320 DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1321 memsize_char(size),
1322 dc->op1, dc->op2));
1323
1324 cris_cc_mask(dc, CC_MASK_NZ);
05ba7d5f 1325 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d 1326 /* Size can only be qi or hi. */
05ba7d5f 1327 t_gen_sext(cpu_T[1], cpu_T[0], size);
8170028d
TS
1328 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1329 return 2;
1330}
1331
1332/* zero extension. From size to dword. */
1333static unsigned int dec_addu_r(DisasContext *dc)
1334{
1335 int size = memsize_z(dc);
1336 DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1337 memsize_char(size),
1338 dc->op1, dc->op2));
1339
1340 cris_cc_mask(dc, CC_MASK_NZVC);
05ba7d5f 1341 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
8170028d 1342 /* Size can only be qi or hi. */
05ba7d5f
EI
1343 t_gen_zext(cpu_T[1], cpu_T[1], size);
1344 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
8170028d
TS
1345 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1346 return 2;
1347}
05ba7d5f 1348
8170028d
TS
1349/* Sign extension. From size to dword. */
1350static unsigned int dec_adds_r(DisasContext *dc)
1351{
1352 int size = memsize_z(dc);
1353 DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1354 memsize_char(size),
1355 dc->op1, dc->op2));
1356
1357 cris_cc_mask(dc, CC_MASK_NZVC);
05ba7d5f 1358 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
8170028d 1359 /* Size can only be qi or hi. */
05ba7d5f
EI
1360 t_gen_sext(cpu_T[1], cpu_T[1], size);
1361 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1362
8170028d
TS
1363 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1364 return 2;
1365}
1366
1367/* Zero extension. From size to dword. */
1368static unsigned int dec_subu_r(DisasContext *dc)
1369{
1370 int size = memsize_z(dc);
1371 DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1372 memsize_char(size),
1373 dc->op1, dc->op2));
1374
1375 cris_cc_mask(dc, CC_MASK_NZVC);
05ba7d5f 1376 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
8170028d 1377 /* Size can only be qi or hi. */
05ba7d5f
EI
1378 t_gen_zext(cpu_T[1], cpu_T[1], size);
1379 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
8170028d
TS
1380 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1381 return 2;
1382}
1383
1384/* Sign extension. From size to dword. */
1385static unsigned int dec_subs_r(DisasContext *dc)
1386{
1387 int size = memsize_z(dc);
1388 DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1389 memsize_char(size),
1390 dc->op1, dc->op2));
1391
1392 cris_cc_mask(dc, CC_MASK_NZVC);
05ba7d5f 1393 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
8170028d 1394 /* Size can only be qi or hi. */
05ba7d5f
EI
1395 t_gen_sext(cpu_T[1], cpu_T[1], size);
1396 t_gen_mov_TN_reg(cpu_T[0], dc->op2);
8170028d
TS
1397 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1398 return 2;
1399}
1400
1401static unsigned int dec_setclrf(DisasContext *dc)
1402{
1403 uint32_t flags;
1404 int set = (~dc->opcode >> 2) & 1;
1405
1406 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1407 | EXTRACT_FIELD(dc->ir, 0, 3);
1408 DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1409 if (set && flags == 0)
1410 DIS(fprintf (logfile, "nop\n"));
1411 else if (!set && (flags & 0x20))
1412 DIS(fprintf (logfile, "di\n"));
1413 else
1414 DIS(fprintf (logfile, "%sf %x\n",
1415 set ? "set" : "clr",
1416 flags));
1417
1418 if (set && (flags & X_FLAG)) {
1419 dc->flagx_live = 1;
1420 dc->flags_x = 1;
1421 }
1422
1423 /* Simply decode the flags. */
1424 cris_evaluate_flags (dc);
1425 cris_update_cc_op(dc, CC_OP_FLAGS);
1426 if (set)
1427 gen_op_setf (flags);
1428 else
1429 gen_op_clrf (flags);
1430 dc->flags_live = 1;
1431 return 2;
1432}
1433
1434static unsigned int dec_move_rs(DisasContext *dc)
1435{
1436 DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1437 cris_cc_mask(dc, 0);
05ba7d5f 1438 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d
TS
1439 gen_op_movl_sreg_T0(dc->op2);
1440
05ba7d5f
EI
1441#if !defined(CONFIG_USER_ONLY)
1442 if (dc->op2 == 6)
1443 gen_op_movl_tlb_hi_T0();
1444 else if (dc->op2 == 5) { /* srs is checked at runtime. */
1445 tcg_gen_helper_0_1(helper_tlb_update, cpu_T[0]);
8170028d 1446 gen_op_movl_tlb_lo_T0();
05ba7d5f
EI
1447 }
1448#endif
8170028d
TS
1449 return 2;
1450}
1451static unsigned int dec_move_sr(DisasContext *dc)
1452{
05ba7d5f 1453 DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1));
8170028d 1454 cris_cc_mask(dc, 0);
05ba7d5f
EI
1455 gen_op_movl_T0_sreg(dc->op2);
1456 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1457 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
8170028d
TS
1458 return 2;
1459}
1460static unsigned int dec_move_rp(DisasContext *dc)
1461{
1462 DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1463 cris_cc_mask(dc, 0);
05ba7d5f
EI
1464 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1465 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
1466 return 2;
1467}
1468static unsigned int dec_move_pr(DisasContext *dc)
1469{
1470 DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1471 cris_cc_mask(dc, 0);
fd56059f
AZ
1472 /* Support register 0 is hardwired to zero.
1473 Treat it specially. */
1474 if (dc->op2 == 0)
05ba7d5f
EI
1475 tcg_gen_movi_tl(cpu_T[1], 0);
1476 else
1477 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
8170028d
TS
1478 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1479 return 2;
1480}
1481
1482static unsigned int dec_move_mr(DisasContext *dc)
1483{
1484 int memsize = memsize_zz(dc);
1485 int insn_len;
1486 DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1487 memsize_char(memsize),
1488 dc->op1, dc->postinc ? "+]" : "]",
1489 dc->op2));
1490
1491 cris_cc_mask(dc, CC_MASK_NZ);
1492 insn_len = dec_prep_alu_m(dc, 0, memsize);
1493 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1494 do_postinc(dc, memsize);
1495 return insn_len;
1496}
1497
1498static unsigned int dec_movs_m(DisasContext *dc)
1499{
1500 int memsize = memsize_z(dc);
1501 int insn_len;
1502 DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1503 memsize_char(memsize),
1504 dc->op1, dc->postinc ? "+]" : "]",
1505 dc->op2));
1506
1507 /* sign extend. */
1508 cris_cc_mask(dc, CC_MASK_NZ);
1509 insn_len = dec_prep_alu_m(dc, 1, memsize);
1510 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1511 do_postinc(dc, memsize);
1512 return insn_len;
1513}
1514
1515static unsigned int dec_addu_m(DisasContext *dc)
1516{
1517 int memsize = memsize_z(dc);
1518 int insn_len;
1519 DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1520 memsize_char(memsize),
1521 dc->op1, dc->postinc ? "+]" : "]",
1522 dc->op2));
1523
1524 /* sign extend. */
1525 cris_cc_mask(dc, CC_MASK_NZVC);
1526 insn_len = dec_prep_alu_m(dc, 0, memsize);
1527 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1528 do_postinc(dc, memsize);
1529 return insn_len;
1530}
1531
1532static unsigned int dec_adds_m(DisasContext *dc)
1533{
1534 int memsize = memsize_z(dc);
1535 int insn_len;
1536 DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1537 memsize_char(memsize),
1538 dc->op1, dc->postinc ? "+]" : "]",
1539 dc->op2));
1540
1541 /* sign extend. */
1542 cris_cc_mask(dc, CC_MASK_NZVC);
1543 insn_len = dec_prep_alu_m(dc, 1, memsize);
1544 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1545 do_postinc(dc, memsize);
1546 return insn_len;
1547}
1548
1549static unsigned int dec_subu_m(DisasContext *dc)
1550{
1551 int memsize = memsize_z(dc);
1552 int insn_len;
1553 DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1554 memsize_char(memsize),
1555 dc->op1, dc->postinc ? "+]" : "]",
1556 dc->op2));
1557
1558 /* sign extend. */
1559 cris_cc_mask(dc, CC_MASK_NZVC);
1560 insn_len = dec_prep_alu_m(dc, 0, memsize);
1561 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1562 do_postinc(dc, memsize);
1563 return insn_len;
1564}
1565
1566static unsigned int dec_subs_m(DisasContext *dc)
1567{
1568 int memsize = memsize_z(dc);
1569 int insn_len;
1570 DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1571 memsize_char(memsize),
1572 dc->op1, dc->postinc ? "+]" : "]",
1573 dc->op2));
1574
1575 /* sign extend. */
1576 cris_cc_mask(dc, CC_MASK_NZVC);
1577 insn_len = dec_prep_alu_m(dc, 1, memsize);
1578 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1579 do_postinc(dc, memsize);
1580 return insn_len;
1581}
1582
1583static unsigned int dec_movu_m(DisasContext *dc)
1584{
1585 int memsize = memsize_z(dc);
1586 int insn_len;
1587
1588 DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1589 memsize_char(memsize),
1590 dc->op1, dc->postinc ? "+]" : "]",
1591 dc->op2));
1592
1593 cris_cc_mask(dc, CC_MASK_NZ);
1594 insn_len = dec_prep_alu_m(dc, 0, memsize);
1595 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1596 do_postinc(dc, memsize);
1597 return insn_len;
1598}
1599
1600static unsigned int dec_cmpu_m(DisasContext *dc)
1601{
1602 int memsize = memsize_z(dc);
1603 int insn_len;
1604 DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1605 memsize_char(memsize),
1606 dc->op1, dc->postinc ? "+]" : "]",
1607 dc->op2));
1608
1609 cris_cc_mask(dc, CC_MASK_NZVC);
1610 insn_len = dec_prep_alu_m(dc, 0, memsize);
1611 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1612 do_postinc(dc, memsize);
1613 return insn_len;
1614}
1615
1616static unsigned int dec_cmps_m(DisasContext *dc)
1617{
1618 int memsize = memsize_z(dc);
1619 int insn_len;
1620 DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1621 memsize_char(memsize),
1622 dc->op1, dc->postinc ? "+]" : "]",
1623 dc->op2));
1624
1625 cris_cc_mask(dc, CC_MASK_NZVC);
1626 insn_len = dec_prep_alu_m(dc, 1, memsize);
1627 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1628 do_postinc(dc, memsize);
1629 return insn_len;
1630}
1631
1632static unsigned int dec_cmp_m(DisasContext *dc)
1633{
1634 int memsize = memsize_zz(dc);
1635 int insn_len;
1636 DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1637 memsize_char(memsize),
1638 dc->op1, dc->postinc ? "+]" : "]",
1639 dc->op2));
1640
1641 cris_cc_mask(dc, CC_MASK_NZVC);
1642 insn_len = dec_prep_alu_m(dc, 0, memsize);
1643 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1644 do_postinc(dc, memsize);
1645 return insn_len;
1646}
1647
1648static unsigned int dec_test_m(DisasContext *dc)
1649{
1650 int memsize = memsize_zz(dc);
1651 int insn_len;
1652 DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1653 memsize_char(memsize),
1654 dc->op1, dc->postinc ? "+]" : "]",
1655 dc->op2));
1656
1657 cris_cc_mask(dc, CC_MASK_NZ);
1658 gen_op_clrf(3);
1659 insn_len = dec_prep_alu_m(dc, 0, memsize);
05ba7d5f
EI
1660 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1661 tcg_gen_movi_tl(cpu_T[1], 0);
8170028d
TS
1662 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1663 do_postinc(dc, memsize);
1664 return insn_len;
1665}
1666
1667static unsigned int dec_and_m(DisasContext *dc)
1668{
1669 int memsize = memsize_zz(dc);
1670 int insn_len;
1671 DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1672 memsize_char(memsize),
1673 dc->op1, dc->postinc ? "+]" : "]",
1674 dc->op2));
1675
1676 cris_cc_mask(dc, CC_MASK_NZ);
1677 insn_len = dec_prep_alu_m(dc, 0, memsize);
1678 crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1679 do_postinc(dc, memsize);
1680 return insn_len;
1681}
1682
1683static unsigned int dec_add_m(DisasContext *dc)
1684{
1685 int memsize = memsize_zz(dc);
1686 int insn_len;
1687 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1688 memsize_char(memsize),
1689 dc->op1, dc->postinc ? "+]" : "]",
1690 dc->op2));
1691
1692 cris_cc_mask(dc, CC_MASK_NZVC);
1693 insn_len = dec_prep_alu_m(dc, 0, memsize);
1694 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1695 do_postinc(dc, memsize);
1696 return insn_len;
1697}
1698
1699static unsigned int dec_addo_m(DisasContext *dc)
1700{
1701 int memsize = memsize_zz(dc);
1702 int insn_len;
1703 DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1704 memsize_char(memsize),
1705 dc->op1, dc->postinc ? "+]" : "]",
1706 dc->op2));
1707
1708 cris_cc_mask(dc, 0);
1709 insn_len = dec_prep_alu_m(dc, 1, memsize);
9004627f 1710 crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
8170028d
TS
1711 do_postinc(dc, memsize);
1712 return insn_len;
1713}
1714
1715static unsigned int dec_bound_m(DisasContext *dc)
1716{
1717 int memsize = memsize_zz(dc);
1718 int insn_len;
1719 DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1720 memsize_char(memsize),
1721 dc->op1, dc->postinc ? "+]" : "]",
1722 dc->op2));
1723
1724 cris_cc_mask(dc, CC_MASK_NZ);
1725 insn_len = dec_prep_alu_m(dc, 0, memsize);
1726 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1727 do_postinc(dc, memsize);
1728 return insn_len;
1729}
1730
1731static unsigned int dec_addc_mr(DisasContext *dc)
1732{
1733 int insn_len = 2;
1734 DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1735 dc->op1, dc->postinc ? "+]" : "]",
1736 dc->op2));
1737
1738 cris_evaluate_flags(dc);
1739 cris_cc_mask(dc, CC_MASK_NZVC);
1740 insn_len = dec_prep_alu_m(dc, 0, 4);
1741 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1742 do_postinc(dc, 4);
1743 return insn_len;
1744}
1745
1746static unsigned int dec_sub_m(DisasContext *dc)
1747{
1748 int memsize = memsize_zz(dc);
1749 int insn_len;
1750 DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1751 memsize_char(memsize),
1752 dc->op1, dc->postinc ? "+]" : "]",
1753 dc->op2, dc->ir, dc->zzsize));
1754
1755 cris_cc_mask(dc, CC_MASK_NZVC);
1756 insn_len = dec_prep_alu_m(dc, 0, memsize);
1757 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1758 do_postinc(dc, memsize);
1759 return insn_len;
1760}
1761
1762static unsigned int dec_or_m(DisasContext *dc)
1763{
1764 int memsize = memsize_zz(dc);
1765 int insn_len;
1766 DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1767 memsize_char(memsize),
1768 dc->op1, dc->postinc ? "+]" : "]",
1769 dc->op2, dc->pc));
1770
1771 cris_cc_mask(dc, CC_MASK_NZ);
1772 insn_len = dec_prep_alu_m(dc, 0, memsize);
1773 crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1774 do_postinc(dc, memsize);
1775 return insn_len;
1776}
1777
1778static unsigned int dec_move_mp(DisasContext *dc)
1779{
1780 int memsize = memsize_zz(dc);
1781 int insn_len = 2;
1782
1783 DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1784 memsize_char(memsize),
1785 dc->op1,
1786 dc->postinc ? "+]" : "]",
1787 dc->op2));
1788
1789 cris_cc_mask(dc, 0);
1790 insn_len = dec_prep_alu_m(dc, 0, memsize);
05ba7d5f 1791 t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
8170028d
TS
1792
1793 do_postinc(dc, memsize);
1794 return insn_len;
1795}
1796
1797static unsigned int dec_move_pm(DisasContext *dc)
1798{
1799 int memsize;
1800
1801 memsize = preg_sizes[dc->op2];
1802
fd56059f
AZ
1803 DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
1804 memsize_char(memsize),
1805 dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
8170028d
TS
1806
1807 cris_cc_mask(dc, 0);
fd56059f 1808 /* prepare store. Address in T0, value in T1. */
05ba7d5f
EI
1809 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1810 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d
TS
1811 gen_store_T0_T1(dc, memsize);
1812 if (dc->postinc)
1813 {
05ba7d5f
EI
1814 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
1815 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
8170028d
TS
1816 }
1817 return 2;
1818}
1819
1820static unsigned int dec_movem_mr(DisasContext *dc)
1821{
1822 int i;
1823
1824 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
1825 dc->postinc ? "+]" : "]", dc->op2));
1826
1827 cris_cc_mask(dc, 0);
05ba7d5f
EI
1828 /* fetch the address into T0 and T1. */
1829 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
8170028d
TS
1830 for (i = 0; i <= dc->op2; i++) {
1831 /* Perform the load onto regnum i. Always dword wide. */
05ba7d5f 1832 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
8170028d 1833 gen_load_T0_T0(dc, 4, 0);
05ba7d5f
EI
1834 t_gen_mov_reg_TN(i, cpu_T[0]);
1835 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
8170028d 1836 }
05ba7d5f
EI
1837 /* writeback the updated pointer value. */
1838 if (dc->postinc)
1839 t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
8170028d
TS
1840 return 2;
1841}
1842
1843static unsigned int dec_movem_rm(DisasContext *dc)
1844{
1845 int i;
1846
1847 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
1848 dc->postinc ? "+]" : "]"));
1849
1850 cris_cc_mask(dc, 0);
1851 for (i = 0; i <= dc->op2; i++) {
1852 /* Fetch register i into T1. */
05ba7d5f 1853 t_gen_mov_TN_reg(cpu_T[1], i);
8170028d 1854 /* Fetch the address into T0. */
05ba7d5f 1855 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d 1856 /* Displace it. */
05ba7d5f 1857 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], i * 4);
8170028d
TS
1858 /* Perform the store. */
1859 gen_store_T0_T1(dc, 4);
1860 }
1861 if (dc->postinc) {
05ba7d5f
EI
1862 /* T0 should point to the last written addr, advance one more
1863 step. */
1864 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 4);
8170028d 1865 /* writeback the updated pointer value. */
05ba7d5f 1866 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
8170028d
TS
1867 }
1868 return 2;
1869}
1870
1871static unsigned int dec_move_rm(DisasContext *dc)
1872{
1873 int memsize;
1874
1875 memsize = memsize_zz(dc);
1876
1877 DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
1878 memsize, dc->op2, dc->op1));
1879
1880 cris_cc_mask(dc, 0);
1881 /* prepare store. */
05ba7d5f
EI
1882 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1883 t_gen_mov_TN_reg(cpu_T[1], dc->op2);
8170028d
TS
1884 gen_store_T0_T1(dc, memsize);
1885 if (dc->postinc)
1886 {
05ba7d5f
EI
1887 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
1888 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
8170028d
TS
1889 }
1890 return 2;
1891}
1892
8170028d
TS
1893static unsigned int dec_lapcq(DisasContext *dc)
1894{
1895 DIS(fprintf (logfile, "lapcq %x, $r%u\n",
1896 dc->pc + dc->op1*2, dc->op2));
1897 cris_cc_mask(dc, 0);
05ba7d5f 1898 tcg_gen_movi_tl(cpu_T[1], dc->pc + dc->op1 * 2);
8170028d
TS
1899 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1900 return 2;
1901}
1902
1903static unsigned int dec_lapc_im(DisasContext *dc)
1904{
1905 unsigned int rd;
1906 int32_t imm;
8170028d
TS
1907
1908 rd = dc->op2;
1909
1910 cris_cc_mask(dc, 0);
1911 imm = ldl_code(dc->pc + 2);
1912 DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
05ba7d5f
EI
1913 t_gen_mov_reg_TN(rd, tcg_const_i32(dc->pc + imm));
1914 return 6;
8170028d
TS
1915}
1916
1917/* Jump to special reg. */
1918static unsigned int dec_jump_p(DisasContext *dc)
1919{
1920 DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
1921 cris_cc_mask(dc, 0);
1922 /* Store the return address in Pd. */
05ba7d5f 1923 t_gen_mov_TN_preg(cpu_T[0], dc->op2);
8170028d
TS
1924 gen_op_movl_btarget_T0();
1925 cris_prepare_dyn_jmp(dc);
1926 return 2;
1927}
1928
1929/* Jump and save. */
1930static unsigned int dec_jas_r(DisasContext *dc)
1931{
1932 DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
1933 cris_cc_mask(dc, 0);
1934 /* Stor the return address in Pd. */
05ba7d5f 1935 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d 1936 gen_op_movl_btarget_T0();
05ba7d5f
EI
1937 tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
1938 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
1939 cris_prepare_dyn_jmp(dc);
1940 return 2;
1941}
1942
1943static unsigned int dec_jas_im(DisasContext *dc)
1944{
1945 uint32_t imm;
1946
1947 imm = ldl_code(dc->pc + 2);
1948
1949 DIS(fprintf (logfile, "jas 0x%x\n", imm));
1950 cris_cc_mask(dc, 0);
1951 /* Stor the return address in Pd. */
05ba7d5f 1952 tcg_gen_movi_tl(cpu_T[0], imm);
8170028d 1953 gen_op_movl_btarget_T0();
05ba7d5f
EI
1954 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
1955 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
1956 cris_prepare_dyn_jmp(dc);
1957 return 6;
1958}
1959
1960static unsigned int dec_jasc_im(DisasContext *dc)
1961{
1962 uint32_t imm;
1963
1964 imm = ldl_code(dc->pc + 2);
1965
1966 DIS(fprintf (logfile, "jasc 0x%x\n", imm));
1967 cris_cc_mask(dc, 0);
1968 /* Stor the return address in Pd. */
05ba7d5f 1969 tcg_gen_movi_tl(cpu_T[0], imm);
8170028d 1970 gen_op_movl_btarget_T0();
05ba7d5f
EI
1971 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
1972 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
1973 cris_prepare_dyn_jmp(dc);
1974 return 6;
1975}
1976
1977static unsigned int dec_jasc_r(DisasContext *dc)
1978{
1979 DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
1980 cris_cc_mask(dc, 0);
1981 /* Stor the return address in Pd. */
05ba7d5f 1982 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
8170028d 1983 gen_op_movl_btarget_T0();
05ba7d5f
EI
1984 tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
1985 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
1986 cris_prepare_dyn_jmp(dc);
1987 return 2;
1988}
1989
1990static unsigned int dec_bcc_im(DisasContext *dc)
1991{
1992 int32_t offset;
1993 uint32_t cond = dc->op2;
1994
1995 offset = ldl_code(dc->pc + 2);
1996 offset = sign_extend(offset, 15);
1997
1998 DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
1999 cc_name(cond), offset,
2000 dc->pc, dc->pc + offset));
2001
2002 cris_cc_mask(dc, 0);
2003 /* op2 holds the condition-code. */
2004 cris_prepare_cc_branch (dc, offset, cond);
2005 return 4;
2006}
2007
2008static unsigned int dec_bas_im(DisasContext *dc)
2009{
2010 int32_t simm;
2011
2012
2013 simm = ldl_code(dc->pc + 2);
2014
2015 DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2016 cris_cc_mask(dc, 0);
2017 /* Stor the return address in Pd. */
05ba7d5f 2018 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
8170028d 2019 gen_op_movl_btarget_T0();
05ba7d5f
EI
2020 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
2021 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
2022 cris_prepare_dyn_jmp(dc);
2023 return 6;
2024}
2025
2026static unsigned int dec_basc_im(DisasContext *dc)
2027{
2028 int32_t simm;
2029 simm = ldl_code(dc->pc + 2);
2030
2031 DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2032 cris_cc_mask(dc, 0);
2033 /* Stor the return address in Pd. */
05ba7d5f 2034 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
8170028d 2035 gen_op_movl_btarget_T0();
05ba7d5f
EI
2036 tcg_gen_movi_tl(cpu_T[0], dc->pc + 12);
2037 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
8170028d
TS
2038 cris_prepare_dyn_jmp(dc);
2039 return 6;
2040}
2041
2042static unsigned int dec_rfe_etc(DisasContext *dc)
2043{
2044 DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2045 dc->opcode, dc->pc, dc->op1, dc->op2));
2046
2047 cris_cc_mask(dc, 0);
2048
2049 if (dc->op2 == 15) /* ignore halt. */
05ba7d5f 2050 return 2;
8170028d
TS
2051
2052 switch (dc->op2 & 7) {
2053 case 2:
2054 /* rfe. */
2055 cris_evaluate_flags(dc);
2056 gen_op_ccs_rshift();
2057 break;
2058 case 5:
2059 /* rfn. */
2060 BUG();
2061 break;
2062 case 6:
2063 /* break. */
05ba7d5f 2064 tcg_gen_movi_tl(cpu_T[0], dc->pc);
8170028d
TS
2065 gen_op_movl_pc_T0();
2066 /* Breaks start at 16 in the exception vector. */
2067 gen_op_break_im(dc->op1 + 16);
4f400ab5 2068 dc->is_jmp = DISAS_SWI;
8170028d
TS
2069 break;
2070 default:
2071 printf ("op2=%x\n", dc->op2);
2072 BUG();
2073 break;
2074
2075 }
8170028d
TS
2076 return 2;
2077}
2078
5d4a534d
EI
2079static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2080{
2081 /* Ignore D-cache flushes. */
2082 return 2;
2083}
2084
2085static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2086{
2087 /* Ignore I-cache flushes. */
2088 return 2;
2089}
2090
8170028d
TS
2091static unsigned int dec_null(DisasContext *dc)
2092{
2093 printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2094 dc->pc, dc->opcode, dc->op1, dc->op2);
2095 fflush(NULL);
2096 BUG();
2097 return 2;
2098}
2099
2100struct decoder_info {
2101 struct {
2102 uint32_t bits;
2103 uint32_t mask;
2104 };
2105 unsigned int (*dec)(DisasContext *dc);
2106} decinfo[] = {
2107 /* Order matters here. */
2108 {DEC_MOVEQ, dec_moveq},
2109 {DEC_BTSTQ, dec_btstq},
2110 {DEC_CMPQ, dec_cmpq},
2111 {DEC_ADDOQ, dec_addoq},
2112 {DEC_ADDQ, dec_addq},
2113 {DEC_SUBQ, dec_subq},
2114 {DEC_ANDQ, dec_andq},
2115 {DEC_ORQ, dec_orq},
2116 {DEC_ASRQ, dec_asrq},
2117 {DEC_LSLQ, dec_lslq},
2118 {DEC_LSRQ, dec_lsrq},
2119 {DEC_BCCQ, dec_bccq},
2120
2121 {DEC_BCC_IM, dec_bcc_im},
2122 {DEC_JAS_IM, dec_jas_im},
2123 {DEC_JAS_R, dec_jas_r},
2124 {DEC_JASC_IM, dec_jasc_im},
2125 {DEC_JASC_R, dec_jasc_r},
2126 {DEC_BAS_IM, dec_bas_im},
2127 {DEC_BASC_IM, dec_basc_im},
2128 {DEC_JUMP_P, dec_jump_p},
2129 {DEC_LAPC_IM, dec_lapc_im},
2130 {DEC_LAPCQ, dec_lapcq},
2131
2132 {DEC_RFE_ETC, dec_rfe_etc},
2133 {DEC_ADDC_MR, dec_addc_mr},
2134
2135 {DEC_MOVE_MP, dec_move_mp},
2136 {DEC_MOVE_PM, dec_move_pm},
2137 {DEC_MOVEM_MR, dec_movem_mr},
2138 {DEC_MOVEM_RM, dec_movem_rm},
2139 {DEC_MOVE_PR, dec_move_pr},
2140 {DEC_SCC_R, dec_scc_r},
2141 {DEC_SETF, dec_setclrf},
2142 {DEC_CLEARF, dec_setclrf},
2143
2144 {DEC_MOVE_SR, dec_move_sr},
2145 {DEC_MOVE_RP, dec_move_rp},
2146 {DEC_SWAP_R, dec_swap_r},
2147 {DEC_ABS_R, dec_abs_r},
2148 {DEC_LZ_R, dec_lz_r},
2149 {DEC_MOVE_RS, dec_move_rs},
2150 {DEC_BTST_R, dec_btst_r},
2151 {DEC_ADDC_R, dec_addc_r},
2152
2153 {DEC_DSTEP_R, dec_dstep_r},
2154 {DEC_XOR_R, dec_xor_r},
2155 {DEC_MCP_R, dec_mcp_r},
2156 {DEC_CMP_R, dec_cmp_r},
2157
2158 {DEC_ADDI_R, dec_addi_r},
2159 {DEC_ADDI_ACR, dec_addi_acr},
2160
2161 {DEC_ADD_R, dec_add_r},
2162 {DEC_SUB_R, dec_sub_r},
2163
2164 {DEC_ADDU_R, dec_addu_r},
2165 {DEC_ADDS_R, dec_adds_r},
2166 {DEC_SUBU_R, dec_subu_r},
2167 {DEC_SUBS_R, dec_subs_r},
2168 {DEC_LSL_R, dec_lsl_r},
2169
2170 {DEC_AND_R, dec_and_r},
2171 {DEC_OR_R, dec_or_r},
2172 {DEC_BOUND_R, dec_bound_r},
2173 {DEC_ASR_R, dec_asr_r},
2174 {DEC_LSR_R, dec_lsr_r},
2175
2176 {DEC_MOVU_R, dec_movu_r},
2177 {DEC_MOVS_R, dec_movs_r},
2178 {DEC_NEG_R, dec_neg_r},
2179 {DEC_MOVE_R, dec_move_r},
2180
5d4a534d
EI
2181 {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2182 {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
8170028d
TS
2183
2184 {DEC_MULS_R, dec_muls_r},
2185 {DEC_MULU_R, dec_mulu_r},
2186
2187 {DEC_ADDU_M, dec_addu_m},
2188 {DEC_ADDS_M, dec_adds_m},
2189 {DEC_SUBU_M, dec_subu_m},
2190 {DEC_SUBS_M, dec_subs_m},
2191
2192 {DEC_CMPU_M, dec_cmpu_m},
2193 {DEC_CMPS_M, dec_cmps_m},
2194 {DEC_MOVU_M, dec_movu_m},
2195 {DEC_MOVS_M, dec_movs_m},
2196
2197 {DEC_CMP_M, dec_cmp_m},
2198 {DEC_ADDO_M, dec_addo_m},
2199 {DEC_BOUND_M, dec_bound_m},
2200 {DEC_ADD_M, dec_add_m},
2201 {DEC_SUB_M, dec_sub_m},
2202 {DEC_AND_M, dec_and_m},
2203 {DEC_OR_M, dec_or_m},
2204 {DEC_MOVE_RM, dec_move_rm},
2205 {DEC_TEST_M, dec_test_m},
2206 {DEC_MOVE_MR, dec_move_mr},
2207
2208 {{0, 0}, dec_null}
2209};
2210
2211static inline unsigned int
2212cris_decoder(DisasContext *dc)
2213{
2214 unsigned int insn_len = 2;
2215 uint32_t tmp;
2216 int i;
2217
2218 /* Load a halfword onto the instruction register. */
2219 tmp = ldl_code(dc->pc);
2220 dc->ir = tmp & 0xffff;
2221
2222 /* Now decode it. */
2223 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
2224 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
2225 dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
2226 dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
2227 dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
2228 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
2229
2230 /* Large switch for all insns. */
2231 for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2232 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2233 {
2234 insn_len = decinfo[i].dec(dc);
2235 break;
2236 }
2237 }
2238
2239 return insn_len;
2240}
2241
2242static void check_breakpoint(CPUState *env, DisasContext *dc)
2243{
2244 int j;
2245 if (env->nb_breakpoints > 0) {
2246 for(j = 0; j < env->nb_breakpoints; j++) {
2247 if (env->breakpoints[j] == dc->pc) {
2248 cris_evaluate_flags (dc);
05ba7d5f 2249 tcg_gen_movi_tl(cpu_T[0], dc->pc);
8170028d
TS
2250 gen_op_movl_pc_T0();
2251 gen_op_debug();
2252 dc->is_jmp = DISAS_UPDATE;
2253 }
2254 }
2255 }
2256}
2257
8170028d
TS
2258/* generate intermediate code for basic block 'tb'. */
2259struct DisasContext ctx;
2260static int
2261gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2262 int search_pc)
2263{
2264 uint16_t *gen_opc_end;
2265 uint32_t pc_start;
2266 unsigned int insn_len;
2267 int j, lj;
2268 struct DisasContext *dc = &ctx;
2269 uint32_t next_page_start;
2270
2271 pc_start = tb->pc;
2272 dc->env = env;
2273 dc->tb = tb;
2274
8170028d 2275 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8170028d
TS
2276
2277 dc->is_jmp = DISAS_NEXT;
2278 dc->pc = pc_start;
2279 dc->singlestep_enabled = env->singlestep_enabled;
2280 dc->flagx_live = 0;
2281 dc->flags_x = 0;
2282 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2283 lj = -1;
2284 do
2285 {
2286 check_breakpoint(env, dc);
4f400ab5
EI
2287 if (dc->is_jmp == DISAS_JUMP
2288 || dc->is_jmp == DISAS_SWI)
8170028d
TS
2289 goto done;
2290
2291 if (search_pc) {
2292 j = gen_opc_ptr - gen_opc_buf;
2293 if (lj < j) {
2294 lj++;
2295 while (lj < j)
2296 gen_opc_instr_start[lj++] = 0;
2297 }
2298 gen_opc_pc[lj] = dc->pc;
2299 gen_opc_instr_start[lj] = 1;
2300 }
2301
2302 insn_len = cris_decoder(dc);
2303 STATS(gen_op_exec_insn());
2304 dc->pc += insn_len;
2305 if (!dc->flagx_live
2306 || (dc->flagx_live &&
2307 !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
05ba7d5f 2308 cris_clear_x_flag(dc);
8170028d
TS
2309 }
2310
2311 /* Check for delayed branches here. If we do it before
2312 actually genereating any host code, the simulator will just
2313 loop doing nothing for on this program location. */
2314 if (dc->delayed_branch) {
2315 dc->delayed_branch--;
2316 if (dc->delayed_branch == 0)
2317 {
2318 if (dc->bcc == CC_A) {
57fec1fe 2319 gen_op_jmp1 ();
8170028d
TS
2320 dc->is_jmp = DISAS_UPDATE;
2321 }
2322 else {
2323 /* Conditional jmp. */
2324 gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2325 dc->is_jmp = DISAS_UPDATE;
2326 }
2327 }
2328 }
2329
2330 if (env->singlestep_enabled)
2331 break;
2332 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2333 && dc->pc < next_page_start);
2334
2335 if (!dc->is_jmp) {
2336 gen_op_movl_T0_im((long)dc->pc);
2337 gen_op_movl_pc_T0();
2338 }
2339
2340 cris_evaluate_flags (dc);
2341 done:
2342 if (__builtin_expect(env->singlestep_enabled, 0)) {
2343 gen_op_debug();
2344 } else {
2345 switch(dc->is_jmp) {
2346 case DISAS_NEXT:
2347 gen_goto_tb(dc, 1, dc->pc);
2348 break;
2349 default:
2350 case DISAS_JUMP:
2351 case DISAS_UPDATE:
2352 /* indicate that the hash table must be used
2353 to find the next TB */
57fec1fe 2354 tcg_gen_exit_tb(0);
8170028d 2355 break;
4f400ab5 2356 case DISAS_SWI:
8170028d
TS
2357 case DISAS_TB_JUMP:
2358 /* nothing more to generate */
2359 break;
2360 }
2361 }
2362 *gen_opc_ptr = INDEX_op_end;
2363 if (search_pc) {
2364 j = gen_opc_ptr - gen_opc_buf;
2365 lj++;
2366 while (lj <= j)
2367 gen_opc_instr_start[lj++] = 0;
2368 } else {
2369 tb->size = dc->pc - pc_start;
2370 }
2371
2372#ifdef DEBUG_DISAS
2373 if (loglevel & CPU_LOG_TB_IN_ASM) {
2374 fprintf(logfile, "--------------\n");
2375 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2376 target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2377 fprintf(logfile, "\n");
8170028d
TS
2378 }
2379#endif
2380 return 0;
2381}
2382
2383int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2384{
2385 return gen_intermediate_code_internal(env, tb, 0);
2386}
2387
2388int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2389{
2390 return gen_intermediate_code_internal(env, tb, 1);
2391}
2392
2393void cpu_dump_state (CPUState *env, FILE *f,
2394 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2395 int flags)
2396{
2397 int i;
2398 uint32_t srs;
2399
2400 if (!env || !f)
2401 return;
2402
2403 cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2404 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2405 "debug=%x %x %x\n",
9004627f 2406 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
8170028d
TS
2407 env->cc_op,
2408 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2409 env->debug1, env->debug2, env->debug3);
2410
2411 for (i = 0; i < 16; i++) {
2412 cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2413 if ((i + 1) % 4 == 0)
2414 cpu_fprintf(f, "\n");
2415 }
2416 cpu_fprintf(f, "\nspecial regs:\n");
2417 for (i = 0; i < 16; i++) {
2418 cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2419 if ((i + 1) % 4 == 0)
2420 cpu_fprintf(f, "\n");
2421 }
9004627f 2422 srs = env->pregs[PR_SRS];
8170028d
TS
2423 cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2424 if (srs < 256) {
2425 for (i = 0; i < 16; i++) {
2426 cpu_fprintf(f, "s%2.2d=%8.8x ",
2427 i, env->sregs[srs][i]);
2428 if ((i + 1) % 4 == 0)
2429 cpu_fprintf(f, "\n");
2430 }
2431 }
2432 cpu_fprintf(f, "\n\n");
2433
2434}
2435
05ba7d5f
EI
2436static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
2437{
2438}
2439
aaed909a 2440CPUCRISState *cpu_cris_init (const char *cpu_model)
8170028d
TS
2441{
2442 CPUCRISState *env;
2443
2444 env = qemu_mallocz(sizeof(CPUCRISState));
2445 if (!env)
2446 return NULL;
2447 cpu_exec_init(env);
05ba7d5f
EI
2448
2449 tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
2450 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
2451#if TARGET_LONG_BITS > HOST_LONG_BITS
2452 cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
2453 TCG_AREG0, offsetof(CPUState, t0), "T0");
2454 cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
2455 TCG_AREG0, offsetof(CPUState, t1), "T1");
2456#else
2457 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
2458 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
2459#endif
2460
8170028d
TS
2461 cpu_reset(env);
2462 return env;
2463}
2464
2465void cpu_reset (CPUCRISState *env)
2466{
2467 memset(env, 0, offsetof(CPUCRISState, breakpoints));
2468 tlb_flush(env, 1);
2469}