Statistics
| Branch: | Revision:

root / target-cris / translate.c @ a699a7be

History | View | Annotate | Download (81.4 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 "exec-all.h"
34
#include "disas.h"
35
#include "tcg-op.h"
36
#include "helper.h"
37
#include "mmu.h"
38
#include "crisv32-decode.h"
39
#include "qemu-common.h"
40

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

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

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

    
55
#define DISAS_SWI 5
56

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

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

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

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

    
81
#include "gen-icount.h"
82

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

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

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

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

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

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

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

    
123
#define JMP_NOJMP    0
124
#define JMP_DIRECT   1
125
#define JMP_INDIRECT 2
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
static void cris_lock_irq(DisasContext *dc)
231
{
232
        dc->clear_locked_irq = 0;
233
        t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
234
}
235

    
236
static inline void t_gen_raise_exception(uint32_t index)
237
{
238
        TCGv_i32 tmp = tcg_const_i32(index);
239
        gen_helper_raise_exception(tmp);
240
        tcg_temp_free_i32(tmp);
241
}
242

    
243
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
244
{
245
        TCGv t0, t_31;
246

    
247
        t0 = tcg_temp_new();
248
        t_31 = tcg_const_tl(31);
249
        tcg_gen_shl_tl(d, a, b);
250

    
251
        tcg_gen_sub_tl(t0, t_31, b);
252
        tcg_gen_sar_tl(t0, t0, t_31);
253
        tcg_gen_and_tl(t0, t0, d);
254
        tcg_gen_xor_tl(d, d, t0);
255
        tcg_temp_free(t0);
256
        tcg_temp_free(t_31);
257
}
258

    
259
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
260
{
261
        TCGv t0, t_31;
262

    
263
        t0 = tcg_temp_new();
264
        t_31 = tcg_temp_new();
265
        tcg_gen_shr_tl(d, a, b);
266

    
267
        tcg_gen_movi_tl(t_31, 31);
268
        tcg_gen_sub_tl(t0, t_31, b);
269
        tcg_gen_sar_tl(t0, t0, t_31);
270
        tcg_gen_and_tl(t0, t0, d);
271
        tcg_gen_xor_tl(d, d, t0);
272
        tcg_temp_free(t0);
273
        tcg_temp_free(t_31);
274
}
275

    
276
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
277
{
278
        TCGv t0, t_31;
279

    
280
        t0 = tcg_temp_new();
281
        t_31 = tcg_temp_new();
282
        tcg_gen_sar_tl(d, a, b);
283

    
284
        tcg_gen_movi_tl(t_31, 31);
285
        tcg_gen_sub_tl(t0, t_31, b);
286
        tcg_gen_sar_tl(t0, t0, t_31);
287
        tcg_gen_or_tl(d, d, t0);
288
        tcg_temp_free(t0);
289
        tcg_temp_free(t_31);
290
}
291

    
292
/* 64-bit signed mul, lower result in d and upper in d2.  */
293
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
294
{
295
        TCGv_i64 t0, t1;
296

    
297
        t0 = tcg_temp_new_i64();
298
        t1 = tcg_temp_new_i64();
299

    
300
        tcg_gen_ext_i32_i64(t0, a);
301
        tcg_gen_ext_i32_i64(t1, b);
302
        tcg_gen_mul_i64(t0, t0, t1);
303

    
304
        tcg_gen_trunc_i64_i32(d, t0);
305
        tcg_gen_shri_i64(t0, t0, 32);
306
        tcg_gen_trunc_i64_i32(d2, t0);
307

    
308
        tcg_temp_free_i64(t0);
309
        tcg_temp_free_i64(t1);
310
}
311

    
312
/* 64-bit unsigned muls, lower result in d and upper in d2.  */
313
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
314
{
315
        TCGv_i64 t0, t1;
316

    
317
        t0 = tcg_temp_new_i64();
318
        t1 = tcg_temp_new_i64();
319

    
320
        tcg_gen_extu_i32_i64(t0, a);
321
        tcg_gen_extu_i32_i64(t1, b);
322
        tcg_gen_mul_i64(t0, t0, t1);
323

    
324
        tcg_gen_trunc_i64_i32(d, t0);
325
        tcg_gen_shri_i64(t0, t0, 32);
326
        tcg_gen_trunc_i64_i32(d2, t0);
327

    
328
        tcg_temp_free_i64(t0);
329
        tcg_temp_free_i64(t1);
330
}
331

    
332
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
333
{
334
        int l1;
335

    
336
        l1 = gen_new_label();
337

    
338
        /* 
339
         * d <<= 1
340
         * if (d >= s)
341
         *    d -= s;
342
         */
343
        tcg_gen_shli_tl(d, a, 1);
344
        tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
345
        tcg_gen_sub_tl(d, d, b);
346
        gen_set_label(l1);
347
}
348

    
349
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
350
{
351
        TCGv t;
352

    
353
        /* 
354
         * d <<= 1
355
         * if (n)
356
         *    d += s;
357
         */
358
        t = tcg_temp_new();
359
        tcg_gen_shli_tl(d, a, 1);
360
        tcg_gen_shli_tl(t, ccs, 31 - 3);
361
        tcg_gen_sari_tl(t, t, 31);
362
        tcg_gen_and_tl(t, t, b);
363
        tcg_gen_add_tl(d, d, t);
364
        tcg_temp_free(t);
365
}
366

    
367
/* Extended arithmetics on CRIS.  */
368
static inline void t_gen_add_flag(TCGv d, int flag)
369
{
370
        TCGv c;
371

    
372
        c = tcg_temp_new();
373
        t_gen_mov_TN_preg(c, PR_CCS);
374
        /* Propagate carry into d.  */
375
        tcg_gen_andi_tl(c, c, 1 << flag);
376
        if (flag)
377
                tcg_gen_shri_tl(c, c, flag);
378
        tcg_gen_add_tl(d, d, c);
379
        tcg_temp_free(c);
380
}
381

    
382
static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
383
{
384
        if (dc->flagx_known) {
385
                if (dc->flags_x) {
386
                        TCGv c;
387
            
388
                        c = tcg_temp_new();
389
                        t_gen_mov_TN_preg(c, PR_CCS);
390
                        /* C flag is already at bit 0.  */
391
                        tcg_gen_andi_tl(c, c, C_FLAG);
392
                        tcg_gen_add_tl(d, d, c);
393
                        tcg_temp_free(c);
394
                }
395
        } else {
396
                TCGv x, c;
397

    
398
                x = tcg_temp_new();
399
                c = tcg_temp_new();
400
                t_gen_mov_TN_preg(x, PR_CCS);
401
                tcg_gen_mov_tl(c, x);
402

    
403
                /* Propagate carry into d if X is set. Branch free.  */
404
                tcg_gen_andi_tl(c, c, C_FLAG);
405
                tcg_gen_andi_tl(x, x, X_FLAG);
406
                tcg_gen_shri_tl(x, x, 4);
407

    
408
                tcg_gen_and_tl(x, x, c);
409
                tcg_gen_add_tl(d, d, x);        
410
                tcg_temp_free(x);
411
                tcg_temp_free(c);
412
        }
413
}
414

    
415
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
416
{
417
        if (dc->flagx_known) {
418
                if (dc->flags_x) {
419
                        TCGv c;
420
            
421
                        c = tcg_temp_new();
422
                        t_gen_mov_TN_preg(c, PR_CCS);
423
                        /* C flag is already at bit 0.  */
424
                        tcg_gen_andi_tl(c, c, C_FLAG);
425
                        tcg_gen_sub_tl(d, d, c);
426
                        tcg_temp_free(c);
427
                }
428
        } else {
429
                TCGv x, c;
430

    
431
                x = tcg_temp_new();
432
                c = tcg_temp_new();
433
                t_gen_mov_TN_preg(x, PR_CCS);
434
                tcg_gen_mov_tl(c, x);
435

    
436
                /* Propagate carry into d if X is set. Branch free.  */
437
                tcg_gen_andi_tl(c, c, C_FLAG);
438
                tcg_gen_andi_tl(x, x, X_FLAG);
439
                tcg_gen_shri_tl(x, x, 4);
440

    
441
                tcg_gen_and_tl(x, x, c);
442
                tcg_gen_sub_tl(d, d, x);
443
                tcg_temp_free(x);
444
                tcg_temp_free(c);
445
        }
446
}
447

    
448
/* Swap the two bytes within each half word of the s operand.
449
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
450
static inline void t_gen_swapb(TCGv d, TCGv s)
451
{
452
        TCGv t, org_s;
453

    
454
        t = tcg_temp_new();
455
        org_s = tcg_temp_new();
456

    
457
        /* d and s may refer to the same object.  */
458
        tcg_gen_mov_tl(org_s, s);
459
        tcg_gen_shli_tl(t, org_s, 8);
460
        tcg_gen_andi_tl(d, t, 0xff00ff00);
461
        tcg_gen_shri_tl(t, org_s, 8);
462
        tcg_gen_andi_tl(t, t, 0x00ff00ff);
463
        tcg_gen_or_tl(d, d, t);
464
        tcg_temp_free(t);
465
        tcg_temp_free(org_s);
466
}
467

    
468
/* Swap the halfwords of the s operand.  */
469
static inline void t_gen_swapw(TCGv d, TCGv s)
470
{
471
        TCGv t;
472
        /* d and s refer the same object.  */
473
        t = tcg_temp_new();
474
        tcg_gen_mov_tl(t, s);
475
        tcg_gen_shli_tl(d, t, 16);
476
        tcg_gen_shri_tl(t, t, 16);
477
        tcg_gen_or_tl(d, d, t);
478
        tcg_temp_free(t);
479
}
480

    
481
/* Reverse the within each byte.
482
   T0 = (((T0 << 7) & 0x80808080) |
483
   ((T0 << 5) & 0x40404040) |
484
   ((T0 << 3) & 0x20202020) |
485
   ((T0 << 1) & 0x10101010) |
486
   ((T0 >> 1) & 0x08080808) |
487
   ((T0 >> 3) & 0x04040404) |
488
   ((T0 >> 5) & 0x02020202) |
489
   ((T0 >> 7) & 0x01010101));
490
 */
491
static inline void t_gen_swapr(TCGv d, TCGv s)
492
{
493
        struct {
494
                int shift; /* LSL when positive, LSR when negative.  */
495
                uint32_t mask;
496
        } bitrev [] = {
497
                {7, 0x80808080},
498
                {5, 0x40404040},
499
                {3, 0x20202020},
500
                {1, 0x10101010},
501
                {-1, 0x08080808},
502
                {-3, 0x04040404},
503
                {-5, 0x02020202},
504
                {-7, 0x01010101}
505
        };
506
        int i;
507
        TCGv t, org_s;
508

    
509
        /* d and s refer the same object.  */
510
        t = tcg_temp_new();
511
        org_s = tcg_temp_new();
512
        tcg_gen_mov_tl(org_s, s);
513

    
514
        tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
515
        tcg_gen_andi_tl(d, t,  bitrev[0].mask);
516
        for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
517
                if (bitrev[i].shift >= 0) {
518
                        tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
519
                } else {
520
                        tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
521
                }
522
                tcg_gen_andi_tl(t, t,  bitrev[i].mask);
523
                tcg_gen_or_tl(d, d, t);
524
        }
525
        tcg_temp_free(t);
526
        tcg_temp_free(org_s);
527
}
528

    
529
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
530
{
531
        TCGv btaken;
532
        int l1;
533

    
534
        l1 = gen_new_label();
535
        btaken = tcg_temp_new();
536

    
537
        /* Conditional jmp.  */
538
        tcg_gen_mov_tl(btaken, env_btaken);
539
        tcg_gen_mov_tl(env_pc, pc_false);
540
        tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1);
541
        tcg_gen_mov_tl(env_pc, pc_true);
542
        gen_set_label(l1);
543

    
544
        tcg_temp_free(btaken);
