Statistics
| Branch: | Revision:

root / target-cris / translate.c @ a825e703

History | View | Annotate | Download (63.2 kB)

1
/*
2
 *  CRIS emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2008 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
#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"
32
#include "tcg-op.h"
33
#include "helper.h"
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

    
50
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
51
#define BUG_ON(x) ({if (x) BUG();})
52

    
53
#define DISAS_SWI 5
54

    
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

    
64
TCGv cpu_env;
65
TCGv cpu_T[2];
66
TCGv cpu_R[16];
67
TCGv cpu_PR[16];
68
TCGv cc_src;
69
TCGv cc_dest;
70
TCGv cc_result;
71
TCGv cc_op;
72
TCGv cc_size;
73
TCGv cc_mask;
74

    
75
/* This is the state at translation time.  */
76
typedef struct DisasContext {
77
        CPUState *env;
78
        target_ulong pc, insn_pc;
79

    
80
        /* Decoder.  */
81
        uint32_t ir;
82
        uint32_t opcode;
83
        unsigned int op1;
84
        unsigned int op2;
85
        unsigned int zsize, zzsize;
86
        unsigned int mode;
87
        unsigned int postinc;
88

    
89
        int update_cc;
90
        int cc_op;
91
        int cc_size;
92
        uint32_t cc_mask;
93
        int flags_live;
94
        int flagx_live;
95
        int flags_x;
96
        uint32_t tb_entry_flags;
97

    
98
        int memidx; /* user or kernel mode.  */
99
        int is_jmp;
100
        int dyn_jmp;
101

    
102
        uint32_t delayed_pc;
103
        int delayed_branch;
104
        int bcc;
105
        uint32_t condlabel;
106

    
107
        struct TranslationBlock *tb;
108
        int singlestep_enabled;
109
} DisasContext;
110

    
111
void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
112
static void gen_BUG(DisasContext *dc, char *file, int line)
113
{
114
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
115
        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
116
        cpu_dump_state (dc->env, stdout, fprintf, 0);
117
        fflush(NULL);
118
        cris_prepare_jmp (dc, 0x70000000 + line);
119
}
120

    
121
#ifdef CONFIG_USER_ONLY
122
#define GEN_OP_LD(width, reg) \
123
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
124
    gen_op_ld##width##_T0_##reg##_raw(); \
125
  }
126
#define GEN_OP_ST(width, reg) \
127
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
128
    gen_op_st##width##_##reg##_T1_raw(); \
129
  }
130
#else
131
#define GEN_OP_LD(width, reg) \
132
  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
133
    if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
134
    else gen_op_ld##width##_T0_##reg##_user();\
135
  }
136
#define GEN_OP_ST(width, reg) \
137
  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
138
    if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
139
    else gen_op_st##width##_##reg##_T1_user();\
140
  }
141
#endif
142

    
143
GEN_OP_LD(ub, T0)
144
GEN_OP_LD(b, T0)
145
GEN_OP_ST(b, T0)
146
GEN_OP_LD(uw, T0)
147
GEN_OP_LD(w, T0)
148
GEN_OP_ST(w, T0)
149
GEN_OP_LD(l, T0)
150
GEN_OP_ST(l, T0)
151

    
152
const char *regnames[] =
153
{
154
        "$r0", "$r1", "$r2", "$r3",
155
        "$r4", "$r5", "$r6", "$r7",
156
        "$r8", "$r9", "$r10", "$r11",
157
        "$r12", "$r13", "$sp", "$acr",
158
};
159
const char *pregnames[] =
160
{
161
        "$bz", "$vr", "$pid", "$srs",
162
        "$wz", "$exs", "$eda", "$mof",
163
        "$dz", "$ebp", "$erp", "$srp",
164
        "$nrp", "$ccs", "$usp", "$spc",
165
};
166

    
167
/* We need this table to handle preg-moves with implicit width.  */
168
int preg_sizes[] = {
169
        1, /* bz.  */
170
        1, /* vr.  */
171
        4, /* pid.  */
172
        1, /* srs.  */
173
        2, /* wz.  */
174
        4, 4, 4,
175
        4, 4, 4, 4,
176
        4, 4, 4, 4,
177
};
178

    
179
#define t_gen_mov_TN_env(tn, member) \
180
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
181
#define t_gen_mov_env_TN(member, tn) \
182
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
183

    
184
#define t_gen_mov_TN_reg(tn, regno) \
185
 tcg_gen_mov_tl(tn, cpu_R[regno])
186
#define t_gen_mov_reg_TN(regno, tn) \
187
 tcg_gen_mov_tl(cpu_R[regno], tn)
188

    
189
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
190
{
191
        tcg_gen_ld_tl(tn, cpu_env, offset);
192
}
193
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
194
{
195
        tcg_gen_st_tl(tn, cpu_env, offset);
196
}
197

    
198
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
199
{
200
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
201
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
202
        else if (r == PR_VR)
203
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
204
        else
205
                tcg_gen_mov_tl(tn, cpu_PR[r]);
206
}
207
static inline void t_gen_mov_preg_TN(int r, TCGv tn)
208
{
209
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
210
                return;
211
        else
212
                tcg_gen_mov_tl(cpu_PR[r], tn);
213
}
214

    
215
static inline void t_gen_mov_TN_im(TCGv tn, int32_t val)
216
{
217
        tcg_gen_movi_tl(tn, val);
218
}
219

    
220
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
221
{
222
        int l1;
223

    
224
        l1 = gen_new_label();
225
        /* Speculative shift. */
226
        tcg_gen_shl_tl(d, a, b);
227
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
228
        /* Clear dst if shift operands were to large.  */
229
        tcg_gen_movi_tl(d, 0);
230
        gen_set_label(l1);
231
}
232

    
233
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
234
{
235
        int l1;
236

    
237
        l1 = gen_new_label();
238
        /* Speculative shift. */
239
        tcg_gen_shr_tl(d, a, b);
240
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
241
        /* Clear dst if shift operands were to large.  */
242
        tcg_gen_movi_tl(d, 0);
243
        gen_set_label(l1);
244
}
245

    
246
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
247
{
248
        int l1;
249

    
250
        l1 = gen_new_label();
251
        /* Speculative shift. */
252
        tcg_gen_sar_tl(d, a, b);
253
        tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
254
        /* Clear dst if shift operands were to large.  */
255
        tcg_gen_movi_tl(d, 0);
256
        tcg_gen_brcond_tl(TCG_COND_LT, b, tcg_const_tl(0x80000000), l1);
257
        tcg_gen_movi_tl(d, 0xffffffff);
258
        gen_set_label(l1);
259
}
260

    
261
/* 64-bit signed mul, lower result in d and upper in d2.  */
262
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
263
{
264
        TCGv t0, t1;
265

    
266
        t0 = tcg_temp_new(TCG_TYPE_I64);
267
        t1 = tcg_temp_new(TCG_TYPE_I64);
268

    
269
        tcg_gen_ext32s_i64(t0, a);
270
        tcg_gen_ext32s_i64(t1, b);
271
        tcg_gen_mul_i64(t0, t0, t1);
272

    
273
        tcg_gen_trunc_i64_i32(d, t0);
274
        tcg_gen_shri_i64(t0, t0, 32);
275
        tcg_gen_trunc_i64_i32(d2, t0);
276
}
277

    
278
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
279
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
280
{
281
        TCGv t0, t1;
282

    
283
        t0 = tcg_temp_new(TCG_TYPE_I64);
284
        t1 = tcg_temp_new(TCG_TYPE_I64);
285

    
286
        tcg_gen_extu_i32_i64(t0, a);
287
        tcg_gen_extu_i32_i64(t1, b);
288
        tcg_gen_mul_i64(t0, t0, t1);
289

    
290
        tcg_gen_trunc_i64_i32(d, t0);
291
        tcg_gen_shri_i64(t0, t0, 32);
292
        tcg_gen_trunc_i64_i32(d2, t0);
293
}
294

    
295
/* Extended arithmetics on CRIS.  */
296
static inline void t_gen_add_flag(TCGv d, int flag)
297
{
298
        TCGv c;
299

    
300
        c = tcg_temp_new(TCG_TYPE_TL);
301
        t_gen_mov_TN_preg(c, PR_CCS);
302
        /* Propagate carry into d.  */
303
        tcg_gen_andi_tl(c, c, 1 << flag);
304
        if (flag)
305
                tcg_gen_shri_tl(c, c, flag);
306
        tcg_gen_add_tl(d, d, c);
307
}
308

    
309
static inline void t_gen_addx_carry(TCGv d)
310
{
311
        TCGv x, c;
312

    
313
        x = tcg_temp_new(TCG_TYPE_TL);
314
        c = tcg_temp_new(TCG_TYPE_TL);
315
        t_gen_mov_TN_preg(x, PR_CCS);
316
        tcg_gen_mov_tl(c, x);
317

    
318
        /* Propagate carry into d if X is set. Branch free.  */
319
        tcg_gen_andi_tl(c, c, C_FLAG);
320
        tcg_gen_andi_tl(x, x, X_FLAG);
321
        tcg_gen_shri_tl(x, x, 4);
322

    
323
        tcg_gen_and_tl(x, x, c);
324
        tcg_gen_add_tl(d, d, x);        
325
}
326

    
327
static inline void t_gen_subx_carry(TCGv d)
328
{
329
        TCGv x, c;
330

    
331
        x = tcg_temp_new(TCG_TYPE_TL);
332
        c = tcg_temp_new(TCG_TYPE_TL);
333
        t_gen_mov_TN_preg(x, PR_CCS);
334
        tcg_gen_mov_tl(c, x);
335

    
336
        /* Propagate carry into d if X is set. Branch free.  */
337
        tcg_gen_andi_tl(c, c, C_FLAG);
338
        tcg_gen_andi_tl(x, x, X_FLAG);
339
        tcg_gen_shri_tl(x, x, 4);
340

    
341
        tcg_gen_and_tl(x, x, c);
342
        tcg_gen_sub_tl(d, d, x);
343
}
344

    
345
/* Swap the two bytes within each half word of the s operand.
346
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
347
static inline void t_gen_swapb(TCGv d, TCGv s)
348
{
349
        TCGv t, org_s;
350

    
351
        t = tcg_temp_new(TCG_TYPE_TL);
352
        org_s = tcg_temp_new(TCG_TYPE_TL);
353

    
354
        /* d and s may refer to the same object.  */
355
        tcg_gen_mov_tl(org_s, s);
356
        tcg_gen_shli_tl(t, org_s, 8);
357
        tcg_gen_andi_tl(d, t, 0xff00ff00);
358
        tcg_gen_shri_tl(t, org_s, 8);
359
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
360
        tcg_gen_or_tl(d, d, t);
