Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 8cfd0495

History | View | Annotate | Download (93.6 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, see <http://www.gnu.org/licenses/>.
19
 */
20

    
21
/*
22
 * FIXME:
23
 * The condition code translation is in need of attention.
24
 */
25

    
26
#include "cpu.h"
27
#include "disas/disas.h"
28
#include "tcg-op.h"
29
#include "helper.h"
30
#include "mmu.h"
31
#include "crisv32-decode.h"
32

    
33
#define GEN_HELPER 1
34
#include "helper.h"
35

    
36
#define DISAS_CRIS 0
37
#if DISAS_CRIS
38
#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
39
#else
40
#  define LOG_DIS(...) do { } while (0)
41
#endif
42

    
43
#define D(x)
44
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
45
#define BUG_ON(x) ({if (x) BUG();})
46

    
47
#define DISAS_SWI 5
48

    
49
/* Used by the decoder.  */
50
#define EXTRACT_FIELD(src, start, end) \
51
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
52

    
53
#define CC_MASK_NZ 0xc
54
#define CC_MASK_NZV 0xe
55
#define CC_MASK_NZVC 0xf
56
#define CC_MASK_RNZV 0x10e
57

    
58
static TCGv_ptr cpu_env;
59
static TCGv cpu_R[16];
60
static TCGv cpu_PR[16];
61
static TCGv cc_x;
62
static TCGv cc_src;
63
static TCGv cc_dest;
64
static TCGv cc_result;
65
static TCGv cc_op;
66
static TCGv cc_size;
67
static TCGv cc_mask;
68

    
69
static TCGv env_btaken;
70
static TCGv env_btarget;
71
static TCGv env_pc;
72

    
73
#include "exec/gen-icount.h"
74

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

    
80
    /* Decoder.  */
81
        unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
82
    uint32_t ir;
83
    uint32_t opcode;
84
    unsigned int op1;
85
    unsigned int op2;
86
    unsigned int zsize, zzsize;
87
    unsigned int mode;
88
    unsigned int postinc;
89

    
90
    unsigned int size;
91
    unsigned int src;
92
    unsigned int dst;
93
    unsigned int cond;
94

    
95
    int update_cc;
96
    int cc_op;
97
    int cc_size;
98
    uint32_t cc_mask;
99

    
100
    int cc_size_uptodate; /* -1 invalid or last written value.  */
101

    
102
    int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
103
    int flags_uptodate; /* Wether or not $ccs is uptodate.  */
104
    int flagx_known; /* Wether or not flags_x has the x flag known at
105
                translation time.  */
106
    int flags_x;
107

    
108
    int clear_x; /* Clear x after this insn?  */
109
    int clear_prefix; /* Clear prefix after this insn?  */
110
    int clear_locked_irq; /* Clear the irq lockout.  */
111
    int cpustate_changed;
112
    unsigned int tb_flags; /* tb dependent flags.  */
113
    int is_jmp;
114

    
115
#define JMP_NOJMP     0
116
#define JMP_DIRECT    1
117
#define JMP_DIRECT_CC 2
118
#define JMP_INDIRECT  3
119
    int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */
120
    uint32_t jmp_pc;
121

    
122
    int delayed_branch;
123

    
124
    struct TranslationBlock *tb;
125
    int singlestep_enabled;
126
} DisasContext;
127

    
128
static void gen_BUG(DisasContext *dc, const char *file, int line)
129
{
130
    printf("BUG: pc=%x %s %d\n", dc->pc, file, line);
131
    qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
132
    cpu_abort(dc->env, "%s:%d\n", file, line);
133
}
134

    
135
static const char *regnames[] =
136
{
137
    "$r0", "$r1", "$r2", "$r3",
138
    "$r4", "$r5", "$r6", "$r7",
139
    "$r8", "$r9", "$r10", "$r11",
140
    "$r12", "$r13", "$sp", "$acr",
141
};
142
static const char *pregnames[] =
143
{
144
    "$bz", "$vr", "$pid", "$srs",
145
    "$wz", "$exs", "$eda", "$mof",
146
    "$dz", "$ebp", "$erp", "$srp",
147
    "$nrp", "$ccs", "$usp", "$spc",
148
};
149

    
150
/* We need this table to handle preg-moves with implicit width.  */
151
static int preg_sizes[] = {
152
    1, /* bz.  */
153
    1, /* vr.  */
154
    4, /* pid.  */
155
    1, /* srs.  */
156
    2, /* wz.  */
157
    4, 4, 4,
158
    4, 4, 4, 4,
159
    4, 4, 4, 4,
160
};
161

    
162
#define t_gen_mov_TN_env(tn, member) \
163
 _t_gen_mov_TN_env((tn), offsetof(CPUCRISState, member))
164
#define t_gen_mov_env_TN(member, tn) \
165
 _t_gen_mov_env_TN(offsetof(CPUCRISState, member), (tn))
166

    
167
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
168
{
169
    if (r < 0 || r > 15) {
170
        fprintf(stderr, "wrong register read $r%d\n", r);
171
    }
172
    tcg_gen_mov_tl(tn, cpu_R[r]);
173
}
174
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
175
{
176
    if (r < 0 || r > 15) {
177
        fprintf(stderr, "wrong register write $r%d\n", r);
178
    }
179
    tcg_gen_mov_tl(cpu_R[r], tn);
180
}
181

    
182
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
183
{
184
    if (offset > sizeof(CPUCRISState)) {
185
        fprintf(stderr, "wrong load from env from off=%d\n", offset);
186
    }
187
    tcg_gen_ld_tl(tn, cpu_env, offset);
188
}
189
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
190
{
191
    if (offset > sizeof(CPUCRISState)) {
192
        fprintf(stderr, "wrong store to env at off=%d\n", offset);
193
    }
194
    tcg_gen_st_tl(tn, cpu_env, offset);
195
}
196

    
197
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
198
{
199
    if (r < 0 || r > 15) {
200
        fprintf(stderr, "wrong register read $p%d\n", r);
201
    }
202
    if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
203
        tcg_gen_mov_tl(tn, tcg_const_tl(0));
204
    } else if (r == PR_VR) {
205
        tcg_gen_mov_tl(tn, tcg_const_tl(32));
206
    } else {
207
        tcg_gen_mov_tl(tn, cpu_PR[r]);
208
    }
209
}
210
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
211
{
212
    if (r < 0 || r > 15) {
213
        fprintf(stderr, "wrong register write $p%d\n", r);
214
    }
215
    if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
216
        return;
217
    } else if (r == PR_SRS) {
218
        tcg_gen_andi_tl(cpu_PR[r], tn, 3);
219
    } else {
220
        if (r == PR_PID) {
221
            gen_helper_tlb_flush_pid(cpu_env, tn);
222
        }
223
        if (dc->tb_flags & S_FLAG && r == PR_SPC) {
224
            gen_helper_spc_write(cpu_env, tn);
225
        } else if (r == PR_CCS) {
226
            dc->cpustate_changed = 1;
227
        }
228
        tcg_gen_mov_tl(cpu_PR[r], tn);
229
    }
230
}
231

    
232
/* Sign extend at translation time.  */
233
static int sign_extend(unsigned int val, unsigned int width)
234
{
235
    int sval;
236

    
237
    /* LSL.  */
238
    val <<= 31 - width;
239
    sval = val;
240
    /* ASR.  */
241
    sval >>= 31 - width;
242
    return sval;
243
}
244

    
245
static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
246
              unsigned int size, unsigned int sign)
247
{
248
    int r;
249

    
250
    switch (size) {
251
    case 4:
252
    {
253
        r = cpu_ldl_code(env, addr);
254
        break;
255
    }
256
    case 2:
257
    {
258
        if (sign) {
259
            r = cpu_ldsw_code(env, addr);
260
        } else {
261
            r = cpu_lduw_code(env, addr);
262
        }
263
        break;
264
    }
265
    case 1:
266
    {
267
        if (sign) {
268
            r = cpu_ldsb_code(env, addr);
269
        } else {
270
            r = cpu_ldub_code(env, addr);
271
        }
272
        break;
273
    }
274
    default:
275
        cpu_abort(dc->env, "Invalid fetch size %d\n", size);
276
        break;
277
    }
278
    return r;
279
}
280

    
281
static void cris_lock_irq(DisasContext *dc)
282
{
283
    dc->clear_locked_irq = 0;
284
    t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
285
}
286

    
287
static inline void t_gen_raise_exception(uint32_t index)
288
{
289
        TCGv_i32 tmp = tcg_const_i32(index);
290
        gen_helper_raise_exception(cpu_env, tmp);
291
        tcg_temp_free_i32(tmp);
292
}
293

    
294
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
295
{
296
    TCGv t0, t_31;
297

    
298
    t0 = tcg_temp_new();
299
    t_31 = tcg_const_tl(31);
300
    tcg_gen_shl_tl(d, a, b);
301

    
302
    tcg_gen_sub_tl(t0, t_31, b);
303
    tcg_gen_sar_tl(t0, t0, t_31);
304
    tcg_gen_and_tl(t0, t0, d);
305
    tcg_gen_xor_tl(d, d, t0);
306
    tcg_temp_free(t0);
307
    tcg_temp_free(t_31);
308
}
309

    
310
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
311
{
312
    TCGv t0, t_31;
313

    
314
    t0 = tcg_temp_new();
315
    t_31 = tcg_temp_new();
316
    tcg_gen_shr_tl(d, a, b);
317

    
318
    tcg_gen_movi_tl(t_31, 31);
319
    tcg_gen_sub_tl(t0, t_31, b);
320
    tcg_gen_sar_tl(t0, t0, t_31);
321
    tcg_gen_and_tl(t0, t0, d);
322
    tcg_gen_xor_tl(d, d, t0);
323
    tcg_temp_free(t0);
324
    tcg_temp_free(t_31);
325
}
326

    
327
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
328
{
329
    TCGv t0, t_31;
330

    
331
    t0 = tcg_temp_new();
332
    t_31 = tcg_temp_new();
333
    tcg_gen_sar_tl(d, a, b);
334

    
335
    tcg_gen_movi_tl(t_31, 31);
336
    tcg_gen_sub_tl(t0, t_31, b);
337
    tcg_gen_sar_tl(t0, t0, t_31);
338
    tcg_gen_or_tl(d, d, t0);
339
    tcg_temp_free(t0);
340
    tcg_temp_free(t_31);
341
}
342

    
343
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
344
{
345
    int l1;
346

    
347
    l1 = gen_new_label();
348

    
349
    /*
350
     * d <<= 1
351
     * if (d >= s)
352
     *    d -= s;
353
     */
354
    tcg_gen_shli_tl(d, a, 1);
355
    tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
356
    tcg_gen_sub_tl(d, d, b);
357
    gen_set_label(l1);
358
}
359

    
360
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
361
{
362
    TCGv t;
363

    
364
    /*
365
     * d <<= 1
366
     * if (n)
367
     *    d += s;
368
     */
369
    t = tcg_temp_new();
370
    tcg_gen_shli_tl(d, a, 1);
371
    tcg_gen_shli_tl(t, ccs, 31 - 3);
372
    tcg_gen_sari_tl(t, t, 31);
373
    tcg_gen_and_tl(t, t, b);
374
    tcg_gen_add_tl(d, d, t);
375
    tcg_temp_free(t);
376
}
377

    
378
/* Extended arithmetics on CRIS.  */
379
static inline void t_gen_add_flag(TCGv d, int flag)
380
{
381
    TCGv c;
382

    
383
    c = tcg_temp_new();
384
    t_gen_mov_TN_preg(c, PR_CCS);
385
    /* Propagate carry into d.  */
386
    tcg_gen_andi_tl(c, c, 1 << flag);
387
    if (flag) {
388
        tcg_gen_shri_tl(c, c, flag);
389
    }
390
    tcg_gen_add_tl(d, d, c);
391
    tcg_temp_free(c);
392
}
393

    
394
static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
395
{
396
    if (dc->flagx_known) {
397
        if (dc->flags_x) {
398
            TCGv c;
399
            
400
            c = tcg_temp_new();
401
            t_gen_mov_TN_preg(c, PR_CCS);
402
            /* C flag is already at bit 0.  */
403
            tcg_gen_andi_tl(c, c, C_FLAG);
404
            tcg_gen_add_tl(d, d, c);
405
            tcg_temp_free(c);
406
        }
407
    } else {
408
        TCGv x, c;
409

    
410
        x = tcg_temp_new();
411
        c = tcg_temp_new();
412
        t_gen_mov_TN_preg(x, PR_CCS);
413
        tcg_gen_mov_tl(c, x);
414

    
415
        /* Propagate carry into d if X is set. Branch free.  */
416
        tcg_gen_andi_tl(c, c, C_FLAG);
417
        tcg_gen_andi_tl(x, x, X_FLAG);
418
        tcg_gen_shri_tl(x, x, 4);
419

    
420
        tcg_gen_and_tl(x, x, c);
421
        tcg_gen_add_tl(d, d, x);
422
        tcg_temp_free(x);
423
        tcg_temp_free(c);
424
    }
425
}
426

    
427
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
428
{
429
    if (dc->flagx_known) {
430
        if (dc->flags_x) {
431
            TCGv c;
432
            
433
            c = tcg_temp_new();
434
            t_gen_mov_TN_preg(c, PR_CCS);
435
            /* C flag is already at bit 0.  */
436
            tcg_gen_andi_tl(c, c, C_FLAG);
437
            tcg_gen_sub_tl(d, d, c);
438
            tcg_temp_free(c);
439
        }
440
    } else {
441
        TCGv x, c;
442

    
443
        x = tcg_temp_new();
444
        c = tcg_temp_new();
445
        t_gen_mov_TN_preg(x, PR_CCS);
446
        tcg_gen_mov_tl(c, x);
447

    
448
        /* Propagate carry into d if X is set. Branch free.  */
449
        tcg_gen_andi_tl(c, c, C_FLAG);
450
        tcg_gen_andi_tl(x, x, X_FLAG);
451
        tcg_gen_shri_tl(x, x, 4);
452

    
453
        tcg_gen_and_tl(x, x, c);
454
        tcg_gen_sub_tl(d, d, x);
455
        tcg_temp_free(x);
456
        tcg_temp_free(c);
457
    }
458
}
459

    
460
/* Swap the two bytes within each half word of the s operand.
461
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
462
static inline void t_gen_swapb(TCGv d, TCGv s)
463
{
464
    TCGv t, org_s;
465

    
466
    t = tcg_temp_new();
467
    org_s = tcg_temp_new();
468

    
469
    /* d and s may refer to the same object.  */