545
}
546

    
547
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
548
{
549
        TranslationBlock *tb;
550
        tb = dc->tb;
551
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
552
                tcg_gen_goto_tb(n);
553
                tcg_gen_movi_tl(env_pc, dest);
554
                tcg_gen_exit_tb((long)tb + n);
555
        } else {
556
                tcg_gen_movi_tl(env_pc, dest);
557
                tcg_gen_exit_tb(0);
558
        }
559
}
560

    
561
/* Sign extend at translation time.  */
562
static int sign_extend(unsigned int val, unsigned int width)
563
{
564
        int sval;
565

    
566
        /* LSL.  */
567
        val <<= 31 - width;
568
        sval = val;
569
        /* ASR.  */
570
        sval >>= 31 - width;
571
        return sval;
572
}
573

    
574
static inline void cris_clear_x_flag(DisasContext *dc)
575
{
576
        if (dc->flagx_known && dc->flags_x)
577
                dc->flags_uptodate = 0;
578

    
579
        dc->flagx_known = 1;
580
        dc->flags_x = 0;
581
}
582

    
583
static void cris_flush_cc_state(DisasContext *dc)
584
{
585
        if (dc->cc_size_uptodate != dc->cc_size) {
586
                tcg_gen_movi_tl(cc_size, dc->cc_size);
587
                dc->cc_size_uptodate = dc->cc_size;
588
        }
589
        tcg_gen_movi_tl(cc_op, dc->cc_op);
590
        tcg_gen_movi_tl(cc_mask, dc->cc_mask);
591
}
592

    
593
static void cris_evaluate_flags(DisasContext *dc)
594
{
595
        if (dc->flags_uptodate)
596
                return;
597

    
598
        cris_flush_cc_state(dc);
599

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

    
650
                break;
651
        default:
652
                switch (dc->cc_size)
653
                {
654
                        case 4:
655
                        gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
656
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
657
                                break;
658
                        default:
659
                                gen_helper_evaluate_flags();
660
                                break;
661
                }
662
                break;
663
        }
664

    
665
        if (dc->flagx_known) {
666
                if (dc->flags_x)
667
                        tcg_gen_ori_tl(cpu_PR[PR_CCS], 
668
                                       cpu_PR[PR_CCS], X_FLAG);
669
                else if (dc->cc_op == CC_OP_FLAGS)
670
                        tcg_gen_andi_tl(cpu_PR[PR_CCS], 
671
                                        cpu_PR[PR_CCS], ~X_FLAG);
672
        }
673
        dc->flags_uptodate = 1;
674
}
675

    
676
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
677
{
678
        uint32_t ovl;
679

    
680
        if (!mask) {
681
                dc->update_cc = 0;
682
                return;
683
        }        
684

    
685
        /* Check if we need to evaluate the condition codes due to 
686
           CC overlaying.  */
687
        ovl = (dc->cc_mask ^ mask) & ~mask;
688
        if (ovl) {
689
                /* TODO: optimize this case. It trigs all the time.  */
690
                cris_evaluate_flags (dc);
691
        }
692
        dc->cc_mask = mask;
693
        dc->update_cc = 1;
694
}
695

    
696
static void cris_update_cc_op(DisasContext *dc, int op, int size)
697
{
698
        dc->cc_op = op;
699
        dc->cc_size = size;
700
        dc->flags_uptodate = 0;
701
}
702

    
703
static inline void cris_update_cc_x(DisasContext *dc)
704
{
705
        /* Save the x flag state at the time of the cc snapshot.  */
706
        if (dc->flagx_known) {
707
                if (dc->cc_x_uptodate == (2 | dc->flags_x))
708
                        return;
709
                tcg_gen_movi_tl(cc_x, dc->flags_x);
710
                dc->cc_x_uptodate = 2 | dc->flags_x;
711
        }
712
        else {
713
                tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
714
                dc->cc_x_uptodate = 1;
715
        }
716
}
717

    
718
/* Update cc prior to executing ALU op. Needs source operands untouched.  */
719
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
720
                                   TCGv dst, TCGv src, int size)
721
{
722
        if (dc->update_cc) {
723
                cris_update_cc_op(dc, op, size);
724
                tcg_gen_mov_tl(cc_src, src);
725

    
726
                if (op != CC_OP_MOVE
727
                    && op != CC_OP_AND
728
                    && op != CC_OP_OR
729
                    && op != CC_OP_XOR
730
                    && op != CC_OP_ASR
731
                    && op != CC_OP_LSR
732
                    && op != CC_OP_LSL)
733
                        tcg_gen_mov_tl(cc_dest, dst);
734

    
735
                cris_update_cc_x(dc);
736
        }
737
}
738

    
739
/* Update cc after executing ALU op. needs the result.  */
740
static inline void cris_update_result(DisasContext *dc, TCGv res)
741
{
742
        if (dc->update_cc)
743
                tcg_gen_mov_tl(cc_result, res);
744
}
745

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

    
833
        if (size == 1)
834
                tcg_gen_andi_tl(dst, dst, 0xff);
835
        else if (size == 2)
836
                tcg_gen_andi_tl(dst, dst, 0xffff);
837
}
838

    
839
static void cris_alu(DisasContext *dc, int op,
840
                               TCGv d, TCGv op_a, TCGv op_b, int size)
841
{
842
        TCGv tmp;
843
        int writeback;
844

    
845
        writeback = 1;
846

    
847
        if (op == CC_OP_CMP) {
848
                tmp = tcg_temp_new();
849
                writeback = 0;
850
        } else if (size == 4) {
851
                tmp = d;
852
                writeback = 0;
853
        } else
854
                tmp = tcg_temp_new();
855

    
856

    
857
        cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
858
        cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
859
        cris_update_result(dc, tmp);
860

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

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

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

    
902
        /* TODO: optimize more condition codes.  */
903

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

    
968
                                if (dc->cc_size == 1)
969
                                        bits = 7;
970
                                else if (dc->cc_size == 2)
971
                                        bits = 15;        
972

    
973
                                tcg_gen_shri_tl(cc, cc_result, bits);
974
                                tcg_gen_xori_tl(cc, cc, 1);
975
                        } else {
976
                                cris_evaluate_flags(dc);
977
                                tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
978
                                                N_FLAG);
979
                                tcg_gen_andi_tl(cc, cc, N_FLAG);
980
                        }
981
                        break;
982
                case CC_MI:
983
                        if (arith_opt || move_opt) {
984
                                int bits = 31;
985

    
986
                                if (dc->cc_size == 1)
987
                                        bits = 7;
988
                                else if (dc->cc_size == 2)
989
                                        bits = 15;        
990

    
991
                                tcg_gen_shri_tl(cc, cc_result, bits);
992
                                tcg_gen_andi_tl(cc, cc, 1);
993
                        }
994
                        else {
995
                                cris_evaluate_flags(dc);
996
                                tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
997
                                                N_FLAG);
998
                        }
999
                        break;
1000
                case CC_LS:
1001
                        cris_evaluate_flags(dc);
1002
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1003
                                        C_FLAG | Z_FLAG);
1004
                        break;
1005
                case CC_HI:
1006
                        cris_evaluate_flags(dc);
1007
                        {
1008
                                TCGv tmp;
1009

    
1010
                                tmp = tcg_temp_new();
1011
                                tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1012
                                                C_FLAG | Z_FLAG);
1013
                                /* Overlay the C flag on top of the Z.  */
1014
                                tcg_gen_shli_tl(cc, tmp, 2);
1015
                                tcg_gen_and_tl(cc, tmp, cc);
1016
                                tcg_gen_andi_tl(cc, cc, Z_FLAG);
1017

    
1018
                                tcg_temp_free(tmp);
1019
                        }
1020
                        break;
1021
                case CC_GE:
1022
                        cris_evaluate_flags(dc);
1023
                        /* Overlay the V flag on top of the N.  */
1024
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1025
                        tcg_gen_xor_tl(cc,
1026
                                       cpu_PR[PR_CCS], cc);
1027
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1028
                        tcg_gen_xori_tl(cc, cc, N_FLAG);
1029
                        break;
1030
                case CC_LT:
1031
                        cris_evaluate_flags(dc);
1032
                        /* Overlay the V flag on top of the N.  */
1033
                        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1034
                        tcg_gen_xor_tl(cc,
1035
                                       cpu_PR[PR_CCS], cc);
1036
                        tcg_gen_andi_tl(cc, cc, N_FLAG);
1037
                        break;
1038
                case CC_GT:
1039
                        cris_evaluate_flags(dc);
1040
                        {
1041
                                TCGv n, z;
1042

    
1043
                                n = tcg_temp_new();
1044
                                z = tcg_temp_new();
1045

    
1046
                                /* To avoid a shift we overlay everything on
1047
                                   the V flag.  */
1048
                                tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1049
                                tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1050
                                /* invert Z.  */
1051
                                tcg_gen_xori_tl(z, z, 2);
1052

    
1053
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1054
                                tcg_gen_xori_tl(n, n, 2);
1055
                                tcg_gen_and_tl(cc, z, n);
1056
                                tcg_gen_andi_tl(cc, cc, 2);
1057

    
1058
                                tcg_temp_free(n);
1059
                                tcg_temp_free(z);
1060
                        }
1061
                        break;
1062
                case CC_LE:
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

    
1075
                                tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1076
                                tcg_gen_or_tl(cc, z, n);
1077
                                tcg_gen_andi_tl(cc, cc, 2);
1078

    
1079
                                tcg_temp_free(n);
1080
                                tcg_temp_free(z);
1081
                        }
1082
                        break;
1083
                case CC_P:
1084
                        cris_evaluate_flags(dc);
1085
                        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1086
                        break;
1087
                case CC_A:
1088
                        tcg_gen_movi_tl(cc, 1);
1089
                        break;
1090
                default:
1091
                        BUG();
1092
                        break;
1093
        };
1094
}
1095

    
1096
static void cris_store_direct_jmp(DisasContext *dc)
1097
{
1098
        /* Store the direct jmp state into the cpu-state.  */
1099
        if (dc->jmp == JMP_DIRECT) {
1100
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1101
                tcg_gen_movi_tl(env_btaken, 1);
1102
        }
1103
}
1104

    
1105
static void cris_prepare_cc_branch (DisasContext *dc, 
1106
                                    int offset, int cond)
1107
{
1108
        /* This helps us re-schedule the micro-code to insns in delay-slots
1109
           before the actual jump.  */
1110
        dc->delayed_branch = 2;
1111
        dc->jmp_pc = dc->pc + offset;
1112

    
1113
        if (cond != CC_A)
1114
        {
1115
                dc->jmp = JMP_INDIRECT;
1116
                gen_tst_cc (dc, env_btaken, cond);
1117
                tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1118
        } else {
1119
                /* Allow chaining.  */
1120
                dc->jmp = JMP_DIRECT;
1121
        }
1122
}
1123

    
1124

    
1125
/* jumps, when the dest is in a live reg for example. Direct should be set
1126
   when the dest addr is constant to allow tb chaining.  */
1127
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1128
{
1129
        /* This helps us re-schedule the micro-code to insns in delay-slots
1130
           before the actual jump.  */
1131
        dc->delayed_branch = 2;
1132
        dc->jmp = type;
1133
        if (type == JMP_INDIRECT)
1134
                tcg_gen_movi_tl(env_btaken, 1);
1135
}
1136

    
1137
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1138
{
1139
        int mem_index = cpu_mmu_index(dc->env);
1140

    
1141
        /* If we get a fault on a delayslot we must keep the jmp state in
1142
           the cpu-state to be able to re-execute the jmp.  */
1143
        if (dc->delayed_branch == 1)
1144
                cris_store_direct_jmp(dc);
1145

    
1146
        tcg_gen_qemu_ld64(dst, addr, mem_index);
1147
}
1148

    
1149
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
1150
                     unsigned int size, int sign)