361
}
362

    
363
/* Swap the halfwords of the s operand.  */
364
static inline void t_gen_swapw(TCGv d, TCGv s)
365
{
366
        TCGv t;
367
        /* d and s refer the same object.  */
368
        t = tcg_temp_new(TCG_TYPE_TL);
369
        tcg_gen_mov_tl(t, s);
370
        tcg_gen_shli_tl(d, t, 16);
371
        tcg_gen_shri_tl(t, t, 16);
372
        tcg_gen_or_tl(d, d, t);
373
}
374

    
375
/* Reverse the within each byte.
376
   T0 = (((T0 << 7) & 0x80808080) |
377
   ((T0 << 5) & 0x40404040) |
378
   ((T0 << 3) & 0x20202020) |
379
   ((T0 << 1) & 0x10101010) |
380
   ((T0 >> 1) & 0x08080808) |
381
   ((T0 >> 3) & 0x04040404) |
382
   ((T0 >> 5) & 0x02020202) |
383
   ((T0 >> 7) & 0x01010101));
384
 */
385
static inline void t_gen_swapr(TCGv d, TCGv s)
386
{
387
        struct {
388
                int shift; /* LSL when positive, LSR when negative.  */
389
                uint32_t mask;
390
        } bitrev [] = {
391
                {7, 0x80808080},
392
                {5, 0x40404040},
393
                {3, 0x20202020},
394
                {1, 0x10101010},
395
                {-1, 0x08080808},
396
                {-3, 0x04040404},
397
                {-5, 0x02020202},
398
                {-7, 0x01010101}
399
        };
400
        int i;
401
        TCGv t, org_s;
402

    
403
        /* d and s refer the same object.  */
404
        t = tcg_temp_new(TCG_TYPE_TL);
405
        org_s = tcg_temp_new(TCG_TYPE_TL);
406
        tcg_gen_mov_tl(org_s, s);
407

    
408
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
409
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
410
        for (i = 1; i < sizeof bitrev / sizeof bitrev[0]; i++) {
411
                if (bitrev[i].shift >= 0) {
412
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
413
                } else {
414
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
415
                }
416
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
417
                tcg_gen_or_tl(d, d, t);
418
        }
419
}
420

    
421
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
422
{
423
        TranslationBlock *tb;
424
        tb = dc->tb;
425
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
426
                tcg_gen_goto_tb(n);
427
                tcg_gen_movi_tl(cpu_T[0], dest);
428
                t_gen_mov_env_TN(pc, cpu_T[0]);
429
                tcg_gen_exit_tb((long)tb + n);
430
        } else {
431
                t_gen_mov_env_TN(pc, cpu_T[0]);
432
                tcg_gen_exit_tb(0);
433
        }
434
}
435

    
436
/* Sign extend at translation time.  */
437
static int sign_extend(unsigned int val, unsigned int width)
438
{
439
        int sval;
440

    
441
        /* LSL.  */
442
        val <<= 31 - width;
443
        sval = val;
444
        /* ASR.  */
445
        sval >>= 31 - width;
446
        return sval;
447
}
448

    
449
static inline void cris_clear_x_flag(DisasContext *dc)
450
{
451
        if (!dc->flagx_live || dc->cc_op != CC_OP_FLAGS) {
452
                t_gen_mov_TN_preg(cpu_T[0], PR_CCS);
453
                tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~X_FLAG);
454
                t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
455
                dc->flagx_live = 1;
456
                dc->flags_x = 0;
457
        }
458
}
459

    
460
static void cris_evaluate_flags(DisasContext *dc)
461
{
462
        if (!dc->flags_live) {
463
                switch (dc->cc_op)
464
                {
465
                        case CC_OP_MCP:
466
                                gen_op_evaluate_flags_mcp ();
467
                                break;
468
                        case CC_OP_MULS:
469
                                gen_op_evaluate_flags_muls ();
470
                                break;
471
                        case CC_OP_MULU:
472
                                gen_op_evaluate_flags_mulu ();
473
                                break;
474
                        case CC_OP_MOVE:
475
                                switch (dc->cc_size)
476
                                {
477
                                        case 4:
478
                                                gen_op_evaluate_flags_move_4();
479
                                                break;
480
                                        case 2:
481
                                                gen_op_evaluate_flags_move_2();
482
                                                break;
483
                                        default:
484
                                                gen_op_evaluate_flags ();
485
                                                break;
486
                                }
487
                                break;
488

    
489
                        default:
490
                        {
491
                                switch (dc->cc_size)
492
                                {
493
                                        case 4:
494
                                                gen_op_evaluate_flags_alu_4 ();
495
                                                break;
496
                                        default:
497
                                                gen_op_evaluate_flags ();
498
                                                break;
499
                                }
500
                        }
501
                        break;
502
                }
503
                dc->flags_live = 1;
504
        }
505
}
506

    
507
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
508
{
509
        uint32_t ovl;
510

    
511
        /* Check if we need to evaluate the condition codes due to 
512
           CC overlaying.  */
513
        ovl = (dc->cc_mask ^ mask) & ~mask;
514
        if (ovl) {
515
                /* TODO: optimize this case. It trigs all the time.  */
516
                cris_evaluate_flags (dc);
517
        }
518
        dc->cc_mask = mask;
519
        dc->update_cc = 1;
520

    
521
        if (mask == 0)
522
                dc->update_cc = 0;
523
        else
524
                dc->flags_live = 0;
525
}
526

    
527
static void cris_update_cc_op(DisasContext *dc, int op)
528
{
529
        dc->cc_op = op;
530
        dc->flags_live = 0;
531
        tcg_gen_movi_tl(cc_op, op);
532
}
533
static void cris_update_cc_size(DisasContext *dc, int size)
534
{
535
        dc->cc_size = size;
536
        tcg_gen_movi_tl(cc_size, size);
537
}
538

    
539
/* op is the operation.
540
   T0, T1 are the operands.
541
   dst is the destination reg.
542
*/
543
static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
544
{
545
        int writeback = 1;
546
        if (dc->update_cc) {
547
                cris_update_cc_op(dc, op);
548
                cris_update_cc_size(dc, size);
549
                tcg_gen_mov_tl(cc_dest, cpu_T[0]);
550
                tcg_gen_movi_tl(cc_mask, dc->cc_mask);
551

    
552
                /* FIXME: This shouldn't be needed. But we don't pass the
553
                 tests without it. Investigate.  */
554
                t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live));
555
                t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x));
556
        }
557

    
558
        /* Emit the ALU insns.  */
559
        switch (op)
560
        {
561
                case CC_OP_ADD:
562
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
563
                        /* Extended arithmetics.  */
564
                        t_gen_addx_carry(cpu_T[0]);
565
                        break;
566
                case CC_OP_ADDC:
567
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
568
                        t_gen_add_flag(cpu_T[0], 0); /* C_FLAG.  */
569
                        break;
570
                case CC_OP_MCP:
571
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
572
                        t_gen_add_flag(cpu_T[0], 8); /* R_FLAG.  */
573
                        break;
574
                case CC_OP_SUB:
575
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
576
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
577
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
578
                        /* CRIS flag evaluation needs ~src.  */
579
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
580

    
581
                        /* Extended arithmetics.  */
582
                        t_gen_subx_carry(cpu_T[0]);
583
                        break;
584
                case CC_OP_MOVE:
585
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
586
                        break;
587
                case CC_OP_OR:
588
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
589
                        break;
590
                case CC_OP_AND:
591
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
592
                        break;
593
                case CC_OP_XOR:
594
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
595
                        break;
596
                case CC_OP_LSL:
597
                        t_gen_lsl(cpu_T[0], cpu_T[0], cpu_T[1]);
598
                        break;
599
                case CC_OP_LSR:
600
                        t_gen_lsr(cpu_T[0], cpu_T[0], cpu_T[1]);
601
                        break;
602
                case CC_OP_ASR:
603
                        t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
604
                        break;
605
                case CC_OP_NEG:
606
                        /* Hopefully the TCG backend recognizes this pattern
607
                           and makes a real neg out of it.  */
608
                        tcg_gen_sub_tl(cpu_T[0], tcg_const_tl(0), cpu_T[1]);
609
                        /* Extended arithmetics.  */
610
                        t_gen_subx_carry(cpu_T[0]);
611
                        break;
612
                case CC_OP_LZ:
613
                        gen_op_lz_T0_T1();
614
                        break;
615
                case CC_OP_BTST:
616
                        gen_op_btst_T0_T1();
617
                        writeback = 0;
618
                        break;
619
                case CC_OP_MULS:
620
                {
621
                        TCGv mof;
622
                        mof = tcg_temp_new(TCG_TYPE_TL);
623
                        t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
624
                        t_gen_mov_preg_TN(PR_MOF, mof);
625
                }
626
                break;
627
                case CC_OP_MULU:
628
                {
629
                        TCGv mof;
630
                        mof = tcg_temp_new(TCG_TYPE_TL);
631
                        t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
632
                        t_gen_mov_preg_TN(PR_MOF, mof);
633
                }
634
                break;
635
                case CC_OP_DSTEP:
636
                        gen_op_dstep_T0_T1();
637
                        break;
638
                case CC_OP_BOUND:
639
                {
640
                        int l1;
641
                        l1 = gen_new_label();
642
                        tcg_gen_brcond_tl(TCG_COND_LEU, 
643
                                          cpu_T[0], cpu_T[1], l1);
644
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
645
                        gen_set_label(l1);
646
                }
647
                break;
648
                case CC_OP_CMP:
649
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
650
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
651
                        /* CRIS flag evaluation needs ~src.  */
652
                        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
653
                        /* CRIS flag evaluation needs ~src.  */
654
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
655

    
656
                        /* Extended arithmetics.  */
657
                        t_gen_subx_carry(cpu_T[0]);
658
                        writeback = 0;
659
                        break;
660
                default:
661
                        fprintf (logfile, "illegal ALU op.\n");
662
                        BUG();
663
                        break;
664
        }
665

    
666
        if (dc->update_cc)
667
                tcg_gen_mov_tl(cc_src, cpu_T[1]);
668

    
669
        if (size == 1)
670
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
671
        else if (size == 2)
672
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
673

    
674
        /* Writeback.  */
675
        if (writeback) {
676
                if (size == 4)
677
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
678
                else {
679
                        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
680
                        t_gen_mov_TN_reg(cpu_T[0], rd);
681
                        if (size == 1)
682
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xff);
683
                        else
684
                                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0xffff);
685
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
686
                        t_gen_mov_reg_TN(rd, cpu_T[0]);
687
                        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
688
                }
689
        }
690
        if (dc->update_cc)
691
                tcg_gen_mov_tl(cc_result, cpu_T[0]);
692

    
693
        {
694
                /* TODO: Optimize this.  */
695
                if (!dc->flagx_live)
696
                        cris_evaluate_flags(dc);
697
        }
