Statistics
| Branch: | Revision:

root / target-cris / translate.c @ 7267c094

History | View | Annotate | Download (81.9 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 <stdarg.h>
27
#include <stdlib.h>
28
#include <stdio.h>
29
#include <string.h>
30
#include <inttypes.h>
31

    
32
#include "cpu.h"
33
#include "disas.h"
34
#include "tcg-op.h"
35
#include "helper.h"
36
#include "mmu.h"
37
#include "crisv32-decode.h"
38
#include "qemu-common.h"
39

    
40
#define GEN_HELPER 1
41
#include "helper.h"
42

    
43
#define DISAS_CRIS 0
44
#if DISAS_CRIS
45
#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46
#else
47
#  define LOG_DIS(...) do { } while (0)
48
#endif
49

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

    
54
#define DISAS_SWI 5
55

    
56
/* Used by the decoder.  */
57
#define EXTRACT_FIELD(src, start, end) \
58
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
59

    
60
#define CC_MASK_NZ 0xc
61
#define CC_MASK_NZV 0xe
62
#define CC_MASK_NZVC 0xf
63
#define CC_MASK_RNZV 0x10e
64

    
65
static TCGv_ptr cpu_env;
66
static TCGv cpu_R[16];
67
static TCGv cpu_PR[16];
68
static TCGv cc_x;
69
static TCGv cc_src;
70
static TCGv cc_dest;
71
static TCGv cc_result;
72
static TCGv cc_op;
73
static TCGv cc_size;
74
static TCGv cc_mask;
75

    
76
static TCGv env_btaken;
77
static TCGv env_btarget;
78
static TCGv env_pc;
79

    
80
#include "gen-icount.h"
81

    
82
/* This is the state at translation time.  */
83
typedef struct DisasContext {
84
        CPUState *env;
85
        target_ulong pc, ppc;
86

    
87
        /* Decoder.  */
88
        unsigned int (*decoder)(struct DisasContext *dc);
89
        uint32_t ir;
90
        uint32_t opcode;
91
        unsigned int op1;
92
        unsigned int op2;
93
        unsigned int zsize, zzsize;
94
        unsigned int mode;
95
        unsigned int postinc;
96

    
97
        unsigned int size;
98
        unsigned int src;
99
        unsigned int dst;
100
        unsigned int cond;
101

    
102
        int update_cc;
103
        int cc_op;
104
        int cc_size;
105
        uint32_t cc_mask;
106

    
107
        int cc_size_uptodate; /* -1 invalid or last written value.  */
108

    
109
        int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
110
        int flags_uptodate; /* Wether or not $ccs is uptodate.  */
111
        int flagx_known; /* Wether or not flags_x has the x flag known at
112
                            translation time.  */
113
        int flags_x;
114

    
115
        int clear_x; /* Clear x after this insn?  */
116
        int clear_prefix; /* Clear prefix after this insn?  */
117
        int clear_locked_irq; /* Clear the irq lockout.  */
118
        int cpustate_changed;
119
        unsigned int tb_flags; /* tb dependent flags.  */
120
        int is_jmp;
121

    
122
#define JMP_NOJMP     0
123
#define JMP_DIRECT    1
124
#define JMP_DIRECT_CC 2
125
#define JMP_INDIRECT  3
126
        int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
127
        uint32_t jmp_pc;
128

    
129
        int delayed_branch;
130

    
131
        struct TranslationBlock *tb;
132
        int singlestep_enabled;
133
} DisasContext;
134

    
135
static void gen_BUG(DisasContext *dc, const char *file, int line)
136
{
137
        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
138
        qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
139
        cpu_abort(dc->env, "%s:%d\n", file, line);
140
}
141

    
142
static const char *regnames[] =
143
{
144
        "$r0", "$r1", "$r2", "$r3",
145
        "$r4", "$r5", "$r6", "$r7",
146
        "$r8", "$r9", "$r10", "$r11",
147
        "$r12", "$r13", "$sp", "$acr",
148
};
149
static const char *pregnames[] =
150
{
151
        "$bz", "$vr", "$pid", "$srs",
152
        "$wz", "$exs", "$eda", "$mof",
153
        "$dz", "$ebp", "$erp", "$srp",
154
        "$nrp", "$ccs", "$usp", "$spc",
155
};
156

    
157
/* We need this table to handle preg-moves with implicit width.  */
158
static int preg_sizes[] = {
159
        1, /* bz.  */
160
        1, /* vr.  */
161
        4, /* pid.  */
162
        1, /* srs.  */
163
        2, /* wz.  */
164
        4, 4, 4,
165
        4, 4, 4, 4,
166
        4, 4, 4, 4,
167
};
168

    
169
#define t_gen_mov_TN_env(tn, member) \
170
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
171
#define t_gen_mov_env_TN(member, tn) \
172
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
173

    
174
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
175
{
176
        if (r < 0 || r > 15)
177
                fprintf(stderr, "wrong register read $r%d\n", r);
178
        tcg_gen_mov_tl(tn, cpu_R[r]);
179
}
180
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
181
{
182
        if (r < 0 || r > 15)
183
                fprintf(stderr, "wrong register write $r%d\n", r);
184
        tcg_gen_mov_tl(cpu_R[r], tn);
185
}
186

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

    
200
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
201
{
202
        if (r < 0 || r > 15)
203
                fprintf(stderr, "wrong register read $p%d\n", r);
204
        if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
205
                tcg_gen_mov_tl(tn, tcg_const_tl(0));
206
        else if (r == PR_VR)
207
                tcg_gen_mov_tl(tn, tcg_const_tl(32));
208
        else
209
                tcg_gen_mov_tl(tn, cpu_PR[r]);
210
}
211
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
212
{
213
        if (r < 0 || r > 15)
214
                fprintf(stderr, "wrong register write $p%d\n", r);
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(tn);
222
                if (dc->tb_flags & S_FLAG && r == PR_SPC) 
223
                        gen_helper_spc_write(tn);
224
                else if (r == PR_CCS)
225
                        dc->cpustate_changed = 1;
226
                tcg_gen_mov_tl(cpu_PR[r], tn);
227
        }
228
}
229

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

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

    
243
static int cris_fetch(DisasContext *dc, uint32_t addr,
244
                      unsigned int size, unsigned int sign)
245
{
246
        int r;
247

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

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

    
285
static inline void t_gen_raise_exception(uint32_t index)
286
{
287
        TCGv_i32 tmp = tcg_const_i32(index);
288
        gen_helper_raise_exception(tmp);
289
        tcg_temp_free_i32(tmp);
290
}
291

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

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

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

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

    
312
        t0 = tcg_temp_new();
313
        t_31 = tcg_temp_new();
314
        tcg_gen_shr_tl(d, a, b);
315

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

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

    
329
        t0 = tcg_temp_new();
330
        t_31 = tcg_temp_new();
331
        tcg_gen_sar_tl(d, a, b);
332

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

    
341
/* 64-bit signed mul, lower result in d and upper in d2.  */
342
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
343
{
344
        TCGv_i64 t0, t1;
345

    
346
        t0 = tcg_temp_new_i64();
347
        t1 = tcg_temp_new_i64();
348

    
349
        tcg_gen_ext_i32_i64(t0, a);
350
        tcg_gen_ext_i32_i64(t1, b);
351
        tcg_gen_mul_i64(t0, t0, t1);
352

    
353
        tcg_gen_trunc_i64_i32(d, t0);
354
        tcg_gen_shri_i64(t0, t0, 32);
355
        tcg_gen_trunc_i64_i32(d2, t0);
356

    
357
        tcg_temp_free_i64(t0);
358
        tcg_temp_free_i64(t1);
359
}
360

    
361
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
362
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
363
{
364
        TCGv_i64 t0, t1;
365

    
366
        t0 = tcg_temp_new_i64();
367
        t1 = tcg_temp_new_i64();
368

    
369
        tcg_gen_extu_i32_i64(t0, a);
370
        tcg_gen_extu_i32_i64(t1, b);
371
        tcg_gen_mul_i64(t0, t0, t1);
372

    
373
        tcg_gen_trunc_i64_i32(d, t0);
374
        tcg_gen_shri_i64(t0, t0, 32);
375
        tcg_gen_trunc_i64_i32(d2, t0);
376

    
377
        tcg_temp_free_i64(t0);
378
        tcg_temp_free_i64(t1);
379
}
380

    
381
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
382
{
383
        int l1;
384

    
385
        l1 = gen_new_label();
386

    
387
        /* 
388
         * d <<= 1
389
         * if (d >= s)
390
         *    d -= s;
391
         */
392
        tcg_gen_shli_tl(d, a, 1);
393
        tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
394
        tcg_gen_sub_tl(d, d, b);
395
        gen_set_label(l1);
396
}
397

    
398
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
399
{
400
        TCGv t;
401

    
402
        /* 
403
         * d <<= 1
404
         * if (n)
405
         *    d += s;
406
         */
407
        t = tcg_temp_new();
408
        tcg_gen_shli_tl(d, a, 1);
409
        tcg_gen_shli_tl(t, ccs, 31 - 3);
410
        tcg_gen_sari_tl(t, t, 31);
411
        tcg_gen_and_tl(t, t, b);
412
        tcg_gen_add_tl(d, d, t);
413
        tcg_temp_free(t);
414
}
415

    
416
/* Extended arithmetics on CRIS.  */
417
static inline void t_gen_add_flag(TCGv d, int flag)
418
{
419
        TCGv c;
420

    
421
        c = tcg_temp_new();
422
        t_gen_mov_TN_preg(c, PR_CCS);
423
        /* Propagate carry into d.  */
424
        tcg_gen_andi_tl(c, c, 1 << flag);
425
        if (flag)
426
                tcg_gen_shri_tl(c, c, flag);
427
        tcg_gen_add_tl(d, d, c);
428
        tcg_temp_free(c);
429
}
430

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

    
447
                x = tcg_temp_new();
448
                c = tcg_temp_new();
449
                t_gen_mov_TN_preg(x, PR_CCS);
450
                tcg_gen_mov_tl(c, x);
451

    
452
                /* Propagate carry into d if X is set. Branch free.  */
453
                tcg_gen_andi_tl(c, c, C_FLAG);
454
                tcg_gen_andi_tl(x, x, X_FLAG);
455
                tcg_gen_shri_tl(x, x, 4);
456

    
457
                tcg_gen_and_tl(x, x, c);
458
                tcg_gen_add_tl(d, d, x);        
459
                tcg_temp_free(x);
460
                tcg_temp_free(c);
461
        }
462
}
463

    
464
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
465
{
466
        if (dc->flagx_known) {
467
                if (dc->flags_x) {
468
                        TCGv c;
469
            
470
                        c = tcg_temp_new();
471
                        t_gen_mov_TN_preg(c, PR_CCS);
472
                        /* C flag is already at bit 0.  */
473
                        tcg_gen_andi_tl(c, c, C_FLAG);
474
                        tcg_gen_sub_tl(d, d, c);
475
                        tcg_temp_free(c);
476
                }
477
        } else {
478
                TCGv x, c;
479

    
480
                x = tcg_temp_new();
481
                c = tcg_temp_new();
482
                t_gen_mov_TN_preg(x, PR_CCS);
483
                tcg_gen_mov_tl(c, x);
484

    
485
                /* Propagate carry into d if X is set. Branch free.  */
486
                tcg_gen_andi_tl(c, c, C_FLAG);
487
                tcg_gen_andi_tl(x, x, X_FLAG);
488
                tcg_gen_shri_tl(x, x, 4);
489

    
490
                tcg_gen_and_tl(x, x, c);
491
                tcg_gen_sub_tl(d, d, x);
492
                tcg_temp_free(x);
493
                tcg_temp_free(c);
494
        }
495
}
496

    
497
/* Swap the two bytes within each half word of the s operand.
498
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
499
static inline void t_gen_swapb(TCGv d, TCGv s)
500
{
501
        TCGv t, org_s;
502

    
503
        t = tcg_temp_new();
504
        org_s = tcg_temp_new();
505

    
506
        /* d and s may refer to the same object.  */
507
        tcg_gen_mov_tl(org_s, s);
508
        tcg_gen_shli_tl(t, org_s, 8);
509
        tcg_gen_andi_tl(d, t, 0xff00ff00);
510
        tcg_gen_shri_tl(t, org_s, 8);
511
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
512
        tcg_gen_or_tl(d, d, t);
513
        tcg_temp_free(t);
514
        tcg_temp_free(org_s);
515
}
516

    
517
/* Swap the halfwords of the s operand.  */
518
static inline void t_gen_swapw(TCGv d, TCGv s)
519
{
520
        TCGv t;
521
        /* d and s refer the same object.  */
522
        t = tcg_temp_new();
523
        tcg_gen_mov_tl(t, s);
524
        tcg_gen_shli_tl(d, t, 16);
525
        tcg_gen_shri_tl(t, t, 16);
526
        tcg_gen_or_tl(d, d, t);
527
        tcg_temp_free(t);
528
}
529

    
530
/* Reverse the within each byte.
531
   T0 = (((T0 << 7) & 0x80808080) |
532
   ((T0 << 5) & 0x40404040) |
533
   ((T0 << 3) & 0x20202020) |
534
   ((T0 << 1) & 0x10101010) |
535
   ((T0 >> 1) & 0x08080808) |
536
   ((T0 >> 3) & 0x04040404) |
537
   ((T0 >> 5) & 0x02020202) |
538
   ((T0 >> 7) & 0x01010101));
539
 */