1151
{
1152
        int mem_index = cpu_mmu_index(dc->env);
1153

    
1154
        /* If we get a fault on a delayslot we must keep the jmp state in
1155
           the cpu-state to be able to re-execute the jmp.  */
1156
        if (dc->delayed_branch == 1)
1157
                cris_store_direct_jmp(dc);
1158

    
1159
        if (size == 1) {
1160
                if (sign)
1161
                        tcg_gen_qemu_ld8s(dst, addr, mem_index);
1162
                else
1163
                        tcg_gen_qemu_ld8u(dst, addr, mem_index);
1164
        }
1165
        else if (size == 2) {
1166
                if (sign)
1167
                        tcg_gen_qemu_ld16s(dst, addr, mem_index);
1168
                else
1169
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
1170
        }
1171
        else if (size == 4) {
1172
                tcg_gen_qemu_ld32u(dst, addr, mem_index);
1173
        }
1174
        else {
1175
                abort();
1176
        }
1177
}
1178

    
1179
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1180
                       unsigned int size)
1181
{
1182
        int mem_index = cpu_mmu_index(dc->env);
1183

    
1184
        /* If we get a fault on a delayslot we must keep the jmp state in
1185
           the cpu-state to be able to re-execute the jmp.  */
1186
        if (dc->delayed_branch == 1)
1187
                 cris_store_direct_jmp(dc);
1188

    
1189

    
1190
        /* Conditional writes. We only support the kind were X and P are known
1191
           at translation time.  */
1192
        if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1193
                dc->postinc = 0;
1194
                cris_evaluate_flags(dc);
1195
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1196
                return;
1197
        }
1198

    
1199
        if (size == 1)
1200
                tcg_gen_qemu_st8(val, addr, mem_index);
1201
        else if (size == 2)
1202
                tcg_gen_qemu_st16(val, addr, mem_index);
1203
        else
1204
                tcg_gen_qemu_st32(val, addr, mem_index);
1205

    
1206
        if (dc->flagx_known && dc->flags_x) {
1207
                cris_evaluate_flags(dc);
1208
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1209
        }
1210
}
1211

    
1212
static inline void t_gen_sext(TCGv d, TCGv s, int size)
1213
{
1214
        if (size == 1)
1215
                tcg_gen_ext8s_i32(d, s);
1216
        else if (size == 2)
1217
                tcg_gen_ext16s_i32(d, s);
1218
        else if(!TCGV_EQUAL(d, s))
1219
                tcg_gen_mov_tl(d, s);
1220
}
1221

    
1222
static inline void t_gen_zext(TCGv d, TCGv s, int size)
1223
{
1224
        if (size == 1)
1225
                tcg_gen_ext8u_i32(d, s);
1226
        else if (size == 2)
1227
                tcg_gen_ext16u_i32(d, s);
1228
        else if (!TCGV_EQUAL(d, s))
1229
                tcg_gen_mov_tl(d, s);
1230
}
1231

    
1232
#if DISAS_CRIS
1233
static char memsize_char(int size)
1234
{
1235
        switch (size)
1236
        {
1237
                case 1: return 'b';  break;
1238
                case 2: return 'w';  break;
1239
                case 4: return 'd';  break;
1240
                default:
1241
                        return 'x';
1242
                        break;
1243
        }
1244
}
1245
#endif
1246

    
1247
static inline unsigned int memsize_z(DisasContext *dc)
1248
{
1249
        return dc->zsize + 1;
1250
}
1251

    
1252
static inline unsigned int memsize_zz(DisasContext *dc)
1253
{
1254
        switch (dc->zzsize)
1255
        {
1256
                case 0: return 1;
1257
                case 1: return 2;
1258
                default:
1259
                        return 4;
1260
        }
1261
}
1262

    
1263
static inline void do_postinc (DisasContext *dc, int size)
1264
{
1265
        if (dc->postinc)
1266
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1267
}
1268

    
1269
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1270
                                   int size, int s_ext, TCGv dst)
1271
{
1272
        if (s_ext)
1273
                t_gen_sext(dst, cpu_R[rs], size);
1274
        else
1275
                t_gen_zext(dst, cpu_R[rs], size);
1276
}
1277

    
1278
/* Prepare T0 and T1 for a register alu operation.
1279
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1280
   needed.  */
1281
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1282
                          int size, int s_ext, TCGv dst, TCGv src)
1283
{
1284
        dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1285

    
1286
        if (s_ext)
1287
                t_gen_sext(dst, cpu_R[rd], size);
1288
        else
1289
                t_gen_zext(dst, cpu_R[rd], size);
1290
}
1291

    
1292
static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1293
                           TCGv dst)
1294
{
1295
        unsigned int rs;
1296
        uint32_t imm;
1297
        int is_imm;
1298
        int insn_len = 2;
1299

    
1300
        rs = dc->op1;
1301
        is_imm = rs == 15 && dc->postinc;
1302

    
1303
        /* Load [$rs] onto T1.  */
1304
        if (is_imm) {
1305
                insn_len = 2 + memsize;
1306
                if (memsize == 1)
1307
                        insn_len++;
1308

    
1309
                if (memsize != 4) {
1310
                        if (s_ext) {
1311
                                if (memsize == 1)
1312
                                        imm = ldsb_code(dc->pc + 2);
1313
                                else
1314
                                        imm = ldsw_code(dc->pc + 2);
1315
                        } else {
1316
                                if (memsize == 1)
1317
                                        imm = ldub_code(dc->pc + 2);
1318
                                else
1319
                                        imm = lduw_code(dc->pc + 2);
1320
                        }
1321
                } else
1322
                        imm = ldl_code(dc->pc + 2);
1323
                        
1324
                tcg_gen_movi_tl(dst, imm);
1325
                dc->postinc = 0;
1326
        } else {
1327
                cris_flush_cc_state(dc);
1328
                gen_load(dc, dst, cpu_R[rs], memsize, 0);
1329
                if (s_ext)
1330
                        t_gen_sext(dst, dst, memsize);
1331
                else
1332
                        t_gen_zext(dst, dst, memsize);
1333
        }
1334
        return insn_len;
1335
}
1336

    
1337
/* Prepare T0 and T1 for a memory + alu operation.
1338
   s_ext decides if the operand1 should be sign-extended or zero-extended when
1339
   needed.  */
1340
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
1341
                          TCGv dst, TCGv src)