698
}
699

    
700
static int arith_cc(DisasContext *dc)
701
{
702
        if (dc->update_cc) {
703
                switch (dc->cc_op) {
704
                        case CC_OP_ADD: return 1;
705
                        case CC_OP_SUB: return 1;
706
                        case CC_OP_LSL: return 1;
707
                        case CC_OP_LSR: return 1;
708
                        case CC_OP_ASR: return 1;
709
                        case CC_OP_CMP: return 1;
710
                        default:
711
                                return 0;
712
                }
713
        }
714
        return 0;
715
}
716

    
717
static void gen_tst_cc (DisasContext *dc, int cond)
718
{
719
        int arith_opt;
720

    
721
        /* TODO: optimize more condition codes.  */
722
        arith_opt = arith_cc(dc) && !dc->flags_live;
723
        switch (cond) {
724
                case CC_EQ:
725
                        if (arith_opt)
726
                                gen_op_tst_cc_eq_fast ();
727
                        else {
728
                                cris_evaluate_flags(dc);
729
                                gen_op_tst_cc_eq ();
730
                        }
731
                        break;
732
                case CC_NE:
733
                        if (arith_opt)
734
                                gen_op_tst_cc_ne_fast ();
735
                        else {
736
                                cris_evaluate_flags(dc);
737
                                gen_op_tst_cc_ne ();
738
                        }
739
                        break;
740
                case CC_CS:
741
                        cris_evaluate_flags(dc);
742
                        gen_op_tst_cc_cs ();
743
                        break;
744
                case CC_CC:
745
                        cris_evaluate_flags(dc);
746
                        gen_op_tst_cc_cc ();
747
                        break;
748
                case CC_VS:
749
                        cris_evaluate_flags(dc);
750
                        gen_op_tst_cc_vs ();
751
                        break;
752
                case CC_VC:
753
                        cris_evaluate_flags(dc);
754
                        gen_op_tst_cc_vc ();
755
                        break;
756
                case CC_PL:
757
                        if (arith_opt)
758
                                gen_op_tst_cc_pl_fast ();
759
                        else {
760
                                cris_evaluate_flags(dc);
761
                                gen_op_tst_cc_pl ();
762
                        }
763
                        break;
764
                case CC_MI:
765
                        if (arith_opt)
766
                                gen_op_tst_cc_mi_fast ();
767
                        else {
768
                                cris_evaluate_flags(dc);
769
                                gen_op_tst_cc_mi ();
770
                        }
771
                        break;
772
                case CC_LS:
773
                        cris_evaluate_flags(dc);
774
                        gen_op_tst_cc_ls ();
775
                        break;
776
                case CC_HI:
777
                        cris_evaluate_flags(dc);
778
                        gen_op_tst_cc_hi ();
779
                        break;
780
                case CC_GE:
781
                        cris_evaluate_flags(dc);
782
                        gen_op_tst_cc_ge ();
783
                        break;
784
                case CC_LT:
785
                        cris_evaluate_flags(dc);
786
                        gen_op_tst_cc_lt ();
787
                        break;
788
                case CC_GT:
789
                        cris_evaluate_flags(dc);
790
                        gen_op_tst_cc_gt ();
791
                        break;
792
                case CC_LE:
793
                        cris_evaluate_flags(dc);
794
                        gen_op_tst_cc_le ();
795
                        break;
796
                case CC_P:
797
                        cris_evaluate_flags(dc);
798
                        gen_op_tst_cc_p ();
799
                        break;
800
                case CC_A:
801
                        cris_evaluate_flags(dc);
802
                        gen_op_movl_T0_im (1);
803
                        break;
804
                default:
805
                        BUG();
806
                        break;
807
        };
808
}
809

    
810
static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
811
{
812
        /* This helps us re-schedule the micro-code to insns in delay-slots
813
           before the actual jump.  */
814
        dc->delayed_branch = 2;
815
        dc->delayed_pc = dc->pc + offset;
816
        dc->bcc = cond;
817
        if (cond != CC_A)
818
        {
819
                gen_tst_cc (dc, cond);
820
                gen_op_evaluate_bcc ();
821
        }
822
        tcg_gen_movi_tl(cpu_T[0], dc->delayed_pc);
823
        t_gen_mov_env_TN(btarget, cpu_T[0]);
824
}
825

    
826
/* Dynamic jumps, when the dest is in a live reg for example.  */
827
void cris_prepare_dyn_jmp (DisasContext *dc)
828
{
829
        /* This helps us re-schedule the micro-code to insns in delay-slots
830
           before the actual jump.  */
831
        dc->delayed_branch = 2;
832
        dc->dyn_jmp = 1;
833
        dc->bcc = CC_A;
834
}
835

    
836
void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
837
{
838
        /* This helps us re-schedule the micro-code to insns in delay-slots
839
           before the actual jump.  */
840
        dc->delayed_branch = 2;
841
        dc->delayed_pc = dst;
842
        dc->dyn_jmp = 0;
843
        dc->bcc = CC_A;
844
}
845

    
846
void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
847
{
848
        if (size == 1) {
849
                if (sign)
850
                        gen_op_ldb_T0_T0(dc);
851
                else
852
                        gen_op_ldub_T0_T0(dc);
853
        }
854
        else if (size == 2) {
855
                if (sign)
856
                        gen_op_ldw_T0_T0(dc);
857
                else
858
                        gen_op_lduw_T0_T0(dc);
859
        }
860
        else {
861
                gen_op_ldl_T0_T0(dc);
862
        }
863
}
864

    
865
void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
866
{
867
        /* Remember, operands are flipped. CRIS has reversed order.  */
868
        if (size == 1) {
869
                gen_op_stb_T0_T1(dc);
870
        }
871
        else if (size == 2) {
872
                gen_op_stw_T0_T1(dc);
873
        }
874
        else
875
                gen_op_stl_T0_T1(dc);
876
}
877

    
878
static inline void t_gen_sext(TCGv d, TCGv s, int size)
879
{
880
        if (size == 1)
881
                tcg_gen_ext8s_i32(d, s);
882
        else if (size == 2)
883
                tcg_gen_ext16s_i32(d, s);
884
}
885

    
886
static inline void t_gen_zext(TCGv d, TCGv s, int size)
887
{
888
        /* TCG-FIXME: this is not optimal. Many archs have fast zext insns.  */
889
        if (size == 1)
890
                tcg_gen_andi_i32(d, s, 0xff);
891
        else if (size == 2)
892
                tcg_gen_andi_i32(d, s, 0xffff);
893
}
894

    
895
#if DISAS_CRIS
896
static char memsize_char(int size)
897
{
898
        switch (size)
899
        {
900
                case 1: return 'b';  break;
901
                case 2: return 'w';  break;
902
                case 4: return 'd';  break;
903
                default:
904
                        return 'x';
905
                        break;
906
        }
907
}
908
#endif
909

    
910
static unsigned int memsize_z(DisasContext *dc)
911
{
912
        return dc->zsize + 1;
913
}
914

    
915
static unsigned int memsize_zz(DisasContext *dc)
916
{
917
        switch (dc->zzsize)
918
        {
919
                case 0: return 1;
920
                case 1: return 2;
921
                default:
922
                        return 4;
923
        }
924
}
925

    
926
static void do_postinc (DisasContext *dc, int size)
927
{
928
        if (!dc->postinc)
929
                return;
930
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
931
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], size);
932
        t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
933
}
934

    
935

    
936
static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
937
                            int size, int s_ext)
938
{
939
        t_gen_mov_TN_reg(cpu_T[1], rs);
940
        if (s_ext)
941
                t_gen_sext(cpu_T[1], cpu_T[1], size);
942
        else
943
                t_gen_zext(cpu_T[1], cpu_T[1], size);
944
}
945

    
946
/* Prepare T0 and T1 for a register alu operation.
947
   s_ext decides if the operand1 should be sign-extended or zero-extended when
948
   needed.  */
949
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
950
                          int size, int s_ext)
951
{
952
        dec_prep_move_r(dc, rs, rd, size, s_ext);
953

    
954
        t_gen_mov_TN_reg(cpu_T[0], rd);
955
        if (s_ext)
956
                t_gen_sext(cpu_T[0], cpu_T[0], size);
957
        else
958
                t_gen_zext(cpu_T[0], cpu_T[0], size);
959
}
960

    
961
/* Prepare T0 and T1 for a memory + alu operation.
962
   s_ext decides if the operand1 should be sign-extended or zero-extended when
963
   needed.  */
964
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
965
{
966
        unsigned int rs, rd;
967
        uint32_t imm;
968
        int is_imm;
969
        int insn_len = 2;
970

    
971
        rs = dc->op1;
972
        rd = dc->op2;
973
        is_imm = rs == 15 && dc->postinc;
974

    
975
        /* Load [$rs] onto T1.  */
976
        if (is_imm) {
977
                insn_len = 2 + memsize;
978
                if (memsize == 1)
979
                        insn_len++;
980

    
981
                imm = ldl_code(dc->pc + 2);
982
                if (memsize != 4) {
983
                        if (s_ext) {
984
                                imm = sign_extend(imm, (memsize * 8) - 1);
985
                        } else {
986
                                if (memsize == 1)
987
                                        imm &= 0xff;
988
                                else
989
                                        imm &= 0xffff;
990
                        }
991
                }
992
                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
993
                            imm, rd, s_ext, memsize));
994
                tcg_gen_movi_tl(cpu_T[1], imm);
995
                dc->postinc = 0;
996
        } else {
997
                t_gen_mov_TN_reg(cpu_T[0], rs);
998
                gen_load_T0_T0(dc, memsize, 0);
999
                tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1000
                if (s_ext)
1001
                        t_gen_sext(cpu_T[1], cpu_T[1], memsize);
1002
                else
1003
                        t_gen_zext(cpu_T[1], cpu_T[1], memsize);
1004
        }
1005

    
1006
        /* put dest in T0.  */
1007
        t_gen_mov_TN_reg(cpu_T[0], rd);
1008
        return insn_len;
