Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 4f400ab5

History | View | Annotate | Download (55.9 kB)

1
/*
2
 *  CRIS emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2007 AXIS Communications AB
5
 *  Written by Edgar E. Iglesias.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21

    
22
/*
23
 * This file implements a CRIS decoder-stage in SW. The decoder translates the
24
 * guest (CRIS) machine-code into host machine code via dyngen using the
25
 * micro-operations described in op.c
26
 *
27
 * The micro-operations for CRIS translation implement a RISC style ISA.
28
 * Note that the micro-operations typically order their operands
29
 * starting with the dst. CRIS asm, does the opposite.
30
 *
31
 * For example the following CRIS code:
32
 * add.d [$r0], $r1
33
 *
34
 * translates into:
35
 *
36
 * gen_movl_T0_reg(0);   // Fetch $r0 into T0
37
 * gen_load_T0_T0();     // Load T0, @T0
38
 * gen_movl_reg_T0(1);   // Writeback T0 into $r1
39
 *
40
 * The actual names for the micro-code generators vary but the example
41
 * illustrates the point.
42
 */
43

    
44
#include <stdarg.h>
45
#include <stdlib.h>
46
#include <stdio.h>
47
#include <string.h>
48
#include <inttypes.h>
49
#include <assert.h>
50

    
51
#include "cpu.h"
52
#include "exec-all.h"
53
#include "disas.h"
54
#include "tcg-op.h"
55
#include "crisv32-decode.h"
56

    
57
#define CRIS_STATS 0
58
#if CRIS_STATS
59
#define STATS(x) x
60
#else
61
#define STATS(x)
62
#endif
63

    
64
#define DISAS_CRIS 0
65
#if DISAS_CRIS
66
#define DIS(x) x
67
#else
68
#define DIS(x)
69
#endif
70

    
71
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
72
#define BUG_ON(x) ({if (x) BUG();})
73

    
74
#define DISAS_SWI 5
75

    
76
/* Used by the decoder.  */
77
#define EXTRACT_FIELD(src, start, end) \
78
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
79

    
80
#define CC_MASK_NZ 0xc
81
#define CC_MASK_NZV 0xe
82
#define CC_MASK_NZVC 0xf
83
#define CC_MASK_RNZV 0x10e
84

    
85
/* This is the state at translation time.  */
86
typedef struct DisasContext {
87
        CPUState *env;
88
        target_ulong pc, insn_pc;
89

    
90
        /* Decoder.  */
91
        uint32_t ir;
92
        uint32_t opcode;
93
        unsigned int op1;
94
        unsigned int op2;
95
        unsigned int zsize, zzsize;
96
        unsigned int mode;
97
        unsigned int postinc;
98

    
99
        int update_cc;
100
        int cc_op;
101
        int cc_size;
102
        uint32_t cc_mask;
103
        int flags_live;
104
        int flagx_live;
105
        int flags_x;
106
        uint32_t tb_entry_flags;
107

    
108
        int memidx; /* user or kernel mode.  */
109
        int is_jmp;
110
        int dyn_jmp;
111

    
112
        uint32_t delayed_pc;
113
        int delayed_branch;
114
        int bcc;
115
        uint32_t condlabel;
116

    
117
        struct TranslationBlock *tb;
118
        int singlestep_enabled;
119
} DisasContext;
120

    
121
void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
122
static void gen_BUG(DisasContext *dc, char *file, int line)
123
{
124
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
125
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
126
        cpu_dump_state (dc->env, stdout, fprintf, 0);
127
        fflush(NULL);
128
        cris_prepare_jmp (dc, 0x70000000 + line);
129
}
130

    
131
/* Table to generate quick moves from T0 onto any register.  */
132
static GenOpFunc *gen_movl_reg_T0[16] =
133
{
134
        gen_op_movl_r0_T0, gen_op_movl_r1_T0,
135
        gen_op_movl_r2_T0, gen_op_movl_r3_T0,
136
        gen_op_movl_r4_T0, gen_op_movl_r5_T0,
137
        gen_op_movl_r6_T0, gen_op_movl_r7_T0,
138
        gen_op_movl_r8_T0, gen_op_movl_r9_T0,
139
        gen_op_movl_r10_T0, gen_op_movl_r11_T0,
140
        gen_op_movl_r12_T0, gen_op_movl_r13_T0,
141
        gen_op_movl_r14_T0, gen_op_movl_r15_T0,
142
};
143
static GenOpFunc *gen_movl_T0_reg[16] =
144
{
145
        gen_op_movl_T0_r0, gen_op_movl_T0_r1,
146
        gen_op_movl_T0_r2, gen_op_movl_T0_r3,
147
        gen_op_movl_T0_r4, gen_op_movl_T0_r5,
148
        gen_op_movl_T0_r6, gen_op_movl_T0_r7,
149
        gen_op_movl_T0_r8, gen_op_movl_T0_r9,
150
        gen_op_movl_T0_r10, gen_op_movl_T0_r11,
151
        gen_op_movl_T0_r12, gen_op_movl_T0_r13,
152
        gen_op_movl_T0_r14, gen_op_movl_T0_r15,
153
};
154

    
155
static void noop_write(void) {
156
        /* nop.  */
157
}
158

    
159
static void gen_vr_read(void) {
160
        gen_op_movl_T0_im(32);
161
}
162

    
163
static void gen_movl_T0_p0(void) {
164
        gen_op_movl_T0_im(0);
165
}
166

    
167
static void gen_ccs_read(void) {
168
        gen_op_movl_T0_p13();
169
}
170

    
171
static void gen_ccs_write(void) {
172
        gen_op_movl_p13_T0();
173
}
174

    
175
/* Table to generate quick moves from T0 onto any register.  */
176
static GenOpFunc *gen_movl_preg_T0[16] =
177
{
178
        noop_write,  /* bz, not writeable.  */
179
        noop_write,  /* vr, not writeable.  */
180
        gen_op_movl_p2_T0, gen_op_movl_p3_T0,
181
        noop_write,  /* wz, not writeable.  */
182
        gen_op_movl_p5_T0,
183
        gen_op_movl_p6_T0, gen_op_movl_p7_T0,
184
        noop_write,  /* dz, not writeable.  */
185
        gen_op_movl_p9_T0,
186
        gen_op_movl_p10_T0, gen_op_movl_p11_T0,
187
        gen_op_movl_p12_T0,
188
        gen_ccs_write, /* ccs needs special treatment.  */
189
        gen_op_movl_p14_T0, gen_op_movl_p15_T0,
190
};
191
static GenOpFunc *gen_movl_T0_preg[16] =
192
{
193
        gen_movl_T0_p0,
194
        gen_vr_read,
195
        gen_op_movl_T0_p2, gen_op_movl_T0_p3,
196
        gen_op_movl_T0_p4, gen_op_movl_T0_p5,
197
        gen_op_movl_T0_p6, gen_op_movl_T0_p7,
198
        gen_op_movl_T0_p8, gen_op_movl_T0_p9,
199
        gen_op_movl_T0_p10, gen_op_movl_T0_p11,
200
        gen_op_movl_T0_p12,
201
        gen_ccs_read, /* ccs needs special treatment.  */
202
        gen_op_movl_T0_p14, gen_op_movl_T0_p15,
203
};
204

    
205
/* We need this table to handle moves with implicit width.  */
206
int preg_sizes[] = {
207
        1, /* bz.  */
208
        1, /* vr.  */
209
        4, /* pid.  */
210
        1, /* srs.  */
211
        2, /* wz.  */
212
        4, 4, 4,
213
        4, 4, 4, 4,
214
        4, 4, 4, 4,
215
};
216

    
217
#ifdef CONFIG_USER_ONLY
218
#define GEN_OP_LD(width, reg) \
219
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
220
    gen_op_ld##width##_T0_##reg##_raw(); \
221
  }
222
#define GEN_OP_ST(width, reg) \
223
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
224
    gen_op_st##width##_##reg##_T1_raw(); \
225
  }
226
#else
227
#define GEN_OP_LD(width, reg) \
228
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
229
    if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
230
    else gen_op_ld##width##_T0_##reg##_user();\
231
  }
232
#define GEN_OP_ST(width, reg) \
233
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
234
    if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
235
    else gen_op_st##width##_##reg##_T1_user();\
236
  }
237
#endif
238

    
239
GEN_OP_LD(ub, T0)
240
GEN_OP_LD(b, T0)
241
GEN_OP_ST(b, T0)
242
GEN_OP_LD(uw, T0)
243
GEN_OP_LD(w, T0)
244
GEN_OP_ST(w, T0)
245
GEN_OP_LD(l, T0)
246
GEN_OP_ST(l, T0)
247

    
248
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
249
{
250
        TranslationBlock *tb;
251
        tb = dc->tb;
252
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
253
#if 0
254
            /* XXX: this code is not finished */
255
            tcg_gen_goto_tb(n);
256
#endif
257
            tcg_gen_exit_tb(0);
258
        } else {
259
            tcg_gen_exit_tb(0);
260
        }
