Annotation of qemu/target-m68k/translate.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  m68k translation
        !             3:  * 
        !             4:  *  Copyright (c) 2005-2006 CodeSourcery
        !             5:  *  Written by Paul Brook
        !             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:  * 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: #include <stdarg.h>
        !            22: #include <stdlib.h>
        !            23: #include <stdio.h>
        !            24: #include <string.h>
        !            25: #include <inttypes.h>
        !            26: 
        !            27: #include "config.h"
        !            28: #include "cpu.h"
        !            29: #include "exec-all.h"
        !            30: #include "disas.h"
        !            31: #include "m68k-qreg.h"
        !            32: 
        !            33: static inline void qemu_assert(int cond, const char *msg)
        !            34: {
        !            35:     if (!cond) {
        !            36:         fprintf (stderr, "badness: %s\n", msg);
        !            37:         abort();
        !            38:     }
        !            39: }
        !            40: 
        !            41: /* internal defines */
        !            42: typedef struct DisasContext {
        !            43:     target_ulong pc;
        !            44:     int is_jmp;
        !            45:     int cc_op;
        !            46:     uint32_t fpcr;
        !            47:     struct TranslationBlock *tb;
        !            48:     int singlestep_enabled;
        !            49: } DisasContext;
        !            50: 
        !            51: #define DISAS_JUMP_NEXT 4
        !            52: 
        !            53: /* XXX: move that elsewhere */
        !            54: /* ??? Fix exceptions.  */
        !            55: static void *gen_throws_exception;
        !            56: #define gen_last_qop NULL
        !            57: 
        !            58: static uint16_t *gen_opc_ptr;
        !            59: static uint32_t *gen_opparam_ptr;
        !            60: extern FILE *logfile;
        !            61: extern int loglevel;
        !            62: 
        !            63: enum {
        !            64: #define DEF(s, n, copy_size) INDEX_op_ ## s,
        !            65: #include "opc.h"
        !            66: #undef DEF
        !            67:     NB_OPS,
        !            68: };
        !            69: 
        !            70: #include "gen-op.h"
        !            71: #include "op-hacks.h"
        !            72: 
        !            73: #define OS_BYTE 0
        !            74: #define OS_WORD 1
        !            75: #define OS_LONG 2
        !            76: #define OS_SINGLE 4
        !            77: #define OS_DOUBLE 5
        !            78: 
        !            79: #define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
        !            80: #define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
        !            81: #define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
        !            82: 
        !            83: #define M68K_INSN_CF_A    (1 << 0)
        !            84: #define M68K_INSN_CF_B    (1 << 1)
        !            85: #define M68K_INSN_CF_C    (1 << 2)
        !            86: #define M68K_INSN_CF_MAC  (1 << 3)
        !            87: #define M68K_INSN_CF_EMAC (1 << 4)
        !            88: #define M68K_INSN_CF_FPU  (1 << 5)
        !            89: 
        !            90: struct m68k_def_t {
        !            91:     const char * name;
        !            92:     uint32_t insns;
        !            93: };
        !            94: 
        !            95: static m68k_def_t m68k_cpu_defs[] = {
        !            96:     {"m5206", M68K_INSN_CF_A},
        !            97:     {"cfv4e", M68K_INSN_CF_A | M68K_INSN_CF_B | M68K_INSN_CF_C
        !            98:             | M68K_INSN_CF_MAC | M68K_INSN_CF_EMAC | M68K_INSN_CF_FPU},
        !            99:     {NULL, 0}, 
        !           100: };
        !           101: 
        !           102: typedef void (*disas_proc)(DisasContext *, uint16_t);
        !           103: 
        !           104: #define DISAS_INSN(name) \
        !           105:   static void disas_##name (DisasContext *s, uint16_t insn)
        !           106: 
        !           107: /* Generate a load from the specified address.  Narrow values are
        !           108:    sign extended to full register width.  */
        !           109: static inline int gen_load(int opsize, int addr, int sign)
        !           110: {
        !           111:     int tmp;
        !           112:     switch(opsize) {
        !           113:     case OS_BYTE:
        !           114:         tmp = gen_new_qreg(QMODE_I32);
        !           115:         if (sign)
        !           116:             gen_op_ld8s32(tmp, addr);
        !           117:         else
        !           118:             gen_op_ld8u32(tmp, addr);
        !           119:         break;
        !           120:     case OS_WORD:
        !           121:         tmp = gen_new_qreg(QMODE_I32);
        !           122:         if (sign)
        !           123:             gen_op_ld16s32(tmp, addr);
        !           124:         else
        !           125:             gen_op_ld16u32(tmp, addr);
        !           126:         break;
        !           127:     case OS_LONG:
        !           128:         tmp = gen_new_qreg(QMODE_I32);
        !           129:         gen_op_ld32(tmp, addr);
        !           130:         break;
        !           131:     case OS_SINGLE:
        !           132:         tmp = gen_new_qreg(QMODE_F32);
        !           133:         gen_op_ldf32(tmp, addr);
        !           134:         break;
        !           135:     case OS_DOUBLE:
        !           136:         tmp  = gen_new_qreg(QMODE_F64);
        !           137:         gen_op_ldf64(tmp, addr);
        !           138:         break;
        !           139:     default:
        !           140:         qemu_assert(0, "bad load size");
        !           141:     }
        !           142:     gen_throws_exception = gen_last_qop;
        !           143:     return tmp;
        !           144: }
        !           145: 
        !           146: /* Generate a store.  */
        !           147: static inline void gen_store(int opsize, int addr, int val)
        !           148: {
        !           149:     switch(opsize) {
        !           150:     case OS_BYTE:
        !           151:         gen_op_st8(addr, val);
        !           152:         break;
        !           153:     case OS_WORD:
        !           154:         gen_op_st16(addr, val);
        !           155:         break;
        !           156:     case OS_LONG:
        !           157:         gen_op_st32(addr, val);
        !           158:         break;
        !           159:     case OS_SINGLE:
        !           160:         gen_op_stf32(addr, val);
        !           161:         break;
        !           162:     case OS_DOUBLE:
        !           163:         gen_op_stf64(addr, val);
        !           164:         break;
        !           165:     default:
        !           166:         qemu_assert(0, "bad store size");
        !           167:     }
        !           168:     gen_throws_exception = gen_last_qop;
        !           169: }
        !           170: 
        !           171: /* Generate an unsigned load if VAL is 0 a signed load if val is -1,
        !           172:    otherwise generate a store.  */
        !           173: static int gen_ldst(int opsize, int addr, int val)
        !           174: {
        !           175:     if (val > 0) {
        !           176:         gen_store(opsize, addr, val);
        !           177:         return 0;
        !           178:     } else {
        !           179:         return gen_load(opsize, addr, val != 0);
        !           180:     }
        !           181: }
        !           182: 
        !           183: /* Handle a base + index + displacement effective addresss.  A base of
        !           184:    -1 means pc-relative.  */
        !           185: static int gen_lea_indexed(DisasContext *s, int opsize, int base)
        !           186: {
        !           187:     int scale;
        !           188:     uint32_t offset;
        !           189:     uint16_t ext;
        !           190:     int add;
        !           191:     int tmp;
        !           192: 
        !           193:     offset = s->pc;
        !           194:     ext = lduw(s->pc);
        !           195:     s->pc += 2;
        !           196:     tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
        !           197:     /* ??? Check W/L bit.  */
        !           198:     scale = (ext >> 9) & 3;
        !           199:     if (scale == 0) {
        !           200:         add = tmp;
        !           201:     } else {
        !           202:         add = gen_new_qreg(QMODE_I32);
        !           203:         gen_op_shl32(add, tmp, gen_im32(scale));
        !           204:     }
        !           205:     tmp = gen_new_qreg(QMODE_I32);
        !           206:     if (base != -1) {
        !           207:         gen_op_add32(tmp, base, gen_im32((int8_t)ext));
        !           208:         gen_op_add32(tmp, tmp, add);
        !           209:     } else {
        !           210:         gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
        !           211:     }
        !           212:     return tmp;
        !           213: }
        !           214: 
        !           215: /* Read a 32-bit immediate constant.  */
        !           216: static inline uint32_t read_im32(DisasContext *s)
        !           217: {
        !           218:     uint32_t im;
        !           219:     im = ((uint32_t)lduw(s->pc)) << 16;
        !           220:     s->pc += 2;
        !           221:     im |= lduw(s->pc);
        !           222:     s->pc += 2;
        !           223:     return im;
        !           224: }
        !           225: 
        !           226: 
        !           227: /* Update the CPU env CC_OP state.  */
        !           228: static inline void gen_flush_cc_op(DisasContext *s)
        !           229: {
        !           230:     if (s->cc_op != CC_OP_DYNAMIC)
        !           231:         gen_op_mov32(QREG_CC_OP, gen_im32(s->cc_op));
        !           232: }
        !           233: 
        !           234: /* Evaluate all the CC flags.  */
        !           235: static inline void gen_flush_flags(DisasContext *s)
        !           236: {
        !           237:     if (s->cc_op == CC_OP_FLAGS)
        !           238:         return;
        !           239:     gen_op_flush_flags(s->cc_op);
        !           240:     s->cc_op = CC_OP_FLAGS;
        !           241: }
        !           242: 
        !           243: static inline int opsize_bytes(int opsize)
        !           244: {
        !           245:     switch (opsize) {
        !           246:     case OS_BYTE: return 1;
        !           247:     case OS_WORD: return 2;
        !           248:     case OS_LONG: return 4;
        !           249:     case OS_SINGLE: return 4;
        !           250:     case OS_DOUBLE: return 8;
        !           251:     default:
        !           252:         qemu_assert(0, "bad operand size");
        !           253:     }
        !           254: }
        !           255: 
        !           256: /* Assign value to a register.  If the width is less than the register width
        !           257:    only the low part of the register is set.  */
        !           258: static void gen_partset_reg(int opsize, int reg, int val)
        !           259: {
        !           260:     int tmp;
        !           261:     switch (opsize) {
        !           262:     case OS_BYTE:
        !           263:         gen_op_and32(reg, reg, gen_im32(0xffffff00));
        !           264:         tmp = gen_new_qreg(QMODE_I32);
        !           265:         gen_op_and32(tmp, val, gen_im32(0xff));
        !           266:         gen_op_or32(reg, reg, tmp);
        !           267:         break;
        !           268:     case OS_WORD:
        !           269:         gen_op_and32(reg, reg, gen_im32(0xffff0000));
        !           270:         tmp = gen_new_qreg(QMODE_I32);
        !           271:         gen_op_and32(tmp, val, gen_im32(0xffff));
        !           272:         gen_op_or32(reg, reg, tmp);
        !           273:         break;
        !           274:     case OS_LONG:
        !           275:         gen_op_mov32(reg, val);
        !           276:         break;
        !           277:     case OS_SINGLE:
        !           278:         gen_op_pack_32_f32(reg, val);
        !           279:         break;
        !           280:     default:
        !           281:         qemu_assert(0, "Bad operand size");
        !           282:         break;
        !           283:     }
        !           284: }
        !           285: 
        !           286: /* Sign or zero extend a value.  */
        !           287: static inline int gen_extend(int val, int opsize, int sign)
        !           288: {
        !           289:     int tmp;
        !           290: 
        !           291:     switch (opsize) {
        !           292:     case OS_BYTE:
        !           293:         tmp = gen_new_qreg(QMODE_I32);
        !           294:         if (sign)
        !           295:             gen_op_ext8s32(tmp, val);
        !           296:         else
        !           297:             gen_op_ext8u32(tmp, val);
        !           298:         break;
        !           299:     case OS_WORD:
        !           300:         tmp = gen_new_qreg(QMODE_I32);
        !           301:         if (sign)
        !           302:             gen_op_ext16s32(tmp, val);
        !           303:         else
        !           304:             gen_op_ext16u32(tmp, val);
        !           305:         break;
        !           306:     case OS_LONG:
        !           307:         tmp = val;
        !           308:         break;
        !           309:     case OS_SINGLE:
        !           310:         tmp = gen_new_qreg(QMODE_F32);
        !           311:         gen_op_pack_f32_32(tmp, val);
        !           312:         break;
        !           313:     default:
        !           314:         qemu_assert(0, "Bad operand size");
        !           315:     }
        !           316:     return tmp;
        !           317: }
        !           318: 
        !           319: /* Generate code for an "effective address".  Does not adjust the base
        !           320:    register for autoincrememnt addressing modes.  */
        !           321: static int gen_lea(DisasContext *s, uint16_t insn, int opsize)
        !           322: {
        !           323:     int reg;
        !           324:     int tmp;
        !           325:     uint16_t ext;
        !           326:     uint32_t offset;
        !           327: 
        !           328:     reg = insn & 7;
        !           329:     switch ((insn >> 3) & 7) {
        !           330:     case 0: /* Data register direct.  */
        !           331:     case 1: /* Address register direct.  */
        !           332:         /* ??? generate bad addressing mode fault.  */
        !           333:         qemu_assert(0, "invalid addressing mode");
        !           334:     case 2: /* Indirect register */
        !           335:     case 3: /* Indirect postincrement.  */
        !           336:         reg += QREG_A0;
        !           337:         return reg;
        !           338:     case 4: /* Indirect predecrememnt.  */
        !           339:         reg += QREG_A0;
        !           340:         tmp = gen_new_qreg(QMODE_I32);
        !           341:         gen_op_sub32(tmp, reg, gen_im32(opsize_bytes(opsize)));
        !           342:         return tmp;
        !           343:     case 5: /* Indirect displacement.  */
        !           344:         reg += QREG_A0;
        !           345:         tmp = gen_new_qreg(QMODE_I32);
        !           346:         ext = lduw(s->pc);
        !           347:         s->pc += 2;
        !           348:         gen_op_add32(tmp, reg, gen_im32((int16_t)ext));
        !           349:         return tmp;
        !           350:     case 6: /* Indirect index + displacement.  */
        !           351:         reg += QREG_A0;
        !           352:         return gen_lea_indexed(s, opsize, reg);
        !           353:     case 7: /* Other */
        !           354:         switch (reg) {
        !           355:         case 0: /* Absolute short.  */
        !           356:             offset = ldsw(s->pc);
        !           357:             s->pc += 2;
        !           358:             return gen_im32(offset);
        !           359:         case 1: /* Absolute long.  */
        !           360:             offset = read_im32(s);
        !           361:             return gen_im32(offset);
        !           362:         case 2: /* pc displacement  */
        !           363:             tmp = gen_new_qreg(QMODE_I32);
        !           364:             offset = s->pc;
        !           365:             offset += ldsw(s->pc);
        !           366:             s->pc += 2;
        !           367:             return gen_im32(offset);
        !           368:         case 3: /* pc index+displacement.  */
        !           369:             return gen_lea_indexed(s, opsize, -1);
        !           370:         case 4: /* Immediate.  */
        !           371:         default:
        !           372:             /* ??? generate bad addressing mode fault.  */
        !           373:             qemu_assert(0, "invalid addressing mode");
        !           374:         }
        !           375:     }
        !           376:     /* Should never happen.  */
        !           377:     return -1;
        !           378: }
        !           379: 
        !           380: /* Helper function for gen_ea. Reuse the computed address between the
        !           381:    for read/write operands.  */
        !           382: static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
        !           383:                               int val, int *addrp)
        !           384: {
        !           385:     int tmp;
        !           386: 
        !           387:     if (addrp && val > 0) {
        !           388:         tmp = *addrp;
        !           389:     } else {
        !           390:         tmp = gen_lea(s, insn, opsize);
        !           391:         if (addrp)
        !           392:             *addrp = tmp;
        !           393:     }
        !           394:     return gen_ldst(opsize, tmp, val);
        !           395: }
        !           396: 
        !           397: /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
        !           398:    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
        !           399:    ADDRP is non-null for readwrite operands.  */
        !           400: static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
        !           401:                   int *addrp)
        !           402: {
        !           403:     int reg;
        !           404:     int result;
        !           405:     uint32_t offset;
        !           406: 
        !           407:     reg = insn & 7;
        !           408:     switch ((insn >> 3) & 7) {
        !           409:     case 0: /* Data register direct.  */
        !           410:         reg += QREG_D0;
        !           411:         if (val > 0) {
        !           412:             gen_partset_reg(opsize, reg, val);
        !           413:             return 0;
        !           414:         } else {
        !           415:             return gen_extend(reg, opsize, val);
        !           416:         }
        !           417:     case 1: /* Address register direct.  */
        !           418:         reg += QREG_A0;
        !           419:         if (val > 0) {
        !           420:             gen_op_mov32(reg, val);
        !           421:             return 0;
        !           422:         } else {
        !           423:             return gen_extend(reg, opsize, val);
        !           424:         }
        !           425:     case 2: /* Indirect register */
        !           426:         reg += QREG_A0;
        !           427:         return gen_ldst(opsize, reg, val);
        !           428:     case 3: /* Indirect postincrement.  */
        !           429:         reg += QREG_A0;
        !           430:         result = gen_ldst(opsize, reg, val);
        !           431:         /* ??? This is not exception safe.  The instruction may still
        !           432:            fault after this point.  */
        !           433:         if (val > 0 || !addrp)
        !           434:             gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
        !           435:         return result;
        !           436:     case 4: /* Indirect predecrememnt.  */
        !           437:         {
        !           438:             int tmp;
        !           439:             if (addrp && val > 0) {
        !           440:                 tmp = *addrp;
        !           441:             } else {
        !           442:                 tmp = gen_lea(s, insn, opsize);
        !           443:                 if (addrp)
        !           444:                     *addrp = tmp;
        !           445:             }
        !           446:             result = gen_ldst(opsize, tmp, val);
        !           447:             /* ??? This is not exception safe.  The instruction may still
        !           448:                fault after this point.  */
        !           449:             if (val > 0 || !addrp) {
        !           450:                 reg += QREG_A0;
        !           451:                 gen_op_mov32(reg, tmp);
        !           452:             }
        !           453:         }
        !           454:         return result;
        !           455:     case 5: /* Indirect displacement.  */
        !           456:     case 6: /* Indirect index + displacement.  */
        !           457:         return gen_ea_once(s, insn, opsize, val, addrp);
        !           458:     case 7: /* Other */
        !           459:         switch (reg) {
        !           460:         case 0: /* Absolute short.  */
        !           461:         case 1: /* Absolute long.  */
        !           462:         case 2: /* pc displacement  */
        !           463:         case 3: /* pc index+displacement.  */
        !           464:             return gen_ea_once(s, insn, opsize, val, addrp);
        !           465:         case 4: /* Immediate.  */
        !           466:             /* Sign extend values for consistency.  */
        !           467:             switch (opsize) {
        !           468:             case OS_BYTE:
        !           469:                 if (val)
        !           470:                     offset = ldsb(s->pc + 1);
        !           471:                 else
        !           472:                     offset = ldub(s->pc + 1);
        !           473:                 s->pc += 2;
        !           474:                 break;
        !           475:             case OS_WORD:
        !           476:                 if (val)
        !           477:                     offset = ldsw(s->pc);
        !           478:                 else
        !           479:                     offset = lduw(s->pc);
        !           480:                 s->pc += 2;
        !           481:                 break;
        !           482:             case OS_LONG:
        !           483:                 offset = read_im32(s);
        !           484:                 break;
        !           485:             default:
        !           486:                 qemu_assert(0, "Bad immediate operand");
        !           487:             }
        !           488:             return gen_im32(offset);
        !           489:         default:
        !           490:             qemu_assert(0, "invalid addressing mode");
        !           491:         }
        !           492:     }
        !           493:     /* Should never happen.  */
        !           494:     return -1;
        !           495: }
        !           496: 
        !           497: static void gen_logic_cc(DisasContext *s, int val)
        !           498: {
        !           499:     gen_op_logic_cc(val);
        !           500:     s->cc_op = CC_OP_LOGIC;
        !           501: }
        !           502: 
        !           503: static void gen_jmpcc(DisasContext *s, int cond, int l1)
        !           504: {
        !           505:     int tmp;
        !           506: 
        !           507:     gen_flush_flags(s);
        !           508:     switch (cond) {
        !           509:     case 0: /* T */
        !           510:         gen_op_jmp(l1);
        !           511:         break;
        !           512:     case 1: /* F */
        !           513:         break;
        !           514:     case 2: /* HI (!C && !Z) */
        !           515:         tmp = gen_new_qreg(QMODE_I32);
        !           516:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
        !           517:         gen_op_jmp_z32(tmp, l1);
        !           518:         break;
        !           519:     case 3: /* LS (C || Z) */
        !           520:         tmp = gen_new_qreg(QMODE_I32);
        !           521:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
        !           522:         gen_op_jmp_nz32(tmp, l1);
        !           523:         break;
        !           524:     case 4: /* CC (!C) */
        !           525:         tmp = gen_new_qreg(QMODE_I32);
        !           526:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
        !           527:         gen_op_jmp_z32(tmp, l1);
        !           528:         break;
        !           529:     case 5: /* CS (C) */
        !           530:         tmp = gen_new_qreg(QMODE_I32);
        !           531:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
        !           532:         gen_op_jmp_nz32(tmp, l1);
        !           533:         break;
        !           534:     case 6: /* NE (!Z) */
        !           535:         tmp = gen_new_qreg(QMODE_I32);
        !           536:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
        !           537:         gen_op_jmp_z32(tmp, l1);
        !           538:         break;
        !           539:     case 7: /* EQ (Z) */
        !           540:         tmp = gen_new_qreg(QMODE_I32);
        !           541:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
        !           542:         gen_op_jmp_nz32(tmp, l1);
        !           543:         break;
        !           544:     case 8: /* VC (!V) */
        !           545:         tmp = gen_new_qreg(QMODE_I32);
        !           546:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
        !           547:         gen_op_jmp_z32(tmp, l1);
        !           548:         break;
        !           549:     case 9: /* VS (V) */
        !           550:         tmp = gen_new_qreg(QMODE_I32);
        !           551:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
        !           552:         gen_op_jmp_nz32(tmp, l1);
        !           553:         break;
        !           554:     case 10: /* PL (!N) */
        !           555:         tmp = gen_new_qreg(QMODE_I32);
        !           556:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
        !           557:         gen_op_jmp_z32(tmp, l1);
        !           558:         break;
        !           559:     case 11: /* MI (N) */
        !           560:         tmp = gen_new_qreg(QMODE_I32);
        !           561:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
        !           562:         gen_op_jmp_nz32(tmp, l1);
        !           563:         break;
        !           564:     case 12: /* GE (!(N ^ V)) */
        !           565:         tmp = gen_new_qreg(QMODE_I32);
        !           566:         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
        !           567:         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
        !           568:         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
        !           569:         gen_op_jmp_z32(tmp, l1);
        !           570:         break;
        !           571:     case 13: /* LT (N ^ V) */
        !           572:         tmp = gen_new_qreg(QMODE_I32);
        !           573:         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
        !           574:         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
        !           575:         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
        !           576:         gen_op_jmp_nz32(tmp, l1);
        !           577:         break;
        !           578:     case 14: /* GT (!(Z || (N ^ V))) */
        !           579:         {
        !           580:             int l2;
        !           581:             l2 = gen_new_label();
        !           582:             tmp = gen_new_qreg(QMODE_I32);
        !           583:             gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
        !           584:             gen_op_jmp_nz32(tmp, l2);
        !           585:             tmp = gen_new_qreg(QMODE_I32);
        !           586:             gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
        !           587:             gen_op_xor32(tmp, tmp, QREG_CC_DEST);
        !           588:             gen_op_and32(tmp, tmp, gen_im32(CCF_V));
        !           589:             gen_op_jmp_nz32(tmp, l2);
        !           590:             gen_op_jmp(l1);
        !           591:             gen_set_label(l2);
        !           592:         }
        !           593:         break;
        !           594:     case 15: /* LE (Z || (N ^ V)) */
        !           595:         tmp = gen_new_qreg(QMODE_I32);
        !           596:         gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
        !           597:         gen_op_jmp_nz32(tmp, l1);
        !           598:         tmp = gen_new_qreg(QMODE_I32);
        !           599:         gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
        !           600:         gen_op_xor32(tmp, tmp, QREG_CC_DEST);
        !           601:         gen_op_and32(tmp, tmp, gen_im32(CCF_V));
        !           602:         gen_op_jmp_nz32(tmp, l1);
        !           603:         break;
        !           604:     default:
        !           605:         /* Should ever happen.  */
        !           606:         abort();
        !           607:     }
        !           608: }
        !           609: 
        !           610: DISAS_INSN(scc)
        !           611: {
        !           612:     int l1;
        !           613:     int cond;
        !           614:     int reg;
        !           615: 
        !           616:     l1 = gen_new_label();
        !           617:     cond = (insn >> 8) & 0xf;
        !           618:     reg = DREG(insn, 0);
        !           619:     gen_op_and32(reg, reg, gen_im32(0xffffff00));
        !           620:     gen_jmpcc(s, cond ^ 1, l1);
        !           621:     gen_op_or32(reg, reg, gen_im32(0xff));
        !           622:     gen_set_label(l1);
        !           623: }
        !           624: 
        !           625: /* Generate a jump to to the address in qreg DEST.  */
        !           626: static void gen_jmp(DisasContext *s, int dest)
        !           627: {
        !           628:     gen_flush_cc_op(s);
        !           629:     gen_op_mov32(QREG_PC, dest);
        !           630:     s->is_jmp = DISAS_JUMP;
        !           631: }
        !           632: 
        !           633: static void gen_exception(DisasContext *s, uint32_t where, int nr)
        !           634: {
        !           635:     gen_flush_cc_op(s);
        !           636:     gen_jmp(s, gen_im32(where));
        !           637:     gen_op_raise_exception(nr);
        !           638: }
        !           639: 
        !           640: /* Generate a jump to an immediate address.  */
        !           641: static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
        !           642: {
        !           643:     TranslationBlock *tb;
        !           644: 
        !           645:     tb = s->tb;
        !           646:     if (__builtin_expect (s->singlestep_enabled, 0)) {
        !           647:         gen_exception(s, dest, EXCP_DEBUG);
        !           648:     } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
        !           649:                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
        !           650:         gen_op_goto_tb(0, n, (long)tb);
        !           651:         gen_op_mov32(QREG_PC, gen_im32(dest));
        !           652:         gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
        !           653:         gen_op_exit_tb();
        !           654:     } else {
        !           655:         gen_jmp(s, gen_im32(dest));
        !           656:         gen_op_mov32(QREG_T0, gen_im32(0));
        !           657:         gen_op_exit_tb();
        !           658:     }
        !           659:     s->is_jmp = DISAS_TB_JUMP;
        !           660: }
        !           661: 
        !           662: DISAS_INSN(undef_mac)
        !           663: {
        !           664:     gen_exception(s, s->pc - 2, EXCP_LINEA);
        !           665: }
        !           666: 
        !           667: DISAS_INSN(undef_fpu)
        !           668: {
        !           669:     gen_exception(s, s->pc - 2, EXCP_LINEF);
        !           670: }
        !           671: 
        !           672: DISAS_INSN(undef)
        !           673: {
        !           674:     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
        !           675:     cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
        !           676:               insn, s->pc - 2);
        !           677: }
        !           678: 
        !           679: DISAS_INSN(mulw)
        !           680: {
        !           681:     int reg;
        !           682:     int tmp;
        !           683:     int src;
        !           684:     int sign;
        !           685: 
        !           686:     sign = (insn & 0x100) != 0;
        !           687:     reg = DREG(insn, 9);
        !           688:     tmp = gen_new_qreg(QMODE_I32);
        !           689:     if (sign)
        !           690:         gen_op_ext16s32(tmp, reg);
        !           691:     else
        !           692:         gen_op_ext16u32(tmp, reg);
        !           693:     src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
        !           694:     gen_op_mul32(tmp, tmp, src);
        !           695:     gen_op_mov32(reg, tmp);
        !           696:     /* Unlike m68k, coldfire always clears the overflow bit.  */
        !           697:     gen_logic_cc(s, tmp);
        !           698: }
        !           699: 
        !           700: DISAS_INSN(divw)
        !           701: {
        !           702:     int reg;
        !           703:     int tmp;
        !           704:     int src;
        !           705:     int sign;
        !           706: 
        !           707:     sign = (insn & 0x100) != 0;
        !           708:     reg = DREG(insn, 9);
        !           709:     if (sign) {
        !           710:         gen_op_ext16s32(QREG_DIV1, reg);
        !           711:     } else {
        !           712:         gen_op_ext16u32(QREG_DIV1, reg);
        !           713:     }
        !           714:     src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
        !           715:     gen_op_mov32(QREG_DIV2, src);
        !           716:     if (sign) {
        !           717:         gen_op_divs(1);
        !           718:     } else {
        !           719:         gen_op_divu(1);
        !           720:     }
        !           721: 
        !           722:     tmp = gen_new_qreg(QMODE_I32);
        !           723:     src = gen_new_qreg(QMODE_I32);
        !           724:     gen_op_ext16u32(tmp, QREG_DIV1);
        !           725:     gen_op_shl32(src, QREG_DIV2, gen_im32(16));
        !           726:     gen_op_or32(reg, tmp, src);
        !           727:     gen_op_flags_set();
        !           728:     s->cc_op = CC_OP_FLAGS;
        !           729: }
        !           730: 
        !           731: DISAS_INSN(divl)
        !           732: {
        !           733:     int num;
        !           734:     int den;
        !           735:     int reg;
        !           736:     uint16_t ext;
        !           737: 
        !           738:     ext = lduw(s->pc);
        !           739:     s->pc += 2;
        !           740:     if (ext & 0x87f8) {
        !           741:         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
        !           742:         return;
        !           743:     }
        !           744:     num = DREG(ext, 12);
        !           745:     reg = DREG(ext, 0);
        !           746:     gen_op_mov32(QREG_DIV1, num);
        !           747:     den = gen_ea(s, insn, OS_LONG, 0, NULL);
        !           748:     gen_op_mov32(QREG_DIV2, den);
        !           749:     if (ext & 0x0800) {
        !           750:         gen_op_divs(2);
        !           751:     } else {
        !           752:         gen_op_divu(2);
        !           753:     }
        !           754:     if (num == reg) {
        !           755:         /* div */
        !           756:         gen_op_mov32 (reg, QREG_DIV1);
        !           757:     } else {
        !           758:         /* rem */
        !           759:         gen_op_mov32 (reg, QREG_DIV2);
        !           760:     }
        !           761:     gen_op_flags_set();
        !           762:     s->cc_op = CC_OP_FLAGS;
        !           763: }
        !           764: 
        !           765: DISAS_INSN(addsub)
        !           766: {
        !           767:     int reg;
        !           768:     int dest;
        !           769:     int src;
        !           770:     int tmp;
        !           771:     int addr;
        !           772:     int add;
        !           773: 
        !           774:     add = (insn & 0x4000) != 0;
        !           775:     reg = DREG(insn, 9);
        !           776:     dest = gen_new_qreg(QMODE_I32);
        !           777:     if (insn & 0x100) {
        !           778:         tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
        !           779:         src = reg;
        !           780:     } else {
        !           781:         tmp = reg;
        !           782:         src = gen_ea(s, insn, OS_LONG, 0, NULL);
        !           783:     }
        !           784:     if (add) {
        !           785:         gen_op_add32(dest, tmp, src);
        !           786:         gen_op_update_xflag_lt(dest, src);
        !           787:         s->cc_op = CC_OP_ADD;
        !           788:     } else {
        !           789:         gen_op_update_xflag_lt(tmp, src);
        !           790:         gen_op_sub32(dest, tmp, src);
        !           791:         s->cc_op = CC_OP_SUB;
        !           792:     }
        !           793:     gen_op_update_cc_add(dest, src);
        !           794:     if (insn & 0x100) {
        !           795:         gen_ea(s, insn, OS_LONG, dest, &addr);
        !           796:     } else {
        !           797:         gen_op_mov32(reg, dest);
        !           798:     }
        !           799: }
        !           800: 
        !           801: 
        !           802: /* Reverse the order of the bits in REG.  */
        !           803: DISAS_INSN(bitrev)
        !           804: {
        !           805:     int val;
        !           806:     int tmp1;
        !           807:     int tmp2;
        !           808:     int reg;
        !           809: 
        !           810:     val = gen_new_qreg(QMODE_I32);
        !           811:     tmp1 = gen_new_qreg(QMODE_I32);
        !           812:     tmp2 = gen_new_qreg(QMODE_I32);
        !           813:     reg = DREG(insn, 0);
        !           814:     gen_op_mov32(val, reg);
        !           815:     /* Reverse bits within each nibble.  */
        !           816:     gen_op_shl32(tmp1, val, gen_im32(3));
        !           817:     gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
        !           818:     gen_op_shl32(tmp2, val, gen_im32(1));
        !           819:     gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
        !           820:     gen_op_or32(tmp1, tmp1, tmp2);
        !           821:     gen_op_shr32(tmp2, val, gen_im32(1));
        !           822:     gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
        !           823:     gen_op_or32(tmp1, tmp1, tmp2);
        !           824:     gen_op_shr32(tmp2, val, gen_im32(3));
        !           825:     gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
        !           826:     gen_op_or32(tmp1, tmp1, tmp2);
        !           827:     /* Reverse nibbles withing bytes.  */
        !           828:     gen_op_shl32(val, tmp1, gen_im32(4));
        !           829:     gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
        !           830:     gen_op_shr32(tmp2, tmp1, gen_im32(4));
        !           831:     gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
        !           832:     gen_op_or32(val, val, tmp2);
        !           833:     /* Reverse bytes.  */
        !           834:     gen_op_bswap32(reg, val);
        !           835:     gen_op_mov32(reg, val);
        !           836: }
        !           837: 
        !           838: DISAS_INSN(bitop_reg)
        !           839: {
        !           840:     int opsize;
        !           841:     int op;
        !           842:     int src1;
        !           843:     int src2;
        !           844:     int tmp;
        !           845:     int addr;
        !           846:     int dest;
        !           847: 
        !           848:     if ((insn & 0x38) != 0)
        !           849:         opsize = OS_BYTE;
        !           850:     else
        !           851:         opsize = OS_LONG;
        !           852:     op = (insn >> 6) & 3;
        !           853:     src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
        !           854:     src2 = DREG(insn, 9);
        !           855:     dest = gen_new_qreg(QMODE_I32);
        !           856: 
        !           857:     gen_flush_flags(s);
        !           858:     tmp = gen_new_qreg(QMODE_I32);
        !           859:     if (opsize == OS_BYTE)
        !           860:         gen_op_and32(tmp, src2, gen_im32(7));
        !           861:     else
        !           862:         gen_op_and32(tmp, src2, gen_im32(31));
        !           863:     src2 = tmp;
        !           864:     tmp = gen_new_qreg(QMODE_I32);
        !           865:     gen_op_shl32(tmp, gen_im32(1), src2);
        !           866: 
        !           867:     gen_op_btest(src1, tmp);
        !           868:     switch (op) {
        !           869:     case 1: /* bchg */
        !           870:         gen_op_xor32(dest, src1, tmp);
        !           871:         break;
        !           872:     case 2: /* bclr */
        !           873:         gen_op_not32(tmp, tmp);
        !           874:         gen_op_and32(dest, src1, tmp);
        !           875:         break;
        !           876:     case 3: /* bset */
        !           877:         gen_op_or32(dest, src1, tmp);
        !           878:         break;
        !           879:     default: /* btst */
        !           880:         break;
        !           881:     }
        !           882:     if (op)
        !           883:         gen_ea(s, insn, opsize, dest, &addr);
        !           884: }
        !           885: 
        !           886: DISAS_INSN(sats)
        !           887: {
        !           888:     int reg;
        !           889:     int tmp;
        !           890:     int l1;
        !           891: 
        !           892:     reg = DREG(insn, 0);
        !           893:     tmp = gen_new_qreg(QMODE_I32);
        !           894:     gen_flush_flags(s);
        !           895:     gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
        !           896:     l1 = gen_new_label();
        !           897:     gen_op_jmp_z32(tmp, l1);
        !           898:     tmp = gen_new_qreg(QMODE_I32);
        !           899:     gen_op_shr32(tmp, reg, gen_im32(31));
        !           900:     gen_op_xor32(tmp, tmp, gen_im32(0x80000000));
        !           901:     gen_op_mov32(reg, tmp);
        !           902:     gen_set_label(l1);
        !           903:     gen_logic_cc(s, tmp);
        !           904: }
        !           905: 
        !           906: static void gen_push(int val)
        !           907: {
        !           908:     int tmp;
        !           909: 
        !           910:     tmp = gen_new_qreg(QMODE_I32);
        !           911:     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
        !           912:     gen_store(OS_LONG, tmp, val);
        !           913:     gen_op_mov32(QREG_SP, tmp);
        !           914: }
        !           915: 
        !           916: DISAS_INSN(movem)
        !           917: {
        !           918:     int addr;
        !           919:     int i;
        !           920:     uint16_t mask;
        !           921:     int reg;
        !           922:     int tmp;
        !           923:     int is_load;
        !           924: 
        !           925:     mask = lduw(s->pc);
        !           926:     s->pc += 2;
        !           927:     tmp = gen_lea(s, insn, OS_LONG);
        !           928:     addr = gen_new_qreg(QMODE_I32);
        !           929:     gen_op_mov32(addr, tmp);
        !           930:     is_load = ((insn & 0x0400) != 0);
        !           931:     for (i = 0; i < 16; i++, mask >>= 1) {
        !           932:         if (mask & 1) {
        !           933:             if (i < 8)
        !           934:                 reg = DREG(i, 0);
        !           935:             else
        !           936:                 reg = AREG(i, 0);
        !           937:             if (is_load) {
        !           938:                 tmp = gen_load(OS_LONG, addr, 0);
        !           939:                 gen_op_mov32(reg, tmp);
        !           940:             } else {
        !           941:                 gen_store(OS_LONG, addr, reg);
        !           942:             }
        !           943:             if (mask != 1)
        !           944:                 gen_op_add32(addr, addr, gen_im32(4));
        !           945:         }
        !           946:     }
        !           947: }
        !           948: 
        !           949: DISAS_INSN(bitop_im)
        !           950: {
        !           951:     int opsize;
        !           952:     int op;
        !           953:     int src1;
        !           954:     uint32_t mask;
        !           955:     int bitnum;
        !           956:     int tmp;
        !           957:     int addr;
        !           958:     int dest;
        !           959: 
        !           960:     if ((insn & 0x38) != 0)
        !           961:         opsize = OS_BYTE;
        !           962:     else
        !           963:         opsize = OS_LONG;
        !           964:     op = (insn >> 6) & 3;
        !           965: 
        !           966:     bitnum = lduw(s->pc);
        !           967:     s->pc += 2;
        !           968:     if (bitnum & 0xff00) {
        !           969:         disas_undef(s, insn);
        !           970:         return;
        !           971:     }
        !           972: 
        !           973:     src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
        !           974: 
        !           975:     gen_flush_flags(s);
        !           976:     tmp = gen_new_qreg(QMODE_I32);
        !           977:     if (opsize == OS_BYTE)
        !           978:         bitnum &= 7;
        !           979:     else
        !           980:         bitnum &= 31;
        !           981:     mask = 1 << bitnum;
        !           982: 
        !           983:     gen_op_btest(src1, gen_im32(mask));
        !           984:     if (op)
        !           985:         dest = gen_new_qreg(QMODE_I32);
        !           986:     else
        !           987:         dest = -1;
        !           988: 
        !           989:     switch (op) {
        !           990:     case 1: /* bchg */
        !           991:         gen_op_xor32(dest, src1, gen_im32(mask));
        !           992:         break;
        !           993:     case 2: /* bclr */
        !           994:         gen_op_and32(dest, src1, gen_im32(~mask));
        !           995:         break;
        !           996:     case 3: /* bset */
        !           997:         gen_op_or32(dest, src1, gen_im32(mask));
        !           998:         break;
        !           999:     default: /* btst */
        !          1000:         break;
        !          1001:     }
        !          1002:     if (op)
        !          1003:         gen_ea(s, insn, opsize, dest, &addr);
        !          1004: }
        !          1005: 
        !          1006: DISAS_INSN(arith_im)
        !          1007: {
        !          1008:     int op;
        !          1009:     int src1;
        !          1010:     int dest;
        !          1011:     int src2;
        !          1012:     int addr;
        !          1013: 
        !          1014:     op = (insn >> 9) & 7;
        !          1015:     src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
        !          1016:     src2 = gen_im32(read_im32(s));
        !          1017:     dest = gen_new_qreg(QMODE_I32);
        !          1018:     switch (op) {
        !          1019:     case 0: /* ori */
        !          1020:         gen_op_or32(dest, src1, src2);
        !          1021:         gen_logic_cc(s, dest);
        !          1022:         break;
        !          1023:     case 1: /* andi */
        !          1024:         gen_op_and32(dest, src1, src2);
        !          1025:         gen_logic_cc(s, dest);
        !          1026:         break;
        !          1027:     case 2: /* subi */
        !          1028:         gen_op_mov32(dest, src1);
        !          1029:         gen_op_update_xflag_lt(dest, src2);
        !          1030:         gen_op_sub32(dest, dest, src2);
        !          1031:         gen_op_update_cc_add(dest, src2);
        !          1032:         s->cc_op = CC_OP_SUB;
        !          1033:         break;
        !          1034:     case 3: /* addi */
        !          1035:         gen_op_mov32(dest, src1);
        !          1036:         gen_op_add32(dest, dest, src2);
        !          1037:         gen_op_update_cc_add(dest, src2);
        !          1038:         gen_op_update_xflag_lt(dest, src2);
        !          1039:         s->cc_op = CC_OP_ADD;
        !          1040:         break;
        !          1041:     case 5: /* eori */
        !          1042:         gen_op_xor32(dest, src1, src2);
        !          1043:         gen_logic_cc(s, dest);
        !          1044:         break;
        !          1045:     case 6: /* cmpi */
        !          1046:         gen_op_mov32(dest, src1);
        !          1047:         gen_op_sub32(dest, dest, src2);
        !          1048:         gen_op_update_cc_add(dest, src2);
        !          1049:         s->cc_op = CC_OP_SUB;
        !          1050:         break;
        !          1051:     default:
        !          1052:         abort();
        !          1053:     }
        !          1054:     if (op != 6) {
        !          1055:         gen_ea(s, insn, OS_LONG, dest, &addr);
        !          1056:     }
        !          1057: }
        !          1058: 
        !          1059: DISAS_INSN(byterev)
        !          1060: {
        !          1061:     int reg;
        !          1062: 
        !          1063:     reg = DREG(insn, 0);
        !          1064:     gen_op_bswap32(reg, reg);
        !          1065: }
        !          1066: 
        !          1067: DISAS_INSN(move)
        !          1068: {
        !          1069:     int src;
        !          1070:     int dest;
        !          1071:     int op;
        !          1072:     int opsize;
        !          1073: 
        !          1074:     switch (insn >> 12) {
        !          1075:     case 1: /* move.b */
        !          1076:         opsize = OS_BYTE;
        !          1077:         break;
        !          1078:     case 2: /* move.l */
        !          1079:         opsize = OS_LONG;
        !          1080:         break;
        !          1081:     case 3: /* move.w */
        !          1082:         opsize = OS_WORD;
        !          1083:         break;
        !          1084:     default:
        !          1085:         abort();
        !          1086:     }
        !          1087:     src = gen_ea(s, insn, opsize, -1, NULL);
        !          1088:     op = (insn >> 6) & 7;
        !          1089:     if (op == 1) {
        !          1090:         /* movea */
        !          1091:         /* The value will already have been sign extended.  */
        !          1092:         dest = AREG(insn, 9);
        !          1093:         gen_op_mov32(dest, src);
        !          1094:     } else {
        !          1095:         /* normal move */
        !          1096:         uint16_t dest_ea;
        !          1097:         dest_ea = ((insn >> 9) & 7) | (op << 3);
        !          1098:         gen_ea(s, dest_ea, opsize, src, NULL);
        !          1099:         /* This will be correct because loads sign extend.  */
        !          1100:         gen_logic_cc(s, src);
        !          1101:     }
        !          1102: }
        !          1103: 
        !          1104: DISAS_INSN(negx)
        !          1105: {
        !          1106:     int reg;
        !          1107:     int dest;
        !          1108:     int tmp;
        !          1109: 
        !          1110:     gen_flush_flags(s);
        !          1111:     reg = DREG(insn, 0);
        !          1112:     dest = gen_new_qreg(QMODE_I32);
        !          1113:     gen_op_mov32 (dest, gen_im32(0));
        !          1114:     gen_op_subx_cc(dest, reg);
        !          1115:     /* !Z is sticky.  */
        !          1116:     tmp = gen_new_qreg(QMODE_I32);
        !          1117:     gen_op_mov32 (tmp, QREG_CC_DEST);
        !          1118:     gen_op_update_cc_add(dest, reg);
        !          1119:     gen_op_mov32(reg, dest);
        !          1120:     s->cc_op = CC_OP_DYNAMIC;
        !          1121:     gen_flush_flags(s);
        !          1122:     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
        !          1123:     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
        !          1124:     s->cc_op = CC_OP_FLAGS;
        !          1125: }
        !          1126: 
        !          1127: DISAS_INSN(lea)
        !          1128: {
        !          1129:     int reg;
        !          1130:     int tmp;
        !          1131: 
        !          1132:     reg = AREG(insn, 9);
        !          1133:     tmp = gen_lea(s, insn, OS_LONG);
        !          1134:     gen_op_mov32(reg, tmp);
        !          1135: }
        !          1136: 
        !          1137: DISAS_INSN(clr)
        !          1138: {
        !          1139:     int opsize;
        !          1140: 
        !          1141:     switch ((insn >> 6) & 3) {
        !          1142:     case 0: /* clr.b */
        !          1143:         opsize = OS_BYTE;
        !          1144:         break;
        !          1145:     case 1: /* clr.w */
        !          1146:         opsize = OS_WORD;
        !          1147:         break;
        !          1148:     case 2: /* clr.l */
        !          1149:         opsize = OS_LONG;
        !          1150:         break;
        !          1151:     default:
        !          1152:         abort();
        !          1153:     }
        !          1154:     gen_ea (s, insn, opsize, gen_im32(0), NULL);
        !          1155:     gen_logic_cc(s, gen_im32(0));
        !          1156: }
        !          1157: 
        !          1158: DISAS_INSN(move_from_ccr)
        !          1159: {
        !          1160:     int reg;
        !          1161:     int dest;
        !          1162: 
        !          1163:     gen_flush_flags(s);
        !          1164:     dest = gen_new_qreg(QMODE_I32);
        !          1165:     gen_op_get_xflag(dest);
        !          1166:     gen_op_shl32(dest, dest, gen_im32(4));
        !          1167:     gen_op_or32(dest, dest, QREG_CC_DEST);
        !          1168:     reg = DREG(insn, 0);
        !          1169:     gen_partset_reg(OS_WORD, reg, dest);
        !          1170: }
        !          1171: 
        !          1172: DISAS_INSN(neg)
        !          1173: {
        !          1174:     int reg;
        !          1175:     int src1;
        !          1176: 
        !          1177:     reg = DREG(insn, 0);
        !          1178:     src1 = gen_new_qreg(QMODE_I32);
        !          1179:     gen_op_mov32(src1, reg);
        !          1180:     gen_op_neg32(reg, src1);
        !          1181:     s->cc_op = CC_OP_SUB;
        !          1182:     gen_op_update_cc_add(reg, src1);
        !          1183:     gen_op_update_xflag_lt(gen_im32(0), src1);
        !          1184:     s->cc_op = CC_OP_SUB;
        !          1185: }
        !          1186: 
        !          1187: DISAS_INSN(move_to_ccr)
        !          1188: {
        !          1189:     int src1;
        !          1190:     int reg;
        !          1191: 
        !          1192:     s->cc_op = CC_OP_FLAGS;
        !          1193:     if ((insn & 0x38) == 0)
        !          1194:       {
        !          1195:         src1 = gen_new_qreg(QMODE_I32);
        !          1196:         reg = DREG(insn, 0);
        !          1197:         gen_op_and32(src1, reg, gen_im32(0xf));
        !          1198:         gen_op_logic_cc(src1);
        !          1199:         gen_op_shr32(src1, reg, gen_im32(4));
        !          1200:         gen_op_and32(src1, src1, gen_im32(1));
        !          1201:         gen_op_update_xflag_tst(src1);
        !          1202:       }
        !          1203:     else if ((insn & 0x3f) != 0x3c)
        !          1204:       {
        !          1205:         uint8_t val;
        !          1206:         val = ldsb(s->pc);
        !          1207:         s->pc += 2;
        !          1208:         gen_op_logic_cc(gen_im32(val & 0xf));
        !          1209:         gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
        !          1210:       }
        !          1211:     else
        !          1212:         disas_undef(s, insn);
        !          1213: }
        !          1214: 
        !          1215: DISAS_INSN(not)
        !          1216: {
        !          1217:     int reg;
        !          1218: 
        !          1219:     reg = DREG(insn, 0);
        !          1220:     gen_op_not32(reg, reg);
        !          1221:     gen_logic_cc(s, reg);
        !          1222: }
        !          1223: 
        !          1224: DISAS_INSN(swap)
        !          1225: {
        !          1226:     int dest;
        !          1227:     int src1;
        !          1228:     int src2;
        !          1229:     int reg;
        !          1230: 
        !          1231:     dest = gen_new_qreg(QMODE_I32);
        !          1232:     src1 = gen_new_qreg(QMODE_I32);
        !          1233:     src2 = gen_new_qreg(QMODE_I32);
        !          1234:     reg = DREG(insn, 0);
        !          1235:     gen_op_shl32(src1, reg, gen_im32(16));
        !          1236:     gen_op_shr32(src2, reg, gen_im32(16));
        !          1237:     gen_op_or32(dest, src1, src2);
        !          1238:     gen_op_mov32(reg, dest);
        !          1239:     gen_logic_cc(s, dest);
        !          1240: }
        !          1241: 
        !          1242: DISAS_INSN(pea)
        !          1243: {
        !          1244:     int tmp;
        !          1245: 
        !          1246:     tmp = gen_lea(s, insn, OS_LONG);
        !          1247:     gen_push(tmp);
        !          1248: }
        !          1249: 
        !          1250: DISAS_INSN(ext)
        !          1251: {
        !          1252:     int reg;
        !          1253:     int op;
        !          1254:     int tmp;
        !          1255: 
        !          1256:     reg = DREG(insn, 0);
        !          1257:     op = (insn >> 6) & 7;
        !          1258:     tmp = gen_new_qreg(QMODE_I32);
        !          1259:     if (op == 3)
        !          1260:         gen_op_ext16s32(tmp, reg);
        !          1261:     else
        !          1262:         gen_op_ext8s32(tmp, reg);
        !          1263:     if (op == 2)
        !          1264:         gen_partset_reg(OS_WORD, reg, tmp);
        !          1265:     else
        !          1266:       gen_op_mov32(reg, tmp);
        !          1267:     gen_logic_cc(s, tmp);
        !          1268: }
        !          1269: 
        !          1270: DISAS_INSN(tst)
        !          1271: {
        !          1272:     int opsize;
        !          1273:     int tmp;
        !          1274: 
        !          1275:     switch ((insn >> 6) & 3) {
        !          1276:     case 0: /* tst.b */
        !          1277:         opsize = OS_BYTE;
        !          1278:         break;
        !          1279:     case 1: /* tst.w */
        !          1280:         opsize = OS_WORD;
        !          1281:         break;
        !          1282:     case 2: /* tst.l */
        !          1283:         opsize = OS_LONG;
        !          1284:         break;
        !          1285:     default:
        !          1286:         abort();
        !          1287:     }
        !          1288:     tmp = gen_ea(s, insn, opsize, -1, NULL);
        !          1289:     gen_logic_cc(s, tmp);
        !          1290: }
        !          1291: 
        !          1292: DISAS_INSN(pulse)
        !          1293: {
        !          1294:   /* Implemented as a NOP.  */
        !          1295: }
        !          1296: 
        !          1297: DISAS_INSN(illegal)
        !          1298: {
        !          1299:     gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
        !          1300: }
        !          1301: 
        !          1302: /* ??? This should be atomic.  */
        !          1303: DISAS_INSN(tas)
        !          1304: {
        !          1305:     int dest;
        !          1306:     int src1;
        !          1307:     int addr;
        !          1308: 
        !          1309:     dest = gen_new_qreg(QMODE_I32);
        !          1310:     src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
        !          1311:     gen_logic_cc(s, src1);
        !          1312:     gen_op_or32(dest, src1, gen_im32(0x80));
        !          1313:     gen_ea(s, insn, OS_BYTE, dest, &addr);
        !          1314: }
        !          1315: 
        !          1316: DISAS_INSN(mull)
        !          1317: {
        !          1318:     uint16_t ext;
        !          1319:     int reg;
        !          1320:     int src1;
        !          1321:     int dest;
        !          1322: 
        !          1323:     /* The upper 32 bits of the product are discarded, so
        !          1324:        muls.l and mulu.l are functionally equivalent.  */
        !          1325:     ext = lduw(s->pc);
        !          1326:     s->pc += 2;
        !          1327:     if (ext & 0x87ff) {
        !          1328:         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
        !          1329:         return;
        !          1330:     }
        !          1331:     reg = DREG(ext, 12);
        !          1332:     src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
        !          1333:     dest = gen_new_qreg(QMODE_I32);
        !          1334:     gen_op_mul32(dest, src1, reg);
        !          1335:     gen_op_mov32(reg, dest);
        !          1336:     /* Unlike m68k, coldfire always clears the overflow bit.  */
        !          1337:     gen_logic_cc(s, dest);
        !          1338: }
        !          1339: 
        !          1340: DISAS_INSN(link)
        !          1341: {
        !          1342:     int16_t offset;
        !          1343:     int reg;
        !          1344:     int tmp;
        !          1345: 
        !          1346:     offset = ldsw(s->pc);
        !          1347:     s->pc += 2;
        !          1348:     reg = AREG(insn, 0);
        !          1349:     tmp = gen_new_qreg(QMODE_I32);
        !          1350:     gen_op_sub32(tmp, QREG_SP, gen_im32(4));
        !          1351:     gen_store(OS_LONG, tmp, reg);
        !          1352:     if (reg != QREG_SP)
        !          1353:         gen_op_mov32(reg, tmp);
        !          1354:     gen_op_add32(QREG_SP, tmp, gen_im32(offset));
        !          1355: }
        !          1356: 
        !          1357: DISAS_INSN(unlk)
        !          1358: {
        !          1359:     int src;
        !          1360:     int reg;
        !          1361:     int tmp;
        !          1362: 
        !          1363:     src = gen_new_qreg(QMODE_I32);
        !          1364:     reg = AREG(insn, 0);
        !          1365:     gen_op_mov32(src, reg);
        !          1366:     tmp = gen_load(OS_LONG, src, 0);
        !          1367:     gen_op_mov32(reg, tmp);
        !          1368:     gen_op_add32(QREG_SP, src, gen_im32(4));
        !          1369: }
        !          1370: 
        !          1371: DISAS_INSN(nop)
        !          1372: {
        !          1373: }
        !          1374: 
        !          1375: DISAS_INSN(rts)
        !          1376: {
        !          1377:     int tmp;
        !          1378: 
        !          1379:     tmp = gen_load(OS_LONG, QREG_SP, 0);
        !          1380:     gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));
        !          1381:     gen_jmp(s, tmp);
        !          1382: }
        !          1383: 
        !          1384: DISAS_INSN(jump)
        !          1385: {
        !          1386:     int tmp;
        !          1387: 
        !          1388:     /* Load the target address first to ensure correct exception
        !          1389:        behavior.  */
        !          1390:     tmp = gen_lea(s, insn, OS_LONG);
        !          1391:     if ((insn & 0x40) == 0) {
        !          1392:         /* jsr */
        !          1393:         gen_push(gen_im32(s->pc));
        !          1394:     }
        !          1395:     gen_jmp(s, tmp);
        !          1396: }
        !          1397: 
        !          1398: DISAS_INSN(addsubq)
        !          1399: {
        !          1400:     int src1;
        !          1401:     int src2;
        !          1402:     int dest;
        !          1403:     int val;
        !          1404:     int addr;
        !          1405: 
        !          1406:     src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
        !          1407:     val = (insn >> 9) & 7;
        !          1408:     if (val == 0)
        !          1409:         val = 8;
        !          1410:     src2 = gen_im32(val);
        !          1411:     dest = gen_new_qreg(QMODE_I32);
        !          1412:     gen_op_mov32(dest, src1);
        !          1413:     if ((insn & 0x38) == 0x08) {
        !          1414:         /* Don't update condition codes if the destination is an
        !          1415:            address register.  */
        !          1416:         if (insn & 0x0100) {
        !          1417:             gen_op_sub32(dest, dest, src2);
        !          1418:         } else {
        !          1419:             gen_op_add32(dest, dest, src2);
        !          1420:         }
        !          1421:     } else {
        !          1422:         if (insn & 0x0100) {
        !          1423:             gen_op_update_xflag_lt(dest, src2);
        !          1424:             gen_op_sub32(dest, dest, src2);
        !          1425:             s->cc_op = CC_OP_SUB;
        !          1426:         } else {
        !          1427:             gen_op_add32(dest, dest, src2);
        !          1428:             gen_op_update_xflag_lt(dest, src2);
        !          1429:             s->cc_op = CC_OP_ADD;
        !          1430:         }
        !          1431:         gen_op_update_cc_add(dest, src2);
        !          1432:     }
        !          1433:     gen_ea(s, insn, OS_LONG, dest, &addr);
        !          1434: }
        !          1435: 
        !          1436: DISAS_INSN(tpf)
        !          1437: {
        !          1438:     switch (insn & 7) {
        !          1439:     case 2: /* One extension word.  */
        !          1440:         s->pc += 2;
        !          1441:         break;
        !          1442:     case 3: /* Two extension words.  */
        !          1443:         s->pc += 4;
        !          1444:         break;
        !          1445:     case 4: /* No extension words.  */
        !          1446:         break;
        !          1447:     default:
        !          1448:         disas_undef(s, insn);
        !          1449:     }
        !          1450: }
        !          1451: 
        !          1452: DISAS_INSN(branch)
        !          1453: {
        !          1454:     int32_t offset;
        !          1455:     uint32_t base;
        !          1456:     int op;
        !          1457:     int l1;
        !          1458:     
        !          1459:     base = s->pc;
        !          1460:     op = (insn >> 8) & 0xf;
        !          1461:     offset = (int8_t)insn;
        !          1462:     if (offset == 0) {
        !          1463:         offset = ldsw(s->pc);
        !          1464:         s->pc += 2;
        !          1465:     } else if (offset == -1) {
        !          1466:         offset = read_im32(s);
        !          1467:     }
        !          1468:     if (op == 1) {
        !          1469:         /* bsr */
        !          1470:         gen_push(gen_im32(s->pc));
        !          1471:     }
        !          1472:     gen_flush_cc_op(s);
        !          1473:     if (op > 1) {
        !          1474:         /* Bcc */
        !          1475:         l1 = gen_new_label();
        !          1476:         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
        !          1477:         gen_jmp_tb(s, 1, base + offset);
        !          1478:         gen_set_label(l1);
        !          1479:         gen_jmp_tb(s, 0, s->pc);
        !          1480:     } else {
        !          1481:         /* Unconditional branch.  */
        !          1482:         gen_jmp_tb(s, 0, base + offset);
        !          1483:     }
        !          1484: }
        !          1485: 
        !          1486: DISAS_INSN(moveq)
        !          1487: {
        !          1488:     int tmp;
        !          1489: 
        !          1490:     tmp = gen_im32((int8_t)insn);
        !          1491:     gen_op_mov32(DREG(insn, 9), tmp);
        !          1492:     gen_logic_cc(s, tmp);
        !          1493: }
        !          1494: 
        !          1495: DISAS_INSN(mvzs)
        !          1496: {
        !          1497:     int opsize;
        !          1498:     int src;
        !          1499:     int reg;
        !          1500: 
        !          1501:     if (insn & 0x40)
        !          1502:         opsize = OS_WORD;
        !          1503:     else
        !          1504:         opsize = OS_BYTE;
        !          1505:     src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
        !          1506:     reg = DREG(insn, 9);
        !          1507:     gen_op_mov32(reg, src);
        !          1508:     gen_logic_cc(s, src);
        !          1509: }
        !          1510: 
        !          1511: DISAS_INSN(or)
        !          1512: {
        !          1513:     int reg;
        !          1514:     int dest;
        !          1515:     int src;
        !          1516:     int addr;
        !          1517: 
        !          1518:     reg = DREG(insn, 9);
        !          1519:     dest = gen_new_qreg(QMODE_I32);
        !          1520:     if (insn & 0x100) {
        !          1521:         src = gen_ea(s, insn, OS_LONG, 0, &addr);
        !          1522:         gen_op_or32(dest, src, reg);
        !          1523:         gen_ea(s, insn, OS_LONG, dest, &addr);
        !          1524:     } else {
        !          1525:         src = gen_ea(s, insn, OS_LONG, 0, NULL);
        !          1526:         gen_op_or32(dest, src, reg);
        !          1527:         gen_op_mov32(reg, dest);
        !          1528:     }
        !          1529:     gen_logic_cc(s, dest);
        !          1530: }
        !          1531: 
        !          1532: DISAS_INSN(suba)
        !          1533: {
        !          1534:     int src;
        !          1535:     int reg;
        !          1536: 
        !          1537:     src = gen_ea(s, insn, OS_LONG, 0, NULL);
        !          1538:     reg = AREG(insn, 9);
        !          1539:     gen_op_sub32(reg, reg, src);
        !          1540: }
        !          1541: 
        !          1542: DISAS_INSN(subx)
        !          1543: {
        !          1544:     int reg;
        !          1545:     int src;
        !          1546:     int dest;
        !          1547:     int tmp;
        !          1548: 
        !          1549:     gen_flush_flags(s);
        !          1550:     reg = DREG(insn, 9);
        !          1551:     src = DREG(insn, 0);
        !          1552:     dest = gen_new_qreg(QMODE_I32);
        !          1553:     gen_op_mov32 (dest, reg);
        !          1554:     gen_op_subx_cc(dest, src);
        !          1555:     /* !Z is sticky.  */
        !          1556:     tmp = gen_new_qreg(QMODE_I32);
        !          1557:     gen_op_mov32 (tmp, QREG_CC_DEST);
        !          1558:     gen_op_update_cc_add(dest, src);
        !          1559:     gen_op_mov32(reg, dest);
        !          1560:     s->cc_op = CC_OP_DYNAMIC;
        !          1561:     gen_flush_flags(s);
        !          1562:     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
        !          1563:     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
        !          1564:     s->cc_op = CC_OP_FLAGS;
        !          1565: }
        !          1566: 
        !          1567: DISAS_INSN(mov3q)
        !          1568: {
        !          1569:     int src;
        !          1570:     int val;
        !          1571: 
        !          1572:     val = (insn >> 9) & 7;
        !          1573:     if (val == 0)
        !          1574:         val = -1;
        !          1575:     src = gen_im32(val);
        !          1576:     gen_logic_cc(s, src);
        !          1577:     gen_ea(s, insn, OS_LONG, src, NULL);
        !          1578: }
        !          1579: 
        !          1580: DISAS_INSN(cmp)
        !          1581: {
        !          1582:     int op;
        !          1583:     int src;
        !          1584:     int reg;
        !          1585:     int dest;
        !          1586:     int opsize;
        !          1587: 
        !          1588:     op = (insn >> 6) & 3;
        !          1589:     switch (op) {
        !          1590:     case 0: /* cmp.b */
        !          1591:         opsize = OS_BYTE;
        !          1592:         s->cc_op = CC_OP_CMPB;
        !          1593:         break;
        !          1594:     case 1: /* cmp.w */
        !          1595:         opsize = OS_WORD;
        !          1596:         s->cc_op = CC_OP_CMPW;
        !          1597:         break;
        !          1598:     case 2: /* cmp.l */
        !          1599:         opsize = OS_LONG;
        !          1600:         s->cc_op = CC_OP_SUB;
        !          1601:         break;
        !          1602:     default:
        !          1603:         abort();
        !          1604:     }
        !          1605:     src = gen_ea(s, insn, opsize, -1, NULL);
        !          1606:     reg = DREG(insn, 9);
        !          1607:     dest = gen_new_qreg(QMODE_I32);
        !          1608:     gen_op_sub32(dest, reg, src);
        !          1609:     gen_op_update_cc_add(dest, src);
        !          1610: }
        !          1611: 
        !          1612: DISAS_INSN(cmpa)
        !          1613: {
        !          1614:     int opsize;
        !          1615:     int src;
        !          1616:     int reg;
        !          1617:     int dest;
        !          1618: 
        !          1619:     if (insn & 0x100) {
        !          1620:         opsize = OS_LONG;
        !          1621:     } else {
        !          1622:         opsize = OS_WORD;
        !          1623:     }
        !          1624:     src = gen_ea(s, insn, opsize, -1, NULL);
        !          1625:     reg = AREG(insn, 9);
        !          1626:     dest = gen_new_qreg(QMODE_I32);
        !          1627:     gen_op_sub32(dest, reg, src);
        !          1628:     gen_op_update_cc_add(dest, src);
        !          1629:     s->cc_op = CC_OP_SUB;
        !          1630: }
        !          1631: 
        !          1632: DISAS_INSN(eor)
        !          1633: {
        !          1634:     int src;
        !          1635:     int reg;
        !          1636:     int dest;
        !          1637:     int addr;
        !          1638: 
        !          1639:     src = gen_ea(s, insn, OS_LONG, 0, &addr);
        !          1640:     reg = DREG(insn, 9);
        !          1641:     dest = gen_new_qreg(QMODE_I32);
        !          1642:     gen_op_xor32(dest, src, reg);
        !          1643:     gen_logic_cc(s, dest);
        !          1644:     gen_ea(s, insn, OS_LONG, dest, &addr);
        !          1645: }
        !          1646: 
        !          1647: DISAS_INSN(and)
        !          1648: {
        !          1649:     int src;
        !          1650:     int reg;
        !          1651:     int dest;
        !          1652:     int addr;
        !          1653: 
        !          1654:     reg = DREG(insn, 9);
        !          1655:     dest = gen_new_qreg(QMODE_I32);
        !          1656:     if (insn & 0x100) {
        !          1657:         src = gen_ea(s, insn, OS_LONG, 0, &addr);
        !          1658:         gen_op_and32(dest, src, reg);
        !          1659:         gen_ea(s, insn, OS_LONG, dest, &addr);
        !          1660:     } else {
        !          1661:         src = gen_ea(s, insn, OS_LONG, 0, NULL);
        !          1662:         gen_op_and32(dest, src, reg);
        !          1663:         gen_op_mov32(reg, dest);
        !          1664:     }
        !          1665:     gen_logic_cc(s, dest);
        !          1666: }
        !          1667: 
        !          1668: DISAS_INSN(adda)
        !          1669: {
        !          1670:     int src;
        !          1671:     int reg;
        !          1672: 
        !          1673:     src = gen_ea(s, insn, OS_LONG, 0, NULL);
        !          1674:     reg = AREG(insn, 9);
        !          1675:     gen_op_add32(reg, reg, src);
        !          1676: }
        !          1677: 
        !          1678: DISAS_INSN(addx)
        !          1679: {
        !          1680:     int reg;
        !          1681:     int src;
        !          1682:     int dest;
        !          1683:     int tmp;
        !          1684: 
        !          1685:     gen_flush_flags(s);
        !          1686:     reg = DREG(insn, 9);
        !          1687:     src = DREG(insn, 0);
        !          1688:     dest = gen_new_qreg(QMODE_I32);
        !          1689:     gen_op_mov32 (dest, reg);
        !          1690:     gen_op_addx_cc(dest, src);
        !          1691:     /* !Z is sticky.  */
        !          1692:     tmp = gen_new_qreg(QMODE_I32);
        !          1693:     gen_op_mov32 (tmp, QREG_CC_DEST);
        !          1694:     gen_op_update_cc_add(dest, src);
        !          1695:     gen_op_mov32(reg, dest);
        !          1696:     s->cc_op = CC_OP_DYNAMIC;
        !          1697:     gen_flush_flags(s);
        !          1698:     gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
        !          1699:     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
        !          1700:     s->cc_op = CC_OP_FLAGS;
        !          1701: }
        !          1702: 
        !          1703: DISAS_INSN(shift_im)
        !          1704: {
        !          1705:     int reg;
        !          1706:     int tmp;
        !          1707: 
        !          1708:     reg = DREG(insn, 0);
        !          1709:     tmp = (insn >> 9) & 7;
        !          1710:     if (tmp == 0)
        !          1711:       tmp = 8;
        !          1712:     if (insn & 0x100) {
        !          1713:         gen_op_shl_im_cc(reg, tmp);
        !          1714:         s->cc_op = CC_OP_SHL;
        !          1715:     } else {
        !          1716:         if (insn & 8) {
        !          1717:             gen_op_shr_im_cc(reg, tmp);
        !          1718:             s->cc_op = CC_OP_SHR;
        !          1719:         } else {
        !          1720:             gen_op_sar_im_cc(reg, tmp);
        !          1721:             s->cc_op = CC_OP_SAR;
        !          1722:         }
        !          1723:     }
        !          1724: }
        !          1725: 
        !          1726: DISAS_INSN(shift_reg)
        !          1727: {
        !          1728:     int reg;
        !          1729:     int src;
        !          1730:     int tmp;
        !          1731: 
        !          1732:     reg = DREG(insn, 0);
        !          1733:     src = DREG(insn, 9);
        !          1734:     tmp = gen_new_qreg(QMODE_I32);
        !          1735:     gen_op_and32(tmp, src, gen_im32(63));
        !          1736:     if (insn & 0x100) {
        !          1737:         gen_op_shl_cc(reg, tmp);
        !          1738:         s->cc_op = CC_OP_SHL;
        !          1739:     } else {
        !          1740:         if (insn & 8) {
        !          1741:             gen_op_shr_cc(reg, tmp);
        !          1742:             s->cc_op = CC_OP_SHR;
        !          1743:         } else {
        !          1744:             gen_op_sar_cc(reg, tmp);
        !          1745:             s->cc_op = CC_OP_SAR;
        !          1746:         }
        !          1747:     }
        !          1748: }
        !          1749: 
        !          1750: DISAS_INSN(ff1)
        !          1751: {
        !          1752:     cpu_abort(NULL, "Unimplemented insn: ff1");
        !          1753: }
        !          1754: 
        !          1755: DISAS_INSN(strldsr)
        !          1756: {
        !          1757:     uint16_t ext;
        !          1758:     uint32_t addr;
        !          1759: 
        !          1760:     addr = s->pc - 2;
        !          1761:     ext = lduw(s->pc);
        !          1762:     s->pc += 2;
        !          1763:     if (ext != 0x46FC)
        !          1764:         gen_exception(s, addr, EXCP_UNSUPPORTED);
        !          1765:     else
        !          1766:         gen_exception(s, addr, EXCP_PRIVILEGE);
        !          1767: }
        !          1768: 
        !          1769: DISAS_INSN(move_from_sr)
        !          1770: {
        !          1771:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1772: }
        !          1773: 
        !          1774: DISAS_INSN(move_to_sr)
        !          1775: {
        !          1776:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1777: }
        !          1778: 
        !          1779: DISAS_INSN(move_from_usp)
        !          1780: {
        !          1781:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1782: }
        !          1783: 
        !          1784: DISAS_INSN(move_to_usp)
        !          1785: {
        !          1786:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1787: }
        !          1788: 
        !          1789: DISAS_INSN(halt)
        !          1790: {
        !          1791:     gen_exception(s, s->pc, EXCP_HLT);
        !          1792: }
        !          1793: 
        !          1794: DISAS_INSN(stop)
        !          1795: {
        !          1796:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1797: }
        !          1798: 
        !          1799: DISAS_INSN(rte)
        !          1800: {
        !          1801:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1802: }
        !          1803: 
        !          1804: DISAS_INSN(movec)
        !          1805: {
        !          1806:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1807: }
        !          1808: 
        !          1809: DISAS_INSN(intouch)
        !          1810: {
        !          1811:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1812: }
        !          1813: 
        !          1814: DISAS_INSN(cpushl)
        !          1815: {
        !          1816:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1817: }
        !          1818: 
        !          1819: DISAS_INSN(wddata)
        !          1820: {
        !          1821:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1822: }
        !          1823: 
        !          1824: DISAS_INSN(wdebug)
        !          1825: {
        !          1826:     gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
        !          1827: }
        !          1828: 
        !          1829: DISAS_INSN(trap)
        !          1830: {
        !          1831:     gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));
        !          1832: }
        !          1833: 
        !          1834: /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
        !          1835:    immediately before the next FP instruction is executed.  */
        !          1836: DISAS_INSN(fpu)
        !          1837: {
        !          1838:     uint16_t ext;
        !          1839:     int opmode;
        !          1840:     int src;
        !          1841:     int dest;
        !          1842:     int res;
        !          1843:     int round;
        !          1844:     int opsize;
        !          1845: 
        !          1846:     ext = lduw(s->pc);
        !          1847:     s->pc += 2;
        !          1848:     opmode = ext & 0x7f;
        !          1849:     switch ((ext >> 13) & 7) {
        !          1850:     case 0: case 2:
        !          1851:         break;
        !          1852:     case 1:
        !          1853:         goto undef;
        !          1854:     case 3: /* fmove out */
        !          1855:         src = FREG(ext, 7);
        !          1856:         /* fmove */
        !          1857:         /* ??? TODO: Proper behavior on overflow.  */
        !          1858:         switch ((ext >> 10) & 7) {
        !          1859:         case 0:
        !          1860:             opsize = OS_LONG;
        !          1861:             res = gen_new_qreg(QMODE_I32);
        !          1862:             gen_op_f64_to_i32(res, src);
        !          1863:             break;
        !          1864:         case 1:
        !          1865:             opsize = OS_SINGLE;
        !          1866:             res = gen_new_qreg(QMODE_F32);
        !          1867:             gen_op_f64_to_f32(res, src);
        !          1868:             break;
        !          1869:         case 4:
        !          1870:             opsize = OS_WORD;
        !          1871:             res = gen_new_qreg(QMODE_I32);
        !          1872:             gen_op_f64_to_i32(res, src);
        !          1873:             break;
        !          1874:         case 5:
        !          1875:             opsize = OS_DOUBLE;
        !          1876:             res = src;
        !          1877:             break;
        !          1878:         case 6:
        !          1879:             opsize = OS_BYTE;
        !          1880:             res = gen_new_qreg(QMODE_I32);
        !          1881:             gen_op_f64_to_i32(res, src);
        !          1882:             break;
        !          1883:         default:
        !          1884:             goto undef;
        !          1885:         }
        !          1886:         gen_ea(s, insn, opsize, res, NULL);
        !          1887:         return;
        !          1888:     case 4: /* fmove to control register.  */
        !          1889:         switch ((ext >> 10) & 7) {
        !          1890:         case 4: /* FPCR */
        !          1891:             /* Not implemented.  Ignore writes.  */
        !          1892:             break;
        !          1893:         case 1: /* FPIAR */
        !          1894:         case 2: /* FPSR */
        !          1895:         default:
        !          1896:             cpu_abort(NULL, "Unimplemented: fmove to control %d",
        !          1897:                       (ext >> 10) & 7);
        !          1898:         }
        !          1899:         break;
        !          1900:     case 5: /* fmove from control register.  */
        !          1901:         switch ((ext >> 10) & 7) {
        !          1902:         case 4: /* FPCR */
        !          1903:             /* Not implemented.  Always return zero.  */
        !          1904:             res = gen_im32(0);
        !          1905:             break;
        !          1906:         case 1: /* FPIAR */
        !          1907:         case 2: /* FPSR */
        !          1908:         default:
        !          1909:             cpu_abort(NULL, "Unimplemented: fmove from control %d",
        !          1910:                       (ext >> 10) & 7);
        !          1911:             goto undef;
        !          1912:         }
        !          1913:         gen_ea(s, insn, OS_LONG, res, NULL);
        !          1914:         break;
        !          1915:     case 6: /* fmovem */ 
        !          1916:     case 7:
        !          1917:         {
        !          1918:         int addr;
        !          1919:         uint16_t mask;
        !          1920:         if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
        !          1921:             goto undef;
        !          1922:         src = gen_lea(s, insn, OS_LONG);
        !          1923:         addr = gen_new_qreg(QMODE_I32);
        !          1924:         gen_op_mov32(addr, src);
        !          1925:         mask = 0x80;
        !          1926:         dest = QREG_F0;
        !          1927:         while (mask) {
        !          1928:             if (ext & mask) {
        !          1929:                 if (ext & (1 << 13)) {
        !          1930:                     /* store */
        !          1931:                     gen_op_stf64(addr, dest);
        !          1932:                 } else {
        !          1933:                     /* load */
        !          1934:                     gen_op_ldf64(dest, addr);
        !          1935:                 }
        !          1936:                 if (ext & (mask - 1))
        !          1937:                     gen_op_add32(addr, addr, gen_im32(8));
        !          1938:             }
        !          1939:             mask >>= 1;
        !          1940:             dest++;
        !          1941:         }
        !          1942:         }
        !          1943:         return;
        !          1944:     }
        !          1945:     if (ext & (1 << 14)) {
        !          1946:         int tmp;
        !          1947: 
        !          1948:         /* Source effective address.  */
        !          1949:         switch ((ext >> 10) & 7) {
        !          1950:         case 0: opsize = OS_LONG; break;
        !          1951:         case 1: opsize = OS_SINGLE; break;
        !          1952:         case 4: opsize = OS_WORD; break;
        !          1953:         case 5: opsize = OS_DOUBLE; break;
        !          1954:         case 6: opsize = OS_BYTE; break;
        !          1955:         default:
        !          1956:             goto undef;
        !          1957:         }
        !          1958:         tmp = gen_ea(s, insn, opsize, -1, NULL);
        !          1959:         if (opsize == OS_DOUBLE) {
        !          1960:             src = tmp;
        !          1961:         } else {
        !          1962:             src = gen_new_qreg(QMODE_F64);
        !          1963:             switch (opsize) {
        !          1964:             case OS_LONG:
        !          1965:             case OS_WORD:
        !          1966:             case OS_BYTE:
        !          1967:                 gen_op_i32_to_f64(src, tmp);
        !          1968:                 break;
        !          1969:             case OS_SINGLE:
        !          1970:                 gen_op_f32_to_f64(src, tmp);
        !          1971:                 break;
        !          1972:             }
        !          1973:         }
        !          1974:     } else {
        !          1975:         /* Source register.  */
        !          1976:         src = FREG(ext, 10);
        !          1977:     }
        !          1978:     dest = FREG(ext, 7);
        !          1979:     res = gen_new_qreg(QMODE_F64);
        !          1980:     if (opmode != 0x3a)
        !          1981:         gen_op_movf64(res, dest);
        !          1982:     round = 1;
        !          1983:     switch (opmode) {
        !          1984:     case 0: case 0x40: case 0x44: /* fmove */
        !          1985:         gen_op_movf64(res, src);
        !          1986:         break;
        !          1987:     case 1: /* fint */
        !          1988:         gen_op_iround_f64(res, src);
        !          1989:         round = 0;
        !          1990:         break;
        !          1991:     case 3: /* fintrz */
        !          1992:         gen_op_itrunc_f64(res, src);
        !          1993:         round = 0;
        !          1994:         break;
        !          1995:     case 4: case 0x41: case 0x45: /* fsqrt */
        !          1996:         gen_op_sqrtf64(res, src);
        !          1997:         break;
        !          1998:     case 0x18: case 0x58: case 0x5c: /* fabs */
        !          1999:         gen_op_absf64(res, src);
        !          2000:         break;
        !          2001:     case 0x1a: case 0x5a: case 0x5e: /* fneg */
        !          2002:         gen_op_chsf64(res, src);
        !          2003:         break;
        !          2004:     case 0x20: case 0x60: case 0x64: /* fdiv */
        !          2005:         gen_op_divf64(res, res, src);
        !          2006:         break;
        !          2007:     case 0x22: case 0x62: case 0x66: /* fadd */
        !          2008:         gen_op_addf64(res, res, src);
        !          2009:         break;
        !          2010:     case 0x23: case 0x63: case 0x67: /* fmul */
        !          2011:         gen_op_mulf64(res, res, src);
        !          2012:         break;
        !          2013:     case 0x28: case 0x68: case 0x6c: /* fsub */
        !          2014:         gen_op_subf64(res, res, src);
        !          2015:         break;
        !          2016:     case 0x38: /* fcmp */
        !          2017:         gen_op_sub_cmpf64(res, res, src);
        !          2018:         dest = 0;
        !          2019:         round = 0;
        !          2020:         break;
        !          2021:     case 0x3a: /* ftst */
        !          2022:         gen_op_movf64(res, src);
        !          2023:         dest = 0;
        !          2024:         round = 0;
        !          2025:         break;
        !          2026:     default:
        !          2027:         goto undef;
        !          2028:     }
        !          2029:     if (round) {
        !          2030:         if (opmode & 0x40) {
        !          2031:             if ((opmode & 0x4) != 0)
        !          2032:                 round = 0;
        !          2033:         } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {
        !          2034:             round = 0;
        !          2035:         }
        !          2036:     }
        !          2037:     if (round) {
        !          2038:         int tmp;
        !          2039: 
        !          2040:         tmp = gen_new_qreg(QMODE_F32);
        !          2041:         gen_op_f64_to_f32(tmp, res);
        !          2042:         gen_op_f32_to_f64(res, tmp);
        !          2043:     } 
        !          2044:     gen_op_fp_result(res);
        !          2045:     if (dest) {
        !          2046:         gen_op_movf64(dest, res);
        !          2047:     }
        !          2048:     return;
        !          2049: undef:
        !          2050:     s->pc -= 2;
        !          2051:     disas_undef_fpu(s, insn);
        !          2052: }
        !          2053: 
        !          2054: DISAS_INSN(fbcc)
        !          2055: {
        !          2056:     uint32_t offset;
        !          2057:     uint32_t addr;
        !          2058:     int flag;
        !          2059:     int zero;
        !          2060:     int l1;
        !          2061: 
        !          2062:     addr = s->pc;
        !          2063:     offset = ldsw(s->pc);
        !          2064:     s->pc += 2;
        !          2065:     if (insn & (1 << 6)) {
        !          2066:         offset = (offset << 16) | lduw(s->pc);
        !          2067:         s->pc += 2;
        !          2068:     }
        !          2069: 
        !          2070:     l1 = gen_new_label();
        !          2071:     /* TODO: Raise BSUN exception.  */
        !          2072:     flag = gen_new_qreg(QMODE_I32);
        !          2073:     zero = gen_new_qreg(QMODE_F64);
        !          2074:     gen_op_zerof64(zero);
        !          2075:     gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
        !          2076:     /* Jump to l1 if condition is true.  */
        !          2077:     switch (insn & 0xf) {
        !          2078:     case 0: /* f */
        !          2079:         break;
        !          2080:     case 1: /* eq (=0) */
        !          2081:         gen_op_jmp_z32(flag, l1);
        !          2082:         break;
        !          2083:     case 2: /* ogt (=1) */
        !          2084:         gen_op_sub32(flag, flag, gen_im32(1));
        !          2085:         gen_op_jmp_z32(flag, l1);
        !          2086:         break;
        !          2087:     case 3: /* oge (=0 or =1) */
        !          2088:         gen_op_jmp_z32(flag, l1);
        !          2089:         gen_op_sub32(flag, flag, gen_im32(1));
        !          2090:         gen_op_jmp_z32(flag, l1);
        !          2091:         break;
        !          2092:     case 4: /* olt (=-1) */
        !          2093:         gen_op_jmp_s32(flag, l1);
        !          2094:         break;
        !          2095:     case 5: /* ole (=-1 or =0) */
        !          2096:         gen_op_jmp_s32(flag, l1);
        !          2097:         gen_op_jmp_z32(flag, l1);
        !          2098:         break;
        !          2099:     case 6: /* ogl (=-1 or =1) */
        !          2100:         gen_op_jmp_s32(flag, l1);
        !          2101:         gen_op_sub32(flag, flag, gen_im32(1));
        !          2102:         gen_op_jmp_z32(flag, l1);
        !          2103:         break;
        !          2104:     case 7: /* or (=2) */
        !          2105:         gen_op_sub32(flag, flag, gen_im32(2));
        !          2106:         gen_op_jmp_z32(flag, l1);
        !          2107:         break;
        !          2108:     case 8: /* un (<2) */
        !          2109:         gen_op_sub32(flag, flag, gen_im32(2));
        !          2110:         gen_op_jmp_s32(flag, l1);
        !          2111:         break;
        !          2112:     case 9: /* ueq (=0 or =2) */
        !          2113:         gen_op_jmp_z32(flag, l1);
        !          2114:         gen_op_sub32(flag, flag, gen_im32(2));
        !          2115:         gen_op_jmp_z32(flag, l1);
        !          2116:         break;
        !          2117:     case 10: /* ugt (>0) */
        !          2118:         /* ??? Add jmp_gtu.  */
        !          2119:         gen_op_sub32(flag, flag, gen_im32(1));
        !          2120:         gen_op_jmp_ns32(flag, l1);
        !          2121:         break;
        !          2122:     case 11: /* uge (>=0) */
        !          2123:         gen_op_jmp_ns32(flag, l1);
        !          2124:         break;
        !          2125:     case 12: /* ult (=-1 or =2) */
        !          2126:         gen_op_jmp_s32(flag, l1);
        !          2127:         gen_op_sub32(flag, flag, gen_im32(2));
        !          2128:         gen_op_jmp_z32(flag, l1);
        !          2129:         break;
        !          2130:     case 13: /* ule (!=1) */
        !          2131:         gen_op_sub32(flag, flag, gen_im32(1));
        !          2132:         gen_op_jmp_nz32(flag, l1);
        !          2133:         break;
        !          2134:     case 14: /* ne (!=0) */
        !          2135:         gen_op_jmp_nz32(flag, l1);
        !          2136:         break;
        !          2137:     case 15: /* t */
        !          2138:         gen_op_mov32(flag, gen_im32(1));
        !          2139:         break;
        !          2140:     }
        !          2141:     gen_jmp_tb(s, 0, s->pc);
        !          2142:     gen_set_label(l1);
        !          2143:     gen_jmp_tb(s, 1, addr + offset);
        !          2144: }
        !          2145: 
        !          2146: static disas_proc opcode_table[65536];
        !          2147: 
        !          2148: static void
        !          2149: register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
        !          2150: {
        !          2151:   int i;
        !          2152:   int from;
        !          2153:   int to;
        !          2154: 
        !          2155:   /* Sanity check.  All set bits must be included in the mask.  */
        !          2156:   if (opcode & ~mask)
        !          2157:       abort();
        !          2158:   /* This could probably be cleverer.  For now just optimize the case where
        !          2159:      the top bits are known.  */
        !          2160:   /* Find the first zero bit in the mask.  */
        !          2161:   i = 0x8000;
        !          2162:   while ((i & mask) != 0)
        !          2163:       i >>= 1;
        !          2164:   /* Iterate over all combinations of this and lower bits.  */
        !          2165:   if (i == 0)
        !          2166:       i = 1;
        !          2167:   else
        !          2168:       i <<= 1;
        !          2169:   from = opcode & ~(i - 1);
        !          2170:   to = from + i;
        !          2171:   for (i = from; i < to; i++)
        !          2172:     {
        !          2173:       if ((i & mask) == opcode)
        !          2174:           opcode_table[i] = proc;
        !          2175:     }
        !          2176: }
        !          2177: 
        !          2178: /* Register m68k opcode handlers.  Order is important.
        !          2179:    Later insn override earlier ones.  */
        !          2180: static void
        !          2181: register_m68k_insns (m68k_def_t *def)
        !          2182: {
        !          2183:     uint32_t iflags;
        !          2184: 
        !          2185:     iflags = def->insns;
        !          2186: #define INSN(name, opcode, mask, isa) \
        !          2187:     if (iflags & M68K_INSN_##isa) \
        !          2188:         register_opcode(disas_##name, 0x##opcode, 0x##mask)
        !          2189:     INSN(undef,     0000, 0000, CF_A);
        !          2190:     INSN(arith_im,  0080, fff8, CF_A);
        !          2191:     INSN(bitrev,    00c0, fff8, CF_C);
        !          2192:     INSN(bitop_reg, 0100, f1c0, CF_A);
        !          2193:     INSN(bitop_reg, 0140, f1c0, CF_A);
        !          2194:     INSN(bitop_reg, 0180, f1c0, CF_A);
        !          2195:     INSN(bitop_reg, 01c0, f1c0, CF_A);
        !          2196:     INSN(arith_im,  0280, fff8, CF_A);
        !          2197:     INSN(byterev,   02c0, fff8, CF_A);
        !          2198:     INSN(arith_im,  0480, fff8, CF_A);
        !          2199:     INSN(ff1,       04c0, fff8, CF_C);
        !          2200:     INSN(arith_im,  0680, fff8, CF_A);
        !          2201:     INSN(bitop_im,  0800, ffc0, CF_A);
        !          2202:     INSN(bitop_im,  0840, ffc0, CF_A);
        !          2203:     INSN(bitop_im,  0880, ffc0, CF_A);
        !          2204:     INSN(bitop_im,  08c0, ffc0, CF_A);
        !          2205:     INSN(arith_im,  0a80, fff8, CF_A);
        !          2206:     INSN(arith_im,  0c00, ff38, CF_A);
        !          2207:     INSN(move,      1000, f000, CF_A);
        !          2208:     INSN(move,      2000, f000, CF_A);
        !          2209:     INSN(move,      3000, f000, CF_A);
        !          2210:     INSN(strldsr,   40e7, ffff, CF_A);
        !          2211:     INSN(negx,      4080, fff8, CF_A);
        !          2212:     INSN(move_from_sr, 40c0, fff8, CF_A);
        !          2213:     INSN(lea,       41c0, f1c0, CF_A);
        !          2214:     INSN(clr,       4200, ff00, CF_A);
        !          2215:     INSN(undef,     42c0, ffc0, CF_A);
        !          2216:     INSN(move_from_ccr, 42c0, fff8, CF_A);
        !          2217:     INSN(neg,       4480, fff8, CF_A);
        !          2218:     INSN(move_to_ccr, 44c0, ffc0, CF_A);
        !          2219:     INSN(not,       4680, fff8, CF_A);
        !          2220:     INSN(move_to_sr, 46c0, ffc0, CF_A);
        !          2221:     INSN(pea,       4840, ffc0, CF_A);
        !          2222:     INSN(swap,      4840, fff8, CF_A);
        !          2223:     INSN(movem,     48c0, fbc0, CF_A);
        !          2224:     INSN(ext,       4880, fff8, CF_A);
        !          2225:     INSN(ext,       48c0, fff8, CF_A);
        !          2226:     INSN(ext,       49c0, fff8, CF_A);
        !          2227:     INSN(tst,       4a00, ff00, CF_A);
        !          2228:     INSN(tas,       4ac0, ffc0, CF_B);
        !          2229:     INSN(halt,      4ac8, ffff, CF_A);
        !          2230:     INSN(pulse,     4acc, ffff, CF_A);
        !          2231:     INSN(illegal,   4afc, ffff, CF_A);
        !          2232:     INSN(mull,      4c00, ffc0, CF_A);
        !          2233:     INSN(divl,      4c40, ffc0, CF_A);
        !          2234:     INSN(sats,      4c80, fff8, CF_B);
        !          2235:     INSN(trap,      4e40, fff0, CF_A);
        !          2236:     INSN(link,      4e50, fff8, CF_A);
        !          2237:     INSN(unlk,      4e58, fff8, CF_A);
        !          2238:     INSN(move_to_usp, 4e60, fff8, CF_B);
        !          2239:     INSN(move_from_usp, 4e68, fff8, CF_B);
        !          2240:     INSN(nop,       4e71, ffff, CF_A);
        !          2241:     INSN(stop,      4e72, ffff, CF_A);
        !          2242:     INSN(rte,       4e73, ffff, CF_A);
        !          2243:     INSN(rts,       4e75, ffff, CF_A);
        !          2244:     INSN(movec,     4e7b, ffff, CF_A);
        !          2245:     INSN(jump,      4e80, ffc0, CF_A);
        !          2246:     INSN(jump,      4ec0, ffc0, CF_A);
        !          2247:     INSN(addsubq,   5180, f1c0, CF_A);
        !          2248:     INSN(scc,       50c0, f0f8, CF_A);
        !          2249:     INSN(addsubq,   5080, f1c0, CF_A);
        !          2250:     INSN(tpf,       51f8, fff8, CF_A);
        !          2251:     INSN(branch,    6000, f000, CF_A);
        !          2252:     INSN(moveq,     7000, f100, CF_A);
        !          2253:     INSN(mvzs,      7100, f100, CF_B);
        !          2254:     INSN(or,        8000, f000, CF_A);
        !          2255:     INSN(divw,      80c0, f0c0, CF_A);
        !          2256:     INSN(addsub,    9000, f000, CF_A);
        !          2257:     INSN(subx,      9180, f1f8, CF_A);
        !          2258:     INSN(suba,      91c0, f1c0, CF_A);
        !          2259:     INSN(undef_mac, a000, f000, CF_A);
        !          2260:     INSN(mov3q,     a140, f1c0, CF_B);
        !          2261:     INSN(cmp,       b000, f1c0, CF_B); /* cmp.b */
        !          2262:     INSN(cmp,       b040, f1c0, CF_B); /* cmp.w */
        !          2263:     INSN(cmpa,      b0c0, f1c0, CF_B); /* cmpa.w */
        !          2264:     INSN(cmp,       b080, f1c0, CF_A);
        !          2265:     INSN(cmpa,      b1c0, f1c0, CF_A);
        !          2266:     INSN(eor,       b180, f1c0, CF_A);
        !          2267:     INSN(and,       c000, f000, CF_A);
        !          2268:     INSN(mulw,      c0c0, f0c0, CF_A);
        !          2269:     INSN(addsub,    d000, f000, CF_A);
        !          2270:     INSN(addx,      d180, f1f8, CF_A);
        !          2271:     INSN(adda,      d1c0, f1c0, CF_A);
        !          2272:     INSN(shift_im,  e080, f0f0, CF_A);
        !          2273:     INSN(shift_reg, e0a0, f0f0, CF_A);
        !          2274:     INSN(undef_fpu, f000, f000, CF_A);
        !          2275:     INSN(fpu,       f200, ffc0, CF_FPU);
        !          2276:     INSN(fbcc,      f280, ffc0, CF_FPU);
        !          2277:     INSN(intouch,   f340, ffc0, CF_A);
        !          2278:     INSN(cpushl,    f428, ff38, CF_A);
        !          2279:     INSN(wddata,    fb00, ff00, CF_A);
        !          2280:     INSN(wdebug,    fbc0, ffc0, CF_A);
        !          2281: #undef INSN
        !          2282: }
        !          2283: 
        !          2284: /* ??? Some of this implementation is not exception safe.  We should always
        !          2285:    write back the result to memory before setting the condition codes.  */
        !          2286: static void disas_m68k_insn(CPUState * env, DisasContext *s)
        !          2287: {
        !          2288:     uint16_t insn;
        !          2289: 
        !          2290:     insn = lduw(s->pc);
        !          2291:     s->pc += 2;
        !          2292: 
        !          2293:     opcode_table[insn](s, insn);
        !          2294: }
        !          2295: 
        !          2296: #if 0
        !          2297: /* Save the result of a floating point operation.  */
        !          2298: static void expand_op_fp_result(qOP *qop)
        !          2299: {
        !          2300:     gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
        !          2301: }
        !          2302: 
        !          2303: /* Dummy op to indicate that the flags have been set.  */
        !          2304: static void expand_op_flags_set(qOP *qop)
        !          2305: {
        !          2306: }
        !          2307: 
        !          2308: /* Convert the confition codes into CC_OP_FLAGS format.  */
        !          2309: static void expand_op_flush_flags(qOP *qop)
        !          2310: {
        !          2311:     int cc_opreg;
        !          2312: 
        !          2313:     if (qop->args[0] == CC_OP_DYNAMIC)
        !          2314:         cc_opreg = QREG_CC_OP;
        !          2315:     else
        !          2316:         cc_opreg = gen_im32(qop->args[0]);
        !          2317:     gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
        !          2318: }
        !          2319: 
        !          2320: /* Set CC_DEST after a logical or direct flag setting operation.  */
        !          2321: static void expand_op_logic_cc(qOP *qop)
        !          2322: {
        !          2323:     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
        !          2324: }
        !          2325: 
        !          2326: /* Set CC_SRC and CC_DEST after an arithmetic operation.  */
        !          2327: static void expand_op_update_cc_add(qOP *qop)
        !          2328: {
        !          2329:     gen_op_mov32(QREG_CC_DEST, qop->args[0]);
        !          2330:     gen_op_mov32(QREG_CC_SRC, qop->args[1]);
        !          2331: }
        !          2332: 
        !          2333: /* Update the X flag.  */
        !          2334: static void expand_op_update_xflag(qOP *qop)
        !          2335: {
        !          2336:     int arg0;
        !          2337:     int arg1;
        !          2338: 
        !          2339:     arg0 = qop->args[0];
        !          2340:     arg1 = qop->args[1];
        !          2341:     if (arg1 == QREG_NULL) {
        !          2342:         /* CC_X = arg0.  */
        !          2343:         gen_op_mov32(QREG_CC_X, arg0);
        !          2344:     } else {
        !          2345:         /* CC_X = arg0 < (unsigned)arg1.  */
        !          2346:         gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
        !          2347:     }
        !          2348: }
        !          2349: 
        !          2350: /* Set arg0 to the contents of the X flag.  */
        !          2351: static void expand_op_get_xflag(qOP *qop)
        !          2352: {
        !          2353:     gen_op_mov32(qop->args[0], QREG_CC_X);
        !          2354: }
        !          2355: 
        !          2356: /* Expand a shift by immediate.  The ISA only allows shifts by 1-8, so we
        !          2357:    already know the shift is within range.  */
        !          2358: static inline void expand_shift_im(qOP *qop, int right, int arith)
        !          2359: {
        !          2360:     int val;
        !          2361:     int reg;
        !          2362:     int tmp;
        !          2363:     int im;
        !          2364: 
        !          2365:     reg = qop->args[0];
        !          2366:     im = qop->args[1];
        !          2367:     tmp = gen_im32(im);
        !          2368:     val = gen_new_qreg(QMODE_I32);
        !          2369:     gen_op_mov32(val, reg);
        !          2370:     gen_op_mov32(QREG_CC_DEST, val);
        !          2371:     gen_op_mov32(QREG_CC_SRC, tmp);
        !          2372:     if (right) {
        !          2373:         if (arith) {
        !          2374:             gen_op_sar32(reg, val, tmp);
        !          2375:         } else {
        !          2376:             gen_op_shr32(reg, val, tmp);
        !          2377:         }
        !          2378:         if (im == 1)
        !          2379:             tmp = QREG_NULL;
        !          2380:         else
        !          2381:             tmp = gen_im32(im - 1);
        !          2382:     } else {
        !          2383:         gen_op_shl32(reg, val, tmp);
        !          2384:         tmp = gen_im32(32 - im);
        !          2385:     }
        !          2386:     if (tmp != QREG_NULL)
        !          2387:         gen_op_shr32(val, val, tmp);
        !          2388:     gen_op_and32(QREG_CC_X, val, gen_im32(1));
        !          2389: }
        !          2390: 
        !          2391: static void expand_op_shl_im_cc(qOP *qop)
        !          2392: {
        !          2393:     expand_shift_im(qop, 0, 0);
        !          2394: }
        !          2395: 
        !          2396: static void expand_op_shr_im_cc(qOP *qop)
        !          2397: {
        !          2398:     expand_shift_im(qop, 1, 0);
        !          2399: }
        !          2400: 
        !          2401: static void expand_op_sar_im_cc(qOP *qop)
        !          2402: {
        !          2403:     expand_shift_im(qop, 1, 1);
        !          2404: }
        !          2405: 
        !          2406: /* Expand a shift by register.  */
        !          2407: /* ??? This gives incorrect answers for shifts by 0 or >= 32 */
        !          2408: static inline void expand_shift_reg(qOP *qop, int right, int arith)
        !          2409: {
        !          2410:     int val;
        !          2411:     int reg;
        !          2412:     int shift;
        !          2413:     int tmp;
        !          2414: 
        !          2415:     reg = qop->args[0];
        !          2416:     shift = qop->args[1];
        !          2417:     val = gen_new_qreg(QMODE_I32);
        !          2418:     gen_op_mov32(val, reg);
        !          2419:     gen_op_mov32(QREG_CC_DEST, val);
        !          2420:     gen_op_mov32(QREG_CC_SRC, shift);
        !          2421:     tmp = gen_new_qreg(QMODE_I32);
        !          2422:     if (right) {
        !          2423:         if (arith) {
        !          2424:             gen_op_sar32(reg, val, shift);
        !          2425:         } else {
        !          2426:             gen_op_shr32(reg, val, shift);
        !          2427:         }
        !          2428:         gen_op_sub32(tmp, shift, gen_im32(1));
        !          2429:     } else {
        !          2430:         gen_op_shl32(reg, val, shift);
        !          2431:         gen_op_sub32(tmp, gen_im32(31), shift);
        !          2432:     }
        !          2433:     gen_op_shl32(val, val, tmp);
        !          2434:     gen_op_and32(QREG_CC_X, val, gen_im32(1));
        !          2435: }
        !          2436: 
        !          2437: static void expand_op_shl_cc(qOP *qop)
        !          2438: {
        !          2439:     expand_shift_reg(qop, 0, 0);
        !          2440: }
        !          2441: 
        !          2442: static void expand_op_shr_cc(qOP *qop)
        !          2443: {
        !          2444:     expand_shift_reg(qop, 1, 0);
        !          2445: }
        !          2446: 
        !          2447: static void expand_op_sar_cc(qOP *qop)
        !          2448: {
        !          2449:     expand_shift_reg(qop, 1, 1);
        !          2450: }
        !          2451: 
        !          2452: /* Set the Z flag to (arg0 & arg1) == 0.  */
        !          2453: static void expand_op_btest(qOP *qop)
        !          2454: {
        !          2455:     int tmp;
        !          2456:     int l1;
        !          2457: 
        !          2458:     l1 = gen_new_label();
        !          2459:     tmp = gen_new_qreg(QMODE_I32);
        !          2460:     gen_op_and32(tmp, qop->args[0], qop->args[1]);
        !          2461:     gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
        !          2462:     gen_op_jmp_nz32(tmp, l1);
        !          2463:     gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
        !          2464:     gen_op_label(l1);
        !          2465: }
        !          2466: 
        !          2467: /* arg0 += arg1 + CC_X */
        !          2468: static void expand_op_addx_cc(qOP *qop)
        !          2469: {
        !          2470:     int arg0 = qop->args[0];
        !          2471:     int arg1 = qop->args[1];
        !          2472:     int l1, l2;
        !          2473:     
        !          2474:     gen_op_add32 (arg0, arg0, arg1);
        !          2475:     l1 = gen_new_label();
        !          2476:     l2 = gen_new_label();
        !          2477:     gen_op_jmp_z32(QREG_CC_X, l1);
        !          2478:     gen_op_add32(arg0, arg0, gen_im32(1));
        !          2479:     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
        !          2480:     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
        !          2481:     gen_op_jmp(l2);
        !          2482:     gen_set_label(l1);
        !          2483:     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
        !          2484:     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
        !          2485:     gen_set_label(l2);
        !          2486: }
        !          2487: 
        !          2488: /* arg0 -= arg1 + CC_X */
        !          2489: static void expand_op_subx_cc(qOP *qop)
        !          2490: {
        !          2491:     int arg0 = qop->args[0];
        !          2492:     int arg1 = qop->args[1];
        !          2493:     int l1, l2;
        !          2494: 
        !          2495:     l1 = gen_new_label();
        !          2496:     l2 = gen_new_label();
        !          2497:     gen_op_jmp_z32(QREG_CC_X, l1);
        !          2498:     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
        !          2499:     gen_op_sub32(arg0, arg0, gen_im32(1));
        !          2500:     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
        !          2501:     gen_op_jmp(l2);
        !          2502:     gen_set_label(l1);
        !          2503:     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
        !          2504:     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
        !          2505:     gen_set_label(l2);
        !          2506:     gen_op_sub32 (arg0, arg0, arg1);
        !          2507: }
        !          2508: 
        !          2509: /* Expand target specific ops to generic qops.  */
        !          2510: static void expand_target_qops(void)
        !          2511: {
        !          2512:     qOP *qop;
        !          2513:     qOP *next;
        !          2514:     int c;
        !          2515: 
        !          2516:     /* Copy the list of qops, expanding target specific ops as we go.  */
        !          2517:     qop = gen_first_qop;
        !          2518:     gen_first_qop = NULL;
        !          2519:     gen_last_qop = NULL;
        !          2520:     for (; qop; qop = next) {
        !          2521:         c = qop->opcode;
        !          2522:         next = qop->next;
        !          2523:         if (c < FIRST_TARGET_OP) {
        !          2524:             qop->prev = gen_last_qop;
        !          2525:             qop->next = NULL;
        !          2526:             if (gen_last_qop)
        !          2527:                 gen_last_qop->next = qop;
        !          2528:             else
        !          2529:                 gen_first_qop = qop;
        !          2530:             gen_last_qop = qop;
        !          2531:             continue;
        !          2532:         }
        !          2533:         switch (c) {
        !          2534: #define DEF(name, nargs, barrier) \
        !          2535:         case INDEX_op_##name: \
        !          2536:             expand_op_##name(qop); \
        !          2537:             break;
        !          2538: #include "qop-target.def"
        !          2539: #undef DEF
        !          2540:         default:
        !          2541:             cpu_abort(NULL, "Unexpanded target qop");
        !          2542:         }
        !          2543:     }
        !          2544: }
        !          2545: 
        !          2546: /* ??? Implement this.  */
        !          2547: static void
        !          2548: optimize_flags(void)
        !          2549: {
        !          2550: }
        !          2551: #endif
        !          2552: 
        !          2553: /* generate intermediate code for basic block 'tb'.  */
        !          2554: int gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
        !          2555:                                    int search_pc)
        !          2556: {
        !          2557:     DisasContext dc1, *dc = &dc1;
        !          2558:     uint16_t *gen_opc_end;
        !          2559:     int j, lj;
        !          2560:     target_ulong pc_start;
        !          2561:     int pc_offset;
        !          2562:     int last_cc_op;
        !          2563: 
        !          2564:     /* generate intermediate code */
        !          2565:     pc_start = tb->pc;
        !          2566:        
        !          2567:     dc->tb = tb;
        !          2568: 
        !          2569:     gen_opc_ptr = gen_opc_buf;
        !          2570:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
        !          2571:     gen_opparam_ptr = gen_opparam_buf;
        !          2572: 
        !          2573:     dc->is_jmp = DISAS_NEXT;
        !          2574:     dc->pc = pc_start;
        !          2575:     dc->cc_op = CC_OP_DYNAMIC;
        !          2576:     dc->singlestep_enabled = env->singlestep_enabled;
        !          2577:     dc->fpcr = env->fpcr;
        !          2578:     nb_gen_labels = 0;
        !          2579:     lj = -1;
        !          2580:     do {
        !          2581:         free_qreg = 0;
        !          2582:         pc_offset = dc->pc - pc_start;
        !          2583:         gen_throws_exception = NULL;
        !          2584:         if (env->nb_breakpoints > 0) {
        !          2585:             for(j = 0; j < env->nb_breakpoints; j++) {
        !          2586:                 if (env->breakpoints[j] == dc->pc) {
        !          2587:                     gen_exception(dc, dc->pc, EXCP_DEBUG);
        !          2588:                     dc->is_jmp = DISAS_JUMP;
        !          2589:                     break;
        !          2590:                 }
        !          2591:             }
        !          2592:             if (dc->is_jmp)
        !          2593:                 break;
        !          2594:         }
        !          2595:         if (search_pc) {
        !          2596:             j = gen_opc_ptr - gen_opc_buf;
        !          2597:             if (lj < j) {
        !          2598:                 lj++;
        !          2599:                 while (lj < j)
        !          2600:                     gen_opc_instr_start[lj++] = 0;
        !          2601:             }
        !          2602:             gen_opc_pc[lj] = dc->pc;
        !          2603:             gen_opc_instr_start[lj] = 1;
        !          2604:         }
        !          2605:         last_cc_op = dc->cc_op;
        !          2606:        disas_m68k_insn(env, dc);
        !          2607:     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
        !          2608:              !env->singlestep_enabled &&
        !          2609:              (pc_offset) < (TARGET_PAGE_SIZE - 32));
        !          2610: 
        !          2611:     if (__builtin_expect(env->singlestep_enabled, 0)) {
        !          2612:         /* Make sure the pc is updated, and raise a debug exception.  */
        !          2613:         if (!dc->is_jmp) {
        !          2614:             gen_flush_cc_op(dc);
        !          2615:             gen_op_mov32(QREG_PC, gen_im32((long)dc->pc));
        !          2616:         }
        !          2617:         gen_op_raise_exception(EXCP_DEBUG);
        !          2618:     } else {
        !          2619:         switch(dc->is_jmp) {
        !          2620:         case DISAS_NEXT:
        !          2621:             gen_flush_cc_op(dc);
        !          2622:             gen_jmp_tb(dc, 0, dc->pc);
        !          2623:             break;
        !          2624:         default:
        !          2625:         case DISAS_JUMP:
        !          2626:         case DISAS_UPDATE:
        !          2627:             gen_flush_cc_op(dc);
        !          2628:             /* indicate that the hash table must be used to find the next TB */
        !          2629:             gen_op_mov32(QREG_T0, gen_im32(0));
        !          2630:             gen_op_exit_tb();
        !          2631:             break;
        !          2632:         case DISAS_TB_JUMP:
        !          2633:             /* nothing more to generate */
        !          2634:             break;
        !          2635:         }
        !          2636:     }
        !          2637:     *gen_opc_ptr = INDEX_op_end;
        !          2638: 
        !          2639: #ifdef DEBUG_DISAS
        !          2640:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          2641:         fprintf(logfile, "----------------\n");
        !          2642:         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
        !          2643:         target_disas(logfile, pc_start, dc->pc - pc_start, 0);
        !          2644:         fprintf(logfile, "\n");
        !          2645:         if (loglevel & (CPU_LOG_TB_OP)) {
        !          2646:             fprintf(logfile, "OP:\n");
        !          2647:             dump_ops(gen_opc_buf, gen_opparam_buf);
        !          2648:             fprintf(logfile, "\n");
        !          2649:         }
        !          2650:     }
        !          2651: #endif
        !          2652:     if (search_pc) {
        !          2653:         j = gen_opc_ptr - gen_opc_buf;
        !          2654:         lj++;
        !          2655:         while (lj <= j)
        !          2656:             gen_opc_instr_start[lj++] = 0;
        !          2657:         tb->size = 0;
        !          2658:     } else {
        !          2659:         tb->size = dc->pc - pc_start;
        !          2660:     }
        !          2661: 
        !          2662:     //optimize_flags();
        !          2663:     //expand_target_qops();
        !          2664:     return 0;
        !          2665: }
        !          2666: 
        !          2667: int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
        !          2668: {
        !          2669:     return gen_intermediate_code_internal(env, tb, 0);
        !          2670: }
        !          2671: 
        !          2672: int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
        !          2673: {
        !          2674:     return gen_intermediate_code_internal(env, tb, 1);
        !          2675: }
        !          2676: 
        !          2677: CPUM68KState *cpu_m68k_init(void)
        !          2678: {
        !          2679:     CPUM68KState *env;
        !          2680: 
        !          2681:     env = malloc(sizeof(CPUM68KState));
        !          2682:     if (!env)
        !          2683:         return NULL;
        !          2684:     cpu_exec_init(env);
        !          2685: 
        !          2686:     memset(env, 0, sizeof(CPUM68KState));
        !          2687:     /* ??? FP regs should be initialized to NaN.  */
        !          2688:     cpu_single_env = env;
        !          2689:     env->cc_op = CC_OP_FLAGS;
        !          2690:     return env;
        !          2691: }
        !          2692: 
        !          2693: void cpu_m68k_close(CPUM68KState *env)
        !          2694: {
        !          2695:     free(env);
        !          2696: }
        !          2697: 
        !          2698: m68k_def_t *m68k_find_by_name(const char *name)
        !          2699: {
        !          2700:     m68k_def_t *def;
        !          2701: 
        !          2702:     def = m68k_cpu_defs;
        !          2703:     while (def->name)
        !          2704:       {
        !          2705:         if (strcmp(def->name, name) == 0)
        !          2706:             return def;
        !          2707:         def++;
        !          2708:       }
        !          2709:     return NULL;
        !          2710: }
        !          2711: 
        !          2712: void cpu_m68k_register(CPUM68KState *env, m68k_def_t *def)
        !          2713: {
        !          2714:     register_m68k_insns(def);
        !          2715: }
        !          2716: 
        !          2717: void cpu_dump_state(CPUState *env, FILE *f, 
        !          2718:                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
        !          2719:                     int flags)
        !          2720: {
        !          2721:     int i;
        !          2722:     uint16_t sr;
        !          2723:     CPU_DoubleU u;
        !          2724:     for (i = 0; i < 8; i++)
        !          2725:       {
        !          2726:         u.d = env->fregs[i];
        !          2727:         cpu_fprintf (f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
        !          2728:                      i, env->dregs[i], i, env->aregs[i],
        !          2729:                      i, u.l.upper, u.l.lower, u.d);
        !          2730:       }
        !          2731:     cpu_fprintf (f, "PC = %08x   ", env->pc);
        !          2732:     sr = env->sr;
        !          2733:     cpu_fprintf (f, "SR = %04x %c%c%c%c%c ", sr, (sr & 0x10) ? 'X' : '-',
        !          2734:                  (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
        !          2735:                  (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
        !          2736:     cpu_fprintf (f, "FPRESULT = %12g\n", env->fp_result);
        !          2737: }
        !          2738: 
        !          2739: /* ??? */
        !          2740: target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
        !          2741: {
        !          2742:     return addr;
        !          2743: }
        !          2744: 
        !          2745: #if defined(CONFIG_USER_ONLY) 
        !          2746: 
        !          2747: int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
        !          2748:                                int is_user, int is_softmmu)
        !          2749: {
        !          2750:     env->exception_index = EXCP_ACCESS;
        !          2751:     env->mmu.ar = address;
        !          2752:     return 1;
        !          2753: }
        !          2754: 
        !          2755: #else
        !          2756: 
        !          2757: #error not implemented
        !          2758: 
        !          2759: #endif

unix.superglobalmegacorp.com

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