1009
}
1010

    
1011
#if DISAS_CRIS
1012
static const char *cc_name(int cc)
1013
{
1014
        static char *cc_names[16] = {
1015
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1016
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1017
        };
1018
        assert(cc < 16);
1019
        return cc_names[cc];
1020
}
1021
#endif
1022

    
1023
static unsigned int dec_bccq(DisasContext *dc)
1024
{
1025
        int32_t offset;
1026
        int sign;
1027
        uint32_t cond = dc->op2;
1028
        int tmp;
1029

    
1030
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1031
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1032

    
1033
        offset *= 2;
1034
        offset |= sign << 8;
1035
        tmp = offset;
1036
        offset = sign_extend(offset, 8);
1037

    
1038
        /* op2 holds the condition-code.  */
1039
        cris_cc_mask(dc, 0);
1040
        cris_prepare_cc_branch (dc, offset, cond);
1041
        return 2;
1042
}
1043
static unsigned int dec_addoq(DisasContext *dc)
1044
{
1045
        uint32_t imm;
1046

    
1047
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1048
        imm = sign_extend(dc->op1, 7);
1049

    
1050
        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1051
        cris_cc_mask(dc, 0);
1052
        /* Fetch register operand,  */
1053
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1054
        tcg_gen_movi_tl(cpu_T[1], imm);
1055
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1056
        return 2;
1057
}
1058
static unsigned int dec_addq(DisasContext *dc)
1059
{
1060
        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
1061

    
1062
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1063

    
1064
        cris_cc_mask(dc, CC_MASK_NZVC);
1065
        /* Fetch register operand,  */
1066
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1067
        tcg_gen_movi_tl(cpu_T[1], dc->op1);
1068
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1069
        return 2;
1070
}
1071
static unsigned int dec_moveq(DisasContext *dc)
1072
{
1073
        uint32_t imm;
1074

    
1075
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1076
        imm = sign_extend(dc->op1, 5);
1077
        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
1078

    
1079
        t_gen_mov_reg_TN(dc->op2, tcg_const_tl(imm));
1080
        return 2;
1081
}
1082
static unsigned int dec_subq(DisasContext *dc)
1083
{
1084
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1085

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

    
1088
        cris_cc_mask(dc, CC_MASK_NZVC);
1089
        /* Fetch register operand,  */
1090
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1091
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1092
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1093
        return 2;
1094
}
1095
static unsigned int dec_cmpq(DisasContext *dc)
1096
{
1097
        uint32_t imm;
1098
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1099
        imm = sign_extend(dc->op1, 5);
1100

    
1101
        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
1102
        cris_cc_mask(dc, CC_MASK_NZVC);
1103
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1104
        t_gen_mov_TN_im(cpu_T[1], imm);
1105
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1106
        return 2;
1107
}
1108
static unsigned int dec_andq(DisasContext *dc)
1109
{
1110
        uint32_t imm;
1111
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1112
        imm = sign_extend(dc->op1, 5);
1113

    
1114
        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
1115
        cris_cc_mask(dc, CC_MASK_NZ);
1116
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1117
        t_gen_mov_TN_im(cpu_T[1], imm);
1118
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
1119
        return 2;
1120
}
1121
static unsigned int dec_orq(DisasContext *dc)
1122
{
1123
        uint32_t imm;
1124
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1125
        imm = sign_extend(dc->op1, 5);
1126
        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
1127
        cris_cc_mask(dc, CC_MASK_NZ);
1128
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1129
        t_gen_mov_TN_im(cpu_T[1], imm);
1130
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
1131
        return 2;
1132
}
1133
static unsigned int dec_btstq(DisasContext *dc)
1134
{
1135
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1136
        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
1137
        cris_cc_mask(dc, CC_MASK_NZ);
1138
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1139
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1140
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1141

    
1142
        cris_update_cc_op(dc, CC_OP_FLAGS);
1143
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1144
        dc->flags_live = 1;
1145
        return 2;
1146
}
1147
static unsigned int dec_asrq(DisasContext *dc)
1148
{
1149
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1150
        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
1151
        cris_cc_mask(dc, CC_MASK_NZ);
1152
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1153
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1154
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
1155
        return 2;
1156
}
1157
static unsigned int dec_lslq(DisasContext *dc)
1158
{
1159
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1160
        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
1161

    
1162
        cris_cc_mask(dc, CC_MASK_NZ);
1163
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1164
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1165
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
1166
        return 2;
1167
}
1168
static unsigned int dec_lsrq(DisasContext *dc)
1169
{
1170
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1171
        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
1172

    
1173
        cris_cc_mask(dc, CC_MASK_NZ);
1174
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1175
        t_gen_mov_TN_im(cpu_T[1], dc->op1);
1176
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
1177
        return 2;
1178
}
1179

    
1180
static unsigned int dec_move_r(DisasContext *dc)
1181
{
1182
        int size = memsize_zz(dc);
1183

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

    
1187
        cris_cc_mask(dc, CC_MASK_NZ);
1188
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1189
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
1190
        return 2;
1191
}
1192

    
1193
static unsigned int dec_scc_r(DisasContext *dc)
1194
{
1195
        int cond = dc->op2;
1196

    
1197
        DIS(fprintf (logfile, "s%s $r%u\n",
1198
                    cc_name(cond), dc->op1));
1199

    
1200
        if (cond != CC_A)
1201
        {
1202
                gen_tst_cc (dc, cond);
1203
                tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1204
        }
1205
        else
1206
                tcg_gen_movi_tl(cpu_T[1], 1);
1207

    
1208
        cris_cc_mask(dc, 0);
1209
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1210
        return 2;
1211
}
1212

    
1213
static unsigned int dec_and_r(DisasContext *dc)
1214
{
1215
        int size = memsize_zz(dc);
1216

    
1217
        DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
1218
                    memsize_char(size), dc->op1, dc->op2));
1219
        cris_cc_mask(dc, CC_MASK_NZ);
1220
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1221
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
1222
        return 2;
1223
}
1224

    
1225
static unsigned int dec_lz_r(DisasContext *dc)
1226
{
1227
        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
1228
                    dc->op1, dc->op2));
1229
        cris_cc_mask(dc, CC_MASK_NZ);
1230
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1231
        crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
1232
        return 2;
1233
}
1234

    
1235
static unsigned int dec_lsl_r(DisasContext *dc)
1236
{
1237
        int size = memsize_zz(dc);
1238

    
1239
        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
1240
                    memsize_char(size), dc->op1, dc->op2));
1241
        cris_cc_mask(dc, CC_MASK_NZ);
1242
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1243
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1244
        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
1245
        return 2;
1246
}
1247

    
1248
static unsigned int dec_lsr_r(DisasContext *dc)
1249
{
1250
        int size = memsize_zz(dc);
1251

    
1252
        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
1253
                    memsize_char(size), dc->op1, dc->op2));
1254
        cris_cc_mask(dc, CC_MASK_NZ);
1255
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1256
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1257
        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
1258
        return 2;
1259
}
1260

    
1261
static unsigned int dec_asr_r(DisasContext *dc)
1262
{
1263
        int size = memsize_zz(dc);
1264

    
1265
        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
1266
                    memsize_char(size), dc->op1, dc->op2));
1267
        cris_cc_mask(dc, CC_MASK_NZ);
1268
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1269
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
1270
        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
1271
        return 2;
1272
}
1273

    
1274
static unsigned int dec_muls_r(DisasContext *dc)
1275
{
1276
        int size = memsize_zz(dc);
1277

    
1278
        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
1279
                    memsize_char(size), dc->op1, dc->op2));
1280
        cris_cc_mask(dc, CC_MASK_NZV);
1281
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
1282
        t_gen_sext(cpu_T[0], cpu_T[0], size);
1283
        crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
1284
        return 2;
1285
}
1286

    
1287
static unsigned int dec_mulu_r(DisasContext *dc)
1288
{
1289
        int size = memsize_zz(dc);
1290

    
1291
        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
1292
                    memsize_char(size), dc->op1, dc->op2));
1293
        cris_cc_mask(dc, CC_MASK_NZV);
1294
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1295
        t_gen_zext(cpu_T[0], cpu_T[0], size);
1296
        crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
1297
        return 2;
1298
}
1299

    
1300

    
1301
static unsigned int dec_dstep_r(DisasContext *dc)
1302
{
1303
        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
1304
        cris_cc_mask(dc, CC_MASK_NZ);
1305
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1306
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1307
        crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
1308
        return 2;
1309
}
1310

    
1311
static unsigned int dec_xor_r(DisasContext *dc)
1312
{
1313
        int size = memsize_zz(dc);
1314
        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
1315
                    memsize_char(size), dc->op1, dc->op2));
1316
        BUG_ON(size != 4); /* xor is dword.  */
1317
        cris_cc_mask(dc, CC_MASK_NZ);
1318
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1319
        crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
1320
        return 2;
1321
}
1322

    
1323
static unsigned int dec_bound_r(DisasContext *dc)
1324
{
1325
        int size = memsize_zz(dc);
1326
        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
1327
                    memsize_char(size), dc->op1, dc->op2));
1328
        cris_cc_mask(dc, CC_MASK_NZ);
1329
        /* TODO: needs optmimization.  */
1330
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1331
        /* rd should be 4.  */
1332
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1333
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1334
        return 2;
1335
}
1336

    
1337
static unsigned int dec_cmp_r(DisasContext *dc)
1338
{
1339
        int size = memsize_zz(dc);
1340
        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
1341
                    memsize_char(size), dc->op1, dc->op2));
1342
        cris_cc_mask(dc, CC_MASK_NZVC);
1343
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1344
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
1345
        return 2;
1346
}
1347

    
1348
static unsigned int dec_abs_r(DisasContext *dc)
1349
{
1350
        int l1;
1351

    
1352
        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
1353
                    dc->op1, dc->op2));
1354
        cris_cc_mask(dc, CC_MASK_NZ);
1355
        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
1356

    
1357
        /* TODO: consider a branch free approach.  */
1358
        l1 = gen_new_label();
1359
        tcg_gen_brcond_tl(TCG_COND_GE, cpu_T[1], tcg_const_tl(0), l1);
1360
        tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]);
1361
        gen_set_label(l1);
1362
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1363
        return 2;
1364
}
1365

    
1366
static unsigned int dec_add_r(DisasContext *dc)
1367
{
1368
        int size = memsize_zz(dc);
1369
        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
1370
                    memsize_char(size), dc->op1, dc->op2));
1371
        cris_cc_mask(dc, CC_MASK_NZVC);
1372
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1373
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
1374
        return 2;
1375
}
1376

    
1377
static unsigned int dec_addc_r(DisasContext *dc)
1378
{
1379
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1380
                    dc->op1, dc->op2));
1381
        cris_evaluate_flags(dc);
1382
        cris_cc_mask(dc, CC_MASK_NZVC);
1383
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1384
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1385
        return 2;
1386
}
1387

    
1388
static unsigned int dec_mcp_r(DisasContext *dc)
1389
{
1390
        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
1391
                     dc->op2, dc->op1));
1392
        cris_evaluate_flags(dc);
1393
        cris_cc_mask(dc, CC_MASK_RNZV);
1394
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1395
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1396
        crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
1397
        return 2;
