Annotation of qemu/target-cris/translate.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  CRIS emulation for qemu: main translation routines.
                      3:  *
                      4:  *  Copyright (c) 2007 AXIS Communications AB
                      5:  *  Written by Edgar E. Iglesias.
                      6:  *
                      7:  * This library is free software; you can redistribute it and/or
                      8:  * modify it under the terms of the GNU Lesser General Public
                      9:  * License as published by the Free Software Foundation; either
                     10:  * version 2 of the License, or (at your option) any later version.
                     11:  *
                     12:  * This library is distributed in the hope that it will be useful,
                     13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * Lesser General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU Lesser General Public
                     18:  * License along with this library; if not, write to the Free Software
                     19:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     20:  */
                     21: 
                     22: /*
                     23:  * This file implements a CRIS decoder-stage in SW. The decoder translates the
                     24:  * guest (CRIS) machine-code into host machine code via dyngen using the
                     25:  * micro-operations described in op.c
                     26:  *
                     27:  * The micro-operations for CRIS translation implement a RISC style ISA.
                     28:  * Note that the micro-operations typically order their operands
                     29:  * starting with the dst. CRIS asm, does the opposite.
                     30:  *
                     31:  * For example the following CRIS code:
                     32:  * add.d [$r0], $r1
                     33:  *
                     34:  * translates into:
                     35:  *
                     36:  * gen_movl_T0_reg(0);   // Fetch $r0 into T0
                     37:  * gen_load_T0_T0();     // Load T0, @T0
                     38:  * gen_movl_reg_T0(1);   // Writeback T0 into $r1
                     39:  *
                     40:  * The actual names for the micro-code generators vary but the example
                     41:  * illustrates the point.
                     42:  */
                     43: 
                     44: #include <stdarg.h>
                     45: #include <stdlib.h>
                     46: #include <stdio.h>
                     47: #include <string.h>
                     48: #include <inttypes.h>
                     49: #include <assert.h>
                     50: 
                     51: #include "cpu.h"
                     52: #include "exec-all.h"
                     53: #include "disas.h"
                     54: #include "crisv32-decode.h"
                     55: 
                     56: #define CRIS_STATS 0
                     57: #if CRIS_STATS
                     58: #define STATS(x) x
                     59: #else
                     60: #define STATS(x)
                     61: #endif
                     62: 
                     63: #define DISAS_CRIS 0
                     64: #if DISAS_CRIS
                     65: #define DIS(x) x
                     66: #else
                     67: #define DIS(x)
                     68: #endif
                     69: 
                     70: #ifdef USE_DIRECT_JUMP
                     71: #define TBPARAM(x)
                     72: #else
                     73: #define TBPARAM(x) (long)(x)
                     74: #endif
                     75: 
                     76: #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
                     77: #define BUG_ON(x) ({if (x) BUG();})
                     78: 
                     79: /* Used by the decoder.  */
                     80: #define EXTRACT_FIELD(src, start, end) \
                     81:             (((src) >> start) & ((1 << (end - start + 1)) - 1))
                     82: 
                     83: #define CC_MASK_NZ 0xc
                     84: #define CC_MASK_NZV 0xe
                     85: #define CC_MASK_NZVC 0xf
                     86: #define CC_MASK_RNZV 0x10e
                     87: 
                     88: static uint16_t *gen_opc_ptr;
                     89: static uint32_t *gen_opparam_ptr;
                     90: 
                     91: enum {
                     92: #define DEF(s, n, copy_size) INDEX_op_ ## s,
                     93: #include "opc.h"
                     94: #undef DEF
                     95:     NB_OPS,
                     96: };
                     97: #include "gen-op.h"
                     98: 
                     99: /* This is the state at translation time.  */
                    100: typedef struct DisasContext {
                    101:        CPUState *env;
                    102:        target_ulong pc, insn_pc;
                    103: 
                    104:        /* Decoder.  */
                    105:        uint32_t ir;
                    106:        uint32_t opcode;
                    107:        unsigned int op1;
                    108:        unsigned int op2;
                    109:        unsigned int zsize, zzsize;
                    110:        unsigned int mode;
                    111:        unsigned int postinc;
                    112: 
                    113: 
                    114:        struct
                    115:        {
                    116:                int op;
                    117:                int size;
                    118:                unsigned int mask;
                    119:        } cc_state[3];
                    120:        int cc_i;
                    121: 
                    122:        int update_cc;
                    123:        int cc_op;
                    124:        int cc_size;
                    125:        uint32_t cc_mask;
                    126:        int flags_live;
                    127:        int flagx_live;
                    128:        int flags_x;
                    129:        uint32_t tb_entry_flags;
                    130: 
                    131:        int memidx; /* user or kernel mode.  */
                    132:        int is_jmp;
                    133:        int dyn_jmp;
                    134: 
                    135:        uint32_t delayed_pc;
                    136:        int delayed_branch;
                    137:        int bcc;
                    138:        uint32_t condlabel;
                    139: 
                    140:        struct TranslationBlock *tb;
                    141:        int singlestep_enabled;
                    142: } DisasContext;
                    143: 
                    144: void cris_prepare_jmp (DisasContext *dc, uint32_t dst);
                    145: static void gen_BUG(DisasContext *dc, char *file, int line)
                    146: {
                    147:        printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
                    148:        fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
                    149:        cpu_dump_state (dc->env, stdout, fprintf, 0);
                    150:        fflush(NULL);
                    151:        cris_prepare_jmp (dc, 0x70000000 + line);
                    152: }
                    153: 
                    154: /* Table to generate quick moves from T0 onto any register.  */
                    155: static GenOpFunc *gen_movl_reg_T0[16] =
                    156: {
                    157:        gen_op_movl_r0_T0, gen_op_movl_r1_T0,
                    158:        gen_op_movl_r2_T0, gen_op_movl_r3_T0,
                    159:        gen_op_movl_r4_T0, gen_op_movl_r5_T0,
                    160:        gen_op_movl_r6_T0, gen_op_movl_r7_T0,
                    161:        gen_op_movl_r8_T0, gen_op_movl_r9_T0,
                    162:        gen_op_movl_r10_T0, gen_op_movl_r11_T0,
                    163:        gen_op_movl_r12_T0, gen_op_movl_r13_T0,
                    164:        gen_op_movl_r14_T0, gen_op_movl_r15_T0,
                    165: };
                    166: static GenOpFunc *gen_movl_T0_reg[16] =
                    167: {
                    168:        gen_op_movl_T0_r0, gen_op_movl_T0_r1,
                    169:        gen_op_movl_T0_r2, gen_op_movl_T0_r3,
                    170:        gen_op_movl_T0_r4, gen_op_movl_T0_r5,
                    171:        gen_op_movl_T0_r6, gen_op_movl_T0_r7,
                    172:        gen_op_movl_T0_r8, gen_op_movl_T0_r9,
                    173:        gen_op_movl_T0_r10, gen_op_movl_T0_r11,
                    174:        gen_op_movl_T0_r12, gen_op_movl_T0_r13,
                    175:        gen_op_movl_T0_r14, gen_op_movl_T0_r15,
                    176: };
                    177: 
                    178: static void noop_write(void) {
                    179:        /* nop.  */
                    180: }
                    181: 
                    182: static void gen_vr_read(void) {
                    183:        gen_op_movl_T0_im(32);
                    184: }
                    185: 
                    186: static void gen_ccs_read(void) {
                    187:        gen_op_movl_T0_p13();
                    188: }
                    189: 
                    190: static void gen_ccs_write(void) {
                    191:        gen_op_movl_p13_T0();
                    192: }
                    193: 
                    194: /* Table to generate quick moves from T0 onto any register.  */
                    195: static GenOpFunc *gen_movl_preg_T0[16] =
                    196: {
                    197:        noop_write,  /* bz, not writeable.  */
                    198:        noop_write,  /* vr, not writeable.  */
                    199:        gen_op_movl_p2_T0, gen_op_movl_p3_T0,
                    200:        noop_write,  /* wz, not writeable.  */
                    201:        gen_op_movl_p5_T0,
                    202:        gen_op_movl_p6_T0, gen_op_movl_p7_T0,
                    203:        noop_write,  /* dz, not writeable.  */
                    204:        gen_op_movl_p9_T0,
                    205:        gen_op_movl_p10_T0, gen_op_movl_p11_T0,
                    206:        gen_op_movl_p12_T0,
                    207:        gen_ccs_write, /* ccs needs special treatment.  */
                    208:        gen_op_movl_p14_T0, gen_op_movl_p15_T0,
                    209: };
                    210: static GenOpFunc *gen_movl_T0_preg[16] =
                    211: {
                    212:        gen_op_movl_T0_p0,
                    213:        gen_vr_read,
                    214:        gen_op_movl_T0_p2, gen_op_movl_T0_p3,
                    215:        gen_op_movl_T0_p4, gen_op_movl_T0_p5,
                    216:        gen_op_movl_T0_p6, gen_op_movl_T0_p7,
                    217:        gen_op_movl_T0_p8, gen_op_movl_T0_p9,
                    218:        gen_op_movl_T0_p10, gen_op_movl_T0_p11,
                    219:        gen_op_movl_T0_p12,
                    220:        gen_ccs_read, /* ccs needs special treatment.  */
                    221:        gen_op_movl_T0_p14, gen_op_movl_T0_p15,
                    222: };
                    223: 
                    224: /* We need this table to handle moves with implicit width.  */
                    225: int preg_sizes[] = {
                    226:        1, /* bz.  */
                    227:        1, /* vr.  */
                    228:        4, /* pid.  */
                    229:        1, /* srs.  */
                    230:        2, /* wz.  */
                    231:        4, 4, 4,
                    232:        4, 4, 4, 4,
                    233:        4, 4, 4, 4,
                    234: };
                    235: 
                    236: #ifdef CONFIG_USER_ONLY
                    237: #define GEN_OP_LD(width, reg) \
                    238:   void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
                    239:     gen_op_ld##width##_T0_##reg##_raw(); \
                    240:   }
                    241: #define GEN_OP_ST(width, reg) \
                    242:   void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
                    243:     gen_op_st##width##_##reg##_T1_raw(); \
                    244:   }
                    245: #else
                    246: #define GEN_OP_LD(width, reg) \
                    247:   void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \
                    248:     if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
                    249:     else gen_op_ld##width##_T0_##reg##_user();\
                    250:   }
                    251: #define GEN_OP_ST(width, reg) \
                    252:   void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \
                    253:     if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
                    254:     else gen_op_st##width##_##reg##_T1_user();\
                    255:   }
                    256: #endif
                    257: 
                    258: GEN_OP_LD(ub, T0)
                    259: GEN_OP_LD(b, T0)
                    260: GEN_OP_ST(b, T0)
                    261: GEN_OP_LD(uw, T0)
                    262: GEN_OP_LD(w, T0)
                    263: GEN_OP_ST(w, T0)
                    264: GEN_OP_LD(l, T0)
                    265: GEN_OP_ST(l, T0)
                    266: 
                    267: static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
                    268: {
                    269:        TranslationBlock *tb;
                    270:        tb = dc->tb;
                    271:        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
                    272:                if (n == 0)
                    273:                        gen_op_goto_tb0(TBPARAM(tb));
                    274:                else
                    275:                        gen_op_goto_tb1(TBPARAM(tb));
                    276:                gen_op_movl_T0_0();
                    277:        } else {
                    278:                gen_op_movl_T0_0();
                    279:        }
                    280:        gen_op_exit_tb();
                    281: }
                    282: 
                    283: /* Sign extend at translation time.  */
                    284: static int sign_extend(unsigned int val, unsigned int width)
                    285: {
                    286:        int sval;
                    287: 
                    288:        /* LSL.  */
                    289:        val <<= 31 - width;
                    290:        sval = val;
                    291:        /* ASR.  */
                    292:        sval >>= 31 - width;
                    293:        return sval;
                    294: }
                    295: 
                    296: static void cris_evaluate_flags(DisasContext *dc)
                    297: {
                    298:        if (!dc->flags_live) {
                    299: 
                    300:                switch (dc->cc_op)
                    301:                {
                    302:                        case CC_OP_MCP:
                    303:                                gen_op_evaluate_flags_mcp ();
                    304:                                break;
                    305:                        case CC_OP_MULS:
                    306:                                gen_op_evaluate_flags_muls ();
                    307:                                break;
                    308:                        case CC_OP_MULU:
                    309:                                gen_op_evaluate_flags_mulu ();
                    310:                                break;
                    311:                        case CC_OP_MOVE:
                    312:                                switch (dc->cc_size)
                    313:                                {
                    314:                                        case 4:
                    315:                                                gen_op_evaluate_flags_move_4();
                    316:                                                break;
                    317:                                        case 2:
                    318:                                                gen_op_evaluate_flags_move_2();
                    319:                                                break;
                    320:                                        default:
                    321:                                                gen_op_evaluate_flags ();
                    322:                                                break;
                    323:                                }
                    324:                                break;
                    325: 
                    326:                        default:
                    327:                        {
                    328:                                switch (dc->cc_size)
                    329:                                {
                    330:                                        case 4:
                    331:                                                gen_op_evaluate_flags_alu_4 ();
                    332:                                                break;
                    333:                                        default:
                    334:                                                gen_op_evaluate_flags ();
                    335:                                                break;
                    336:                                }
                    337:                        }
                    338:                        break;
                    339:                }
                    340:                dc->flags_live = 1;
                    341:        }
                    342: }
                    343: 
                    344: static void cris_cc_mask(DisasContext *dc, unsigned int mask)
                    345: {
                    346:        uint32_t ovl;
                    347: 
                    348:        ovl = (dc->cc_mask ^ mask) & ~mask;
                    349:        if (ovl) {
                    350:                /* TODO: optimize this case. It trigs all the time.  */
                    351:                cris_evaluate_flags (dc);
                    352:        }
                    353:        dc->cc_mask = mask;
                    354: 
                    355:        dc->update_cc = 1;
                    356:        if (mask == 0)
                    357:                dc->update_cc = 0;
                    358:        else {
                    359:                gen_op_update_cc_mask(mask);
                    360:                dc->flags_live = 0;
                    361:        }
                    362: }
                    363: 
                    364: static void cris_update_cc_op(DisasContext *dc, int op)
                    365: {
                    366:        dc->cc_op = op;
                    367:        gen_op_update_cc_op(op);
                    368:        dc->flags_live = 0;
                    369: }
                    370: static void cris_update_cc_size(DisasContext *dc, int size)
                    371: {
                    372:        dc->cc_size = size;
                    373:        gen_op_update_cc_size_im(size);
                    374: }
                    375: 
                    376: /* op is the operation.
                    377:    T0, T1 are the operands.
                    378:    dst is the destination reg.
                    379: */
                    380: static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
                    381: {
                    382:        int writeback = 1;
                    383:        if (dc->update_cc) {
                    384:                cris_update_cc_op(dc, op);
                    385:                cris_update_cc_size(dc, size);
                    386:                gen_op_update_cc_x(dc->flagx_live, dc->flags_x);
                    387:                gen_op_update_cc_dest_T0();
                    388:        }
                    389: 
                    390:        /* Emit the ALU insns.  */
                    391:        switch (op)
                    392:        {
                    393:                case CC_OP_ADD:
                    394:                        gen_op_addl_T0_T1();
                    395:                        /* Extended arithmetics.  */
                    396:                        if (!dc->flagx_live)
                    397:                                gen_op_addxl_T0_C();
                    398:                        else if (dc->flags_x)
                    399:                                gen_op_addxl_T0_C();
                    400:                        break;
                    401:                case CC_OP_ADDC:
                    402:                        gen_op_addl_T0_T1();
                    403:                        gen_op_addl_T0_C();
                    404:                        break;
                    405:                case CC_OP_MCP:
                    406:                        gen_op_addl_T0_T1();
                    407:                        gen_op_addl_T0_R();
                    408:                        break;
                    409:                case CC_OP_SUB:
                    410:                        gen_op_negl_T1_T1();
                    411:                        gen_op_addl_T0_T1();
                    412:                        /* CRIS flag evaluation needs ~src.  */
                    413:                        gen_op_negl_T1_T1();
                    414:                        gen_op_not_T1_T1();
                    415: 
                    416:                        /* Extended arithmetics.  */
                    417:                        if (!dc->flagx_live)
                    418:                                gen_op_subxl_T0_C();
                    419:                        else if (dc->flags_x)
                    420:                                gen_op_subxl_T0_C();
                    421:                        break;
                    422:                case CC_OP_MOVE:
                    423:                        gen_op_movl_T0_T1();
                    424:                        break;
                    425:                case CC_OP_OR:
                    426:                        gen_op_orl_T0_T1();
                    427:                        break;
                    428:                case CC_OP_AND:
                    429:                        gen_op_andl_T0_T1();
                    430:                        break;
                    431:                case CC_OP_XOR:
                    432:                        gen_op_xorl_T0_T1();
                    433:                        break;
                    434:                case CC_OP_LSL:
                    435:                        gen_op_lsll_T0_T1();
                    436:                        break;
                    437:                case CC_OP_LSR:
                    438:                        gen_op_lsrl_T0_T1();
                    439:                        break;
                    440:                case CC_OP_ASR:
                    441:                        gen_op_asrl_T0_T1();
                    442:                        break;
                    443:                case CC_OP_NEG:
                    444:                        gen_op_negl_T0_T1();
                    445:                        /* Extended arithmetics.  */
                    446:                        gen_op_subxl_T0_C();
                    447:                        break;
                    448:                case CC_OP_LZ:
                    449:                        gen_op_lz_T0_T1();
                    450:                        break;
                    451:                case CC_OP_BTST:
                    452:                        gen_op_btst_T0_T1();
                    453:                        writeback = 0;
                    454:                        break;
                    455:                case CC_OP_MULS:
                    456:                        gen_op_muls_T0_T1();
                    457:                        break;
                    458:                case CC_OP_MULU:
                    459:                        gen_op_mulu_T0_T1();
                    460:                        break;
                    461:                case CC_OP_DSTEP:
                    462:                        gen_op_dstep_T0_T1();
                    463:                        break;
                    464:                case CC_OP_BOUND:
                    465:                        gen_op_bound_T0_T1();
                    466:                        break;
                    467:                case CC_OP_CMP:
                    468:                        gen_op_negl_T1_T1();
                    469:                        gen_op_addl_T0_T1();
                    470:                        /* CRIS flag evaluation needs ~src.  */
                    471:                        gen_op_negl_T1_T1();
                    472:                        gen_op_not_T1_T1();
                    473: 
                    474:                        /* Extended arithmetics.  */
                    475:                        gen_op_subxl_T0_C();
                    476:                        writeback = 0;
                    477:                        break;
                    478:                default:
                    479:                        fprintf (logfile, "illegal ALU op.\n");
                    480:                        BUG();
                    481:                        break;
                    482:        }
                    483: 
                    484:        if (dc->update_cc)
                    485:                gen_op_update_cc_src_T1();
                    486: 
                    487:        if (size == 1)
                    488:                gen_op_andl_T0_im(0xff);
                    489:        else if (size == 2)
                    490:                gen_op_andl_T0_im(0xffff);
                    491:        /* Writeback.  */
                    492:        if (writeback) {
                    493:                if (size == 4)
                    494:                        gen_movl_reg_T0[rd]();
                    495:                else {
                    496:                        gen_op_movl_T1_T0();
                    497:                        gen_movl_T0_reg[rd]();
                    498:                        if (size == 1)
                    499:                                gen_op_andl_T0_im(~0xff);
                    500:                        else
                    501:                                gen_op_andl_T0_im(~0xffff);
                    502:                        gen_op_orl_T0_T1();
                    503:                        gen_movl_reg_T0[rd]();
                    504:                        gen_op_movl_T0_T1();
                    505:                }
                    506:        }
                    507:        if (dc->update_cc)
                    508:                gen_op_update_cc_result_T0();
                    509: 
                    510:        {
                    511:                /* TODO: Optimize this.  */
                    512:                if (!dc->flagx_live)
                    513:                        cris_evaluate_flags(dc);
                    514:        }
                    515: }
                    516: 
                    517: static int arith_cc(DisasContext *dc)
                    518: {
                    519:        if (dc->update_cc) {
                    520:                switch (dc->cc_op) {
                    521:                        case CC_OP_ADD: return 1;
                    522:                        case CC_OP_SUB: return 1;
                    523:                        case CC_OP_LSL: return 1;
                    524:                        case CC_OP_LSR: return 1;
                    525:                        case CC_OP_ASR: return 1;
                    526:                        case CC_OP_CMP: return 1;
                    527:                        default:
                    528:                                return 0;
                    529:                }
                    530:        }
                    531:        return 0;
                    532: }
                    533: 
                    534: static void gen_tst_cc (DisasContext *dc, int cond)
                    535: {
                    536:        int arith_opt;
                    537: 
                    538:        /* TODO: optimize more condition codes.  */
                    539:        arith_opt = arith_cc(dc) && !dc->flags_live;
                    540:        switch (cond) {
                    541:                case CC_EQ:
                    542:                        if (arith_opt)
                    543:                                gen_op_tst_cc_eq_fast ();
                    544:                        else {
                    545:                                cris_evaluate_flags(dc);
                    546:                                gen_op_tst_cc_eq ();
                    547:                        }
                    548:                        break;
                    549:                case CC_NE:
                    550:                        if (arith_opt)
                    551:                                gen_op_tst_cc_ne_fast ();
                    552:                        else {
                    553:                                cris_evaluate_flags(dc);
                    554:                                gen_op_tst_cc_ne ();
                    555:                        }
                    556:                        break;
                    557:                case CC_CS:
                    558:                        cris_evaluate_flags(dc);
                    559:                        gen_op_tst_cc_cs ();
                    560:                        break;
                    561:                case CC_CC:
                    562:                        cris_evaluate_flags(dc);
                    563:                        gen_op_tst_cc_cc ();
                    564:                        break;
                    565:                case CC_VS:
                    566:                        cris_evaluate_flags(dc);
                    567:                        gen_op_tst_cc_vs ();
                    568:                        break;
                    569:                case CC_VC:
                    570:                        cris_evaluate_flags(dc);
                    571:                        gen_op_tst_cc_vc ();
                    572:                        break;
                    573:                case CC_PL:
                    574:                        if (arith_opt)
                    575:                                gen_op_tst_cc_pl_fast ();
                    576:                        else {
                    577:                                cris_evaluate_flags(dc);
                    578:                                gen_op_tst_cc_pl ();
                    579:                        }
                    580:                        break;
                    581:                case CC_MI:
                    582:                        if (arith_opt)
                    583:                                gen_op_tst_cc_mi_fast ();
                    584:                        else {
                    585:                                cris_evaluate_flags(dc);
                    586:                                gen_op_tst_cc_mi ();
                    587:                        }
                    588:                        break;
                    589:                case CC_LS:
                    590:                        cris_evaluate_flags(dc);
                    591:                        gen_op_tst_cc_ls ();
                    592:                        break;
                    593:                case CC_HI:
                    594:                        cris_evaluate_flags(dc);
                    595:                        gen_op_tst_cc_hi ();
                    596:                        break;
                    597:                case CC_GE:
                    598:                        cris_evaluate_flags(dc);
                    599:                        gen_op_tst_cc_ge ();
                    600:                        break;
                    601:                case CC_LT:
                    602:                        cris_evaluate_flags(dc);
                    603:                        gen_op_tst_cc_lt ();
                    604:                        break;
                    605:                case CC_GT:
                    606:                        cris_evaluate_flags(dc);
                    607:                        gen_op_tst_cc_gt ();
                    608:                        break;
                    609:                case CC_LE:
                    610:                        cris_evaluate_flags(dc);
                    611:                        gen_op_tst_cc_le ();
                    612:                        break;
                    613:                case CC_P:
                    614:                        cris_evaluate_flags(dc);
                    615:                        gen_op_tst_cc_p ();
                    616:                        break;
                    617:                case CC_A:
                    618:                        cris_evaluate_flags(dc);
                    619:                        gen_op_movl_T0_im (1);
                    620:                        break;
                    621:                default:
                    622:                        BUG();
                    623:                        break;
                    624:        };
                    625: }
                    626: 
                    627: static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
                    628: {
                    629:        /* This helps us re-schedule the micro-code to insns in delay-slots
                    630:           before the actual jump.  */
                    631:        dc->delayed_branch = 2;
                    632:        dc->delayed_pc = dc->pc + offset;
                    633:        dc->bcc = cond;
                    634:        if (cond != CC_A)
                    635:        {
                    636:                gen_tst_cc (dc, cond);
                    637:                gen_op_evaluate_bcc ();
                    638:        }
                    639:        gen_op_movl_T0_im (dc->delayed_pc);
                    640:        gen_op_movl_btarget_T0 ();
                    641: }
                    642: 
                    643: /* Dynamic jumps, when the dest is in a live reg for example.  */
                    644: void cris_prepare_dyn_jmp (DisasContext *dc)
                    645: {
                    646:        /* This helps us re-schedule the micro-code to insns in delay-slots
                    647:           before the actual jump.  */
                    648:        dc->delayed_branch = 2;
                    649:        dc->dyn_jmp = 1;
                    650:        dc->bcc = CC_A;
                    651: }
                    652: 
                    653: void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
                    654: {
                    655:        /* This helps us re-schedule the micro-code to insns in delay-slots
                    656:           before the actual jump.  */
                    657:        dc->delayed_branch = 2;
                    658:        dc->delayed_pc = dst;
                    659:        dc->dyn_jmp = 0;
                    660:        dc->bcc = CC_A;
                    661: }
                    662: 
                    663: void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign)
                    664: {
                    665:        if (size == 1) {
                    666:                if (sign)
                    667:                        gen_op_ldb_T0_T0(dc);
                    668:                else
                    669:                        gen_op_ldub_T0_T0(dc);
                    670:        }
                    671:        else if (size == 2) {
                    672:                if (sign)
                    673:                        gen_op_ldw_T0_T0(dc);
                    674:                else
                    675:                        gen_op_lduw_T0_T0(dc);
                    676:        }
                    677:        else {
                    678:                gen_op_ldl_T0_T0(dc);
                    679:        }
                    680: }
                    681: 
                    682: void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
                    683: {
                    684:        /* Remember, operands are flipped. CRIS has reversed order.  */
                    685:        if (size == 1) {
                    686:                gen_op_stb_T0_T1(dc);
                    687:        }
                    688:        else if (size == 2) {
                    689:                gen_op_stw_T0_T1(dc);
                    690:        }
                    691:        else
                    692:                gen_op_stl_T0_T1(dc);
                    693: }
                    694: 
                    695: /* sign extend T1 according to size.  */
                    696: static void gen_sext_T1_T0(int size)
                    697: {
                    698:        if (size == 1)
                    699:                gen_op_extb_T1_T0();
                    700:        else if (size == 2)
                    701:                gen_op_extw_T1_T0();
                    702: }
                    703: 
                    704: static void gen_sext_T1_T1(int size)
                    705: {
                    706:        if (size == 1)
                    707:                gen_op_extb_T1_T1();
                    708:        else if (size == 2)
                    709:                gen_op_extw_T1_T1();
                    710: }
                    711: 
                    712: static void gen_sext_T0_T0(int size)
                    713: {
                    714:        if (size == 1)
                    715:                gen_op_extb_T0_T0();
                    716:        else if (size == 2)
                    717:                gen_op_extw_T0_T0();
                    718: }
                    719: 
                    720: static void gen_zext_T0_T0(int size)
                    721: {
                    722:        if (size == 1)
                    723:                gen_op_zextb_T0_T0();
                    724:        else if (size == 2)
                    725:                gen_op_zextw_T0_T0();
                    726: }
                    727: 
                    728: static void gen_zext_T1_T0(int size)
                    729: {
                    730:        if (size == 1)
                    731:                gen_op_zextb_T1_T0();
                    732:        else if (size == 2)
                    733:                gen_op_zextw_T1_T0();
                    734: }
                    735: 
                    736: static void gen_zext_T1_T1(int size)
                    737: {
                    738:        if (size == 1)
                    739:                gen_op_zextb_T1_T1();
                    740:        else if (size == 2)
                    741:                gen_op_zextw_T1_T1();
                    742: }
                    743: 
                    744: #if DISAS_CRIS
                    745: static char memsize_char(int size)
                    746: {
                    747:        switch (size)
                    748:        {
                    749:                case 1: return 'b';  break;
                    750:                case 2: return 'w';  break;
                    751:                case 4: return 'd';  break;
                    752:                default:
                    753:                        return 'x';
                    754:                        break;
                    755:        }
                    756: }
                    757: #endif
                    758: 
                    759: static unsigned int memsize_z(DisasContext *dc)
                    760: {
                    761:        return dc->zsize + 1;
                    762: }
                    763: 
                    764: static unsigned int memsize_zz(DisasContext *dc)
                    765: {
                    766:        switch (dc->zzsize)
                    767:        {
                    768:                case 0: return 1;
                    769:                case 1: return 2;
                    770:                default:
                    771:                        return 4;
                    772:        }
                    773: }
                    774: 
                    775: static void do_postinc (DisasContext *dc, int size)
                    776: {
                    777:        if (!dc->postinc)
                    778:                return;
                    779:        gen_movl_T0_reg[dc->op1]();
                    780:        gen_op_addl_T0_im(size);
                    781:        gen_movl_reg_T0[dc->op1]();
                    782: }
                    783: 
                    784: 
                    785: static void dec_prep_move_r(DisasContext *dc, int rs, int rd,
                    786:                            int size, int s_ext)
                    787: {
                    788:        gen_movl_T0_reg[rs]();
                    789:        gen_op_movl_T1_T0();
                    790:        if (s_ext)
                    791:                gen_sext_T1_T1(size);
                    792:        else
                    793:                gen_zext_T1_T1(size);
                    794: }
                    795: 
                    796: /* Prepare T0 and T1 for a register alu operation.
                    797:    s_ext decides if the operand1 should be sign-extended or zero-extended when
                    798:    needed.  */
                    799: static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
                    800:                          int size, int s_ext)
                    801: {
                    802:        dec_prep_move_r(dc, rs, rd, size, s_ext);
                    803: 
                    804:        gen_movl_T0_reg[rd]();
                    805:        if (s_ext)
                    806:                gen_sext_T0_T0(size);
                    807:        else
                    808:                gen_zext_T0_T0(size);
                    809: }
                    810: 
                    811: /* Prepare T0 and T1 for a memory + alu operation.
                    812:    s_ext decides if the operand1 should be sign-extended or zero-extended when
                    813:    needed.  */
                    814: static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
                    815: {
                    816:        unsigned int rs, rd;
                    817:        uint32_t imm;
                    818:        int is_imm;
                    819:        int insn_len = 2;
                    820: 
                    821:        rs = dc->op1;
                    822:        rd = dc->op2;
                    823:        is_imm = rs == 15 && dc->postinc;
                    824: 
                    825:        /* Load [$rs] onto T1.  */
                    826:        if (is_imm) {
                    827:                insn_len = 2 + memsize;
                    828:                if (memsize == 1)
                    829:                        insn_len++;
                    830: 
                    831:                imm = ldl_code(dc->pc + 2);
                    832:                if (memsize != 4) {
                    833:                        if (s_ext) {
                    834:                                imm = sign_extend(imm, (memsize * 8) - 1);
                    835:                        } else {
                    836:                                if (memsize == 1)
                    837:                                        imm &= 0xff;
                    838:                                else
                    839:                                        imm &= 0xffff;
                    840:                        }
                    841:                }
                    842:                DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
                    843:                            imm, rd, s_ext, memsize));
                    844:                gen_op_movl_T1_im (imm);
                    845:                dc->postinc = 0;
                    846:        } else {
                    847:                gen_movl_T0_reg[rs]();
                    848:                gen_load_T0_T0(dc, memsize, 0);
                    849:                gen_op_movl_T1_T0();
                    850:                if (s_ext)
                    851:                        gen_sext_T1_T1(memsize);
                    852:                else
                    853:                        gen_zext_T1_T1(memsize);
                    854:        }
                    855: 
                    856:        /* put dest in T0.  */
                    857:        gen_movl_T0_reg[rd]();
                    858:        return insn_len;
                    859: }
                    860: 
                    861: #if DISAS_CRIS
                    862: static const char *cc_name(int cc)
                    863: {
                    864:        static char *cc_names[16] = {
                    865:                "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
                    866:                "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
                    867:        };
                    868:        assert(cc < 16);
                    869:        return cc_names[cc];
                    870: }
                    871: #endif
                    872: 
                    873: static unsigned int dec_bccq(DisasContext *dc)
                    874: {
                    875:        int32_t offset;
                    876:        int sign;
                    877:        uint32_t cond = dc->op2;
                    878:        int tmp;
                    879: 
                    880:        offset = EXTRACT_FIELD (dc->ir, 1, 7);
                    881:        sign = EXTRACT_FIELD(dc->ir, 0, 0);
                    882: 
                    883:        offset *= 2;
                    884:        offset |= sign << 8;
                    885:        tmp = offset;
                    886:        offset = sign_extend(offset, 8);
                    887: 
                    888:        /* op2 holds the condition-code.  */
                    889:        cris_cc_mask(dc, 0);
                    890:        cris_prepare_cc_branch (dc, offset, cond);
                    891:        return 2;
                    892: }
                    893: static unsigned int dec_addoq(DisasContext *dc)
                    894: {
                    895:        uint32_t imm;
                    896: 
                    897:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
                    898:        imm = sign_extend(dc->op1, 7);
                    899: 
                    900:        DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
                    901:        cris_cc_mask(dc, 0);
                    902:        /* Fetch register operand,  */
                    903:        gen_movl_T0_reg[dc->op2]();
                    904:        gen_op_movl_T1_im(imm);
                    905:        crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
                    906:        return 2;
                    907: }
                    908: static unsigned int dec_addq(DisasContext *dc)
                    909: {
                    910:        DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2));
                    911: 
                    912:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    913: 
                    914:        cris_cc_mask(dc, CC_MASK_NZVC);
                    915:        /* Fetch register operand,  */
                    916:        gen_movl_T0_reg[dc->op2]();
                    917:        gen_op_movl_T1_im(dc->op1);
                    918:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
                    919:        return 2;
                    920: }
                    921: static unsigned int dec_moveq(DisasContext *dc)
                    922: {
                    923:        uint32_t imm;
                    924: 
                    925:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    926:        imm = sign_extend(dc->op1, 5);
                    927:        DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2));
                    928: 
                    929:        cris_cc_mask(dc, 0);
                    930:        gen_op_movl_T1_im(imm);
                    931:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                    932: 
                    933:        return 2;
                    934: }
                    935: static unsigned int dec_subq(DisasContext *dc)
                    936: {
                    937:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    938: 
                    939:        DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2));
                    940: 
                    941:        cris_cc_mask(dc, CC_MASK_NZVC);
                    942:        /* Fetch register operand,  */
                    943:        gen_movl_T0_reg[dc->op2]();
                    944:        gen_op_movl_T1_im(dc->op1);
                    945:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
                    946:        return 2;
                    947: }
                    948: static unsigned int dec_cmpq(DisasContext *dc)
                    949: {
                    950:        uint32_t imm;
                    951:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    952:        imm = sign_extend(dc->op1, 5);
                    953: 
                    954:        DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2));
                    955:        cris_cc_mask(dc, CC_MASK_NZVC);
                    956:        gen_movl_T0_reg[dc->op2]();
                    957:        gen_op_movl_T1_im(imm);
                    958:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
                    959:        return 2;
                    960: }
                    961: static unsigned int dec_andq(DisasContext *dc)
                    962: {
                    963:        uint32_t imm;
                    964:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    965:        imm = sign_extend(dc->op1, 5);
                    966: 
                    967:        DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2));
                    968:        cris_cc_mask(dc, CC_MASK_NZ);
                    969:        gen_movl_T0_reg[dc->op2]();
                    970:        gen_op_movl_T1_im(imm);
                    971:        crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4);
                    972:        return 2;
                    973: }
                    974: static unsigned int dec_orq(DisasContext *dc)
                    975: {
                    976:        uint32_t imm;
                    977:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
                    978:        imm = sign_extend(dc->op1, 5);
                    979:        DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2));
                    980:        cris_cc_mask(dc, CC_MASK_NZ);
                    981:        gen_movl_T0_reg[dc->op2]();
                    982:        gen_op_movl_T1_im(imm);
                    983:        crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4);
                    984:        return 2;
                    985: }
                    986: static unsigned int dec_btstq(DisasContext *dc)
                    987: {
                    988:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
                    989:        DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
                    990:        cris_evaluate_flags(dc);
                    991:        cris_cc_mask(dc, CC_MASK_NZ);
                    992:        gen_movl_T0_reg[dc->op2]();
                    993:        gen_op_movl_T1_im(dc->op1);
                    994:        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
                    995: 
                    996:        cris_update_cc_op(dc, CC_OP_FLAGS);
                    997:        gen_op_movl_flags_T0();
                    998:        dc->flags_live = 1;
                    999:        return 2;
                   1000: }
                   1001: static unsigned int dec_asrq(DisasContext *dc)
                   1002: {
                   1003:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
                   1004:        DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2));
                   1005:        cris_cc_mask(dc, CC_MASK_NZ);
                   1006:        gen_movl_T0_reg[dc->op2]();
                   1007:        gen_op_movl_T1_im(dc->op1);
                   1008:        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4);
                   1009:        return 2;
                   1010: }
                   1011: static unsigned int dec_lslq(DisasContext *dc)
                   1012: {
                   1013:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
                   1014:        DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2));
                   1015: 
                   1016:        cris_cc_mask(dc, CC_MASK_NZ);
                   1017:        gen_movl_T0_reg[dc->op2]();
                   1018:        gen_op_movl_T1_im(dc->op1);
                   1019:        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4);
                   1020:        return 2;
                   1021: }
                   1022: static unsigned int dec_lsrq(DisasContext *dc)
                   1023: {
                   1024:        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
                   1025:        DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2));
                   1026: 
                   1027:        cris_cc_mask(dc, CC_MASK_NZ);
                   1028:        gen_movl_T0_reg[dc->op2]();
                   1029:        gen_op_movl_T1_im(dc->op1);
                   1030:        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4);
                   1031:        return 2;
                   1032: }
                   1033: 
                   1034: static unsigned int dec_move_r(DisasContext *dc)
                   1035: {
                   1036:        int size = memsize_zz(dc);
                   1037: 
                   1038:        DIS(fprintf (logfile, "move.%c $r%u, $r%u\n",
                   1039:                    memsize_char(size), dc->op1, dc->op2));
                   1040: 
                   1041:        cris_cc_mask(dc, CC_MASK_NZ);
                   1042:        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
                   1043:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size);
                   1044:        return 2;
                   1045: }
                   1046: 
                   1047: static unsigned int dec_scc_r(DisasContext *dc)
                   1048: {
                   1049:        int cond = dc->op2;
                   1050: 
                   1051:        DIS(fprintf (logfile, "s%s $r%u\n",
                   1052:                    cc_name(cond), dc->op1));
                   1053: 
                   1054:        if (cond != CC_A)
                   1055:        {
                   1056:                gen_tst_cc (dc, cond);
                   1057:                gen_op_movl_T1_T0();
                   1058:        }
                   1059:        else
                   1060:                gen_op_movl_T1_im(1);
                   1061: 
                   1062:        cris_cc_mask(dc, 0);
                   1063:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
                   1064:        return 2;
                   1065: }
                   1066: 
                   1067: static unsigned int dec_and_r(DisasContext *dc)
                   1068: {
                   1069:        int size = memsize_zz(dc);
                   1070: 
                   1071:        DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
                   1072:                    memsize_char(size), dc->op1, dc->op2));
                   1073:        cris_cc_mask(dc, CC_MASK_NZ);
                   1074:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1075:        crisv32_alu_op(dc, CC_OP_AND, dc->op2, size);
                   1076:        return 2;
                   1077: }
                   1078: 
                   1079: static unsigned int dec_lz_r(DisasContext *dc)
                   1080: {
                   1081:        DIS(fprintf (logfile, "lz $r%u, $r%u\n",
                   1082:                    dc->op1, dc->op2));
                   1083:        cris_cc_mask(dc, CC_MASK_NZ);
                   1084:        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
                   1085:        crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4);
                   1086:        return 2;
                   1087: }
                   1088: 
                   1089: static unsigned int dec_lsl_r(DisasContext *dc)
                   1090: {
                   1091:        int size = memsize_zz(dc);
                   1092: 
                   1093:        DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
                   1094:                    memsize_char(size), dc->op1, dc->op2));
                   1095:        cris_cc_mask(dc, CC_MASK_NZ);
                   1096:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1097:        gen_op_andl_T1_im(63);
                   1098:        crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size);
                   1099:        return 2;
                   1100: }
                   1101: 
                   1102: static unsigned int dec_lsr_r(DisasContext *dc)
                   1103: {
                   1104:        int size = memsize_zz(dc);
                   1105: 
                   1106:        DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
                   1107:                    memsize_char(size), dc->op1, dc->op2));
                   1108:        cris_cc_mask(dc, CC_MASK_NZ);
                   1109:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1110:        gen_op_andl_T1_im(63);
                   1111:        crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size);
                   1112:        return 2;
                   1113: }
                   1114: 
                   1115: static unsigned int dec_asr_r(DisasContext *dc)
                   1116: {
                   1117:        int size = memsize_zz(dc);
                   1118: 
                   1119:        DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
                   1120:                    memsize_char(size), dc->op1, dc->op2));
                   1121:        cris_cc_mask(dc, CC_MASK_NZ);
                   1122:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
                   1123:        gen_op_andl_T1_im(63);
                   1124:        crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size);
                   1125:        return 2;
                   1126: }
                   1127: 
                   1128: static unsigned int dec_muls_r(DisasContext *dc)
                   1129: {
                   1130:        int size = memsize_zz(dc);
                   1131: 
                   1132:        DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
                   1133:                    memsize_char(size), dc->op1, dc->op2));
                   1134:        cris_cc_mask(dc, CC_MASK_NZV);
                   1135:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
                   1136:        gen_sext_T0_T0(size);
                   1137:        crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4);
                   1138:        return 2;
                   1139: }
                   1140: 
                   1141: static unsigned int dec_mulu_r(DisasContext *dc)
                   1142: {
                   1143:        int size = memsize_zz(dc);
                   1144: 
                   1145:        DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
                   1146:                    memsize_char(size), dc->op1, dc->op2));
                   1147:        cris_cc_mask(dc, CC_MASK_NZV);
                   1148:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1149:        gen_zext_T0_T0(size);
                   1150:        crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4);
                   1151:        return 2;
                   1152: }
                   1153: 
                   1154: 
                   1155: static unsigned int dec_dstep_r(DisasContext *dc)
                   1156: {
                   1157:        DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2));
                   1158:        cris_cc_mask(dc, CC_MASK_NZ);
                   1159:        gen_movl_T0_reg[dc->op1]();
                   1160:        gen_op_movl_T1_T0();
                   1161:        gen_movl_T0_reg[dc->op2]();
                   1162:        crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4);
                   1163:        return 2;
                   1164: }
                   1165: 
                   1166: static unsigned int dec_xor_r(DisasContext *dc)
                   1167: {
                   1168:        int size = memsize_zz(dc);
                   1169:        DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
                   1170:                    memsize_char(size), dc->op1, dc->op2));
                   1171:        BUG_ON(size != 4); /* xor is dword.  */
                   1172:        cris_cc_mask(dc, CC_MASK_NZ);
                   1173:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1174:        crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4);
                   1175:        return 2;
                   1176: }
                   1177: 
                   1178: static unsigned int dec_bound_r(DisasContext *dc)
                   1179: {
                   1180:        int size = memsize_zz(dc);
                   1181:        DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
                   1182:                    memsize_char(size), dc->op1, dc->op2));
                   1183:        cris_cc_mask(dc, CC_MASK_NZ);
                   1184:        /* TODO: needs optmimization.  */
                   1185:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1186:        /* rd should be 4.  */
                   1187:        gen_movl_T0_reg[dc->op2]();
                   1188:        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
                   1189:        return 2;
                   1190: }
                   1191: 
                   1192: static unsigned int dec_cmp_r(DisasContext *dc)
                   1193: {
                   1194:        int size = memsize_zz(dc);
                   1195:        DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
                   1196:                    memsize_char(size), dc->op1, dc->op2));
                   1197:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1198:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1199:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size);
                   1200:        return 2;
                   1201: }
                   1202: 
                   1203: static unsigned int dec_abs_r(DisasContext *dc)
                   1204: {
                   1205:        DIS(fprintf (logfile, "abs $r%u, $r%u\n",
                   1206:                    dc->op1, dc->op2));
                   1207:        cris_cc_mask(dc, CC_MASK_NZ);
                   1208:        dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0);
                   1209:        gen_op_absl_T1_T1();
                   1210:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1211:        return 2;
                   1212: }
                   1213: 
                   1214: static unsigned int dec_add_r(DisasContext *dc)
                   1215: {
                   1216:        int size = memsize_zz(dc);
                   1217:        DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
                   1218:                    memsize_char(size), dc->op1, dc->op2));
                   1219:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1220:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1221:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size);
                   1222:        return 2;
                   1223: }
                   1224: 
                   1225: static unsigned int dec_addc_r(DisasContext *dc)
                   1226: {
                   1227:        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
                   1228:                    dc->op1, dc->op2));
                   1229:        cris_evaluate_flags(dc);
                   1230:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1231:        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
                   1232:        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
                   1233:        return 2;
                   1234: }
                   1235: 
                   1236: static unsigned int dec_mcp_r(DisasContext *dc)
                   1237: {
                   1238:        DIS(fprintf (logfile, "mcp $p%u, $r%u\n",
                   1239:                     dc->op2, dc->op1));
                   1240:        cris_evaluate_flags(dc);
                   1241:        cris_cc_mask(dc, CC_MASK_RNZV);
                   1242:        gen_movl_T0_preg[dc->op2]();
                   1243:        gen_op_movl_T1_T0();
                   1244:        gen_movl_T0_reg[dc->op1]();
                   1245:        crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4);
                   1246:        return 2;
                   1247: }
                   1248: 
                   1249: #if DISAS_CRIS
                   1250: static char * swapmode_name(int mode, char *modename) {
                   1251:        int i = 0;
                   1252:        if (mode & 8)
                   1253:                modename[i++] = 'n';
                   1254:        if (mode & 4)
                   1255:                modename[i++] = 'w';
                   1256:        if (mode & 2)
                   1257:                modename[i++] = 'b';
                   1258:        if (mode & 1)
                   1259:                modename[i++] = 'r';
                   1260:        modename[i++] = 0;
                   1261:        return modename;
                   1262: }
                   1263: #endif
                   1264: 
                   1265: static unsigned int dec_swap_r(DisasContext *dc)
                   1266: {
                   1267:        DIS(char modename[4]);
                   1268:        DIS(fprintf (logfile, "swap%s $r%u\n",
                   1269:                     swapmode_name(dc->op2, modename), dc->op1));
                   1270: 
                   1271:        cris_cc_mask(dc, CC_MASK_NZ);
                   1272:        gen_movl_T0_reg[dc->op1]();
                   1273:        if (dc->op2 & 8)
                   1274:                gen_op_not_T0_T0();
                   1275:        if (dc->op2 & 4)
                   1276:                gen_op_swapw_T0_T0();
                   1277:        if (dc->op2 & 2)
                   1278:                gen_op_swapb_T0_T0();
                   1279:        if (dc->op2 & 1)
                   1280:                gen_op_swapr_T0_T0();
                   1281:        gen_op_movl_T1_T0();
                   1282:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4);
                   1283:        return 2;
                   1284: }
                   1285: 
                   1286: static unsigned int dec_or_r(DisasContext *dc)
                   1287: {
                   1288:        int size = memsize_zz(dc);
                   1289:        DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
                   1290:                    memsize_char(size), dc->op1, dc->op2));
                   1291:        cris_cc_mask(dc, CC_MASK_NZ);
                   1292:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1293:        crisv32_alu_op(dc, CC_OP_OR, dc->op2, size);
                   1294:        return 2;
                   1295: }
                   1296: 
                   1297: static unsigned int dec_addi_r(DisasContext *dc)
                   1298: {
                   1299:        DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
                   1300:                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
                   1301:        cris_cc_mask(dc, 0);
                   1302:        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
                   1303:        gen_op_lsll_T0_im(dc->zzsize);
                   1304:        gen_op_addl_T0_T1();
                   1305:        gen_movl_reg_T0[dc->op1]();
                   1306:        return 2;
                   1307: }
                   1308: 
                   1309: static unsigned int dec_addi_acr(DisasContext *dc)
                   1310: {
                   1311:        DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
                   1312:                    memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
                   1313:        cris_cc_mask(dc, 0);
                   1314:        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
                   1315:        gen_op_lsll_T0_im(dc->zzsize);
                   1316:        gen_op_addl_T0_T1();
                   1317:        gen_movl_reg_T0[REG_ACR]();
                   1318:        return 2;
                   1319: }
                   1320: 
                   1321: static unsigned int dec_neg_r(DisasContext *dc)
                   1322: {
                   1323:        int size = memsize_zz(dc);
                   1324:        DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
                   1325:                    memsize_char(size), dc->op1, dc->op2));
                   1326:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1327:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1328:        crisv32_alu_op(dc, CC_OP_NEG, dc->op2, size);
                   1329:        return 2;
                   1330: }
                   1331: 
                   1332: static unsigned int dec_btst_r(DisasContext *dc)
                   1333: {
                   1334:        DIS(fprintf (logfile, "btst $r%u, $r%u\n",
                   1335:                    dc->op1, dc->op2));
                   1336:        cris_evaluate_flags(dc);
                   1337:        cris_cc_mask(dc, CC_MASK_NZ);
                   1338:        dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
                   1339:        crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
                   1340: 
                   1341:        cris_update_cc_op(dc, CC_OP_FLAGS);
                   1342:        gen_op_movl_flags_T0();
                   1343:        dc->flags_live = 1;
                   1344:        return 2;
                   1345: }
                   1346: 
                   1347: static unsigned int dec_sub_r(DisasContext *dc)
                   1348: {
                   1349:        int size = memsize_zz(dc);
                   1350:        DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
                   1351:                    memsize_char(size), dc->op1, dc->op2));
                   1352:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1353:        dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
                   1354:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, size);
                   1355:        return 2;
                   1356: }
                   1357: 
                   1358: /* Zero extension. From size to dword.  */
                   1359: static unsigned int dec_movu_r(DisasContext *dc)
                   1360: {
                   1361:        int size = memsize_z(dc);
                   1362:        DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
                   1363:                    memsize_char(size),
                   1364:                    dc->op1, dc->op2));
                   1365: 
                   1366:        cris_cc_mask(dc, CC_MASK_NZ);
                   1367:        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0);
                   1368:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1369:        return 2;
                   1370: }
                   1371: 
                   1372: /* Sign extension. From size to dword.  */
                   1373: static unsigned int dec_movs_r(DisasContext *dc)
                   1374: {
                   1375:        int size = memsize_z(dc);
                   1376:        DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
                   1377:                    memsize_char(size),
                   1378:                    dc->op1, dc->op2));
                   1379: 
                   1380:        cris_cc_mask(dc, CC_MASK_NZ);
                   1381:        gen_movl_T0_reg[dc->op1]();
                   1382:        /* Size can only be qi or hi.  */
                   1383:        gen_sext_T1_T0(size);
                   1384:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1385:        return 2;
                   1386: }
                   1387: 
                   1388: /* zero extension. From size to dword.  */
                   1389: static unsigned int dec_addu_r(DisasContext *dc)
                   1390: {
                   1391:        int size = memsize_z(dc);
                   1392:        DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
                   1393:                    memsize_char(size),
                   1394:                    dc->op1, dc->op2));
                   1395: 
                   1396:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1397:        gen_movl_T0_reg[dc->op1]();
                   1398:        /* Size can only be qi or hi.  */
                   1399:        gen_zext_T1_T0(size);
                   1400:        gen_movl_T0_reg[dc->op2]();
                   1401:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
                   1402:        return 2;
                   1403: }
                   1404: /* Sign extension. From size to dword.  */
                   1405: static unsigned int dec_adds_r(DisasContext *dc)
                   1406: {
                   1407:        int size = memsize_z(dc);
                   1408:        DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
                   1409:                    memsize_char(size),
                   1410:                    dc->op1, dc->op2));
                   1411: 
                   1412:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1413:        gen_movl_T0_reg[dc->op1]();
                   1414:        /* Size can only be qi or hi.  */
                   1415:        gen_sext_T1_T0(size);
                   1416:        gen_movl_T0_reg[dc->op2]();
                   1417:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
                   1418:        return 2;
                   1419: }
                   1420: 
                   1421: /* Zero extension. From size to dword.  */
                   1422: static unsigned int dec_subu_r(DisasContext *dc)
                   1423: {
                   1424:        int size = memsize_z(dc);
                   1425:        DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
                   1426:                    memsize_char(size),
                   1427:                    dc->op1, dc->op2));
                   1428: 
                   1429:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1430:        gen_movl_T0_reg[dc->op1]();
                   1431:        /* Size can only be qi or hi.  */
                   1432:        gen_zext_T1_T0(size);
                   1433:        gen_movl_T0_reg[dc->op2]();
                   1434:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
                   1435:        return 2;
                   1436: }
                   1437: 
                   1438: /* Sign extension. From size to dword.  */
                   1439: static unsigned int dec_subs_r(DisasContext *dc)
                   1440: {
                   1441:        int size = memsize_z(dc);
                   1442:        DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
                   1443:                    memsize_char(size),
                   1444:                    dc->op1, dc->op2));
                   1445: 
                   1446:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1447:        gen_movl_T0_reg[dc->op1]();
                   1448:        /* Size can only be qi or hi.  */
                   1449:        gen_sext_T1_T0(size);
                   1450:        gen_movl_T0_reg[dc->op2]();
                   1451:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
                   1452:        return 2;
                   1453: }
                   1454: 
                   1455: static unsigned int dec_setclrf(DisasContext *dc)
                   1456: {
                   1457:        uint32_t flags;
                   1458:        int set = (~dc->opcode >> 2) & 1;
                   1459: 
                   1460:        flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
                   1461:                | EXTRACT_FIELD(dc->ir, 0, 3);
                   1462:        DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
                   1463:        if (set && flags == 0)
                   1464:                DIS(fprintf (logfile, "nop\n"));
                   1465:        else if (!set && (flags & 0x20))
                   1466:                DIS(fprintf (logfile, "di\n"));
                   1467:        else
                   1468:                DIS(fprintf (logfile, "%sf %x\n",
                   1469:                            set ? "set" : "clr",
                   1470:                            flags));
                   1471: 
                   1472:        if (set && (flags & X_FLAG)) {
                   1473:                dc->flagx_live = 1;
                   1474:                dc->flags_x = 1;
                   1475:        }
                   1476: 
                   1477:        /* Simply decode the flags.  */
                   1478:        cris_evaluate_flags (dc);
                   1479:        cris_update_cc_op(dc, CC_OP_FLAGS);
                   1480:        if (set)
                   1481:                gen_op_setf (flags);
                   1482:        else
                   1483:                gen_op_clrf (flags);
                   1484:        dc->flags_live = 1;
                   1485:        return 2;
                   1486: }
                   1487: 
                   1488: static unsigned int dec_move_rs(DisasContext *dc)
                   1489: {
                   1490:        DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2));
                   1491:        cris_cc_mask(dc, 0);
                   1492:        gen_movl_T0_reg[dc->op1]();
                   1493:        gen_op_movl_sreg_T0(dc->op2);
                   1494: 
                   1495:        if (dc->op2 == 5) /* srs is checked at runtime.  */
                   1496:                gen_op_movl_tlb_lo_T0();
                   1497:        return 2;
                   1498: }
                   1499: static unsigned int dec_move_sr(DisasContext *dc)
                   1500: {
                   1501:        DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op1, dc->op2));
                   1502:        cris_cc_mask(dc, 0);
                   1503:        gen_op_movl_T0_sreg(dc->op1);
                   1504:        gen_op_movl_T1_T0();
                   1505:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1506:        return 2;
                   1507: }
                   1508: static unsigned int dec_move_rp(DisasContext *dc)
                   1509: {
                   1510:        DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
                   1511:        cris_cc_mask(dc, 0);
                   1512:        gen_movl_T0_reg[dc->op1]();
                   1513:        gen_op_movl_T1_T0();
                   1514:        gen_movl_preg_T0[dc->op2]();
                   1515:        return 2;
                   1516: }
                   1517: static unsigned int dec_move_pr(DisasContext *dc)
                   1518: {
                   1519:        DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
                   1520:        cris_cc_mask(dc, 0);
                   1521:        gen_movl_T0_preg[dc->op2]();
                   1522:        gen_op_movl_T1_T0();
                   1523:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
                   1524:        return 2;
                   1525: }
                   1526: 
                   1527: static unsigned int dec_move_mr(DisasContext *dc)
                   1528: {
                   1529:        int memsize = memsize_zz(dc);
                   1530:        int insn_len;
                   1531:        DIS(fprintf (logfile, "move.%c [$r%u%s, $r%u\n",
                   1532:                    memsize_char(memsize),
                   1533:                    dc->op1, dc->postinc ? "+]" : "]",
                   1534:                    dc->op2));
                   1535: 
                   1536:        cris_cc_mask(dc, CC_MASK_NZ);
                   1537:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1538:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
                   1539:        do_postinc(dc, memsize);
                   1540:        return insn_len;
                   1541: }
                   1542: 
                   1543: static unsigned int dec_movs_m(DisasContext *dc)
                   1544: {
                   1545:        int memsize = memsize_z(dc);
                   1546:        int insn_len;
                   1547:        DIS(fprintf (logfile, "movs.%c [$r%u%s, $r%u\n",
                   1548:                    memsize_char(memsize),
                   1549:                    dc->op1, dc->postinc ? "+]" : "]",
                   1550:                    dc->op2));
                   1551: 
                   1552:        /* sign extend.  */
                   1553:        cris_cc_mask(dc, CC_MASK_NZ);
                   1554:        insn_len = dec_prep_alu_m(dc, 1, memsize);
                   1555:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1556:        do_postinc(dc, memsize);
                   1557:        return insn_len;
                   1558: }
                   1559: 
                   1560: static unsigned int dec_addu_m(DisasContext *dc)
                   1561: {
                   1562:        int memsize = memsize_z(dc);
                   1563:        int insn_len;
                   1564:        DIS(fprintf (logfile, "addu.%c [$r%u%s, $r%u\n",
                   1565:                    memsize_char(memsize),
                   1566:                    dc->op1, dc->postinc ? "+]" : "]",
                   1567:                    dc->op2));
                   1568: 
                   1569:        /* sign extend.  */
                   1570:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1571:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1572:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
                   1573:        do_postinc(dc, memsize);
                   1574:        return insn_len;
                   1575: }
                   1576: 
                   1577: static unsigned int dec_adds_m(DisasContext *dc)
                   1578: {
                   1579:        int memsize = memsize_z(dc);
                   1580:        int insn_len;
                   1581:        DIS(fprintf (logfile, "adds.%c [$r%u%s, $r%u\n",
                   1582:                    memsize_char(memsize),
                   1583:                    dc->op1, dc->postinc ? "+]" : "]",
                   1584:                    dc->op2));
                   1585: 
                   1586:        /* sign extend.  */
                   1587:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1588:        insn_len = dec_prep_alu_m(dc, 1, memsize);
                   1589:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
                   1590:        do_postinc(dc, memsize);
                   1591:        return insn_len;
                   1592: }
                   1593: 
                   1594: static unsigned int dec_subu_m(DisasContext *dc)
                   1595: {
                   1596:        int memsize = memsize_z(dc);
                   1597:        int insn_len;
                   1598:        DIS(fprintf (logfile, "subu.%c [$r%u%s, $r%u\n",
                   1599:                    memsize_char(memsize),
                   1600:                    dc->op1, dc->postinc ? "+]" : "]",
                   1601:                    dc->op2));
                   1602: 
                   1603:        /* sign extend.  */
                   1604:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1605:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1606:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
                   1607:        do_postinc(dc, memsize);
                   1608:        return insn_len;
                   1609: }
                   1610: 
                   1611: static unsigned int dec_subs_m(DisasContext *dc)
                   1612: {
                   1613:        int memsize = memsize_z(dc);
                   1614:        int insn_len;
                   1615:        DIS(fprintf (logfile, "subs.%c [$r%u%s, $r%u\n",
                   1616:                    memsize_char(memsize),
                   1617:                    dc->op1, dc->postinc ? "+]" : "]",
                   1618:                    dc->op2));
                   1619: 
                   1620:        /* sign extend.  */
                   1621:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1622:        insn_len = dec_prep_alu_m(dc, 1, memsize);
                   1623:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
                   1624:        do_postinc(dc, memsize);
                   1625:        return insn_len;
                   1626: }
                   1627: 
                   1628: static unsigned int dec_movu_m(DisasContext *dc)
                   1629: {
                   1630:        int memsize = memsize_z(dc);
                   1631:        int insn_len;
                   1632: 
                   1633:        DIS(fprintf (logfile, "movu.%c [$r%u%s, $r%u\n",
                   1634:                    memsize_char(memsize),
                   1635:                    dc->op1, dc->postinc ? "+]" : "]",
                   1636:                    dc->op2));
                   1637: 
                   1638:        cris_cc_mask(dc, CC_MASK_NZ);
                   1639:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1640:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1641:        do_postinc(dc, memsize);
                   1642:        return insn_len;
                   1643: }
                   1644: 
                   1645: static unsigned int dec_cmpu_m(DisasContext *dc)
                   1646: {
                   1647:        int memsize = memsize_z(dc);
                   1648:        int insn_len;
                   1649:        DIS(fprintf (logfile, "cmpu.%c [$r%u%s, $r%u\n",
                   1650:                    memsize_char(memsize),
                   1651:                    dc->op1, dc->postinc ? "+]" : "]",
                   1652:                    dc->op2));
                   1653: 
                   1654:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1655:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1656:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
                   1657:        do_postinc(dc, memsize);
                   1658:        return insn_len;
                   1659: }
                   1660: 
                   1661: static unsigned int dec_cmps_m(DisasContext *dc)
                   1662: {
                   1663:        int memsize = memsize_z(dc);
                   1664:        int insn_len;
                   1665:        DIS(fprintf (logfile, "cmps.%c [$r%u%s, $r%u\n",
                   1666:                    memsize_char(memsize),
                   1667:                    dc->op1, dc->postinc ? "+]" : "]",
                   1668:                    dc->op2));
                   1669: 
                   1670:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1671:        insn_len = dec_prep_alu_m(dc, 1, memsize);
                   1672:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
                   1673:        do_postinc(dc, memsize);
                   1674:        return insn_len;
                   1675: }
                   1676: 
                   1677: static unsigned int dec_cmp_m(DisasContext *dc)
                   1678: {
                   1679:        int memsize = memsize_zz(dc);
                   1680:        int insn_len;
                   1681:        DIS(fprintf (logfile, "cmp.%c [$r%u%s, $r%u\n",
                   1682:                    memsize_char(memsize),
                   1683:                    dc->op1, dc->postinc ? "+]" : "]",
                   1684:                    dc->op2));
                   1685: 
                   1686:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1687:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1688:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
                   1689:        do_postinc(dc, memsize);
                   1690:        return insn_len;
                   1691: }
                   1692: 
                   1693: static unsigned int dec_test_m(DisasContext *dc)
                   1694: {
                   1695:        int memsize = memsize_zz(dc);
                   1696:        int insn_len;
                   1697:        DIS(fprintf (logfile, "test.%d [$r%u%s] op2=%x\n",
                   1698:                    memsize_char(memsize),
                   1699:                    dc->op1, dc->postinc ? "+]" : "]",
                   1700:                    dc->op2));
                   1701: 
                   1702:        cris_cc_mask(dc, CC_MASK_NZ);
                   1703:        gen_op_clrf(3);
                   1704:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1705:        gen_op_swp_T0_T1();
                   1706:        gen_op_movl_T1_im(0);
                   1707:        crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
                   1708:        do_postinc(dc, memsize);
                   1709:        return insn_len;
                   1710: }
                   1711: 
                   1712: static unsigned int dec_and_m(DisasContext *dc)
                   1713: {
                   1714:        int memsize = memsize_zz(dc);
                   1715:        int insn_len;
                   1716:        DIS(fprintf (logfile, "and.%d [$r%u%s, $r%u\n",
                   1717:                    memsize_char(memsize),
                   1718:                    dc->op1, dc->postinc ? "+]" : "]",
                   1719:                    dc->op2));
                   1720: 
                   1721:        cris_cc_mask(dc, CC_MASK_NZ);
                   1722:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1723:        crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
                   1724:        do_postinc(dc, memsize);
                   1725:        return insn_len;
                   1726: }
                   1727: 
                   1728: static unsigned int dec_add_m(DisasContext *dc)
                   1729: {
                   1730:        int memsize = memsize_zz(dc);
                   1731:        int insn_len;
                   1732:        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
                   1733:                    memsize_char(memsize),
                   1734:                    dc->op1, dc->postinc ? "+]" : "]",
                   1735:                    dc->op2));
                   1736: 
                   1737:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1738:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1739:        crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
                   1740:        do_postinc(dc, memsize);
                   1741:        return insn_len;
                   1742: }
                   1743: 
                   1744: static unsigned int dec_addo_m(DisasContext *dc)
                   1745: {
                   1746:        int memsize = memsize_zz(dc);
                   1747:        int insn_len;
                   1748:        DIS(fprintf (logfile, "add.%d [$r%u%s, $r%u\n",
                   1749:                    memsize_char(memsize),
                   1750:                    dc->op1, dc->postinc ? "+]" : "]",
                   1751:                    dc->op2));
                   1752: 
                   1753:        cris_cc_mask(dc, 0);
                   1754:        insn_len = dec_prep_alu_m(dc, 1, memsize);
                   1755:        crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4);
                   1756:        do_postinc(dc, memsize);
                   1757:        return insn_len;
                   1758: }
                   1759: 
                   1760: static unsigned int dec_bound_m(DisasContext *dc)
                   1761: {
                   1762:        int memsize = memsize_zz(dc);
                   1763:        int insn_len;
                   1764:        DIS(fprintf (logfile, "bound.%d [$r%u%s, $r%u\n",
                   1765:                    memsize_char(memsize),
                   1766:                    dc->op1, dc->postinc ? "+]" : "]",
                   1767:                    dc->op2));
                   1768: 
                   1769:        cris_cc_mask(dc, CC_MASK_NZ);
                   1770:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1771:        crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
                   1772:        do_postinc(dc, memsize);
                   1773:        return insn_len;
                   1774: }
                   1775: 
                   1776: static unsigned int dec_addc_mr(DisasContext *dc)
                   1777: {
                   1778:        int insn_len = 2;
                   1779:        DIS(fprintf (logfile, "addc [$r%u%s, $r%u\n",
                   1780:                    dc->op1, dc->postinc ? "+]" : "]",
                   1781:                    dc->op2));
                   1782: 
                   1783:        cris_evaluate_flags(dc);
                   1784:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1785:        insn_len = dec_prep_alu_m(dc, 0, 4);
                   1786:        crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
                   1787:        do_postinc(dc, 4);
                   1788:        return insn_len;
                   1789: }
                   1790: 
                   1791: static unsigned int dec_sub_m(DisasContext *dc)
                   1792: {
                   1793:        int memsize = memsize_zz(dc);
                   1794:        int insn_len;
                   1795:        DIS(fprintf (logfile, "sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
                   1796:                    memsize_char(memsize),
                   1797:                    dc->op1, dc->postinc ? "+]" : "]",
                   1798:                    dc->op2, dc->ir, dc->zzsize));
                   1799: 
                   1800:        cris_cc_mask(dc, CC_MASK_NZVC);
                   1801:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1802:        crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
                   1803:        do_postinc(dc, memsize);
                   1804:        return insn_len;
                   1805: }
                   1806: 
                   1807: static unsigned int dec_or_m(DisasContext *dc)
                   1808: {
                   1809:        int memsize = memsize_zz(dc);
                   1810:        int insn_len;
                   1811:        DIS(fprintf (logfile, "or.%d [$r%u%s, $r%u pc=%x\n",
                   1812:                    memsize_char(memsize),
                   1813:                    dc->op1, dc->postinc ? "+]" : "]",
                   1814:                    dc->op2, dc->pc));
                   1815: 
                   1816:        cris_cc_mask(dc, CC_MASK_NZ);
                   1817:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1818:        crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
                   1819:        do_postinc(dc, memsize);
                   1820:        return insn_len;
                   1821: }
                   1822: 
                   1823: static unsigned int dec_move_mp(DisasContext *dc)
                   1824: {
                   1825:        int memsize = memsize_zz(dc);
                   1826:        int insn_len = 2;
                   1827: 
                   1828:        DIS(fprintf (logfile, "move.%c [$r%u%s, $p%u\n",
                   1829:                    memsize_char(memsize),
                   1830:                    dc->op1,
                   1831:                    dc->postinc ? "+]" : "]",
                   1832:                    dc->op2));
                   1833: 
                   1834:        cris_cc_mask(dc, 0);
                   1835:        insn_len = dec_prep_alu_m(dc, 0, memsize);
                   1836:        gen_op_movl_T0_T1();
                   1837:        gen_movl_preg_T0[dc->op2]();
                   1838: 
                   1839:        do_postinc(dc, memsize);
                   1840:        return insn_len;
                   1841: }
                   1842: 
                   1843: static unsigned int dec_move_pm(DisasContext *dc)
                   1844: {
                   1845:        int memsize;
                   1846: 
                   1847:        memsize = preg_sizes[dc->op2];
                   1848: 
                   1849:        DIS(fprintf (logfile, "move.%d $p%u, [$r%u%s\n",
                   1850:                     memsize, dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
                   1851: 
                   1852:        cris_cc_mask(dc, 0);
                   1853:        /* prepare store.  */
                   1854:        gen_movl_T0_preg[dc->op2]();
                   1855:        gen_op_movl_T1_T0();
                   1856:        gen_movl_T0_reg[dc->op1]();
                   1857:        gen_store_T0_T1(dc, memsize);
                   1858:        if (dc->postinc)
                   1859:        {
                   1860:                gen_op_addl_T0_im(memsize);
                   1861:                gen_movl_reg_T0[dc->op1]();
                   1862:        }
                   1863:        return 2;
                   1864: }
                   1865: 
                   1866: static unsigned int dec_movem_mr(DisasContext *dc)
                   1867: {
                   1868:        int i;
                   1869: 
                   1870:        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
                   1871:                    dc->postinc ? "+]" : "]", dc->op2));
                   1872: 
                   1873:        cris_cc_mask(dc, 0);
                   1874:        /* fetch the address into T1.  */
                   1875:        gen_movl_T0_reg[dc->op1]();
                   1876:        gen_op_movl_T1_T0();
                   1877:        for (i = 0; i <= dc->op2; i++) {
                   1878:                /* Perform the load onto regnum i. Always dword wide.  */
                   1879:                gen_load_T0_T0(dc, 4, 0);
                   1880:                gen_movl_reg_T0[i]();
                   1881:                /* Update the address.  */
                   1882:                gen_op_addl_T1_im(4);
                   1883:                gen_op_movl_T0_T1();
                   1884:        }
                   1885:        if (dc->postinc) {
                   1886:                /* writeback the updated pointer value.  */
                   1887:                gen_movl_reg_T0[dc->op1]();
                   1888:        }
                   1889:        return 2;
                   1890: }
                   1891: 
                   1892: static unsigned int dec_movem_rm(DisasContext *dc)
                   1893: {
                   1894:        int i;
                   1895: 
                   1896:        DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
                   1897:                     dc->postinc ? "+]" : "]"));
                   1898: 
                   1899:        cris_cc_mask(dc, 0);
                   1900:        for (i = 0; i <= dc->op2; i++) {
                   1901:                /* Fetch register i into T1.  */
                   1902:                gen_movl_T0_reg[i]();
                   1903:                gen_op_movl_T1_T0();
                   1904: 
                   1905:                /* Fetch the address into T0.  */
                   1906:                gen_movl_T0_reg[dc->op1]();
                   1907:                /* Displace it.  */
                   1908:                gen_op_addl_T0_im(i * 4);
                   1909: 
                   1910:                /* Perform the store.  */
                   1911:                gen_store_T0_T1(dc, 4);
                   1912:        }
                   1913:        if (dc->postinc) {
                   1914:                /* Update the address.  */
                   1915:                gen_op_addl_T0_im(4);
                   1916:                /* writeback the updated pointer value.  */
                   1917:                gen_movl_reg_T0[dc->op1]();
                   1918:        }
                   1919:        return 2;
                   1920: }
                   1921: 
                   1922: static unsigned int dec_move_rm(DisasContext *dc)
                   1923: {
                   1924:        int memsize;
                   1925: 
                   1926:        memsize = memsize_zz(dc);
                   1927: 
                   1928:        DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
                   1929:                     memsize, dc->op2, dc->op1));
                   1930: 
                   1931:        cris_cc_mask(dc, 0);
                   1932:        /* prepare store.  */
                   1933:        gen_movl_T0_reg[dc->op2]();
                   1934:        gen_op_movl_T1_T0();
                   1935:        gen_movl_T0_reg[dc->op1]();
                   1936:        gen_store_T0_T1(dc, memsize);
                   1937:        if (dc->postinc)
                   1938:        {
                   1939:                gen_op_addl_T0_im(memsize);
                   1940:                gen_movl_reg_T0[dc->op1]();
                   1941:        }
                   1942:        return 2;
                   1943: }
                   1944: 
                   1945: 
                   1946: static unsigned int dec_lapcq(DisasContext *dc)
                   1947: {
                   1948:        DIS(fprintf (logfile, "lapcq %x, $r%u\n",
                   1949:                    dc->pc + dc->op1*2, dc->op2));
                   1950:        cris_cc_mask(dc, 0);
                   1951:        gen_op_movl_T1_im(dc->pc + dc->op1*2);
                   1952:        crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
                   1953:        return 2;
                   1954: }
                   1955: 
                   1956: static unsigned int dec_lapc_im(DisasContext *dc)
                   1957: {
                   1958:        unsigned int rd;
                   1959:        int32_t imm;
                   1960:        int insn_len = 6;
                   1961: 
                   1962:        rd = dc->op2;
                   1963: 
                   1964:        cris_cc_mask(dc, 0);
                   1965:        imm = ldl_code(dc->pc + 2);
                   1966:        DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
                   1967:        gen_op_movl_T0_im (dc->pc + imm);
                   1968:        gen_movl_reg_T0[rd] ();
                   1969:        return insn_len;
                   1970: }
                   1971: 
                   1972: /* Jump to special reg.  */
                   1973: static unsigned int dec_jump_p(DisasContext *dc)
                   1974: {
                   1975:        DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
                   1976:        cris_cc_mask(dc, 0);
                   1977:        /* Store the return address in Pd.  */
                   1978:        gen_movl_T0_preg[dc->op2]();
                   1979:        gen_op_movl_btarget_T0();
                   1980:        cris_prepare_dyn_jmp(dc);
                   1981:        return 2;
                   1982: }
                   1983: 
                   1984: /* Jump and save.  */
                   1985: static unsigned int dec_jas_r(DisasContext *dc)
                   1986: {
                   1987:        DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
                   1988:        cris_cc_mask(dc, 0);
                   1989:        /* Stor the return address in Pd.  */
                   1990:        gen_movl_T0_reg[dc->op1]();
                   1991:        gen_op_movl_btarget_T0();
                   1992:        gen_op_movl_T0_im(dc->pc + 4);
                   1993:        gen_movl_preg_T0[dc->op2]();
                   1994:        cris_prepare_dyn_jmp(dc);
                   1995:        return 2;
                   1996: }
                   1997: 
                   1998: static unsigned int dec_jas_im(DisasContext *dc)
                   1999: {
                   2000:        uint32_t imm;
                   2001: 
                   2002:        imm = ldl_code(dc->pc + 2);
                   2003: 
                   2004:        DIS(fprintf (logfile, "jas 0x%x\n", imm));
                   2005:        cris_cc_mask(dc, 0);
                   2006:        /* Stor the return address in Pd.  */
                   2007:        gen_op_movl_T0_im(imm);
                   2008:        gen_op_movl_btarget_T0();
                   2009:        gen_op_movl_T0_im(dc->pc + 8);
                   2010:        gen_movl_preg_T0[dc->op2]();
                   2011:        cris_prepare_dyn_jmp(dc);
                   2012:        return 6;
                   2013: }
                   2014: 
                   2015: static unsigned int dec_jasc_im(DisasContext *dc)
                   2016: {
                   2017:        uint32_t imm;
                   2018: 
                   2019:        imm = ldl_code(dc->pc + 2);
                   2020: 
                   2021:        DIS(fprintf (logfile, "jasc 0x%x\n", imm));
                   2022:        cris_cc_mask(dc, 0);
                   2023:        /* Stor the return address in Pd.  */
                   2024:        gen_op_movl_T0_im(imm);
                   2025:        gen_op_movl_btarget_T0();
                   2026:        gen_op_movl_T0_im(dc->pc + 8 + 4);
                   2027:        gen_movl_preg_T0[dc->op2]();
                   2028:        cris_prepare_dyn_jmp(dc);
                   2029:        return 6;
                   2030: }
                   2031: 
                   2032: static unsigned int dec_jasc_r(DisasContext *dc)
                   2033: {
                   2034:        DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2));
                   2035:        cris_cc_mask(dc, 0);
                   2036:        /* Stor the return address in Pd.  */
                   2037:        gen_movl_T0_reg[dc->op1]();
                   2038:        gen_op_movl_btarget_T0();
                   2039:        gen_op_movl_T0_im(dc->pc + 4 + 4);
                   2040:        gen_movl_preg_T0[dc->op2]();
                   2041:        cris_prepare_dyn_jmp(dc);
                   2042:        return 2;
                   2043: }
                   2044: 
                   2045: static unsigned int dec_bcc_im(DisasContext *dc)
                   2046: {
                   2047:        int32_t offset;
                   2048:        uint32_t cond = dc->op2;
                   2049: 
                   2050:        offset = ldl_code(dc->pc + 2);
                   2051:        offset = sign_extend(offset, 15);
                   2052: 
                   2053:        DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n",
                   2054:                    cc_name(cond), offset,
                   2055:                    dc->pc, dc->pc + offset));
                   2056: 
                   2057:        cris_cc_mask(dc, 0);
                   2058:        /* op2 holds the condition-code.  */
                   2059:        cris_prepare_cc_branch (dc, offset, cond);
                   2060:        return 4;
                   2061: }
                   2062: 
                   2063: static unsigned int dec_bas_im(DisasContext *dc)
                   2064: {
                   2065:        int32_t simm;
                   2066: 
                   2067: 
                   2068:        simm = ldl_code(dc->pc + 2);
                   2069: 
                   2070:        DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2));
                   2071:        cris_cc_mask(dc, 0);
                   2072:        /* Stor the return address in Pd.  */
                   2073:        gen_op_movl_T0_im(dc->pc + simm);
                   2074:        gen_op_movl_btarget_T0();
                   2075:        gen_op_movl_T0_im(dc->pc + 8);
                   2076:        gen_movl_preg_T0[dc->op2]();
                   2077:        cris_prepare_dyn_jmp(dc);
                   2078:        return 6;
                   2079: }
                   2080: 
                   2081: static unsigned int dec_basc_im(DisasContext *dc)
                   2082: {
                   2083:        int32_t simm;
                   2084:        simm = ldl_code(dc->pc + 2);
                   2085: 
                   2086:        DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2));
                   2087:        cris_cc_mask(dc, 0);
                   2088:        /* Stor the return address in Pd.  */
                   2089:        gen_op_movl_T0_im(dc->pc + simm);
                   2090:        gen_op_movl_btarget_T0();
                   2091:        gen_op_movl_T0_im(dc->pc + 12);
                   2092:        gen_movl_preg_T0[dc->op2]();
                   2093:        cris_prepare_dyn_jmp(dc);
                   2094:        return 6;
                   2095: }
                   2096: 
                   2097: static unsigned int dec_rfe_etc(DisasContext *dc)
                   2098: {
                   2099:        DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
                   2100:                    dc->opcode, dc->pc, dc->op1, dc->op2));
                   2101: 
                   2102:        cris_cc_mask(dc, 0);
                   2103: 
                   2104:        if (dc->op2 == 15) /* ignore halt.  */
                   2105:                goto done;
                   2106: 
                   2107:        switch (dc->op2 & 7) {
                   2108:                case 2:
                   2109:                        /* rfe.  */
                   2110:                        cris_evaluate_flags(dc);
                   2111:                        gen_op_ccs_rshift();
                   2112:                        break;
                   2113:                case 5:
                   2114:                        /* rfn.  */
                   2115:                        BUG();
                   2116:                        break;
                   2117:                case 6:
                   2118:                        /* break.  */
                   2119:                        gen_op_movl_T0_im(dc->pc);
                   2120:                        gen_op_movl_pc_T0();
                   2121:                        /* Breaks start at 16 in the exception vector.  */
                   2122:                        gen_op_break_im(dc->op1 + 16);
                   2123:                        break;
                   2124:                default:
                   2125:                        printf ("op2=%x\n", dc->op2);
                   2126:                        BUG();
                   2127:                        break;
                   2128: 
                   2129:        }
                   2130:   done:
                   2131:        return 2;
                   2132: }
                   2133: 
                   2134: static unsigned int dec_null(DisasContext *dc)
                   2135: {
                   2136:        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
                   2137:                dc->pc, dc->opcode, dc->op1, dc->op2);
                   2138:        fflush(NULL);
                   2139:        BUG();
                   2140:        return 2;
                   2141: }
                   2142: 
                   2143: struct decoder_info {
                   2144:        struct {
                   2145:                uint32_t bits;
                   2146:                uint32_t mask;
                   2147:        };
                   2148:        unsigned int (*dec)(DisasContext *dc);
                   2149: } decinfo[] = {
                   2150:        /* Order matters here.  */
                   2151:        {DEC_MOVEQ, dec_moveq},
                   2152:        {DEC_BTSTQ, dec_btstq},
                   2153:        {DEC_CMPQ, dec_cmpq},
                   2154:        {DEC_ADDOQ, dec_addoq},
                   2155:        {DEC_ADDQ, dec_addq},
                   2156:        {DEC_SUBQ, dec_subq},
                   2157:        {DEC_ANDQ, dec_andq},
                   2158:        {DEC_ORQ, dec_orq},
                   2159:        {DEC_ASRQ, dec_asrq},
                   2160:        {DEC_LSLQ, dec_lslq},
                   2161:        {DEC_LSRQ, dec_lsrq},
                   2162:        {DEC_BCCQ, dec_bccq},
                   2163: 
                   2164:        {DEC_BCC_IM, dec_bcc_im},
                   2165:        {DEC_JAS_IM, dec_jas_im},
                   2166:        {DEC_JAS_R, dec_jas_r},
                   2167:        {DEC_JASC_IM, dec_jasc_im},
                   2168:        {DEC_JASC_R, dec_jasc_r},
                   2169:        {DEC_BAS_IM, dec_bas_im},
                   2170:        {DEC_BASC_IM, dec_basc_im},
                   2171:        {DEC_JUMP_P, dec_jump_p},
                   2172:        {DEC_LAPC_IM, dec_lapc_im},
                   2173:        {DEC_LAPCQ, dec_lapcq},
                   2174: 
                   2175:        {DEC_RFE_ETC, dec_rfe_etc},
                   2176:        {DEC_ADDC_MR, dec_addc_mr},
                   2177: 
                   2178:        {DEC_MOVE_MP, dec_move_mp},
                   2179:        {DEC_MOVE_PM, dec_move_pm},
                   2180:        {DEC_MOVEM_MR, dec_movem_mr},
                   2181:        {DEC_MOVEM_RM, dec_movem_rm},
                   2182:        {DEC_MOVE_PR, dec_move_pr},
                   2183:        {DEC_SCC_R, dec_scc_r},
                   2184:        {DEC_SETF, dec_setclrf},
                   2185:        {DEC_CLEARF, dec_setclrf},
                   2186: 
                   2187:        {DEC_MOVE_SR, dec_move_sr},
                   2188:        {DEC_MOVE_RP, dec_move_rp},
                   2189:        {DEC_SWAP_R, dec_swap_r},
                   2190:        {DEC_ABS_R, dec_abs_r},
                   2191:        {DEC_LZ_R, dec_lz_r},
                   2192:        {DEC_MOVE_RS, dec_move_rs},
                   2193:        {DEC_BTST_R, dec_btst_r},
                   2194:        {DEC_ADDC_R, dec_addc_r},
                   2195: 
                   2196:        {DEC_DSTEP_R, dec_dstep_r},
                   2197:        {DEC_XOR_R, dec_xor_r},
                   2198:        {DEC_MCP_R, dec_mcp_r},
                   2199:        {DEC_CMP_R, dec_cmp_r},
                   2200: 
                   2201:        {DEC_ADDI_R, dec_addi_r},
                   2202:        {DEC_ADDI_ACR, dec_addi_acr},
                   2203: 
                   2204:        {DEC_ADD_R, dec_add_r},
                   2205:        {DEC_SUB_R, dec_sub_r},
                   2206: 
                   2207:        {DEC_ADDU_R, dec_addu_r},
                   2208:        {DEC_ADDS_R, dec_adds_r},
                   2209:        {DEC_SUBU_R, dec_subu_r},
                   2210:        {DEC_SUBS_R, dec_subs_r},
                   2211:        {DEC_LSL_R, dec_lsl_r},
                   2212: 
                   2213:        {DEC_AND_R, dec_and_r},
                   2214:        {DEC_OR_R, dec_or_r},
                   2215:        {DEC_BOUND_R, dec_bound_r},
                   2216:        {DEC_ASR_R, dec_asr_r},
                   2217:        {DEC_LSR_R, dec_lsr_r},
                   2218: 
                   2219:        {DEC_MOVU_R, dec_movu_r},
                   2220:        {DEC_MOVS_R, dec_movs_r},
                   2221:        {DEC_NEG_R, dec_neg_r},
                   2222:        {DEC_MOVE_R, dec_move_r},
                   2223: 
                   2224:        /* ftag_fidx_i_m.  */
                   2225:        /* ftag_fidx_d_m.  */
                   2226: 
                   2227:        {DEC_MULS_R, dec_muls_r},
                   2228:        {DEC_MULU_R, dec_mulu_r},
                   2229: 
                   2230:        {DEC_ADDU_M, dec_addu_m},
                   2231:        {DEC_ADDS_M, dec_adds_m},
                   2232:        {DEC_SUBU_M, dec_subu_m},
                   2233:        {DEC_SUBS_M, dec_subs_m},
                   2234: 
                   2235:        {DEC_CMPU_M, dec_cmpu_m},
                   2236:        {DEC_CMPS_M, dec_cmps_m},
                   2237:        {DEC_MOVU_M, dec_movu_m},
                   2238:        {DEC_MOVS_M, dec_movs_m},
                   2239: 
                   2240:        {DEC_CMP_M, dec_cmp_m},
                   2241:        {DEC_ADDO_M, dec_addo_m},
                   2242:        {DEC_BOUND_M, dec_bound_m},
                   2243:        {DEC_ADD_M, dec_add_m},
                   2244:        {DEC_SUB_M, dec_sub_m},
                   2245:        {DEC_AND_M, dec_and_m},
                   2246:        {DEC_OR_M, dec_or_m},
                   2247:        {DEC_MOVE_RM, dec_move_rm},
                   2248:        {DEC_TEST_M, dec_test_m},
                   2249:        {DEC_MOVE_MR, dec_move_mr},
                   2250: 
                   2251:        {{0, 0}, dec_null}
                   2252: };
                   2253: 
                   2254: static inline unsigned int
                   2255: cris_decoder(DisasContext *dc)
                   2256: {
                   2257:        unsigned int insn_len = 2;
                   2258:        uint32_t tmp;
                   2259:        int i;
                   2260: 
                   2261:        /* Load a halfword onto the instruction register.  */
                   2262:        tmp = ldl_code(dc->pc);
                   2263:        dc->ir = tmp & 0xffff;
                   2264: 
                   2265:        /* Now decode it.  */
                   2266:        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
                   2267:        dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
                   2268:        dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
                   2269:        dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
                   2270:        dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
                   2271:        dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
                   2272: 
                   2273:        /* Large switch for all insns.  */
                   2274:        for (i = 0; i < sizeof decinfo / sizeof decinfo[0]; i++) {
                   2275:                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
                   2276:                {
                   2277:                        insn_len = decinfo[i].dec(dc);
                   2278:                        break;
                   2279:                }
                   2280:        }
                   2281: 
                   2282:        return insn_len;
                   2283: }
                   2284: 
                   2285: static void check_breakpoint(CPUState *env, DisasContext *dc)
                   2286: {
                   2287:        int j;
                   2288:        if (env->nb_breakpoints > 0) {
                   2289:                for(j = 0; j < env->nb_breakpoints; j++) {
                   2290:                        if (env->breakpoints[j] == dc->pc) {
                   2291:                                cris_evaluate_flags (dc);
                   2292:                                gen_op_movl_T0_im((long)dc->pc);
                   2293:                                gen_op_movl_pc_T0();
                   2294:                                gen_op_debug();
                   2295:                                dc->is_jmp = DISAS_UPDATE;
                   2296:                        }
                   2297:                }
                   2298:        }
                   2299: }
                   2300: 
                   2301: 
                   2302: /* generate intermediate code for basic block 'tb'.  */
                   2303: struct DisasContext ctx;
                   2304: static int
                   2305: gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                   2306:                                int search_pc)
                   2307: {
                   2308:        uint16_t *gen_opc_end;
                   2309:        uint32_t pc_start;
                   2310:        unsigned int insn_len;
                   2311:        int j, lj;
                   2312:        struct DisasContext *dc = &ctx;
                   2313:        uint32_t next_page_start;
                   2314: 
                   2315:        pc_start = tb->pc;
                   2316:        dc->env = env;
                   2317:        dc->tb = tb;
                   2318: 
                   2319:        gen_opc_ptr = gen_opc_buf;
                   2320:        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   2321:        gen_opparam_ptr = gen_opparam_buf;
                   2322: 
                   2323:        dc->is_jmp = DISAS_NEXT;
                   2324:        dc->pc = pc_start;
                   2325:        dc->singlestep_enabled = env->singlestep_enabled;
                   2326:        dc->flagx_live = 0;
                   2327:        dc->flags_x = 0;
                   2328:        next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
                   2329:        lj = -1;
                   2330:        do
                   2331:        {
                   2332:                check_breakpoint(env, dc);
                   2333:                if (dc->is_jmp == DISAS_JUMP)
                   2334:                        goto done;
                   2335: 
                   2336:                if (search_pc) {
                   2337:                        j = gen_opc_ptr - gen_opc_buf;
                   2338:                        if (lj < j) {
                   2339:                                lj++;
                   2340:                                while (lj < j)
                   2341:                                        gen_opc_instr_start[lj++] = 0;
                   2342:                        }
                   2343:                        gen_opc_pc[lj] = dc->pc;
                   2344:                        gen_opc_instr_start[lj] = 1;
                   2345:                }
                   2346: 
                   2347:                insn_len = cris_decoder(dc);
                   2348:                STATS(gen_op_exec_insn());
                   2349:                dc->pc += insn_len;
                   2350:                if (!dc->flagx_live
                   2351:                    || (dc->flagx_live &&
                   2352:                        !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) {
                   2353:                        gen_movl_T0_preg[SR_CCS]();
                   2354:                        gen_op_andl_T0_im(~X_FLAG);
                   2355:                        gen_movl_preg_T0[SR_CCS]();
                   2356:                        dc->flagx_live = 1;
                   2357:                        dc->flags_x = 0;
                   2358:                }
                   2359: 
                   2360:                /* Check for delayed branches here. If we do it before
                   2361:                   actually genereating any host code, the simulator will just
                   2362:                   loop doing nothing for on this program location.  */
                   2363:                if (dc->delayed_branch) {
                   2364:                        dc->delayed_branch--;
                   2365:                        if (dc->delayed_branch == 0)
                   2366:                        {
                   2367:                                if (dc->bcc == CC_A) {
                   2368:                                        gen_op_jmp ();
                   2369:                                        dc->is_jmp = DISAS_UPDATE;
                   2370:                                }
                   2371:                                else {
                   2372:                                        /* Conditional jmp.  */
                   2373:                                        gen_op_cc_jmp (dc->delayed_pc, dc->pc);
                   2374:                                        dc->is_jmp = DISAS_UPDATE;
                   2375:                                }
                   2376:                        }
                   2377:                }
                   2378: 
                   2379:                if (env->singlestep_enabled)
                   2380:                        break;
                   2381:        } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
                   2382:                 && dc->pc < next_page_start);
                   2383: 
                   2384:        if (!dc->is_jmp) {
                   2385:                gen_op_movl_T0_im((long)dc->pc);
                   2386:                gen_op_movl_pc_T0();
                   2387:        }
                   2388: 
                   2389:        cris_evaluate_flags (dc);
                   2390:   done:
                   2391:        if (__builtin_expect(env->singlestep_enabled, 0)) {
                   2392:                gen_op_debug();
                   2393:        } else {
                   2394:                switch(dc->is_jmp) {
                   2395:                        case DISAS_NEXT:
                   2396:                                gen_goto_tb(dc, 1, dc->pc);
                   2397:                                break;
                   2398:                        default:
                   2399:                        case DISAS_JUMP:
                   2400:                        case DISAS_UPDATE:
                   2401:                                /* indicate that the hash table must be used
                   2402:                                   to find the next TB */
                   2403:                                /* T0 is used to index the jmp tables.  */
                   2404:                                gen_op_movl_T0_0();
                   2405:                                gen_op_exit_tb();
                   2406:                                break;
                   2407:                        case DISAS_TB_JUMP:
                   2408:                                /* nothing more to generate */
                   2409:                                break;
                   2410:                }
                   2411:        }
                   2412:        *gen_opc_ptr = INDEX_op_end;
                   2413:        if (search_pc) {
                   2414:                j = gen_opc_ptr - gen_opc_buf;
                   2415:                lj++;
                   2416:                while (lj <= j)
                   2417:                        gen_opc_instr_start[lj++] = 0;
                   2418:        } else {
                   2419:                tb->size = dc->pc - pc_start;
                   2420:        }
                   2421: 
                   2422: #ifdef DEBUG_DISAS
                   2423:        if (loglevel & CPU_LOG_TB_IN_ASM) {
                   2424:                fprintf(logfile, "--------------\n");
                   2425:                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
                   2426:                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
                   2427:                fprintf(logfile, "\n");
                   2428:                if (loglevel & CPU_LOG_TB_OP) {
                   2429:                        fprintf(logfile, "OP:\n");
                   2430:                        dump_ops(gen_opc_buf, gen_opparam_buf);
                   2431:                        fprintf(logfile, "\n");
                   2432:                }
                   2433:        }
                   2434: #endif
                   2435:        return 0;
                   2436: }
                   2437: 
                   2438: int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
                   2439: {
                   2440:     return gen_intermediate_code_internal(env, tb, 0);
                   2441: }
                   2442: 
                   2443: int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
                   2444: {
                   2445:     return gen_intermediate_code_internal(env, tb, 1);
                   2446: }
                   2447: 
                   2448: void cpu_dump_state (CPUState *env, FILE *f,
                   2449:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   2450:                      int flags)
                   2451: {
                   2452:        int i;
                   2453:        uint32_t srs;
                   2454: 
                   2455:        if (!env || !f)
                   2456:                return;
                   2457: 
                   2458:        cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
                   2459:                    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n"
                   2460:                    "debug=%x %x %x\n",
                   2461:                    env->pc, env->pregs[SR_CCS], env->btaken, env->btarget,
                   2462:                    env->cc_op,
                   2463:                    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask,
                   2464:                    env->debug1, env->debug2, env->debug3);
                   2465: 
                   2466:        for (i = 0; i < 16; i++) {
                   2467:                cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
                   2468:                if ((i + 1) % 4 == 0)
                   2469:                        cpu_fprintf(f, "\n");
                   2470:        }
                   2471:        cpu_fprintf(f, "\nspecial regs:\n");
                   2472:        for (i = 0; i < 16; i++) {
                   2473:                cpu_fprintf(f, "p%2.2d=%8.8x ", i, env->pregs[i]);
                   2474:                if ((i + 1) % 4 == 0)
                   2475:                        cpu_fprintf(f, "\n");
                   2476:        }
                   2477:        srs = env->pregs[SR_SRS];
                   2478:        cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs);
                   2479:        if (srs < 256) {
                   2480:                for (i = 0; i < 16; i++) {
                   2481:                        cpu_fprintf(f, "s%2.2d=%8.8x ",
                   2482:                                    i, env->sregs[srs][i]);
                   2483:                        if ((i + 1) % 4 == 0)
                   2484:                                cpu_fprintf(f, "\n");
                   2485:                }
                   2486:        }
                   2487:        cpu_fprintf(f, "\n\n");
                   2488: 
                   2489: }
                   2490: 
                   2491: CPUCRISState *cpu_cris_init (const char *cpu_model)
                   2492: {
                   2493:        CPUCRISState *env;
                   2494: 
                   2495:        env = qemu_mallocz(sizeof(CPUCRISState));
                   2496:        if (!env)
                   2497:                return NULL;
                   2498:        cpu_exec_init(env);
                   2499:        cpu_reset(env);
                   2500:        return env;
                   2501: }
                   2502: 
                   2503: void cpu_reset (CPUCRISState *env)
                   2504: {
                   2505:        memset(env, 0, offsetof(CPUCRISState, breakpoints));
                   2506:        tlb_flush(env, 1);
                   2507: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.