261
}
262

    
263
/* Sign extend at translation time.  */
264
static int sign_extend(unsigned int val, unsigned int width)
265
{
266
        int sval;
267

    
268
        /* LSL.  */
269
        val <<= 31 - width;
270
        sval = val;
271
        /* ASR.  */
272
        sval >>= 31 - width;
273
        return sval;
274
}
275

    
276
static void cris_evaluate_flags(DisasContext *dc)
277
{
278
        if (!dc->flags_live) {
279

    
280
                switch (dc->cc_op)
281
                {
282
                        case CC_OP_MCP:
283
                                gen_op_evaluate_flags_mcp ();
284
                                break;
285
                        case CC_OP_MULS:
286
                                gen_op_evaluate_flags_muls ();
287
                                break;
288
                        case CC_OP_MULU:
289
                                gen_op_evaluate_flags_mulu ();
290
                                break;
291
                        case CC_OP_MOVE:
292
                                switch (dc->cc_size)
293
                                {
294
                                        case 4:
295
                                                gen_op_evaluate_flags_move_4();
296
                                                break;
297
                                        case 2:
298
                                                gen_op_evaluate_flags_move_2();
299
                                                break;
300
                                        default:
301
                                                gen_op_evaluate_flags ();
302
                                                break;
303
                                }
304
                                break;
305

    
306
                        default:
307
                        {
308
                                switch (dc->cc_size)
309
                                {
310
                                        case 4:
311
                                                gen_op_evaluate_flags_alu_4 ();
312
                                                break;
313
                                        default:
314
                                                gen_op_evaluate_flags ();
315
                                                break;
316
                                }
317
                        }
318
                        break;
319
                }
320
                dc->flags_live = 1;
321
        }
322
}
323

    
324
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
325
{
326
        uint32_t ovl;
327

    
328
        /* Check if we need to evaluate the condition codes due to 
329
           CC overlaying.  */
330
        ovl = (dc->cc_mask ^ mask) & ~mask;
331
        if (ovl) {
332
                /* TODO: optimize this case. It trigs all the time.  */
333
                cris_evaluate_flags (dc);
334
        }
335
        dc->cc_mask = mask;
336

    
337
        dc->update_cc = 1;
338
        if (mask == 0)
339
                dc->update_cc = 0;
340
        else {
341
                gen_op_update_cc_mask(mask);
342
                dc->flags_live = 0;
343
        }
344
}
345

    
346
static void cris_update_cc_op(DisasContext *dc, int op)
347
{
348
        dc->cc_op = op;
349
        gen_op_update_cc_op(op);
350
        dc->flags_live = 0;
351
}
352
static void cris_update_cc_size(DisasContext *dc, int size)
353
{
354
        dc->cc_size = size;
355
        gen_op_update_cc_size_im(size);
356
}
357

    
358
/* op is the operation.
359
   T0, T1 are the operands.
360
   dst is the destination reg.
361
*/
362
static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
363
{
364
        int writeback = 1;
365
        if (dc->update_cc) {
366
                cris_update_cc_op(dc, op);
367
                cris_update_cc_size(dc, size);
368
                gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
369
                gen_op_update_cc_dest_T0();
370
        }
371

    
372
        /* Emit the ALU insns.  */
373
        switch (op)
374
        {
375
                case CC_OP_ADD:
376
                        gen_op_addl_T0_T1();
377
                        /* Extended arithmetics.  */
378
                        if (!dc->flagx_live)
379
                                gen_op_addxl_T0_C();
380
                        else if (dc->flags_x)
381
                                gen_op_addxl_T0_C();
382
                        break;
383
                case CC_OP_ADDC:
384
                        gen_op_addl_T0_T1();
385
                        gen_op_addl_T0_C();
386
                        break;
387
                case CC_OP_MCP:
388
                        gen_op_addl_T0_T1();
389
                        gen_op_addl_T0_R();
390
                        break;
391
                case CC_OP_SUB:
392
                        gen_op_negl_T1_T1();
393
                        gen_op_addl_T0_T1();
394
                        /* CRIS flag evaluation needs ~src.  */
395
                        gen_op_negl_T1_T1();
396
                        gen_op_not_T1_T1();
397

    
398
                        /* Extended arithmetics.  */
399
                        if (!dc->flagx_live)
400
                                gen_op_subxl_T0_C();
401
                        else if (dc->flags_x)
402
                                gen_op_subxl_T0_C();
403
                        break;
404
                case CC_OP_MOVE:
405
                        gen_op_movl_T0_T1();
406
                        break;
407
                case CC_OP_OR:
408
                        gen_op_orl_T0_T1();
409
                        break;
410
                case CC_OP_AND:
411
                        gen_op_andl_T0_T1();
412
                        break;
413
                case CC_OP_XOR:
414
                        gen_op_xorl_T0_T1();
415
                        break;
416
                case CC_OP_LSL:
417
                        gen_op_lsll_T0_T1();
418
                        break;
419
                case CC_OP_LSR:
420
                        gen_op_lsrl_T0_T1();
421
                        break;
422
                case CC_OP_ASR:
423
                        gen_op_asrl_T0_T1();
424
                        break;
425
                case CC_OP_NEG:
426
                        gen_op_negl_T0_T1();
427
                        /* Extended arithmetics.  */
428
                        gen_op_subxl_T0_C();
429
                        break;
430
                case CC_OP_LZ:
431
                        gen_op_lz_T0_T1();
432
                        break;
433
                case CC_OP_BTST:
434
                        gen_op_btst_T0_T1();
435
                        writeback = 0;
436
                        break;
437
                case CC_OP_MULS:
438
                        gen_op_muls_T0_T1();
439
                        break;
440
                case CC_OP_MULU:
441
                        gen_op_mulu_T0_T1();
442
                        break;
443
                case CC_OP_DSTEP:
444
                        gen_op_dstep_T0_T1();
445
                        break;
446
                case CC_OP_BOUND:
447
                        gen_op_bound_T0_T1();
448
                        break;
449
                case CC_OP_CMP:
450
                        gen_op_negl_T1_T1();
451
                        gen_op_addl_T0_T1();
452
                        /* CRIS flag evaluation needs ~src.  */
453
                        gen_op_negl_T1_T1();
454
                        gen_op_not_T1_T1();
455

    
456
                        /* Extended arithmetics.  */
457
                        gen_op_subxl_T0_C();
458
                        writeback = 0;
459
                        break;
460
                default:
461
                        fprintf (logfile, "illegal ALU op.\n");
462
                        BUG();
463
                        break;
464
        }
465

    
466
        if (dc->update_cc)
467
                gen_op_update_cc_src_T1();
468

    
469
        if (size == 1)
470
                gen_op_andl_T0_im(0xff);
471
        else if (size == 2)
472
                gen_op_andl_T0_im(0xffff);
473
        /* Writeback.  */
474
        if (writeback) {
475
                if (size == 4)
476
                        gen_movl_reg_T0[rd]();
477
                else {
478
                        gen_op_movl_T1_T0();
479
                        gen_movl_T0_reg[rd]();
480
                        if (size == 1)
481
                                gen_op_andl_T0_im(~0xff);
482
                        else
483
                                gen_op_andl_T0_im(~0xffff);
484
                        gen_op_orl_T0_T1();
485
                        gen_movl_reg_T0[rd]();
486
                        gen_op_movl_T0_T1();
487
                }
488
        }
489
        if (dc->update_cc)
490
                gen_op_update_cc_result_T0();
491

    
492
        {
493
                /* TODO: Optimize this.  */
494
                if (!dc->flagx_live)
495
                        cris_evaluate_flags(dc);
496
        }
497
}
498

    
499
static int arith_cc(DisasContext *dc)
500
{
501
        if (dc->update_cc) {
502
                switch (dc->cc_op) {
503
                        case CC_OP_ADD: return 1;
504
                        case CC_OP_SUB: return 1;
505
                        case CC_OP_LSL: return 1;
506
                        case CC_OP_LSR: return 1;
507
                        case CC_OP_ASR: return 1;
508
                        case CC_OP_CMP: return 1;
509
                        default:
510
                                return 0;
511
                }
512
        }
513
        return 0;
514
}
515

    
516
static void gen_tst_cc (DisasContext *dc, int cond)
517
{
518
        int arith_opt;
519

    
520
        /* TODO: optimize more condition codes.  */
521
        arith_opt = arith_cc(dc) && !dc->flags_live;
522
        switch (cond) {
523
                case CC_EQ:
524
                        if (arith_opt)
525
                                gen_op_tst_cc_eq_fast ();
526
                        else {
527
                                cris_evaluate_flags(dc);
528
                                gen_op_tst_cc_eq ();
529
                        }
530
                        break;
531
                case CC_NE:
532
                        if (arith_opt)
533
                                gen_op_tst_cc_ne_fast ();
534
                        else {
535
                                cris_evaluate_flags(dc);
536
                                gen_op_tst_cc_ne ();
537
                        }
538
                        break;
539
                case CC_CS:
540
                        cris_evaluate_flags(dc);
541
                        gen_op_tst_cc_cs ();
542
                        break;
543
                case CC_CC:
544
                        cris_evaluate_flags(dc);
545
                        gen_op_tst_cc_cc ();
546
                        break;
547
                case CC_VS:
548
                        cris_evaluate_flags(dc);
549
                        gen_op_tst_cc_vs ();
550
                        break;
551
                case CC_VC:
552
                        cris_evaluate_flags(dc);
553
                        gen_op_tst_cc_vc ();
554
                        break;
555
                case CC_PL:
556
                        if (arith_opt)
557
                                gen_op_tst_cc_pl_fast ();
558
                        else {
559
                                cris_evaluate_flags(dc);
560
                                gen_op_tst_cc_pl ();
561
                        }
562
                        break;
563
                case CC_MI:
564
                        if (arith_opt)
565
                                gen_op_tst_cc_mi_fast ();
566
                        else {
567
                                cris_evaluate_flags(dc);
568
                                gen_op_tst_cc_mi ();
569
                        }
570
                        break;
571
                case CC_LS:
572
                        cris_evaluate_flags(dc);
573
                        gen_op_tst_cc_ls ();
574
                        break;
575
                case CC_HI:
576
                        cris_evaluate_flags(dc);
577
                        gen_op_tst_cc_hi ();
578
                        break;
579
                case CC_GE:
580
                        cris_evaluate_flags(dc);
581
                        gen_op_tst_cc_ge ();
582
                        break;
583
                case CC_LT:
584
                        cris_evaluate_flags(dc);
585
                        gen_op_tst_cc_lt ();
586
                        break;
587
                case CC_GT:
588
                        cris_evaluate_flags(dc);
589
                        gen_op_tst_cc_gt ();
590
                        break;
591
                case CC_LE:
592
                        cris_evaluate_flags(dc);
593
                        gen_op_tst_cc_le ();
594
                        break;
595
                case CC_P:
596
                        cris_evaluate_flags(dc);
597
                        gen_op_tst_cc_p ();
598
                        break;
599
                case CC_A:
600
                        cris_evaluate_flags(dc);
601
                        gen_op_movl_T0_im (1);
602
                        break;
603
                default:
604
                        BUG();
605
                        break;
606
        };
607
}
608

    
609
static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
610
{
611
        /* This helps us re-schedule the micro-code to insns in delay-slots
612
           before the actual jump.  */
613
        dc->delayed_branch = 2;
614
        dc->delayed_pc = dc->pc + offset;
615
        dc->bcc = cond;
616
        if (cond != CC_A)
617
        {
618
                gen_tst_cc (dc, cond);
619
                gen_op_evaluate_bcc ();
620
        }
621
        gen_op_movl_T0_im (dc->delayed_pc);
622
        gen_op_movl_btarget_T0 ();
623
}
624

    
625
/* Dynamic jumps, when the dest is in a live reg for example.  */
626
void cris_prepare_dyn_jmp (DisasContext *dc)
627
{
628
        /* This helps us re-schedule the micro-code to insns in delay-slots
629
           before the actual jump.  */
630
        dc->delayed_branch = 2;
631
        dc->dyn_jmp = 1;
632
        dc->bcc = CC_A;
633
}
634

    
635
void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
636
{
637
        /* This helps us re-schedule the micro-code to insns in delay-slots
638
           before the actual jump.  */
639
        dc->delayed_branch = 2;
640
        dc->delayed_pc = dst;
641
        dc->dyn_jmp = 0;
642
        dc->bcc = CC_A;
643
}
644

    
645
void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
646
{
647
        if (size == 1) {
648
                if (sign)
649
                        gen_op_ldb_T0_T0(dc);
650
                else
651
                        gen_op_ldub_T0_T0(dc);
652
        }
653
        else if (size == 2) {
654
                if (sign)
655
                        gen_op_ldw_T0_T0(dc);
656
                else
657
                        gen_op_lduw_T0_T0(dc);
658
        }
659
        else {
660
                gen_op_ldl_T0_T0(dc);
661
        }
662
}
663

    
664
void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
665
{
666
        /* Remember, operands are flipped. CRIS has reversed order.  */
667
        if (size == 1) {
668
                gen_op_stb_T0_T1(dc);
669
        }
670
        else if (size == 2) {
671
                gen_op_stw_T0_T1(dc);
672
        }
673
        else
674
                gen_op_stl_T0_T1(dc);
675
}
676

    
677
/* sign extend T1 according to size.  */
678
static void gen_sext_T1_T0(int size)
679
{
680
        if (size == 1)
681
                gen_op_extb_T1_T0();
682
        else if (size == 2)
683
                gen_op_extw_T1_T0();
684
}
685

    
686
static void gen_sext_T1_T1(int size)
687
{
688
        if (size == 1)
689
                gen_op_extb_T1_T1();
690
        else if (size == 2)
691
                gen_op_extw_T1_T1();
692
}
693

    
694
static void gen_sext_T0_T0(int size)
695
{
696
        if (size == 1)
697
                gen_op_extb_T0_T0();
698
        else if (size == 2)
699
                gen_op_extw_T0_T0();
700
}
701

    
702
static void gen_zext_T0_T0(int size)
703
{
704
        if (size == 1)
705
                gen_op_zextb_T0_T0();
706
        else if (size == 2)
707
                gen_op_zextw_T0_T0();
708
}
709

    
710
static void gen_zext_T1_T0(int size)
711
{
712
        if (size == 1)
713
                gen_op_zextb_T1_T0();
714
        else if (size == 2)
715
                gen_op_zextw_T1_T0();
716
}
717

    
718
static void gen_zext_T1_T1(int size)
719
{
720
        if (size == 1)
721
                gen_op_zextb_T1_T1();
722
        else if (size == 2)
723
                gen_op_zextw_T1_T1();
724
}
725

    
726
#if DISAS_CRIS
727
static char memsize_char(int size)
728
{
729
        switch (size)
730
        {
731
                case 1: return 'b';  break;
732
                case 2: return 'w';  break;
733
                case 4: return 'd';  break;
734
                default:
735
                        return 'x';
736
                        break;
737
        }
738
}
739
#endif
740

    
741
static unsigned int memsize_z(DisasContext *dc)
742
{
743
        return dc->zsize + 1;
744
}
745

    
746
static unsigned int memsize_zz(DisasContext *dc)
747
{
748
        switch (dc->zzsize)
749
        {
750
                case 0: return 1;
751
                case 1: return 2;
752
                default:
753
                        return 4;
754
        }
755
}
756

    
757
static void do_postinc (DisasContext *dc, int size)
758
{
759
        if (!dc->postinc)
760
                return;
761
        gen_movl_T0_reg[dc->op1]();
762
        gen_op_addl_T0_im(size);
763
        gen_movl_reg_T0[dc->op1]();
764
}
765

    
766

    
767
static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
768
                            int size, int s_ext)