1398
}
1399

    
1400
#if DISAS_CRIS
1401
static char * swapmode_name(int mode, char *modename) {
1402
        int i = 0;
1403
        if (mode & 8)
1404
                modename[i++] = 'n';
1405
        if (mode & 4)
1406
                modename[i++] = 'w';
1407
        if (mode & 2)
1408
                modename[i++] = 'b';
1409
        if (mode & 1)
1410
                modename[i++] = 'r';
1411
        modename[i++] = 0;
1412
        return modename;
1413
}
1414
#endif
1415

    
1416
static unsigned int dec_swap_r(DisasContext *dc)
1417
{
1418
        DIS(char modename[4]);
1419
        DIS(fprintf (logfile, "swap%s $r%u\n",
1420
                     swapmode_name(dc->op2, modename), dc->op1));
1421

    
1422
        cris_cc_mask(dc, CC_MASK_NZ);
1423
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1424
        if (dc->op2 & 8)
1425
                tcg_gen_xori_tl(cpu_T[0], cpu_T[0], -1);
1426
        if (dc->op2 & 4)
1427
                t_gen_swapw(cpu_T[0], cpu_T[0]);
1428
        if (dc->op2 & 2)
1429
                t_gen_swapb(cpu_T[0], cpu_T[0]);
1430
        if (dc->op2 & 1)
1431
                t_gen_swapr(cpu_T[0], cpu_T[0]);
1432
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1433
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1434
        return 2;
1435
}
1436

    
1437
static unsigned int dec_or_r(DisasContext *dc)
1438
{
1439
        int size = memsize_zz(dc);
1440
        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
1441
                    memsize_char(size), dc->op1, dc->op2));
1442
        cris_cc_mask(dc, CC_MASK_NZ);
1443
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1444
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
1445
        return 2;
1446
}
1447

    
1448
static unsigned int dec_addi_r(DisasContext *dc)
1449
{
1450
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
1451
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1452
        cris_cc_mask(dc, 0);
1453
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1454
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1455
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1456
        t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
1457
        return 2;
1458
}
1459

    
1460
static unsigned int dec_addi_acr(DisasContext *dc)
1461
{
1462
        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1463
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1464
        cris_cc_mask(dc, 0);
1465
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1466
        t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1467

    
1468
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1469
        t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
1470
        return 2;
1471
}
1472

    
1473
static unsigned int dec_neg_r(DisasContext *dc)
1474
{
1475
        int size = memsize_zz(dc);
1476
        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
1477
                    memsize_char(size), dc->op1, dc->op2));
1478
        cris_cc_mask(dc, CC_MASK_NZVC);
1479
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1480
        crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
1481
        return 2;
1482
}
1483

    
1484
static unsigned int dec_btst_r(DisasContext *dc)
1485
{
1486
        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
1487
                    dc->op1, dc->op2));
1488
        cris_cc_mask(dc, CC_MASK_NZ);
1489
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1490
        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1491

    
1492
        cris_update_cc_op(dc, CC_OP_FLAGS);
1493
        t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1494
        dc->flags_live = 1;
1495
        return 2;
1496
}
1497

    
1498
static unsigned int dec_sub_r(DisasContext *dc)
1499
{
1500
        int size = memsize_zz(dc);
1501
        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
1502
                    memsize_char(size), dc->op1, dc->op2));
1503
        cris_cc_mask(dc, CC_MASK_NZVC);
1504
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
1505
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
1506
        return 2;
1507
}
1508

    
1509
/* Zero extension. From size to dword.  */
1510
static unsigned int dec_movu_r(DisasContext *dc)
1511
{
1512
        int size = memsize_z(dc);
1513
        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
1514
                    memsize_char(size),
1515
                    dc->op1, dc->op2));
1516

    
1517
        cris_cc_mask(dc, CC_MASK_NZ);
1518
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
1519
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1520
        return 2;
1521
}
1522

    
1523
/* Sign extension. From size to dword.  */
1524
static unsigned int dec_movs_r(DisasContext *dc)
1525
{
1526
        int size = memsize_z(dc);
1527
        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
1528
                    memsize_char(size),
1529
                    dc->op1, dc->op2));
1530

    
1531
        cris_cc_mask(dc, CC_MASK_NZ);
1532
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1533
        /* Size can only be qi or hi.  */
1534
        t_gen_sext(cpu_T[1], cpu_T[0], size);
1535
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1536
        return 2;
1537
}
1538

    
1539
/* zero extension. From size to dword.  */
1540
static unsigned int dec_addu_r(DisasContext *dc)
1541
{
1542
        int size = memsize_z(dc);
1543
        DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
1544
                    memsize_char(size),
1545
                    dc->op1, dc->op2));
1546

    
1547
        cris_cc_mask(dc, CC_MASK_NZVC);
1548
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1549
        /* Size can only be qi or hi.  */
1550
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1551
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1552
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1553
        return 2;
1554
}
1555

    
1556
/* Sign extension. From size to dword.  */
1557
static unsigned int dec_adds_r(DisasContext *dc)
1558
{
1559
        int size = memsize_z(dc);
1560
        DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
1561
                    memsize_char(size),
1562
                    dc->op1, dc->op2));
1563

    
1564
        cris_cc_mask(dc, CC_MASK_NZVC);
1565
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1566
        /* Size can only be qi or hi.  */
1567
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1568
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1569

    
1570
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1571
        return 2;
1572
}
1573

    
1574
/* Zero extension. From size to dword.  */
1575
static unsigned int dec_subu_r(DisasContext *dc)
1576
{
1577
        int size = memsize_z(dc);
1578
        DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
1579
                    memsize_char(size),
1580
                    dc->op1, dc->op2));
1581

    
1582
        cris_cc_mask(dc, CC_MASK_NZVC);
1583
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1584
        /* Size can only be qi or hi.  */
1585
        t_gen_zext(cpu_T[1], cpu_T[1], size);
1586
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1587
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1588
        return 2;
1589
}
1590

    
1591
/* Sign extension. From size to dword.  */
1592
static unsigned int dec_subs_r(DisasContext *dc)
1593
{
1594
        int size = memsize_z(dc);
1595
        DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
1596
                    memsize_char(size),
1597
                    dc->op1, dc->op2));
1598

    
1599
        cris_cc_mask(dc, CC_MASK_NZVC);
1600
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
1601
        /* Size can only be qi or hi.  */
1602
        t_gen_sext(cpu_T[1], cpu_T[1], size);
1603
        t_gen_mov_TN_reg(cpu_T[0], dc->op2);
1604
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1605
        return 2;
1606
}
1607

    
1608
static unsigned int dec_setclrf(DisasContext *dc)
1609
{
1610
        uint32_t flags;
1611
        int set = (~dc->opcode >> 2) & 1;
1612

    
1613
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1614
                | EXTRACT_FIELD(dc->ir, 0, 3);
1615
        DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1616
        if (set && flags == 0)
1617
                DIS(fprintf (logfile, "nop\n"));
1618
        else if (!set && (flags & 0x20))
1619
                DIS(fprintf (logfile, "di\n"));
1620
        else
1621
                DIS(fprintf (logfile, "%sf %x\n",
1622
                            set ? "set" : "clr",
1623
                            flags));
1624

    
1625
        if (set && (flags & X_FLAG)) {
1626
                dc->flagx_live = 1;
1627
                dc->flags_x = 1;
1628
        }
1629

    
1630
        /* Simply decode the flags.  */
1631
        cris_evaluate_flags (dc);
1632
        cris_update_cc_op(dc, CC_OP_FLAGS);
1633
        if (set)
1634
                gen_op_setf(flags);
1635
        else
1636
                gen_op_clrf(flags);
1637
        dc->flags_live = 1;
1638
        return 2;
1639
}
1640

    
1641
static unsigned int dec_move_rs(DisasContext *dc)
1642
{
1643
        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
1644
        cris_cc_mask(dc, 0);
1645
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1646
        gen_op_movl_sreg_T0(dc->op2);
1647

    
1648
#if !defined(CONFIG_USER_ONLY)
1649
        if (dc->op2 == 6)
1650
                gen_op_movl_tlb_hi_T0();
1651
        else if (dc->op2 == 5) { /* srs is checked at runtime.  */
1652
                tcg_gen_helper_0_1(helper_tlb_update, cpu_T[0]);
1653
                gen_op_movl_tlb_lo_T0();
1654
        }
1655
#endif
1656
        return 2;
1657
}
1658
static unsigned int dec_move_sr(DisasContext *dc)
1659
{
1660
        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1));
1661
        cris_cc_mask(dc, 0);
1662
        gen_op_movl_T0_sreg(dc->op2);
1663
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1664
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
1665
        return 2;
1666
}
1667
static unsigned int dec_move_rp(DisasContext *dc)
1668
{
1669
        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1670
        cris_cc_mask(dc, 0);
1671
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1672
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
1673
        return 2;
1674
}
1675
static unsigned int dec_move_pr(DisasContext *dc)
1676
{
1677
        DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
1678
        cris_cc_mask(dc, 0);
1679
        /* Support register 0 is hardwired to zero. 
1680
           Treat it specially. */
1681
        if (dc->op2 == 0)
1682
                tcg_gen_movi_tl(cpu_T[1], 0);
1683
        else
1684
                t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1685
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1686
        return 2;
1687
}
1688

    
1689
static unsigned int dec_move_mr(DisasContext *dc)
1690
{
1691
        int memsize = memsize_zz(dc);
1692
        int insn_len;
1693
        DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
1694
                    memsize_char(memsize),
1695
                    dc->op1, dc->postinc ? "+]" : "]",
1696
                    dc->op2));
1697

    
1698
        cris_cc_mask(dc, CC_MASK_NZ);
1699
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1700
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1701
        do_postinc(dc, memsize);
1702
        return insn_len;
1703
}
1704

    
1705
static unsigned int dec_movs_m(DisasContext *dc)
1706
{
1707
        int memsize = memsize_z(dc);
1708
        int insn_len;
1709
        DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
1710
                    memsize_char(memsize),
1711
                    dc->op1, dc->postinc ? "+]" : "]",
1712
                    dc->op2));
1713

    
1714
        /* sign extend.  */
1715
        cris_cc_mask(dc, CC_MASK_NZ);
1716
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1717
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1718
        do_postinc(dc, memsize);
1719
        return insn_len;
1720
}
1721

    
1722
static unsigned int dec_addu_m(DisasContext *dc)
1723
{
1724
        int memsize = memsize_z(dc);
1725
        int insn_len;
1726
        DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
1727
                    memsize_char(memsize),
1728
                    dc->op1, dc->postinc ? "+]" : "]",
1729
                    dc->op2));
1730

    
1731
        /* sign extend.  */
1732
        cris_cc_mask(dc, CC_MASK_NZVC);
1733
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1734
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1735
        do_postinc(dc, memsize);
1736
        return insn_len;