1342
{
1343
        int insn_len;
1344

    
1345
        insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
1346
        tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1347
        return insn_len;
1348
}
1349

    
1350
#if DISAS_CRIS
1351
static const char *cc_name(int cc)
1352
{
1353
        static const char *cc_names[16] = {
1354
                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1355
                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1356
        };
1357
        assert(cc < 16);
1358
        return cc_names[cc];
1359
}
1360
#endif
1361

    
1362
/* Start of insn decoders.  */
1363

    
1364
static int dec_bccq(DisasContext *dc)
1365
{
1366
        int32_t offset;
1367
        int sign;
1368
        uint32_t cond = dc->op2;
1369

    
1370
        offset = EXTRACT_FIELD (dc->ir, 1, 7);
1371
        sign = EXTRACT_FIELD(dc->ir, 0, 0);
1372

    
1373
        offset *= 2;
1374
        offset |= sign << 8;
1375
        offset = sign_extend(offset, 8);
1376

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

    
1379
        /* op2 holds the condition-code.  */
1380
        cris_cc_mask(dc, 0);
1381
        cris_prepare_cc_branch (dc, offset, cond);
1382
        return 2;
1383
}
1384
static int dec_addoq(DisasContext *dc)
1385
{
1386
        int32_t imm;
1387

    
1388
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1389
        imm = sign_extend(dc->op1, 7);
1390

    
1391
        LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1392
        cris_cc_mask(dc, 0);
1393
        /* Fetch register operand,  */
1394
        tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1395

    
1396
        return 2;
1397
}
1398
static int dec_addq(DisasContext *dc)
1399
{
1400
        LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1401

    
1402
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1403

    
1404
        cris_cc_mask(dc, CC_MASK_NZVC);
1405

    
1406
        cris_alu(dc, CC_OP_ADD,
1407
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1408
        return 2;
1409
}
1410
static int dec_moveq(DisasContext *dc)
1411
{
1412
        uint32_t imm;
1413

    
1414
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1415
        imm = sign_extend(dc->op1, 5);
1416
        LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1417

    
1418
        tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1419
        return 2;
1420
}
1421
static int dec_subq(DisasContext *dc)
1422
{
1423
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1424

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

    
1427
        cris_cc_mask(dc, CC_MASK_NZVC);
1428
        cris_alu(dc, CC_OP_SUB,
1429
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1430
        return 2;
1431
}
1432
static int dec_cmpq(DisasContext *dc)
1433
{
1434
        uint32_t imm;
1435
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1436
        imm = sign_extend(dc->op1, 5);
1437

    
1438
        LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1439
        cris_cc_mask(dc, CC_MASK_NZVC);
1440

    
1441
        cris_alu(dc, CC_OP_CMP,
1442
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1443
        return 2;
1444
}
1445
static int dec_andq(DisasContext *dc)
1446
{
1447
        uint32_t imm;
1448
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1449
        imm = sign_extend(dc->op1, 5);
1450

    
1451
        LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1452
        cris_cc_mask(dc, CC_MASK_NZ);
1453

    
1454
        cris_alu(dc, CC_OP_AND,
1455
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1456
        return 2;
1457
}
1458
static int dec_orq(DisasContext *dc)
1459
{
1460
        uint32_t imm;
1461
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1462
        imm = sign_extend(dc->op1, 5);
1463
        LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1464
        cris_cc_mask(dc, CC_MASK_NZ);
1465

    
1466
        cris_alu(dc, CC_OP_OR,
1467
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1468
        return 2;
1469
}
1470
static int dec_btstq(DisasContext *dc)
1471
{
1472
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1473
        LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1474

    
1475
        cris_cc_mask(dc, CC_MASK_NZ);
1476
        cris_evaluate_flags(dc);
1477
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1478
                        tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1479
        cris_alu(dc, CC_OP_MOVE,
1480
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1481
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1482
        dc->flags_uptodate = 1;
1483
        return 2;
1484
}
1485
static int dec_asrq(DisasContext *dc)
1486
{
1487
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1488
        LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1489
        cris_cc_mask(dc, CC_MASK_NZ);
1490

    
1491
        tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1492
        cris_alu(dc, CC_OP_MOVE,
1493
                    cpu_R[dc->op2],
1494
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1495
        return 2;
1496
}
1497
static int dec_lslq(DisasContext *dc)
1498
{
1499
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1500
        LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1501

    
1502
        cris_cc_mask(dc, CC_MASK_NZ);
1503

    
1504
        tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1505

    
1506
        cris_alu(dc, CC_OP_MOVE,
1507
                    cpu_R[dc->op2],
1508
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1509
        return 2;
1510
}
1511
static int dec_lsrq(DisasContext *dc)
1512
{
1513
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1514
        LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1515

    
1516
        cris_cc_mask(dc, CC_MASK_NZ);
1517

    
1518
        tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1519
        cris_alu(dc, CC_OP_MOVE,
1520
                    cpu_R[dc->op2],
1521
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1522
        return 2;
1523
}
1524

    
1525
static int dec_move_r(DisasContext *dc)
1526
{
1527
        int size = memsize_zz(dc);
1528

    
1529
        LOG_DIS("move.%c $r%u, $r%u\n",
1530
                    memsize_char(size), dc->op1, dc->op2);
1531

    
1532
        cris_cc_mask(dc, CC_MASK_NZ);
1533
        if (size == 4) {
1534
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1535
                cris_cc_mask(dc, CC_MASK_NZ);
1536
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
1537
                cris_update_cc_x(dc);
1538
                cris_update_result(dc, cpu_R[dc->op2]);
1539
        }
1540
        else {
1541
                TCGv t0;
1542

    
1543
                t0 = tcg_temp_new();
1544
                dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1545
                cris_alu(dc, CC_OP_MOVE,
1546
                         cpu_R[dc->op2],
1547
                         cpu_R[dc->op2], t0, size);
1548
                tcg_temp_free(t0);
1549
        }
1550
        return 2;
1551
}
1552

    
1553
static int dec_scc_r(DisasContext *dc)
1554
{
1555
        int cond = dc->op2;
1556

    
1557
        LOG_DIS("s%s $r%u\n",
1558
                    cc_name(cond), dc->op1);
1559

    
1560
        if (cond != CC_A)
1561
        {
1562
                int l1;
1563

    
1564
                gen_tst_cc (dc, cpu_R[dc->op1], cond);
1565
                l1 = gen_new_label();
1566
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1567
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1568
                gen_set_label(l1);
1569
        }
1570
        else
1571
                tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1572

    
1573
        cris_cc_mask(dc, 0);
1574
        return 2;
1575
}
1576

    
1577
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1578
{
1579
        if (size == 4) {
1580
                t[0] = cpu_R[dc->op2];
1581
                t[1] = cpu_R[dc->op1];
1582
        } else {
1583
                t[0] = tcg_temp_new();
1584
                t[1] = tcg_temp_new();
1585
        }
1586
}
1587

    
1588
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1589
{
1590
        if (size != 4) {
1591
                tcg_temp_free(t[0]);
1592
                tcg_temp_free(t[1]);
1593
        }
1594
}
1595

    
1596
static int dec_and_r(DisasContext *dc)
1597
{
1598
        TCGv t[2];
1599
        int size = memsize_zz(dc);
1600

    
1601
        LOG_DIS("and.%c $r%u, $r%u\n",
1602
                    memsize_char(size), dc->op1, dc->op2);
1603

    
1604
        cris_cc_mask(dc, CC_MASK_NZ);
1605

    
1606
        cris_alu_alloc_temps(dc, size, t);
1607
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1608
        cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1609
        cris_alu_free_temps(dc, size, t);
1610
        return 2;
1611
}
1612

    
1613
static int dec_lz_r(DisasContext *dc)
1614
{
1615
        TCGv t0;
1616
        LOG_DIS("lz $r%u, $r%u\n",
1617
                    dc->op1, dc->op2);
1618
        cris_cc_mask(dc, CC_MASK_NZ);
1619
        t0 = tcg_temp_new();
1620
        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1621
        cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1622
        tcg_temp_free(t0);
1623
        return 2;
1624
}
1625

    
1626
static int dec_lsl_r(DisasContext *dc)
1627
{
1628
        TCGv t[2];
1629
        int size = memsize_zz(dc);
1630

    
1631
        LOG_DIS("lsl.%c $r%u, $r%u\n",
1632
                    memsize_char(size), dc->op1, dc->op2);
1633

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

    
1643
static int dec_lsr_r(DisasContext *dc)
1644
{
1645
        TCGv t[2];
1646
        int size = memsize_zz(dc);
1647

    
1648
        LOG_DIS("lsr.%c $r%u, $r%u\n",
1649
                    memsize_char(size), dc->op1, dc->op2);
1650

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

    
1660
static int dec_asr_r(DisasContext *dc)
1661
{
1662
        TCGv t[2];
1663
        int size = memsize_zz(dc);
1664

    
1665
        LOG_DIS("asr.%c $r%u, $r%u\n",
1666
                    memsize_char(size), dc->op1, dc->op2);
1667

    
1668
        cris_cc_mask(dc, CC_MASK_NZ);
1669
        cris_alu_alloc_temps(dc, size, t);
1670
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1671
        tcg_gen_andi_tl(t[1], t[1], 63);
1672
        cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1673
        cris_alu_free_temps(dc, size, t);
1674
        return 2;
1675
}
1676

    
1677
static int dec_muls_r(DisasContext *dc)
1678
{
1679
        TCGv t[2];
1680
        int size = memsize_zz(dc);
1681

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

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

    
1693
static int dec_mulu_r(DisasContext *dc)
1694
{
1695
        TCGv t[2];
1696
        int size = memsize_zz(dc);
1697

    
1698
        LOG_DIS("mulu.%c $r%u, $r%u\n",
1699
                    memsize_char(size), dc->op1, dc->op2);
1700
        cris_cc_mask(dc, CC_MASK_NZV);
1701
        cris_alu_alloc_temps(dc, size, t);
1702
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1703

    
1704
        cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1705
        cris_alu_alloc_temps(dc, size, t);
1706
        return 2;
1707
}
1708

    
1709

    
1710
static int dec_dstep_r(DisasContext *dc)
1711
{
1712
        LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1713
        cris_cc_mask(dc, CC_MASK_NZ);
1714
        cris_alu(dc, CC_OP_DSTEP,
1715
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1716
        return 2;
1717
}
1718

    
1719
static int dec_xor_r(DisasContext *dc)
1720
{
1721
        TCGv t[2];
1722
        int size = memsize_zz(dc);
1723
        LOG_DIS("xor.%c $r%u, $r%u\n",
1724
                    memsize_char(size), dc->op1, dc->op2);
1725
        BUG_ON(size != 4); /* xor is dword.  */
1726
        cris_cc_mask(dc, CC_MASK_NZ);
1727
        cris_alu_alloc_temps(dc, size, t);
1728
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1729

    
1730
        cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1731
        cris_alu_free_temps(dc, size, t);
1732
        return 2;
1733
}
1734

    
1735
static int dec_bound_r(DisasContext *dc)
1736
{
1737
        TCGv l0;
1738
        int size = memsize_zz(dc);
1739
        LOG_DIS("bound.%c $r%u, $r%u\n",
1740
                    memsize_char(size), dc->op1, dc->op2);
1741
        cris_cc_mask(dc, CC_MASK_NZ);
1742
        l0 = tcg_temp_local_new();
1743
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1744
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1745
        tcg_temp_free(l0);
1746
        return 2;
1747
}
1748

    
1749
static int dec_cmp_r(DisasContext *dc)
1750
{
1751
        TCGv t[2];
1752
        int size = memsize_zz(dc);
1753
        LOG_DIS("cmp.%c $r%u, $r%u\n",
1754
                    memsize_char(size), dc->op1, dc->op2);
1755
        cris_cc_mask(dc, CC_MASK_NZVC);
1756
        cris_alu_alloc_temps(dc, size, t);
1757
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1758

    
1759
        cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1760
        cris_alu_free_temps(dc, size, t);
1761
        return 2;
1762
}
1763

    
1764
static int dec_abs_r(DisasContext *dc)
1765
{
1766
        TCGv t0;
1767

    
1768
        LOG_DIS("abs $r%u, $r%u\n",
1769
                    dc->op1, dc->op2);
1770
        cris_cc_mask(dc, CC_MASK_NZ);
1771

    
1772
        t0 = tcg_temp_new();
1773
        tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1774
        tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1775
        tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1776
        tcg_temp_free(t0);
1777

    
1778
        cris_alu(dc, CC_OP_MOVE,
1779
                    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1780
        return 2;
1781
}
1782

    
1783
static int dec_add_r(DisasContext *dc)
1784
{
1785
        TCGv t[2];
1786
        int size = memsize_zz(dc);
1787
        LOG_DIS("add.%c $r%u, $r%u\n",
1788
                    memsize_char(size), dc->op1, dc->op2);
1789
        cris_cc_mask(dc, CC_MASK_NZVC);
1790
        cris_alu_alloc_temps(dc, size, t);
1791
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1792

    
1793
        cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1794
        cris_alu_free_temps(dc, size, t);
1795
        return 2;
1796
}
1797

    
1798
static int dec_addc_r(DisasContext *dc)
1799
{
1800
        LOG_DIS("addc $r%u, $r%u\n",
1801
                    dc->op1, dc->op2);
1802
        cris_evaluate_flags(dc);
1803
        /* Set for this insn.  */
1804
        dc->flagx_known = 1;
1805
        dc->flags_x = X_FLAG;
1806

    
1807
        cris_cc_mask(dc, CC_MASK_NZVC);
1808
        cris_alu(dc, CC_OP_ADDC,
1809
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1810
        return 2;
1811
}
1812

    
1813
static int dec_mcp_r(DisasContext *dc)
1814
{
1815
        LOG_DIS("mcp $p%u, $r%u\n",
1816
                     dc->op2, dc->op1);
1817
        cris_evaluate_flags(dc);
1818
        cris_cc_mask(dc, CC_MASK_RNZV);
1819
        cris_alu(dc, CC_OP_MCP,
1820
                    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1821
        return 2;
1822
}
1823

    
1824
#if DISAS_CRIS
1825
static char * swapmode_name(int mode, char *modename) {
1826
        int i = 0;
1827
        if (mode & 8)
1828
                modename[i++] = 'n';
1829
        if (mode & 4)
1830
                modename[i++] = 'w';
1831
        if (mode & 2)
1832
                modename[i++] = 'b';
1833
        if (mode & 1)
1834
                modename[i++] = 'r';
1835
        modename[i++] = 0;
1836
        return modename;
1837
}
1838
#endif
1839

    
1840
static int dec_swap_r(DisasContext *dc)
1841
{
1842
        TCGv t0;
1843
#if DISAS_CRIS
1844
        char modename[4];
1845
#endif
1846
        LOG_DIS("swap%s $r%u\n",
1847
                     swapmode_name(dc->op2, modename), dc->op1);
1848

    
1849
        cris_cc_mask(dc, CC_MASK_NZ);
1850
        t0 = tcg_temp_new();
1851
        t_gen_mov_TN_reg(t0, dc->op1);
1852
        if (dc->op2 & 8)
1853
                tcg_gen_not_tl(t0, t0);
1854
        if (dc->op2 & 4)
1855
                t_gen_swapw(t0, t0);
1856
        if (dc->op2 & 2)
1857
                t_gen_swapb(t0, t0);
1858
        if (dc->op2 & 1)
1859
                t_gen_swapr(t0, t0);
1860
        cris_alu(dc, CC_OP_MOVE,
1861
                    cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1862
        tcg_temp_free(t0);
1863
        return 2;
1864
}
1865

    
1866
static int dec_or_r(DisasContext *dc)
1867
{
1868
        TCGv t[2];
1869
        int size = memsize_zz(dc);
1870
        LOG_DIS("or.%c $r%u, $r%u\n",
1871
                    memsize_char(size), dc->op1, dc->op2);
1872
        cris_cc_mask(dc, CC_MASK_NZ);
1873
        cris_alu_alloc_temps(dc, size, t);
1874
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1875
        cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1876
        cris_alu_free_temps(dc, size, t);
1877
        return 2;
1878
}
1879

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

    
1893
static int dec_addi_acr(DisasContext *dc)
1894
{
1895
        TCGv t0;
1896
        LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1897
                  memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1898
        cris_cc_mask(dc, 0);
1899
        t0 = tcg_temp_new();
1900
        tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1901
        tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1902
        tcg_temp_free(t0);
1903
        return 2;
1904
}
1905

    
1906
static int dec_neg_r(DisasContext *dc)
1907
{
1908
        TCGv t[2];
1909
        int size = memsize_zz(dc);
1910
        LOG_DIS("neg.%c $r%u, $r%u\n",
1911
                    memsize_char(size), dc->op1, dc->op2);
1912
        cris_cc_mask(dc, CC_MASK_NZVC);
1913
        cris_alu_alloc_temps(dc, size, t);
1914
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1915

    
1916
        cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1917
        cris_alu_free_temps(dc, size, t);
1918
        return 2;
1919
}
1920

    
1921
static int dec_btst_r(DisasContext *dc)
1922
{
1923
        LOG_DIS("btst $r%u, $r%u\n",
1924
                    dc->op1, dc->op2);
1925
        cris_cc_mask(dc, CC_MASK_NZ);
1926
        cris_evaluate_flags(dc);
1927
        gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1928
                        cpu_R[dc->op1], cpu_PR[PR_CCS]);
1929
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1930
                 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1931
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1932
        dc->flags_uptodate = 1;
1933
        return 2;
1934
}
1935

    
1936
static int dec_sub_r(DisasContext *dc)
1937
{
1938
        TCGv t[2];
1939
        int size = memsize_zz(dc);
1940
        LOG_DIS("sub.%c $r%u, $r%u\n",
1941
                    memsize_char(size), dc->op1, dc->op2);
1942
        cris_cc_mask(dc, CC_MASK_NZVC);
1943
        cris_alu_alloc_temps(dc, size, t);
1944
        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1945
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1946
        cris_alu_free_temps(dc, size, t);
1947
        return 2;
1948
}
1949

    
1950
/* Zero extension. From size to dword.  */
1951
static int dec_movu_r(DisasContext *dc)
1952
{
1953
        TCGv t0;
1954
        int size = memsize_z(dc);
1955
        LOG_DIS("movu.%c $r%u, $r%u\n",
1956
                    memsize_char(size),
1957
                    dc->op1, dc->op2);
1958

    
1959
        cris_cc_mask(dc, CC_MASK_NZ);
1960
        t0 = tcg_temp_new();
1961
        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1962
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1963
        tcg_temp_free(t0);
1964
        return 2;
1965
}
1966

    
1967
/* Sign extension. From size to dword.  */
1968
static int dec_movs_r(DisasContext *dc)
1969
{
1970
        TCGv t0;
1971
        int size = memsize_z(dc);
1972
        LOG_DIS("movs.%c $r%u, $r%u\n",
1973
                    memsize_char(size),
1974
                    dc->op1, dc->op2);
1975

    
1976
        cris_cc_mask(dc, CC_MASK_NZ);
1977
        t0 = tcg_temp_new();
1978
        /* Size can only be qi or hi.  */
1979
        t_gen_sext(t0, cpu_R[dc->op1], size);
1980
        cris_alu(dc, CC_OP_MOVE,
1981
                    cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1982
        tcg_temp_free(t0);
1983
        return 2;
1984
}
1985

    
1986
/* zero extension. From size to dword.  */
1987
static int dec_addu_r(DisasContext *dc)
1988
{
1989
        TCGv t0;
1990
        int size = memsize_z(dc);
1991
        LOG_DIS("addu.%c $r%u, $r%u\n",
1992
                    memsize_char(size),
1993
                    dc->op1, dc->op2);
1994

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

    
2005
/* Sign extension. From size to dword.  */
2006
static int dec_adds_r(DisasContext *dc)
2007
{
2008
        TCGv t0;
2009
        int size = memsize_z(dc);
2010
        LOG_DIS("adds.%c $r%u, $r%u\n",
2011
                    memsize_char(size),
2012
                    dc->op1, dc->op2);
2013

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

    
2024
/* Zero extension. From size to dword.  */
2025
static int dec_subu_r(DisasContext *dc)
2026
{
2027
        TCGv t0;
2028
        int size = memsize_z(dc);
2029
        LOG_DIS("subu.%c $r%u, $r%u\n",
2030
                    memsize_char(size),
2031
                    dc->op1, dc->op2);
2032

    
2033
        cris_cc_mask(dc, CC_MASK_NZVC);
2034
        t0 = tcg_temp_new();
2035
        /* Size can only be qi or hi.  */
2036
        t_gen_zext(t0, cpu_R[dc->op1], size);
2037
        cris_alu(dc, CC_OP_SUB,
2038
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2039
        tcg_temp_free(t0);
2040
        return 2;
2041
}
2042

    
2043
/* Sign extension. From size to dword.  */
2044
static int dec_subs_r(DisasContext *dc)
2045
{
2046
        TCGv t0;
2047
        int size = memsize_z(dc);
2048
        LOG_DIS("subs.%c $r%u, $r%u\n",
2049
                    memsize_char(size),
2050
                    dc->op1, dc->op2);
2051

    
2052
        cris_cc_mask(dc, CC_MASK_NZVC);
2053
        t0 = tcg_temp_new();
2054
        /* Size can only be qi or hi.  */
2055
        t_gen_sext(t0, cpu_R[dc->op1], size);
2056
        cris_alu(dc, CC_OP_SUB,
2057
                    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2058
        tcg_temp_free(t0);
2059
        return 2;
2060
}
2061

    
2062
static int dec_setclrf(DisasContext *dc)
2063
{
2064
        uint32_t flags;
2065
        int set = (~dc->opcode >> 2) & 1;
2066

    
2067

    
2068
        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2069
                | EXTRACT_FIELD(dc->ir, 0, 3);
2070
        if (set && flags == 0) {
2071
                LOG_DIS("nop\n");
2072
                return 2;
2073
        } else if (!set && (flags & 0x20)) {
2074
                LOG_DIS("di\n");
2075
        }
2076
        else {
2077
                LOG_DIS("%sf %x\n",
2078
                             set ? "set" : "clr",
2079
                            flags);
2080
        }
2081

    
2082
        /* User space is not allowed to touch these. Silently ignore.  */
2083
        if (dc->tb_flags & U_FLAG) {
2084
                flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2085
        }
2086

    
2087
        if (flags & X_FLAG) {
2088
                dc->flagx_known = 1;
2089
                if (set)
2090
                        dc->flags_x = X_FLAG;
2091
                else
2092
                        dc->flags_x = 0;
2093
        }
2094

    
2095
        /* Break the TB if any of the SPI flag changes.  */
2096
        if (flags & (P_FLAG | S_FLAG)) {
2097
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2098
                dc->is_jmp = DISAS_UPDATE;
2099
                dc->cpustate_changed = 1;
2100
        }
2101

    
2102
        /* For the I flag, only act on posedge.  */
2103
        if ((flags & I_FLAG)) {
2104
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2105
                dc->is_jmp = DISAS_UPDATE;
2106
                dc->cpustate_changed = 1;
2107
        }
2108

    
2109

    
2110
        /* Simply decode the flags.  */
2111
        cris_evaluate_flags (dc);
2112
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2113
        cris_update_cc_x(dc);
2114
        tcg_gen_movi_tl(cc_op, dc->cc_op);
2115

    
2116
        if (set) {
2117
                if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2118
                        /* Enter user mode.  */
2119
                        t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2120
                        tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2121
                        dc->cpustate_changed = 1;
2122
                }
2123
                tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2124
        }
2125
        else
2126
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2127

    
2128
        dc->flags_uptodate = 1;
2129
        dc->clear_x = 0;
2130
        return 2;
2131
}
2132

    
2133
static int dec_move_rs(DisasContext *dc)
2134
{
2135
        LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2136
        cris_cc_mask(dc, 0);
2137
        gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
2138
        return 2;
2139
}
2140
static int dec_move_sr(DisasContext *dc)
2141
{
2142
        LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2143
        cris_cc_mask(dc, 0);
2144
        gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
2145
        return 2;
2146
}
2147

    
2148
static int dec_move_rp(DisasContext *dc)
2149
{
2150
        TCGv t[2];
2151
        LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2152
        cris_cc_mask(dc, 0);
2153

    
2154
        t[0] = tcg_temp_new();
2155
        if (dc->op2 == PR_CCS) {
2156
                cris_evaluate_flags(dc);
2157
                t_gen_mov_TN_reg(t[0], dc->op1);
2158
                if (dc->tb_flags & U_FLAG) {
2159
                        t[1] = tcg_temp_new();
2160
                        /* User space is not allowed to touch all flags.  */
2161
                        tcg_gen_andi_tl(t[0], t[0], 0x39f);
2162
                        tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2163
                        tcg_gen_or_tl(t[0], t[1], t[0]);
2164
                        tcg_temp_free(t[1]);
2165
                }
2166
        }
2167
        else
2168
                t_gen_mov_TN_reg(t[0], dc->op1);
2169

    
2170
        t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2171
        if (dc->op2 == PR_CCS) {
2172
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2173
                dc->flags_uptodate = 1;
2174
        }
2175
        tcg_temp_free(t[0]);
2176
        return 2;
2177
}
2178
static int dec_move_pr(DisasContext *dc)
2179
{
2180
        TCGv t0;
2181
        LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2182
        cris_cc_mask(dc, 0);
2183

    
2184
        if (dc->op2 == PR_CCS)
2185
                cris_evaluate_flags(dc);
2186

    
2187
        if (dc->op2 == PR_DZ) {
2188
                tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2189
        } else {
2190
                t0 = tcg_temp_new();
2191
                t_gen_mov_TN_preg(t0, dc->op2);
2192
                cris_alu(dc, CC_OP_MOVE,
2193
                         cpu_R[dc->op1], cpu_R[dc->op1], t0,
2194
                         preg_sizes[dc->op2]);
2195
                tcg_temp_free(t0);
2196
        }
2197
        return 2;
2198
}
2199

    
2200
static int dec_move_mr(DisasContext *dc)
2201
{
2202
        int memsize = memsize_zz(dc);
2203
        int insn_len;
2204
        LOG_DIS("move.%c [$r%u%s, $r%u\n",
2205
                    memsize_char(memsize),
2206
                    dc->op1, dc->postinc ? "+]" : "]",
2207
                    dc->op2);
2208

    
2209
        if (memsize == 4) {
2210
                insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
2211
                cris_cc_mask(dc, CC_MASK_NZ);
2212
                cris_update_cc_op(dc, CC_OP_MOVE, 4);
2213
                cris_update_cc_x(dc);
2214
                cris_update_result(dc, cpu_R[dc->op2]);
2215
        }
2216
        else {
2217
                TCGv t0;
2218

    
2219
                t0 = tcg_temp_new();
2220
                insn_len = dec_prep_move_m(dc, 0, memsize, t0);
2221
                cris_cc_mask(dc, CC_MASK_NZ);
2222
                cris_alu(dc, CC_OP_MOVE,
2223
                            cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2224
                tcg_temp_free(t0);
2225
        }
2226
        do_postinc(dc, memsize);
2227
        return insn_len;
2228
}
2229

    
2230
static inline void cris_alu_m_alloc_temps(TCGv *t)
2231
{
2232
        t[0] = tcg_temp_new();
2233
        t[1] = tcg_temp_new();
2234
}
2235

    
2236
static inline void cris_alu_m_free_temps(TCGv *t)
2237
{
2238
        tcg_temp_free(t[0]);
2239
        tcg_temp_free(t[1]);
2240
}
2241

    
2242
static int dec_movs_m(DisasContext *dc)
2243
{
2244
        TCGv t[2];
2245
        int memsize = memsize_z(dc);
2246
        int insn_len;
2247
        LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2248
                    memsize_char(memsize),
2249
                    dc->op1, dc->postinc ? "+]" : "]",
2250
                    dc->op2);
2251

    
2252
        cris_alu_m_alloc_temps(t);
2253
        /* sign extend.  */
2254
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2255
        cris_cc_mask(dc, CC_MASK_NZ);
2256
        cris_alu(dc, CC_OP_MOVE,
2257
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2258
        do_postinc(dc, memsize);
2259
        cris_alu_m_free_temps(t);
2260
        return insn_len;
2261
}
2262

    
2263
static int dec_addu_m(DisasContext *dc)
2264
{
2265
        TCGv t[2];
2266
        int memsize = memsize_z(dc);
2267
        int insn_len;
2268
        LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2269
                    memsize_char(memsize),
2270
                    dc->op1, dc->postinc ? "+]" : "]",
2271
                    dc->op2);
2272

    
2273
        cris_alu_m_alloc_temps(t);
2274
        /* sign extend.  */
2275
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2276
        cris_cc_mask(dc, CC_MASK_NZVC);
2277
        cris_alu(dc, CC_OP_ADD,
2278
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2279
        do_postinc(dc, memsize);
2280
        cris_alu_m_free_temps(t);
2281
        return insn_len;
2282
}
2283

    
2284
static int dec_adds_m(DisasContext *dc)
2285
{
2286
        TCGv t[2];
2287
        int memsize = memsize_z(dc);
2288
        int insn_len;
2289
        LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2290
                    memsize_char(memsize),
2291
                    dc->op1, dc->postinc ? "+]" : "]",
2292
                    dc->op2);
2293

    
2294
        cris_alu_m_alloc_temps(t);
2295
        /* sign extend.  */
2296
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2297
        cris_cc_mask(dc, CC_MASK_NZVC);
2298
        cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2299
        do_postinc(dc, memsize);
2300
        cris_alu_m_free_temps(t);
2301
        return insn_len;
2302
}
2303

    
2304
static int dec_subu_m(DisasContext *dc)
2305
{
2306
        TCGv t[2];
2307
        int memsize = memsize_z(dc);
2308
        int insn_len;
2309
        LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2310
                    memsize_char(memsize),
2311
                    dc->op1, dc->postinc ? "+]" : "]",
2312
                    dc->op2);
2313

    
2314
        cris_alu_m_alloc_temps(t);
2315
        /* sign extend.  */
2316
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2317
        cris_cc_mask(dc, CC_MASK_NZVC);
2318
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2319
        do_postinc(dc, memsize);
2320
        cris_alu_m_free_temps(t);
2321
        return insn_len;
2322
}
2323

    
2324
static int dec_subs_m(DisasContext *dc)
2325
{
2326
        TCGv t[2];
2327
        int memsize = memsize_z(dc);
2328
        int insn_len;
2329
        LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2330
                    memsize_char(memsize),
2331
                    dc->op1, dc->postinc ? "+]" : "]",
2332
                    dc->op2);
2333

    
2334
        cris_alu_m_alloc_temps(t);
2335
        /* sign extend.  */
2336
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2337
        cris_cc_mask(dc, CC_MASK_NZVC);
2338
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2339
        do_postinc(dc, memsize);
2340
        cris_alu_m_free_temps(t);
2341
        return insn_len;
2342
}
2343

    
2344
static int dec_movu_m(DisasContext *dc)
2345
{
2346
        TCGv t[2];
2347
        int memsize = memsize_z(dc);
2348
        int insn_len;
2349

    
2350
        LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2351
                    memsize_char(memsize),
2352
                    dc->op1, dc->postinc ? "+]" : "]",
2353
                    dc->op2);
2354

    
2355
        cris_alu_m_alloc_temps(t);
2356
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2357
        cris_cc_mask(dc, CC_MASK_NZ);
2358
        cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2359
        do_postinc(dc, memsize);
2360
        cris_alu_m_free_temps(t);
2361
        return insn_len;
2362
}
2363

    
2364
static int dec_cmpu_m(DisasContext *dc)
2365
{
2366
        TCGv t[2];
2367
        int memsize = memsize_z(dc);
2368
        int insn_len;
2369
        LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2370
                    memsize_char(memsize),
2371
                    dc->op1, dc->postinc ? "+]" : "]",
2372
                    dc->op2);
2373

    
2374
        cris_alu_m_alloc_temps(t);
2375
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2376
        cris_cc_mask(dc, CC_MASK_NZVC);
2377
        cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2378
        do_postinc(dc, memsize);
2379
        cris_alu_m_free_temps(t);
2380
        return insn_len;
2381
}
2382

    
2383
static int dec_cmps_m(DisasContext *dc)
2384
{
2385
        TCGv t[2];
2386
        int memsize = memsize_z(dc);
2387
        int insn_len;
2388
        LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2389
                    memsize_char(memsize),
2390
                    dc->op1, dc->postinc ? "+]" : "]",
2391
                    dc->op2);
2392

    
2393
        cris_alu_m_alloc_temps(t);
2394
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2395
        cris_cc_mask(dc, CC_MASK_NZVC);
2396
        cris_alu(dc, CC_OP_CMP,
2397
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2398
                    memsize_zz(dc));
2399
        do_postinc(dc, memsize);
2400
        cris_alu_m_free_temps(t);
2401
        return insn_len;
2402
}
2403

    
2404
static int dec_cmp_m(DisasContext *dc)
2405
{
2406
        TCGv t[2];
2407
        int memsize = memsize_zz(dc);
2408
        int insn_len;
2409
        LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2410
                    memsize_char(memsize),
2411
                    dc->op1, dc->postinc ? "+]" : "]",
2412
                    dc->op2);
2413

    
2414
        cris_alu_m_alloc_temps(t);
2415
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2416
        cris_cc_mask(dc, CC_MASK_NZVC);
2417
        cris_alu(dc, CC_OP_CMP,
2418
                    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2419
                    memsize_zz(dc));
2420
        do_postinc(dc, memsize);
2421
        cris_alu_m_free_temps(t);
2422
        return insn_len;
2423
}
2424

    
2425
static int dec_test_m(DisasContext *dc)
2426
{
2427
        TCGv t[2];
2428
        int memsize = memsize_zz(dc);
2429
        int insn_len;
2430
        LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2431
                    memsize_char(memsize),
2432
                    dc->op1, dc->postinc ? "+]" : "]",
2433
                    dc->op2);
2434

    
2435
        cris_evaluate_flags(dc);
2436

    
2437
        cris_alu_m_alloc_temps(t);
2438
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2439
        cris_cc_mask(dc, CC_MASK_NZ);
2440
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2441

    
2442
        cris_alu(dc, CC_OP_CMP,
2443
                 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2444
        do_postinc(dc, memsize);
2445
        cris_alu_m_free_temps(t);
2446
        return insn_len;
2447
}
2448

    
2449
static int dec_and_m(DisasContext *dc)
2450
{
2451
        TCGv t[2];
2452
        int memsize = memsize_zz(dc);
2453
        int insn_len;
2454
        LOG_DIS("and.%c [$r%u%s, $r%u\n",
2455
                    memsize_char(memsize),
2456
                    dc->op1, dc->postinc ? "+]" : "]",
2457
                    dc->op2);
2458

    
2459
        cris_alu_m_alloc_temps(t);
2460
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2461
        cris_cc_mask(dc, CC_MASK_NZ);
2462
        cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2463
        do_postinc(dc, memsize);
2464
        cris_alu_m_free_temps(t);
2465
        return insn_len;
2466
}
2467

    
2468
static int dec_add_m(DisasContext *dc)
2469
{
2470
        TCGv t[2];
2471
        int memsize = memsize_zz(dc);
2472
        int insn_len;
2473
        LOG_DIS("add.%c [$r%u%s, $r%u\n",
2474
                    memsize_char(memsize),
2475
                    dc->op1, dc->postinc ? "+]" : "]",
2476
                    dc->op2);
2477

    
2478
        cris_alu_m_alloc_temps(t);
2479
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2480
        cris_cc_mask(dc, CC_MASK_NZVC);
2481
        cris_alu(dc, CC_OP_ADD,
2482
                 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2483
        do_postinc(dc, memsize);
2484
        cris_alu_m_free_temps(t);
2485
        return insn_len;
2486
}
2487

    
2488
static int dec_addo_m(DisasContext *dc)
2489
{
2490
        TCGv t[2];
2491
        int memsize = memsize_zz(dc);
2492
        int insn_len;
2493
        LOG_DIS("add.%c [$r%u%s, $r%u\n",
2494
                    memsize_char(memsize),
2495
                    dc->op1, dc->postinc ? "+]" : "]",
2496
                    dc->op2);
2497

    
2498
        cris_alu_m_alloc_temps(t);
2499
        insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2500
        cris_cc_mask(dc, 0);
2501
        cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2502
        do_postinc(dc, memsize);
2503
        cris_alu_m_free_temps(t);
2504
        return insn_len;
2505
}
2506

    
2507
static int dec_bound_m(DisasContext *dc)
2508
{
2509
        TCGv l[2];
2510
        int memsize = memsize_zz(dc);
2511
        int insn_len;
2512
        LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2513
                    memsize_char(memsize),
2514
                    dc->op1, dc->postinc ? "+]" : "]",
2515
                    dc->op2);
2516

    
2517
        l[0] = tcg_temp_local_new();
2518
        l[1] = tcg_temp_local_new();
2519
        insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
2520
        cris_cc_mask(dc, CC_MASK_NZ);
2521
        cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2522
        do_postinc(dc, memsize);
2523
        tcg_temp_free(l[0]);
2524
        tcg_temp_free(l[1]);
2525
        return insn_len;
2526
}
2527

    
2528
static int dec_addc_mr(DisasContext *dc)
2529
{
2530
        TCGv t[2];
2531
        int insn_len = 2;
2532
        LOG_DIS("addc [$r%u%s, $r%u\n",
2533
                    dc->op1, dc->postinc ? "+]" : "]",
2534
                    dc->op2);
2535

    
2536
        cris_evaluate_flags(dc);
2537

    
2538
        /* Set for this insn.  */
2539
        dc->flagx_known = 1;
2540
        dc->flags_x = X_FLAG;
2541

    
2542
        cris_alu_m_alloc_temps(t);
2543
        insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2544
        cris_cc_mask(dc, CC_MASK_NZVC);
2545
        cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2546
        do_postinc(dc, 4);
2547
        cris_alu_m_free_temps(t);
2548
        return insn_len;
2549
}
2550

    
2551
static int dec_sub_m(DisasContext *dc)
2552
{
2553
        TCGv t[2];
2554
        int memsize = memsize_zz(dc);
2555
        int insn_len;
2556
        LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2557
                    memsize_char(memsize),
2558
                    dc->op1, dc->postinc ? "+]" : "]",
2559
                    dc->op2, dc->ir, dc->zzsize);
2560

    
2561
        cris_alu_m_alloc_temps(t);
2562
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2563
        cris_cc_mask(dc, CC_MASK_NZVC);
2564
        cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2565
        do_postinc(dc, memsize);
2566
        cris_alu_m_free_temps(t);
2567
        return insn_len;
2568
}
2569

    
2570
static int dec_or_m(DisasContext *dc)
2571
{
2572
        TCGv t[2];
2573
        int memsize = memsize_zz(dc);
2574
        int insn_len;
2575
        LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2576
                    memsize_char(memsize),
2577
                    dc->op1, dc->postinc ? "+]" : "]",
2578
                    dc->op2, dc->pc);
2579

    
2580
        cris_alu_m_alloc_temps(t);
2581
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2582
        cris_cc_mask(dc, CC_MASK_NZ);
2583
        cris_alu(dc, CC_OP_OR,
2584
                    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2585
        do_postinc(dc, memsize);
2586
        cris_alu_m_free_temps(t);
2587
        return insn_len;
2588
}
2589

    
2590
static int dec_move_mp(DisasContext *dc)
2591
{
2592
        TCGv t[2];
2593
        int memsize = memsize_zz(dc);
2594
        int insn_len = 2;
2595

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

    
2602
        cris_alu_m_alloc_temps(t);
2603
        insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2604
        cris_cc_mask(dc, 0);
2605
        if (dc->op2 == PR_CCS) {
2606
                cris_evaluate_flags(dc);
2607
                if (dc->tb_flags & U_FLAG) {
2608
                        /* User space is not allowed to touch all flags.  */
2609
                        tcg_gen_andi_tl(t[1], t[1], 0x39f);
2610
                        tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2611
                        tcg_gen_or_tl(t[1], t[0], t[1]);
2612
                }
2613
        }
2614

    
2615
        t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2616

    
2617
        do_postinc(dc, memsize);
2618
        cris_alu_m_free_temps(t);
2619
        return insn_len;
2620
}
2621

    
2622
static int dec_move_pm(DisasContext *dc)
2623
{
2624
        TCGv t0;
2625
        int memsize;
2626

    
2627
        memsize = preg_sizes[dc->op2];
2628

    
2629
        LOG_DIS("move.%c $p%u, [$r%u%s\n",
2630
                     memsize_char(memsize), 
2631
                     dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2632

    
2633
        /* prepare store. Address in T0, value in T1.  */
2634
        if (dc->op2 == PR_CCS)
2635
                cris_evaluate_flags(dc);
2636
        t0 = tcg_temp_new();
2637
        t_gen_mov_TN_preg(t0, dc->op2);
2638
        cris_flush_cc_state(dc);
2639
        gen_store(dc, cpu_R[dc->op1], t0, memsize);
2640
        tcg_temp_free(t0);
2641

    
2642
        cris_cc_mask(dc, 0);
2643
        if (dc->postinc)
2644
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2645
        return 2;
2646
}
2647

    
2648
static int dec_movem_mr(DisasContext *dc)
2649
{
2650
        TCGv_i64 tmp[16];
2651
        TCGv tmp32;
2652
        TCGv addr;
2653
        int i;
2654
        int nr = dc->op2 + 1;
2655

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

    
2659
        addr = tcg_temp_new();
2660
        /* There are probably better ways of doing this.  */
2661
        cris_flush_cc_state(dc);
2662
        for (i = 0; i < (nr >> 1); i++) {
2663
                tmp[i] = tcg_temp_new_i64();
2664
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2665
                gen_load64(dc, tmp[i], addr);
2666
        }
2667
        if (nr & 1) {
2668
                tmp32 = tcg_temp_new_i32();
2669
                tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2670
                gen_load(dc, tmp32, addr, 4, 0);
2671
        } else
2672
                TCGV_UNUSED(tmp32);
2673
        tcg_temp_free(addr);
2674

    
2675
        for (i = 0; i < (nr >> 1); i++) {
2676
                tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2677
                tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2678
                tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2679
                tcg_temp_free_i64(tmp[i]);
2680
        }
2681
        if (nr & 1) {
2682
                tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2683
                tcg_temp_free(tmp32);
2684
        }
2685

    
2686
        /* writeback the updated pointer value.  */
2687
        if (dc->postinc)
2688
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2689

    
2690
        /* gen_load might want to evaluate the previous insns flags.  */
2691
        cris_cc_mask(dc, 0);
2692
        return 2;
2693
}
2694

    
2695
static int dec_movem_rm(DisasContext *dc)
2696
{
2697
        TCGv tmp;
2698
        TCGv addr;
2699
        int i;
2700

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

    
2704
        cris_flush_cc_state(dc);
2705

    
2706
        tmp = tcg_temp_new();
2707
        addr = tcg_temp_new();
2708
        tcg_gen_movi_tl(tmp, 4);
2709
        tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2710
        for (i = 0; i <= dc->op2; i++) {
2711
                /* Displace addr.  */
2712
                /* Perform the store.  */
2713
                gen_store(dc, addr, cpu_R[i], 4);
2714
                tcg_gen_add_tl(addr, addr, tmp);
2715
        }
2716
        if (dc->postinc)
2717
                tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2718
        cris_cc_mask(dc, 0);
2719
        tcg_temp_free(tmp);
2720
        tcg_temp_free(addr);
2721
        return 2;
2722
}
2723

    
2724
static int dec_move_rm(DisasContext *dc)
2725
{
2726
        int memsize;
2727

    
2728
        memsize = memsize_zz(dc);
2729

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

    
2733
        /* prepare store.  */
2734
        cris_flush_cc_state(dc);
2735
        gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2736

    
2737
        if (dc->postinc)
2738
                tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2739
        cris_cc_mask(dc, 0);
2740
        return 2;
2741
}
2742

    
2743
static int dec_lapcq(DisasContext *dc)
2744
{
2745
        LOG_DIS("lapcq %x, $r%u\n",
2746
                    dc->pc + dc->op1*2, dc->op2);
2747
        cris_cc_mask(dc, 0);
2748
        tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2749
        return 2;
2750
}
2751

    
2752
static int dec_lapc_im(DisasContext *dc)
2753
{
2754
        unsigned int rd;
2755
        int32_t imm;
2756
        int32_t pc;
2757

    
2758
        rd = dc->op2;
2759

    
2760
        cris_cc_mask(dc, 0);
2761
        imm = ldl_code(dc->pc + 2);
2762
        LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2763

    
2764
        pc = dc->pc;
2765
        pc += imm;
2766
        tcg_gen_movi_tl(cpu_R[rd], pc);
2767
        return 6;
2768
}
2769

    
2770
/* Jump to special reg.  */
2771
static int dec_jump_p(DisasContext *dc)
2772
{
2773
        LOG_DIS("jump $p%u\n", dc->op2);
2774

    
2775
        if (dc->op2 == PR_CCS)
2776
                cris_evaluate_flags(dc);
2777
        t_gen_mov_TN_preg(env_btarget, dc->op2);
2778
        /* rete will often have low bit set to indicate delayslot.  */
2779
        tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2780
        cris_cc_mask(dc, 0);
2781
        cris_prepare_jmp(dc, JMP_INDIRECT);
2782
        return 2;
2783
}
2784

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

    
2796
        cris_prepare_jmp(dc, JMP_INDIRECT);
2797
        return 2;
2798
}
2799

    
2800
static int dec_jas_im(DisasContext *dc)
2801
{
2802
        uint32_t imm;
2803

    
2804
        imm = ldl_code(dc->pc + 2);
2805

    
2806
        LOG_DIS("jas 0x%x\n", imm);
2807
        cris_cc_mask(dc, 0);
2808
        /* Store the return address in Pd.  */
2809
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2810

    
2811
        dc->jmp_pc = imm;
2812
        cris_prepare_jmp(dc, JMP_DIRECT);
2813
        return 6;
2814
}
2815

    
2816
static int dec_jasc_im(DisasContext *dc)
2817
{
2818
        uint32_t imm;
2819

    
2820
        imm = ldl_code(dc->pc + 2);
2821

    
2822
        LOG_DIS("jasc 0x%x\n", imm);
2823
        cris_cc_mask(dc, 0);
2824
        /* Store the return address in Pd.  */
2825
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
2826

    
2827
        dc->jmp_pc = imm;
2828
        cris_prepare_jmp(dc, JMP_DIRECT);
2829
        return 6;
2830
}
2831

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

    
2843
static int dec_bcc_im(DisasContext *dc)
2844
{
2845
        int32_t offset;
2846
        uint32_t cond = dc->op2;
2847

    
2848
        offset = ldsw_code(dc->pc + 2);
2849

    
2850
        LOG_DIS("b%s %d pc=%x dst=%x\n",
2851
                    cc_name(cond), offset,
2852
                    dc->pc, dc->pc + offset);
2853

    
2854
        cris_cc_mask(dc, 0);
2855
        /* op2 holds the condition-code.  */
2856
        cris_prepare_cc_branch (dc, offset, cond);
2857
        return 4;
2858
}
2859

    
2860
static int dec_bas_im(DisasContext *dc)
2861
{
2862
        int32_t simm;
2863

    
2864

    
2865
        simm = ldl_code(dc->pc + 2);
2866

    
2867
        LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2868
        cris_cc_mask(dc, 0);
2869
        /* Store the return address in Pd.  */
2870
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2871

    
2872
        dc->jmp_pc = dc->pc + simm;
2873
        cris_prepare_jmp(dc, JMP_DIRECT);
2874
        return 6;
2875
}
2876

    
2877
static int dec_basc_im(DisasContext *dc)
2878
{
2879
        int32_t simm;
2880
        simm = ldl_code(dc->pc + 2);
2881

    
2882
        LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2883
        cris_cc_mask(dc, 0);
2884
        /* Store the return address in Pd.  */
2885
        t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
2886

    
2887
        dc->jmp_pc = dc->pc + simm;
2888
        cris_prepare_jmp(dc, JMP_DIRECT);
2889
        return 6;
2890
}
2891

    
2892
static int dec_rfe_etc(DisasContext *dc)
2893
{
2894
        cris_cc_mask(dc, 0);
2895

    
2896
        if (dc->op2 == 15) {
2897
                t_gen_mov_env_TN(halted, tcg_const_tl(1));
2898
                tcg_gen_movi_tl(env_pc, dc->pc + 2);
2899
                t_gen_raise_exception(EXCP_HLT);
2900
                return 2;
2901
        }
2902

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

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

    
2935
        }
2936
        return 2;
2937
}
2938

    
2939
static int dec_ftag_fidx_d_m(DisasContext *dc)
2940
{
2941
        return 2;
2942
}
2943

    
2944
static int dec_ftag_fidx_i_m(DisasContext *dc)
2945
{
2946
        return 2;
2947
}
2948

    
2949
static int dec_null(DisasContext *dc)
2950
{
2951
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2952
                dc->pc, dc->opcode, dc->op1, dc->op2);
2953
        fflush(NULL);
2954
        BUG();
2955
        return 2;
2956
}
2957

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

    
2979
        {DEC_BCC_IM, dec_bcc_im},
2980
        {DEC_JAS_IM, dec_jas_im},
2981
        {DEC_JAS_R, dec_jas_r},
2982
        {DEC_JASC_IM, dec_jasc_im},
2983
        {DEC_JASC_R, dec_jasc_r},
2984
        {DEC_BAS_IM, dec_bas_im},
2985
        {DEC_BASC_IM, dec_basc_im},
2986
        {DEC_JUMP_P, dec_jump_p},
2987
        {DEC_LAPC_IM, dec_lapc_im},
2988
        {DEC_LAPCQ, dec_lapcq},
2989

    
2990
        {DEC_RFE_ETC, dec_rfe_etc},
2991
        {DEC_ADDC_MR, dec_addc_mr},
2992

    
2993
        {DEC_MOVE_MP, dec_move_mp},
2994
        {DEC_MOVE_PM, dec_move_pm},
2995
        {DEC_MOVEM_MR, dec_movem_mr},
2996
        {DEC_MOVEM_RM, dec_movem_rm},
2997
        {DEC_MOVE_PR, dec_move_pr},
2998
        {DEC_SCC_R, dec_scc_r},
2999
        {DEC_SETF, dec_setclrf},
3000
        {DEC_CLEARF, dec_setclrf},
3001

    
3002
        {DEC_MOVE_SR, dec_move_sr},
3003
        {DEC_MOVE_RP, dec_move_rp},
3004
        {DEC_SWAP_R, dec_swap_r},
3005
        {DEC_ABS_R, dec_abs_r},
3006
        {DEC_LZ_R, dec_lz_r},
3007
        {DEC_MOVE_RS, dec_move_rs},
3008
        {DEC_BTST_R, dec_btst_r},
3009
        {DEC_ADDC_R, dec_addc_r},
3010

    
3011
        {DEC_DSTEP_R, dec_dstep_r},
3012
        {DEC_XOR_R, dec_xor_r},
3013
        {DEC_MCP_R, dec_mcp_r},
3014
        {DEC_CMP_R, dec_cmp_r},
3015

    
3016
        {DEC_ADDI_R, dec_addi_r},
3017
        {DEC_ADDI_ACR, dec_addi_acr},
3018

    
3019
        {DEC_ADD_R, dec_add_r},
3020
        {DEC_SUB_R, dec_sub_r},
3021

    
3022
        {DEC_ADDU_R, dec_addu_r},
3023
        {DEC_ADDS_R, dec_adds_r},
3024
        {DEC_SUBU_R, dec_subu_r},
3025
        {DEC_SUBS_R, dec_subs_r},
3026
        {DEC_LSL_R, dec_lsl_r},
3027

    
3028
        {DEC_AND_R, dec_and_r},
3029
        {DEC_OR_R, dec_or_r},
3030
        {DEC_BOUND_R, dec_bound_r},
3031
        {DEC_ASR_R, dec_asr_r},
3032
        {DEC_LSR_R, dec_lsr_r},
3033

    
3034
        {DEC_MOVU_R, dec_movu_r},
3035
        {DEC_MOVS_R, dec_movs_r},
3036
        {DEC_NEG_R, dec_neg_r},
3037
        {DEC_MOVE_R, dec_move_r},
3038

    
3039
        {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
3040
        {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
3041

    
3042
        {DEC_MULS_R, dec_muls_r},
3043
        {DEC_MULU_R, dec_mulu_r},
3044

    
3045
        {DEC_ADDU_M, dec_addu_m},
3046
        {DEC_ADDS_M, dec_adds_m},
3047
        {DEC_SUBU_M, dec_subu_m},
3048
        {DEC_SUBS_M, dec_subs_m},
3049

    
3050
        {DEC_CMPU_M, dec_cmpu_m},
3051
        {DEC_CMPS_M, dec_cmps_m},
3052
        {DEC_MOVU_M, dec_movu_m},
3053
        {DEC_MOVS_M, dec_movs_m},
3054

    
3055
        {DEC_CMP_M, dec_cmp_m},
3056
        {DEC_ADDO_M, dec_addo_m},
3057
        {DEC_BOUND_M, dec_bound_m},
3058
        {DEC_ADD_M, dec_add_m},
3059
        {DEC_SUB_M, dec_sub_m},
3060
        {DEC_AND_M, dec_and_m},
3061
        {DEC_OR_M, dec_or_m},
3062
        {DEC_MOVE_RM, dec_move_rm},
3063
        {DEC_TEST_M, dec_test_m},
3064
        {DEC_MOVE_MR, dec_move_mr},
3065

    
3066
        {{0, 0}, dec_null}
3067
};
3068

    
3069
static unsigned int crisv32_decoder(DisasContext *dc)
3070
{
3071
        int insn_len = 2;
3072
        int i;
3073

    
3074
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
3075
                tcg_gen_debug_insn_start(dc->pc);
3076

    
3077
        /* Load a halfword onto the instruction register.  */
3078
        dc->ir = lduw_code(dc->pc);
3079

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

    
3088
        /* Large switch for all insns.  */
3089
        for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
3090
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
3091
                {
3092
                        insn_len = decinfo[i].dec(dc);
3093
                        break;
3094
                }
3095
        }
3096

    
3097
#if !defined(CONFIG_USER_ONLY)
3098
        /* Single-stepping ?  */
3099
        if (dc->tb_flags & S_FLAG) {
3100
                int l1;
3101

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

    
3116
static void check_breakpoint(CPUState *env, DisasContext *dc)
3117
{
3118
        CPUBreakpoint *bp;
3119

    
3120
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3121
                QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3122
                        if (bp->pc == dc->pc) {
3123
                                cris_evaluate_flags (dc);
3124
                                tcg_gen_movi_tl(env_pc, dc->pc);
3125
                                t_gen_raise_exception(EXCP_DEBUG);
3126
                                dc->is_jmp = DISAS_UPDATE;
3127
                        }
3128
                }
3129
        }
3130
}
3131

    
3132
#include "translate_v10.c"
3133

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

    
3168
/* generate intermediate code for basic block 'tb'.  */
3169
static void
3170
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3171
                               int search_pc)
3172
{
3173
        uint16_t *gen_opc_end;
3174
           uint32_t pc_start;
3175
        unsigned int insn_len, orig_flags;
3176
        int j, lj;
3177
        struct DisasContext ctx;
3178
        struct DisasContext *dc = &ctx;
3179
        uint32_t next_page_start;
3180
        target_ulong npc;
3181
        int num_insns;
3182
        int max_insns;
3183

    
3184
        qemu_log_try_set_file(stderr);
3185

    
3186
        if (env->pregs[PR_VR] == 32)
3187
                dc->decoder = crisv32_decoder;
3188
        else
3189
                dc->decoder = crisv10_decoder;
3190

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

    
3198
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3199

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

    
3213
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3214
        dc->cc_size_uptodate = -1;
3215

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

    
3225
        dc->cpustate_changed = 0;
3226

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

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

    
3257
        gen_icount_start();
3258
        do
3259
        {
3260
                check_breakpoint(env, dc);
3261

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

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

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

    
3284
                insn_len = dc->decoder(dc);
3285
                dc->ppc = dc->pc;
3286
                dc->pc += insn_len;
3287
                if (dc->clear_x)
3288
                        cris_clear_x_flag(dc);
3289

    
3290
                num_insns++;
3291
                /* Check for delayed branches here. If we do it before
3292
                   actually generating any host code, the simulator will just
3293
                   loop doing nothing for on this program location.  */
3294
                if (dc->delayed_branch) {
3295
                        dc->delayed_branch--;
3296
                        if (dc->delayed_branch == 0)
3297
                        {
3298
                                if (tb->flags & 7)
3299
                                        t_gen_mov_env_TN(dslot, 
3300
                                                tcg_const_tl(0));
3301
                                if (dc->jmp == JMP_DIRECT) {
3302
                                        dc->is_jmp = DISAS_NEXT;
3303
                                } else {
3304
                                        t_gen_cc_jmp(env_btarget, 
3305
                                                     tcg_const_tl(dc->pc));
3306
                                        dc->is_jmp = DISAS_JUMP;
3307
                                }
3308
                                break;
3309
                        }
3310
                }
3311

    
3312
                /* If we are rexecuting a branch due to exceptions on
3313
                   delay slots dont break.  */
3314
                if (!(tb->pc & 1) && env->singlestep_enabled)
3315
                        break;
3316
        } while (!dc->is_jmp && !dc->cpustate_changed
3317
                 && gen_opc_ptr < gen_opc_end
3318
                 && !singlestep
3319
                 && (dc->pc < next_page_start)
3320
                 && num_insns < max_insns);
3321

    
3322
        if (dc->tb_flags != orig_flags) {
3323
                dc->cpustate_changed = 1;
3324
        }
3325

    
3326
        if (dc->clear_locked_irq)
3327
                t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3328

    
3329
        npc = dc->pc;
3330
        if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
3331
                npc = dc->jmp_pc;
3332

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

    
3349
        cris_evaluate_flags (dc);
3350

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

    
3385
#ifdef DEBUG_DISAS
3386
#if !DISAS_CRIS
3387
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3388
                log_target_disas(pc_start, dc->pc - pc_start,
3389
                                 dc->env->pregs[PR_VR]);
3390
                qemu_log("\nisize=%d osize=%zd\n",
3391
                        dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3392
        }
3393
#endif
3394
#endif
3395
}
3396

    
3397
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3398
{
3399
    gen_intermediate_code_internal(env, tb, 0);
3400
}
3401

    
3402
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3403
{
3404
    gen_intermediate_code_internal(env, tb, 1);
3405
}
3406

    
3407
void cpu_dump_state (CPUState *env, FILE *f,
3408
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3409
                     int flags)
3410
{
3411
        int i;
3412
        uint32_t srs;
3413

    
3414
        if (!env || !f)
3415
                return;
3416

    
3417
        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3418
                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3419
                    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3420
                    env->cc_op,
3421
                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3422

    
3423

    
3424
        for (i = 0; i < 16; i++) {
3425
                cpu_fprintf(f, "%s=%8.8x ",regnames[i], env->regs[i]);
3426
                if ((i + 1) % 4 == 0)
3427
                        cpu_fprintf(f, "\n");
3428
        }
3429
        cpu_fprintf(f, "\nspecial regs:\n");
3430
        for (i = 0; i < 16; i++) {
3431
                cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3432
                if ((i + 1) % 4 == 0)
3433
                        cpu_fprintf(f, "\n");
3434
        }
3435
        srs = env->pregs[PR_SRS];
3436
        cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3437
        if (srs < 256) {
3438
                for (i = 0; i < 16; i++) {
3439
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
3440
                                    i, env->sregs[srs][i]);
3441
                        if ((i + 1) % 4 == 0)
3442
                                cpu_fprintf(f, "\n");
3443
                }
3444
        }
3445
        cpu_fprintf(f, "\n\n");
3446

    
3447
}
3448

    
3449
struct
3450
{
3451
    uint32_t vr;
3452
    const char *name;
3453
} cris_cores[] = {
3454
        {8, "crisv8"},
3455
        {9, "crisv9"},
3456
        {10, "crisv10"},
3457
        {11, "crisv11"},
3458
        {32, "crisv32"},
3459
};
3460

    
3461
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
3462
{
3463
    unsigned int i;
3464

    
3465
    (*cpu_fprintf)(f, "Available CPUs:\n");
3466
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3467
        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
3468
    }
3469
}
3470

    
3471
static uint32_t vr_by_name(const char *name)
3472
{
3473
    unsigned int i;
3474
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3475
        if (strcmp(name, cris_cores[i].name) == 0) {
3476
            return cris_cores[i].vr;
3477
        }
3478
    }
3479
    return 32;
3480
}
3481

    
3482
CPUCRISState *cpu_cris_init (const char *cpu_model)
3483
{
3484
        CPUCRISState *env;
3485
        static int tcg_initialized = 0;
3486
        int i;
3487

    
3488
        env = qemu_mallocz(sizeof(CPUCRISState));
3489

    
3490
        env->pregs[PR_VR] = vr_by_name(cpu_model);
3491
        cpu_exec_init(env);
3492
        cpu_reset(env);
3493
        qemu_init_vcpu(env);
3494

    
3495
        if (tcg_initialized)
3496
                return env;
3497

    
3498
        tcg_initialized = 1;
3499

    
3500
#define GEN_HELPER 2
3501
#include "helper.h"
3502

    
3503
        if (env->pregs[PR_VR] < 32) {
3504
                cpu_crisv10_init(env);
3505
                return env; 
3506
        }
3507

    
3508

    
3509
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3510
        cc_x = tcg_global_mem_new(TCG_AREG0,
3511
                                  offsetof(CPUState, cc_x), "cc_x");
3512
        cc_src = tcg_global_mem_new(TCG_AREG0,
3513
                                    offsetof(CPUState, cc_src), "cc_src");
3514
        cc_dest = tcg_global_mem_new(TCG_AREG0,
3515
                                     offsetof(CPUState, cc_dest),
3516
                                     "cc_dest");
3517
        cc_result = tcg_global_mem_new(TCG_AREG0,
3518
                                       offsetof(CPUState, cc_result),
3519
                                       "cc_result");
3520
        cc_op = tcg_global_mem_new(TCG_AREG0,
3521
                                   offsetof(CPUState, cc_op), "cc_op");
3522
        cc_size = tcg_global_mem_new(TCG_AREG0,
3523
                                     offsetof(CPUState, cc_size),
3524
                                     "cc_size");
3525
        cc_mask = tcg_global_mem_new(TCG_AREG0,
3526
                                     offsetof(CPUState, cc_mask),
3527
                                     "cc_mask");
3528

    
3529
        env_pc = tcg_global_mem_new(TCG_AREG0, 
3530
                                    offsetof(CPUState, pc),
3531
                                    "pc");
3532
        env_btarget = tcg_global_mem_new(TCG_AREG0,
3533
                                         offsetof(CPUState, btarget),
3534
                                         "btarget");
3535
        env_btaken = tcg_global_mem_new(TCG_AREG0,
3536
                                         offsetof(CPUState, btaken),
3537
                                         "btaken");
3538
        for (i = 0; i < 16; i++) {
3539
                cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
3540
                                              offsetof(CPUState, regs[i]),
3541
                                              regnames[i]);
3542
        }
3543
        for (i = 0; i < 16; i++) {
3544
                cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
3545
                                               offsetof(CPUState, pregs[i]),
3546
                                               pregnames[i]);
3547
        }
3548

    
3549
        return env;
3550
}
3551

    
3552
void cpu_reset (CPUCRISState *env)
3553
{
3554
        uint32_t vr;
3555

    
3556
        if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3557
                qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3558
                log_cpu_state(env, 0);
3559
        }
3560

    
3561
        vr = env->pregs[PR_VR];
3562
        memset(env, 0, offsetof(CPUCRISState, breakpoints));
3563
        env->pregs[PR_VR] = vr;
3564
        tlb_flush(env, 1);
3565

    
3566
#if defined(CONFIG_USER_ONLY)
3567
        /* start in user mode with interrupts enabled.  */
3568
        env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
3569
#else
3570
        cris_mmu_init(env);
3571
        env->pregs[PR_CCS] = 0;
3572
#endif
3573
}
3574

    
3575
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
3576
                 unsigned long searched_pc, int pc_pos, void *puc)
3577
{
3578
        env->pc = gen_opc_pc[pc_pos];
3579
}