769
{
770
        gen_movl_T0_reg[rs]();
771
        gen_op_movl_T1_T0();
772
        if (s_ext)
773
                gen_sext_T1_T1(size);
774
        else
775
                gen_zext_T1_T1(size);
776
}
777

    
778
/* Prepare T0 and T1 for a register alu operation.
779
   s_ext decides if the operand1 should be sign-extended or zero-extended when
780
   needed.  */
781
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
782
                          int size, int s_ext)
783
{
784
        dec_prep_move_r(dc, rs, rd, size, s_ext);
785

    
786
        gen_movl_T0_reg[rd]();
787
        if (s_ext)
788
                gen_sext_T0_T0(size);
789
        else
790
                gen_zext_T0_T0(size);
791
}
792

    
793
/* Prepare T0 and T1 for a memory + alu operation.
794
   s_ext decides if the operand1 should be sign-extended or zero-extended when
795
   needed.  */
796
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
797
{
798
        unsigned int rs, rd;
799
        uint32_t imm;
800
        int is_imm;
801
        int insn_len = 2;
802

    
803
        rs = dc->op1;
804
        rd = dc->op2;
805
        is_imm = rs == 15 && dc->postinc;
806

    
807
        /* Load [$rs] onto T1.  */
808
        if (is_imm) {
809
                insn_len = 2 + memsize;
810
                if (memsize == 1)
811
                        insn_len++;
812

    
813
                imm = ldl_code(dc->pc + 2);
814
                if (memsize != 4) {
815
                        if (s_ext) {
816
                                imm = sign_extend(imm, (memsize * 8) - 1);
817
                        } else {
818
                                if (memsize == 1)
819
                                        imm &= 0xff;
820
                                else
821
                                        imm &= 0xffff;
822
                        }
823
                }
824
                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
825
                            imm, rd, s_ext, memsize));
826
                gen_op_movl_T1_im (imm);
827
                dc->postinc = 0;
828
        } else {
829
                gen_movl_T0_reg[rs]();
830
                gen_load_T0_T0(dc, memsize, 0);
831
                gen_op_movl_T1_T0();
832
                if (s_ext)
833
                        gen_sext_T1_T1(memsize);
834
                else
835
                        gen_zext_T1_T1(memsize);
836
        }
837

    
838
        /* put dest in T0.  */
839
        gen_movl_T0_reg[rd]();
840
        return insn_len;
841
}
842

    
843
#if DISAS_CRIS
844
static const char *cc_name(int cc)
845
{
846
        static char *cc_names[16] = {
847
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
848
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
849
        };
850
        assert(cc < 16);
851
        return cc_names[cc];
852
}
853
#endif
854

    
855
static unsigned int dec_bccq(DisasContext *dc)
856
{
857
        int32_t offset;
858
        int sign;
859
        uint32_t cond = dc->op2;
860
        int tmp;
861

    
862
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
863
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
864

    
865
        offset *= 2;
866
        offset |= sign << 8;
867
        tmp = offset;
868
        offset = sign_extend(offset, 8);
869

    
870
        /* op2 holds the condition-code.  */
871
        cris_cc_mask(dc, 0);
872
        cris_prepare_cc_branch (dc, offset, cond);
873
        return 2;
874
}
875
static unsigned int dec_addoq(DisasContext *dc)
876
{
877
        uint32_t imm;
878

    
879
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
880
        imm = sign_extend(dc->op1, 7);
881

    
882
        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
883
        cris_cc_mask(dc, 0);
884
        /* Fetch register operand,  */
885
        gen_movl_T0_reg[dc->op2]();
886
        gen_op_movl_T1_im(imm);
887
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
888
        return 2;
889
}
890
static unsigned int dec_addq(DisasContext *dc)
891
{
892
        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
893

    
894
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
895

    
896
        cris_cc_mask(dc, CC_MASK_NZVC);
897
        /* Fetch register operand,  */
898
        gen_movl_T0_reg[dc->op2]();
899
        gen_op_movl_T1_im(dc->op1);
900
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
901
        return 2;
902
}
903
static unsigned int dec_moveq(DisasContext *dc)
904
{
905
        uint32_t imm;
906

    
907
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
908
        imm = sign_extend(dc->op1, 5);
909
        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
910

    
911
        cris_cc_mask(dc, 0);
912
        gen_op_movl_T1_im(imm);
913
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
914

    
915
        return 2;
916
}
917
static unsigned int dec_subq(DisasContext *dc)
918
{
919
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
920

    
921
        DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
922

    
923
        cris_cc_mask(dc, CC_MASK_NZVC);
924
        /* Fetch register operand,  */
925
        gen_movl_T0_reg[dc->op2]();
926
        gen_op_movl_T1_im(dc->op1);
927
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
928
        return 2;
929
}
930
static unsigned int dec_cmpq(DisasContext *dc)
931
{
932
        uint32_t imm;
933
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
934
        imm = sign_extend(dc->op1, 5);
935

    
936
        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
937
        cris_cc_mask(dc, CC_MASK_NZVC);
938
        gen_movl_T0_reg[dc->op2]();
939
        gen_op_movl_T1_im(imm);
940
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
941
        return 2;
942
}
943
static unsigned int dec_andq(DisasContext *dc)
944
{
945
        uint32_t imm;
946
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
947
        imm = sign_extend(dc->op1, 5);
948

    
949
        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
950
        cris_cc_mask(dc, CC_MASK_NZ);
951
        gen_movl_T0_reg[dc->op2]();
952
        gen_op_movl_T1_im(imm);
953
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
954
        return 2;
955
}
956
static unsigned int dec_orq(DisasContext *dc)
957
{
958
        uint32_t imm;
959
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
960
        imm = sign_extend(dc->op1, 5);
961
        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
962
        cris_cc_mask(dc, CC_MASK_NZ);
963
        gen_movl_T0_reg[dc->op2]();
964
        gen_op_movl_T1_im(imm);
965
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
966
        return 2;
967
}
968
static unsigned int dec_btstq(DisasContext *dc)
969
{
970
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
971
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
972
        cris_cc_mask(dc, CC_MASK_NZ);
973
        gen_movl_T0_reg[dc->op2]();
974
        gen_op_movl_T1_im(dc->op1);
975
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
976

    
977
        cris_update_cc_op(dc, CC_OP_FLAGS);
978
        gen_op_movl_flags_T0();
979
        dc->flags_live = 1;
980
        return 2;
981
}
982
static unsigned int dec_asrq(DisasContext *dc)
983
{
984
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
985
        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
986
        cris_cc_mask(dc, CC_MASK_NZ);
987
        gen_movl_T0_reg[dc->op2]();
988
        gen_op_movl_T1_im(dc->op1);
989
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
990
        return 2;
991
}
992
static unsigned int dec_lslq(DisasContext *dc)
993
{
994
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
995
        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
996

    
997
        cris_cc_mask(dc, CC_MASK_NZ);
998
        gen_movl_T0_reg[dc->op2]();
999
        gen_op_movl_T1_im(dc->op1);
1000
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
1001
        return 2;
1002
}
1003
static unsigned int dec_lsrq(DisasContext *dc)
1004
{
1005
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1006
        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1007

    
1008
        cris_cc_mask(dc, CC_MASK_NZ);
1009
        gen_movl_T0_reg[dc->op2]();
1010
        gen_op_movl_T1_im(dc->op1);
1011
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1012
        return 2;
1013
}
1014

    
1015
static unsigned int dec_move_r(DisasContext *dc)
1016
{
1017
        int size = memsize_zz(dc);
1018

    
1019
        DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
1020
                    memsize_char(size), dc->op1, dc->op2));