470
    tcg_gen_mov_tl(org_s, s);
471
    tcg_gen_shli_tl(t, org_s, 8);
472
    tcg_gen_andi_tl(d, t, 0xff00ff00);
473
    tcg_gen_shri_tl(t, org_s, 8);
474
    tcg_gen_andi_tl(t, t, 0x00ff00ff);
475
    tcg_gen_or_tl(d, d, t);
476
    tcg_temp_free(t);
477
    tcg_temp_free(org_s);
478
}
479

    
480
/* Swap the halfwords of the s operand.  */
481
static inline void t_gen_swapw(TCGv d, TCGv s)
482
{
483
    TCGv t;
484
    /* d and s refer the same object.  */
485
    t = tcg_temp_new();
486
    tcg_gen_mov_tl(t, s);
487
    tcg_gen_shli_tl(d, t, 16);
488
    tcg_gen_shri_tl(t, t, 16);
489
    tcg_gen_or_tl(d, d, t);
490
    tcg_temp_free(t);
491
}
492

    
493
/* Reverse the within each byte.
494
   T0 = (((T0 << 7) & 0x80808080) |
495
   ((T0 << 5) & 0x40404040) |
496
   ((T0 << 3) & 0x20202020) |
497
   ((T0 << 1) & 0x10101010) |
498
   ((T0 >> 1) & 0x08080808) |
499
   ((T0 >> 3) & 0x04040404) |
500
   ((T0 >> 5) & 0x02020202) |
501
   ((T0 >> 7) & 0x01010101));
502
 */
503
static inline void t_gen_swapr(TCGv d, TCGv s)
504
{
505
    struct {
506
        int shift; /* LSL when positive, LSR when negative.  */
507
        uint32_t mask;
508
    } bitrev[] = {
509
        {7, 0x80808080},
510
        {5, 0x40404040},
511
        {3, 0x20202020},
512
        {1, 0x10101010},
513
        {-1, 0x08080808},
514
        {-3, 0x04040404},
515
        {-5, 0x02020202},
516
        {-7, 0x01010101}
517
    };
518
    int i;
519
    TCGv t, org_s;
520

    
521
    /* d and s refer the same object.  */
522
    t = tcg_temp_new();
523
    org_s = tcg_temp_new();
524
    tcg_gen_mov_tl(org_s, s);
525

    
526
    tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
527
    tcg_gen_andi_tl(d, t,  bitrev[0].mask);
528
    for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
529
        if (bitrev[i].shift >= 0) {
530
            tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
531
        } else {
532
            tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
533
        }
534
        tcg_gen_andi_tl(t, t,  bitrev[i].mask);
535
        tcg_gen_or_tl(d, d, t);
536
    }
537
    tcg_temp_free(t);
538
    tcg_temp_free(org_s);
539
}
540

    
541
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
542
{
543
    int l1;
544

    
545
    l1 = gen_new_label();
546

    
547
    /* Conditional jmp.  */
548
    tcg_gen_mov_tl(env_pc, pc_false);
549
    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
550
    tcg_gen_mov_tl(env_pc, pc_true);
551
    gen_set_label(l1);
552
}
553

    
554
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
555
{
556
    TranslationBlock *tb;
557
    tb = dc->tb;
558
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
559
        tcg_gen_goto_tb(n);
560
        tcg_gen_movi_tl(env_pc, dest);
561
                tcg_gen_exit_tb((uintptr_t)tb + n);
562
    } else {
563
        tcg_gen_movi_tl(env_pc, dest);
564
        tcg_gen_exit_tb(0);
565
    }
566
}
567

    
568
static inline void cris_clear_x_flag(DisasContext *dc)
569
{
570
    if (dc->flagx_known && dc->flags_x) {
571
        dc->flags_uptodate = 0;
572
    }
573

    
574
    dc->flagx_known = 1;
575
    dc->flags_x = 0;
576
}
577

    
578
static void cris_flush_cc_state(DisasContext *dc)
579
{
580
    if (dc->cc_size_uptodate != dc->cc_size) {
581
        tcg_gen_movi_tl(cc_size, dc->cc_size);
582
        dc->cc_size_uptodate = dc->cc_size;
583
    }
584
    tcg_gen_movi_tl(cc_op, dc->cc_op);
585
    tcg_gen_movi_tl(cc_mask, dc->cc_mask);
586
}
587

    
588
static void cris_evaluate_flags(DisasContext *dc)
589
{
590
    if (dc->flags_uptodate) {
591
        return;
592
    }
593

    
594
    cris_flush_cc_state(dc);
595

    
596
    switch (dc->cc_op) {
597
    case CC_OP_MCP:
598
        gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
599
                cpu_PR[PR_CCS], cc_src,
600
                cc_dest, cc_result);
601
        break;
602
    case CC_OP_MULS:
603
        gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
604
                cpu_PR[PR_CCS], cc_result,
605
                cpu_PR[PR_MOF]);
606
        break;
607
    case CC_OP_MULU:
608
        gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
609
                cpu_PR[PR_CCS], cc_result,
610
                cpu_PR[PR_MOF]);
611
        break;
612
    case CC_OP_MOVE:
613
    case CC_OP_AND:
614
    case CC_OP_OR:
615
    case CC_OP_XOR:
616
    case CC_OP_ASR:
617
    case CC_OP_LSR:
618
    case CC_OP_LSL:
619
        switch (dc->cc_size) {
620
        case 4:
621
            gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
622
                    cpu_env, cpu_PR[PR_CCS], cc_result);
623
            break;
624
        case 2:
625
            gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
626
                    cpu_env, cpu_PR[PR_CCS], cc_result);
627
            break;
628
        default:
629
            gen_helper_evaluate_flags(cpu_env);
630
            break;
631
        }
632
        break;
633
    case CC_OP_FLAGS:
634
        /* live.  */
635
        break;
636
    case CC_OP_SUB:
637
    case CC_OP_CMP:
638
        if (dc->cc_size == 4) {
639
            gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
640
                    cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
641
        } else {
642
            gen_helper_evaluate_flags(cpu_env);
643
        }
644

    
645
        break;
646
    default:
647
        switch (dc->cc_size) {
648
        case 4:
649
            gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
650
                    cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
651
            break;
652
        default:
653
            gen_helper_evaluate_flags(cpu_env);
654
            break;
655
        }
656
        break;
657
    }
658

    
659
    if (dc->flagx_known) {
660
        if (dc->flags_x) {
661
            tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
662
        } else if (dc->cc_op == CC_OP_FLAGS) {
663
            tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
664
        }
665
    }
666
    dc->flags_uptodate = 1;
667
}
668

    
669
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
670
{
671
    uint32_t ovl;
672

    
673
    if (!mask) {
674
        dc->update_cc = 0;
675
        return;
676
    }
677

    
678
    /* Check if we need to evaluate the condition codes due to
679
       CC overlaying.  */
680
    ovl = (dc->cc_mask ^ mask) & ~mask;
681
    if (ovl) {
682
        /* TODO: optimize this case. It trigs all the time.  */
683
        cris_evaluate_flags(dc);
684
    }
685
    dc->cc_mask = mask;
686
    dc->update_cc = 1;
687
}
688

    
689
static void cris_update_cc_op(DisasContext *dc, int op, int size)
690
{
691
    dc->cc_op = op;
692
    dc->cc_size = size;
693
    dc->flags_uptodate = 0;
694
}
695

    
696
static inline void cris_update_cc_x(DisasContext *dc)
697
{
698
    /* Save the x flag state at the time of the cc snapshot.  */
699
    if (dc->flagx_known) {
700
        if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
701
            return;
702
        }
703
        tcg_gen_movi_tl(cc_x, dc->flags_x);
704
        dc->cc_x_uptodate = 2 | dc->flags_x;
705
    } else {
706
        tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
707
        dc->cc_x_uptodate = 1;
708
    }
709
}
710

    
711
/* Update cc prior to executing ALU op. Needs source operands untouched.  */
712
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
713
                   TCGv dst, TCGv src, int size)
714
{
715
    if (dc->update_cc) {
716
        cris_update_cc_op(dc, op, size);
717
        tcg_gen_mov_tl(cc_src, src);
718

    
719
        if (op != CC_OP_MOVE
720
            && op != CC_OP_AND
721
            && op != CC_OP_OR
722
            && op != CC_OP_XOR
723
            && op != CC_OP_ASR
724
            && op != CC_OP_LSR
725
            && op != CC_OP_LSL) {
726
            tcg_gen_mov_tl(cc_dest, dst);
727
        }
728

    
729
        cris_update_cc_x(dc);
730
    }
731
}
732

    
733
/* Update cc after executing ALU op. needs the result.  */
734
static inline void cris_update_result(DisasContext *dc, TCGv res)
735
{
736
    if (dc->update_cc) {
737
        tcg_gen_mov_tl(cc_result, res);
738
    }
739
}
740

    
741
/* Returns one if the write back stage should execute.  */
742
static void cris_alu_op_exec(DisasContext *dc, int op, 
743
                   TCGv dst, TCGv a, TCGv b, int size)
744
{
745
    /* Emit the ALU insns.  */
746
    switch (op) {
747
    case CC_OP_ADD:
748
        tcg_gen_add_tl(dst, a, b);
749
        /* Extended arithmetics.  */
750
        t_gen_addx_carry(dc, dst);
751
        break;
752
    case CC_OP_ADDC:
753
        tcg_gen_add_tl(dst, a, b);
754
        t_gen_add_flag(dst, 0); /* C_FLAG.  */
755
        break;
756
    case CC_OP_MCP:
757
        tcg_gen_add_tl(dst, a, b);
758
        t_gen_add_flag(dst, 8); /* R_FLAG.  */
759
        break;
760
    case CC_OP_SUB:
761
        tcg_gen_sub_tl(dst, a, b);
762
        /* Extended arithmetics.  */
763
        t_gen_subx_carry(dc, dst);
764
        break;
765
    case CC_OP_MOVE:
766
        tcg_gen_mov_tl(dst, b);
767
        break;
768
    case CC_OP_OR:
769
        tcg_gen_or_tl(dst, a, b);
770
        break;
771
    case CC_OP_AND:
772
        tcg_gen_and_tl(dst, a, b);
773
        break;
774
    case CC_OP_XOR:
775
        tcg_gen_xor_tl(dst, a, b);
776
        break;
777
    case CC_OP_LSL:
778
        t_gen_lsl(dst, a, b);
779
        break;
780
    case CC_OP_LSR:
781
        t_gen_lsr(dst, a, b);
782
        break;
783
    case CC_OP_ASR:
784
        t_gen_asr(dst, a, b);
785
        break;
786
    case CC_OP_NEG:
787
        tcg_gen_neg_tl(dst, b);
788
        /* Extended arithmetics.  */
789
        t_gen_subx_carry(dc, dst);
790
        break;
791
    case CC_OP_LZ:
792
        gen_helper_lz(dst, b);
793
        break;
794
    case CC_OP_MULS:
795
        tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
796
        break;
797
    case CC_OP_MULU:
798
        tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b);
799
        break;
800
    case CC_OP_DSTEP:
801
        t_gen_cris_dstep(dst, a, b);
802
        break;
803
    case CC_OP_MSTEP:
804
        t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
805
        break;
806
    case CC_OP_BOUND:
807
    {
808
        int l1;
809
        l1 = gen_new_label();
810
        tcg_gen_mov_tl(dst, a);
811
        tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
812
        tcg_gen_mov_tl(dst, b);
813
        gen_set_label(l1);
814
    }
815
        break;
816
    case CC_OP_CMP:
817
        tcg_gen_sub_tl(dst, a, b);
818
        /* Extended arithmetics.  */
819
        t_gen_subx_carry(dc, dst);
820
        break;
821
    default:
822
        qemu_log("illegal ALU op.\n");
823
        BUG();
824
        break;
825
    }
826

    
827
    if (size == 1) {
828
        tcg_gen_andi_tl(dst, dst, 0xff);
829
    } else if (size == 2) {
830
        tcg_gen_andi_tl(dst, dst, 0xffff);
831
    }
832
}
833

    
834
static void cris_alu(DisasContext *dc, int op,
835
                   TCGv d, TCGv op_a, TCGv op_b, int size)
836
{
837
    TCGv tmp;
838
    int writeback;
839

    
840
    writeback = 1;
841

    
842
    if (op == CC_OP_CMP) {
843
        tmp = tcg_temp_new();
844
        writeback = 0;
845
    } else if (size == 4) {
846
        tmp = d;
847
        writeback = 0;
848
    } else {
849
        tmp = tcg_temp_new();
850
    }
851

    
852

    
853
    cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
854
    cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
855
    cris_update_result(dc, tmp);
856

    
857
    /* Writeback.  */
858
    if (writeback) {
859
        if (size == 1) {
860
            tcg_gen_andi_tl(d, d, ~0xff);
861
        } else {
862
            tcg_gen_andi_tl(d, d, ~0xffff);
863
        }
864
        tcg_gen_or_tl(d, d, tmp);
865
    }
866
    if (!TCGV_EQUAL(tmp, d)) {
867
        tcg_temp_free(tmp);
868
    }
869
}
870

    
871
static int arith_cc(DisasContext *dc)
872
{
873
    if (dc->update_cc) {
874
        switch (dc->cc_op) {
875
        case CC_OP_ADDC: return 1;
876
        case CC_OP_ADD: return 1;
877
        case CC_OP_SUB: return 1;
878
        case CC_OP_DSTEP: return 1;
879
        case CC_OP_LSL: return 1;
880
        case CC_OP_LSR: return 1;
881
        case CC_OP_ASR: return 1;
882
        case CC_OP_CMP: return 1;
883
        case CC_OP_NEG: return 1;
884
        case CC_OP_OR: return 1;
885
        case CC_OP_AND: return 1;
886
        case CC_OP_XOR: return 1;
887
        case CC_OP_MULU: return 1;
888
        case CC_OP_MULS: return 1;
889
        default:
890
            return 0;
891
        }
892
    }
893
    return 0;
894
}
895

    
896
static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
897
{
898
    int arith_opt, move_opt;
899

    
900
    /* TODO: optimize more condition codes.  */
901

    
902
    /*
903
     * If the flags are live, we've gotta look into the bits of CCS.
904
     * Otherwise, if we just did an arithmetic operation we try to
905
     * evaluate the condition code faster.
906
     *
907
     * When this function is done, T0 should be non-zero if the condition
908
     * code is true.
909
     */
910
    arith_opt = arith_cc(dc) && !dc->flags_uptodate;
911
    move_opt = (dc->cc_op == CC_OP_MOVE);
912
    switch (cond) {
913
    case CC_EQ:
914
        if ((arith_opt || move_opt)
915
                && dc->cc_x_uptodate != (2 | X_FLAG)) {
916
            tcg_gen_setcond_tl(TCG_COND_EQ, cc,
917
                    cc_result, tcg_const_tl(0));
918
        } else {
919
            cris_evaluate_flags(dc);
920
            tcg_gen_andi_tl(cc,
921
                    cpu_PR[PR_CCS], Z_FLAG);
922
        }
923
        break;
924
    case CC_NE:
925
        if ((arith_opt || move_opt)
926
                && dc->cc_x_uptodate != (2 | X_FLAG)) {
927
            tcg_gen_mov_tl(cc, cc_result);
928
        } else {
929
            cris_evaluate_flags(dc);
930
            tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
931
                    Z_FLAG);
932
            tcg_gen_andi_tl(cc, cc, Z_FLAG);
933
        }
934
        break;
935
    case CC_CS:
936
        cris_evaluate_flags(dc);
937
        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
938
        break;
939
    case CC_CC:
940
        cris_evaluate_flags(dc);
941
        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
942
        tcg_gen_andi_tl(cc, cc, C_FLAG);
943
        break;
944
    case CC_VS:
945
        cris_evaluate_flags(dc);
946
        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
947
        break;
948
    case CC_VC:
949
        cris_evaluate_flags(dc);
950
        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
951
                V_FLAG);