540
static inline void t_gen_swapr(TCGv d, TCGv s)
541
{
542
        struct {
543
                int shift; /* LSL when positive, LSR when negative.  */
544
                uint32_t mask;
545
        } bitrev [] = {
546
                {7, 0x80808080},
547
                {5, 0x40404040},
548
                {3, 0x20202020},
549
                {1, 0x10101010},
550
                {-1, 0x08080808},
551
                {-3, 0x04040404},
552
                {-5, 0x02020202},
553
                {-7, 0x01010101}
554
        };
555
        int i;
556
        TCGv t, org_s;
557

    
558
        /* d and s refer the same object.  */
559
        t = tcg_temp_new();
560
        org_s = tcg_temp_new();
561
        tcg_gen_mov_tl(org_s, s);
562

    
563
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
564
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
565
        for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
566
                if (bitrev[i].shift >= 0) {
567
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
568
                } else {
569
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
570
                }
571
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
572
                tcg_gen_or_tl(d, d, t);
573
        }
574
        tcg_temp_free(t);
575
        tcg_temp_free(org_s);
576
}
577

    
578
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
579
{
580
        int l1;
581

    
582
        l1 = gen_new_label();
583

    
584
        /* Conditional jmp.  */
585
        tcg_gen_mov_tl(env_pc, pc_false);
586
        tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
587
        tcg_gen_mov_tl(env_pc, pc_true);
588
        gen_set_label(l1);
589
}
590

    
591
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
592
{
593
        TranslationBlock *tb;
594
        tb = dc->tb;
595
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
596
                tcg_gen_goto_tb(n);
597
                tcg_gen_movi_tl(env_pc, dest);
598
                tcg_gen_exit_tb((tcg_target_long)tb + n);
599
        } else {
600
                tcg_gen_movi_tl(env_pc, dest);
601
                tcg_gen_exit_tb(0);
602
        }
603
}
604

    
605
static inline void cris_clear_x_flag(DisasContext *dc)
606
{
607
        if (dc->flagx_known && dc->flags_x)
608
                dc->flags_uptodate = 0;
609

    
610
        dc->flagx_known = 1;
611
        dc->flags_x = 0;
612
}
613

    
614
static void cris_flush_cc_state(DisasContext *dc)
615
{
616
        if (dc->cc_size_uptodate != dc->cc_size) {
617
                tcg_gen_movi_tl(cc_size, dc->cc_size);
618
                dc->cc_size_uptodate = dc->cc_size;
619
        }
620
        tcg_gen_movi_tl(cc_op, dc->cc_op);
621
        tcg_gen_movi_tl(cc_mask, dc->cc_mask);
622
}
623

    
624
static void cris_evaluate_flags(DisasContext *dc)
625
{
626
        if (dc->flags_uptodate)
627
                return;
628

    
629
        cris_flush_cc_state(dc);
630

    
631
        switch (dc->cc_op)
632
        {
633
        case CC_OP_MCP:
634
                gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
635
                                        cpu_PR[PR_CCS], cc_src,
636
                                        cc_dest, cc_result);
637
                break;
638
        case CC_OP_MULS:
639
                gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
640
                                        cpu_PR[PR_CCS], cc_result,
641
                                        cpu_PR[PR_MOF]);
642
                break;
643
        case CC_OP_MULU:
644
                gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
645
                                        cpu_PR[PR_CCS], cc_result,
646
                                        cpu_PR[PR_MOF]);
647
                break;
648
        case CC_OP_MOVE:
649
        case CC_OP_AND:
650
        case CC_OP_OR:
651
        case CC_OP_XOR:
652
        case CC_OP_ASR:
653
        case CC_OP_LSR:
654
        case CC_OP_LSL:
655
                switch (dc->cc_size)
656
                {
657
                case 4:
658
                        gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
659
                                                cpu_PR[PR_CCS], cc_result);
660
                        break;
661
                case 2:
662
                        gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
663
                                                cpu_PR[PR_CCS], cc_result);
664
                        break;
665
                default:
666
                        gen_helper_evaluate_flags();
667
                        break;
668
                }
669
                break;
670
        case CC_OP_FLAGS:
671
                /* live.  */
672
                break;
673
        case CC_OP_SUB:
674
        case CC_OP_CMP:
675
                if (dc->cc_size == 4)
676
                        gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
677
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
678
                else
679
                        gen_helper_evaluate_flags();
680

    
681
                break;
682
        default:
683
                switch (dc->cc_size)
684
                {
685
                        case 4:
686
                        gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
687
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
688
                                break;
689
                        default:
690
                                gen_helper_evaluate_flags();
691
                                break;
692
                }
693
                break;
694
        }
695

    
696
        if (dc->flagx_known) {
697
                if (dc->flags_x)
698
                        tcg_gen_ori_tl(cpu_PR[PR_CCS], 
699
                                       cpu_PR[PR_CCS], X_FLAG);
700
                else if (dc->cc_op == CC_OP_FLAGS)
701
                        tcg_gen_andi_tl(cpu_PR[PR_CCS], 
702
                                        cpu_PR[PR_CCS], ~X_FLAG);
703
        }
704
        dc->flags_uptodate = 1;
705
}
706

    
707
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
708
{
709
        uint32_t ovl;
710

    
711
        if (!mask) {
712
                dc->update_cc = 0;
713
                return;
714
        }        
715

    
716
        /* Check if we need to evaluate the condition codes due to 
717
           CC overlaying.  */
718
        ovl = (dc->cc_mask ^ mask) & ~mask;
719
        if (ovl) {
720
                /* TODO: optimize this case. It trigs all the time.  */
721
                cris_evaluate_flags (dc);
722
        }
723
        dc->cc_mask = mask;
724
        dc->update_cc = 1;
725
}
726

    
727
static void cris_update_cc_op(DisasContext *dc, int op, int size)
728
{
729
        dc->cc_op = op;
730
        dc->cc_size = size;
731
        dc->flags_uptodate = 0;
732
}
733

    
734
static inline void cris_update_cc_x(DisasContext *dc)
735
{
736
        /* Save the x flag state at the time of the cc snapshot.  */
737
        if (dc->flagx_known) {
738
                if (dc->cc_x_uptodate == (2 | dc->flags_x))
739
                        return;
740
                tcg_gen_movi_tl(cc_x, dc->flags_x);
741
                dc->cc_x_uptodate = 2 | dc->flags_x;
742
        }
743
        else {
744
                tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
745
                dc->cc_x_uptodate = 1;
746
        }
747
}
748

    
749
/* Update cc prior to executing ALU op. Needs source operands untouched.  */
750
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
751
                                   TCGv dst, TCGv src, int size)
752
{
753
        if (dc->update_cc) {
754
                cris_update_cc_op(dc, op, size);
755
                tcg_gen_mov_tl(cc_src, src);
756

    
757
                if (op != CC_OP_MOVE
758
                    && op != CC_OP_AND
759
                    && op != CC_OP_OR
760
                    && op != CC_OP_XOR
761
                    && op != CC_OP_ASR
762
                    && op != CC_OP_LSR
763
                    && op != CC_OP_LSL)
764
                        tcg_gen_mov_tl(cc_dest, dst);
765

    
766
                cris_update_cc_x(dc);
767
        }
768
}
769

    
770
/* Update cc after executing ALU op. needs the result.  */
771
static inline void cris_update_result(DisasContext *dc, TCGv res)
772
{
773
        if (dc->update_cc)
774
                tcg_gen_mov_tl(cc_result, res);
775
}
776

    
777
/* Returns one if the write back stage should execute.  */
778
static void cris_alu_op_exec(DisasContext *dc, int op, 
779
                               TCGv dst, TCGv a, TCGv b, int size)
780
{
781
        /* Emit the ALU insns.  */
782
        switch (op)
783
        {
784
                case CC_OP_ADD:
785
                        tcg_gen_add_tl(dst, a, b);
786
                        /* Extended arithmetics.  */
787
                        t_gen_addx_carry(dc, dst);
788
                        break;
789
                case CC_OP_ADDC:
790
                        tcg_gen_add_tl(dst, a, b);
791
                        t_gen_add_flag(dst, 0); /* C_FLAG.  */
792
                        break;
793
                case CC_OP_MCP:
794
                        tcg_gen_add_tl(dst, a, b);
795
                        t_gen_add_flag(dst, 8); /* R_FLAG.  */
796
                        break;
797
                case CC_OP_SUB:
798
                        tcg_gen_sub_tl(dst, a, b);
799
                        /* Extended arithmetics.  */
800
                        t_gen_subx_carry(dc, dst);
801
                        break;
802
                case CC_OP_MOVE:
803
                        tcg_gen_mov_tl(dst, b);
804
                        break;
805
                case CC_OP_OR:
806
                        tcg_gen_or_tl(dst, a, b);
807
                        break;
808
                case CC_OP_AND:
809
                        tcg_gen_and_tl(dst, a, b);
810
                        break;
811
                case CC_OP_XOR:
812
                        tcg_gen_xor_tl(dst, a, b);
813
                        break;
814
                case CC_OP_LSL:
815
                        t_gen_lsl(dst, a, b);
816
                        break;
817
                case CC_OP_LSR:
818
                        t_gen_lsr(dst, a, b);
819
                        break;
820
                case CC_OP_ASR:
821
                        t_gen_asr(dst, a, b);
822
                        break;
823
                case CC_OP_NEG:
824
                        tcg_gen_neg_tl(dst, b);
825
                        /* Extended arithmetics.  */
826
                        t_gen_subx_carry(dc, dst);
827
                        break;
828
                case CC_OP_LZ:
829
                        gen_helper_lz(dst, b);
830
                        break;
831
                case CC_OP_MULS:
832
                        t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
833
                        break;
834
                case CC_OP_MULU:
835
                        t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
836
                        break;
837
                case CC_OP_DSTEP:
838
                        t_gen_cris_dstep(dst, a, b);
839
                        break;
840
                case CC_OP_MSTEP:
841
                        t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
842
                        break;
843
                case CC_OP_BOUND:
844
                {
845
                        int l1;
846
                        l1 = gen_new_label();
847
                        tcg_gen_mov_tl(dst, a);
848
                        tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
849
                        tcg_gen_mov_tl(dst, b);
850
                        gen_set_label(l1);
851
                }
852
                break;
853
                case CC_OP_CMP:
854
                        tcg_gen_sub_tl(dst, a, b);
855
                        /* Extended arithmetics.  */
856
                        t_gen_subx_carry(dc, dst);
857
                        break;
858
                default:
859
                        qemu_log("illegal ALU op.\n");
860
                        BUG();
861
                        break;
862
        }
863

    
864
        if (size == 1)
865
                tcg_gen_andi_tl(dst, dst, 0xff);
866
        else if (size == 2)
867
                tcg_gen_andi_tl(dst, dst, 0xffff);
868
}
869

    
870
static void cris_alu(DisasContext *dc, int op,
871
                               TCGv d, TCGv op_a, TCGv op_b, int size)
872
{
873
        TCGv tmp;
874
        int writeback;
875

    
876
        writeback = 1;
877

    
878
        if (op == CC_OP_CMP) {
879
                tmp = tcg_temp_new();
880
                writeback = 0;
881
        } else if (size == 4) {
882
                tmp = d;
883
                writeback = 0;
884
        } else
885
                tmp = tcg_temp_new();
886

    
887

    
888
        cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
889
        cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
890
        cris_update_result(dc, tmp);
891

    
892
        /* Writeback.  */
893
        if (writeback) {
894
                if (size == 1)
895
                        tcg_gen_andi_tl(d, d, ~0xff);
896
                else
897
                        tcg_gen_andi_tl(d, d, ~0xffff);
898
                tcg_gen_or_tl(d, d, tmp);
899
        }
900
        if (!TCGV_EQUAL(tmp, d))
901
                tcg_temp_free(tmp);
902
}
903

    
904
static int arith_cc(DisasContext *dc)
905
{
906
        if (dc->update_cc) {
907
                switch (dc->cc_op) {
908
                        case CC_OP_ADDC: return 1;
909
                        case CC_OP_ADD: return 1;
910
                        case CC_OP_SUB: return 1;
911
                        case CC_OP_DSTEP: return 1;
912
                        case CC_OP_LSL: return 1;
913
                        case CC_OP_LSR: return 1;
914
                        case CC_OP_ASR: return 1;
915
                        case CC_OP_CMP: return 1;
916
                        case CC_OP_NEG: return 1;
917
                        case CC_OP_OR: return 1;
918
                        case CC_OP_AND: return 1;
919
                        case CC_OP_XOR: return 1;
920
                        case CC_OP_MULU: return 1;
921
                        case CC_OP_MULS: return 1;
922
                        default:
923
                                return 0;
924
                }
925
        }
926
        return 0;
927
}
928

    
929
static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
930
{
931
        int arith_opt, move_opt;
932

    
933
        /* TODO: optimize more condition codes.  */
934

    
935
        /*
936
         * If the flags are live, we've gotta look into the bits of CCS.
937
         * Otherwise, if we just did an arithmetic operation we try to
938
         * evaluate the condition code faster.
939
         *
940
         * When this function is done, T0 should be non-zero if the condition
941
         * code is true.
942
         */
943
        arith_opt = arith_cc(dc) && !dc->flags_uptodate;
944
        move_opt = (dc->cc_op == CC_OP_MOVE);
945
        switch (cond) {
946
                case CC_EQ:
947
                        if ((arith_opt || move_opt)
948
                            && dc->cc_x_uptodate != (2 | X_FLAG)) {
949
                                tcg_gen_setcond_tl(TCG_COND_EQ, cc,
950
                                                   cc_result, tcg_const_tl(0));
951
                        }
952
                        else {
953
                                cris_evaluate_flags(dc);
954
                                tcg_gen_andi_tl(cc, 
955
                                                cpu_PR[PR_CCS], Z_FLAG);
956
                        }
957
                        break;
958
                case CC_NE:
959
                        if ((arith_opt || move_opt)
960
                            && dc->cc_x_uptodate != (2 | X_FLAG)) {
961
                                tcg_gen_mov_tl(cc, cc_result);
962
                         } else {
963
                                cris_evaluate_flags(dc);
964
                                tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
965
                                                Z_FLAG);
966
                                tcg_gen_andi_tl(cc, cc, Z_FLAG);
967
                        }
968
                        break;
969
                case CC_CS:
970
                        cris_evaluate_flags(dc);
971
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
972
                        break;
973
                case CC_CC:
974
                        cris_evaluate_flags(dc);
975
                        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
976
                        tcg_gen_andi_tl(cc, cc, C_FLAG);
977
                        break;
978
                case CC_VS:
979
                        cris_evaluate_flags(dc);
980
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
981
                        break;
982
                case CC_VC:
983
                        cris_evaluate_flags(dc);
984
                        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
985
                                        V_FLAG);