1021

    
1022
        cris_cc_mask(dc, CC_MASK_NZ);
1023
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1024
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1025
        return 2;
1026
}
1027

    
1028
static unsigned int dec_scc_r(DisasContext *dc)
1029
{
1030
        int cond = dc->op2;
1031

    
1032
        DIS(fprintf (logfile, "s%s $r%u\n",
1033
                    cc_name(cond), dc->op1));
1034

    
1035
        if (cond != CC_A)
1036
        {
1037
                gen_tst_cc (dc, cond);
1038
                gen_op_movl_T1_T0();
1039
        }
1040
        else
1041
                gen_op_movl_T1_im(1);
1042

    
1043
        cris_cc_mask(dc, 0);
1044
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1045
        return 2;
1046
}
1047

    
1048
static unsigned int dec_and_r(DisasContext *dc)
1049
{
1050
        int size = memsize_zz(dc);
1051

    
1052
        DIS(fprintf (logfile, "and.%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);
1056
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1057
        return 2;
1058
}
1059

    
1060
static unsigned int dec_lz_r(DisasContext *dc)
1061
{
1062
        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1063
                    dc->op1, dc->op2));
1064
        cris_cc_mask(dc, CC_MASK_NZ);
1065
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1066
        crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1067
        return 2;
1068
}
1069

    
1070
static unsigned int dec_lsl_r(DisasContext *dc)
1071
{
1072
        int size = memsize_zz(dc);
1073

    
1074
        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1075
                    memsize_char(size), dc->op1, dc->op2));
1076
        cris_cc_mask(dc, CC_MASK_NZ);
1077
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1078
        gen_op_andl_T1_im(63);
1079
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1080
        return 2;
1081
}
1082

    
1083
static unsigned int dec_lsr_r(DisasContext *dc)
1084
{
1085
        int size = memsize_zz(dc);
1086

    
1087
        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1088
                    memsize_char(size), dc->op1, dc->op2));
1089
        cris_cc_mask(dc, CC_MASK_NZ);
1090
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1091
        gen_op_andl_T1_im(63);
1092
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1093
        return 2;
1094
}
1095

    
1096
static unsigned int dec_asr_r(DisasContext *dc)
1097
{
1098
        int size = memsize_zz(dc);
1099

    
1100
        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1101
                    memsize_char(size), dc->op1, dc->op2));
1102
        cris_cc_mask(dc, CC_MASK_NZ);
1103
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1104
        gen_op_andl_T1_im(63);
1105
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1106
        return 2;
1107
}
1108

    
1109
static unsigned int dec_muls_r(DisasContext *dc)
1110
{
1111
        int size = memsize_zz(dc);
1112

    
1113
        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1114
                    memsize_char(size), dc->op1, dc->op2));
1115
        cris_cc_mask(dc, CC_MASK_NZV);
1116
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1117
        gen_sext_T0_T0(size);
1118
        crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1119
        return 2;
1120
}
1121

    
1122
static unsigned int dec_mulu_r(DisasContext *dc)
1123
{
1124
        int size = memsize_zz(dc);
1125

    
1126
        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1127
                    memsize_char(size), dc->op1, dc->op2));
1128
        cris_cc_mask(dc, CC_MASK_NZV);
1129
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1130
        gen_zext_T0_T0(size);
1131
        crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1132
        return 2;
1133
}
1134

    
1135

    
1136
static unsigned int dec_dstep_r(DisasContext *dc)
1137
{
1138
        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1139
        cris_cc_mask(dc, CC_MASK_NZ);
1140
        gen_movl_T0_reg[dc->op1]();
1141
        gen_op_movl_T1_T0();
1142
        gen_movl_T0_reg[dc->op2]();
1143
        crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1144
        return 2;
1145
}
1146

    
1147
static unsigned int dec_xor_r(DisasContext *dc)
1148
{
1149
        int size = memsize_zz(dc);
1150
        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1151
                    memsize_char(size), dc->op1, dc->op2));
1152
        BUG_ON(size != 4); /* xor is dword.  */
1153
        cris_cc_mask(dc, CC_MASK_NZ);
1154
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1155
        crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1156
        return 2;
1157
}
1158

    
1159
static unsigned int dec_bound_r(DisasContext *dc)
1160
{
1161
        int size = memsize_zz(dc);
1162
        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1163
                    memsize_char(size), dc->op1, dc->op2));
1164
        cris_cc_mask(dc, CC_MASK_NZ);
1165
        /* TODO: needs optmimization.  */
1166
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1167
        /* rd should be 4.  */
1168
        gen_movl_T0_reg[dc->op2]();
1169
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1170
        return 2;
1171
}
1172

    
1173
static unsigned int dec_cmp_r(DisasContext *dc)
1174
{
1175
        int size = memsize_zz(dc);
1176
        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1177
                    memsize_char(size), dc->op1, dc->op2));
1178
        cris_cc_mask(dc, CC_MASK_NZVC);
1179
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1180
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1181
        return 2;
1182
}
1183

    
1184
static unsigned int dec_abs_r(DisasContext *dc)
1185
{
1186
        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1187
                    dc->op1, dc->op2));
1188
        cris_cc_mask(dc, CC_MASK_NZ);
1189
        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1190
        gen_op_absl_T1_T1();
1191
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1192
        return 2;
1193
}
1194

    
1195
static unsigned int dec_add_r(DisasContext *dc)
1196
{
1197
        int size = memsize_zz(dc);
1198
        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1199
                    memsize_char(size), dc->op1, dc->op2));
1200
        cris_cc_mask(dc, CC_MASK_NZVC);
1201
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1202
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1203
        return 2;
1204
}
1205

    
1206
static unsigned int dec_addc_r(DisasContext *dc)
1207
{
1208
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1209
                    dc->op1, dc->op2));
1210
        cris_evaluate_flags(dc);
1211
        cris_cc_mask(dc, CC_MASK_NZVC);
1212
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1213
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1214
        return 2;
1215
}
1216

    
1217
static unsigned int dec_mcp_r(DisasContext *dc)
1218
{
1219
        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1220
                     dc->op2, dc->op1));
1221
        cris_evaluate_flags(dc);
1222
        cris_cc_mask(dc, CC_MASK_RNZV);
1223
        gen_movl_T0_preg[dc->op2]();
1224
        gen_op_movl_T1_T0();
1225
        gen_movl_T0_reg[dc->op1]();
1226
        crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1227
        return 2;
1228
}
1229

    
1230
#if DISAS_CRIS
1231
static char * swapmode_name(int mode, char *modename) {
1232
        int i = 0;
1233
        if (mode & 8)
1234
                modename[i++] = 'n';
1235
        if (mode & 4)
1236
                modename[i++] = 'w';
1237
        if (mode & 2)
1238
                modename[i++] = 'b';
1239
        if (mode & 1)
1240
                modename[i++] = 'r';
1241
        modename[i++] = 0;
1242
        return modename;
1243
}
1244
#endif
1245

    
1246
static unsigned int dec_swap_r(DisasContext *dc)
1247
{
1248
        DIS(char modename[4]);
1249
        DIS(fprintf (logfile, "swap%s $r%u\n",
1250
                     swapmode_name(dc->op2, modename), dc->op1));
1251

    
1252
        cris_cc_mask(dc, CC_MASK_NZ);
1253
        gen_movl_T0_reg[dc->op1]();
1254
        if (dc->op2 & 8)
1255
                gen_op_not_T0_T0();
1256
        if (dc->op2 & 4)
1257
                gen_op_swapw_T0_T0();
1258
        if (dc->op2 & 2)
1259
                gen_op_swapb_T0_T0();
1260
        if (dc->op2 & 1)
1261
                gen_op_swapr_T0_T0();
1262
        gen_op_movl_T1_T0();
1263
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1264
        return 2;
1265
}
1266

    
1267
static unsigned int dec_or_r(DisasContext *dc)
1268
{
1269
        int size = memsize_zz(dc);
1270
        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1271
                    memsize_char(size), dc->op1, dc->op2));
1272
        cris_cc_mask(dc, CC_MASK_NZ);
1273
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1274
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1275
        return 2;
1276
}
1277

    
1278
static unsigned int dec_addi_r(DisasContext *dc)
1279
{
1280
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1281
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1282
        cris_cc_mask(dc, 0);
1283
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1284
        gen_op_lsll_T0_im(dc->zzsize);
1285
        gen_op_addl_T0_T1();
1286
        gen_movl_reg_T0[dc->op1]();
1287
        return 2;
1288
}
1289

    
1290
static unsigned int dec_addi_acr(DisasContext *dc)
1291
{
1292
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1293
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1294
        cris_cc_mask(dc, 0);
1295
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1296
        gen_op_lsll_T0_im(dc->zzsize);
1297
        gen_op_addl_T0_T1();
1298
        gen_movl_reg_T0[R_ACR]();
1299
        return 2;
1300
}
1301

    
1302
static unsigned int dec_neg_r(DisasContext *dc)
1303
{
1304
        int size = memsize_zz(dc);
1305
        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1306
                    memsize_char(size), dc->op1, dc->op2));
1307
        cris_cc_mask(dc, CC_MASK_NZVC);
1308
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1309
        crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1310
        return 2;
1311
}
1312

    
1313
static unsigned int dec_btst_r(DisasContext *dc)
1314
{
1315
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1316
                    dc->op1, dc->op2));
1317
        cris_cc_mask(dc, CC_MASK_NZ);
1318
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1319
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1320

    
1321
        cris_update_cc_op(dc, CC_OP_FLAGS);