952
        tcg_gen_andi_tl(cc, cc, V_FLAG);
953
        break;
954
    case CC_PL:
955
        if (arith_opt || move_opt) {
956
            int bits = 31;
957

    
958
            if (dc->cc_size == 1) {
959
                bits = 7;
960
            } else if (dc->cc_size == 2) {
961
                bits = 15;
962
            }
963

    
964
            tcg_gen_shri_tl(cc, cc_result, bits);
965
            tcg_gen_xori_tl(cc, cc, 1);
966
        } else {
967
            cris_evaluate_flags(dc);
968
            tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
969
                    N_FLAG);
970
            tcg_gen_andi_tl(cc, cc, N_FLAG);
971
        }
972
        break;
973
    case CC_MI:
974
        if (arith_opt || move_opt) {
975
            int bits = 31;
976

    
977
            if (dc->cc_size == 1) {
978
                bits = 7;
979
            } else if (dc->cc_size == 2) {
980
                bits = 15;
981
            }
982

    
983
            tcg_gen_shri_tl(cc, cc_result, bits);
984
            tcg_gen_andi_tl(cc, cc, 1);
985
        } else {
986
            cris_evaluate_flags(dc);
987
            tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
988
                    N_FLAG);
989
        }
990
        break;
991
    case CC_LS:
992
        cris_evaluate_flags(dc);
993
        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
994
                C_FLAG | Z_FLAG);
995
        break;
996
    case CC_HI:
997
        cris_evaluate_flags(dc);
998
        {
999
            TCGv tmp;
1000

    
1001
            tmp = tcg_temp_new();
1002
            tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1003
                    C_FLAG | Z_FLAG);
1004
            /* Overlay the C flag on top of the Z.  */
1005
            tcg_gen_shli_tl(cc, tmp, 2);
1006
            tcg_gen_and_tl(cc, tmp, cc);
1007
            tcg_gen_andi_tl(cc, cc, Z_FLAG);
1008

    
1009
            tcg_temp_free(tmp);
1010
        }
1011
        break;
1012
    case CC_GE:
1013
        cris_evaluate_flags(dc);
1014
        /* Overlay the V flag on top of the N.  */
1015
        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1016
        tcg_gen_xor_tl(cc,
1017
                cpu_PR[PR_CCS], cc);
1018
        tcg_gen_andi_tl(cc, cc, N_FLAG);
1019
        tcg_gen_xori_tl(cc, cc, N_FLAG);
1020
        break;
1021
    case CC_LT:
1022
        cris_evaluate_flags(dc);
1023
        /* Overlay the V flag on top of the N.  */
1024
        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1025
        tcg_gen_xor_tl(cc,
1026
                cpu_PR[PR_CCS], cc);
1027
        tcg_gen_andi_tl(cc, cc, N_FLAG);
1028
        break;
1029
    case CC_GT:
1030
        cris_evaluate_flags(dc);
1031
        {
1032
            TCGv n, z;
1033

    
1034
            n = tcg_temp_new();
1035
            z = tcg_temp_new();
1036

    
1037
            /* To avoid a shift we overlay everything on
1038
                   the V flag.  */
1039
            tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1040
            tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1041
            /* invert Z.  */
1042
            tcg_gen_xori_tl(z, z, 2);
1043

    
1044
            tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1045
            tcg_gen_xori_tl(n, n, 2);
1046
            tcg_gen_and_tl(cc, z, n);
1047
            tcg_gen_andi_tl(cc, cc, 2);
1048

    
1049
            tcg_temp_free(n);
1050
            tcg_temp_free(z);
1051
        }
1052
        break;
1053
    case CC_LE:
1054
        cris_evaluate_flags(dc);
1055
        {
1056
            TCGv n, z;
1057

    
1058
            n = tcg_temp_new();
1059
            z = tcg_temp_new();
1060

    
1061
            /* To avoid a shift we overlay everything on
1062
                   the V flag.  */
1063
            tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1064
            tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1065

    
1066
            tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1067
            tcg_gen_or_tl(cc, z, n);
1068
            tcg_gen_andi_tl(cc, cc, 2);
1069

    
1070
            tcg_temp_free(n);
1071
            tcg_temp_free(z);
1072
        }
1073
        break;
1074
    case CC_P:
1075
        cris_evaluate_flags(dc);
1076
        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1077
        break;
1078
    case CC_A:
1079
        tcg_gen_movi_tl(cc, 1);
1080
        break;
1081
    default:
1082
        BUG();
1083
        break;
1084
    };
1085
}
1086

    
1087
static void cris_store_direct_jmp(DisasContext *dc)
1088
{
1089
    /* Store the direct jmp state into the cpu-state.  */
1090
    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1091
        if (dc->jmp == JMP_DIRECT) {
1092
            tcg_gen_movi_tl(env_btaken, 1);
1093
        }
1094
        tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1095
        dc->jmp = JMP_INDIRECT;
1096
    }
1097
}
1098

    
1099
static void cris_prepare_cc_branch (DisasContext *dc, 
1100
                    int offset, int cond)
1101
{
1102
    /* This helps us re-schedule the micro-code to insns in delay-slots
1103
       before the actual jump.  */
1104
    dc->delayed_branch = 2;
1105
    dc->jmp = JMP_DIRECT_CC;
1106
    dc->jmp_pc = dc->pc + offset;
1107

    
1108
    gen_tst_cc(dc, env_btaken, cond);
1109
    tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1110
}
1111

    
1112

    
1113
/* jumps, when the dest is in a live reg for example. Direct should be set
1114
   when the dest addr is constant to allow tb chaining.  */
1115
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1116
{
1117
    /* This helps us re-schedule the micro-code to insns in delay-slots
1118
       before the actual jump.  */
1119
    dc->delayed_branch = 2;
1120
    dc->jmp = type;
1121
    if (type == JMP_INDIRECT) {
1122
        tcg_gen_movi_tl(env_btaken, 1);
1123
    }
1124
}
1125

    
1126
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1127
{
1128
    int mem_index = cpu_mmu_index(dc->env);
1129

    
1130
    /* If we get a fault on a delayslot we must keep the jmp state in
1131
       the cpu-state to be able to re-execute the jmp.  */
1132
    if (dc->delayed_branch == 1) {
1133
        cris_store_direct_jmp(dc);
1134
    }
1135

    
1136
    tcg_gen_qemu_ld64(dst, addr, mem_index);
1137
}
1138

    
1139
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1140
             unsigned int size, int sign)
1141
{
1142
    int mem_index = cpu_mmu_index(dc->env);
1143

    
1144
    /* If we get a fault on a delayslot we must keep the jmp state in
1145
       the cpu-state to be able to re-execute the jmp.  */
1146
    if (dc->delayed_branch == 1) {
1147
        cris_store_direct_jmp(dc);
1148
    }
1149

    
1150
    if (size == 1) {
1151
        if (sign) {
1152
            tcg_gen_qemu_ld8s(dst, addr, mem_index);
1153
        } else {
1154
            tcg_gen_qemu_ld8u(dst, addr, mem_index);
1155
        }
1156
    } else if (size == 2) {
1157
        if (sign) {
1158
            tcg_gen_qemu_ld16s(dst, addr, mem_index);
1159
        } else {
1160
            tcg_gen_qemu_ld16u(dst, addr, mem_index);
1161
        }
1162
    } else if (size == 4) {
1163
        tcg_gen_qemu_ld32u(dst, addr, mem_index);
1164
    } else {
1165
        abort();
1166
    }
1167
}
1168

    
1169
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1170
               unsigned int size)
1171
{
1172
    int mem_index = cpu_mmu_index(dc->env);
1173

    
1174
    /* If we get a fault on a delayslot we must keep the jmp state in
1175
       the cpu-state to be able to re-execute the jmp.  */
1176
    if (dc->delayed_branch == 1) {
1177
        cris_store_direct_jmp(dc);
1178
    }
1179

    
1180

    
1181
    /* Conditional writes. We only support the kind were X and P are known
1182
       at translation time.  */
1183
    if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1184
        dc->postinc = 0;
1185
        cris_evaluate_flags(dc);
1186
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1187
        return;
1188
    }
1189

    
1190
    if (size == 1) {
1191
        tcg_gen_qemu_st8(val, addr, mem_index);
1192
    } else if (size == 2) {
1193
        tcg_gen_qemu_st16(val, addr, mem_index);
1194
    } else {
1195
        tcg_gen_qemu_st32(val, addr, mem_index);
1196
    }
1197

    
1198
    if (dc->flagx_known && dc->flags_x) {
1199
        cris_evaluate_flags(dc);
1200
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1201
    }
1202
}
1203

    
1204
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1205
{
1206
    if (size == 1) {
1207
        tcg_gen_ext8s_i32(d, s);
1208
    } else if (size == 2) {
1209
        tcg_gen_ext16s_i32(d, s);
1210
    } else if (!TCGV_EQUAL(d, s)) {
1211
        tcg_gen_mov_tl(d, s);
1212
    }
1213
}
1214

    
1215
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1216
{
1217
    if (size == 1) {
1218
        tcg_gen_ext8u_i32(d, s);
1219
    } else if (size == 2) {
1220
        tcg_gen_ext16u_i32(d, s);
1221
    } else if (!TCGV_EQUAL(d, s)) {
1222
        tcg_gen_mov_tl(d, s);
1223
    }
1224
}
1225

    
1226
#if DISAS_CRIS
1227
static char memsize_char(int size)
1228
{
1229
    switch (size) {
1230
    case 1: return 'b';  break;
1231
    case 2: return 'w';  break;
1232
    case 4: return 'd';  break;
1233
    default:
1234
        return 'x';
1235
        break;
1236
    }
1237
}
1238
#endif
1239

    
1240
static inline unsigned int memsize_z(DisasContext *dc)
1241
{
1242
    return dc->zsize + 1;
1243
}
1244

    
1245
static inline unsigned int memsize_zz(DisasContext *dc)
1246
{
1247
    switch (dc->zzsize) {
1248
    case 0: return 1;
1249
    case 1: return 2;
1250
    default:
1251
        return 4;
1252
    }
1253
}
1254

    
1255
static inline void do_postinc (DisasContext *dc, int size)
1256
{
1257
    if (dc->postinc) {
1258
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1259
    }
1260
}
1261

    
1262
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1263
                   int size, int s_ext, TCGv dst)
1264
{
1265
    if (s_ext) {
1266
        t_gen_sext(dst, cpu_R[rs], size);
1267
    } else {
1268
        t_gen_zext(dst, cpu_R[rs], size);
1269
    }
1270
}
1271

    
1272
/* Prepare T0 and T1 for a register alu operation.
1273
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1274
   needed.  */
1275
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1276
              int size, int s_ext, TCGv dst, TCGv src)
1277
{
1278
    dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1279

    
1280
    if (s_ext) {
1281
        t_gen_sext(dst, cpu_R[rd], size);
1282
    } else {
1283
        t_gen_zext(dst, cpu_R[rd], size);
1284
    }
1285
}
1286

    
1287
static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1288
                           int s_ext, int memsize, TCGv dst)
1289
{
1290
    unsigned int rs;
1291
    uint32_t imm;
1292
    int is_imm;
1293
    int insn_len = 2;
1294

    
1295
    rs = dc->op1;
1296
    is_imm = rs == 15 && dc->postinc;
1297

    
1298
    /* Load [$rs] onto T1.  */
1299
    if (is_imm) {
1300
        insn_len = 2 + memsize;
1301
        if (memsize == 1) {
1302
            insn_len++;
1303
        }
1304

    
1305
        imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1306
        tcg_gen_movi_tl(dst, imm);
1307
        dc->postinc = 0;
1308
    } else {
1309
        cris_flush_cc_state(dc);
1310
        gen_load(dc, dst, cpu_R[rs], memsize, 0);
1311
        if (s_ext) {
1312
            t_gen_sext(dst, dst, memsize);
1313
        } else {
1314
            t_gen_zext(dst, dst, memsize);
1315
        }
1316
    }
1317
    return insn_len;
1318
}
1319

    
1320
/* Prepare T0 and T1 for a memory + alu operation.
1321
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1322
   needed.  */
1323
static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1324
                          int s_ext, int memsize, TCGv dst, TCGv src)