986
                        tcg_gen_andi_tl(cc, cc, V_FLAG);
987
                        break;
988
                case CC_PL:
989
                        if (arith_opt || move_opt) {
990
                                int bits = 31;
991

    
992
                                if (dc->cc_size == 1)
993
                                        bits = 7;
994
                                else if (dc->cc_size == 2)
995
                                        bits = 15;        
996

    
997
                                tcg_gen_shri_tl(cc, cc_result, bits);
998
                                tcg_gen_xori_tl(cc, cc, 1);
999
                        } else {
1000
                                cris_evaluate_flags(dc);
1001
                                tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
1002
                                                N_FLAG);
1003
                                tcg_gen_andi_tl(cc, cc, N_FLAG);
1004
                        }
1005
                        break;
1006
                case CC_MI:
1007
                        if (arith_opt || move_opt) {
1008
                                int bits = 31;
1009

    
1010
                                if (dc->cc_size == 1)
1011
                                        bits = 7;
1012
                                else if (dc->cc_size == 2)
1013
                                        bits = 15;        
1014

    
1015
                                tcg_gen_shri_tl(cc, cc_result, bits);
1016
                                tcg_gen_andi_tl(cc, cc, 1);
1017
                        }
1018
                        else {
1019
                                cris_evaluate_flags(dc);
1020
                                tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1021
                                                N_FLAG);
1022
                        }
1023
                        break;
1024
                case CC_LS:
1025
                        cris_evaluate_flags(dc);
1026
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1027
                                        C_FLAG | Z_FLAG);
1028
                        break;
1029
                case CC_HI:
1030
                        cris_evaluate_flags(dc);
1031
                        {
1032
                                TCGv tmp;
1033

    
1034
                                tmp = tcg_temp_new();
1035
                                tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1036
                                                C_FLAG | Z_FLAG);
1037
                                /* Overlay the C flag on top of the Z.  */
1038
                                tcg_gen_shli_tl(cc, tmp, 2);
1039
                                tcg_gen_and_tl(cc, tmp, cc);
1040
                                tcg_gen_andi_tl(cc, cc, Z_FLAG);
1041

    
1042
                                tcg_temp_free(tmp);
1043
                        }
1044
                        break;
1045
                case CC_GE:
1046
                        cris_evaluate_flags(dc);
1047
                        /* Overlay the V flag on top of the N.  */
1048
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1049
                        tcg_gen_xor_tl(cc,
1050
                                       cpu_PR[PR_CCS], cc);
1051
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1052
                        tcg_gen_xori_tl(cc, cc, N_FLAG);
1053
                        break;
1054
                case CC_LT:
1055
                        cris_evaluate_flags(dc);
1056
                        /* Overlay the V flag on top of the N.  */
1057
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1058
                        tcg_gen_xor_tl(cc,
1059
                                       cpu_PR[PR_CCS], cc);
1060
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1061
                        break;
1062
                case CC_GT:
1063
                        cris_evaluate_flags(dc);
1064
                        {
1065
                                TCGv n, z;
1066

    
1067
                                n = tcg_temp_new();
1068
                                z = tcg_temp_new();
1069

    
1070
                                /* To avoid a shift we overlay everything on
1071
                                   the V flag.  */
1072
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1073
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1074
                                /* invert Z.  */
1075
                                tcg_gen_xori_tl(z, z, 2);
1076

    
1077
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1078
                                tcg_gen_xori_tl(n, n, 2);
1079
                                tcg_gen_and_tl(cc, z, n);
1080
                                tcg_gen_andi_tl(cc, cc, 2);
1081

    
1082
                                tcg_temp_free(n);
1083
                                tcg_temp_free(z);
1084
                        }
1085
                        break;
1086
                case CC_LE:
1087
                        cris_evaluate_flags(dc);
1088
                        {
1089
                                TCGv n, z;
1090

    
1091
                                n = tcg_temp_new();
1092
                                z = tcg_temp_new();
1093

    
1094
                                /* To avoid a shift we overlay everything on
1095
                                   the V flag.  */
1096
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1097
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1098

    
1099
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1100
                                tcg_gen_or_tl(cc, z, n);
1101
                                tcg_gen_andi_tl(cc, cc, 2);
1102

    
1103
                                tcg_temp_free(n);
1104
                                tcg_temp_free(z);
1105
                        }
1106
                        break;
1107
                case CC_P:
1108
                        cris_evaluate_flags(dc);
1109
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1110
                        break;
1111
                case CC_A:
1112
                        tcg_gen_movi_tl(cc, 1);
1113
                        break;
1114
                default:
1115
                        BUG();
1116
                        break;
1117
        };
1118
}
1119

    
1120
static void cris_store_direct_jmp(DisasContext *dc)
1121
{
1122
        /* Store the direct jmp state into the cpu-state.  */
1123
        if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1124
                if (dc->jmp == JMP_DIRECT) {
1125
                        tcg_gen_movi_tl(env_btaken, 1);
1126
                }
1127
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1128
                dc->jmp = JMP_INDIRECT;
1129
        }
1130
}
1131

    
1132
static void cris_prepare_cc_branch (DisasContext *dc, 
1133
                                    int offset, int cond)
1134
{
1135
        /* This helps us re-schedule the micro-code to insns in delay-slots
1136
           before the actual jump.  */
1137
        dc->delayed_branch = 2;
1138
        dc->jmp = JMP_DIRECT_CC;
1139
        dc->jmp_pc = dc->pc + offset;
1140

    
1141
        gen_tst_cc (dc, env_btaken, cond);
1142
        tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1143
}
1144

    
1145

    
1146
/* jumps, when the dest is in a live reg for example. Direct should be set
1147
   when the dest addr is constant to allow tb chaining.  */
1148
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1149
{
1150
        /* This helps us re-schedule the micro-code to insns in delay-slots
1151
           before the actual jump.  */
1152
        dc->delayed_branch = 2;
1153
        dc->jmp = type;
1154
        if (type == JMP_INDIRECT) {
1155
                tcg_gen_movi_tl(env_btaken, 1);
1156
        }
1157
}
1158

    
1159
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1160
{
1161
        int mem_index = cpu_mmu_index(dc->env);
1162

    
1163
        /* If we get a fault on a delayslot we must keep the jmp state in
1164
           the cpu-state to be able to re-execute the jmp.  */
1165
        if (dc->delayed_branch == 1)
1166
                cris_store_direct_jmp(dc);
1167

    
1168
        tcg_gen_qemu_ld64(dst, addr, mem_index);
1169
}
1170

    
1171
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1172
                     unsigned int size, int sign)
1173
{
1174
        int mem_index = cpu_mmu_index(dc->env);
1175

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

    
1181
        if (size == 1) {
1182
                if (sign)
1183
                        tcg_gen_qemu_ld8s(dst, addr, mem_index);
1184
                else
1185
                        tcg_gen_qemu_ld8u(dst, addr, mem_index);
1186
        }
1187
        else if (size == 2) {
1188
                if (sign)
1189
                        tcg_gen_qemu_ld16s(dst, addr, mem_index);
1190
                else
1191
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
1192
        }
1193
        else if (size == 4) {
1194
                tcg_gen_qemu_ld32u(dst, addr, mem_index);
1195
        }
1196
        else {
1197
                abort();
1198
        }
1199
}
1200

    
1201
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1202
                       unsigned int size)
1203
{
1204
        int mem_index = cpu_mmu_index(dc->env);
1205

    
1206
        /* If we get a fault on a delayslot we must keep the jmp state in
1207
           the cpu-state to be able to re-execute the jmp.  */
1208
        if (dc->delayed_branch == 1)
1209
                 cris_store_direct_jmp(dc);
1210

    
1211

    
1212
        /* Conditional writes. We only support the kind were X and P are known
1213
           at translation time.  */
1214
        if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1215
                dc->postinc = 0;
1216
                cris_evaluate_flags(dc);
1217
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1218
                return;
1219
        }
1220

    
1221
        if (size == 1)
1222
                tcg_gen_qemu_st8(val, addr, mem_index);
1223
        else if (size == 2)
1224
                tcg_gen_qemu_st16(val, addr, mem_index);
1225
        else
1226
                tcg_gen_qemu_st32(val, addr, mem_index);
1227

    
1228
        if (dc->flagx_known && dc->flags_x) {
1229
                cris_evaluate_flags(dc);
1230
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1231
        }
1232
}
1233

    
1234
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1235
{
1236
        if (size == 1)
1237
                tcg_gen_ext8s_i32(d, s);
1238
        else if (size == 2)
1239
                tcg_gen_ext16s_i32(d, s);
1240
        else if(!TCGV_EQUAL(d, s))
1241
                tcg_gen_mov_tl(d, s);
1242
}
1243

    
1244
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1245
{
1246
        if (size == 1)
1247
                tcg_gen_ext8u_i32(d, s);
1248
        else if (size == 2)
1249
                tcg_gen_ext16u_i32(d, s);
1250
        else if (!TCGV_EQUAL(d, s))
1251
                tcg_gen_mov_tl(d, s);
1252
}
1253

    
1254
#if DISAS_CRIS
1255
static char memsize_char(int size)
1256
{
1257
        switch (size)
1258
        {
1259
                case 1: return 'b';  break;
1260
                case 2: return 'w';  break;
1261
                case 4: return 'd';  break;
1262
                default:
1263
                        return 'x';
1264
                        break;
1265
        }
1266
}
1267
#endif
1268

    
1269
static inline unsigned int memsize_z(DisasContext *dc)
1270
{
1271
        return dc->zsize + 1;
1272
}
1273

    
1274
static inline unsigned int memsize_zz(DisasContext *dc)
1275
{
1276
        switch (dc->zzsize)
1277
        {
1278
                case 0: return 1;
1279
                case 1: return 2;
1280
                default:
1281
                        return 4;
1282
        }
1283
}
1284

    
1285
static inline void do_postinc (DisasContext *dc, int size)
1286
{
1287
        if (dc->postinc)
1288
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1289
}
1290

    
1291
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1292
                                   int size, int s_ext, TCGv dst)
1293
{
1294
        if (s_ext)
1295
                t_gen_sext(dst, cpu_R[rs], size);
1296
        else
1297
                t_gen_zext(dst, cpu_R[rs], size);
1298
}
1299

    
1300
/* Prepare T0 and T1 for a register alu operation.
1301
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1302
   needed.  */
1303
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1304
                          int size, int s_ext, TCGv dst, TCGv src)
1305
{
1306
        dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1307

    
1308
        if (s_ext)
1309
                t_gen_sext(dst, cpu_R[rd], size);
1310
        else
1311
                t_gen_zext(dst, cpu_R[rd], size);
1312
}
1313

    
1314
static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1315
                           TCGv dst)
1316
{
1317
        unsigned int rs;
1318
        uint32_t imm;
1319
        int is_imm;
1320
        int insn_len = 2;
1321

    
1322
        rs = dc->op1;
1323
        is_imm = rs == 15 && dc->postinc;
1324

    
1325
        /* Load [$rs] onto T1.  */
1326
        if (is_imm) {
1327
                insn_len = 2 + memsize;
1328
                if (memsize == 1)
1329
                        insn_len++;
1330

    
1331
                imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
1332
                tcg_gen_movi_tl(dst, imm);
1333
                dc->postinc = 0;
1334
        } else {
1335
                cris_flush_cc_state(dc);
1336
                gen_load(dc, dst, cpu_R[rs], memsize, 0);
1337
                if (s_ext)
1338
                        t_gen_sext(dst, dst, memsize);
1339
                else
1340
                        t_gen_zext(dst, dst, memsize);
1341
        }
1342
        return insn_len;
1343
}
1344

    
1345
/* Prepare T0 and T1 for a memory + alu operation.
1346
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1347
   needed.  */