1322
        gen_op_movl_flags_T0();
1323
        dc->flags_live = 1;
1324
        return 2;
1325
}
1326

    
1327
static unsigned int dec_sub_r(DisasContext *dc)
1328
{
1329
        int size = memsize_zz(dc);
1330
        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1331
                    memsize_char(size), dc->op1, dc->op2));
1332
        cris_cc_mask(dc, CC_MASK_NZVC);
1333
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1334
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1335
        return 2;
1336
}
1337

    
1338
/* Zero extension. From size to dword.  */
1339
static unsigned int dec_movu_r(DisasContext *dc)
1340
{
1341
        int size = memsize_z(dc);
1342
        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1343
                    memsize_char(size),
1344
                    dc->op1, dc->op2));
1345

    
1346
        cris_cc_mask(dc, CC_MASK_NZ);
1347
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1348
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1349
        return 2;
1350
}
1351

    
1352
/* Sign extension. From size to dword.  */
1353
static unsigned int dec_movs_r(DisasContext *dc)
1354
{
1355
        int size = memsize_z(dc);
1356
        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1357
                    memsize_char(size),
1358
                    dc->op1, dc->op2));
1359

    
1360
        cris_cc_mask(dc, CC_MASK_NZ);
1361
        gen_movl_T0_reg[dc->op1]();
1362
        /* Size can only be qi or hi.  */
1363
        gen_sext_T1_T0(size);
1364
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1365
        return 2;
1366
}
1367

    
1368
/* zero extension. From size to dword.  */
1369
static unsigned int dec_addu_r(DisasContext *dc)
1370
{
1371
        int size = memsize_z(dc);
1372
        DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1373
                    memsize_char(size),
1374
                    dc->op1, dc->op2));
1375

    
1376
        cris_cc_mask(dc, CC_MASK_NZVC);
1377
        gen_movl_T0_reg[dc->op1]();
1378
        /* Size can only be qi or hi.  */
1379
        gen_zext_T1_T0(size);
1380
        gen_movl_T0_reg[dc->op2]();
1381
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1382
        return 2;
1383
}
1384
/* Sign extension. From size to dword.  */
1385
static unsigned int dec_adds_r(DisasContext *dc)
1386
{
1387
        int size = memsize_z(dc);
1388
        DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1389
                    memsize_char(size),
1390
                    dc->op1, dc->op2));
1391

    
1392
        cris_cc_mask(dc, CC_MASK_NZVC);
1393
        gen_movl_T0_reg[dc->op1]();
1394
        /* Size can only be qi or hi.  */
1395
        gen_sext_T1_T0(size);
1396
        gen_movl_T0_reg[dc->op2]();
1397
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1398
        return 2;
1399
}
1400

    
1401
/* Zero extension. From size to dword.  */
1402
static unsigned int dec_subu_r(DisasContext *dc)
1403
{
1404
        int size = memsize_z(dc);
1405
        DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1406
                    memsize_char(size),
1407
                    dc->op1, dc->op2));
1408

    
1409
        cris_cc_mask(dc, CC_MASK_NZVC);
1410
        gen_movl_T0_reg[dc->op1]();
1411
        /* Size can only be qi or hi.  */
1412
        gen_zext_T1_T0(size);
1413
        gen_movl_T0_reg[dc->op2]();
1414
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1415
        return 2;
1416
}
1417

    
1418
/* Sign extension. From size to dword.  */
1419
static unsigned int dec_subs_r(DisasContext *dc)
1420
{
1421
        int size = memsize_z(dc);
1422
        DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1423
                    memsize_char(size),
1424
                    dc->op1, dc->op2));
1425

    
1426
        cris_cc_mask(dc, CC_MASK_NZVC);
1427
        gen_movl_T0_reg[dc->op1]();
1428
        /* Size can only be qi or hi.  */
1429
        gen_sext_T1_T0(size);
1430
        gen_movl_T0_reg[dc->op2]();
1431
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1432
        return 2;
1433
}
1434

    
1435
static unsigned int dec_setclrf(DisasContext *dc)
1436
{
1437
        uint32_t flags;
1438
        int set = (~dc->opcode >> 2) & 1;
1439

    
1440
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1441
                | EXTRACT_FIELD(dc->ir, 0, 3);
1442
        DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1443
        if (set && flags == 0)
1444
                DIS(fprintf (logfile, "nop\n"));
1445
        else if (!set && (flags & 0x20))
1446
                DIS(fprintf (logfile, "di\n"));
1447
        else
1448
                DIS(fprintf (logfile, "%sf %x\n",
1449
                            set ? "set" : "clr",
1450
                            flags));
1451

    
1452
        if (set && (flags & X_FLAG)) {
1453
                dc->flagx_live = 1;
1454
                dc->flags_x = 1;
1455
        }
1456

    
1457
        /* Simply decode the flags.  */
1458
        cris_evaluate_flags (dc);
1459
        cris_update_cc_op(dc, CC_OP_FLAGS);
1460
        if (set)
1461
                gen_op_setf (flags);
1462
        else
1463
                gen_op_clrf (flags);
1464
        dc->flags_live = 1;
1465
        return 2;
1466
}
1467

    
1468
static unsigned int dec_move_rs(DisasContext *dc)
1469
{
1470
        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1471
        cris_cc_mask(dc, 0);
1472
        gen_movl_T0_reg[dc->op1]();
1473
        gen_op_movl_sreg_T0(dc->op2);
1474

    
1475
        if (dc->op2 == 5) /* srs is checked at runtime.  */
1476
                gen_op_movl_tlb_lo_T0();
1477
        return 2;
1478
}
1479
static unsigned int dec_move_sr(DisasContext *dc)
1480
{
1481
        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op1, dc->op2));
1482
        cris_cc_mask(dc, 0);
1483
        gen_op_movl_T0_sreg(dc->op1);
1484
        gen_op_movl_T1_T0();
1485
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1486
        return 2;
1487
}
1488
static unsigned int dec_move_rp(DisasContext *dc)
1489
{
1490
        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1491
        cris_cc_mask(dc, 0);
1492
        gen_movl_T0_reg[dc->op1]();
1493
        gen_op_movl_T1_T0();
1494
        gen_movl_preg_T0[dc->op2]();
1495
        return 2;
1496
}
1497
static unsigned int dec_move_pr(DisasContext *dc)
1498
{
1499
        DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1500
        cris_cc_mask(dc, 0);
1501
        /* Support register 0 is hardwired to zero. 
1502
           Treat it specially. */
1503
        if (dc->op2 == 0)
1504
                gen_op_movl_T1_im(0);
1505
        else {
1506
                gen_movl_T0_preg[dc->op2]();
1507
                gen_op_movl_T1_T0();
1508
        }
1509
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1510
        return 2;
1511
}
1512

    
1513
static unsigned int dec_move_mr(DisasContext *dc)
1514
{
1515
        int memsize = memsize_zz(dc);
1516
        int insn_len;
1517
        DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1518
                    memsize_char(memsize),
1519
                    dc->op1, dc->postinc ? "+]" : "]",
1520
                    dc->op2));
1521

    
1522
        cris_cc_mask(dc, CC_MASK_NZ);
1523
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1524
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1525
        do_postinc(dc, memsize);
1526
        return insn_len;
1527
}
1528

    
1529
static unsigned int dec_movs_m(DisasContext *dc)
1530
{
1531
        int memsize = memsize_z(dc);
1532
        int insn_len;
1533
        DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1534
                    memsize_char(memsize),
1535
                    dc->op1, dc->postinc ? "+]" : "]",
1536
                    dc->op2));
1537

    
1538
        /* sign extend.  */
1539
        cris_cc_mask(dc, CC_MASK_NZ);
1540
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1541
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1542
        do_postinc(dc, memsize);
1543
        return insn_len;
1544
}
1545

    
1546
static unsigned int dec_addu_m(DisasContext *dc)
1547
{
1548
        int memsize = memsize_z(dc);
1549
        int insn_len;
1550
        DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1551
                    memsize_char(memsize),
1552
                    dc->op1, dc->postinc ? "+]" : "]",
1553
                    dc->op2));
1554

    
1555
        /* sign extend.  */
1556
        cris_cc_mask(dc, CC_MASK_NZVC);
1557
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1558
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1559
        do_postinc(dc, memsize);
1560
        return insn_len;
1561
}
1562

    
1563
static unsigned int dec_adds_m(DisasContext *dc)
1564
{
1565
        int memsize = memsize_z(dc);
1566
        int insn_len;
1567
        DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1568
                    memsize_char(memsize),
1569
                    dc->op1, dc->postinc ? "+]" : "]",
1570
                    dc->op2));
1571

    
1572
        /* sign extend.  */
1573
        cris_cc_mask(dc, CC_MASK_NZVC);
1574
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1575
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1576
        do_postinc(dc, memsize);
1577
        return insn_len;
1578
}
1579

    
1580
static unsigned int dec_subu_m(DisasContext *dc)
1581
{
1582
        int memsize = memsize_z(dc);
1583
        int insn_len;
1584
        DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1585
                    memsize_char(memsize),
1586
                    dc->op1, dc->postinc ? "+]" : "]",
1587
                    dc->op2));
1588

    
1589
        /* sign extend.  */
1590
        cris_cc_mask(dc, CC_MASK_NZVC);
1591
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1592
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1593
        do_postinc(dc, memsize);
1594
        return insn_len;
1595
}
1596

    
1597
static unsigned int dec_subs_m(DisasContext *dc)
1598
{
1599
        int memsize = memsize_z(dc);
1600
        int insn_len;
1601
        DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1602
                    memsize_char(memsize),
1603
                    dc->op1, dc->postinc ? "+]" : "]",
1604
                    dc->op2));
1605

    
1606
        /* sign extend.  */
1607
        cris_cc_mask(dc, CC_MASK_NZVC);
1608
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1609
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1610
        do_postinc(dc, memsize);
1611
        return insn_len;
1612
}
1613

    
1614
static unsigned int dec_movu_m(DisasContext *dc)
1615
{
1616
        int memsize = memsize_z(dc);
1617
        int insn_len;
1618

    
1619
        DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1620
                    memsize_char(memsize),
1621
                    dc->op1, dc->postinc ? "+]" : "]",
1622
                    dc->op2));
1623

    
1624
        cris_cc_mask(dc, CC_MASK_NZ);
1625
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1626
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1627
        do_postinc(dc, memsize);
1628
        return insn_len;