1325
{
1326
    int insn_len;
1327

    
1328
    insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1329
    tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1330
    return insn_len;
1331
}
1332

    
1333
#if DISAS_CRIS
1334
static const char *cc_name(int cc)
1335
{
1336
    static const char *cc_names[16] = {
1337
        "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1338
        "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1339
    };
1340
    assert(cc < 16);
1341
    return cc_names[cc];
1342
}
1343
#endif
1344

    
1345
/* Start of insn decoders.  */
1346

    
1347
static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1348
{
1349
    int32_t offset;
1350
    int sign;
1351
    uint32_t cond = dc->op2;
1352

    
1353
    offset = EXTRACT_FIELD(dc->ir, 1, 7);
1354
    sign = EXTRACT_FIELD(dc->ir, 0, 0);
1355

    
1356
    offset *= 2;
1357
    offset |= sign << 8;
1358
    offset = sign_extend(offset, 8);
1359

    
1360
    LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1361

    
1362
    /* op2 holds the condition-code.  */
1363
    cris_cc_mask(dc, 0);
1364
    cris_prepare_cc_branch(dc, offset, cond);
1365
    return 2;
1366
}
1367
static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1368
{
1369
    int32_t imm;
1370

    
1371
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1372
    imm = sign_extend(dc->op1, 7);
1373

    
1374
    LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1375
    cris_cc_mask(dc, 0);
1376
    /* Fetch register operand,  */
1377
    tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1378

    
1379
    return 2;
1380
}
1381
static int dec_addq(CPUCRISState *env, DisasContext *dc)
1382
{
1383
    LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1384

    
1385
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1386

    
1387
    cris_cc_mask(dc, CC_MASK_NZVC);
1388

    
1389
    cris_alu(dc, CC_OP_ADD,
1390
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1391
    return 2;
1392
}
1393
static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1394
{
1395
    uint32_t imm;
1396

    
1397
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1398
    imm = sign_extend(dc->op1, 5);
1399
    LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1400

    
1401
    tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1402
    return 2;
1403
}
1404
static int dec_subq(CPUCRISState *env, DisasContext *dc)
1405
{
1406
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1407

    
1408
    LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1409

    
1410
    cris_cc_mask(dc, CC_MASK_NZVC);
1411
    cris_alu(dc, CC_OP_SUB,
1412
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1413
    return 2;
1414
}
1415
static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1416
{
1417
    uint32_t imm;
1418
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1419
    imm = sign_extend(dc->op1, 5);
1420

    
1421
    LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1422
    cris_cc_mask(dc, CC_MASK_NZVC);
1423

    
1424
    cris_alu(dc, CC_OP_CMP,
1425
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1426
    return 2;
1427
}
1428
static int dec_andq(CPUCRISState *env, DisasContext *dc)
1429
{
1430
    uint32_t imm;
1431
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1432
    imm = sign_extend(dc->op1, 5);
1433

    
1434
    LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1435
    cris_cc_mask(dc, CC_MASK_NZ);
1436

    
1437
    cris_alu(dc, CC_OP_AND,
1438
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1439
    return 2;
1440
}
1441
static int dec_orq(CPUCRISState *env, DisasContext *dc)
1442
{
1443
    uint32_t imm;
1444
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1445
    imm = sign_extend(dc->op1, 5);
1446
    LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1447
    cris_cc_mask(dc, CC_MASK_NZ);
1448

    
1449
    cris_alu(dc, CC_OP_OR,
1450
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1451
    return 2;
1452
}
1453
static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1454
{
1455
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1456
    LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1457

    
1458
    cris_cc_mask(dc, CC_MASK_NZ);
1459
    cris_evaluate_flags(dc);
1460
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1461
            tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1462
    cris_alu(dc, CC_OP_MOVE,
1463
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1464
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1465
    dc->flags_uptodate = 1;
1466
    return 2;
1467
}
1468
static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1469
{
1470
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1471
    LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1472
    cris_cc_mask(dc, CC_MASK_NZ);
1473

    
1474
    tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1475
    cris_alu(dc, CC_OP_MOVE,
1476
            cpu_R[dc->op2],
1477
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1478
    return 2;
1479
}
1480
static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1481
{
1482
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1483
    LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1484

    
1485
    cris_cc_mask(dc, CC_MASK_NZ);
1486

    
1487
    tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1488

    
1489
    cris_alu(dc, CC_OP_MOVE,
1490
            cpu_R[dc->op2],
1491
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1492
    return 2;
1493
}
1494
static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1495
{
1496
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1497
    LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1498

    
1499
    cris_cc_mask(dc, CC_MASK_NZ);
1500

    
1501
    tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1502
    cris_alu(dc, CC_OP_MOVE,
1503
            cpu_R[dc->op2],
1504
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1505
    return 2;
1506
}
1507

    
1508
static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1509
{
1510
    int size = memsize_zz(dc);
1511

    
1512
    LOG_DIS("move.%c $r%u, $r%u\n",
1513
            memsize_char(size), dc->op1, dc->op2);
1514

    
1515
    cris_cc_mask(dc, CC_MASK_NZ);
1516
    if (size == 4) {
1517
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1518
        cris_cc_mask(dc, CC_MASK_NZ);
1519
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
1520
        cris_update_cc_x(dc);
1521
        cris_update_result(dc, cpu_R[dc->op2]);
1522
    } else {
1523
        TCGv t0;
1524

    
1525
        t0 = tcg_temp_new();
1526
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1527
        cris_alu(dc, CC_OP_MOVE,
1528
             cpu_R[dc->op2],
1529
             cpu_R[dc->op2], t0, size);
1530
        tcg_temp_free(t0);
1531
    }
1532
    return 2;
1533
}
1534

    
1535
static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1536
{
1537
    int cond = dc->op2;
1538

    
1539
    LOG_DIS("s%s $r%u\n",
1540
            cc_name(cond), dc->op1);
1541

    
1542
    if (cond != CC_A) {
1543
        int l1;
1544

    
1545
        gen_tst_cc(dc, cpu_R[dc->op1], cond);
1546
        l1 = gen_new_label();
1547
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1548
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1549
        gen_set_label(l1);
1550
    } else {
1551
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1552
    }
1553

    
1554
    cris_cc_mask(dc, 0);
1555
    return 2;
1556
}
1557

    
1558
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1559
{
1560
    if (size == 4) {
1561
        t[0] = cpu_R[dc->op2];
1562
        t[1] = cpu_R[dc->op1];
1563
    } else {
1564
        t[0] = tcg_temp_new();
1565
        t[1] = tcg_temp_new();
1566
    }
1567
}
1568

    
1569
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1570
{
1571
    if (size != 4) {
1572
        tcg_temp_free(t[0]);
1573
        tcg_temp_free(t[1]);
1574
    }
1575
}
1576

    
1577
static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1578
{
1579
    TCGv t[2];
1580
    int size = memsize_zz(dc);
1581

    
1582
    LOG_DIS("and.%c $r%u, $r%u\n",
1583
            memsize_char(size), dc->op1, dc->op2);
1584

    
1585
    cris_cc_mask(dc, CC_MASK_NZ);
1586

    
1587
    cris_alu_alloc_temps(dc, size, t);
1588
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1589
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1590
    cris_alu_free_temps(dc, size, t);
1591
    return 2;
1592
}
1593

    
1594
static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1595
{
1596
    TCGv t0;
1597
    LOG_DIS("lz $r%u, $r%u\n",
1598
            dc->op1, dc->op2);
1599
    cris_cc_mask(dc, CC_MASK_NZ);
1600
    t0 = tcg_temp_new();
1601
    dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1602
    cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1603
    tcg_temp_free(t0);
1604
    return 2;
1605
}
1606

    
1607
static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1608
{
1609
    TCGv t[2];
1610
    int size = memsize_zz(dc);
1611

    
1612
    LOG_DIS("lsl.%c $r%u, $r%u\n",
1613
            memsize_char(size), dc->op1, dc->op2);
1614

    
1615
    cris_cc_mask(dc, CC_MASK_NZ);
1616
    cris_alu_alloc_temps(dc, size, t);
1617
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1618
    tcg_gen_andi_tl(t[1], t[1], 63);
1619
    cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1620
    cris_alu_alloc_temps(dc, size, t);
1621
    return 2;
1622
}
1623

    
1624
static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1625
{
1626
    TCGv t[2];
1627
    int size = memsize_zz(dc);
1628

    
1629
    LOG_DIS("lsr.%c $r%u, $r%u\n",
1630
            memsize_char(size), dc->op1, dc->op2);
1631

    
1632
    cris_cc_mask(dc, CC_MASK_NZ);
1633
    cris_alu_alloc_temps(dc, size, t);
1634
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1635
    tcg_gen_andi_tl(t[1], t[1], 63);
1636
    cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1637
    cris_alu_free_temps(dc, size, t);
1638
    return 2;
1639
}
1640

    
1641
static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1642
{
1643
    TCGv t[2];
1644
    int size = memsize_zz(dc);
1645

    
1646
    LOG_DIS("asr.%c $r%u, $r%u\n",
1647
            memsize_char(size), dc->op1, dc->op2);
1648

    
1649
    cris_cc_mask(dc, CC_MASK_NZ);
1650
    cris_alu_alloc_temps(dc, size, t);
1651
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1652
    tcg_gen_andi_tl(t[1], t[1], 63);
1653
    cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1654
    cris_alu_free_temps(dc, size, t);
1655
    return 2;
1656
}
1657

    
1658
static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1659
{
1660
    TCGv t[2];
1661
    int size = memsize_zz(dc);
1662

    
1663
    LOG_DIS("muls.%c $r%u, $r%u\n",
1664
            memsize_char(size), dc->op1, dc->op2);
1665
    cris_cc_mask(dc, CC_MASK_NZV);
1666
    cris_alu_alloc_temps(dc, size, t);
1667
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1668

    
1669
    cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1670
    cris_alu_free_temps(dc, size, t);
1671
    return 2;
1672
}
1673

    
1674
static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1675
{
1676
    TCGv t[2];
1677
    int size = memsize_zz(dc);
1678

    
1679
    LOG_DIS("mulu.%c $r%u, $r%u\n",
1680
            memsize_char(size), dc->op1, dc->op2);
1681
    cris_cc_mask(dc, CC_MASK_NZV);
1682
    cris_alu_alloc_temps(dc, size, t);
1683
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1684

    
1685
    cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1686
    cris_alu_alloc_temps(dc, size, t);
1687
    return 2;
1688
}
1689

    
1690

    
1691
static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1692
{
1693
    LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1694
    cris_cc_mask(dc, CC_MASK_NZ);
1695
    cris_alu(dc, CC_OP_DSTEP,
1696
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1697
    return 2;
1698
}
1699

    
1700
static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1701
{
1702
    TCGv t[2];
1703
    int size = memsize_zz(dc);
1704
    LOG_DIS("xor.%c $r%u, $r%u\n",
1705
            memsize_char(size), dc->op1, dc->op2);
1706
    BUG_ON(size != 4); /* xor is dword.  */
1707
    cris_cc_mask(dc, CC_MASK_NZ);
1708
    cris_alu_alloc_temps(dc, size, t);
1709
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1710

    
1711
    cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1712
    cris_alu_free_temps(dc, size, t);
1713
    return 2;
1714
}
1715

    
1716
static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1717
{
1718
    TCGv l0;
1719
    int size = memsize_zz(dc);
1720
    LOG_DIS("bound.%c $r%u, $r%u\n",
1721
            memsize_char(size), dc->op1, dc->op2);
1722
    cris_cc_mask(dc, CC_MASK_NZ);
1723
    l0 = tcg_temp_local_new();
1724
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1725
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1726
    tcg_temp_free(l0);
1727
    return 2;
1728
}
1729

    
1730
static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1731
{
1732
    TCGv t[2];
1733
    int size = memsize_zz(dc);
1734
    LOG_DIS("cmp.%c $r%u, $r%u\n",
1735
            memsize_char(size), dc->op1, dc->op2);
1736
    cris_cc_mask(dc, CC_MASK_NZVC);
1737
    cris_alu_alloc_temps(dc, size, t);
1738
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1739

    
1740
    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1741
    cris_alu_free_temps(dc, size, t);
1742
    return 2;
1743
}
1744

    
1745
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1746
{
1747
    TCGv t0;
1748

    
1749
    LOG_DIS("abs $r%u, $r%u\n",
1750
            dc->op1, dc->op2);
1751
    cris_cc_mask(dc, CC_MASK_NZ);
1752

    
1753
    t0 = tcg_temp_new();
1754
    tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1755
    tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1756
    tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1757
    tcg_temp_free(t0);
1758

    
1759
    cris_alu(dc, CC_OP_MOVE,
1760
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1761
    return 2;
1762
}
1763

    
1764
static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1765
{
1766
    TCGv t[2];
1767
    int size = memsize_zz(dc);
1768
    LOG_DIS("add.%c $r%u, $r%u\n",
1769
            memsize_char(size), dc->op1, dc->op2);
1770
    cris_cc_mask(dc, CC_MASK_NZVC);
1771
    cris_alu_alloc_temps(dc, size, t);
1772
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1773

    
1774
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1775
    cris_alu_free_temps(dc, size, t);
1776
    return 2;
1777
}
1778

    
1779
static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1780
{
1781
    LOG_DIS("addc $r%u, $r%u\n",
1782
            dc->op1, dc->op2);
1783
    cris_evaluate_flags(dc);
1784
    /* Set for this insn.  */
1785
    dc->flagx_known = 1;
1786
    dc->flags_x = X_FLAG;
1787

    
1788
    cris_cc_mask(dc, CC_MASK_NZVC);
1789
    cris_alu(dc, CC_OP_ADDC,
1790
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1791
    return 2;
1792
}
1793

    
1794
static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1795
{
1796
    LOG_DIS("mcp $p%u, $r%u\n",
1797
             dc->op2, dc->op1);
1798
    cris_evaluate_flags(dc);
1799
    cris_cc_mask(dc, CC_MASK_RNZV);
1800
    cris_alu(dc, CC_OP_MCP,
1801
            cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1802
    return 2;
1803
}
1804

    
1805
#if DISAS_CRIS
1806
static char * swapmode_name(int mode, char *modename) {
1807
    int i = 0;
1808
    if (mode & 8) {
1809
        modename[i++] = 'n';
1810
    }
1811
    if (mode & 4) {
1812
        modename[i++] = 'w';
1813
    }
1814
    if (mode & 2) {
1815
        modename[i++] = 'b';
1816
    }
1817
    if (mode & 1) {
1818
        modename[i++] = 'r';
1819
    }
1820
    modename[i++] = 0;
1821
    return modename;
1822
}
1823
#endif
1824

    
1825
static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1826
{
1827
    TCGv t0;
1828
#if DISAS_CRIS
1829
    char modename[4];
1830
#endif
1831
    LOG_DIS("swap%s $r%u\n",
1832
             swapmode_name(dc->op2, modename), dc->op1);
1833

    
1834
    cris_cc_mask(dc, CC_MASK_NZ);
1835
    t0 = tcg_temp_new();
1836
    t_gen_mov_TN_reg(t0, dc->op1);
1837
    if (dc->op2 & 8) {
1838
        tcg_gen_not_tl(t0, t0);
1839
    }
1840
    if (dc->op2 & 4) {
1841
        t_gen_swapw(t0, t0);
1842
    }
1843
    if (dc->op2 & 2) {
1844
        t_gen_swapb(t0, t0);
1845
    }
1846
    if (dc->op2 & 1) {
1847
        t_gen_swapr(t0, t0);
1848
    }
1849
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1850
    tcg_temp_free(t0);
1851
    return 2;
1852
}
1853

    
1854
static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1855
{
1856
    TCGv t[2];
1857
    int size = memsize_zz(dc);
1858
    LOG_DIS("or.%c $r%u, $r%u\n",
1859
            memsize_char(size), dc->op1, dc->op2);
1860
    cris_cc_mask(dc, CC_MASK_NZ);
1861
    cris_alu_alloc_temps(dc, size, t);
1862
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1863
    cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1864
    cris_alu_free_temps(dc, size, t);
1865
    return 2;
1866
}
1867

    
1868
static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1869
{
1870
    TCGv t0;
1871
    LOG_DIS("addi.%c $r%u, $r%u\n",
1872
            memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1873
    cris_cc_mask(dc, 0);
1874
    t0 = tcg_temp_new();
1875
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1876
    tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1877
    tcg_temp_free(t0);
1878
    return 2;
1879
}
1880

    
1881
static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1882
{
1883
    TCGv t0;
1884
    LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1885
          memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1886
    cris_cc_mask(dc, 0);
1887
    t0 = tcg_temp_new();
1888
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1889
    tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1890
    tcg_temp_free(t0);
1891
    return 2;
1892
}
1893

    
1894
static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1895
{
1896
    TCGv t[2];
1897
    int size = memsize_zz(dc);
1898
    LOG_DIS("neg.%c $r%u, $r%u\n",
1899
            memsize_char(size), dc->op1, dc->op2);
1900
    cris_cc_mask(dc, CC_MASK_NZVC);
1901
    cris_alu_alloc_temps(dc, size, t);
1902
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1903

    
1904
    cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1905
    cris_alu_free_temps(dc, size, t);
1906
    return 2;
1907
}
1908

    
1909
static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1910
{
1911
    LOG_DIS("btst $r%u, $r%u\n",
1912
            dc->op1, dc->op2);
1913
    cris_cc_mask(dc, CC_MASK_NZ);
1914
    cris_evaluate_flags(dc);
1915
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1916
            cpu_R[dc->op1], cpu_PR[PR_CCS]);
1917
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1918
         cpu_R[dc->op2], cpu_R[dc->op2], 4);
1919
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1920
    dc->flags_uptodate = 1;
1921
    return 2;
1922
}
1923

    
1924
static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1925
{
1926
    TCGv t[2];
1927
    int size = memsize_zz(dc);
1928
    LOG_DIS("sub.%c $r%u, $r%u\n",
1929
            memsize_char(size), dc->op1, dc->op2);
1930
    cris_cc_mask(dc, CC_MASK_NZVC);
1931
    cris_alu_alloc_temps(dc, size, t);
1932
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1933
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1934
    cris_alu_free_temps(dc, size, t);
1935
    return 2;
1936
}
1937

    
1938
/* Zero extension. From size to dword.  */
1939
static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1940
{
1941
    TCGv t0;
1942
    int size = memsize_z(dc);
1943
    LOG_DIS("movu.%c $r%u, $r%u\n",
1944
            memsize_char(size),
1945
            dc->op1, dc->op2);
1946

    
1947
    cris_cc_mask(dc, CC_MASK_NZ);
1948
    t0 = tcg_temp_new();
1949
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1950
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1951
    tcg_temp_free(t0);
1952
    return 2;
1953
}
1954

    
1955
/* Sign extension. From size to dword.  */
1956
static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1957
{
1958
    TCGv t0;
1959
    int size = memsize_z(dc);
1960
    LOG_DIS("movs.%c $r%u, $r%u\n",
1961
            memsize_char(size),
1962
            dc->op1, dc->op2);
1963

    
1964
    cris_cc_mask(dc, CC_MASK_NZ);
1965
    t0 = tcg_temp_new();
1966
    /* Size can only be qi or hi.  */
1967
    t_gen_sext(t0, cpu_R[dc->op1], size);
1968
    cris_alu(dc, CC_OP_MOVE,
1969
            cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1970
    tcg_temp_free(t0);
1971
    return 2;
1972
}
1973

    
1974
/* zero extension. From size to dword.  */
1975
static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
1976
{
1977
    TCGv t0;
1978
    int size = memsize_z(dc);
1979
    LOG_DIS("addu.%c $r%u, $r%u\n",
1980
            memsize_char(size),
1981
            dc->op1, dc->op2);
1982

    
1983
    cris_cc_mask(dc, CC_MASK_NZVC);
1984
    t0 = tcg_temp_new();
1985
    /* Size can only be qi or hi.  */
1986
    t_gen_zext(t0, cpu_R[dc->op1], size);
1987
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1988
    tcg_temp_free(t0);
1989
    return 2;
1990
}
1991

    
1992
/* Sign extension. From size to dword.  */
1993
static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1994
{
1995
    TCGv t0;
1996
    int size = memsize_z(dc);
1997
    LOG_DIS("adds.%c $r%u, $r%u\n",
1998
            memsize_char(size),
1999
            dc->op1, dc->op2);
2000

    
2001
    cris_cc_mask(dc, CC_MASK_NZVC);
2002
    t0 = tcg_temp_new();
2003
    /* Size can only be qi or hi.  */
2004
    t_gen_sext(t0, cpu_R[dc->op1], size);
2005
    cris_alu(dc, CC_OP_ADD,
2006
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2007
    tcg_temp_free(t0);
2008
    return 2;
2009
}
2010

    
2011
/* Zero extension. From size to dword.  */
2012
static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
2013
{
2014
    TCGv t0;
2015
    int size = memsize_z(dc);
2016
    LOG_DIS("subu.%c $r%u, $r%u\n",
2017
            memsize_char(size),
2018
            dc->op1, dc->op2);
2019

    
2020
    cris_cc_mask(dc, CC_MASK_NZVC);
2021
    t0 = tcg_temp_new();
2022
    /* Size can only be qi or hi.  */
2023
    t_gen_zext(t0, cpu_R[dc->op1], size);
2024
    cris_alu(dc, CC_OP_SUB,
2025
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2026
    tcg_temp_free(t0);
2027
    return 2;
2028
}
2029

    
2030
/* Sign extension. From size to dword.  */
2031
static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
2032
{
2033
    TCGv t0;
2034
    int size = memsize_z(dc);
2035
    LOG_DIS("subs.%c $r%u, $r%u\n",
2036
            memsize_char(size),
2037
            dc->op1, dc->op2);
2038

    
2039
    cris_cc_mask(dc, CC_MASK_NZVC);
2040
    t0 = tcg_temp_new();
2041
    /* Size can only be qi or hi.  */
2042
    t_gen_sext(t0, cpu_R[dc->op1], size);
2043
    cris_alu(dc, CC_OP_SUB,
2044
            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2045
    tcg_temp_free(t0);
2046
    return 2;
2047
}
2048

    
2049
static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
2050
{
2051
    uint32_t flags;
2052
    int set = (~dc->opcode >> 2) & 1;
2053

    
2054

    
2055
    flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2056
        | EXTRACT_FIELD(dc->ir, 0, 3);
2057
    if (set && flags == 0) {
2058
        LOG_DIS("nop\n");
2059
        return 2;
2060
    } else if (!set && (flags & 0x20)) {
2061
        LOG_DIS("di\n");
2062
    } else {
2063
        LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
2064
    }
2065

    
2066
    /* User space is not allowed to touch these. Silently ignore.  */
2067
    if (dc->tb_flags & U_FLAG) {
2068
        flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2069
    }
2070

    
2071
    if (flags & X_FLAG) {
2072
        dc->flagx_known = 1;
2073
        if (set) {
2074
            dc->flags_x = X_FLAG;
2075
        } else {
2076
            dc->flags_x = 0;
2077
        }
2078
    }
2079

    
2080
    /* Break the TB if any of the SPI flag changes.  */
2081
    if (flags & (P_FLAG | S_FLAG)) {
2082
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2083
        dc->is_jmp = DISAS_UPDATE;
2084
        dc->cpustate_changed = 1;
2085
    }
2086

    
2087
    /* For the I flag, only act on posedge.  */
2088
    if ((flags & I_FLAG)) {
2089
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2090
        dc->is_jmp = DISAS_UPDATE;
2091
        dc->cpustate_changed = 1;
2092
    }
2093

    
2094

    
2095
    /* Simply decode the flags.  */
2096
    cris_evaluate_flags(dc);
2097
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2098
    cris_update_cc_x(dc);
2099
    tcg_gen_movi_tl(cc_op, dc->cc_op);
2100

    
2101
    if (set) {
2102
        if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2103
            /* Enter user mode.  */
2104
            t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2105
            tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2106
            dc->cpustate_changed = 1;
2107
        }
2108
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2109
    } else {
2110
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2111
    }
2112

    
2113
    dc->flags_uptodate = 1;
2114
    dc->clear_x = 0;
2115
    return 2;
2116
}
2117

    
2118
static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
2119
{
2120
    LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2121
    cris_cc_mask(dc, 0);
2122
        gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
2123
                                 tcg_const_tl(dc->op1));
2124
    return 2;
2125
}
2126
static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
2127
{
2128
    LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2129
    cris_cc_mask(dc, 0);
2130
        gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
2131
                                 tcg_const_tl(dc->op2));
2132
    return 2;
2133
}
2134

    
2135
static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
2136
{
2137
    TCGv t[2];
2138
    LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2139
    cris_cc_mask(dc, 0);
2140

    
2141
    t[0] = tcg_temp_new();
2142
    if (dc->op2 == PR_CCS) {
2143
        cris_evaluate_flags(dc);
2144
        t_gen_mov_TN_reg(t[0], dc->op1);
2145
        if (dc->tb_flags & U_FLAG) {
2146
            t[1] = tcg_temp_new();
2147
            /* User space is not allowed to touch all flags.  */
2148
            tcg_gen_andi_tl(t[0], t[0], 0x39f);
2149
            tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2150
            tcg_gen_or_tl(t[0], t[1], t[0]);
2151
            tcg_temp_free(t[1]);
2152
        }
2153
    } else {
2154
        t_gen_mov_TN_reg(t[0], dc->op1);
2155
    }
2156

    
2157
    t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2158
    if (dc->op2 == PR_CCS) {
2159
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2160
        dc->flags_uptodate = 1;
2161
    }
2162
    tcg_temp_free(t[0]);
2163
    return 2;
2164
}
2165
static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
2166
{
2167
    TCGv t0;
2168
    LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2169
    cris_cc_mask(dc, 0);
2170

    
2171
    if (dc->op2 == PR_CCS) {
2172
        cris_evaluate_flags(dc);
2173
    }
2174

    
2175
    if (dc->op2 == PR_DZ) {
2176
        tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2177
    } else {
2178
        t0 = tcg_temp_new();
2179
        t_gen_mov_TN_preg(t0, dc->op2);
2180
        cris_alu(dc, CC_OP_MOVE,
2181
                cpu_R[dc->op1], cpu_R[dc->op1], t0,
2182
                preg_sizes[dc->op2]);
2183
        tcg_temp_free(t0);
2184
    }
2185
    return 2;
2186
}
2187

    
2188
static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
2189
{
2190
    int memsize = memsize_zz(dc);
2191
    int insn_len;
2192
    LOG_DIS("move.%c [$r%u%s, $r%u\n",
2193
            memsize_char(memsize),
2194
            dc->op1, dc->postinc ? "+]" : "]",
2195
                    dc->op2);
2196

    
2197
    if (memsize == 4) {
2198
        insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2199
        cris_cc_mask(dc, CC_MASK_NZ);
2200
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
2201
        cris_update_cc_x(dc);
2202
        cris_update_result(dc, cpu_R[dc->op2]);
2203
    } else {
2204
        TCGv t0;
2205

    
2206
        t0 = tcg_temp_new();
2207
        insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2208
        cris_cc_mask(dc, CC_MASK_NZ);
2209
        cris_alu(dc, CC_OP_MOVE,
2210
                cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2211
        tcg_temp_free(t0);
2212
    }
2213
    do_postinc(dc, memsize);
2214
    return insn_len;
2215
}
2216

    
2217
static inline void cris_alu_m_alloc_temps(TCGv *t)
2218
{
2219
    t[0] = tcg_temp_new();
2220
    t[1] = tcg_temp_new();
2221
}
2222

    
2223
static inline void cris_alu_m_free_temps(TCGv *t)
2224
{
2225
    tcg_temp_free(t[0]);
2226
    tcg_temp_free(t[1]);
2227
}
2228

    
2229
static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
2230
{
2231
    TCGv t[2];
2232
    int memsize = memsize_z(dc);
2233
    int insn_len;
2234
    LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2235
            memsize_char(memsize),
2236
            dc->op1, dc->postinc ? "+]" : "]",
2237
            dc->op2);
2238

    
2239
    cris_alu_m_alloc_temps(t);
2240
    /* sign extend.  */
2241
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2242
    cris_cc_mask(dc, CC_MASK_NZ);
2243
    cris_alu(dc, CC_OP_MOVE,
2244
            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2245
    do_postinc(dc, memsize);
2246
    cris_alu_m_free_temps(t);
2247
    return insn_len;
2248
}
2249

    
2250
static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
2251
{
2252
    TCGv t[2];
2253
    int memsize = memsize_z(dc);
2254
    int insn_len;
2255
    LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2256
            memsize_char(memsize),
2257
            dc->op1, dc->postinc ? "+]" : "]",
2258
            dc->op2);
2259

    
2260
    cris_alu_m_alloc_temps(t);
2261
    /* sign extend.  */
2262
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2263
    cris_cc_mask(dc, CC_MASK_NZVC);
2264
    cris_alu(dc, CC_OP_ADD,
2265
            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2266
    do_postinc(dc, memsize);
2267
    cris_alu_m_free_temps(t);
2268
    return insn_len;
2269
}
2270

    
2271
static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
2272
{
2273
    TCGv t[2];
2274
    int memsize = memsize_z(dc);
2275
    int insn_len;
2276
    LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2277
            memsize_char(memsize),
2278
            dc->op1, dc->postinc ? "+]" : "]",
2279
            dc->op2);
2280

    
2281
    cris_alu_m_alloc_temps(t);
2282
    /* sign extend.  */
2283
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2284
    cris_cc_mask(dc, CC_MASK_NZVC);
2285
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2286
    do_postinc(dc, memsize);
2287
    cris_alu_m_free_temps(t);
2288
    return insn_len;
2289
}
2290

    
2291
static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
2292
{
2293
    TCGv t[2];
2294
    int memsize = memsize_z(dc);
2295
    int insn_len;
2296
    LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2297
            memsize_char(memsize),
2298
            dc->op1, dc->postinc ? "+]" : "]",
2299
            dc->op2);
2300

    
2301
    cris_alu_m_alloc_temps(t);
2302
    /* sign extend.  */
2303
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2304
    cris_cc_mask(dc, CC_MASK_NZVC);
2305
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2306
    do_postinc(dc, memsize);
2307
    cris_alu_m_free_temps(t);
2308
    return insn_len;
2309
}
2310

    
2311
static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
2312
{
2313
    TCGv t[2];
2314
    int memsize = memsize_z(dc);
2315
    int insn_len;
2316
    LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2317
            memsize_char(memsize),
2318
            dc->op1, dc->postinc ? "+]" : "]",
2319
            dc->op2);
2320

    
2321
    cris_alu_m_alloc_temps(t);
2322
    /* sign extend.  */
2323
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2324
    cris_cc_mask(dc, CC_MASK_NZVC);
2325
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2326
    do_postinc(dc, memsize);
2327
    cris_alu_m_free_temps(t);
2328
    return insn_len;
2329
}
2330

    
2331
static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2332
{
2333
    TCGv t[2];
2334
    int memsize = memsize_z(dc);
2335
    int insn_len;
2336

    
2337
    LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2338
            memsize_char(memsize),
2339
            dc->op1, dc->postinc ? "+]" : "]",
2340
            dc->op2);
2341

    
2342
    cris_alu_m_alloc_temps(t);
2343
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2344
    cris_cc_mask(dc, CC_MASK_NZ);
2345
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2346
    do_postinc(dc, memsize);
2347
    cris_alu_m_free_temps(t);
2348
    return insn_len;
2349
}
2350

    
2351
static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2352
{
2353
    TCGv t[2];
2354
    int memsize = memsize_z(dc);
2355
    int insn_len;
2356
    LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2357
            memsize_char(memsize),
2358
            dc->op1, dc->postinc ? "+]" : "]",
2359
            dc->op2);
2360

    
2361
    cris_alu_m_alloc_temps(t);
2362
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2363
    cris_cc_mask(dc, CC_MASK_NZVC);
2364
    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2365
    do_postinc(dc, memsize);
2366
    cris_alu_m_free_temps(t);
2367
    return insn_len;
2368
}
2369

    
2370
static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
2371
{
2372
    TCGv t[2];
2373
    int memsize = memsize_z(dc);
2374
    int insn_len;
2375
    LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2376
            memsize_char(memsize),
2377
            dc->op1, dc->postinc ? "+]" : "]",
2378
            dc->op2);
2379

    
2380
    cris_alu_m_alloc_temps(t);
2381
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2382
    cris_cc_mask(dc, CC_MASK_NZVC);
2383
    cris_alu(dc, CC_OP_CMP,
2384
            cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2385
            memsize_zz(dc));
2386
    do_postinc(dc, memsize);
2387
    cris_alu_m_free_temps(t);
2388
    return insn_len;
2389
}
2390

    
2391
static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
2392
{
2393
    TCGv t[2];
2394
    int memsize = memsize_zz(dc);
2395
    int insn_len;
2396
    LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2397
            memsize_char(memsize),
2398
            dc->op1, dc->postinc ? "+]" : "]",
2399
            dc->op2);
2400

    
2401
    cris_alu_m_alloc_temps(t);
2402
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2403
    cris_cc_mask(dc, CC_MASK_NZVC);
2404
    cris_alu(dc, CC_OP_CMP,
2405
            cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2406
            memsize_zz(dc));
2407
    do_postinc(dc, memsize);
2408
    cris_alu_m_free_temps(t);
2409
    return insn_len;
2410
}
2411

    
2412
static int dec_test_m(CPUCRISState *env, DisasContext *dc)
2413
{
2414
    TCGv t[2];
2415
    int memsize = memsize_zz(dc);
2416
    int insn_len;
2417
    LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2418
            memsize_char(memsize),
2419
            dc->op1, dc->postinc ? "+]" : "]",
2420
            dc->op2);
2421

    
2422
    cris_evaluate_flags(dc);
2423

    
2424
    cris_alu_m_alloc_temps(t);
2425
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2426
    cris_cc_mask(dc, CC_MASK_NZ);
2427
    tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2428

    
2429
    cris_alu(dc, CC_OP_CMP,
2430
         cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2431
    do_postinc(dc, memsize);
2432
    cris_alu_m_free_temps(t);
2433
    return insn_len;
2434
}
2435

    
2436
static int dec_and_m(CPUCRISState *env, DisasContext *dc)
2437
{
2438
    TCGv t[2];
2439
    int memsize = memsize_zz(dc);
2440
    int insn_len;
2441
    LOG_DIS("and.%c [$r%u%s, $r%u\n",
2442
            memsize_char(memsize),
2443
            dc->op1, dc->postinc ? "+]" : "]",
2444
            dc->op2);
2445

    
2446
    cris_alu_m_alloc_temps(t);
2447
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2448
    cris_cc_mask(dc, CC_MASK_NZ);
2449
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2450
    do_postinc(dc, memsize);
2451
    cris_alu_m_free_temps(t);
2452
    return insn_len;
2453
}
2454

    
2455
static int dec_add_m(CPUCRISState *env, DisasContext *dc)
2456
{
2457
    TCGv t[2];
2458
    int memsize = memsize_zz(dc);
2459
    int insn_len;
2460
    LOG_DIS("add.%c [$r%u%s, $r%u\n",
2461
            memsize_char(memsize),
2462
            dc->op1, dc->postinc ? "+]" : "]",
2463
            dc->op2);
2464

    
2465
    cris_alu_m_alloc_temps(t);
2466
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2467
    cris_cc_mask(dc, CC_MASK_NZVC);
2468
    cris_alu(dc, CC_OP_ADD,
2469
         cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2470
    do_postinc(dc, memsize);
2471
    cris_alu_m_free_temps(t);
2472
    return insn_len;
2473
}
2474

    
2475
static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
2476
{
2477
    TCGv t[2];
2478
    int memsize = memsize_zz(dc);
2479
    int insn_len;
2480
    LOG_DIS("add.%c [$r%u%s, $r%u\n",
2481
            memsize_char(memsize),
2482
            dc->op1, dc->postinc ? "+]" : "]",
2483
            dc->op2);
2484

    
2485
    cris_alu_m_alloc_temps(t);
2486
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2487
    cris_cc_mask(dc, 0);
2488
    cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2489
    do_postinc(dc, memsize);
2490
    cris_alu_m_free_temps(t);
2491
    return insn_len;
2492
}
2493

    
2494
static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
2495
{
2496
    TCGv l[2];
2497
    int memsize = memsize_zz(dc);
2498
    int insn_len;
2499
    LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2500
            memsize_char(memsize),
2501
            dc->op1, dc->postinc ? "+]" : "]",
2502
            dc->op2);
2503

    
2504
    l[0] = tcg_temp_local_new();
2505
    l[1] = tcg_temp_local_new();
2506
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2507
    cris_cc_mask(dc, CC_MASK_NZ);
2508
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2509
    do_postinc(dc, memsize);
2510
    tcg_temp_free(l[0]);
2511
    tcg_temp_free(l[1]);
2512
    return insn_len;
2513
}
2514

    
2515
static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2516
{
2517
    TCGv t[2];
2518
    int insn_len = 2;
2519
    LOG_DIS("addc [$r%u%s, $r%u\n",
2520
            dc->op1, dc->postinc ? "+]" : "]",
2521
            dc->op2);
2522

    
2523
    cris_evaluate_flags(dc);
2524

    
2525
    /* Set for this insn.  */
2526
    dc->flagx_known = 1;
2527
    dc->flags_x = X_FLAG;
2528

    
2529
    cris_alu_m_alloc_temps(t);
2530
        insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2531
    cris_cc_mask(dc, CC_MASK_NZVC);
2532
    cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2533
    do_postinc(dc, 4);
2534
    cris_alu_m_free_temps(t);
2535
    return insn_len;
2536
}
2537

    
2538
static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2539
{
2540
    TCGv t[2];
2541
    int memsize = memsize_zz(dc);
2542
    int insn_len;
2543
    LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2544
            memsize_char(memsize),
2545
            dc->op1, dc->postinc ? "+]" : "]",
2546
            dc->op2, dc->ir, dc->zzsize);
2547

    
2548
    cris_alu_m_alloc_temps(t);
2549
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2550
    cris_cc_mask(dc, CC_MASK_NZVC);
2551
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2552
    do_postinc(dc, memsize);
2553
    cris_alu_m_free_temps(t);
2554
    return insn_len;
2555
}
2556

    
2557
static int dec_or_m(CPUCRISState *env, DisasContext *dc)
2558
{
2559
    TCGv t[2];
2560
    int memsize = memsize_zz(dc);
2561
    int insn_len;
2562
    LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2563
            memsize_char(memsize),
2564
            dc->op1, dc->postinc ? "+]" : "]",
2565
            dc->op2, dc->pc);
2566

    
2567
    cris_alu_m_alloc_temps(t);
2568
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2569
    cris_cc_mask(dc, CC_MASK_NZ);
2570
    cris_alu(dc, CC_OP_OR,
2571
            cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2572
    do_postinc(dc, memsize);
2573
    cris_alu_m_free_temps(t);
2574
    return insn_len;
2575
}
2576

    
2577
static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2578
{
2579
    TCGv t[2];
2580
    int memsize = memsize_zz(dc);
2581
    int insn_len = 2;
2582

    
2583
    LOG_DIS("move.%c [$r%u%s, $p%u\n",
2584
            memsize_char(memsize),
2585
            dc->op1,
2586
            dc->postinc ? "+]" : "]",
2587
            dc->op2);
2588

    
2589
    cris_alu_m_alloc_temps(t);
2590
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2591
    cris_cc_mask(dc, 0);
2592
    if (dc->op2 == PR_CCS) {
2593
        cris_evaluate_flags(dc);
2594
        if (dc->tb_flags & U_FLAG) {
2595
            /* User space is not allowed to touch all flags.  */
2596
            tcg_gen_andi_tl(t[1], t[1], 0x39f);
2597
            tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2598
            tcg_gen_or_tl(t[1], t[0], t[1]);
2599
        }
2600
    }
2601

    
2602
    t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2603

    
2604
    do_postinc(dc, memsize);
2605
    cris_alu_m_free_temps(t);
2606
    return insn_len;
2607
}
2608

    
2609
static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2610
{
2611
    TCGv t0;
2612
    int memsize;
2613

    
2614
    memsize = preg_sizes[dc->op2];
2615

    
2616
    LOG_DIS("move.%c $p%u, [$r%u%s\n",
2617
            memsize_char(memsize),
2618
            dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2619

    
2620
    /* prepare store. Address in T0, value in T1.  */
2621
    if (dc->op2 == PR_CCS) {
2622
        cris_evaluate_flags(dc);
2623
    }
2624
    t0 = tcg_temp_new();
2625
    t_gen_mov_TN_preg(t0, dc->op2);
2626
    cris_flush_cc_state(dc);
2627
    gen_store(dc, cpu_R[dc->op1], t0, memsize);
2628
    tcg_temp_free(t0);
2629

    
2630
    cris_cc_mask(dc, 0);
2631
    if (dc->postinc) {
2632
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2633
    }
2634
    return 2;
2635
}
2636

    
2637
static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2638
{
2639
    TCGv_i64 tmp[16];
2640
    TCGv tmp32;
2641
    TCGv addr;
2642
    int i;
2643
    int nr = dc->op2 + 1;
2644

    
2645
    LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2646
            dc->postinc ? "+]" : "]", dc->op2);
2647

    
2648
    addr = tcg_temp_new();
2649
    /* There are probably better ways of doing this.  */
2650
    cris_flush_cc_state(dc);
2651
    for (i = 0; i < (nr >> 1); i++) {
2652
        tmp[i] = tcg_temp_new_i64();
2653
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2654
        gen_load64(dc, tmp[i], addr);
2655
    }
2656
    if (nr & 1) {
2657
        tmp32 = tcg_temp_new_i32();
2658
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2659
        gen_load(dc, tmp32, addr, 4, 0);
2660
    } else {
2661
        TCGV_UNUSED(tmp32);
2662
    }
2663
    tcg_temp_free(addr);
2664

    
2665
    for (i = 0; i < (nr >> 1); i++) {
2666
        tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2667
        tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2668
        tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2669
        tcg_temp_free_i64(tmp[i]);
2670
    }
2671
    if (nr & 1) {
2672
        tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2673
        tcg_temp_free(tmp32);
2674
    }
2675

    
2676
    /* writeback the updated pointer value.  */
2677
    if (dc->postinc) {
2678
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2679
    }
2680

    
2681
    /* gen_load might want to evaluate the previous insns flags.  */
2682
    cris_cc_mask(dc, 0);
2683
    return 2;
2684
}
2685

    
2686
static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2687
{
2688
    TCGv tmp;
2689
    TCGv addr;
2690
    int i;
2691

    
2692
    LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2693
            dc->postinc ? "+]" : "]");
2694

    
2695
    cris_flush_cc_state(dc);
2696

    
2697
    tmp = tcg_temp_new();
2698
    addr = tcg_temp_new();
2699
    tcg_gen_movi_tl(tmp, 4);
2700
    tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2701
    for (i = 0; i <= dc->op2; i++) {
2702
        /* Displace addr.  */
2703
        /* Perform the store.  */
2704
        gen_store(dc, addr, cpu_R[i], 4);
2705
        tcg_gen_add_tl(addr, addr, tmp);
2706
    }
2707
    if (dc->postinc) {
2708
        tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2709
    }
2710
    cris_cc_mask(dc, 0);
2711
    tcg_temp_free(tmp);
2712
    tcg_temp_free(addr);
2713
    return 2;
2714
}
2715

    
2716
static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2717
{
2718
    int memsize;
2719

    
2720
    memsize = memsize_zz(dc);
2721

    
2722
    LOG_DIS("move.%c $r%u, [$r%u]\n",
2723
            memsize_char(memsize), dc->op2, dc->op1);
2724

    
2725
    /* prepare store.  */
2726
    cris_flush_cc_state(dc);
2727
    gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2728

    
2729
    if (dc->postinc) {
2730
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2731
    }
2732
    cris_cc_mask(dc, 0);
2733
    return 2;
2734
}
2735

    
2736
static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2737
{
2738
    LOG_DIS("lapcq %x, $r%u\n",
2739
            dc->pc + dc->op1*2, dc->op2);
2740
    cris_cc_mask(dc, 0);
2741
    tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2742
    return 2;
2743
}
2744

    
2745
static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2746
{
2747
    unsigned int rd;
2748
    int32_t imm;
2749
    int32_t pc;
2750

    
2751
    rd = dc->op2;
2752

    
2753
    cris_cc_mask(dc, 0);
2754
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2755
    LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2756

    
2757
    pc = dc->pc;
2758
    pc += imm;
2759
    tcg_gen_movi_tl(cpu_R[rd], pc);
2760
    return 6;
2761
}
2762

    
2763
/* Jump to special reg.  */
2764
static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2765
{
2766
    LOG_DIS("jump $p%u\n", dc->op2);
2767

    
2768
    if (dc->op2 == PR_CCS) {
2769
        cris_evaluate_flags(dc);
2770
    }
2771
    t_gen_mov_TN_preg(env_btarget, dc->op2);
2772
    /* rete will often have low bit set to indicate delayslot.  */
2773
    tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2774
    cris_cc_mask(dc, 0);
2775
    cris_prepare_jmp(dc, JMP_INDIRECT);
2776
    return 2;
2777
}
2778

    
2779
/* Jump and save.  */
2780
static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2781
{
2782
    LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2783
    cris_cc_mask(dc, 0);
2784
    /* Store the return address in Pd.  */
2785
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2786
    if (dc->op2 > 15) {
2787
        abort();
2788
    }
2789
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2790

    
2791
    cris_prepare_jmp(dc, JMP_INDIRECT);
2792
    return 2;
2793
}
2794

    
2795
static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2796
{
2797
    uint32_t imm;
2798

    
2799
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2800

    
2801
    LOG_DIS("jas 0x%x\n", imm);
2802
    cris_cc_mask(dc, 0);
2803
    /* Store the return address in Pd.  */
2804
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2805

    
2806
    dc->jmp_pc = imm;
2807
    cris_prepare_jmp(dc, JMP_DIRECT);
2808
    return 6;
2809
}
2810

    
2811
static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2812
{
2813
    uint32_t imm;
2814

    
2815
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2816

    
2817
    LOG_DIS("jasc 0x%x\n", imm);
2818
    cris_cc_mask(dc, 0);
2819
    /* Store the return address in Pd.  */
2820
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2821

    
2822
    dc->jmp_pc = imm;
2823
    cris_prepare_jmp(dc, JMP_DIRECT);
2824
    return 6;
2825
}
2826

    
2827
static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2828
{
2829
    LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2830
    cris_cc_mask(dc, 0);
2831
    /* Store the return address in Pd.  */
2832
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2833
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2834
    cris_prepare_jmp(dc, JMP_INDIRECT);
2835
    return 2;
2836
}
2837

    
2838
static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2839
{
2840
    int32_t offset;
2841
    uint32_t cond = dc->op2;
2842

    
2843
    offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2844

    
2845
    LOG_DIS("b%s %d pc=%x dst=%x\n",
2846
            cc_name(cond), offset,
2847
            dc->pc, dc->pc + offset);
2848

    
2849
    cris_cc_mask(dc, 0);
2850
    /* op2 holds the condition-code.  */
2851
    cris_prepare_cc_branch(dc, offset, cond);
2852
    return 4;
2853
}
2854

    
2855
static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2856
{
2857
    int32_t simm;
2858

    
2859
    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2860

    
2861
    LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2862
    cris_cc_mask(dc, 0);
2863
    /* Store the return address in Pd.  */
2864
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2865

    
2866
    dc->jmp_pc = dc->pc + simm;
2867
    cris_prepare_jmp(dc, JMP_DIRECT);
2868
    return 6;
2869
}
2870

    
2871
static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2872
{
2873
    int32_t simm;
2874
    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2875

    
2876
    LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2877
    cris_cc_mask(dc, 0);
2878
    /* Store the return address in Pd.  */
2879
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2880

    
2881
    dc->jmp_pc = dc->pc + simm;
2882
    cris_prepare_jmp(dc, JMP_DIRECT);
2883
    return 6;
2884
}
2885

    
2886
static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2887
{
2888
    cris_cc_mask(dc, 0);
2889

    
2890
    if (dc->op2 == 15) {
2891
        tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
2892
                       -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2893
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2894
        t_gen_raise_exception(EXCP_HLT);
2895
        return 2;
2896
    }
2897

    
2898
    switch (dc->op2 & 7) {
2899
    case 2:
2900
        /* rfe.  */
2901
        LOG_DIS("rfe\n");
2902
        cris_evaluate_flags(dc);
2903
        gen_helper_rfe(cpu_env);
2904
        dc->is_jmp = DISAS_UPDATE;
2905
        break;
2906
    case 5:
2907
        /* rfn.  */
2908
        LOG_DIS("rfn\n");
2909
        cris_evaluate_flags(dc);
2910
        gen_helper_rfn(cpu_env);
2911
        dc->is_jmp = DISAS_UPDATE;
2912
        break;
2913
    case 6:
2914
        LOG_DIS("break %d\n", dc->op1);
2915
        cris_evaluate_flags(dc);
2916
        /* break.  */
2917
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2918

    
2919
        /* Breaks start at 16 in the exception vector.  */
2920
        t_gen_mov_env_TN(trap_vector,
2921
                tcg_const_tl(dc->op1 + 16));
2922
        t_gen_raise_exception(EXCP_BREAK);
2923
        dc->is_jmp = DISAS_UPDATE;
2924
        break;
2925
    default:
2926
        printf("op2=%x\n", dc->op2);
2927
        BUG();
2928
        break;
2929

    
2930
    }
2931
    return 2;
2932
}
2933

    
2934
static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2935
{
2936
    return 2;
2937
}
2938

    
2939
static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2940
{
2941
    return 2;
2942
}
2943

    
2944
static int dec_null(CPUCRISState *env, DisasContext *dc)
2945
{
2946
    printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2947
        dc->pc, dc->opcode, dc->op1, dc->op2);
2948
    fflush(NULL);
2949
    BUG();
2950
    return 2;
2951
}
2952

    
2953
static struct decoder_info {
2954
    struct {
2955
        uint32_t bits;
2956
        uint32_t mask;
2957
    };
2958
    int (*dec)(CPUCRISState *env, DisasContext *dc);
2959
} decinfo[] = {
2960
    /* Order matters here.  */
2961
    {DEC_MOVEQ, dec_moveq},
2962
    {DEC_BTSTQ, dec_btstq},
2963
    {DEC_CMPQ, dec_cmpq},
2964
    {DEC_ADDOQ, dec_addoq},
2965
    {DEC_ADDQ, dec_addq},
2966
    {DEC_SUBQ, dec_subq},
2967
    {DEC_ANDQ, dec_andq},
2968
    {DEC_ORQ, dec_orq},
2969
    {DEC_ASRQ, dec_asrq},
2970
    {DEC_LSLQ, dec_lslq},
2971
    {DEC_LSRQ, dec_lsrq},
2972
    {DEC_BCCQ, dec_bccq},
2973

    
2974
    {DEC_BCC_IM, dec_bcc_im},
2975
    {DEC_JAS_IM, dec_jas_im},
2976
    {DEC_JAS_R, dec_jas_r},
2977
    {DEC_JASC_IM, dec_jasc_im},
2978
    {DEC_JASC_R, dec_jasc_r},
2979
    {DEC_BAS_IM, dec_bas_im},
2980
    {DEC_BASC_IM, dec_basc_im},
2981
    {DEC_JUMP_P, dec_jump_p},
2982
    {DEC_LAPC_IM, dec_lapc_im},
2983
    {DEC_LAPCQ, dec_lapcq},
2984

    
2985
    {DEC_RFE_ETC, dec_rfe_etc},
2986
    {DEC_ADDC_MR, dec_addc_mr},
2987

    
2988
    {DEC_MOVE_MP, dec_move_mp},
2989
    {DEC_MOVE_PM, dec_move_pm},
2990
    {DEC_MOVEM_MR, dec_movem_mr},
2991
    {DEC_MOVEM_RM, dec_movem_rm},
2992
    {DEC_MOVE_PR, dec_move_pr},
2993
    {DEC_SCC_R, dec_scc_r},
2994
    {DEC_SETF, dec_setclrf},
2995
    {DEC_CLEARF, dec_setclrf},
2996

    
2997
    {DEC_MOVE_SR, dec_move_sr},
2998
    {DEC_MOVE_RP, dec_move_rp},
2999
    {DEC_SWAP_R, dec_swap_r},
3000
    {DEC_ABS_R, dec_abs_r},
3001
    {DEC_LZ_R, dec_lz_r},
3002
    {DEC_MOVE_RS, dec_move_rs},
3003
    {DEC_BTST_R, dec_btst_r},
3004
    {DEC_ADDC_R, dec_addc_r},
3005

    
3006
    {DEC_DSTEP_R, dec_dstep_r},
3007
    {DEC_XOR_R, dec_xor_r},
3008
    {DEC_MCP_R, dec_mcp_r},
3009
    {DEC_CMP_R, dec_cmp_r},
3010

    
3011
    {DEC_ADDI_R, dec_addi_r},
3012
    {DEC_ADDI_ACR, dec_addi_acr},
3013

    
3014
    {DEC_ADD_R, dec_add_r},
3015
    {DEC_SUB_R, dec_sub_r},
3016

    
3017
    {DEC_ADDU_R, dec_addu_r},
3018
    {DEC_ADDS_R, dec_adds_r},
3019
    {DEC_SUBU_R, dec_subu_r},
3020
    {DEC_SUBS_R, dec_subs_r},
3021
    {DEC_LSL_R, dec_lsl_r},
3022

    
3023
    {DEC_AND_R, dec_and_r},
3024
    {DEC_OR_R, dec_or_r},
3025
    {DEC_BOUND_R, dec_bound_r},
3026
    {DEC_ASR_R, dec_asr_r},
3027
    {DEC_LSR_R, dec_lsr_r},
3028

    
3029
    {DEC_MOVU_R, dec_movu_r},
3030
    {DEC_MOVS_R, dec_movs_r},
3031
    {DEC_NEG_R, dec_neg_r},
3032
    {DEC_MOVE_R, dec_move_r},
3033

    
3034
    {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3035
    {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3036

    
3037
    {DEC_MULS_R, dec_muls_r},
3038
    {DEC_MULU_R, dec_mulu_r},
3039

    
3040
    {DEC_ADDU_M, dec_addu_m},
3041
    {DEC_ADDS_M, dec_adds_m},
3042
    {DEC_SUBU_M, dec_subu_m},
3043
    {DEC_SUBS_M, dec_subs_m},
3044

    
3045
    {DEC_CMPU_M, dec_cmpu_m},
3046
    {DEC_CMPS_M, dec_cmps_m},
3047
    {DEC_MOVU_M, dec_movu_m},
3048
    {DEC_MOVS_M, dec_movs_m},
3049

    
3050
    {DEC_CMP_M, dec_cmp_m},
3051
    {DEC_ADDO_M, dec_addo_m},
3052
    {DEC_BOUND_M, dec_bound_m},
3053
    {DEC_ADD_M, dec_add_m},
3054
    {DEC_SUB_M, dec_sub_m},
3055
    {DEC_AND_M, dec_and_m},
3056
    {DEC_OR_M, dec_or_m},
3057
    {DEC_MOVE_RM, dec_move_rm},
3058
    {DEC_TEST_M, dec_test_m},
3059
    {DEC_MOVE_MR, dec_move_mr},
3060

    
3061
    {{0, 0}, dec_null}
3062
};
3063

    
3064
static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
3065
{
3066
    int insn_len = 2;
3067
    int i;
3068

    
3069
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3070
        tcg_gen_debug_insn_start(dc->pc);
3071
        }
3072

    
3073
    /* Load a halfword onto the instruction register.  */
3074
        dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
3075

    
3076
    /* Now decode it.  */
3077
    dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3078
    dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3079
    dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3080
    dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3081
    dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3082
    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3083

    
3084
    /* Large switch for all insns.  */
3085
    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3086
        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
3087
            insn_len = decinfo[i].dec(env, dc);
3088
            break;
3089
        }
3090
    }
3091

    
3092
#if !defined(CONFIG_USER_ONLY)
3093
    /* Single-stepping ?  */
3094
    if (dc->tb_flags & S_FLAG) {
3095
        int l1;
3096

    
3097
        l1 = gen_new_label();
3098
        tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3099
        /* We treat SPC as a break with an odd trap vector.  */
3100
        cris_evaluate_flags(dc);
3101
        t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3102
        tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3103
        tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3104
        t_gen_raise_exception(EXCP_BREAK);
3105
        gen_set_label(l1);
3106
    }
3107
#endif
3108
    return insn_len;
3109
}
3110

    
3111
static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
3112
{
3113
    CPUBreakpoint *bp;
3114

    
3115
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3116
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3117
            if (bp->pc == dc->pc) {
3118
                cris_evaluate_flags(dc);
3119
                tcg_gen_movi_tl(env_pc, dc->pc);
3120
                t_gen_raise_exception(EXCP_DEBUG);
3121
                dc->is_jmp = DISAS_UPDATE;
3122
            }
3123
        }
3124
    }
3125
}
3126

    
3127
#include "translate_v10.c"
3128

    
3129
/*
3130
 * Delay slots on QEMU/CRIS.
3131
 *
3132
 * If an exception hits on a delayslot, the core will let ERP (the Exception
3133
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
3134
 * to give SW a hint that the exception actually hit on the dslot.
3135
 *
3136
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
3137
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
3138
 * simply there to let sw know there was an exception on a dslot.
3139
 *
3140
 * When the software returns from an exception, the branch will re-execute.
3141
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3142
 * and the branch and delayslot dont share pages.
3143
 *
3144
 * The TB contaning the branch insn will set up env->btarget and evaluate 
3145
 * env->btaken. When the translation loop exits we will note that the branch 
3146
 * sequence is broken and let env->dslot be the size of the branch insn (those
3147
 * vary in length).
3148
 *
3149
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3150
 * set). It will also expect to have env->dslot setup with the size of the 
3151
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3152
 * will execute the dslot and take the branch, either to btarget or just one 
3153
 * insn ahead.
3154
 *
3155
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3156
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
3157
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
3158
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3159
 * masked off and we will reexecute the branch insn.
3160
 *
3161
 */
3162

    
3163
/* generate intermediate code for basic block 'tb'.  */
3164
static inline void
3165
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
3166
                               bool search_pc)