1737
}
1738

    
1739
static unsigned int dec_adds_m(DisasContext *dc)
1740
{
1741
        int memsize = memsize_z(dc);
1742
        int insn_len;
1743
        DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
1744
                    memsize_char(memsize),
1745
                    dc->op1, dc->postinc ? "+]" : "]",
1746
                    dc->op2));
1747

    
1748
        /* sign extend.  */
1749
        cris_cc_mask(dc, CC_MASK_NZVC);
1750
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1751
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1752
        do_postinc(dc, memsize);
1753
        return insn_len;
1754
}
1755

    
1756
static unsigned int dec_subu_m(DisasContext *dc)
1757
{
1758
        int memsize = memsize_z(dc);
1759
        int insn_len;
1760
        DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
1761
                    memsize_char(memsize),
1762
                    dc->op1, dc->postinc ? "+]" : "]",
1763
                    dc->op2));
1764

    
1765
        /* sign extend.  */
1766
        cris_cc_mask(dc, CC_MASK_NZVC);
1767
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1768
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1769
        do_postinc(dc, memsize);
1770
        return insn_len;
1771
}
1772

    
1773
static unsigned int dec_subs_m(DisasContext *dc)
1774
{
1775
        int memsize = memsize_z(dc);
1776
        int insn_len;
1777
        DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
1778
                    memsize_char(memsize),
1779
                    dc->op1, dc->postinc ? "+]" : "]",
1780
                    dc->op2));
1781

    
1782
        /* sign extend.  */
1783
        cris_cc_mask(dc, CC_MASK_NZVC);
1784
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1785
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1786
        do_postinc(dc, memsize);
1787
        return insn_len;
1788
}
1789

    
1790
static unsigned int dec_movu_m(DisasContext *dc)
1791
{
1792
        int memsize = memsize_z(dc);
1793
        int insn_len;
1794

    
1795
        DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
1796
                    memsize_char(memsize),
1797
                    dc->op1, dc->postinc ? "+]" : "]",
1798
                    dc->op2));
1799

    
1800
        cris_cc_mask(dc, CC_MASK_NZ);
1801
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1802
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1803
        do_postinc(dc, memsize);
1804
        return insn_len;
1805
}
1806

    
1807
static unsigned int dec_cmpu_m(DisasContext *dc)
1808
{
1809
        int memsize = memsize_z(dc);
1810
        int insn_len;
1811
        DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
1812
                    memsize_char(memsize),
1813
                    dc->op1, dc->postinc ? "+]" : "]",
1814
                    dc->op2));
1815

    
1816
        cris_cc_mask(dc, CC_MASK_NZVC);
1817
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1818
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1819
        do_postinc(dc, memsize);
1820
        return insn_len;
1821
}
1822

    
1823
static unsigned int dec_cmps_m(DisasContext *dc)
1824
{
1825
        int memsize = memsize_z(dc);
1826
        int insn_len;
1827
        DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
1828
                    memsize_char(memsize),
1829
                    dc->op1, dc->postinc ? "+]" : "]",
1830
                    dc->op2));
1831

    
1832
        cris_cc_mask(dc, CC_MASK_NZVC);
1833
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1834
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1835
        do_postinc(dc, memsize);
1836
        return insn_len;
1837
}
1838

    
1839
static unsigned int dec_cmp_m(DisasContext *dc)
1840
{
1841
        int memsize = memsize_zz(dc);
1842
        int insn_len;
1843
        DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
1844
                    memsize_char(memsize),
1845
                    dc->op1, dc->postinc ? "+]" : "]",
1846
                    dc->op2));
1847

    
1848
        cris_cc_mask(dc, CC_MASK_NZVC);
1849
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1850
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1851
        do_postinc(dc, memsize);
1852
        return insn_len;
1853
}
1854

    
1855
static unsigned int dec_test_m(DisasContext *dc)
1856
{
1857
        int memsize = memsize_zz(dc);
1858
        int insn_len;
1859
        DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
1860
                    memsize_char(memsize),
1861
                    dc->op1, dc->postinc ? "+]" : "]",
1862
                    dc->op2));
1863

    
1864
        cris_cc_mask(dc, CC_MASK_NZ);
1865
        gen_op_clrf(3);
1866
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1867
        tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1868
        tcg_gen_movi_tl(cpu_T[1], 0);
1869
        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1870
        do_postinc(dc, memsize);
1871
        return insn_len;
1872
}
1873

    
1874
static unsigned int dec_and_m(DisasContext *dc)
1875
{
1876
        int memsize = memsize_zz(dc);
1877
        int insn_len;
1878
        DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
1879
                    memsize_char(memsize),
1880
                    dc->op1, dc->postinc ? "+]" : "]",
1881
                    dc->op2));
1882

    
1883
        cris_cc_mask(dc, CC_MASK_NZ);
1884
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1885
        crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1886
        do_postinc(dc, memsize);
1887
        return insn_len;
1888
}
1889

    
1890
static unsigned int dec_add_m(DisasContext *dc)
1891
{
1892
        int memsize = memsize_zz(dc);
1893
        int insn_len;
1894
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1895
                    memsize_char(memsize),
1896
                    dc->op1, dc->postinc ? "+]" : "]",
1897
                    dc->op2));
1898

    
1899
        cris_cc_mask(dc, CC_MASK_NZVC);
1900
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1901
        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1902
        do_postinc(dc, memsize);
1903
        return insn_len;
1904
}
1905

    
1906
static unsigned int dec_addo_m(DisasContext *dc)
1907
{
1908
        int memsize = memsize_zz(dc);
1909
        int insn_len;
1910
        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
1911
                    memsize_char(memsize),
1912
                    dc->op1, dc->postinc ? "+]" : "]",
1913
                    dc->op2));
1914

    
1915
        cris_cc_mask(dc, 0);
1916
        insn_len = dec_prep_alu_m(dc, 1, memsize);
1917
        crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1918
        do_postinc(dc, memsize);
1919
        return insn_len;
1920
}
1921

    
1922
static unsigned int dec_bound_m(DisasContext *dc)
1923
{
1924
        int memsize = memsize_zz(dc);
1925
        int insn_len;
1926
        DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
1927
                    memsize_char(memsize),
1928
                    dc->op1, dc->postinc ? "+]" : "]",
1929
                    dc->op2));
1930

    
1931
        cris_cc_mask(dc, CC_MASK_NZ);
1932
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1933
        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1934
        do_postinc(dc, memsize);
1935
        return insn_len;
1936
}
1937

    
1938
static unsigned int dec_addc_mr(DisasContext *dc)
1939
{
1940
        int insn_len = 2;
1941
        DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
1942
                    dc->op1, dc->postinc ? "+]" : "]",
1943
                    dc->op2));
1944

    
1945
        cris_evaluate_flags(dc);
1946
        cris_cc_mask(dc, CC_MASK_NZVC);
1947
        insn_len = dec_prep_alu_m(dc, 0, 4);
1948
        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1949
        do_postinc(dc, 4);
1950
        return insn_len;
1951
}
1952

    
1953
static unsigned int dec_sub_m(DisasContext *dc)
1954
{
1955
        int memsize = memsize_zz(dc);
1956
        int insn_len;
1957
        DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
1958
                    memsize_char(memsize),
1959
                    dc->op1, dc->postinc ? "+]" : "]",
1960
                    dc->op2, dc->ir, dc->zzsize));
1961

    
1962
        cris_cc_mask(dc, CC_MASK_NZVC);
1963
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1964
        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1965
        do_postinc(dc, memsize);
1966
        return insn_len;
1967
}
1968

    
1969
static unsigned int dec_or_m(DisasContext *dc)
1970
{
1971
        int memsize = memsize_zz(dc);
1972
        int insn_len;
1973
        DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
1974
                    memsize_char(memsize),
1975
                    dc->op1, dc->postinc ? "+]" : "]",
1976
                    dc->op2, dc->pc));
1977

    
1978
        cris_cc_mask(dc, CC_MASK_NZ);
1979
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1980
        crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1981
        do_postinc(dc, memsize);
1982
        return insn_len;
1983
}
1984

    
1985
static unsigned int dec_move_mp(DisasContext *dc)
1986
{
1987
        int memsize = memsize_zz(dc);
1988
        int insn_len = 2;
1989

    
1990
        DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
1991
                    memsize_char(memsize),
1992
                    dc->op1,
1993
                    dc->postinc ? "+]" : "]",
1994
                    dc->op2));
1995

    
1996
        cris_cc_mask(dc, 0);
1997
        insn_len = dec_prep_alu_m(dc, 0, memsize);
1998
        t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
1999

    
2000
        do_postinc(dc, memsize);
2001
        return insn_len;
2002
}
2003

    
2004
static unsigned int dec_move_pm(DisasContext *dc)
2005
{
2006
        int memsize;
2007

    
2008
        memsize = preg_sizes[dc->op2];
2009

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

    
2014
        cris_cc_mask(dc, 0);
2015
        /* prepare store. Address in T0, value in T1.  */
2016
        t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2017
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2018
        gen_store_T0_T1(dc, memsize);
2019
        if (dc->postinc)
2020
        {
2021
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2022
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2023
        }
2024
        return 2;
2025
}
2026

    
2027
static unsigned int dec_movem_mr(DisasContext *dc)
2028
{
2029
        int i;
2030

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

    
2034
        cris_cc_mask(dc, 0);
2035
        /* fetch the address into T0 and T1.  */
2036
        t_gen_mov_TN_reg(cpu_T[1], dc->op1);
2037
        for (i = 0; i <= dc->op2; i++) {
2038
                /* Perform the load onto regnum i. Always dword wide.  */
2039
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
2040
                gen_load_T0_T0(dc, 4, 0);
2041
                t_gen_mov_reg_TN(i, cpu_T[0]);
2042
                tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
2043
        }
2044
        /* writeback the updated pointer value.  */
2045
        if (dc->postinc)
2046
                t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
2047
        return 2;
2048
}
2049

    
2050
static unsigned int dec_movem_rm(DisasContext *dc)
2051
{
2052
        int i;
2053

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

    
2057
        cris_cc_mask(dc, 0);
2058
        for (i = 0; i <= dc->op2; i++) {
2059
                /* Fetch register i into T1.  */
2060
                t_gen_mov_TN_reg(cpu_T[1], i);
2061
                /* Fetch the address into T0.  */
2062
                t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2063
                /* Displace it.  */
2064
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], i * 4);
2065
                /* Perform the store.  */
2066
                gen_store_T0_T1(dc, 4);
2067
        }
2068
        if (dc->postinc) {
2069
                /* T0 should point to the last written addr, advance one more
2070
                   step. */
2071
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 4);
2072
                /* writeback the updated pointer value.  */
2073
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2074
        }
2075
        return 2;