1629
}
1630

    
1631
static unsigned int dec_cmpu_m(DisasContext *dc)
1632
{
1633
        int memsize = memsize_z(dc);
1634
        int insn_len;
1635
        DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1636
                    memsize_char(memsize),
1637
                    dc->op1, dc->postinc ? "+]" : "]",
1638
                    dc->op2));
1639

    
1640
        cris_cc_mask(dc, CC_MASK_NZVC);
1641
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1642
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1643
        do_postinc(dc, memsize);
1644
        return insn_len;
1645
}
1646

    
1647
static unsigned int dec_cmps_m(DisasContext *dc)
1648
{
1649
        int memsize = memsize_z(dc);
1650
        int insn_len;
1651
        DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1652
                    memsize_char(memsize),
1653
                    dc->op1, dc->postinc ? "+]" : "]",
1654
                    dc->op2));
1655

    
1656
        cris_cc_mask(dc, CC_MASK_NZVC);
1657
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1658
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1659
        do_postinc(dc, memsize);
1660
        return insn_len;
1661
}
1662

    
1663
static unsigned int dec_cmp_m(DisasContext *dc)
1664
{
1665
        int memsize = memsize_zz(dc);
1666
        int insn_len;
1667
        DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1668
                    memsize_char(memsize),
1669
                    dc->op1, dc->postinc ? "+]" : "]",
1670
                    dc->op2));
1671

    
1672
        cris_cc_mask(dc, CC_MASK_NZVC);
1673
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1674
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1675
        do_postinc(dc, memsize);
1676
        return insn_len;
1677
}
1678

    
1679
static unsigned int dec_test_m(DisasContext *dc)
1680
{
1681
        int memsize = memsize_zz(dc);
1682
        int insn_len;
1683
        DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1684
                    memsize_char(memsize),
1685
                    dc->op1, dc->postinc ? "+]" : "]",
1686
                    dc->op2));
1687

    
1688
        cris_cc_mask(dc, CC_MASK_NZ);
1689
        gen_op_clrf(3);
1690
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1691
        gen_op_swp_T0_T1();
1692
        gen_op_movl_T1_im(0);
1693
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1694
        do_postinc(dc, memsize);
1695
        return insn_len;
1696
}
1697

    
1698
static unsigned int dec_and_m(DisasContext *dc)
1699
{
1700
        int memsize = memsize_zz(dc);
1701
        int insn_len;
1702
        DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1703
                    memsize_char(memsize),
1704
                    dc->op1, dc->postinc ? "+]" : "]",
1705
                    dc->op2));
1706

    
1707
        cris_cc_mask(dc, CC_MASK_NZ);
1708
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1709
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1710
        do_postinc(dc, memsize);
1711
        return insn_len;
1712
}
1713

    
1714
static unsigned int dec_add_m(DisasContext *dc)
1715
{
1716
        int memsize = memsize_zz(dc);
1717
        int insn_len;
1718
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1719
                    memsize_char(memsize),
1720
                    dc->op1, dc->postinc ? "+]" : "]",
1721
                    dc->op2));
1722

    
1723
        cris_cc_mask(dc, CC_MASK_NZVC);
1724
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1725
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1726
        do_postinc(dc, memsize);
1727
        return insn_len;
1728
}
1729

    
1730
static unsigned int dec_addo_m(DisasContext *dc)
1731
{
1732
        int memsize = memsize_zz(dc);
1733
        int insn_len;
1734
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1735
                    memsize_char(memsize),
1736
                    dc->op1, dc->postinc ? "+]" : "]",
1737
                    dc->op2));
1738

    
1739
        cris_cc_mask(dc, 0);
1740
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1741
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1742
        do_postinc(dc, memsize);
1743
        return insn_len;
1744
}
1745

    
1746
static unsigned int dec_bound_m(DisasContext *dc)
1747
{
1748
        int memsize = memsize_zz(dc);
1749
        int insn_len;
1750
        DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1751
                    memsize_char(memsize),
1752
                    dc->op1, dc->postinc ? "+]" : "]",
1753
                    dc->op2));
1754

    
1755
        cris_cc_mask(dc, CC_MASK_NZ);
1756
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1757
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1758
        do_postinc(dc, memsize);
1759
        return insn_len;
1760
}
1761

    
1762
static unsigned int dec_addc_mr(DisasContext *dc)
1763
{
1764
        int insn_len = 2;
1765
        DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1766
                    dc->op1, dc->postinc ? "+]" : "]",
1767
                    dc->op2));
1768

    
1769
        cris_evaluate_flags(dc);
1770
        cris_cc_mask(dc, CC_MASK_NZVC);
1771
        insn_len = dec_prep_alu_m(dc, 0, 4);
1772
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1773
        do_postinc(dc, 4);
1774
        return insn_len;
1775
}
1776

    
1777
static unsigned int dec_sub_m(DisasContext *dc)
1778
{
1779
        int memsize = memsize_zz(dc);
1780
        int insn_len;
1781
        DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1782
                    memsize_char(memsize),
1783
                    dc->op1, dc->postinc ? "+]" : "]",
1784
                    dc->op2, dc->ir, dc->zzsize));
1785

    
1786
        cris_cc_mask(dc, CC_MASK_NZVC);
1787
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1788
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1789
        do_postinc(dc, memsize);
1790
        return insn_len;
1791
}
1792

    
1793
static unsigned int dec_or_m(DisasContext *dc)
1794
{
1795
        int memsize = memsize_zz(dc);
1796
        int insn_len;
1797
        DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1798
                    memsize_char(memsize),
1799
                    dc->op1, dc->postinc ? "+]" : "]",
1800
                    dc->op2, dc->pc));
1801

    
1802
        cris_cc_mask(dc, CC_MASK_NZ);
1803
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1804
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1805
        do_postinc(dc, memsize);
1806
        return insn_len;
1807
}
1808

    
1809
static unsigned int dec_move_mp(DisasContext *dc)
1810
{
1811
        int memsize = memsize_zz(dc);
1812
        int insn_len = 2;
1813

    
1814
        DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1815
                    memsize_char(memsize),
1816
                    dc->op1,
1817
                    dc->postinc ? "+]" : "]",
1818
                    dc->op2));
1819

    
1820
        cris_cc_mask(dc, 0);
1821
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1822
        gen_op_movl_T0_T1();
1823
        gen_movl_preg_T0[dc->op2]();
1824

    
1825
        do_postinc(dc, memsize);
1826
        return insn_len;
1827
}
1828

    
1829
static unsigned int dec_move_pm(DisasContext *dc)
1830
{
1831
        int memsize;
1832

    
1833
        memsize = preg_sizes[dc->op2];
1834

    
1835
        DIS(fprintf (logfile, "move.%c $p%u, [$r%u%s\n",
1836
                     memsize_char(memsize), 
1837
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
1838

    
1839
        cris_cc_mask(dc, 0);
1840
        /* prepare store. Address in T0, value in T1.  */
1841
        /* Support register 0 is hardwired to zero. 
1842
           Treat it specially. */
1843
        if (dc->op2 == 0)
1844
                gen_op_movl_T1_im(0);
1845
        else
1846
        {
1847
                gen_movl_T0_preg[dc->op2]();
1848
                gen_op_movl_T1_T0();
1849
        }
1850
        gen_movl_T0_reg[dc->op1]();
1851
        gen_store_T0_T1(dc, memsize);
1852
        if (dc->postinc)
1853
        {
1854
                gen_op_addl_T0_im(memsize);
1855
                gen_movl_reg_T0[dc->op1]();
1856
        }
1857
        return 2;
1858
}
1859

    
1860
static unsigned int dec_movem_mr(DisasContext *dc)
1861
{
1862
        int i;
1863

    
1864
        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
1865
                    dc->postinc ? "+]" : "]", dc->op2));
1866

    
1867
        cris_cc_mask(dc, 0);
1868
        /* fetch the address into T1.  */
1869
        gen_movl_T0_reg[dc->op1]();
1870
        gen_op_movl_T1_T0();
1871
        for (i = 0; i <= dc->op2; i++) {
1872
                /* Perform the load onto regnum i. Always dword wide.  */
1873
                gen_load_T0_T0(dc, 4, 0);
1874
                gen_movl_reg_T0[i]();
1875
                /* Update the address.  */
1876
                gen_op_addl_T1_im(4);
1877
                gen_op_movl_T0_T1();
1878
        }
1879
        if (dc->postinc) {
1880
                /* writeback the updated pointer value.  */
1881
                gen_movl_reg_T0[dc->op1]();
1882
        }
1883
        return 2;
1884
}
1885

    
1886
static unsigned int dec_movem_rm(DisasContext *dc)
1887
{
1888
        int i;
1889

    
1890
        DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
1891
                     dc->postinc ? "+]" : "]"));
1892

    
1893
        cris_cc_mask(dc, 0);
1894
        for (i = 0; i <= dc->op2; i++) {
1895
                /* Fetch register i into T1.  */
1896
                gen_movl_T0_reg[i]();
1897
                gen_op_movl_T1_T0();
1898

    
1899
                /* Fetch the address into T0.  */
1900
                gen_movl_T0_reg[dc->op1]();
1901
                /* Displace it.  */
1902
                gen_op_addl_T0_im(i * 4);
1903

    
1904
                /* Perform the store.  */
1905
                gen_store_T0_T1(dc, 4);
1906
        }
1907
        if (dc->postinc) {
1908
                /* Update the address.  */
1909
                gen_op_addl_T0_im(4);
1910
                /* writeback the updated pointer value.  */
1911
                gen_movl_reg_T0[dc->op1]();
1912
        }
1913
        return 2;
1914
}
1915

    
1916
static unsigned int dec_move_rm(DisasContext *dc)
1917
{
1918
        int memsize;
1919

    
1920
        memsize = memsize_zz(dc);
1921

    
1922
        DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
1923
                     memsize, dc->op2, dc->op1));
1924

    
1925
        cris_cc_mask(dc, 0);
1926
        /* prepare store.  */
1927
        gen_movl_T0_reg[dc->op2]();
1928
        gen_op_movl_T1_T0();
1929
        gen_movl_T0_reg[dc->op1]();
1930
        gen_store_T0_T1(dc, memsize);
1931
        if (dc->postinc)
1932
        {
1933
                gen_op_addl_T0_im(memsize);
1934
                gen_movl_reg_T0[dc->op1]();
1935
        }
1936
        return 2;
