Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 5d12aa63

History | View | Annotate | Download (93.1 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_ld_i64(dst, addr, mem_index, MO_TEQ);
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
    tcg_gen_qemu_ld_tl(dst, addr, mem_index,
1151
                       MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
1152
}
1153

    
1154
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1155
               unsigned int size)
1156
{
1157
    int mem_index = cpu_mmu_index(dc->env);
1158

    
1159
    /* If we get a fault on a delayslot we must keep the jmp state in
1160
       the cpu-state to be able to re-execute the jmp.  */
1161
    if (dc->delayed_branch == 1) {
1162
        cris_store_direct_jmp(dc);
1163
    }
1164

    
1165

    
1166
    /* Conditional writes. We only support the kind were X and P are known
1167
       at translation time.  */
1168
    if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1169
        dc->postinc = 0;
1170
        cris_evaluate_flags(dc);
1171
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1172
        return;
1173
    }
1174

    
1175
    tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
1176

    
1177
    if (dc->flagx_known && dc->flags_x) {
1178
        cris_evaluate_flags(dc);
1179
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1180
    }
1181
}
1182

    
1183
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1184
{
1185
    if (size == 1) {
1186
        tcg_gen_ext8s_i32(d, s);
1187
    } else if (size == 2) {
1188
        tcg_gen_ext16s_i32(d, s);
1189
    } else if (!TCGV_EQUAL(d, s)) {
1190
        tcg_gen_mov_tl(d, s);
1191
    }
1192
}
1193

    
1194
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1195
{
1196
    if (size == 1) {
1197
        tcg_gen_ext8u_i32(d, s);
1198
    } else if (size == 2) {
1199
        tcg_gen_ext16u_i32(d, s);
1200
    } else if (!TCGV_EQUAL(d, s)) {
1201
        tcg_gen_mov_tl(d, s);
1202
    }
1203
}
1204

    
1205
#if DISAS_CRIS
1206
static char memsize_char(int size)
1207
{
1208
    switch (size) {
1209
    case 1: return 'b';  break;
1210
    case 2: return 'w';  break;
1211
    case 4: return 'd';  break;
1212
    default:
1213
        return 'x';
1214
        break;
1215
    }
1216
}
1217
#endif
1218

    
1219
static inline unsigned int memsize_z(DisasContext *dc)
1220
{
1221
    return dc->zsize + 1;
1222
}
1223

    
1224
static inline unsigned int memsize_zz(DisasContext *dc)
1225
{
1226
    switch (dc->zzsize) {
1227
    case 0: return 1;
1228
    case 1: return 2;
1229
    default:
1230
        return 4;
1231
    }
1232
}
1233

    
1234
static inline void do_postinc (DisasContext *dc, int size)
1235
{
1236
    if (dc->postinc) {
1237
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1238
    }
1239
}
1240

    
1241
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1242
                   int size, int s_ext, TCGv dst)
1243
{
1244
    if (s_ext) {
1245
        t_gen_sext(dst, cpu_R[rs], size);
1246
    } else {
1247
        t_gen_zext(dst, cpu_R[rs], size);
1248
    }
1249
}
1250

    
1251
/* Prepare T0 and T1 for a register alu operation.
1252
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1253
   needed.  */
1254
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1255
              int size, int s_ext, TCGv dst, TCGv src)
1256
{
1257
    dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1258

    
1259
    if (s_ext) {
1260
        t_gen_sext(dst, cpu_R[rd], size);
1261
    } else {
1262
        t_gen_zext(dst, cpu_R[rd], size);
1263
    }
1264
}
1265

    
1266
static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1267
                           int s_ext, int memsize, TCGv dst)
1268
{
1269
    unsigned int rs;
1270
    uint32_t imm;
1271
    int is_imm;
1272
    int insn_len = 2;
1273

    
1274
    rs = dc->op1;
1275
    is_imm = rs == 15 && dc->postinc;
1276

    
1277
    /* Load [$rs] onto T1.  */
1278
    if (is_imm) {
1279
        insn_len = 2 + memsize;
1280
        if (memsize == 1) {
1281
            insn_len++;
1282
        }
1283

    
1284
        imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1285
        tcg_gen_movi_tl(dst, imm);
1286
        dc->postinc = 0;
1287
    } else {
1288
        cris_flush_cc_state(dc);
1289
        gen_load(dc, dst, cpu_R[rs], memsize, 0);
1290
        if (s_ext) {
1291
            t_gen_sext(dst, dst, memsize);
1292
        } else {
1293
            t_gen_zext(dst, dst, memsize);
1294
        }
1295
    }
1296
    return insn_len;
1297
}
1298

    
1299
/* Prepare T0 and T1 for a memory + alu operation.
1300
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1301
   needed.  */
1302
static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1303
                          int s_ext, int memsize, TCGv dst, TCGv src)