1348
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
1349
                          TCGv dst, TCGv src)
1350
{
1351
        int insn_len;
1352

    
1353
        insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
1354
        tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1355
        return insn_len;
1356
}
1357

    
1358
#if DISAS_CRIS
1359
static const char *cc_name(int cc)
1360
{
1361
        static const char *cc_names[16] = {
1362
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1363
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1364
        };
1365
        assert(cc < 16);
1366
        return cc_names[cc];
1367
}
1368
#endif
1369

    
1370
/* Start of insn decoders.  */
1371

    
1372
static int dec_bccq(DisasContext *dc)
1373
{
1374
        int32_t offset;
1375
        int sign;
1376
        uint32_t cond = dc->op2;
1377

    
1378
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1379
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1380

    
1381
        offset *= 2;
1382
        offset |= sign << 8;
1383
        offset = sign_extend(offset, 8);
1384

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

    
1387
        /* op2 holds the condition-code.  */
1388
        cris_cc_mask(dc, 0);
1389
        cris_prepare_cc_branch (dc, offset, cond);
1390
        return 2;
1391
}
1392
static int dec_addoq(DisasContext *dc)
1393
{
1394
        int32_t imm;
1395

    
1396
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1397
        imm = sign_extend(dc->op1, 7);
1398

    
1399
        LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1400
        cris_cc_mask(dc, 0);
1401
        /* Fetch register operand,  */
1402
        tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1403

    
1404
        return 2;
1405
}
1406
static int dec_addq(DisasContext *dc)
1407
{
1408
        LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1409

    
1410
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1411

    
1412
        cris_cc_mask(dc, CC_MASK_NZVC);
1413

    
1414
        cris_alu(dc, CC_OP_ADD,
1415
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1416
        return 2;
1417
}
1418
static int dec_moveq(DisasContext *dc)
1419
{
1420
        uint32_t imm;
1421

    
1422
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1423
        imm = sign_extend(dc->op1, 5);
1424
        LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1425

    
1426
        tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1427
        return 2;
1428
}
1429
static int dec_subq(DisasContext *dc)
1430
{
1431
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1432

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

    
1435
        cris_cc_mask(dc, CC_MASK_NZVC);
1436
        cris_alu(dc, CC_OP_SUB,
1437
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1438
        return 2;
1439
}
1440
static int dec_cmpq(DisasContext *dc)
1441
{
1442
        uint32_t imm;
1443
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1444
        imm = sign_extend(dc->op1, 5);
1445

    
1446
        LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1447
        cris_cc_mask(dc, CC_MASK_NZVC);
1448

    
1449
        cris_alu(dc, CC_OP_CMP,
1450
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1451
        return 2;
1452
}
1453
static int dec_andq(DisasContext *dc)
1454
{
1455
        uint32_t imm;
1456
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1457
        imm = sign_extend(dc->op1, 5);
1458

    
1459
        LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1460
        cris_cc_mask(dc, CC_MASK_NZ);
1461

    
1462
        cris_alu(dc, CC_OP_AND,
1463
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1464
        return 2;
1465
}
1466
static int dec_orq(DisasContext *dc)
1467
{
1468
        uint32_t imm;
1469
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1470
        imm = sign_extend(dc->op1, 5);
1471
        LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1472
        cris_cc_mask(dc, CC_MASK_NZ);
1473

    
1474
        cris_alu(dc, CC_OP_OR,
1475
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1476
        return 2;
1477
}
1478
static int dec_btstq(DisasContext *dc)
1479
{
1480
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1481
        LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1482

    
1483
        cris_cc_mask(dc, CC_MASK_NZ);
1484
        cris_evaluate_flags(dc);
1485
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1486
                        tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1487
        cris_alu(dc, CC_OP_MOVE,
1488
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1489
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1490
        dc->flags_uptodate = 1;
1491
        return 2;
1492
}
1493
static int dec_asrq(DisasContext *dc)
1494
{
1495
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1496
        LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1497
        cris_cc_mask(dc, CC_MASK_NZ);
1498

    
1499
        tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1500
        cris_alu(dc, CC_OP_MOVE,
1501
                    cpu_R[dc->op2],
1502
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1503
        return 2;
1504
}
1505
static int dec_lslq(DisasContext *dc)
1506
{
1507
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1508
        LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1509

    
1510
        cris_cc_mask(dc, CC_MASK_NZ);
1511

    
1512
        tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1513

    
1514
        cris_alu(dc, CC_OP_MOVE,
1515
                    cpu_R[dc->op2],
1516
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1517
        return 2;
1518
}
1519
static int dec_lsrq(DisasContext *dc)
1520
{
1521
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1522
        LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1523

    
1524
        cris_cc_mask(dc, CC_MASK_NZ);
1525

    
1526
        tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1527
        cris_alu(dc, CC_OP_MOVE,
1528
                    cpu_R[dc->op2],
1529
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1530
        return 2;
1531
}
1532

    
1533
static int dec_move_r(DisasContext *dc)
1534
{
1535
        int size = memsize_zz(dc);
1536

    
1537
        LOG_DIS("move.%c $r%u, $r%u\n",
1538
                    memsize_char(size), dc->op1, dc->op2);
1539

    
1540
        cris_cc_mask(dc, CC_MASK_NZ);
1541
        if (size == 4) {
1542
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1543
                cris_cc_mask(dc, CC_MASK_NZ);
1544
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
1545
                cris_update_cc_x(dc);
1546
                cris_update_result(dc, cpu_R[dc->op2]);
1547
        }
1548
        else {
1549
                TCGv t0;
1550

    
1551
                t0 = tcg_temp_new();
1552
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1553
                cris_alu(dc, CC_OP_MOVE,
1554
                         cpu_R[dc->op2],
1555
                         cpu_R[dc->op2], t0, size);
1556
                tcg_temp_free(t0);
1557
        }
1558
        return 2;
1559
}
1560

    
1561
static int dec_scc_r(DisasContext *dc)
1562
{
1563
        int cond = dc->op2;
1564

    
1565
        LOG_DIS("s%s $r%u\n",
1566
                    cc_name(cond), dc->op1);
1567

    
1568
        if (cond != CC_A)
1569
        {
1570
                int l1;
1571

    
1572
                gen_tst_cc (dc, cpu_R[dc->op1], cond);
1573
                l1 = gen_new_label();
1574
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1575
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1576
                gen_set_label(l1);
1577
        }
1578
        else
1579
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1580

    
1581
        cris_cc_mask(dc, 0);
1582
        return 2;
1583
}
1584

    
1585
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1586
{
1587
        if (size == 4) {
1588
                t[0] = cpu_R[dc->op2];
1589
                t[1] = cpu_R[dc->op1];
1590
        } else {
1591
                t[0] = tcg_temp_new();
1592
                t[1] = tcg_temp_new();
1593
        }
1594
}
1595

    
1596
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1597
{
1598
        if (size != 4) {
1599
                tcg_temp_free(t[0]);
1600
                tcg_temp_free(t[1]);
1601
        }
1602
}
1603

    
1604
static int dec_and_r(DisasContext *dc)
1605
{
1606
        TCGv t[2];
1607
        int size = memsize_zz(dc);
1608

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

    
1612
        cris_cc_mask(dc, CC_MASK_NZ);
1613

    
1614
        cris_alu_alloc_temps(dc, size, t);
1615
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1616
        cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1617
        cris_alu_free_temps(dc, size, t);
1618
        return 2;
1619
}
1620

    
1621
static int dec_lz_r(DisasContext *dc)
1622
{
1623
        TCGv t0;
1624
        LOG_DIS("lz $r%u, $r%u\n",
1625
                    dc->op1, dc->op2);
1626
        cris_cc_mask(dc, CC_MASK_NZ);
1627
        t0 = tcg_temp_new();
1628
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1629
        cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1630
        tcg_temp_free(t0);
1631
        return 2;
1632
}
1633

    
1634
static int dec_lsl_r(DisasContext *dc)
1635
{
1636
        TCGv t[2];
1637
        int size = memsize_zz(dc);
1638

    
1639
        LOG_DIS("lsl.%c $r%u, $r%u\n",
1640
                    memsize_char(size), dc->op1, dc->op2);
1641

    
1642
        cris_cc_mask(dc, CC_MASK_NZ);
1643
        cris_alu_alloc_temps(dc, size, t);
1644
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1645
        tcg_gen_andi_tl(t[1], t[1], 63);
1646
        cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1647
        cris_alu_alloc_temps(dc, size, t);
1648
        return 2;
1649
}
1650

    
1651
static int dec_lsr_r(DisasContext *dc)
1652
{
1653
        TCGv t[2];
1654
        int size = memsize_zz(dc);
1655

    
1656
        LOG_DIS("lsr.%c $r%u, $r%u\n",
1657
                    memsize_char(size), dc->op1, dc->op2);
1658

    
1659
        cris_cc_mask(dc, CC_MASK_NZ);
1660
        cris_alu_alloc_temps(dc, size, t);
1661
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1662
        tcg_gen_andi_tl(t[1], t[1], 63);
1663
        cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1664
        cris_alu_free_temps(dc, size, t);
1665
        return 2;
1666
}
1667

    
1668
static int dec_asr_r(DisasContext *dc)
1669
{
1670
        TCGv t[2];
1671
        int size = memsize_zz(dc);
1672

    
1673
        LOG_DIS("asr.%c $r%u, $r%u\n",
1674
                    memsize_char(size), dc->op1, dc->op2);
1675

    
1676
        cris_cc_mask(dc, CC_MASK_NZ);
1677
        cris_alu_alloc_temps(dc, size, t);
1678
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1679
        tcg_gen_andi_tl(t[1], t[1], 63);
1680
        cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1681
        cris_alu_free_temps(dc, size, t);
1682
        return 2;
1683
}
1684

    
1685
static int dec_muls_r(DisasContext *dc)
1686
{
1687
        TCGv t[2];
1688
        int size = memsize_zz(dc);
1689

    
1690
        LOG_DIS("muls.%c $r%u, $r%u\n",
1691
                    memsize_char(size), dc->op1, dc->op2);
1692
        cris_cc_mask(dc, CC_MASK_NZV);
1693
        cris_alu_alloc_temps(dc, size, t);
1694
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1695

    
1696
        cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1697
        cris_alu_free_temps(dc, size, t);
1698
        return 2;
1699
}
1700

    
1701
static int dec_mulu_r(DisasContext *dc)
1702
{
1703
        TCGv t[2];
1704
        int size = memsize_zz(dc);
1705

    
1706
        LOG_DIS("mulu.%c $r%u, $r%u\n",
1707
                    memsize_char(size), dc->op1, dc->op2);
1708
        cris_cc_mask(dc, CC_MASK_NZV);
1709
        cris_alu_alloc_temps(dc, size, t);
1710
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1711

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

    
1717

    
1718
static int dec_dstep_r(DisasContext *dc)
1719
{
1720
        LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1721
        cris_cc_mask(dc, CC_MASK_NZ);
1722
        cris_alu(dc, CC_OP_DSTEP,
1723
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1724
        return 2;
1725
}
1726

    
1727
static int dec_xor_r(DisasContext *dc)
1728
{
1729
        TCGv t[2];
1730
        int size = memsize_zz(dc);
1731
        LOG_DIS("xor.%c $r%u, $r%u\n",
1732
                    memsize_char(size), dc->op1, dc->op2);
1733
        BUG_ON(size != 4); /* xor is dword.  */
1734
        cris_cc_mask(dc, CC_MASK_NZ);
1735
        cris_alu_alloc_temps(dc, size, t);
1736
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1737

    
1738
        cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1739
        cris_alu_free_temps(dc, size, t);
1740
        return 2;
1741
}
1742

    
1743
static int dec_bound_r(DisasContext *dc)
1744
{
1745
        TCGv l0;
1746
        int size = memsize_zz(dc);
1747
        LOG_DIS("bound.%c $r%u, $r%u\n",
1748
                    memsize_char(size), dc->op1, dc->op2);
1749
        cris_cc_mask(dc, CC_MASK_NZ);
1750
        l0 = tcg_temp_local_new();
1751
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1752
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1753
        tcg_temp_free(l0);
1754
        return 2;
1755
}
1756

    
1757
static int dec_cmp_r(DisasContext *dc)
1758
{
1759
        TCGv t[2];
1760
        int size = memsize_zz(dc);
1761
        LOG_DIS("cmp.%c $r%u, $r%u\n",
1762
                    memsize_char(size), dc->op1, dc->op2);
1763
        cris_cc_mask(dc, CC_MASK_NZVC);
1764
        cris_alu_alloc_temps(dc, size, t);
1765
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1766

    
1767
        cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1768
        cris_alu_free_temps(dc, size, t);
1769
        return 2;
1770
}
1771

    
1772
static int dec_abs_r(DisasContext *dc)
1773
{
1774
        TCGv t0;
1775

    
1776
        LOG_DIS("abs $r%u, $r%u\n",
1777
                    dc->op1, dc->op2);
1778
        cris_cc_mask(dc, CC_MASK_NZ);
1779

    
1780
        t0 = tcg_temp_new();
1781
        tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1782
        tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1783
        tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1784
        tcg_temp_free(t0);
1785

    
1786
        cris_alu(dc, CC_OP_MOVE,
1787
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1788
        return 2;
1789
}
1790

    
1791
static int dec_add_r(DisasContext *dc)
1792
{
1793
        TCGv t[2];
1794
        int size = memsize_zz(dc);
1795
        LOG_DIS("add.%c $r%u, $r%u\n",
1796
                    memsize_char(size), dc->op1, dc->op2);
1797
        cris_cc_mask(dc, CC_MASK_NZVC);
1798
        cris_alu_alloc_temps(dc, size, t);
1799
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1800

    
1801
        cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1802
        cris_alu_free_temps(dc, size, t);
1803
        return 2;
1804
}
1805

    
1806
static int dec_addc_r(DisasContext *dc)
1807
{
1808
        LOG_DIS("addc $r%u, $r%u\n",
1809
                    dc->op1, dc->op2);
1810
        cris_evaluate_flags(dc);
1811
        /* Set for this insn.  */
1812
        dc->flagx_known = 1;
1813
        dc->flags_x = X_FLAG;
1814

    
1815
        cris_cc_mask(dc, CC_MASK_NZVC);
1816
        cris_alu(dc, CC_OP_ADDC,
1817
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1818
        return 2;
1819
}
1820

    
1821
static int dec_mcp_r(DisasContext *dc)
1822
{
1823
        LOG_DIS("mcp $p%u, $r%u\n",
1824
                     dc->op2, dc->op1);
1825
        cris_evaluate_flags(dc);
1826
        cris_cc_mask(dc, CC_MASK_RNZV);
1827
        cris_alu(dc, CC_OP_MCP,
1828
                    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1829
        return 2;
1830
}
1831

    
1832
#if DISAS_CRIS
1833
static char * swapmode_name(int mode, char *modename) {
1834
        int i = 0;
1835
        if (mode & 8)
1836
                modename[i++] = 'n';
1837
        if (mode & 4)
1838
                modename[i++] = 'w';
1839
        if (mode & 2)
1840
                modename[i++] = 'b';
1841
        if (mode & 1)
1842
                modename[i++] = 'r';
1843
        modename[i++] = 0;
1844
        return modename;
1845
}
1846
#endif
1847

    
1848
static int dec_swap_r(DisasContext *dc)
1849
{
1850
        TCGv t0;
1851
#if DISAS_CRIS
1852
        char modename[4];
1853
#endif
1854
        LOG_DIS("swap%s $r%u\n",
1855
                     swapmode_name(dc->op2, modename), dc->op1);
1856

    
1857
        cris_cc_mask(dc, CC_MASK_NZ);
1858
        t0 = tcg_temp_new();
1859
        t_gen_mov_TN_reg(t0, dc->op1);
1860
        if (dc->op2 & 8)
1861
                tcg_gen_not_tl(t0, t0);
1862
        if (dc->op2 & 4)
1863
                t_gen_swapw(t0, t0);
1864
        if (dc->op2 & 2)
1865
                t_gen_swapb(t0, t0);
1866
        if (dc->op2 & 1)
1867
                t_gen_swapr(t0, t0);
1868
        cris_alu(dc, CC_OP_MOVE,
1869
                    cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1870
        tcg_temp_free(t0);
1871
        return 2;
1872
}
1873

    
1874
static int dec_or_r(DisasContext *dc)
1875
{
1876
        TCGv t[2];
1877
        int size = memsize_zz(dc);
1878
        LOG_DIS("or.%c $r%u, $r%u\n",
1879
                    memsize_char(size), dc->op1, dc->op2);
1880
        cris_cc_mask(dc, CC_MASK_NZ);
1881
        cris_alu_alloc_temps(dc, size, t);
1882
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1883
        cris_alu(dc, CC_OP_OR, 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_addi_r(DisasContext *dc)
1889
{
1890
        TCGv t0;
1891
        LOG_DIS("addi.%c $r%u, $r%u\n",
1892
                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1893
        cris_cc_mask(dc, 0);
1894
        t0 = tcg_temp_new();
1895
        tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1896
        tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1897
        tcg_temp_free(t0);
1898
        return 2;
1899
}
1900

    
1901
static int dec_addi_acr(DisasContext *dc)
1902
{
1903
        TCGv t0;
1904
        LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1905
                  memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1906
        cris_cc_mask(dc, 0);
1907
        t0 = tcg_temp_new();
1908
        tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1909
        tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1910
        tcg_temp_free(t0);
1911
        return 2;
1912
}
1913

    
1914
static int dec_neg_r(DisasContext *dc)
1915
{
1916
        TCGv t[2];
1917
        int size = memsize_zz(dc);
1918
        LOG_DIS("neg.%c $r%u, $r%u\n",
1919
                    memsize_char(size), dc->op1, dc->op2);
1920
        cris_cc_mask(dc, CC_MASK_NZVC);
1921
        cris_alu_alloc_temps(dc, size, t);
1922
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1923

    
1924
        cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1925
        cris_alu_free_temps(dc, size, t);
1926
        return 2;
1927
}
1928

    
1929
static int dec_btst_r(DisasContext *dc)
1930
{
1931
        LOG_DIS("btst $r%u, $r%u\n",
1932
                    dc->op1, dc->op2);
1933
        cris_cc_mask(dc, CC_MASK_NZ);
1934
        cris_evaluate_flags(dc);
1935
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1936
                        cpu_R[dc->op1], cpu_PR[PR_CCS]);
1937
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1938
                 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1939
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1940
        dc->flags_uptodate = 1;
1941
        return 2;
1942
}
1943

    
1944
static int dec_sub_r(DisasContext *dc)
1945
{
1946
        TCGv t[2];
1947
        int size = memsize_zz(dc);
1948
        LOG_DIS("sub.%c $r%u, $r%u\n",
1949
                    memsize_char(size), dc->op1, dc->op2);
1950
        cris_cc_mask(dc, CC_MASK_NZVC);
1951
        cris_alu_alloc_temps(dc, size, t);
1952
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1953
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1954
        cris_alu_free_temps(dc, size, t);
1955
        return 2;
1956
}
1957

    
1958
/* Zero extension. From size to dword.  */
1959
static int dec_movu_r(DisasContext *dc)
1960
{
1961
        TCGv t0;
1962
        int size = memsize_z(dc);
1963
        LOG_DIS("movu.%c $r%u, $r%u\n",
1964
                    memsize_char(size),
1965
                    dc->op1, dc->op2);
1966

    
1967
        cris_cc_mask(dc, CC_MASK_NZ);
1968
        t0 = tcg_temp_new();
1969
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1970
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1971
        tcg_temp_free(t0);
1972
        return 2;
1973
}
1974

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

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

    
1994
/* zero extension. From size to dword.  */
1995
static int dec_addu_r(DisasContext *dc)
1996
{
1997
        TCGv t0;
1998
        int size = memsize_z(dc);
1999
        LOG_DIS("addu.%c $r%u, $r%u\n",
2000
                    memsize_char(size),
2001
                    dc->op1, dc->op2);
2002

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

    
2013
/* Sign extension. From size to dword.  */
2014
static int dec_adds_r(DisasContext *dc)
2015
{
2016
        TCGv t0;
2017
        int size = memsize_z(dc);
2018
        LOG_DIS("adds.%c $r%u, $r%u\n",
2019
                    memsize_char(size),
2020
                    dc->op1, dc->op2);
2021

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

    
2032
/* Zero extension. From size to dword.  */
2033
static int dec_subu_r(DisasContext *dc)
2034
{
2035
        TCGv t0;
2036
        int size = memsize_z(dc);
2037
        LOG_DIS("subu.%c $r%u, $r%u\n",
2038
                    memsize_char(size),
2039
                    dc->op1, dc->op2);
2040

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

    
2051
/* Sign extension. From size to dword.  */
2052
static int dec_subs_r(DisasContext *dc)
2053
{
2054
        TCGv t0;
2055
        int size = memsize_z(dc);
2056
        LOG_DIS("subs.%c $r%u, $r%u\n",
2057
                    memsize_char(size),
2058
                    dc->op1, dc->op2);
2059

    
2060
        cris_cc_mask(dc, CC_MASK_NZVC);
2061
        t0 = tcg_temp_new();
2062
        /* Size can only be qi or hi.  */
2063
        t_gen_sext(t0, cpu_R[dc->op1], size);
2064
        cris_alu(dc, CC_OP_SUB,
2065
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2066
        tcg_temp_free(t0);
2067
        return 2;
2068
}
2069

    
2070
static int dec_setclrf(DisasContext *dc)
2071
{
2072
        uint32_t flags;
2073
        int set = (~dc->opcode >> 2) & 1;
2074

    
2075

    
2076
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2077
                | EXTRACT_FIELD(dc->ir, 0, 3);
2078
        if (set && flags == 0) {
2079
                LOG_DIS("nop\n");
2080
                return 2;
2081
        } else if (!set && (flags & 0x20)) {
2082
                LOG_DIS("di\n");
2083
        }
2084
        else {
2085
                LOG_DIS("%sf %x\n",
2086
                             set ? "set" : "clr",
2087
                            flags);
2088
        }
2089

    
2090
        /* User space is not allowed to touch these. Silently ignore.  */
2091
        if (dc->tb_flags & U_FLAG) {
2092
                flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2093
        }
2094

    
2095
        if (flags & X_FLAG) {
2096
                dc->flagx_known = 1;
2097
                if (set)
2098
                        dc->flags_x = X_FLAG;
2099
                else
2100
                        dc->flags_x = 0;
2101
        }
2102

    
2103
        /* Break the TB if any of the SPI flag changes.  */
2104
        if (flags & (P_FLAG | S_FLAG)) {
2105
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2106
                dc->is_jmp = DISAS_UPDATE;
2107
                dc->cpustate_changed = 1;
2108
        }
2109

    
2110
        /* For the I flag, only act on posedge.  */
2111
        if ((flags & I_FLAG)) {
2112
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2113
                dc->is_jmp = DISAS_UPDATE;
2114
                dc->cpustate_changed = 1;
2115
        }
2116

    
2117

    
2118
        /* Simply decode the flags.  */
2119
        cris_evaluate_flags (dc);
2120
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2121
        cris_update_cc_x(dc);
2122
        tcg_gen_movi_tl(cc_op, dc->cc_op);
2123

    
2124
        if (set) {
2125
                if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2126
                        /* Enter user mode.  */
2127
                        t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2128
                        tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2129
                        dc->cpustate_changed = 1;
2130
                }
2131
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2132
        }
2133
        else
2134
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2135

    
2136
        dc->flags_uptodate = 1;
2137
        dc->clear_x = 0;
2138
        return 2;
2139
}
2140

    
2141
static int dec_move_rs(DisasContext *dc)
2142
{
2143
        LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2144
        cris_cc_mask(dc, 0);
2145
        gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
2146
        return 2;
2147
}
2148
static int dec_move_sr(DisasContext *dc)
2149
{
2150
        LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2151
        cris_cc_mask(dc, 0);
2152
        gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
2153
        return 2;
2154
}
2155

    
2156
static int dec_move_rp(DisasContext *dc)
2157
{
2158
        TCGv t[2];
2159
        LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2160
        cris_cc_mask(dc, 0);
2161

    
2162
        t[0] = tcg_temp_new();
2163
        if (dc->op2 == PR_CCS) {
2164
                cris_evaluate_flags(dc);
2165
                t_gen_mov_TN_reg(t[0], dc->op1);
2166
                if (dc->tb_flags & U_FLAG) {
2167
                        t[1] = tcg_temp_new();
2168
                        /* User space is not allowed to touch all flags.  */
2169
                        tcg_gen_andi_tl(t[0], t[0], 0x39f);
2170
                        tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2171
                        tcg_gen_or_tl(t[0], t[1], t[0]);
2172
                        tcg_temp_free(t[1]);
2173
                }
2174
        }
2175
        else
2176
                t_gen_mov_TN_reg(t[0], dc->op1);
2177

    
2178
        t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2179
        if (dc->op2 == PR_CCS) {
2180
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2181
                dc->flags_uptodate = 1;
2182
        }
2183
        tcg_temp_free(t[0]);
2184
        return 2;
2185
}
2186
static int dec_move_pr(DisasContext *dc)
2187
{
2188
        TCGv t0;
2189
        LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2190
        cris_cc_mask(dc, 0);
2191

    
2192
        if (dc->op2 == PR_CCS)
2193
                cris_evaluate_flags(dc);
2194

    
2195
        if (dc->op2 == PR_DZ) {
2196
                tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2197
        } else {
2198
                t0 = tcg_temp_new();
2199
                t_gen_mov_TN_preg(t0, dc->op2);
2200
                cris_alu(dc, CC_OP_MOVE,
2201
                         cpu_R[dc->op1], cpu_R[dc->op1], t0,
2202
                         preg_sizes[dc->op2]);
2203
                tcg_temp_free(t0);
2204
        }
2205
        return 2;
2206
}
2207

    
2208
static int dec_move_mr(DisasContext *dc)
2209
{
2210
        int memsize = memsize_zz(dc);
2211
        int insn_len;
2212
        LOG_DIS("move.%c [$r%u%s, $r%u\n",
2213
                    memsize_char(memsize),
2214
                    dc->op1, dc->postinc ? "+]" : "]",
2215
                    dc->op2);
2216

    
2217
        if (memsize == 4) {
2218
                insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
2219
                cris_cc_mask(dc, CC_MASK_NZ);
2220
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
2221
                cris_update_cc_x(dc);
2222
                cris_update_result(dc, cpu_R[dc->op2]);
2223
        }
2224
        else {
2225
                TCGv t0;
2226

    
2227
                t0 = tcg_temp_new();
2228
                insn_len = dec_prep_move_m(dc, 0, memsize, t0);
2229
                cris_cc_mask(dc, CC_MASK_NZ);
2230
                cris_alu(dc, CC_OP_MOVE,
2231
                            cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2232
                tcg_temp_free(t0);
2233
        }
2234
        do_postinc(dc, memsize);
2235
        return insn_len;
2236
}
2237

    
2238
static inline void cris_alu_m_alloc_temps(TCGv *t)
2239
{
2240
        t[0] = tcg_temp_new();
2241
        t[1] = tcg_temp_new();
2242
}
2243

    
2244
static inline void cris_alu_m_free_temps(TCGv *t)
2245
{
2246
        tcg_temp_free(t[0]);
2247
        tcg_temp_free(t[1]);
2248
}
2249

    
2250
static int dec_movs_m(DisasContext *dc)
2251
{
2252
        TCGv t[2];
2253
        int memsize = memsize_z(dc);
2254
        int insn_len;
2255
        LOG_DIS("movs.%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(dc, 1, memsize, t[0], t[1]);
2263
        cris_cc_mask(dc, CC_MASK_NZ);
2264
        cris_alu(dc, CC_OP_MOVE,
2265
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2266
        do_postinc(dc, memsize);
2267
        cris_alu_m_free_temps(t);
2268
        return insn_len;
2269
}
2270

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

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

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

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

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

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

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

    
2342
        cris_alu_m_alloc_temps(t);
2343
        /* sign extend.  */
2344
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2345
        cris_cc_mask(dc, CC_MASK_NZVC);
2346
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2347
        do_postinc(dc, memsize);
2348
        cris_alu_m_free_temps(t);
2349
        return insn_len;
2350
}
2351

    
2352
static int dec_movu_m(DisasContext *dc)
2353
{
2354
        TCGv t[2];
2355
        int memsize = memsize_z(dc);
2356
        int insn_len;
2357

    
2358
        LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2359
                    memsize_char(memsize),
2360
                    dc->op1, dc->postinc ? "+]" : "]",
2361
                    dc->op2);
2362

    
2363
        cris_alu_m_alloc_temps(t);
2364
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2365
        cris_cc_mask(dc, CC_MASK_NZ);
2366
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2367
        do_postinc(dc, memsize);
2368
        cris_alu_m_free_temps(t);
2369
        return insn_len;
2370
}
2371

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

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

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

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

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

    
2422
        cris_alu_m_alloc_temps(t);
2423
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2424
        cris_cc_mask(dc, CC_MASK_NZVC);
2425
        cris_alu(dc, CC_OP_CMP,
2426
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2427
                    memsize_zz(dc));
2428
        do_postinc(dc, memsize);
2429
        cris_alu_m_free_temps(t);
2430
        return insn_len;
2431
}
2432

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

    
2443
        cris_evaluate_flags(dc);
2444

    
2445
        cris_alu_m_alloc_temps(t);
2446
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2447
        cris_cc_mask(dc, CC_MASK_NZ);
2448
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2449

    
2450
        cris_alu(dc, CC_OP_CMP,
2451
                 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2452
        do_postinc(dc, memsize);
2453
        cris_alu_m_free_temps(t);
2454
        return insn_len;
2455
}
2456

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

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

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

    
2486
        cris_alu_m_alloc_temps(t);
2487
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2488
        cris_cc_mask(dc, CC_MASK_NZVC);
2489
        cris_alu(dc, CC_OP_ADD,
2490
                 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2491
        do_postinc(dc, memsize);
2492
        cris_alu_m_free_temps(t);
2493
        return insn_len;
2494
}
2495

    
2496
static int dec_addo_m(DisasContext *dc)
2497
{
2498
        TCGv t[2];
2499
        int memsize = memsize_zz(dc);
2500
        int insn_len;
2501
        LOG_DIS("add.%c [$r%u%s, $r%u\n",
2502
                    memsize_char(memsize),
2503
                    dc->op1, dc->postinc ? "+]" : "]",
2504
                    dc->op2);
2505

    
2506
        cris_alu_m_alloc_temps(t);
2507
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2508
        cris_cc_mask(dc, 0);
2509
        cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2510
        do_postinc(dc, memsize);
2511
        cris_alu_m_free_temps(t);
2512
        return insn_len;
2513
}
2514

    
2515
static int dec_bound_m(DisasContext *dc)
2516
{
2517
        TCGv l[2];
2518
        int memsize = memsize_zz(dc);
2519
        int insn_len;
2520
        LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2521
                    memsize_char(memsize),
2522
                    dc->op1, dc->postinc ? "+]" : "]",
2523
                    dc->op2);
2524

    
2525
        l[0] = tcg_temp_local_new();
2526
        l[1] = tcg_temp_local_new();
2527
        insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
2528
        cris_cc_mask(dc, CC_MASK_NZ);
2529
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2530
        do_postinc(dc, memsize);
2531
        tcg_temp_free(l[0]);
2532
        tcg_temp_free(l[1]);
2533
        return insn_len;
2534
}
2535

    
2536
static int dec_addc_mr(DisasContext *dc)
2537
{
2538
        TCGv t[2];
2539
        int insn_len = 2;
2540
        LOG_DIS("addc [$r%u%s, $r%u\n",
2541
                    dc->op1, dc->postinc ? "+]" : "]",
2542
                    dc->op2);
2543

    
2544
        cris_evaluate_flags(dc);
2545

    
2546
        /* Set for this insn.  */
2547
        dc->flagx_known = 1;
2548
        dc->flags_x = X_FLAG;
2549

    
2550
        cris_alu_m_alloc_temps(t);
2551
        insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2552
        cris_cc_mask(dc, CC_MASK_NZVC);
2553
        cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2554
        do_postinc(dc, 4);
2555
        cris_alu_m_free_temps(t);
2556
        return insn_len;
2557
}
2558

    
2559
static int dec_sub_m(DisasContext *dc)
2560
{
2561
        TCGv t[2];
2562
        int memsize = memsize_zz(dc);
2563
        int insn_len;
2564
        LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2565
                    memsize_char(memsize),
2566
                    dc->op1, dc->postinc ? "+]" : "]",
2567
                    dc->op2, dc->ir, dc->zzsize);
2568

    
2569
        cris_alu_m_alloc_temps(t);
2570
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2571
        cris_cc_mask(dc, CC_MASK_NZVC);
2572
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2573
        do_postinc(dc, memsize);
2574
        cris_alu_m_free_temps(t);
2575
        return insn_len;
2576
}
2577

    
2578
static int dec_or_m(DisasContext *dc)
2579
{
2580
        TCGv t[2];
2581
        int memsize = memsize_zz(dc);
2582
        int insn_len;
2583
        LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2584
                    memsize_char(memsize),
2585
                    dc->op1, dc->postinc ? "+]" : "]",
2586
                    dc->op2, dc->pc);
2587

    
2588
        cris_alu_m_alloc_temps(t);
2589
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2590
        cris_cc_mask(dc, CC_MASK_NZ);
2591
        cris_alu(dc, CC_OP_OR,
2592
                    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2593
        do_postinc(dc, memsize);
2594
        cris_alu_m_free_temps(t);
2595
        return insn_len;
2596
}
2597

    
2598
static int dec_move_mp(DisasContext *dc)
2599
{
2600
        TCGv t[2];
2601
        int memsize = memsize_zz(dc);
2602
        int insn_len = 2;
2603

    
2604
        LOG_DIS("move.%c [$r%u%s, $p%u\n",
2605
                    memsize_char(memsize),
2606
                    dc->op1,
2607
                    dc->postinc ? "+]" : "]",
2608
                    dc->op2);
2609

    
2610
        cris_alu_m_alloc_temps(t);
2611
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2612
        cris_cc_mask(dc, 0);
2613
        if (dc->op2 == PR_CCS) {
2614
                cris_evaluate_flags(dc);
2615
                if (dc->tb_flags & U_FLAG) {
2616
                        /* User space is not allowed to touch all flags.  */
2617
                        tcg_gen_andi_tl(t[1], t[1], 0x39f);
2618
                        tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2619
                        tcg_gen_or_tl(t[1], t[0], t[1]);
2620
                }
2621
        }
2622

    
2623
        t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2624

    
2625
        do_postinc(dc, memsize);
2626
        cris_alu_m_free_temps(t);
2627
        return insn_len;
2628
}
2629

    
2630
static int dec_move_pm(DisasContext *dc)
2631
{
2632
        TCGv t0;
2633
        int memsize;
2634

    
2635
        memsize = preg_sizes[dc->op2];
2636

    
2637
        LOG_DIS("move.%c $p%u, [$r%u%s\n",
2638
                     memsize_char(memsize), 
2639
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2640

    
2641
        /* prepare store. Address in T0, value in T1.  */
2642
        if (dc->op2 == PR_CCS)
2643
                cris_evaluate_flags(dc);
2644
        t0 = tcg_temp_new();
2645
        t_gen_mov_TN_preg(t0, dc->op2);
2646
        cris_flush_cc_state(dc);
2647
        gen_store(dc, cpu_R[dc->op1], t0, memsize);
2648
        tcg_temp_free(t0);
2649

    
2650
        cris_cc_mask(dc, 0);
2651
        if (dc->postinc)
2652
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2653
        return 2;
2654
}
2655

    
2656
static int dec_movem_mr(DisasContext *dc)
2657
{
2658
        TCGv_i64 tmp[16];
2659
        TCGv tmp32;
2660
        TCGv addr;
2661
        int i;
2662
        int nr = dc->op2 + 1;
2663

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

    
2667
        addr = tcg_temp_new();
2668
        /* There are probably better ways of doing this.  */
2669
        cris_flush_cc_state(dc);
2670
        for (i = 0; i < (nr >> 1); i++) {
2671
                tmp[i] = tcg_temp_new_i64();
2672
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2673
                gen_load64(dc, tmp[i], addr);
2674
        }
2675
        if (nr & 1) {
2676
                tmp32 = tcg_temp_new_i32();
2677
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2678
                gen_load(dc, tmp32, addr, 4, 0);
2679
        } else
2680
                TCGV_UNUSED(tmp32);
2681
        tcg_temp_free(addr);
2682

    
2683
        for (i = 0; i < (nr >> 1); i++) {
2684
                tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2685
                tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2686
                tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2687
                tcg_temp_free_i64(tmp[i]);
2688
        }
2689
        if (nr & 1) {
2690
                tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2691
                tcg_temp_free(tmp32);
2692
        }
2693

    
2694
        /* writeback the updated pointer value.  */
2695
        if (dc->postinc)
2696
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2697

    
2698
        /* gen_load might want to evaluate the previous insns flags.  */
2699
        cris_cc_mask(dc, 0);
2700
        return 2;
2701
}
2702

    
2703
static int dec_movem_rm(DisasContext *dc)
2704
{
2705
        TCGv tmp;
2706
        TCGv addr;
2707
        int i;
2708

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

    
2712
        cris_flush_cc_state(dc);
2713

    
2714
        tmp = tcg_temp_new();
2715
        addr = tcg_temp_new();
2716
        tcg_gen_movi_tl(tmp, 4);
2717
        tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2718
        for (i = 0; i <= dc->op2; i++) {
2719
                /* Displace addr.  */
2720
                /* Perform the store.  */
2721
                gen_store(dc, addr, cpu_R[i], 4);
2722
                tcg_gen_add_tl(addr, addr, tmp);
2723
        }
2724
        if (dc->postinc)
2725
                tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2726
        cris_cc_mask(dc, 0);
2727
        tcg_temp_free(tmp);
2728
        tcg_temp_free(addr);
2729
        return 2;
2730
}
2731

    
2732
static int dec_move_rm(DisasContext *dc)
2733
{
2734
        int memsize;
2735

    
2736
        memsize = memsize_zz(dc);
2737

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

    
2741
        /* prepare store.  */
2742
        cris_flush_cc_state(dc);
2743
        gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2744

    
2745
        if (dc->postinc)
2746
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2747
        cris_cc_mask(dc, 0);
2748
        return 2;
2749
}
2750

    
2751
static int dec_lapcq(DisasContext *dc)
2752
{
2753
        LOG_DIS("lapcq %x, $r%u\n",
2754
                    dc->pc + dc->op1*2, dc->op2);
2755
        cris_cc_mask(dc, 0);
2756
        tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2757
        return 2;
2758
}
2759

    
2760
static int dec_lapc_im(DisasContext *dc)
2761
{
2762
        unsigned int rd;
2763
        int32_t imm;
2764
        int32_t pc;
2765

    
2766
        rd = dc->op2;
2767

    
2768
        cris_cc_mask(dc, 0);
2769
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2770
        LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2771

    
2772
        pc = dc->pc;
2773
        pc += imm;
2774
        tcg_gen_movi_tl(cpu_R[rd], pc);
2775
        return 6;
2776
}
2777

    
2778
/* Jump to special reg.  */
2779
static int dec_jump_p(DisasContext *dc)
2780
{
2781
        LOG_DIS("jump $p%u\n", dc->op2);
2782

    
2783
        if (dc->op2 == PR_CCS)
2784
                cris_evaluate_flags(dc);
2785
        t_gen_mov_TN_preg(env_btarget, dc->op2);
2786
        /* rete will often have low bit set to indicate delayslot.  */
2787
        tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2788
        cris_cc_mask(dc, 0);
2789
        cris_prepare_jmp(dc, JMP_INDIRECT);
2790
        return 2;
2791
}
2792

    
2793
/* Jump and save.  */
2794
static int dec_jas_r(DisasContext *dc)
2795
{
2796
        LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2797
        cris_cc_mask(dc, 0);
2798
        /* Store the return address in Pd.  */
2799
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2800
        if (dc->op2 > 15)
2801
                abort();
2802
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
2803

    
2804
        cris_prepare_jmp(dc, JMP_INDIRECT);
2805
        return 2;
2806
}
2807

    
2808
static int dec_jas_im(DisasContext *dc)
2809
{
2810
        uint32_t imm;
2811

    
2812
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2813

    
2814
        LOG_DIS("jas 0x%x\n", imm);
2815
        cris_cc_mask(dc, 0);
2816
        /* Store the return address in Pd.  */
2817
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2818

    
2819
        dc->jmp_pc = imm;
2820
        cris_prepare_jmp(dc, JMP_DIRECT);
2821
        return 6;
2822
}
2823

    
2824
static int dec_jasc_im(DisasContext *dc)
2825
{
2826
        uint32_t imm;
2827

    
2828
        imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2829

    
2830
        LOG_DIS("jasc 0x%x\n", imm);
2831
        cris_cc_mask(dc, 0);
2832
        /* Store the return address in Pd.  */
2833
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2834

    
2835
        dc->jmp_pc = imm;
2836
        cris_prepare_jmp(dc, JMP_DIRECT);
2837
        return 6;
2838
}
2839

    
2840
static int dec_jasc_r(DisasContext *dc)
2841
{
2842
        LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2843
        cris_cc_mask(dc, 0);
2844
        /* Store the return address in Pd.  */
2845
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2846
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
2847
        cris_prepare_jmp(dc, JMP_INDIRECT);
2848
        return 2;
2849
}
2850

    
2851
static int dec_bcc_im(DisasContext *dc)
2852
{
2853
        int32_t offset;
2854
        uint32_t cond = dc->op2;
2855

    
2856
        offset = cris_fetch(dc, dc->pc + 2, 2, 1);
2857

    
2858
        LOG_DIS("b%s %d pc=%x dst=%x\n",
2859
                    cc_name(cond), offset,
2860
                    dc->pc, dc->pc + offset);
2861

    
2862
        cris_cc_mask(dc, 0);
2863
        /* op2 holds the condition-code.  */
2864
        cris_prepare_cc_branch (dc, offset, cond);
2865
        return 4;
2866
}
2867

    
2868
static int dec_bas_im(DisasContext *dc)
2869
{
2870
        int32_t simm;
2871

    
2872

    
2873
        simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2874

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

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

    
2885
static int dec_basc_im(DisasContext *dc)
2886
{
2887
        int32_t simm;
2888
        simm = cris_fetch(dc, dc->pc + 2, 4, 0);
2889

    
2890
        LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2891
        cris_cc_mask(dc, 0);
2892
        /* Store the return address in Pd.  */
2893
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2894

    
2895
        dc->jmp_pc = dc->pc + simm;
2896
        cris_prepare_jmp(dc, JMP_DIRECT);
2897
        return 6;
2898
}
2899

    
2900
static int dec_rfe_etc(DisasContext *dc)
2901
{
2902
        cris_cc_mask(dc, 0);
2903

    
2904
        if (dc->op2 == 15) {
2905
                t_gen_mov_env_TN(halted, tcg_const_tl(1));
2906
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2907
                t_gen_raise_exception(EXCP_HLT);
2908
                return 2;
2909
        }
2910

    
2911
        switch (dc->op2 & 7) {
2912
                case 2:
2913
                        /* rfe.  */
2914
                        LOG_DIS("rfe\n");
2915
                        cris_evaluate_flags(dc);
2916
                        gen_helper_rfe();
2917
                        dc->is_jmp = DISAS_UPDATE;
2918
                        break;
2919
                case 5:
2920
                        /* rfn.  */
2921
                        LOG_DIS("rfn\n");
2922
                        cris_evaluate_flags(dc);
2923
                        gen_helper_rfn();
2924
                        dc->is_jmp = DISAS_UPDATE;
2925
                        break;
2926
                case 6:
2927
                        LOG_DIS("break %d\n", dc->op1);
2928
                        cris_evaluate_flags (dc);
2929
                        /* break.  */
2930
                        tcg_gen_movi_tl(env_pc, dc->pc + 2);
2931

    
2932
                        /* Breaks start at 16 in the exception vector.  */
2933
                        t_gen_mov_env_TN(trap_vector, 
2934
                                         tcg_const_tl(dc->op1 + 16));
2935
                        t_gen_raise_exception(EXCP_BREAK);
2936
                        dc->is_jmp = DISAS_UPDATE;
2937
                        break;
2938
                default:
2939
                        printf ("op2=%x\n", dc->op2);
2940
                        BUG();
2941
                        break;
2942

    
2943
        }
2944
        return 2;
2945
}
2946

    
2947
static int dec_ftag_fidx_d_m(DisasContext *dc)
2948
{
2949
        return 2;
2950
}
2951

    
2952
static int dec_ftag_fidx_i_m(DisasContext *dc)
2953
{
2954
        return 2;
2955
}
2956

    
2957
static int dec_null(DisasContext *dc)
2958
{
2959
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2960
                dc->pc, dc->opcode, dc->op1, dc->op2);
2961
        fflush(NULL);
2962
        BUG();
2963
        return 2;
2964
}
2965

    
2966
static struct decoder_info {
2967
        struct {
2968
                uint32_t bits;
2969
                uint32_t mask;
2970
        };
2971
        int (*dec)(DisasContext *dc);
2972
} decinfo[] = {
2973
        /* Order matters here.  */
2974
        {DEC_MOVEQ, dec_moveq},
2975
        {DEC_BTSTQ, dec_btstq},
2976
        {DEC_CMPQ, dec_cmpq},
2977
        {DEC_ADDOQ, dec_addoq},
2978
        {DEC_ADDQ, dec_addq},
2979
        {DEC_SUBQ, dec_subq},
2980
        {DEC_ANDQ, dec_andq},
2981
        {DEC_ORQ, dec_orq},
2982
        {DEC_ASRQ, dec_asrq},
2983
        {DEC_LSLQ, dec_lslq},
2984
        {DEC_LSRQ, dec_lsrq},
2985
        {DEC_BCCQ, dec_bccq},
2986

    
2987
        {DEC_BCC_IM, dec_bcc_im},
2988
        {DEC_JAS_IM, dec_jas_im},
2989
        {DEC_JAS_R, dec_jas_r},
2990
        {DEC_JASC_IM, dec_jasc_im},
2991
        {DEC_JASC_R, dec_jasc_r},
2992
        {DEC_BAS_IM, dec_bas_im},
2993
        {DEC_BASC_IM, dec_basc_im},
2994
        {DEC_JUMP_P, dec_jump_p},
2995
        {DEC_LAPC_IM, dec_lapc_im},
2996
        {DEC_LAPCQ, dec_lapcq},
2997

    
2998
        {DEC_RFE_ETC, dec_rfe_etc},
2999
        {DEC_ADDC_MR, dec_addc_mr},
3000

    
3001
        {DEC_MOVE_MP, dec_move_mp},
3002
        {DEC_MOVE_PM, dec_move_pm},
3003
        {DEC_MOVEM_MR, dec_movem_mr},
3004
        {DEC_MOVEM_RM, dec_movem_rm},
3005
        {DEC_MOVE_PR, dec_move_pr},
3006
        {DEC_SCC_R, dec_scc_r},
3007
        {DEC_SETF, dec_setclrf},
3008
        {DEC_CLEARF, dec_setclrf},
3009

    
3010
        {DEC_MOVE_SR, dec_move_sr},
3011
        {DEC_MOVE_RP, dec_move_rp},
3012
        {DEC_SWAP_R, dec_swap_r},
3013
        {DEC_ABS_R, dec_abs_r},
3014
        {DEC_LZ_R, dec_lz_r},
3015
        {DEC_MOVE_RS, dec_move_rs},
3016
        {DEC_BTST_R, dec_btst_r},
3017
        {DEC_ADDC_R, dec_addc_r},
3018

    
3019
        {DEC_DSTEP_R, dec_dstep_r},
3020
        {DEC_XOR_R, dec_xor_r},
3021
        {DEC_MCP_R, dec_mcp_r},
3022
        {DEC_CMP_R, dec_cmp_r},
3023

    
3024
        {DEC_ADDI_R, dec_addi_r},
3025
        {DEC_ADDI_ACR, dec_addi_acr},
3026

    
3027
        {DEC_ADD_R, dec_add_r},
3028
        {DEC_SUB_R, dec_sub_r},
3029

    
3030
        {DEC_ADDU_R, dec_addu_r},
3031
        {DEC_ADDS_R, dec_adds_r},
3032
        {DEC_SUBU_R, dec_subu_r},
3033
        {DEC_SUBS_R, dec_subs_r},
3034
        {DEC_LSL_R, dec_lsl_r},
3035

    
3036
        {DEC_AND_R, dec_and_r},
3037
        {DEC_OR_R, dec_or_r},
3038
        {DEC_BOUND_R, dec_bound_r},
3039
        {DEC_ASR_R, dec_asr_r},
3040
        {DEC_LSR_R, dec_lsr_r},
3041

    
3042
        {DEC_MOVU_R, dec_movu_r},
3043
        {DEC_MOVS_R, dec_movs_r},
3044
        {DEC_NEG_R, dec_neg_r},
3045
        {DEC_MOVE_R, dec_move_r},
3046

    
3047
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3048
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3049

    
3050
        {DEC_MULS_R, dec_muls_r},
3051
        {DEC_MULU_R, dec_mulu_r},
3052

    
3053
        {DEC_ADDU_M, dec_addu_m},
3054
        {DEC_ADDS_M, dec_adds_m},
3055
        {DEC_SUBU_M, dec_subu_m},
3056
        {DEC_SUBS_M, dec_subs_m},
3057

    
3058
        {DEC_CMPU_M, dec_cmpu_m},
3059
        {DEC_CMPS_M, dec_cmps_m},
3060
        {DEC_MOVU_M, dec_movu_m},
3061
        {DEC_MOVS_M, dec_movs_m},
3062

    
3063
        {DEC_CMP_M, dec_cmp_m},
3064
        {DEC_ADDO_M, dec_addo_m},
3065
        {DEC_BOUND_M, dec_bound_m},
3066
        {DEC_ADD_M, dec_add_m},
3067
        {DEC_SUB_M, dec_sub_m},
3068
        {DEC_AND_M, dec_and_m},
3069
        {DEC_OR_M, dec_or_m},
3070
        {DEC_MOVE_RM, dec_move_rm},
3071
        {DEC_TEST_M, dec_test_m},
3072
        {DEC_MOVE_MR, dec_move_mr},
3073

    
3074
        {{0, 0}, dec_null}
3075
};
3076

    
3077
static unsigned int crisv32_decoder(DisasContext *dc)
3078
{
3079
        int insn_len = 2;
3080
        int i;
3081

    
3082
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
3083
                tcg_gen_debug_insn_start(dc->pc);
3084

    
3085
        /* Load a halfword onto the instruction register.  */
3086
        dc->ir = cris_fetch(dc, dc->pc, 2, 0);
3087

    
3088
        /* Now decode it.  */
3089
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
3090
        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
3091
        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
3092
        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
3093
        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
3094
        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
3095

    
3096
        /* Large switch for all insns.  */
3097
        for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3098
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
3099
                {
3100
                        insn_len = decinfo[i].dec(dc);
3101
                        break;
3102
                }
3103
        }
3104

    
3105
#if !defined(CONFIG_USER_ONLY)
3106
        /* Single-stepping ?  */
3107
        if (dc->tb_flags & S_FLAG) {
3108
                int l1;
3109

    
3110
                l1 = gen_new_label();
3111
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
3112
                /* We treat SPC as a break with an odd trap vector.  */
3113
                cris_evaluate_flags (dc);
3114
                t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
3115
                tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
3116
                tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
3117
                t_gen_raise_exception(EXCP_BREAK);
3118
                gen_set_label(l1);
3119
        }
3120
#endif
3121
        return insn_len;
3122
}
3123

    
3124
static void check_breakpoint(CPUState *env, DisasContext *dc)
3125
{
3126
        CPUBreakpoint *bp;
3127

    
3128
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3129
                QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3130
                        if (bp->pc == dc->pc) {
3131
                                cris_evaluate_flags (dc);
3132
                                tcg_gen_movi_tl(env_pc, dc->pc);
3133
                                t_gen_raise_exception(EXCP_DEBUG);
3134
                                dc->is_jmp = DISAS_UPDATE;
3135
                        }
3136
                }
3137
        }
3138
}
3139

    
3140
#include "translate_v10.c"
3141

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

    
3176
/* generate intermediate code for basic block 'tb'.  */
3177
static void
3178
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3179
                               int search_pc)
3180
{
3181
        uint16_t *gen_opc_end;
3182
           uint32_t pc_start;
3183
        unsigned int insn_len;
3184
        int j, lj;
3185
        struct DisasContext ctx;
3186
        struct DisasContext *dc = &ctx;
3187
        uint32_t next_page_start;
3188
        target_ulong npc;
3189
        int num_insns;
3190
        int max_insns;
3191

    
3192
        qemu_log_try_set_file(stderr);
3193

    
3194
        if (env->pregs[PR_VR] == 32) {
3195
                dc->decoder = crisv32_decoder;
3196
                dc->clear_locked_irq = 0;
3197
        } else {
3198
                dc->decoder = crisv10_decoder;
3199
                dc->clear_locked_irq = 1;
3200
        }
3201

    
3202
        /* Odd PC indicates that branch is rexecuting due to exception in the
3203
         * delayslot, like in real hw.
3204
         */
3205
        pc_start = tb->pc & ~1;
3206
        dc->env = env;
3207
        dc->tb = tb;
3208

    
3209
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3210

    
3211
        dc->is_jmp = DISAS_NEXT;
3212
        dc->ppc = pc_start;
3213
        dc->pc = pc_start;
3214
        dc->singlestep_enabled = env->singlestep_enabled;
3215
        dc->flags_uptodate = 1;
3216
        dc->flagx_known = 1;
3217
        dc->flags_x = tb->flags & X_FLAG;
3218
        dc->cc_x_uptodate = 0;
3219
        dc->cc_mask = 0;
3220
        dc->update_cc = 0;
3221
        dc->clear_prefix = 0;
3222

    
3223
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3224
        dc->cc_size_uptodate = -1;
3225

    
3226
        /* Decode TB flags.  */
3227
        dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3228
                                        | X_FLAG | PFIX_FLAG);
3229
        dc->delayed_branch = !!(tb->flags & 7);
3230
        if (dc->delayed_branch)
3231
                dc->jmp = JMP_INDIRECT;
3232
        else
3233
                dc->jmp = JMP_NOJMP;
3234

    
3235
        dc->cpustate_changed = 0;
3236

    
3237
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3238
                qemu_log(
3239
                        "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
3240
                        "pid=%x usp=%x\n"
3241
                        "%x.%x.%x.%x\n"
3242
                        "%x.%x.%x.%x\n"
3243
                        "%x.%x.%x.%x\n"
3244
                        "%x.%x.%x.%x\n",
3245
                        search_pc, dc->pc, dc->ppc,
3246
                        (uint64_t)tb->flags,
3247
                        env->btarget, (unsigned)tb->flags & 7,
3248
                        env->pregs[PR_CCS], 
3249
                        env->pregs[PR_PID], env->pregs[PR_USP],
3250
                        env->regs[0], env->regs[1], env->regs[2], env->regs[3],
3251
                        env->regs[4], env->regs[5], env->regs[6], env->regs[7],
3252
                        env->regs[8], env->regs[9],
3253
                        env->regs[10], env->regs[11],
3254
                        env->regs[12], env->regs[13],
3255
                        env->regs[14], env->regs[15]);
3256
                qemu_log("--------------\n");
3257
                qemu_log("IN: %s\n", lookup_symbol(pc_start));
3258
        }
3259

    
3260
        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3261
        lj = -1;
3262
        num_insns = 0;
3263
        max_insns = tb->cflags & CF_COUNT_MASK;
3264
        if (max_insns == 0)
3265
            max_insns = CF_COUNT_MASK;
3266

    
3267
        gen_icount_start();
3268
        do
3269
        {
3270
                check_breakpoint(env, dc);
3271

    
3272
                if (search_pc) {
3273
                        j = gen_opc_ptr - gen_opc_buf;
3274
                        if (lj < j) {
3275
                                lj++;
3276
                                while (lj < j)
3277
                                        gen_opc_instr_start[lj++] = 0;
3278
                        }
3279
                        if (dc->delayed_branch == 1)
3280
                                gen_opc_pc[lj] = dc->ppc | 1;
3281
                        else
3282
                                gen_opc_pc[lj] = dc->pc;
3283
                        gen_opc_instr_start[lj] = 1;
3284
                        gen_opc_icount[lj] = num_insns;
3285
                }
3286

    
3287
                /* Pretty disas.  */
3288
                LOG_DIS("%8.8x:\t", dc->pc);
3289

    
3290
                if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3291
                    gen_io_start();
3292
                dc->clear_x = 1;
3293

    
3294
                insn_len = dc->decoder(dc);
3295
                dc->ppc = dc->pc;
3296
                dc->pc += insn_len;
3297
                if (dc->clear_x)
3298
                        cris_clear_x_flag(dc);
3299

    
3300
                num_insns++;
3301
                /* Check for delayed branches here. If we do it before
3302
                   actually generating any host code, the simulator will just
3303
                   loop doing nothing for on this program location.  */
3304
                if (dc->delayed_branch) {
3305
                        dc->delayed_branch--;
3306
                        if (dc->delayed_branch == 0)
3307
                        {
3308
                                if (tb->flags & 7)
3309
                                        t_gen_mov_env_TN(dslot, 
3310
                                                tcg_const_tl(0));
3311
                                if (dc->cpustate_changed || !dc->flagx_known
3312
                                    || (dc->flags_x != (tb->flags & X_FLAG))) {
3313
                                        cris_store_direct_jmp(dc);
3314
                                }
3315

    
3316
                                if (dc->clear_locked_irq) {
3317
                                        dc->clear_locked_irq = 0;
3318
                                        t_gen_mov_env_TN(locked_irq,
3319
                                                         tcg_const_tl(0));
3320
                                }
3321

    
3322
                                if (dc->jmp == JMP_DIRECT_CC) {
3323
                                        int l1;
3324

    
3325
                                        l1 = gen_new_label();
3326
                                        cris_evaluate_flags(dc);
3327

    
3328
                                        /* Conditional jmp.  */
3329
                                        tcg_gen_brcondi_tl(TCG_COND_EQ,
3330
                                                           env_btaken, 0, l1);
3331
                                        gen_goto_tb(dc, 1, dc->jmp_pc);
3332
                                        gen_set_label(l1);
3333
                                        gen_goto_tb(dc, 0, dc->pc);
3334
                                        dc->is_jmp = DISAS_TB_JUMP;
3335
                                        dc->jmp = JMP_NOJMP;
3336
                                } else if (dc->jmp == JMP_DIRECT) {
3337
                                        cris_evaluate_flags(dc);
3338
                                        gen_goto_tb(dc, 0, dc->jmp_pc);
3339
                                        dc->is_jmp = DISAS_TB_JUMP;
3340
                                        dc->jmp = JMP_NOJMP;
3341
                                } else {
3342
                                        t_gen_cc_jmp(env_btarget, 
3343
                                                     tcg_const_tl(dc->pc));
3344
                                        dc->is_jmp = DISAS_JUMP;
3345
                                }
3346
                                break;
3347
                        }
3348
                }
3349

    
3350
                /* If we are rexecuting a branch due to exceptions on
3351
                   delay slots dont break.  */
3352
                if (!(tb->pc & 1) && env->singlestep_enabled)
3353
                        break;
3354
        } while (!dc->is_jmp && !dc->cpustate_changed
3355
                 && gen_opc_ptr < gen_opc_end
3356
                 && !singlestep
3357
                 && (dc->pc < next_page_start)
3358
                 && num_insns < max_insns);
3359

    
3360
        if (dc->clear_locked_irq)
3361
                t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3362

    
3363
        npc = dc->pc;
3364

    
3365
        if (tb->cflags & CF_LAST_IO)
3366
            gen_io_end();
3367
        /* Force an update if the per-tb cpu state has changed.  */
3368
        if (dc->is_jmp == DISAS_NEXT
3369
            && (dc->cpustate_changed || !dc->flagx_known 
3370
            || (dc->flags_x != (tb->flags & X_FLAG)))) {
3371
                dc->is_jmp = DISAS_UPDATE;
3372
                tcg_gen_movi_tl(env_pc, npc);
3373
        }
3374
        /* Broken branch+delayslot sequence.  */
3375
        if (dc->delayed_branch == 1) {
3376
                /* Set env->dslot to the size of the branch insn.  */
3377
                t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
3378
                cris_store_direct_jmp(dc);
3379
        }
3380

    
3381
        cris_evaluate_flags (dc);
3382

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

    
3417
#ifdef DEBUG_DISAS
3418
#if !DISAS_CRIS
3419
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3420
                log_target_disas(pc_start, dc->pc - pc_start,
3421
                                 dc->env->pregs[PR_VR]);
3422
                qemu_log("\nisize=%d osize=%td\n",
3423
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3424
        }
3425
#endif
3426
#endif
3427
}
3428

    
3429
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3430
{
3431
    gen_intermediate_code_internal(env, tb, 0);
3432
}
3433

    
3434
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3435
{
3436
    gen_intermediate_code_internal(env, tb, 1);
3437
}
3438

    
3439
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
3440
                     int flags)
3441
{
3442
        int i;
3443
        uint32_t srs;
3444

    
3445
        if (!env || !f)
3446
                return;
3447

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

    
3454

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

    
3478
}
3479

    
3480
struct
3481
{
3482
    uint32_t vr;
3483
    const char *name;
3484
} cris_cores[] = {
3485
        {8, "crisv8"},
3486
        {9, "crisv9"},
3487
        {10, "crisv10"},
3488
        {11, "crisv11"},
3489
        {32, "crisv32"},
3490
};
3491

    
3492
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
3493
{
3494
    unsigned int i;
3495

    
3496
    (*cpu_fprintf)(f, "Available CPUs:\n");
3497
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3498
        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
3499
    }
3500
}
3501

    
3502
static uint32_t vr_by_name(const char *name)
3503
{
3504
    unsigned int i;
3505
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3506
        if (strcmp(name, cris_cores[i].name) == 0) {
3507
            return cris_cores[i].vr;
3508
        }
3509
    }
3510
    return 32;
3511
}
3512

    
3513
CPUCRISState *cpu_cris_init (const char *cpu_model)
3514
{
3515
        CPUCRISState *env;
3516
        static int tcg_initialized = 0;
3517
        int i;
3518

    
3519
        env = g_malloc0(sizeof(CPUCRISState));
3520

    
3521
        env->pregs[PR_VR] = vr_by_name(cpu_model);
3522
        cpu_exec_init(env);
3523
        cpu_reset(env);
3524
        qemu_init_vcpu(env);
3525

    
3526
        if (tcg_initialized)
3527
                return env;
3528

    
3529
        tcg_initialized = 1;
3530

    
3531
#define GEN_HELPER 2
3532
#include "helper.h"
3533

    
3534
        if (env->pregs[PR_VR] < 32) {
3535
                cpu_crisv10_init(env);
3536
                return env; 
3537
        }
3538

    
3539

    
3540
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3541
        cc_x = tcg_global_mem_new(TCG_AREG0,
3542
                                  offsetof(CPUState, cc_x), "cc_x");
3543
        cc_src = tcg_global_mem_new(TCG_AREG0,
3544
                                    offsetof(CPUState, cc_src), "cc_src");
3545
        cc_dest = tcg_global_mem_new(TCG_AREG0,
3546
                                     offsetof(CPUState, cc_dest),
3547
                                     "cc_dest");
3548
        cc_result = tcg_global_mem_new(TCG_AREG0,
3549
                                       offsetof(CPUState, cc_result),
3550
                                       "cc_result");
3551
        cc_op = tcg_global_mem_new(TCG_AREG0,
3552
                                   offsetof(CPUState, cc_op), "cc_op");
3553
        cc_size = tcg_global_mem_new(TCG_AREG0,
3554
                                     offsetof(CPUState, cc_size),
3555
                                     "cc_size");
3556
        cc_mask = tcg_global_mem_new(TCG_AREG0,
3557
                                     offsetof(CPUState, cc_mask),
3558
                                     "cc_mask");
3559

    
3560
        env_pc = tcg_global_mem_new(TCG_AREG0, 
3561
                                    offsetof(CPUState, pc),
3562
                                    "pc");
3563
        env_btarget = tcg_global_mem_new(TCG_AREG0,
3564
                                         offsetof(CPUState, btarget),
3565
                                         "btarget");
3566
        env_btaken = tcg_global_mem_new(TCG_AREG0,
3567
                                         offsetof(CPUState, btaken),
3568
                                         "btaken");
3569
        for (i = 0; i < 16; i++) {
3570
                cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3571
                                              offsetof(CPUState, regs[i]),
3572
                                              regnames[i]);
3573
        }
3574
        for (i = 0; i < 16; i++) {
3575
                cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3576
                                               offsetof(CPUState, pregs[i]),
3577
                                               pregnames[i]);
3578
        }
3579

    
3580
        return env;
3581
}
3582

    
3583
void cpu_reset (CPUCRISState *env)
3584
{
3585
        uint32_t vr;
3586

    
3587
        if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3588
                qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3589
                log_cpu_state(env, 0);
3590
        }
3591

    
3592
        vr = env->pregs[PR_VR];
3593
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
3594
        env->pregs[PR_VR] = vr;
3595
        tlb_flush(env, 1);
3596

    
3597
#if defined(CONFIG_USER_ONLY)
3598
        /* start in user mode with interrupts enabled.  */
3599
        env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
3600
#else
3601
        cris_mmu_init(env);
3602
        env->pregs[PR_CCS] = 0;
3603
#endif
3604
}
3605

    
3606
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
3607
{
3608
        env->pc = gen_opc_pc[pc_pos];
3609
}