3167
{
3168
    CPUState *cs = CPU(cpu);
3169
    CPUCRISState *env = &cpu->env;
3170
    uint16_t *gen_opc_end;
3171
    uint32_t pc_start;
3172
    unsigned int insn_len;
3173
    int j, lj;
3174
    struct DisasContext ctx;
3175
    struct DisasContext *dc = &ctx;
3176
    uint32_t next_page_start;
3177
    target_ulong npc;
3178
    int num_insns;
3179
    int max_insns;
3180

    
3181
    if (env->pregs[PR_VR] == 32) {
3182
        dc->decoder = crisv32_decoder;
3183
        dc->clear_locked_irq = 0;
3184
    } else {
3185
        dc->decoder = crisv10_decoder;
3186
        dc->clear_locked_irq = 1;
3187
    }
3188

    
3189
    /* Odd PC indicates that branch is rexecuting due to exception in the
3190
     * delayslot, like in real hw.
3191
     */
3192
    pc_start = tb->pc & ~1;
3193
    dc->env = env;
3194
    dc->tb = tb;
3195

    
3196
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3197

    
3198
    dc->is_jmp = DISAS_NEXT;
3199
    dc->ppc = pc_start;
3200
    dc->pc = pc_start;
3201
    dc->singlestep_enabled = cs->singlestep_enabled;
3202
    dc->flags_uptodate = 1;
3203
    dc->flagx_known = 1;
3204
    dc->flags_x = tb->flags & X_FLAG;
3205
    dc->cc_x_uptodate = 0;
3206
    dc->cc_mask = 0;
3207
    dc->update_cc = 0;
3208
    dc->clear_prefix = 0;
3209

    
3210
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3211
    dc->cc_size_uptodate = -1;
3212

    
3213
    /* Decode TB flags.  */
3214
    dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3215
            | X_FLAG | PFIX_FLAG);