1937
}
1938

    
1939

    
1940
static unsigned int dec_lapcq(DisasContext *dc)
1941
{
1942
        DIS(fprintf (logfile, "lapcq %x, $r%u\n",
1943
                    dc->pc + dc->op1*2, dc->op2));
1944
        cris_cc_mask(dc, 0);
1945
        gen_op_movl_T1_im(dc->pc + dc->op1*2);
1946
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1947
        return 2;
1948
}
1949

    
1950
static unsigned int dec_lapc_im(DisasContext *dc)
1951
{
1952
        unsigned int rd;
1953
        int32_t imm;
1954
        int insn_len = 6;
1955

    
1956
        rd = dc->op2;
1957

    
1958
        cris_cc_mask(dc, 0);
1959
        imm = ldl_code(dc->pc + 2);
1960
        DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
1961
        gen_op_movl_T0_im (dc->pc + imm);
1962
        gen_movl_reg_T0[rd] ();
1963
        return insn_len;
1964
}
1965

    
1966
/* Jump to special reg.  */
1967
static unsigned int dec_jump_p(DisasContext *dc)
1968
{
1969
        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
1970
        cris_cc_mask(dc, 0);
1971
        /* Store the return address in Pd.  */
1972
        gen_movl_T0_preg[dc->op2]();
1973
        gen_op_movl_btarget_T0();
1974
        cris_prepare_dyn_jmp(dc);
1975
        return 2;
1976
}
1977

    
1978
/* Jump and save.  */
1979
static unsigned int dec_jas_r(DisasContext *dc)
1980
{
1981
        DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
1982
        cris_cc_mask(dc, 0);
1983
        /* Stor the return address in Pd.  */
1984
        gen_movl_T0_reg[dc->op1]();
1985
        gen_op_movl_btarget_T0();
1986
        gen_op_movl_T0_im(dc->pc + 4);
1987
        gen_movl_preg_T0[dc->op2]();
1988
        cris_prepare_dyn_jmp(dc);
1989
        return 2;
1990
}
1991

    
1992
static unsigned int dec_jas_im(DisasContext *dc)
1993
{
1994
        uint32_t imm;
1995

    
1996
        imm = ldl_code(dc->pc + 2);
1997

    
1998
        DIS(fprintf (logfile, "jas 0x%x\n", imm));
1999
        cris_cc_mask(dc, 0);
2000
        /* Stor the return address in Pd.  */
2001
        gen_op_movl_T0_im(imm);
2002
        gen_op_movl_btarget_T0();
2003
        gen_op_movl_T0_im(dc->pc + 8);
2004
        gen_movl_preg_T0[dc->op2]();
2005
        cris_prepare_dyn_jmp(dc);
2006
        return 6;
2007
}
2008

    
2009
static unsigned int dec_jasc_im(DisasContext *dc)
2010
{
2011
        uint32_t imm;
2012

    
2013
        imm = ldl_code(dc->pc + 2);
2014

    
2015
        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2016
        cris_cc_mask(dc, 0);
2017
        /* Stor the return address in Pd.  */
2018
        gen_op_movl_T0_im(imm);
2019
        gen_op_movl_btarget_T0();
2020
        gen_op_movl_T0_im(dc->pc + 8 + 4);
2021
        gen_movl_preg_T0[dc->op2]();
2022
        cris_prepare_dyn_jmp(dc);
2023
        return 6;
2024
}
2025

    
2026
static unsigned int dec_jasc_r(DisasContext *dc)
2027
{
2028
        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2029
        cris_cc_mask(dc, 0);
2030
        /* Stor the return address in Pd.  */
2031
        gen_movl_T0_reg[dc->op1]();
2032
        gen_op_movl_btarget_T0();
2033
        gen_op_movl_T0_im(dc->pc + 4 + 4);
2034
        gen_movl_preg_T0[dc->op2]();
2035
        cris_prepare_dyn_jmp(dc);
2036
        return 2;
2037
}
2038

    
2039
static unsigned int dec_bcc_im(DisasContext *dc)
2040
{
2041
        int32_t offset;
2042
        uint32_t cond = dc->op2;
2043

    
2044
        offset = ldl_code(dc->pc + 2);
2045
        offset = sign_extend(offset, 15);
2046

    
2047
        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2048
                    cc_name(cond), offset,
2049
                    dc->pc, dc->pc + offset));
2050

    
2051
        cris_cc_mask(dc, 0);
2052
        /* op2 holds the condition-code.  */
2053
        cris_prepare_cc_branch (dc, offset, cond);
2054
        return 4;
2055
}
2056

    
2057
static unsigned int dec_bas_im(DisasContext *dc)
2058
{
2059
        int32_t simm;
2060

    
2061

    
2062
        simm = ldl_code(dc->pc + 2);
2063

    
2064
        DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2065
        cris_cc_mask(dc, 0);
2066
        /* Stor the return address in Pd.  */
2067
        gen_op_movl_T0_im(dc->pc + simm);
2068
        gen_op_movl_btarget_T0();
2069
        gen_op_movl_T0_im(dc->pc + 8);
2070
        gen_movl_preg_T0[dc->op2]();
2071
        cris_prepare_dyn_jmp(dc);
2072
        return 6;
2073
}
2074

    
2075
static unsigned int dec_basc_im(DisasContext *dc)
2076
{
2077
        int32_t simm;
2078
        simm = ldl_code(dc->pc + 2);
2079

    
2080
        DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2081
        cris_cc_mask(dc, 0);
2082
        /* Stor the return address in Pd.  */
2083
        gen_op_movl_T0_im(dc->pc + simm);
2084
        gen_op_movl_btarget_T0();
2085
        gen_op_movl_T0_im(dc->pc + 12);
2086
        gen_movl_preg_T0[dc->op2]();
2087
        cris_prepare_dyn_jmp(dc);
2088
        return 6;
2089
}
2090

    
2091
static unsigned int dec_rfe_etc(DisasContext *dc)
2092
{
2093
        DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2094
                    dc->opcode, dc->pc, dc->op1, dc->op2));
2095

    
2096
        cris_cc_mask(dc, 0);
2097

    
2098
        if (dc->op2 == 15) /* ignore halt.  */
2099
                goto done;
2100

    
2101
        switch (dc->op2 & 7) {
2102
                case 2:
2103
                        /* rfe.  */
2104
                        cris_evaluate_flags(dc);
2105
                        gen_op_ccs_rshift();
2106
                        break;
2107
                case 5:
2108
                        /* rfn.  */
2109
                        BUG();
2110
                        break;
2111
                case 6:
2112
                        /* break.  */
2113
                        gen_op_movl_T0_im(dc->pc);
2114
                        gen_op_movl_pc_T0();
2115
                        /* Breaks start at 16 in the exception vector.  */
2116
                        gen_op_break_im(dc->op1 + 16);
2117
                        dc->is_jmp = DISAS_SWI;
2118
                        break;
2119
                default:
2120
                        printf ("op2=%x\n", dc->op2);
2121
                        BUG();
2122
                        break;
2123

    
2124
        }
2125
  done:
2126
        return 2;
2127
}
2128

    
2129
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2130
{
2131
        /* Ignore D-cache flushes.  */
2132
        return 2;
2133
}
2134

    
2135
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2136
{
2137
        /* Ignore I-cache flushes.  */
2138
        return 2;
2139
}
2140

    
2141
static unsigned int dec_null(DisasContext *dc)
2142
{
2143
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2144
                dc->pc, dc->opcode, dc->op1, dc->op2);
2145
        fflush(NULL);
2146
        BUG();
2147
        return 2;