2076
}
2077

    
2078
static unsigned int dec_move_rm(DisasContext *dc)
2079
{
2080
        int memsize;
2081

    
2082
        memsize = memsize_zz(dc);
2083

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

    
2087
        cris_cc_mask(dc, 0);
2088
        /* prepare store.  */
2089
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2090
        t_gen_mov_TN_reg(cpu_T[1], dc->op2);
2091
        gen_store_T0_T1(dc, memsize);
2092
        if (dc->postinc)
2093
        {
2094
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2095
                t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2096
        }
2097
        return 2;
2098
}
2099

    
2100
static unsigned int dec_lapcq(DisasContext *dc)
2101
{
2102
        DIS(fprintf (logfile, "lapcq %x, $r%u\n",
2103
                    dc->pc + dc->op1*2, dc->op2));
2104
        cris_cc_mask(dc, 0);
2105
        tcg_gen_movi_tl(cpu_T[1], dc->pc + dc->op1 * 2);
2106
        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
2107
        return 2;
2108
}
2109

    
2110
static unsigned int dec_lapc_im(DisasContext *dc)
2111
{
2112
        unsigned int rd;
2113
        int32_t imm;
2114

    
2115
        rd = dc->op2;
2116

    
2117
        cris_cc_mask(dc, 0);
2118
        imm = ldl_code(dc->pc + 2);
2119
        DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
2120
        t_gen_mov_reg_TN(rd, tcg_const_tl(dc->pc + imm));
2121
        return 6;
2122
}
2123

    
2124
/* Jump to special reg.  */
2125
static unsigned int dec_jump_p(DisasContext *dc)
2126
{
2127
        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2128
        cris_cc_mask(dc, 0);
2129
        /* Store the return address in Pd.  */
2130
        t_gen_mov_TN_preg(cpu_T[0], dc->op2);
2131
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2132
        cris_prepare_dyn_jmp(dc);
2133
        return 2;
2134
}
2135

    
2136
/* Jump and save.  */
2137
static unsigned int dec_jas_r(DisasContext *dc)
2138
{
2139
        DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
2140
        cris_cc_mask(dc, 0);
2141
        /* Stor the return address in Pd.  */
2142
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2143
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2144
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);
2145
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2146
        cris_prepare_dyn_jmp(dc);
2147
        return 2;
2148
}
2149

    
2150
static unsigned int dec_jas_im(DisasContext *dc)
2151
{
2152
        uint32_t imm;
2153

    
2154
        imm = ldl_code(dc->pc + 2);
2155

    
2156
        DIS(fprintf (logfile, "jas 0x%x\n", imm));
2157
        cris_cc_mask(dc, 0);
2158
        /* Stor the return address in Pd.  */
2159
        t_gen_mov_env_TN(btarget, tcg_const_tl(imm));
2160
        t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2161
        cris_prepare_dyn_jmp(dc);
2162
        return 6;
2163
}
2164

    
2165
static unsigned int dec_jasc_im(DisasContext *dc)
2166
{
2167
        uint32_t imm;
2168

    
2169
        imm = ldl_code(dc->pc + 2);
2170

    
2171
        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
2172
        cris_cc_mask(dc, 0);
2173
        /* Stor the return address in Pd.  */
2174
        tcg_gen_movi_tl(cpu_T[0], imm);
2175
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2176
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
2177
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2178
        cris_prepare_dyn_jmp(dc);
2179
        return 6;
2180
}
2181

    
2182
static unsigned int dec_jasc_r(DisasContext *dc)
2183
{
2184
        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
2185
        cris_cc_mask(dc, 0);
2186
        /* Stor the return address in Pd.  */
2187
        t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2188
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2189
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
2190
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2191
        cris_prepare_dyn_jmp(dc);
2192
        return 2;
2193
}
2194

    
2195
static unsigned int dec_bcc_im(DisasContext *dc)
2196
{
2197
        int32_t offset;
2198
        uint32_t cond = dc->op2;
2199

    
2200
        offset = ldl_code(dc->pc + 2);
2201
        offset = sign_extend(offset, 15);
2202

    
2203
        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
2204
                    cc_name(cond), offset,
2205
                    dc->pc, dc->pc + offset));
2206

    
2207
        cris_cc_mask(dc, 0);
2208
        /* op2 holds the condition-code.  */
2209
        cris_prepare_cc_branch (dc, offset, cond);
2210
        return 4;
2211
}
2212

    
2213
static unsigned int dec_bas_im(DisasContext *dc)
2214
{
2215
        int32_t simm;
2216

    
2217

    
2218
        simm = ldl_code(dc->pc + 2);
2219

    
2220
        DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2221
        cris_cc_mask(dc, 0);
2222
        /* Stor the return address in Pd.  */
2223
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2224
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2225
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
2226
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2227
        cris_prepare_dyn_jmp(dc);
2228
        return 6;
2229
}
2230

    
2231
static unsigned int dec_basc_im(DisasContext *dc)
2232
{
2233
        int32_t simm;
2234
        simm = ldl_code(dc->pc + 2);
2235

    
2236
        DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
2237
        cris_cc_mask(dc, 0);
2238
        /* Stor the return address in Pd.  */
2239
        tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2240
        t_gen_mov_env_TN(btarget, cpu_T[0]);
2241
        tcg_gen_movi_tl(cpu_T[0], dc->pc + 12);
2242
        t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
2243
        cris_prepare_dyn_jmp(dc);
2244
        return 6;
2245
}
2246

    
2247
static unsigned int dec_rfe_etc(DisasContext *dc)
2248
{
2249
        DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2250
                    dc->opcode, dc->pc, dc->op1, dc->op2));
2251

    
2252
        cris_cc_mask(dc, 0);
2253

    
2254
        if (dc->op2 == 15) /* ignore halt.  */
2255
                return 2;
2256

    
2257
        switch (dc->op2 & 7) {
2258
                case 2:
2259
                        /* rfe.  */
2260
                        cris_evaluate_flags(dc);
2261
                        gen_op_ccs_rshift();
2262
                        break;
2263
                case 5:
2264
                        /* rfn.  */
2265
                        BUG();
2266
                        break;
2267
                case 6:
2268
                        /* break.  */
2269
                        tcg_gen_movi_tl(cpu_T[0], dc->pc);
2270
                        t_gen_mov_env_TN(pc, cpu_T[0]);
2271
                        /* Breaks start at 16 in the exception vector.  */
2272
                        gen_op_break_im(dc->op1 + 16);
2273
                        dc->is_jmp = DISAS_SWI;
2274
                        break;
2275
                default:
2276
                        printf ("op2=%x\n", dc->op2);
2277
                        BUG();
2278
                        break;
2279

    
2280
        }
2281
        return 2;
2282
}
2283

    
2284
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
2285
{
2286
        /* Ignore D-cache flushes.  */
2287
        return 2;
2288
}
2289

    
2290
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
2291
{
2292
        /* Ignore I-cache flushes.  */
2293
        return 2;
2294
}
2295

    
2296
static unsigned int dec_null(DisasContext *dc)
2297
{
2298
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2299
                dc->pc, dc->opcode, dc->op1, dc->op2);
2300
        fflush(NULL);
2301
        BUG();
2302
        return 2;
2303
}
2304

    
2305
struct decoder_info {
2306
        struct {
2307
                uint32_t bits;
2308
                uint32_t mask;
2309
        };
2310
        unsigned int (*dec)(DisasContext *dc);
2311
} decinfo[] = {
2312
        /* Order matters here.  */
2313
        {DEC_MOVEQ, dec_moveq},
2314
        {DEC_BTSTQ, dec_btstq},
2315
        {DEC_CMPQ, dec_cmpq},
2316
        {DEC_ADDOQ, dec_addoq},
2317
        {DEC_ADDQ, dec_addq},
2318
        {DEC_SUBQ, dec_subq},
2319
        {DEC_ANDQ, dec_andq},
2320
        {DEC_ORQ, dec_orq},
2321
        {DEC_ASRQ, dec_asrq},
2322
        {DEC_LSLQ, dec_lslq},
2323
        {DEC_LSRQ, dec_lsrq},
2324
        {DEC_BCCQ, dec_bccq},
2325

    
2326
        {DEC_BCC_IM, dec_bcc_im},
2327
        {DEC_JAS_IM, dec_jas_im},
2328
        {DEC_JAS_R, dec_jas_r},
2329
        {DEC_JASC_IM, dec_jasc_im},
2330
        {DEC_JASC_R, dec_jasc_r},
2331
        {DEC_BAS_IM, dec_bas_im},
2332
        {DEC_BASC_IM, dec_basc_im},
2333
        {DEC_JUMP_P, dec_jump_p},
2334
        {DEC_LAPC_IM, dec_lapc_im},
2335
        {DEC_LAPCQ, dec_lapcq},
2336

    
2337
        {DEC_RFE_ETC, dec_rfe_etc},
2338
        {DEC_ADDC_MR, dec_addc_mr},
2339

    
2340
        {DEC_MOVE_MP, dec_move_mp},
2341
        {DEC_MOVE_PM, dec_move_pm},
2342
        {DEC_MOVEM_MR, dec_movem_mr},
2343
        {DEC_MOVEM_RM, dec_movem_rm},
2344
        {DEC_MOVE_PR, dec_move_pr},
2345
        {DEC_SCC_R, dec_scc_r},
2346
        {DEC_SETF, dec_setclrf},
2347
        {DEC_CLEARF, dec_setclrf},
2348

    
2349
        {DEC_MOVE_SR, dec_move_sr},
2350
        {DEC_MOVE_RP, dec_move_rp},
2351
        {DEC_SWAP_R, dec_swap_r},
2352
        {DEC_ABS_R, dec_abs_r},
2353
        {DEC_LZ_R, dec_lz_r},
2354
        {DEC_MOVE_RS, dec_move_rs},
2355
        {DEC_BTST_R, dec_btst_r},
2356
        {DEC_ADDC_R, dec_addc_r},
2357

    
2358
        {DEC_DSTEP_R, dec_dstep_r},
2359
        {DEC_XOR_R, dec_xor_r},
2360
        {DEC_MCP_R, dec_mcp_r},
2361
        {DEC_CMP_R, dec_cmp_r},
2362

    
2363
        {DEC_ADDI_R, dec_addi_r},
2364
        {DEC_ADDI_ACR, dec_addi_acr},
2365

    
2366
        {DEC_ADD_R, dec_add_r},
2367
        {DEC_SUB_R, dec_sub_r},
2368

    
2369
        {DEC_ADDU_R, dec_addu_r},
2370
        {DEC_ADDS_R, dec_adds_r},
2371
        {DEC_SUBU_R, dec_subu_r},
2372
        {DEC_SUBS_R, dec_subs_r},
2373
        {DEC_LSL_R, dec_lsl_r},
2374

    
2375
        {DEC_AND_R, dec_and_r},
2376
        {DEC_OR_R, dec_or_r},
2377
        {DEC_BOUND_R, dec_bound_r},
2378
        {DEC_ASR_R, dec_asr_r},
2379
        {DEC_LSR_R, dec_lsr_r},
2380

    
2381
        {DEC_MOVU_R, dec_movu_r},
2382
        {DEC_MOVS_R, dec_movs_r},
2383
        {DEC_NEG_R, dec_neg_r},
2384
        {DEC_MOVE_R, dec_move_r},
2385

    
2386
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2387
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2388

    
2389
        {DEC_MULS_R, dec_muls_r},
2390
        {DEC_MULU_R, dec_mulu_r},
2391

    
2392
        {DEC_ADDU_M, dec_addu_m},
2393
        {DEC_ADDS_M, dec_adds_m},
2394
        {DEC_SUBU_M, dec_subu_m},
2395
        {DEC_SUBS_M, dec_subs_m},
2396

    
2397
        {DEC_CMPU_M, dec_cmpu_m},
2398
        {DEC_CMPS_M, dec_cmps_m},
2399
        {DEC_MOVU_M, dec_movu_m},
2400
        {DEC_MOVS_M, dec_movs_m},
2401

    
2402
        {DEC_CMP_M, dec_cmp_m},
2403
        {DEC_ADDO_M, dec_addo_m},
2404
        {DEC_BOUND_M, dec_bound_m},
2405
        {DEC_ADD_M, dec_add_m},
2406
        {DEC_SUB_M, dec_sub_m},
2407
        {DEC_AND_M, dec_and_m},
2408
        {DEC_OR_M, dec_or_m},
2409
        {DEC_MOVE_RM, dec_move_rm},
2410
        {DEC_TEST_M, dec_test_m},
2411
        {DEC_MOVE_MR, dec_move_mr},
2412

    
2413
        {{0, 0}, dec_null}
2414
};
2415

    
2416
static inline unsigned int
2417
cris_decoder(DisasContext *dc)
2418
{
2419
        unsigned int insn_len = 2;
2420
        uint32_t tmp;
2421
        int i;
2422

    
2423
        /* Load a halfword onto the instruction register.  */
2424
        tmp = ldl_code(dc->pc);
2425
        dc->ir = tmp & 0xffff;
2426

    
2427
        /* Now decode it.  */
2428
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2429
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2430
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2431
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2432
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2433
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2434

    
2435
        /* Large switch for all insns.  */
2436
        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
2437
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
2438
                {
2439
                        insn_len = decinfo[i].dec(dc);
2440
                        break;
2441
                }
2442
        }