3216
    dc->delayed_branch = !!(tb->flags & 7);
3217
    if (dc->delayed_branch) {
3218
        dc->jmp = JMP_INDIRECT;
3219
    } else {
3220
        dc->jmp = JMP_NOJMP;
3221
    }
3222

    
3223
    dc->cpustate_changed = 0;
3224

    
3225
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3226
        qemu_log(
3227
                "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3228
                "pid=%x usp=%x\n"
3229
                "%x.%x.%x.%x\n"
3230
                "%x.%x.%x.%x\n"
3231
                "%x.%x.%x.%x\n"
3232
                "%x.%x.%x.%x\n",
3233
                search_pc, dc->pc, dc->ppc,
3234
                (uint64_t)tb->flags,
3235
                env->btarget, (unsigned)tb->flags & 7,
3236
                env->pregs[PR_CCS],
3237
                env->pregs[PR_PID], env->pregs[PR_USP],
3238
                env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3239
                env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3240
                env->regs[8], env->regs[9],
3241
                env->regs[10], env->regs[11],
3242
                env->regs[12], env->regs[13],
3243
                env->regs[14], env->regs[15]);
3244
        qemu_log("--------------\n");
3245
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3246
    }
3247

    
3248
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3249
    lj = -1;
3250
    num_insns = 0;