1304
{
1305
    int insn_len;
1306

    
1307
    insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1308
    tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1309
    return insn_len;
1310
}
1311

    
1312
#if DISAS_CRIS
1313
static const char *cc_name(int cc)
1314
{
1315
    static const char *cc_names[16] = {
1316
        "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1317
        "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1318
    };
1319
    assert(cc < 16);
1320
    return cc_names[cc];
1321
}
1322
#endif
1323

    
1324
/* Start of insn decoders.  */
1325

    
1326
static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1327
{
1328
    int32_t offset;
1329
    int sign;
1330
    uint32_t cond = dc->op2;
1331

    
1332
    offset = EXTRACT_FIELD(dc->ir, 1, 7);
1333
    sign = EXTRACT_FIELD(dc->ir, 0, 0);
1334

    
1335
    offset *= 2;
1336
    offset |= sign << 8;
1337
    offset = sign_extend(offset, 8);
1338

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

    
1341
    /* op2 holds the condition-code.  */
1342
    cris_cc_mask(dc, 0);
1343
    cris_prepare_cc_branch(dc, offset, cond);
1344
    return 2;
1345
}
1346
static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1347
{
1348
    int32_t imm;
1349

    
1350
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1351
    imm = sign_extend(dc->op1, 7);
1352

    
1353
    LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1354
    cris_cc_mask(dc, 0);
1355
    /* Fetch register operand,  */
1356
    tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1357

    
1358
    return 2;
1359
}
1360
static int dec_addq(CPUCRISState *env, DisasContext *dc)
1361
{
1362
    LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1363

    
1364
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1365

    
1366
    cris_cc_mask(dc, CC_MASK_NZVC);
1367

    
1368
    cris_alu(dc, CC_OP_ADD,
1369
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1370
    return 2;
1371
}
1372
static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1373
{
1374
    uint32_t imm;
1375

    
1376
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1377
    imm = sign_extend(dc->op1, 5);
1378
    LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1379

    
1380
    tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1381
    return 2;
1382
}
1383
static int dec_subq(CPUCRISState *env, DisasContext *dc)
1384
{
1385
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1386

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

    
1389
    cris_cc_mask(dc, CC_MASK_NZVC);
1390
    cris_alu(dc, CC_OP_SUB,
1391
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1392
    return 2;
1393
}
1394
static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1395
{
1396
    uint32_t imm;
1397
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1398
    imm = sign_extend(dc->op1, 5);
1399

    
1400
    LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1401
    cris_cc_mask(dc, CC_MASK_NZVC);
1402

    
1403
    cris_alu(dc, CC_OP_CMP,
1404
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1405
    return 2;
1406
}
1407
static int dec_andq(CPUCRISState *env, DisasContext *dc)
1408
{
1409
    uint32_t imm;
1410
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1411
    imm = sign_extend(dc->op1, 5);
1412

    
1413
    LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1414
    cris_cc_mask(dc, CC_MASK_NZ);
1415

    
1416
    cris_alu(dc, CC_OP_AND,
1417
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1418
    return 2;
1419
}
1420
static int dec_orq(CPUCRISState *env, DisasContext *dc)
1421
{
1422
    uint32_t imm;
1423
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1424
    imm = sign_extend(dc->op1, 5);
1425
    LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1426
    cris_cc_mask(dc, CC_MASK_NZ);
1427

    
1428
    cris_alu(dc, CC_OP_OR,
1429
            cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1430
    return 2;
1431
}
1432
static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1433
{
1434
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1435
    LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1436

    
1437
    cris_cc_mask(dc, CC_MASK_NZ);
1438
    cris_evaluate_flags(dc);
1439
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1440
            tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1441
    cris_alu(dc, CC_OP_MOVE,
1442
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1443
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1444
    dc->flags_uptodate = 1;
1445
    return 2;
1446
}
1447
static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1448
{
1449
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1450
    LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1451
    cris_cc_mask(dc, CC_MASK_NZ);
1452

    
1453
    tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1454
    cris_alu(dc, CC_OP_MOVE,
1455
            cpu_R[dc->op2],
1456
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1457
    return 2;
1458
}
1459
static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1460
{
1461
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1462
    LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1463

    
1464
    cris_cc_mask(dc, CC_MASK_NZ);
1465

    
1466
    tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1467

    
1468
    cris_alu(dc, CC_OP_MOVE,
1469
            cpu_R[dc->op2],
1470
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1471
    return 2;
1472
}
1473
static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1474
{
1475
    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1476
    LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1477

    
1478
    cris_cc_mask(dc, CC_MASK_NZ);
1479

    
1480
    tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1481
    cris_alu(dc, CC_OP_MOVE,
1482
            cpu_R[dc->op2],
1483
            cpu_R[dc->op2], cpu_R[dc->op2], 4);
1484
    return 2;
1485
}
1486

    
1487
static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1488
{
1489
    int size = memsize_zz(dc);
1490

    
1491
    LOG_DIS("move.%c $r%u, $r%u\n",
1492
            memsize_char(size), dc->op1, dc->op2);
1493

    
1494
    cris_cc_mask(dc, CC_MASK_NZ);
1495
    if (size == 4) {
1496
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1497
        cris_cc_mask(dc, CC_MASK_NZ);
1498
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
1499
        cris_update_cc_x(dc);
1500
        cris_update_result(dc, cpu_R[dc->op2]);
1501
    } else {
1502
        TCGv t0;
1503

    
1504
        t0 = tcg_temp_new();
1505
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1506
        cris_alu(dc, CC_OP_MOVE,
1507
             cpu_R[dc->op2],
1508
             cpu_R[dc->op2], t0, size);
1509
        tcg_temp_free(t0);
1510
    }
1511
    return 2;
1512
}
1513

    
1514
static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1515
{
1516
    int cond = dc->op2;
1517

    
1518
    LOG_DIS("s%s $r%u\n",
1519
            cc_name(cond), dc->op1);
1520

    
1521
    if (cond != CC_A) {
1522
        int l1;
1523

    
1524
        gen_tst_cc(dc, cpu_R[dc->op1], cond);
1525
        l1 = gen_new_label();
1526
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1527
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1528
        gen_set_label(l1);
1529
    } else {
1530
        tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1531
    }
1532

    
1533
    cris_cc_mask(dc, 0);
1534
    return 2;
1535
}
1536

    
1537
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1538
{
1539
    if (size == 4) {
1540
        t[0] = cpu_R[dc->op2];
1541
        t[1] = cpu_R[dc->op1];
1542
    } else {
1543
        t[0] = tcg_temp_new();
1544
        t[1] = tcg_temp_new();
1545
    }
1546
}
1547

    
1548
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1549
{
1550
    if (size != 4) {
1551
        tcg_temp_free(t[0]);
1552
        tcg_temp_free(t[1]);
1553
    }
1554
}
1555

    
1556
static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1557
{
1558
    TCGv t[2];
1559
    int size = memsize_zz(dc);
1560

    
1561
    LOG_DIS("and.%c $r%u, $r%u\n",
1562
            memsize_char(size), dc->op1, dc->op2);
1563

    
1564
    cris_cc_mask(dc, CC_MASK_NZ);
1565

    
1566
    cris_alu_alloc_temps(dc, size, t);
1567
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1568
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1569
    cris_alu_free_temps(dc, size, t);
1570
    return 2;
1571
}
1572

    
1573
static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1574
{
1575
    TCGv t0;
1576
    LOG_DIS("lz $r%u, $r%u\n",
1577
            dc->op1, dc->op2);
1578
    cris_cc_mask(dc, CC_MASK_NZ);
1579
    t0 = tcg_temp_new();
1580
    dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1581
    cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1582
    tcg_temp_free(t0);
1583
    return 2;
1584
}
1585

    
1586
static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1587
{
1588
    TCGv t[2];
1589
    int size = memsize_zz(dc);
1590

    
1591
    LOG_DIS("lsl.%c $r%u, $r%u\n",
1592
            memsize_char(size), dc->op1, dc->op2);
1593

    
1594
    cris_cc_mask(dc, CC_MASK_NZ);
1595
    cris_alu_alloc_temps(dc, size, t);
1596
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1597
    tcg_gen_andi_tl(t[1], t[1], 63);
1598
    cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1599
    cris_alu_alloc_temps(dc, size, t);
1600
    return 2;
1601
}
1602

    
1603
static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1604
{
1605
    TCGv t[2];
1606
    int size = memsize_zz(dc);
1607

    
1608
    LOG_DIS("lsr.%c $r%u, $r%u\n",
1609
            memsize_char(size), dc->op1, dc->op2);
1610

    
1611
    cris_cc_mask(dc, CC_MASK_NZ);
1612
    cris_alu_alloc_temps(dc, size, t);
1613
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1614
    tcg_gen_andi_tl(t[1], t[1], 63);
1615
    cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1616
    cris_alu_free_temps(dc, size, t);
1617
    return 2;
1618
}
1619

    
1620
static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1621
{
1622
    TCGv t[2];
1623
    int size = memsize_zz(dc);
1624

    
1625
    LOG_DIS("asr.%c $r%u, $r%u\n",
1626
            memsize_char(size), dc->op1, dc->op2);
1627

    
1628
    cris_cc_mask(dc, CC_MASK_NZ);
1629
    cris_alu_alloc_temps(dc, size, t);
1630
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1631
    tcg_gen_andi_tl(t[1], t[1], 63);
1632
    cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1633
    cris_alu_free_temps(dc, size, t);
1634
    return 2;
1635
}
1636

    
1637
static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1638
{
1639
    TCGv t[2];
1640
    int size = memsize_zz(dc);
1641

    
1642
    LOG_DIS("muls.%c $r%u, $r%u\n",
1643
            memsize_char(size), dc->op1, dc->op2);
1644
    cris_cc_mask(dc, CC_MASK_NZV);
1645
    cris_alu_alloc_temps(dc, size, t);
1646
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1647

    
1648
    cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1649
    cris_alu_free_temps(dc, size, t);
1650
    return 2;
1651
}
1652

    
1653
static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1654
{
1655
    TCGv t[2];
1656
    int size = memsize_zz(dc);
1657

    
1658
    LOG_DIS("mulu.%c $r%u, $r%u\n",
1659
            memsize_char(size), dc->op1, dc->op2);
1660
    cris_cc_mask(dc, CC_MASK_NZV);
1661
    cris_alu_alloc_temps(dc, size, t);
1662
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1663

    
1664
    cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1665
    cris_alu_alloc_temps(dc, size, t);
1666
    return 2;
1667
}
1668

    
1669

    
1670
static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1671
{
1672
    LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1673
    cris_cc_mask(dc, CC_MASK_NZ);
1674
    cris_alu(dc, CC_OP_DSTEP,
1675
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1676
    return 2;
1677
}
1678

    
1679
static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1680
{
1681
    TCGv t[2];
1682
    int size = memsize_zz(dc);
1683
    LOG_DIS("xor.%c $r%u, $r%u\n",
1684
            memsize_char(size), dc->op1, dc->op2);
1685
    BUG_ON(size != 4); /* xor is dword.  */
1686
    cris_cc_mask(dc, CC_MASK_NZ);
1687
    cris_alu_alloc_temps(dc, size, t);
1688
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1689

    
1690
    cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1691
    cris_alu_free_temps(dc, size, t);
1692
    return 2;
1693
}
1694

    
1695
static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1696
{
1697
    TCGv l0;
1698
    int size = memsize_zz(dc);
1699
    LOG_DIS("bound.%c $r%u, $r%u\n",
1700
            memsize_char(size), dc->op1, dc->op2);
1701
    cris_cc_mask(dc, CC_MASK_NZ);
1702
    l0 = tcg_temp_local_new();
1703
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1704
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1705
    tcg_temp_free(l0);
1706
    return 2;
1707
}
1708

    
1709
static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1710
{
1711
    TCGv t[2];
1712
    int size = memsize_zz(dc);
1713
    LOG_DIS("cmp.%c $r%u, $r%u\n",
1714
            memsize_char(size), dc->op1, dc->op2);
1715
    cris_cc_mask(dc, CC_MASK_NZVC);
1716
    cris_alu_alloc_temps(dc, size, t);
1717
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1718

    
1719
    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1720
    cris_alu_free_temps(dc, size, t);
1721
    return 2;
1722
}
1723

    
1724
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1725
{
1726
    TCGv t0;
1727

    
1728
    LOG_DIS("abs $r%u, $r%u\n",
1729
            dc->op1, dc->op2);
1730
    cris_cc_mask(dc, CC_MASK_NZ);
1731

    
1732
    t0 = tcg_temp_new();
1733
    tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1734
    tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1735
    tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1736
    tcg_temp_free(t0);
1737

    
1738
    cris_alu(dc, CC_OP_MOVE,
1739
            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1740
    return 2;
1741
}
1742

    
1743
static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1744
{
1745
    TCGv t[2];
1746
    int size = memsize_zz(dc);
1747
    LOG_DIS("add.%c $r%u, $r%u\n",
1748
            memsize_char(size), dc->op1, dc->op2);
1749
    cris_cc_mask(dc, CC_MASK_NZVC);
1750
    cris_alu_alloc_temps(dc, size, t);
1751
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1752

    
1753
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1754
    cris_alu_free_temps(dc, size, t);
1755
    return 2;
1756
}
1757

    
1758
static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1759
{
1760
    LOG_DIS("addc $r%u, $r%u\n",
1761
            dc->op1, dc->op2);
1762
    cris_evaluate_flags(dc);
1763
    /* Set for this insn.  */
1764
    dc->flagx_known = 1;
1765
    dc->flags_x = X_FLAG;
1766

    
1767
    cris_cc_mask(dc, CC_MASK_NZVC);
1768
    cris_alu(dc, CC_OP_ADDC,
1769
         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1770
    return 2;
1771
}
1772

    
1773
static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1774
{
1775
    LOG_DIS("mcp $p%u, $r%u\n",
1776
             dc->op2, dc->op1);
1777
    cris_evaluate_flags(dc);
1778
    cris_cc_mask(dc, CC_MASK_RNZV);
1779
    cris_alu(dc, CC_OP_MCP,
1780
            cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1781
    return 2;
1782
}
1783

    
1784
#if DISAS_CRIS
1785
static char * swapmode_name(int mode, char *modename) {
1786
    int i = 0;
1787
    if (mode & 8) {
1788
        modename[i++] = 'n';
1789
    }
1790
    if (mode & 4) {
1791
        modename[i++] = 'w';
1792
    }
1793
    if (mode & 2) {
1794
        modename[i++] = 'b';
1795
    }
1796
    if (mode & 1) {
1797
        modename[i++] = 'r';
1798
    }
1799
    modename[i++] = 0;
1800
    return modename;
1801
}
1802
#endif
1803

    
1804
static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1805
{
1806
    TCGv t0;
1807
#if DISAS_CRIS
1808
    char modename[4];
1809
#endif
1810
    LOG_DIS("swap%s $r%u\n",
1811
             swapmode_name(dc->op2, modename), dc->op1);
1812

    
1813
    cris_cc_mask(dc, CC_MASK_NZ);
1814
    t0 = tcg_temp_new();
1815
    t_gen_mov_TN_reg(t0, dc->op1);
1816
    if (dc->op2 & 8) {
1817
        tcg_gen_not_tl(t0, t0);
1818
    }
1819
    if (dc->op2 & 4) {
1820
        t_gen_swapw(t0, t0);
1821
    }
1822
    if (dc->op2 & 2) {
1823
        t_gen_swapb(t0, t0);
1824
    }
1825
    if (dc->op2 & 1) {
1826
        t_gen_swapr(t0, t0);
1827
    }
1828
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1829
    tcg_temp_free(t0);
1830
    return 2;
1831
}
1832

    
1833
static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1834
{
1835
    TCGv t[2];
1836
    int size = memsize_zz(dc);
1837
    LOG_DIS("or.%c $r%u, $r%u\n",
1838
            memsize_char(size), dc->op1, dc->op2);
1839
    cris_cc_mask(dc, CC_MASK_NZ);
1840
    cris_alu_alloc_temps(dc, size, t);
1841
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1842
    cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1843
    cris_alu_free_temps(dc, size, t);
1844
    return 2;
1845
}
1846

    
1847
static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1848
{
1849
    TCGv t0;
1850
    LOG_DIS("addi.%c $r%u, $r%u\n",
1851
            memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1852
    cris_cc_mask(dc, 0);
1853
    t0 = tcg_temp_new();
1854
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1855
    tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1856
    tcg_temp_free(t0);
1857
    return 2;
1858
}
1859

    
1860
static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1861
{
1862
    TCGv t0;
1863
    LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1864
          memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1865
    cris_cc_mask(dc, 0);
1866
    t0 = tcg_temp_new();
1867
    tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1868
    tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1869
    tcg_temp_free(t0);
1870
    return 2;
1871
}
1872

    
1873
static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1874
{
1875
    TCGv t[2];
1876
    int size = memsize_zz(dc);
1877
    LOG_DIS("neg.%c $r%u, $r%u\n",
1878
            memsize_char(size), dc->op1, dc->op2);
1879
    cris_cc_mask(dc, CC_MASK_NZVC);
1880
    cris_alu_alloc_temps(dc, size, t);
1881
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1882

    
1883
    cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1884
    cris_alu_free_temps(dc, size, t);
1885
    return 2;
1886
}
1887

    
1888
static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1889
{
1890
    LOG_DIS("btst $r%u, $r%u\n",
1891
            dc->op1, dc->op2);
1892
    cris_cc_mask(dc, CC_MASK_NZ);
1893
    cris_evaluate_flags(dc);
1894
        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
1895
            cpu_R[dc->op1], cpu_PR[PR_CCS]);
1896
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1897
         cpu_R[dc->op2], cpu_R[dc->op2], 4);
1898
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1899
    dc->flags_uptodate = 1;
1900
    return 2;
1901
}
1902

    
1903
static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1904
{
1905
    TCGv t[2];
1906
    int size = memsize_zz(dc);
1907
    LOG_DIS("sub.%c $r%u, $r%u\n",
1908
            memsize_char(size), dc->op1, dc->op2);
1909
    cris_cc_mask(dc, CC_MASK_NZVC);
1910
    cris_alu_alloc_temps(dc, size, t);
1911
    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1912
    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1913
    cris_alu_free_temps(dc, size, t);
1914
    return 2;
1915
}
1916

    
1917
/* Zero extension. From size to dword.  */
1918
static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1919
{
1920
    TCGv t0;
1921
    int size = memsize_z(dc);
1922
    LOG_DIS("movu.%c $r%u, $r%u\n",
1923
            memsize_char(size),
1924
            dc->op1, dc->op2);
1925

    
1926
    cris_cc_mask(dc, CC_MASK_NZ);
1927
    t0 = tcg_temp_new();
1928
    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1929
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1930
    tcg_temp_free(t0);
1931
    return 2;
1932
}
1933

    
1934
/* Sign extension. From size to dword.  */
1935
static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1936
{
1937
    TCGv t0;
1938
    int size = memsize_z(dc);
1939
    LOG_DIS("movs.%c $r%u, $r%u\n",
1940
            memsize_char(size),
1941
            dc->op1, dc->op2);
1942

    
1943
    cris_cc_mask(dc, CC_MASK_NZ);
1944
    t0 = tcg_temp_new();
1945
    /* Size can only be qi or hi.  */
1946
    t_gen_sext(t0, cpu_R[dc->op1], size);
1947
    cris_alu(dc, CC_OP_MOVE,
1948
            cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1949
    tcg_temp_free(t0);
1950
    return 2;
1951
}
1952

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

    
1962
    cris_cc_mask(dc, CC_MASK_NZVC);
1963
    t0 = tcg_temp_new();
1964
    /* Size can only be qi or hi.  */
1965
    t_gen_zext(t0, cpu_R[dc->op1], size);
1966
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1967
    tcg_temp_free(t0);
1968
    return 2;
1969
}
1970

    
1971
/* Sign extension. From size to dword.  */
1972
static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1973
{
1974
    TCGv t0;
1975
    int size = memsize_z(dc);
1976
    LOG_DIS("adds.%c $r%u, $r%u\n",
1977
            memsize_char(size),
1978
            dc->op1, dc->op2);
1979

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

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

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

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

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

    
2028
static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
2029
{
2030
    uint32_t flags;
2031
    int set = (~dc->opcode >> 2) & 1;
2032

    
2033

    
2034
    flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2035
        | EXTRACT_FIELD(dc->ir, 0, 3);
2036
    if (set && flags == 0) {
2037
        LOG_DIS("nop\n");
2038
        return 2;
2039
    } else if (!set && (flags & 0x20)) {
2040
        LOG_DIS("di\n");
2041
    } else {
2042
        LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
2043
    }
2044

    
2045
    /* User space is not allowed to touch these. Silently ignore.  */
2046
    if (dc->tb_flags & U_FLAG) {
2047
        flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2048
    }
2049

    
2050
    if (flags & X_FLAG) {
2051
        dc->flagx_known = 1;
2052
        if (set) {
2053
            dc->flags_x = X_FLAG;
2054
        } else {
2055
            dc->flags_x = 0;
2056
        }
2057
    }
2058

    
2059
    /* Break the TB if any of the SPI flag changes.  */
2060
    if (flags & (P_FLAG | S_FLAG)) {
2061
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2062
        dc->is_jmp = DISAS_UPDATE;
2063
        dc->cpustate_changed = 1;
2064
    }
2065

    
2066
    /* For the I flag, only act on posedge.  */
2067
    if ((flags & I_FLAG)) {
2068
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2069
        dc->is_jmp = DISAS_UPDATE;
2070
        dc->cpustate_changed = 1;
2071
    }
2072

    
2073

    
2074
    /* Simply decode the flags.  */
2075
    cris_evaluate_flags(dc);
2076
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2077
    cris_update_cc_x(dc);
2078
    tcg_gen_movi_tl(cc_op, dc->cc_op);
2079

    
2080
    if (set) {
2081
        if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2082
            /* Enter user mode.  */
2083
            t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2084
            tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2085
            dc->cpustate_changed = 1;
2086
        }
2087
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2088
    } else {
2089
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2090
    }
2091

    
2092
    dc->flags_uptodate = 1;
2093
    dc->clear_x = 0;
2094
    return 2;
2095
}
2096

    
2097
static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
2098
{
2099
    LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2100
    cris_cc_mask(dc, 0);
2101
        gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
2102
                                 tcg_const_tl(dc->op1));
2103
    return 2;
2104
}
2105
static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
2106
{
2107
    LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2108
    cris_cc_mask(dc, 0);
2109
        gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
2110
                                 tcg_const_tl(dc->op2));
2111
    return 2;
2112
}
2113

    
2114
static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
2115
{
2116
    TCGv t[2];
2117
    LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2118
    cris_cc_mask(dc, 0);
2119

    
2120
    t[0] = tcg_temp_new();
2121
    if (dc->op2 == PR_CCS) {
2122
        cris_evaluate_flags(dc);
2123
        t_gen_mov_TN_reg(t[0], dc->op1);
2124
        if (dc->tb_flags & U_FLAG) {
2125
            t[1] = tcg_temp_new();
2126
            /* User space is not allowed to touch all flags.  */
2127
            tcg_gen_andi_tl(t[0], t[0], 0x39f);
2128
            tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2129
            tcg_gen_or_tl(t[0], t[1], t[0]);
2130
            tcg_temp_free(t[1]);
2131
        }
2132
    } else {
2133
        t_gen_mov_TN_reg(t[0], dc->op1);
2134
    }
2135

    
2136
    t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2137
    if (dc->op2 == PR_CCS) {
2138
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2139
        dc->flags_uptodate = 1;
2140
    }
2141
    tcg_temp_free(t[0]);
2142
    return 2;
2143
}
2144
static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
2145
{
2146
    TCGv t0;
2147
    LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2148
    cris_cc_mask(dc, 0);
2149

    
2150
    if (dc->op2 == PR_CCS) {
2151
        cris_evaluate_flags(dc);
2152
    }
2153

    
2154
    if (dc->op2 == PR_DZ) {
2155
        tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2156
    } else {
2157
        t0 = tcg_temp_new();
2158
        t_gen_mov_TN_preg(t0, dc->op2);
2159
        cris_alu(dc, CC_OP_MOVE,
2160
                cpu_R[dc->op1], cpu_R[dc->op1], t0,
2161
                preg_sizes[dc->op2]);
2162
        tcg_temp_free(t0);
2163
    }
2164
    return 2;
2165
}
2166

    
2167
static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
2168
{
2169
    int memsize = memsize_zz(dc);
2170
    int insn_len;
2171
    LOG_DIS("move.%c [$r%u%s, $r%u\n",
2172
            memsize_char(memsize),
2173
            dc->op1, dc->postinc ? "+]" : "]",
2174
                    dc->op2);
2175

    
2176
    if (memsize == 4) {
2177
        insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2178
        cris_cc_mask(dc, CC_MASK_NZ);
2179
        cris_update_cc_op(dc, CC_OP_MOVE, 4);
2180
        cris_update_cc_x(dc);
2181
        cris_update_result(dc, cpu_R[dc->op2]);
2182
    } else {
2183
        TCGv t0;
2184

    
2185
        t0 = tcg_temp_new();
2186
        insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2187
        cris_cc_mask(dc, CC_MASK_NZ);
2188
        cris_alu(dc, CC_OP_MOVE,
2189
                cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2190
        tcg_temp_free(t0);
2191
    }
2192
    do_postinc(dc, memsize);
2193
    return insn_len;
2194
}
2195

    
2196
static inline void cris_alu_m_alloc_temps(TCGv *t)
2197
{
2198
    t[0] = tcg_temp_new();
2199
    t[1] = tcg_temp_new();
2200
}
2201

    
2202
static inline void cris_alu_m_free_temps(TCGv *t)
2203
{
2204
    tcg_temp_free(t[0]);
2205
    tcg_temp_free(t[1]);
2206
}
2207

    
2208
static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
2209
{
2210
    TCGv t[2];
2211
    int memsize = memsize_z(dc);
2212
    int insn_len;
2213
    LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2214
            memsize_char(memsize),
2215
            dc->op1, dc->postinc ? "+]" : "]",
2216
            dc->op2);
2217

    
2218
    cris_alu_m_alloc_temps(t);
2219
    /* sign extend.  */
2220
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2221
    cris_cc_mask(dc, CC_MASK_NZ);
2222
    cris_alu(dc, CC_OP_MOVE,
2223
            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2224
    do_postinc(dc, memsize);
2225
    cris_alu_m_free_temps(t);
2226
    return insn_len;
2227
}
2228

    
2229
static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
2230
{
2231
    TCGv t[2];
2232
    int memsize = memsize_z(dc);
2233
    int insn_len;
2234
    LOG_DIS("addu.%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, 0, memsize, t[0], t[1]);
2242
    cris_cc_mask(dc, CC_MASK_NZVC);
2243
    cris_alu(dc, CC_OP_ADD,
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_adds_m(CPUCRISState *env, DisasContext *dc)
2251
{
2252
    TCGv t[2];
2253
    int memsize = memsize_z(dc);
2254
    int insn_len;
2255
    LOG_DIS("adds.%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, 1, memsize, t[0], t[1]);
2263
    cris_cc_mask(dc, CC_MASK_NZVC);
2264
    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2265
    do_postinc(dc, memsize);
2266
    cris_alu_m_free_temps(t);
2267
    return insn_len;
2268
}
2269

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

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

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

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

    
2310
static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2311
{
2312
    TCGv t[2];
2313
    int memsize = memsize_z(dc);
2314
    int insn_len;
2315

    
2316
    LOG_DIS("movu.%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
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2323
    cris_cc_mask(dc, CC_MASK_NZ);
2324
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2325
    do_postinc(dc, memsize);
2326
    cris_alu_m_free_temps(t);
2327
    return insn_len;
2328
}
2329

    
2330
static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2331
{
2332
    TCGv t[2];
2333
    int memsize = memsize_z(dc);
2334
    int insn_len;
2335
    LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2336
            memsize_char(memsize),
2337
            dc->op1, dc->postinc ? "+]" : "]",
2338
            dc->op2);
2339

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

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

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

    
2370
static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
2371
{
2372
    TCGv t[2];
2373
    int memsize = memsize_zz(dc);
2374
    int insn_len;
2375
    LOG_DIS("cmp.%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, 0, 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_test_m(CPUCRISState *env, DisasContext *dc)
2392
{
2393
    TCGv t[2];
2394
    int memsize = memsize_zz(dc);
2395
    int insn_len;
2396
    LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2397
            memsize_char(memsize),
2398
            dc->op1, dc->postinc ? "+]" : "]",
2399
            dc->op2);
2400

    
2401
    cris_evaluate_flags(dc);
2402

    
2403
    cris_alu_m_alloc_temps(t);
2404
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2405
    cris_cc_mask(dc, CC_MASK_NZ);
2406
    tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2407

    
2408
    cris_alu(dc, CC_OP_CMP,
2409
         cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2410
    do_postinc(dc, memsize);
2411
    cris_alu_m_free_temps(t);
2412
    return insn_len;
2413
}
2414

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

    
2425
    cris_alu_m_alloc_temps(t);
2426
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2427
    cris_cc_mask(dc, CC_MASK_NZ);
2428
    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2429
    do_postinc(dc, memsize);
2430
    cris_alu_m_free_temps(t);
2431
    return insn_len;
2432
}
2433

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

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

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

    
2464
    cris_alu_m_alloc_temps(t);
2465
        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2466
    cris_cc_mask(dc, 0);
2467
    cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2468
    do_postinc(dc, memsize);
2469
    cris_alu_m_free_temps(t);
2470
    return insn_len;
2471
}
2472

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

    
2483
    l[0] = tcg_temp_local_new();
2484
    l[1] = tcg_temp_local_new();
2485
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2486
    cris_cc_mask(dc, CC_MASK_NZ);
2487
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2488
    do_postinc(dc, memsize);
2489
    tcg_temp_free(l[0]);
2490
    tcg_temp_free(l[1]);
2491
    return insn_len;
2492
}
2493

    
2494
static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2495
{
2496
    TCGv t[2];
2497
    int insn_len = 2;
2498
    LOG_DIS("addc [$r%u%s, $r%u\n",
2499
            dc->op1, dc->postinc ? "+]" : "]",
2500
            dc->op2);
2501

    
2502
    cris_evaluate_flags(dc);
2503

    
2504
    /* Set for this insn.  */
2505
    dc->flagx_known = 1;
2506
    dc->flags_x = X_FLAG;
2507

    
2508
    cris_alu_m_alloc_temps(t);
2509
        insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2510
    cris_cc_mask(dc, CC_MASK_NZVC);
2511
    cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2512
    do_postinc(dc, 4);
2513
    cris_alu_m_free_temps(t);
2514
    return insn_len;
2515
}
2516

    
2517
static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2518
{
2519
    TCGv t[2];
2520
    int memsize = memsize_zz(dc);
2521
    int insn_len;
2522
    LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2523
            memsize_char(memsize),
2524
            dc->op1, dc->postinc ? "+]" : "]",
2525
            dc->op2, dc->ir, dc->zzsize);
2526

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

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

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

    
2556
static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2557
{
2558
    TCGv t[2];
2559
    int memsize = memsize_zz(dc);
2560
    int insn_len = 2;
2561

    
2562
    LOG_DIS("move.%c [$r%u%s, $p%u\n",
2563
            memsize_char(memsize),
2564
            dc->op1,
2565
            dc->postinc ? "+]" : "]",
2566
            dc->op2);
2567

    
2568
    cris_alu_m_alloc_temps(t);
2569
        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2570
    cris_cc_mask(dc, 0);
2571
    if (dc->op2 == PR_CCS) {
2572
        cris_evaluate_flags(dc);
2573
        if (dc->tb_flags & U_FLAG) {
2574
            /* User space is not allowed to touch all flags.  */
2575
            tcg_gen_andi_tl(t[1], t[1], 0x39f);
2576
            tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2577
            tcg_gen_or_tl(t[1], t[0], t[1]);
2578
        }
2579
    }
2580

    
2581
    t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2582

    
2583
    do_postinc(dc, memsize);
2584
    cris_alu_m_free_temps(t);
2585
    return insn_len;
2586
}
2587

    
2588
static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2589
{
2590
    TCGv t0;
2591
    int memsize;
2592

    
2593
    memsize = preg_sizes[dc->op2];
2594

    
2595
    LOG_DIS("move.%c $p%u, [$r%u%s\n",
2596
            memsize_char(memsize),
2597
            dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2598

    
2599
    /* prepare store. Address in T0, value in T1.  */
2600
    if (dc->op2 == PR_CCS) {
2601
        cris_evaluate_flags(dc);
2602
    }
2603
    t0 = tcg_temp_new();
2604
    t_gen_mov_TN_preg(t0, dc->op2);
2605
    cris_flush_cc_state(dc);
2606
    gen_store(dc, cpu_R[dc->op1], t0, memsize);
2607
    tcg_temp_free(t0);
2608

    
2609
    cris_cc_mask(dc, 0);
2610
    if (dc->postinc) {
2611
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2612
    }
2613
    return 2;
2614
}
2615

    
2616
static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2617
{
2618
    TCGv_i64 tmp[16];
2619
    TCGv tmp32;
2620
    TCGv addr;
2621
    int i;
2622
    int nr = dc->op2 + 1;
2623

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

    
2627
    addr = tcg_temp_new();
2628
    /* There are probably better ways of doing this.  */
2629
    cris_flush_cc_state(dc);
2630
    for (i = 0; i < (nr >> 1); i++) {
2631
        tmp[i] = tcg_temp_new_i64();
2632
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2633
        gen_load64(dc, tmp[i], addr);
2634
    }
2635
    if (nr & 1) {
2636
        tmp32 = tcg_temp_new_i32();
2637
        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2638
        gen_load(dc, tmp32, addr, 4, 0);
2639
    } else {
2640
        TCGV_UNUSED(tmp32);
2641
    }
2642
    tcg_temp_free(addr);
2643

    
2644
    for (i = 0; i < (nr >> 1); i++) {
2645
        tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2646
        tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2647
        tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2648
        tcg_temp_free_i64(tmp[i]);
2649
    }
2650
    if (nr & 1) {
2651
        tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2652
        tcg_temp_free(tmp32);
2653
    }
2654

    
2655
    /* writeback the updated pointer value.  */
2656
    if (dc->postinc) {
2657
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2658
    }
2659

    
2660
    /* gen_load might want to evaluate the previous insns flags.  */
2661
    cris_cc_mask(dc, 0);
2662
    return 2;
2663
}
2664

    
2665
static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2666
{
2667
    TCGv tmp;
2668
    TCGv addr;
2669
    int i;
2670

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

    
2674
    cris_flush_cc_state(dc);
2675

    
2676
    tmp = tcg_temp_new();
2677
    addr = tcg_temp_new();
2678
    tcg_gen_movi_tl(tmp, 4);
2679
    tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2680
    for (i = 0; i <= dc->op2; i++) {
2681
        /* Displace addr.  */
2682
        /* Perform the store.  */
2683
        gen_store(dc, addr, cpu_R[i], 4);
2684
        tcg_gen_add_tl(addr, addr, tmp);
2685
    }
2686
    if (dc->postinc) {
2687
        tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2688
    }
2689
    cris_cc_mask(dc, 0);
2690
    tcg_temp_free(tmp);
2691
    tcg_temp_free(addr);
2692
    return 2;
2693
}
2694

    
2695
static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2696
{
2697
    int memsize;
2698

    
2699
    memsize = memsize_zz(dc);
2700

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

    
2704
    /* prepare store.  */
2705
    cris_flush_cc_state(dc);
2706
    gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2707

    
2708
    if (dc->postinc) {
2709
        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2710
    }
2711
    cris_cc_mask(dc, 0);
2712
    return 2;
2713
}
2714

    
2715
static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2716
{
2717
    LOG_DIS("lapcq %x, $r%u\n",
2718
            dc->pc + dc->op1*2, dc->op2);
2719
    cris_cc_mask(dc, 0);
2720
    tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2721
    return 2;
2722
}
2723

    
2724
static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2725
{
2726
    unsigned int rd;
2727
    int32_t imm;
2728
    int32_t pc;
2729

    
2730
    rd = dc->op2;
2731

    
2732
    cris_cc_mask(dc, 0);
2733
    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2734
    LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2735

    
2736
    pc = dc->pc;
2737
    pc += imm;
2738
    tcg_gen_movi_tl(cpu_R[rd], pc);
2739
    return 6;
2740
}
2741

    
2742
/* Jump to special reg.  */
2743
static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2744
{
2745
    LOG_DIS("jump $p%u\n", dc->op2);
2746

    
2747
    if (dc->op2 == PR_CCS) {
2748
        cris_evaluate_flags(dc);
2749
    }
2750
    t_gen_mov_TN_preg(env_btarget, dc->op2);
2751
    /* rete will often have low bit set to indicate delayslot.  */
2752
    tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2753
    cris_cc_mask(dc, 0);
2754
    cris_prepare_jmp(dc, JMP_INDIRECT);
2755
    return 2;
2756
}
2757

    
2758
/* Jump and save.  */
2759
static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2760
{
2761
    LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2762
    cris_cc_mask(dc, 0);
2763
    /* Store the return address in Pd.  */
2764
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2765
    if (dc->op2 > 15) {
2766
        abort();
2767
    }
2768
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2769

    
2770
    cris_prepare_jmp(dc, JMP_INDIRECT);
2771
    return 2;
2772
}
2773

    
2774
static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2775
{
2776
    uint32_t imm;
2777

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

    
2780
    LOG_DIS("jas 0x%x\n", imm);
2781
    cris_cc_mask(dc, 0);
2782
    /* Store the return address in Pd.  */
2783
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2784

    
2785
    dc->jmp_pc = imm;
2786
    cris_prepare_jmp(dc, JMP_DIRECT);
2787
    return 6;
2788
}
2789

    
2790
static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2791
{
2792
    uint32_t imm;
2793

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

    
2796
    LOG_DIS("jasc 0x%x\n", imm);
2797
    cris_cc_mask(dc, 0);
2798
    /* Store the return address in Pd.  */
2799
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2800

    
2801
    dc->jmp_pc = imm;
2802
    cris_prepare_jmp(dc, JMP_DIRECT);
2803
    return 6;
2804
}
2805

    
2806
static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2807
{
2808
    LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2809
    cris_cc_mask(dc, 0);
2810
    /* Store the return address in Pd.  */
2811
    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2812
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2813
    cris_prepare_jmp(dc, JMP_INDIRECT);
2814
    return 2;
2815
}
2816

    
2817
static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2818
{
2819
    int32_t offset;
2820
    uint32_t cond = dc->op2;
2821

    
2822
    offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2823

    
2824
    LOG_DIS("b%s %d pc=%x dst=%x\n",
2825
            cc_name(cond), offset,
2826
            dc->pc, dc->pc + offset);
2827

    
2828
    cris_cc_mask(dc, 0);
2829
    /* op2 holds the condition-code.  */
2830
    cris_prepare_cc_branch(dc, offset, cond);
2831
    return 4;
2832
}
2833

    
2834
static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2835
{
2836
    int32_t simm;
2837

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

    
2840
    LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2841
    cris_cc_mask(dc, 0);
2842
    /* Store the return address in Pd.  */
2843
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2844

    
2845
    dc->jmp_pc = dc->pc + simm;
2846
    cris_prepare_jmp(dc, JMP_DIRECT);
2847
    return 6;
2848
}
2849

    
2850
static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2851
{
2852
    int32_t simm;
2853
    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2854

    
2855
    LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2856
    cris_cc_mask(dc, 0);
2857
    /* Store the return address in Pd.  */
2858
    t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2859

    
2860
    dc->jmp_pc = dc->pc + simm;
2861
    cris_prepare_jmp(dc, JMP_DIRECT);
2862
    return 6;
2863
}
2864

    
2865
static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2866
{
2867
    cris_cc_mask(dc, 0);
2868

    
2869
    if (dc->op2 == 15) {
2870
        tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
2871
                       -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2872
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2873
        t_gen_raise_exception(EXCP_HLT);
2874
        return 2;
2875
    }
2876

    
2877
    switch (dc->op2 & 7) {
2878
    case 2:
2879
        /* rfe.  */
2880
        LOG_DIS("rfe\n");
2881
        cris_evaluate_flags(dc);
2882
        gen_helper_rfe(cpu_env);
2883
        dc->is_jmp = DISAS_UPDATE;
2884
        break;
2885
    case 5:
2886
        /* rfn.  */
2887
        LOG_DIS("rfn\n");
2888
        cris_evaluate_flags(dc);
2889
        gen_helper_rfn(cpu_env);
2890
        dc->is_jmp = DISAS_UPDATE;
2891
        break;
2892
    case 6:
2893
        LOG_DIS("break %d\n", dc->op1);
2894
        cris_evaluate_flags(dc);
2895
        /* break.  */
2896
        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2897

    
2898
        /* Breaks start at 16 in the exception vector.  */
2899
        t_gen_mov_env_TN(trap_vector,
2900
                tcg_const_tl(dc->op1 + 16));
2901
        t_gen_raise_exception(EXCP_BREAK);
2902
        dc->is_jmp = DISAS_UPDATE;
2903
        break;
2904
    default:
2905
        printf("op2=%x\n", dc->op2);
2906
        BUG();
2907
        break;
2908

    
2909
    }
2910
    return 2;
2911
}
2912

    
2913
static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2914
{
2915
    return 2;
2916
}
2917

    
2918
static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2919
{
2920
    return 2;
2921
}
2922

    
2923
static int dec_null(CPUCRISState *env, DisasContext *dc)
2924
{
2925
    printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2926
        dc->pc, dc->opcode, dc->op1, dc->op2);
2927
    fflush(NULL);
2928
    BUG();
2929
    return 2;
2930
}
2931

    
2932
static struct decoder_info {
2933
    struct {
2934
        uint32_t bits;
2935
        uint32_t mask;
2936
    };
2937
    int (*dec)(CPUCRISState *env, DisasContext *dc);
2938
} decinfo[] = {
2939
    /* Order matters here.  */
2940
    {DEC_MOVEQ, dec_moveq},
2941
    {DEC_BTSTQ, dec_btstq},
2942
    {DEC_CMPQ, dec_cmpq},
2943
    {DEC_ADDOQ, dec_addoq},
2944
    {DEC_ADDQ, dec_addq},
2945
    {DEC_SUBQ, dec_subq},
2946
    {DEC_ANDQ, dec_andq},
2947
    {DEC_ORQ, dec_orq},
2948
    {DEC_ASRQ, dec_asrq},
2949
    {DEC_LSLQ, dec_lslq},
2950
    {DEC_LSRQ, dec_lsrq},
2951
    {DEC_BCCQ, dec_bccq},
2952

    
2953
    {DEC_BCC_IM, dec_bcc_im},
2954
    {DEC_JAS_IM, dec_jas_im},
2955
    {DEC_JAS_R, dec_jas_r},
2956
    {DEC_JASC_IM, dec_jasc_im},
2957
    {DEC_JASC_R, dec_jasc_r},
2958
    {DEC_BAS_IM, dec_bas_im},
2959
    {DEC_BASC_IM, dec_basc_im},
2960
    {DEC_JUMP_P, dec_jump_p},
2961
    {DEC_LAPC_IM, dec_lapc_im},
2962
    {DEC_LAPCQ, dec_lapcq},
2963

    
2964
    {DEC_RFE_ETC, dec_rfe_etc},
2965
    {DEC_ADDC_MR, dec_addc_mr},
2966

    
2967
    {DEC_MOVE_MP, dec_move_mp},
2968
    {DEC_MOVE_PM, dec_move_pm},
2969
    {DEC_MOVEM_MR, dec_movem_mr},
2970
    {DEC_MOVEM_RM, dec_movem_rm},
2971
    {DEC_MOVE_PR, dec_move_pr},
2972
    {DEC_SCC_R, dec_scc_r},
2973
    {DEC_SETF, dec_setclrf},
2974
    {DEC_CLEARF, dec_setclrf},
2975

    
2976
    {DEC_MOVE_SR, dec_move_sr},
2977
    {DEC_MOVE_RP, dec_move_rp},
2978
    {DEC_SWAP_R, dec_swap_r},
2979
    {DEC_ABS_R, dec_abs_r},
2980
    {DEC_LZ_R, dec_lz_r},
2981
    {DEC_MOVE_RS, dec_move_rs},
2982
    {DEC_BTST_R, dec_btst_r},
2983
    {DEC_ADDC_R, dec_addc_r},
2984

    
2985
    {DEC_DSTEP_R, dec_dstep_r},
2986
    {DEC_XOR_R, dec_xor_r},
2987
    {DEC_MCP_R, dec_mcp_r},
2988
    {DEC_CMP_R, dec_cmp_r},
2989

    
2990
    {DEC_ADDI_R, dec_addi_r},
2991
    {DEC_ADDI_ACR, dec_addi_acr},
2992

    
2993
    {DEC_ADD_R, dec_add_r},
2994
    {DEC_SUB_R, dec_sub_r},
2995

    
2996
    {DEC_ADDU_R, dec_addu_r},
2997
    {DEC_ADDS_R, dec_adds_r},
2998
    {DEC_SUBU_R, dec_subu_r},
2999
    {DEC_SUBS_R, dec_subs_r},
3000
    {DEC_LSL_R, dec_lsl_r},
3001

    
3002
    {DEC_AND_R, dec_and_r},
3003
    {DEC_OR_R, dec_or_r},
3004
    {DEC_BOUND_R, dec_bound_r},
3005
    {DEC_ASR_R, dec_asr_r},
3006
    {DEC_LSR_R, dec_lsr_r},
3007

    
3008
    {DEC_MOVU_R, dec_movu_r},
3009
    {DEC_MOVS_R, dec_movs_r},
3010
    {DEC_NEG_R, dec_neg_r},
3011
    {DEC_MOVE_R, dec_move_r},
3012

    
3013
    {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3014
    {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3015

    
3016
    {DEC_MULS_R, dec_muls_r},
3017
    {DEC_MULU_R, dec_mulu_r},
3018

    
3019
    {DEC_ADDU_M, dec_addu_m},
3020
    {DEC_ADDS_M, dec_adds_m},
3021
    {DEC_SUBU_M, dec_subu_m},
3022
    {DEC_SUBS_M, dec_subs_m},
3023

    
3024
    {DEC_CMPU_M, dec_cmpu_m},
3025
    {DEC_CMPS_M, dec_cmps_m},
3026
    {DEC_MOVU_M, dec_movu_m},
3027
    {DEC_MOVS_M, dec_movs_m},
3028

    
3029
    {DEC_CMP_M, dec_cmp_m},
3030
    {DEC_ADDO_M, dec_addo_m},
3031
    {DEC_BOUND_M, dec_bound_m},
3032
    {DEC_ADD_M, dec_add_m},
3033
    {DEC_SUB_M, dec_sub_m},
3034
    {DEC_AND_M, dec_and_m},
3035
    {DEC_OR_M, dec_or_m},
3036
    {DEC_MOVE_RM, dec_move_rm},
3037
    {DEC_TEST_M, dec_test_m},
3038
    {DEC_MOVE_MR, dec_move_mr},
3039

    
3040
    {{0, 0}, dec_null}
3041
};
3042

    
3043
static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
3044
{
3045
    int insn_len = 2;
3046
    int i;
3047

    
3048
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3049
        tcg_gen_debug_insn_start(dc->pc);
3050
        }
3051

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

    
3055
    /* Now decode it.  */
3056
    dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3057
    dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3058
    dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3059
    dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3060
    dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3061
    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3062

    
3063
    /* Large switch for all insns.  */
3064
    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3065
        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
3066
            insn_len = decinfo[i].dec(env, dc);
3067
            break;
3068
        }
3069
    }
3070

    
3071
#if !defined(CONFIG_USER_ONLY)
3072
    /* Single-stepping ?  */
3073
    if (dc->tb_flags & S_FLAG) {
3074
        int l1;
3075

    
3076
        l1 = gen_new_label();
3077
        tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3078
        /* We treat SPC as a break with an odd trap vector.  */
3079
        cris_evaluate_flags(dc);
3080
        t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3081
        tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3082
        tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3083
        t_gen_raise_exception(EXCP_BREAK);
3084
        gen_set_label(l1);
3085
    }
3086
#endif
3087
    return insn_len;
3088
}
3089

    
3090
static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
3091
{
3092
    CPUBreakpoint *bp;
3093

    
3094
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3095
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3096
            if (bp->pc == dc->pc) {
3097
                cris_evaluate_flags(dc);
3098
                tcg_gen_movi_tl(env_pc, dc->pc);
3099
                t_gen_raise_exception(EXCP_DEBUG);
3100
                dc->is_jmp = DISAS_UPDATE;
3101
            }
3102
        }
3103
    }
3104
}
3105

    
3106
#include "translate_v10.c"
3107

    
3108
/*
3109
 * Delay slots on QEMU/CRIS.
3110
 *
3111
 * If an exception hits on a delayslot, the core will let ERP (the Exception
3112
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
3113
 * to give SW a hint that the exception actually hit on the dslot.
3114
 *
3115
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
3116
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
3117
 * simply there to let sw know there was an exception on a dslot.
3118
 *
3119
 * When the software returns from an exception, the branch will re-execute.
3120
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
3121
 * and the branch and delayslot dont share pages.
3122
 *
3123
 * The TB contaning the branch insn will set up env->btarget and evaluate 
3124
 * env->btaken. When the translation loop exits we will note that the branch 
3125
 * sequence is broken and let env->dslot be the size of the branch insn (those
3126
 * vary in length).
3127
 *
3128
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
3129
 * set). It will also expect to have env->dslot setup with the size of the 
3130
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
3131
 * will execute the dslot and take the branch, either to btarget or just one 
3132
 * insn ahead.
3133
 *
3134
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
3135
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
3136
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
3137
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
3138
 * masked off and we will reexecute the branch insn.
3139
 *
3140
 */
3141

    
3142
/* generate intermediate code for basic block 'tb'.  */
3143
static inline void
3144
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
3145
                               bool search_pc)
3146
{
3147
    CPUState *cs = CPU(cpu);
3148
    CPUCRISState *env = &cpu->env;
3149
    uint16_t *gen_opc_end;
3150
    uint32_t pc_start;
3151
    unsigned int insn_len;
3152
    int j, lj;
3153
    struct DisasContext ctx;
3154
    struct DisasContext *dc = &ctx;
3155
    uint32_t next_page_start;
3156
    target_ulong npc;
3157
    int num_insns;
3158
    int max_insns;
3159

    
3160
    if (env->pregs[PR_VR] == 32) {
3161
        dc->decoder = crisv32_decoder;
3162
        dc->clear_locked_irq = 0;
3163
    } else {
3164
        dc->decoder = crisv10_decoder;
3165
        dc->clear_locked_irq = 1;
3166
    }
3167

    
3168
    /* Odd PC indicates that branch is rexecuting due to exception in the
3169
     * delayslot, like in real hw.
3170
     */
3171
    pc_start = tb->pc & ~1;
3172
    dc->env = env;
3173
    dc->tb = tb;
3174

    
3175
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3176

    
3177
    dc->is_jmp = DISAS_NEXT;
3178
    dc->ppc = pc_start;
3179
    dc->pc = pc_start;
3180
    dc->singlestep_enabled = cs->singlestep_enabled;
3181
    dc->flags_uptodate = 1;
3182
    dc->flagx_known = 1;
3183
    dc->flags_x = tb->flags & X_FLAG;
3184
    dc->cc_x_uptodate = 0;
3185
    dc->cc_mask = 0;
3186
    dc->update_cc = 0;
3187
    dc->clear_prefix = 0;
3188

    
3189
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3190
    dc->cc_size_uptodate = -1;
3191

    
3192
    /* Decode TB flags.  */
3193
    dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3194
            | X_FLAG | PFIX_FLAG);
3195
    dc->delayed_branch = !!(tb->flags & 7);
3196
    if (dc->delayed_branch) {
3197
        dc->jmp = JMP_INDIRECT;
3198
    } else {
3199
        dc->jmp = JMP_NOJMP;
3200
    }
3201

    
3202
    dc->cpustate_changed = 0;
3203

    
3204
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3205
        qemu_log(
3206
                "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3207
                "pid=%x usp=%x\n"
3208
                "%x.%x.%x.%x\n"
3209
                "%x.%x.%x.%x\n"
3210
                "%x.%x.%x.%x\n"
3211
                "%x.%x.%x.%x\n",
3212
                search_pc, dc->pc, dc->ppc,
3213
                (uint64_t)tb->flags,
3214
                env->btarget, (unsigned)tb->flags & 7,
3215
                env->pregs[PR_CCS],
3216
                env->pregs[PR_PID], env->pregs[PR_USP],
3217
                env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3218
                env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3219
                env->regs[8], env->regs[9],
3220
                env->regs[10], env->regs[11],
3221
                env->regs[12], env->regs[13],
3222
                env->regs[14], env->regs[15]);
3223
        qemu_log("--------------\n");
3224
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3225
    }
3226

    
3227
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3228
    lj = -1;
3229
    num_insns = 0;
3230
    max_insns = tb->cflags & CF_COUNT_MASK;
3231
    if (max_insns == 0) {
3232
        max_insns = CF_COUNT_MASK;
3233
    }
3234

    
3235
    gen_tb_start();
3236
    do {
3237
        check_breakpoint(env, dc);
3238

    
3239
        if (search_pc) {
3240
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3241
            if (lj < j) {
3242
                lj++;
3243
                while (lj < j) {
3244
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
3245
                }
3246
            }
3247
            if (dc->delayed_branch == 1) {
3248
                tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;
3249
            } else {
3250
                tcg_ctx.gen_opc_pc[lj] = dc->pc;
3251
            }
3252
            tcg_ctx.gen_opc_instr_start[lj] = 1;
3253
            tcg_ctx.gen_opc_icount[lj] = num_insns;
3254
        }
3255

    
3256
        /* Pretty disas.  */
3257
        LOG_DIS("%8.8x:\t", dc->pc);
3258

    
3259
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3260
            gen_io_start();
3261
        }
3262
        dc->clear_x = 1;
3263

    
3264
        insn_len = dc->decoder(env, dc);
3265
        dc->ppc = dc->pc;
3266
        dc->pc += insn_len;
3267
        if (dc->clear_x) {
3268
            cris_clear_x_flag(dc);
3269
        }
3270

    
3271
        num_insns++;
3272
        /* Check for delayed branches here. If we do it before
3273
           actually generating any host code, the simulator will just
3274
           loop doing nothing for on this program location.  */
3275
        if (dc->delayed_branch) {
3276
            dc->delayed_branch--;
3277
            if (dc->delayed_branch == 0) {
3278
                if (tb->flags & 7) {
3279
                    t_gen_mov_env_TN(dslot, tcg_const_tl(0));
3280
                }
3281
                if (dc->cpustate_changed || !dc->flagx_known
3282
                    || (dc->flags_x != (tb->flags & X_FLAG))) {
3283
                    cris_store_direct_jmp(dc);
3284
                }
3285

    
3286
                if (dc->clear_locked_irq) {
3287
                    dc->clear_locked_irq = 0;
3288
                    t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3289
                }
3290

    
3291
                if (dc->jmp == JMP_DIRECT_CC) {
3292
                    int l1;
3293

    
3294
                    l1 = gen_new_label();
3295
                    cris_evaluate_flags(dc);
3296

    
3297
                    /* Conditional jmp.  */
3298
                    tcg_gen_brcondi_tl(TCG_COND_EQ,
3299
                               env_btaken, 0, l1);
3300
                    gen_goto_tb(dc, 1, dc->jmp_pc);
3301
                    gen_set_label(l1);
3302
                    gen_goto_tb(dc, 0, dc->pc);
3303
                    dc->is_jmp = DISAS_TB_JUMP;
3304
                    dc->jmp = JMP_NOJMP;
3305
                } else if (dc->jmp == JMP_DIRECT) {
3306
                    cris_evaluate_flags(dc);
3307
                    gen_goto_tb(dc, 0, dc->jmp_pc);
3308
                    dc->is_jmp = DISAS_TB_JUMP;
3309
                    dc->jmp = JMP_NOJMP;
3310
                } else {
3311
                    t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
3312
                    dc->is_jmp = DISAS_JUMP;
3313
                }
3314
                break;
3315
            }
3316
        }
3317

    
3318
        /* If we are rexecuting a branch due to exceptions on
3319
           delay slots dont break.  */
3320
        if (!(tb->pc & 1) && cs->singlestep_enabled) {
3321
            break;
3322
        }
3323
    } while (!dc->is_jmp && !dc->cpustate_changed
3324
            && tcg_ctx.gen_opc_ptr < gen_opc_end
3325
            && !singlestep
3326
            && (dc->pc < next_page_start)
3327
            && num_insns < max_insns);
3328

    
3329
    if (dc->clear_locked_irq) {
3330
        t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3331
    }
3332

    
3333
    npc = dc->pc;
3334

    
3335
        if (tb->cflags & CF_LAST_IO)
3336
            gen_io_end();
3337
    /* Force an update if the per-tb cpu state has changed.  */
3338
    if (dc->is_jmp == DISAS_NEXT
3339
        && (dc->cpustate_changed || !dc->flagx_known
3340
        || (dc->flags_x != (tb->flags & X_FLAG)))) {
3341
        dc->is_jmp = DISAS_UPDATE;
3342
        tcg_gen_movi_tl(env_pc, npc);
3343
    }
3344
    /* Broken branch+delayslot sequence.  */
3345
    if (dc->delayed_branch == 1) {
3346
        /* Set env->dslot to the size of the branch insn.  */
3347
        t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3348
        cris_store_direct_jmp(dc);
3349
    }
3350

    
3351
    cris_evaluate_flags(dc);
3352

    
3353
    if (unlikely(cs->singlestep_enabled)) {
3354
        if (dc->is_jmp == DISAS_NEXT) {
3355
            tcg_gen_movi_tl(env_pc, npc);
3356
        }
3357
        t_gen_raise_exception(EXCP_DEBUG);
3358
    } else {
3359
        switch (dc->is_jmp) {
3360
        case DISAS_NEXT:
3361
            gen_goto_tb(dc, 1, npc);
3362
            break;
3363
        default:
3364
        case DISAS_JUMP:
3365
        case DISAS_UPDATE:
3366
            /* indicate that the hash table must be used
3367
                   to find the next TB */
3368
            tcg_gen_exit_tb(0);
3369
            break;
3370
        case DISAS_SWI:
3371
        case DISAS_TB_JUMP:
3372
            /* nothing more to generate */
3373
            break;
3374
        }
3375
    }
3376
    gen_tb_end(tb, num_insns);
3377
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3378
    if (search_pc) {
3379
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3380
        lj++;
3381
        while (lj <= j) {
3382
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
3383
        }
3384
    } else {
3385
        tb->size = dc->pc - pc_start;
3386
        tb->icount = num_insns;
3387
    }
3388

    
3389
#ifdef DEBUG_DISAS
3390
#if !DISAS_CRIS
3391
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3392
        log_target_disas(env, pc_start, dc->pc - pc_start,
3393
                                 dc->env->pregs[PR_VR]);
3394
        qemu_log("\nisize=%d osize=%td\n",
3395
            dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf);
3396
    }
3397
#endif
3398
#endif
3399
}
3400

    
3401
void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
3402
{
3403
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
3404
}
3405

    
3406
void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
3407
{
3408
    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
3409
}
3410

    
3411
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
3412
                         int flags)
3413
{
3414
    CRISCPU *cpu = CRIS_CPU(cs);
3415
    CPUCRISState *env = &cpu->env;
3416
    int i;
3417
    uint32_t srs;
3418

    
3419
    if (!env || !f) {
3420
        return;
3421
    }
3422

    
3423
    cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3424
            "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3425
            env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3426
            env->cc_op,
3427
            env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3428

    
3429

    
3430
    for (i = 0; i < 16; i++) {
3431
        cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3432
        if ((i + 1) % 4 == 0) {
3433
            cpu_fprintf(f, "\n");
3434
        }
3435
    }
3436
    cpu_fprintf(f, "\nspecial regs:\n");
3437
    for (i = 0; i < 16; i++) {
3438
        cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3439
        if ((i + 1) % 4 == 0) {
3440
            cpu_fprintf(f, "\n");
3441
        }
3442
    }
3443
    srs = env->pregs[PR_SRS];
3444
    cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3445
    if (srs < ARRAY_SIZE(env->sregs)) {
3446
        for (i = 0; i < 16; i++) {
3447
            cpu_fprintf(f, "s%2.2d=%8.8x ",
3448
                    i, env->sregs[srs][i]);
3449
            if ((i + 1) % 4 == 0) {
3450
                cpu_fprintf(f, "\n");
3451
            }
3452
        }
3453
    }
3454
    cpu_fprintf(f, "\n\n");
3455

    
3456
}
3457

    
3458
void cris_initialize_tcg(void)
3459
{
3460
    int i;
3461

    
3462
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3463
    cc_x = tcg_global_mem_new(TCG_AREG0,
3464
                              offsetof(CPUCRISState, cc_x), "cc_x");
3465
    cc_src = tcg_global_mem_new(TCG_AREG0,
3466
                                offsetof(CPUCRISState, cc_src), "cc_src");
3467
    cc_dest = tcg_global_mem_new(TCG_AREG0,
3468
                                 offsetof(CPUCRISState, cc_dest),
3469
                                 "cc_dest");
3470
    cc_result = tcg_global_mem_new(TCG_AREG0,
3471
                                   offsetof(CPUCRISState, cc_result),
3472
                                   "cc_result");
3473
    cc_op = tcg_global_mem_new(TCG_AREG0,
3474
                               offsetof(CPUCRISState, cc_op), "cc_op");
3475
    cc_size = tcg_global_mem_new(TCG_AREG0,
3476
                                 offsetof(CPUCRISState, cc_size),
3477
                                 "cc_size");
3478
    cc_mask = tcg_global_mem_new(TCG_AREG0,
3479
                                 offsetof(CPUCRISState, cc_mask),
3480
                                 "cc_mask");
3481

    
3482
    env_pc = tcg_global_mem_new(TCG_AREG0,
3483
                                offsetof(CPUCRISState, pc),
3484
                                "pc");
3485
    env_btarget = tcg_global_mem_new(TCG_AREG0,
3486
                                     offsetof(CPUCRISState, btarget),
3487
                                     "btarget");
3488
    env_btaken = tcg_global_mem_new(TCG_AREG0,
3489
                                    offsetof(CPUCRISState, btaken),
3490
                                    "btaken");
3491
    for (i = 0; i < 16; i++) {
3492
        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3493
                                      offsetof(CPUCRISState, regs[i]),
3494
                                      regnames[i]);
3495
    }
3496
    for (i = 0; i < 16; i++) {
3497
        cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3498
                                       offsetof(CPUCRISState, pregs[i]),
3499
                                       pregnames[i]);
3500
    }
3501
}
3502

    
3503
void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
3504
{
3505
    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3506
}