2443

    
2444
        return insn_len;
2445
}
2446

    
2447
static void check_breakpoint(CPUState *env, DisasContext *dc)
2448
{
2449
        int j;
2450
        if (env->nb_breakpoints > 0) {
2451
                for(j = 0; j < env->nb_breakpoints; j++) {
2452
                        if (env->breakpoints[j] == dc->pc) {
2453
                                cris_evaluate_flags (dc);
2454
                                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2455
                                t_gen_mov_env_TN(pc, cpu_T[0]);
2456
                                gen_op_debug();
2457
                                dc->is_jmp = DISAS_UPDATE;
2458
                        }
2459
                }
2460
        }
2461
}
2462

    
2463
/* generate intermediate code for basic block 'tb'.  */
2464
struct DisasContext ctx;
2465
static int
2466
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2467
                               int search_pc)
2468
{
2469
        uint16_t *gen_opc_end;
2470
           uint32_t pc_start;
2471
        unsigned int insn_len;
2472
        int j, lj;
2473
        struct DisasContext *dc = &ctx;
2474
        uint32_t next_page_start;
2475

    
2476
        if (!logfile)
2477
                logfile = stderr;
2478

    
2479
        pc_start = tb->pc;
2480
        dc->env = env;
2481
        dc->tb = tb;
2482

    
2483
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2484

    
2485
        dc->is_jmp = DISAS_NEXT;
2486
        dc->pc = pc_start;
2487
        dc->singlestep_enabled = env->singlestep_enabled;
2488
        dc->flagx_live = 0;
2489
        dc->flags_x = 0;
2490

    
2491
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2492
        lj = -1;
2493
        do
2494
        {
2495
                check_breakpoint(env, dc);
2496
                if (dc->is_jmp == DISAS_JUMP
2497
                    || dc->is_jmp == DISAS_SWI)
2498
                        goto done;
2499

    
2500
                if (search_pc) {
2501
                        j = gen_opc_ptr - gen_opc_buf;
2502
                        if (lj < j) {
2503
                                lj++;
2504
                                while (lj < j)
2505
                                        gen_opc_instr_start[lj++] = 0;
2506
                        }
2507
                        gen_opc_pc[lj] = dc->pc;
2508
                        gen_opc_instr_start[lj] = 1;
2509
                }
2510

    
2511
                insn_len = cris_decoder(dc);
2512
                STATS(gen_op_exec_insn());
2513
                dc->pc += insn_len;
2514
                cris_clear_x_flag(dc);
2515

    
2516
                /* Check for delayed branches here. If we do it before
2517
                   actually genereating any host code, the simulator will just
2518
                   loop doing nothing for on this program location.  */
2519
                if (dc->delayed_branch) {
2520
                        dc->delayed_branch--;
2521
                        if (dc->delayed_branch == 0)
2522
                        {
2523
                                if (dc->bcc == CC_A) {
2524
                                        gen_op_jmp1 ();
2525
                                        dc->is_jmp = DISAS_UPDATE;
2526
                                }
2527
                                else {
2528
                                        /* Conditional jmp.  */
2529
                                        gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2530
                                        dc->is_jmp = DISAS_UPDATE;
2531
                                }
2532
                        }
2533
                }
2534

    
2535
                if (env->singlestep_enabled)
2536
                        break;
2537
        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2538
                 && dc->pc < next_page_start);
2539

    
2540
        if (!dc->is_jmp) {
2541
                tcg_gen_movi_tl(cpu_T[0], dc->pc);
2542
                t_gen_mov_env_TN(pc, cpu_T[0]);
2543
        }
2544

    
2545
        cris_evaluate_flags (dc);
2546
  done:
2547
        if (__builtin_expect(env->singlestep_enabled, 0)) {
2548
                gen_op_debug();
2549
        } else {
2550
                switch(dc->is_jmp) {
2551
                        case DISAS_NEXT:
2552
                                gen_goto_tb(dc, 1, dc->pc);
2553
                                break;
2554
                        default:
2555
                        case DISAS_JUMP:
2556
                        case DISAS_UPDATE:
2557
                                /* indicate that the hash table must be used
2558
                                   to find the next TB */
2559
                                tcg_gen_exit_tb(0);
2560
                                break;
2561
                        case DISAS_SWI:
2562
                        case DISAS_TB_JUMP:
2563
                                /* nothing more to generate */
2564
                                break;
2565
                }
2566
        }
2567
        *gen_opc_ptr = INDEX_op_end;
2568
        if (search_pc) {
2569
                j = gen_opc_ptr - gen_opc_buf;
2570
                lj++;
2571
                while (lj <= j)
2572
                        gen_opc_instr_start[lj++] = 0;
2573
        } else {
2574
                tb->size = dc->pc - pc_start;
2575
        }
2576

    
2577
#ifdef DEBUG_DISAS
2578
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2579
                fprintf(logfile, "--------------\n");
2580
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2581
                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2582
                fprintf(logfile, "\n");
2583
        }
2584
#endif
2585
        return 0;
2586
}
2587

    
2588
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2589
{
2590
    return gen_intermediate_code_internal(env, tb, 0);
2591
}
2592

    
2593
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2594
{
2595
    return gen_intermediate_code_internal(env, tb, 1);
2596
}
2597

    
2598
void cpu_dump_state (CPUState *env, FILE *f,
2599
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2600
                     int flags)
2601
{
2602
        int i;
2603
        uint32_t srs;
2604

    
2605
        if (!env || !f)
2606
                return;
2607

    
2608
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
2609
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
2610
                    "debug=%x %x %x\n",
2611
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
2612
                    env->cc_op,
2613
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
2614
                    env->debug1, env->debug2, env->debug3);
2615

    
2616
        for (i = 0; i < 16; i++) {
2617
                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
2618
                if ((i + 1) % 4 == 0)
2619
                        cpu_fprintf(f, "\n");
2620
        }
2621
        cpu_fprintf(f, "\nspecial regs:\n");
2622
        for (i = 0; i < 16; i++) {
2623
                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
2624
                if ((i + 1) % 4 == 0)
2625
                        cpu_fprintf(f, "\n");
2626
        }
2627
        srs = env->pregs[PR_SRS];
2628
        cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
2629
        if (srs < 256) {
2630
                for (i = 0; i < 16; i++) {
2631
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
2632
                                    i, env->sregs[srs][i]);
2633
                        if ((i + 1) % 4 == 0)
2634
                                cpu_fprintf(f, "\n");
2635
                }
2636
        }
2637
        cpu_fprintf(f, "\n\n");
2638

    
2639
}
2640

    
2641
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
2642
{
2643
}
2644

    
2645
CPUCRISState *cpu_cris_init (const char *cpu_model)
2646
{
2647
        CPUCRISState *env;
2648
        int i;
2649

    
2650
        env = qemu_mallocz(sizeof(CPUCRISState));
2651
        if (!env)
2652
                return NULL;
2653
        cpu_exec_init(env);
2654

    
2655
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
2656
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
2657
#if TARGET_LONG_BITS > HOST_LONG_BITS
2658
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
2659
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
2660
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
2661
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
2662
#else
2663
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
2664
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
2665
#endif
2666

    
2667
        cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2668
                                    offsetof(CPUState, cc_src), "cc_src");
2669
        cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2670
                                     offsetof(CPUState, cc_dest), 
2671
                                     "cc_dest");
2672
        cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2673
                                       offsetof(CPUState, cc_result), 
2674
                                       "cc_result");
2675
        cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2676
                                   offsetof(CPUState, cc_op), "cc_op");
2677
        cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2678
                                     offsetof(CPUState, cc_size), 
2679
                                     "cc_size");
2680
        cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2681
                                     offsetof(CPUState, cc_mask),
2682
                                     "cc_mask");
2683

    
2684
        for (i = 0; i < 16; i++) {
2685
                cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2686
                                              offsetof(CPUState, regs[i]), 
2687
                                              regnames[i]);
2688
        }
2689
        for (i = 0; i < 16; i++) {
2690
                cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 
2691
                                               offsetof(CPUState, pregs[i]), 
2692
                                               pregnames[i]);
2693
        }
2694

    
2695
        cpu_reset(env);
2696
        return env;
2697
}
2698

    
2699
void cpu_reset (CPUCRISState *env)
2700
{
2701
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
2702
        tlb_flush(env, 1);
2703
}