3251
    max_insns = tb->cflags & CF_COUNT_MASK;
3252
    if (max_insns == 0) {
3253
        max_insns = CF_COUNT_MASK;
3254
    }
3255

    
3256
    gen_tb_start();
3257
    do {
3258
        check_breakpoint(env, dc);
3259

    
3260
        if (search_pc) {
3261
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3262
            if (lj < j) {
3263
                lj++;
3264
                while (lj < j) {
3265
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
3266
                }
3267
            }
3268
            if (dc->delayed_branch == 1) {
3269
                tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;
3270
            } else {
3271
                tcg_ctx.gen_opc_pc[lj] = dc->pc;
3272
            }
3273
            tcg_ctx.gen_opc_instr_start[lj] = 1;
3274
            tcg_ctx.gen_opc_icount[lj] = num_insns;
3275
        }
3276

    
3277
        /* Pretty disas.  */
3278
        LOG_DIS("%8.8x:\t", dc->pc);
3279

    
3280
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3281
            gen_io_start();
3282
        }
3283
        dc->clear_x = 1;
3284

    
3285
        insn_len = dc->decoder(env, dc);
3286
        dc->ppc = dc->pc;
3287
        dc->pc += insn_len;
3288
        if (dc->clear_x) {
3289
            cris_clear_x_flag(dc);
3290
        }