2148
}
2149

    
2150
struct decoder_info {
2151
        struct {
2152
                uint32_t bits;
2153
                uint32_t mask;
2154
        };
2155
        unsigned int (*dec)(DisasContext *dc);
2156
} decinfo[] = {
2157
        /* Order matters here.  */
2158
        {DEC_MOVEQ, dec_moveq},
2159
        {DEC_BTSTQ, dec_btstq},
2160
        {DEC_CMPQ, dec_cmpq},
2161
        {DEC_ADDOQ, dec_addoq},
2162
        {DEC_ADDQ, dec_addq},
2163
        {DEC_SUBQ, dec_subq},
2164
        {DEC_ANDQ, dec_andq},
2165
        {DEC_ORQ, dec_orq},
2166
        {DEC_ASRQ, dec_asrq},
2167
        {DEC_LSLQ, dec_lslq},
2168
        {DEC_LSRQ, dec_lsrq},
2169
        {DEC_BCCQ, dec_bccq},
2170

    
2171
        {DEC_BCC_IM, dec_bcc_im},
2172
        {DEC_JAS_IM, dec_jas_im},
2173
        {DEC_JAS_R, dec_jas_r},
2174
        {DEC_JASC_IM, dec_jasc_im},
2175
        {DEC_JASC_R, dec_jasc_r},
2176
        {DEC_BAS_IM, dec_bas_im},
2177
        {DEC_BASC_IM, dec_basc_im},
2178
        {DEC_JUMP_P, dec_jump_p},
2179
        {DEC_LAPC_IM, dec_lapc_im},
2180
        {DEC_LAPCQ, dec_lapcq},
2181

    
2182
        {DEC_RFE_ETC, dec_rfe_etc},
2183
        {DEC_ADDC_MR, dec_addc_mr},
2184

    
2185
        {DEC_MOVE_MP, dec_move_mp},
2186
        {DEC_MOVE_PM, dec_move_pm},
2187
        {DEC_MOVEM_MR, dec_movem_mr},
2188
        {DEC_MOVEM_RM, dec_movem_rm},
2189
        {DEC_MOVE_PR, dec_move_pr},
2190
        {DEC_SCC_R, dec_scc_r},
2191
        {DEC_SETF, dec_setclrf},
2192
        {DEC_CLEARF, dec_setclrf},
2193

    
2194
        {DEC_MOVE_SR, dec_move_sr},
2195
        {DEC_MOVE_RP, dec_move_rp},
2196
        {DEC_SWAP_R, dec_swap_r},
2197
        {DEC_ABS_R, dec_abs_r},
2198
        {DEC_LZ_R, dec_lz_r},
2199
        {DEC_MOVE_RS, dec_move_rs},
2200
        {DEC_BTST_R, dec_btst_r},
2201
        {DEC_ADDC_R, dec_addc_r},
2202

    
2203
        {DEC_DSTEP_R, dec_dstep_r},
2204
        {DEC_XOR_R, dec_xor_r},
2205
        {DEC_MCP_R, dec_mcp_r},
2206
        {DEC_CMP_R, dec_cmp_r},
2207

    
2208
        {DEC_ADDI_R, dec_addi_r},
2209
        {DEC_ADDI_ACR, dec_addi_acr},
2210

    
2211
        {DEC_ADD_R, dec_add_r},
2212
        {DEC_SUB_R, dec_sub_r},
2213

    
2214
        {DEC_ADDU_R, dec_addu_r},
2215
        {DEC_ADDS_R, dec_adds_r},
2216
        {DEC_SUBU_R, dec_subu_r},
2217
        {DEC_SUBS_R, dec_subs_r},
2218
        {DEC_LSL_R, dec_lsl_r},
2219

    
2220
        {DEC_AND_R, dec_and_r},
2221
        {DEC_OR_R, dec_or_r},
2222
        {DEC_BOUND_R, dec_bound_r},
2223
        {DEC_ASR_R, dec_asr_r},
2224
        {DEC_LSR_R, dec_lsr_r},
2225

    
2226
        {DEC_MOVU_R, dec_movu_r},
2227
        {DEC_MOVS_R, dec_movs_r},
2228
        {DEC_NEG_R, dec_neg_r},
2229
        {DEC_MOVE_R, dec_move_r},
2230

    
2231
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2232
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2233

    
2234
        {DEC_MULS_R, dec_muls_r},
2235
        {DEC_MULU_R, dec_mulu_r},
2236

    
2237
        {DEC_ADDU_M, dec_addu_m},
2238
        {DEC_ADDS_M, dec_adds_m},
2239
        {DEC_SUBU_M, dec_subu_m},
2240
        {DEC_SUBS_M, dec_subs_m},
2241

    
2242
        {DEC_CMPU_M, dec_cmpu_m},
2243
        {DEC_CMPS_M, dec_cmps_m},
2244
        {DEC_MOVU_M, dec_movu_m},
2245
        {DEC_MOVS_M, dec_movs_m},
2246

    
2247
        {DEC_CMP_M, dec_cmp_m},
2248
        {DEC_ADDO_M, dec_addo_m},
2249
        {DEC_BOUND_M, dec_bound_m},
2250
        {DEC_ADD_M, dec_add_m},
2251
        {DEC_SUB_M, dec_sub_m},
2252
        {DEC_AND_M, dec_and_m},
2253
        {DEC_OR_M, dec_or_m},
2254
        {DEC_MOVE_RM, dec_move_rm},
2255
        {DEC_TEST_M, dec_test_m},
2256
        {DEC_MOVE_MR, dec_move_mr},
2257

    
2258
        {{0, 0}, dec_null}
2259
};
2260

    
2261
static inline unsigned int
2262
cris_decoder(DisasContext *dc)
2263
{
2264
        unsigned int insn_len = 2;
2265
        uint32_t tmp;
2266
        int i;
2267

    
2268
        /* Load a halfword onto the instruction register.  */
2269
        tmp = ldl_code(dc->pc);
2270
        dc->ir = tmp & 0xffff;
2271

    
2272
        /* Now decode it.  */
2273
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2274
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2275
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2276
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2277
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2278
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2279

    
2280
        /* Large switch for all insns.  */
2281
        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2282
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2283
                {
2284
                        insn_len = decinfo[i].dec(dc);
2285
                        break;
2286
                }
2287
        }
2288

    
2289
        return insn_len;
2290
}
2291

    
2292
static void check_breakpoint(CPUState *env, DisasContext *dc)
2293
{
2294
        int j;
2295
        if (env->nb_breakpoints > 0) {
2296
                for(j = 0; j < env->nb_breakpoints; j++) {
2297
                        if (env->breakpoints[j] == dc->pc) {
2298
                                cris_evaluate_flags (dc);
2299
                                gen_op_movl_T0_im((long)dc->pc);
2300
                                gen_op_movl_pc_T0();
2301
                                gen_op_debug();
2302
                                dc->is_jmp = DISAS_UPDATE;
2303
                        }
2304
                }
2305
        }
2306
}
2307

    
2308

    
2309
/* generate intermediate code for basic block 'tb'.  */
2310
struct DisasContext ctx;
2311
static int
2312
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2313
                               int search_pc)
2314
{
2315
        uint16_t *gen_opc_end;
2316
           uint32_t pc_start;
2317
        unsigned int insn_len;
2318
        int j, lj;
2319
        struct DisasContext *dc = &ctx;
2320
        uint32_t next_page_start;
2321

    
2322
        pc_start = tb->pc;
2323
        dc->env = env;
2324
        dc->tb = tb;
2325

    
2326
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2327

    
2328
        dc->is_jmp = DISAS_NEXT;
2329
        dc->pc = pc_start;
2330
        dc->singlestep_enabled = env->singlestep_enabled;
2331
        dc->flagx_live = 0;
2332
        dc->flags_x = 0;
2333
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2334
        lj = -1;
2335
        do
2336
        {
2337
                check_breakpoint(env, dc);
2338
                if (dc->is_jmp == DISAS_JUMP
2339
                    || dc->is_jmp == DISAS_SWI)
2340
                        goto done;
2341

    
2342
                if (search_pc) {
2343
                        j = gen_opc_ptr - gen_opc_buf;
2344
                        if (lj < j) {
2345
                                lj++;
2346
                                while (lj < j)
2347
                                        gen_opc_instr_start[lj++] = 0;
2348
                        }
2349
                        gen_opc_pc[lj] = dc->pc;
2350
                        gen_opc_instr_start[lj] = 1;
2351
                }
2352

    
2353
                insn_len = cris_decoder(dc);
2354
                STATS(gen_op_exec_insn());
2355
                dc->pc += insn_len;
2356
                if (!dc->flagx_live
2357
                    || (dc->flagx_live &&
2358
                        !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
2359
                        gen_movl_T0_preg[PR_CCS]();
2360
                        gen_op_andl_T0_im(~X_FLAG);
2361
                        gen_movl_preg_T0[PR_CCS]();
2362
                        dc->flagx_live = 1;
2363
                        dc->flags_x = 0;
2364
                }
2365

    
2366
                /* Check for delayed branches here. If we do it before
2367
                   actually genereating any host code, the simulator will just
2368
                   loop doing nothing for on this program location.  */
2369
                if (dc->delayed_branch) {
2370
                        dc->delayed_branch--;
2371
                        if (dc->delayed_branch == 0)
2372
                        {
2373
                                if (dc->bcc == CC_A) {
2374
                                        gen_op_jmp1 ();
2375
                                        dc->is_jmp = DISAS_UPDATE;
2376
                                }
2377
                                else {
2378
                                        /* Conditional jmp.  */
2379
                                        gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2380
                                        dc->is_jmp = DISAS_UPDATE;
2381
                                }
2382
                        }
2383
                }
2384

    
2385
                if (env->singlestep_enabled)
2386
                        break;
2387
        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2388
                 && dc->pc < next_page_start);
2389

    
2390
        if (!dc->is_jmp) {
2391
                gen_op_movl_T0_im((long)dc->pc);
2392
                gen_op_movl_pc_T0();
2393
        }
2394

    
2395
        cris_evaluate_flags (dc);
2396
  done:
2397
        if (__builtin_expect(env->singlestep_enabled, 0)) {
2398
                gen_op_debug();
2399
        } else {
2400
                switch(dc->is_jmp) {
2401
                        case DISAS_NEXT:
2402
                                gen_goto_tb(dc, 1, dc->pc);
2403
                                break;
2404
                        default:
2405
                        case DISAS_JUMP:
2406
                        case DISAS_UPDATE:
2407
                                /* indicate that the hash table must be used
2408
                                   to find the next TB */
2409
                                tcg_gen_exit_tb(0);
2410
                                break;
2411
                        case DISAS_SWI:
2412
                        case DISAS_TB_JUMP:
2413
                                /* nothing more to generate */
2414
                                break;
2415
                }
2416
        }
2417
        *gen_opc_ptr = INDEX_op_end;
2418
        if (search_pc) {
2419
                j = gen_opc_ptr - gen_opc_buf;
2420
                lj++;
2421
                while (lj <= j)
2422
                        gen_opc_instr_start[lj++] = 0;
2423
        } else {
2424
                tb->size = dc->pc - pc_start;
2425
        }
2426

    
2427
#ifdef DEBUG_DISAS
2428
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2429
                fprintf(logfile, "--------------\n");
2430
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2431
                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2432
                fprintf(logfile, "\n");
2433
        }
2434
#endif
2435
        return 0;
2436
}
2437

    
2438
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2439
{
2440
    return gen_intermediate_code_internal(env, tb, 0);
2441
}
2442

    
2443
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2444
{
2445
    return gen_intermediate_code_internal(env, tb, 1);
2446
}
2447

    
2448
void cpu_dump_state (CPUState *env, FILE *f,
2449
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2450
                     int flags)
2451
{
2452
        int i;
2453
        uint32_t srs;
2454

    
2455
        if (!env || !f)
2456
                return;
2457

    
2458
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2459
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2460
                    "debug=%x %x %x\n",
2461
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
2462
                    env->cc_op,
2463
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2464
                    env->debug1, env->debug2, env->debug3);
2465

    
2466
        for (i = 0; i < 16; i++) {
2467
                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2468
                if ((i + 1) % 4 == 0)
2469
                        cpu_fprintf(f, "\n");
2470
        }
2471
        cpu_fprintf(f, "\nspecial regs:\n");
2472
        for (i = 0; i < 16; i++) {
2473
                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2474
                if ((i + 1) % 4 == 0)
2475
                        cpu_fprintf(f, "\n");
2476
        }
2477
        srs = env->pregs[PR_SRS];
2478
        cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2479
        if (srs < 256) {
2480
                for (i = 0; i < 16; i++) {
2481
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
2482
                                    i, env->sregs[srs][i]);
2483
                        if ((i + 1) % 4 == 0)
2484
                                cpu_fprintf(f, "\n");
2485
                }
2486
        }
2487
        cpu_fprintf(f, "\n\n");
2488

    
2489
}
2490

    
2491
CPUCRISState *cpu_cris_init (const char *cpu_model)
2492
{
2493
        CPUCRISState *env;
2494

    
2495
        env = qemu_mallocz(sizeof(CPUCRISState));
2496
        if (!env)
2497
                return NULL;
2498
        cpu_exec_init(env);
2499
        cpu_reset(env);
2500
        return env;
2501
}
2502

    
2503
void cpu_reset (CPUCRISState *env)
2504
{
2505
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
2506
        tlb_flush(env, 1);
2507
}