3291

    
3292
        num_insns++;
3293
        /* Check for delayed branches here. If we do it before
3294
           actually generating any host code, the simulator will just
3295
           loop doing nothing for on this program location.  */
3296
        if (dc->delayed_branch) {
3297
            dc->delayed_branch--;
3298
            if (dc->delayed_branch == 0) {
3299
                if (tb->flags & 7) {
3300
                    t_gen_mov_env_TN(dslot, tcg_const_tl(0));
3301
                }
3302
                if (dc->cpustate_changed || !dc->flagx_known
3303
                    || (dc->flags_x != (tb->flags & X_FLAG))) {
3304
                    cris_store_direct_jmp(dc);
3305
                }
3306

    
3307
                if (dc->clear_locked_irq) {
3308
                    dc->clear_locked_irq = 0;
3309
                    t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3310
                }
3311

    
3312
                if (dc->jmp == JMP_DIRECT_CC) {
3313
                    int l1;
3314

    
3315
                    l1 = gen_new_label();
3316
                    cris_evaluate_flags(dc);
3317

    
3318
                    /* Conditional jmp.  */
3319
                    tcg_gen_brcondi_tl(TCG_COND_EQ,
3320
                               env_btaken, 0, l1);
3321
                    gen_goto_tb(dc, 1, dc->jmp_pc);
3322
                    gen_set_label(l1);
3323
                    gen_goto_tb(dc, 0, dc->pc);
3324
                    dc->is_jmp = DISAS_TB_JUMP;
3325
                    dc->jmp = JMP_NOJMP;
3326
                } else if (dc->jmp == JMP_DIRECT) {
3327
                    cris_evaluate_flags(dc);
3328
                    gen_goto_tb(dc, 0, dc->jmp_pc);
3329
                    dc->is_jmp = DISAS_TB_JUMP;
3330
                    dc->jmp = JMP_NOJMP;
3331
                } else {
3332
                    t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
3333
                    dc->is_jmp = DISAS_JUMP;
3334
                }
3335
                break;
3336
            }
3337
        }
3338

    
3339
        /* If we are rexecuting a branch due to exceptions on
3340
           delay slots dont break.  */
3341
        if (!(tb->pc & 1) && cs->singlestep_enabled) {
3342
            break;
3343
        }
3344
    } while (!dc->is_jmp && !dc->cpustate_changed
3345
            && tcg_ctx.gen_opc_ptr < gen_opc_end
3346
            && !singlestep
3347
            && (dc->pc < next_page_start)
3348
            && num_insns < max_insns);
3349

    
3350
    if (dc->clear_locked_irq) {
3351
        t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3352
    }
3353

    
3354
    npc = dc->pc;
3355

    
3356
        if (tb->cflags & CF_LAST_IO)
3357
            gen_io_end();
3358
    /* Force an update if the per-tb cpu state has changed.  */
3359
    if (dc->is_jmp == DISAS_NEXT
3360
        && (dc->cpustate_changed || !dc->flagx_known
3361
        || (dc->flags_x != (tb->flags & X_FLAG)))) {
3362
        dc->is_jmp = DISAS_UPDATE;
3363
        tcg_gen_movi_tl(env_pc, npc);
3364
    }
3365
    /* Broken branch+delayslot sequence.  */
3366
    if (dc->delayed_branch == 1) {
3367
        /* Set env->dslot to the size of the branch insn.  */
3368
        t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3369
        cris_store_direct_jmp(dc);
3370
    }
3371

    
3372
    cris_evaluate_flags(dc);
3373

    
3374
    if (unlikely(cs->singlestep_enabled)) {
3375
        if (dc->is_jmp == DISAS_NEXT) {
3376
            tcg_gen_movi_tl(env_pc, npc);
3377
        }
3378
        t_gen_raise_exception(EXCP_DEBUG);
3379
    } else {
3380
        switch (dc->is_jmp) {
3381
        case DISAS_NEXT:
3382
            gen_goto_tb(dc, 1, npc);
3383
            break;
3384
        default:
3385
        case DISAS_JUMP:
3386
        case DISAS_UPDATE:
3387
            /* indicate that the hash table must be used
3388
                   to find the next TB */
3389
            tcg_gen_exit_tb(0);
3390
            break;
3391
        case DISAS_SWI:
3392
        case DISAS_TB_JUMP:
3393
            /* nothing more to generate */
3394
            break;
3395
        }
3396
    }
3397
    gen_tb_end(tb, num_insns);
3398
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3399
    if (search_pc) {
3400
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3401
        lj++;
3402
        while (lj <= j) {
3403
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
3404
        }
3405
    } else {
3406
        tb->size = dc->pc - pc_start;
3407
        tb->icount = num_insns;
3408
    }
3409

    
3410
#ifdef DEBUG_DISAS
3411
#if !DISAS_CRIS
3412
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3413
        log_target_disas(env, pc_start, dc->pc - pc_start,
3414
                                 dc->env->pregs[PR_VR]);
3415
        qemu_log("\nisize=%d osize=%td\n",
3416
            dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf);
3417
    }
3418
#endif
3419
#endif
3420
}
3421

    
3422
void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
3423
{
3424
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
3425
}
3426

    
3427
void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
3428
{
3429
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
3430
}
3431

    
3432
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
3433
                         int flags)
3434
{
3435
    CRISCPU *cpu = CRIS_CPU(cs);
3436
    CPUCRISState *env = &cpu->env;
3437
    int i;
3438
    uint32_t srs;
3439

    
3440
    if (!env || !f) {
3441
        return;
3442
    }
3443

    
3444
    cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3445
            "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3446
            env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3447
            env->cc_op,
3448
            env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3449

    
3450

    
3451
    for (i = 0; i < 16; i++) {
3452
        cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3453
        if ((i + 1) % 4 == 0) {
3454
            cpu_fprintf(f, "\n");
3455
        }
3456
    }
3457
    cpu_fprintf(f, "\nspecial regs:\n");
3458
    for (i = 0; i < 16; i++) {
3459
        cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3460
        if ((i + 1) % 4 == 0) {
3461
            cpu_fprintf(f, "\n");
3462
        }
3463
    }
3464
    srs = env->pregs[PR_SRS];
3465
    cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3466
    if (srs < ARRAY_SIZE(env->sregs)) {
3467
        for (i = 0; i < 16; i++) {
3468
            cpu_fprintf(f, "s%2.2d=%8.8x ",
3469
                    i, env->sregs[srs][i]);
3470
            if ((i + 1) % 4 == 0) {
3471
                cpu_fprintf(f, "\n");
3472
            }
3473
        }
3474
    }
3475
    cpu_fprintf(f, "\n\n");
3476

    
3477
}
3478

    
3479
void cris_initialize_tcg(void)
3480
{
3481
    int i;
3482

    
3483
#define GEN_HELPER 2
3484
#include "helper.h"
3485

    
3486
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3487
    cc_x = tcg_global_mem_new(TCG_AREG0,
3488
                              offsetof(CPUCRISState, cc_x), "cc_x");
3489
    cc_src = tcg_global_mem_new(TCG_AREG0,
3490
                                offsetof(CPUCRISState, cc_src), "cc_src");
3491
    cc_dest = tcg_global_mem_new(TCG_AREG0,
3492
                                 offsetof(CPUCRISState, cc_dest),
3493
                                 "cc_dest");
3494
    cc_result = tcg_global_mem_new(TCG_AREG0,
3495
                                   offsetof(CPUCRISState, cc_result),
3496
                                   "cc_result");
3497
    cc_op = tcg_global_mem_new(TCG_AREG0,
3498
                               offsetof(CPUCRISState, cc_op), "cc_op");
3499
    cc_size = tcg_global_mem_new(TCG_AREG0,
3500
                                 offsetof(CPUCRISState, cc_size),
3501
                                 "cc_size");
3502
    cc_mask = tcg_global_mem_new(TCG_AREG0,
3503
                                 offsetof(CPUCRISState, cc_mask),
3504
                                 "cc_mask");
3505

    
3506
    env_pc = tcg_global_mem_new(TCG_AREG0,
3507
                                offsetof(CPUCRISState, pc),
3508
                                "pc");
3509
    env_btarget = tcg_global_mem_new(TCG_AREG0,
3510
                                     offsetof(CPUCRISState, btarget),
3511
                                     "btarget");
3512
    env_btaken = tcg_global_mem_new(TCG_AREG0,
3513
                                    offsetof(CPUCRISState, btaken),
3514
                                    "btaken");
3515
    for (i = 0; i < 16; i++) {
3516
        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3517
                                      offsetof(CPUCRISState, regs[i]),
3518
                                      regnames[i]);
3519
    }
3520
    for (i = 0; i < 16; i++) {
3521
        cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3522
                                       offsetof(CPUCRISState, pregs[i]),
3523
                                       pregnames[i]);
3524
    }
3525
}
3526

    
3527
void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
3528
{
3529
    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3530
}