Annotation of tme/ic/m68k/m68k-insns-auto.c, revision 1.1

1.1     ! root        1: /* automatically generated by m68k-insns-auto.sh, do not edit! */
        !             2: _TME_RCSID("$Id: m68k-insns-auto.sh,v 1.19 2003/05/16 21:48:11 fredette Exp $");
        !             3: 
        !             4: #include "m68k-impl.h"
        !             5: 
        !             6: 
        !             7: /* this does a 8-bit "add SRC, DST": */
        !             8: TME_M68K_INSN(tme_m68k_add8)
        !             9: {
        !            10:   tme_uint8_t res, op0, op1;
        !            11:   tme_uint8_t flags;
        !            12: 
        !            13:   /* load the operand(s): */
        !            14:   op0 = *((tme_uint8_t *) _op0);
        !            15:   op1 = *((tme_uint8_t *) _op1);
        !            16: 
        !            17:   /* perform the operation: */
        !            18:   res = op1 + op0;
        !            19: 
        !            20:   /* store the result: */
        !            21:   *((tme_uint8_t *) _op1) = res;
        !            22: 
        !            23:   /* set the flags: */
        !            24:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !            25:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !            26:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !            27:   if (op0 > (op1 ^ 0xff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !            28:   ic->tme_m68k_ireg_ccr = flags;
        !            29: 
        !            30:   TME_M68K_INSN_OK;
        !            31: }
        !            32: 
        !            33: /* this does a 8-bit "sub SRC, DST": */
        !            34: TME_M68K_INSN(tme_m68k_sub8)
        !            35: {
        !            36:   tme_uint8_t res, op0, op1;
        !            37:   tme_uint8_t flags;
        !            38: 
        !            39:   /* load the operand(s): */
        !            40:   op0 = *((tme_uint8_t *) _op0);
        !            41:   op1 = *((tme_uint8_t *) _op1);
        !            42: 
        !            43:   /* perform the operation: */
        !            44:   res = op1 - op0;
        !            45: 
        !            46:   /* store the result: */
        !            47:   *((tme_uint8_t *) _op1) = res;
        !            48: 
        !            49:   /* set the flags: */
        !            50:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !            51:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !            52:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !            53:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !            54:   ic->tme_m68k_ireg_ccr = flags;
        !            55: 
        !            56:   TME_M68K_INSN_OK;
        !            57: }
        !            58: 
        !            59: /* this does a 8-bit "cmp SRC, DST": */
        !            60: TME_M68K_INSN(tme_m68k_cmp8)
        !            61: {
        !            62:   tme_uint8_t res, op0, op1;
        !            63:   tme_uint8_t flags;
        !            64: 
        !            65:   /* load the operand(s): */
        !            66:   op0 = *((tme_uint8_t *) _op0);
        !            67:   op1 = *((tme_uint8_t *) _op1);
        !            68: 
        !            69:   /* perform the operation: */
        !            70:   res = op1 - op0;
        !            71: 
        !            72:   /* set the flags: */
        !            73:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !            74:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !            75:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !            76:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !            77:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !            78:   ic->tme_m68k_ireg_ccr = flags;
        !            79: 
        !            80:   TME_M68K_INSN_OK;
        !            81: }
        !            82: 
        !            83: /* this does a 8-bit "neg DST": */
        !            84: TME_M68K_INSN(tme_m68k_neg8)
        !            85: {
        !            86:   tme_uint8_t res, op1;
        !            87:   tme_uint8_t flags;
        !            88: 
        !            89:   /* load the operand(s): */
        !            90:   op1 = *((tme_uint8_t *) _op1);
        !            91: 
        !            92:   /* perform the operation: */
        !            93:   res = 0 - op1;
        !            94: 
        !            95:   /* store the result: */
        !            96:   *((tme_uint8_t *) _op1) = res;
        !            97: 
        !            98:   /* set the flags: */
        !            99:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           100:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           101:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !           102:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !           103:   ic->tme_m68k_ireg_ccr = flags;
        !           104: 
        !           105:   TME_M68K_INSN_OK;
        !           106: }
        !           107: 
        !           108: /* this does a 8-bit "or SRC, DST": */
        !           109: TME_M68K_INSN(tme_m68k_or8)
        !           110: {
        !           111:   tme_uint8_t res, op0, op1;
        !           112:   tme_uint8_t flags;
        !           113: 
        !           114:   /* load the operand(s): */
        !           115:   op0 = *((tme_uint8_t *) _op0);
        !           116:   op1 = *((tme_uint8_t *) _op1);
        !           117: 
        !           118:   /* perform the operation: */
        !           119:   res = op1 | op0;
        !           120: 
        !           121:   /* store the result: */
        !           122:   *((tme_uint8_t *) _op1) = res;
        !           123: 
        !           124:   /* set the flags: */
        !           125:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           126:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           127:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           128:   ic->tme_m68k_ireg_ccr = flags;
        !           129: 
        !           130:   TME_M68K_INSN_OK;
        !           131: }
        !           132: 
        !           133: /* this does a 8-bit "and SRC, DST": */
        !           134: TME_M68K_INSN(tme_m68k_and8)
        !           135: {
        !           136:   tme_uint8_t res, op0, op1;
        !           137:   tme_uint8_t flags;
        !           138: 
        !           139:   /* load the operand(s): */
        !           140:   op0 = *((tme_uint8_t *) _op0);
        !           141:   op1 = *((tme_uint8_t *) _op1);
        !           142: 
        !           143:   /* perform the operation: */
        !           144:   res = op1 & op0;
        !           145: 
        !           146:   /* store the result: */
        !           147:   *((tme_uint8_t *) _op1) = res;
        !           148: 
        !           149:   /* set the flags: */
        !           150:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           151:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           152:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           153:   ic->tme_m68k_ireg_ccr = flags;
        !           154: 
        !           155:   TME_M68K_INSN_OK;
        !           156: }
        !           157: 
        !           158: /* this does a 8-bit "eor SRC, DST": */
        !           159: TME_M68K_INSN(tme_m68k_eor8)
        !           160: {
        !           161:   tme_uint8_t res, op0, op1;
        !           162:   tme_uint8_t flags;
        !           163: 
        !           164:   /* load the operand(s): */
        !           165:   op0 = *((tme_uint8_t *) _op0);
        !           166:   op1 = *((tme_uint8_t *) _op1);
        !           167: 
        !           168:   /* perform the operation: */
        !           169:   res = op1 ^ op0;
        !           170: 
        !           171:   /* store the result: */
        !           172:   *((tme_uint8_t *) _op1) = res;
        !           173: 
        !           174:   /* set the flags: */
        !           175:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           176:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           177:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           178:   ic->tme_m68k_ireg_ccr = flags;
        !           179: 
        !           180:   TME_M68K_INSN_OK;
        !           181: }
        !           182: 
        !           183: /* this does a 8-bit "not DST": */
        !           184: TME_M68K_INSN(tme_m68k_not8)
        !           185: {
        !           186:   tme_uint8_t res, op1;
        !           187:   tme_uint8_t flags;
        !           188: 
        !           189:   /* load the operand(s): */
        !           190:   op1 = *((tme_uint8_t *) _op1);
        !           191: 
        !           192:   /* perform the operation: */
        !           193:   res = ~ op1;
        !           194: 
        !           195:   /* store the result: */
        !           196:   *((tme_uint8_t *) _op1) = res;
        !           197: 
        !           198:   /* set the flags: */
        !           199:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           200:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           201:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           202:   ic->tme_m68k_ireg_ccr = flags;
        !           203: 
        !           204:   TME_M68K_INSN_OK;
        !           205: }
        !           206: 
        !           207: /* this does a 8-bit "tst DST": */
        !           208: TME_M68K_INSN(tme_m68k_tst8)
        !           209: {
        !           210:   tme_uint8_t res, op1;
        !           211:   tme_uint8_t flags;
        !           212: 
        !           213:   /* load the operand(s): */
        !           214:   op1 = *((tme_uint8_t *) _op1);
        !           215: 
        !           216:   /* perform the operation: */
        !           217:   res = op1;
        !           218: 
        !           219:   /* set the flags: */
        !           220:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           221:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           222:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           223:   ic->tme_m68k_ireg_ccr = flags;
        !           224: 
        !           225:   TME_M68K_INSN_OK;
        !           226: }
        !           227: 
        !           228: /* this does a 8-bit "move DST": */
        !           229: TME_M68K_INSN(tme_m68k_move8)
        !           230: {
        !           231:   tme_uint8_t res, op1;
        !           232:   tme_uint8_t flags;
        !           233: 
        !           234:   /* load the operand(s): */
        !           235:   op1 = *((tme_uint8_t *) _op1);
        !           236: 
        !           237:   /* perform the operation: */
        !           238:   res = op1;
        !           239: 
        !           240:   /* store the result: */
        !           241:   *((tme_uint8_t *) _op0) = res;
        !           242: 
        !           243:   /* set the flags: */
        !           244:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           245:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           246:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           247:   ic->tme_m68k_ireg_ccr = flags;
        !           248: 
        !           249:   TME_M68K_INSN_OK;
        !           250: }
        !           251: 
        !           252: /* this does a 8-bit "clr DST": */
        !           253: TME_M68K_INSN(tme_m68k_clr8)
        !           254: {
        !           255:   tme_uint8_t res;
        !           256:   tme_uint8_t flags;
        !           257: 
        !           258:   /* load the operand(s): */
        !           259: 
        !           260:   /* perform the operation: */
        !           261:   res = 0;
        !           262: 
        !           263:   /* store the result: */
        !           264:   *((tme_uint8_t *) _op1) = res;
        !           265: 
        !           266:   /* set the flags: */
        !           267:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           268:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           269:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           270:   ic->tme_m68k_ireg_ccr = flags;
        !           271: 
        !           272:   TME_M68K_INSN_OK;
        !           273: }
        !           274: 
        !           275: /* this does a 8-bit "negx DST": */
        !           276: TME_M68K_INSN(tme_m68k_negx8)
        !           277: {
        !           278:   tme_uint8_t res, op1;
        !           279:   tme_uint8_t flags;
        !           280: 
        !           281:   /* load the operand(s): */
        !           282:   op1 = *((tme_uint8_t *) _op1);
        !           283: 
        !           284:   /* perform the operation: */
        !           285:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !           286: 
        !           287:   /* store the result: */
        !           288:   *((tme_uint8_t *) _op1) = res;
        !           289: 
        !           290:   /* set the flags: */
        !           291:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           292:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !           293:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !           294:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !           295:   ic->tme_m68k_ireg_ccr = flags;
        !           296: 
        !           297:   TME_M68K_INSN_OK;
        !           298: }
        !           299: 
        !           300: /* this does a 8-bit "addx SRC, DST": */
        !           301: TME_M68K_INSN(tme_m68k_addx8)
        !           302: {
        !           303:   tme_uint8_t res, op0, op1;
        !           304:   tme_uint8_t flags;
        !           305: 
        !           306:   /* load the operand(s): */
        !           307:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !           308:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !           309:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !           310:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
        !           311:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
        !           312:   tme_uint16_t memory;
        !           313: 
        !           314:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !           315:   if (memory) {
        !           316:     TME_M68K_INSN_CANFAULT;
        !           317:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           318:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !           319:       ic->_tme_m68k_ea_function_code = function_code;
        !           320:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !           321:     }
        !           322:     tme_m68k_read_memx8(ic);
        !           323:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           324:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !           325:       ic->_tme_m68k_ea_function_code = function_code;
        !           326:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !           327:     }
        !           328:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
        !           329:     op1 = ic->tme_m68k_ireg_memx8;
        !           330:     op0 = ic->tme_m68k_ireg_memy8;
        !           331:   }
        !           332:   else {
        !           333:     op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2);
        !           334:     op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2);
        !           335:   }
        !           336: 
        !           337:   /* perform the operation: */
        !           338:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !           339: 
        !           340:   /* store the result: */
        !           341:   if (memory) {
        !           342:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           343:       ic->tme_m68k_ireg_memx8 = res;
        !           344:       ic->_tme_m68k_ea_function_code = function_code;
        !           345:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !           346:     }
        !           347:     tme_m68k_write_memx8(ic);
        !           348:   }
        !           349:   else {
        !           350:     ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res;
        !           351:   }
        !           352: 
        !           353:   /* set the flags: */
        !           354:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           355:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !           356:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !           357:   if (op0 > (op1 ^ 0xff) || (op0 == (op1 ^ 0xff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !           358:   ic->tme_m68k_ireg_ccr = flags;
        !           359: 
        !           360:   TME_M68K_INSN_OK;
        !           361: }
        !           362: 
        !           363: /* this does a 8-bit "subx SRC, DST": */
        !           364: TME_M68K_INSN(tme_m68k_subx8)
        !           365: {
        !           366:   tme_uint8_t res, op0, op1;
        !           367:   tme_uint8_t flags;
        !           368: 
        !           369:   /* load the operand(s): */
        !           370:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !           371:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !           372:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !           373:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
        !           374:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
        !           375:   tme_uint16_t memory;
        !           376: 
        !           377:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !           378:   if (memory) {
        !           379:     TME_M68K_INSN_CANFAULT;
        !           380:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           381:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !           382:       ic->_tme_m68k_ea_function_code = function_code;
        !           383:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !           384:     }
        !           385:     tme_m68k_read_memx8(ic);
        !           386:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           387:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !           388:       ic->_tme_m68k_ea_function_code = function_code;
        !           389:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !           390:     }
        !           391:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
        !           392:     op1 = ic->tme_m68k_ireg_memx8;
        !           393:     op0 = ic->tme_m68k_ireg_memy8;
        !           394:   }
        !           395:   else {
        !           396:     op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2);
        !           397:     op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2);
        !           398:   }
        !           399: 
        !           400:   /* perform the operation: */
        !           401:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !           402: 
        !           403:   /* store the result: */
        !           404:   if (memory) {
        !           405:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           406:       ic->tme_m68k_ireg_memx8 = res;
        !           407:       ic->_tme_m68k_ea_function_code = function_code;
        !           408:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !           409:     }
        !           410:     tme_m68k_write_memx8(ic);
        !           411:   }
        !           412:   else {
        !           413:     ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res;
        !           414:   }
        !           415: 
        !           416:   /* set the flags: */
        !           417:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           418:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !           419:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !           420:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !           421:   ic->tme_m68k_ireg_ccr = flags;
        !           422: 
        !           423:   TME_M68K_INSN_OK;
        !           424: }
        !           425: 
        !           426: /* this does a 8-bit "cmpm SRC, DST": */
        !           427: TME_M68K_INSN(tme_m68k_cmpm8)
        !           428: {
        !           429:   tme_uint8_t res, op0, op1;
        !           430:   tme_uint8_t flags;
        !           431: 
        !           432:   /* load the operand(s): */
        !           433:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !           434:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !           435:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !           436:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
        !           437:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
        !           438: 
        !           439:   TME_M68K_INSN_CANFAULT;
        !           440: 
        !           441:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           442:     ic->_tme_m68k_ea_function_code = function_code;
        !           443:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !           444:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
        !           445:   }
        !           446:   tme_m68k_read_memx8(ic);
        !           447:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !           448:     ic->_tme_m68k_ea_function_code = function_code;
        !           449:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !           450:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
        !           451:   }
        !           452:   tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
        !           453:   op1 = ic->tme_m68k_ireg_memx8;
        !           454:   op0 = ic->tme_m68k_ireg_memy8;
        !           455: 
        !           456:   /* perform the operation: */
        !           457:   res = op1 - op0;
        !           458: 
        !           459:   /* set the flags: */
        !           460:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           461:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           462:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
        !           463:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !           464:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !           465:   ic->tme_m68k_ireg_ccr = flags;
        !           466: 
        !           467:   TME_M68K_INSN_OK;
        !           468: }
        !           469: 
        !           470: /* the btst function on a 8-byte EA: */
        !           471: TME_M68K_INSN(tme_m68k_btst8)
        !           472: {
        !           473:   tme_uint8_t value, bit;
        !           474:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
        !           475:   value = TME_M68K_INSN_OP1(tme_uint8_t);
        !           476:   if (value & bit) {
        !           477:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !           478:   }
        !           479:   else {
        !           480:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !           481:   }
        !           482:   TME_M68K_INSN_OK;
        !           483: }
        !           484: 
        !           485: /* the bchg function on a 8-byte EA: */
        !           486: TME_M68K_INSN(tme_m68k_bchg8)
        !           487: {
        !           488:   tme_uint8_t value, bit;
        !           489:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
        !           490:   value = TME_M68K_INSN_OP1(tme_uint8_t);
        !           491:   if (value & bit) {
        !           492:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !           493:   }
        !           494:   else {
        !           495:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !           496:   }
        !           497:   TME_M68K_INSN_OP1(tme_uint8_t) = value ^ bit;
        !           498:   TME_M68K_INSN_OK;
        !           499: }
        !           500: 
        !           501: /* the bclr function on a 8-byte EA: */
        !           502: TME_M68K_INSN(tme_m68k_bclr8)
        !           503: {
        !           504:   tme_uint8_t value, bit;
        !           505:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
        !           506:   value = TME_M68K_INSN_OP1(tme_uint8_t);
        !           507:   if (value & bit) {
        !           508:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !           509:   }
        !           510:   else {
        !           511:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !           512:   }
        !           513:   TME_M68K_INSN_OP1(tme_uint8_t) = value & ~bit;
        !           514:   TME_M68K_INSN_OK;
        !           515: }
        !           516: 
        !           517: /* the bset function on a 8-byte EA: */
        !           518: TME_M68K_INSN(tme_m68k_bset8)
        !           519: {
        !           520:   tme_uint8_t value, bit;
        !           521:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
        !           522:   value = TME_M68K_INSN_OP1(tme_uint8_t);
        !           523:   if (value & bit) {
        !           524:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !           525:   }
        !           526:   else {
        !           527:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !           528:   }
        !           529:   TME_M68K_INSN_OP1(tme_uint8_t) = value | bit;
        !           530:   TME_M68K_INSN_OK;
        !           531: }
        !           532: 
        !           533: /* the asl function on a 8-byte EA: */
        !           534: TME_M68K_INSN(tme_m68k_asl8)
        !           535: {
        !           536:   unsigned int count;
        !           537:   tme_uint8_t sign_bits;
        !           538:   tme_uint8_t res;
        !           539:   tme_uint8_t flags;
        !           540: 
        !           541:   /* get the count and operand: */
        !           542:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           543:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           544: 
        !           545:   /* generate the X, V, and C flags assuming the count is zero: */
        !           546:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           547: 
        !           548:   /* if the count is nonzero, update the result and
        !           549:      generate the X, V, and C flags: */
        !           550:   if (count > 0) {
        !           551: 
        !           552:     /* we need to see how the sign of the result will change during
        !           553:        shifting in order to generate V.
        !           554: 
        !           555:        in general, the idea is to get all of the bits that will ever
        !           556:        appear in the sign position into sign_bits; if sign_bits is
        !           557:        all-bits-one or all-bits zero, clear V, else set V.  a good trick
        !           558:        is that ((sign_bits + 1) & sign_bits) is nonzero iff all of the
        !           559:        bits in sign_bits are the same.
        !           560: 
        !           561:        start by loading all of the operand into sign_bits.
        !           562: 
        !           563:        if the shift count is exactly 8 - 1, then all of the bits
        !           564:        of the operand will appear in the sign position.
        !           565: 
        !           566:        if the shift count is less than 8 - 1, then some of the
        !           567:        less significant bits of the operand will never appear in the
        !           568:        sign position, so we can shift them off of sign_bits now.
        !           569: 
        !           570:        if the shift count is greater than 8 - 1, then all of the
        !           571:        bits in the operand, plus at least one zero bit, will appear in
        !           572:        the sign position.  the only way that the sign bit will never
        !           573:        change during the shift is if the operand was zero to begin with.
        !           574:        we need to change sign_bits such that ((sign_bits + 1) &
        !           575:        sign_bits) will be zero iff the operand was zero to begin with.
        !           576:        the magic below does just that: */
        !           577:     sign_bits = res;
        !           578:     if (63 > SHIFTMAX_INT8_T
        !           579:         && count > 8) {
        !           580:       res = 0;
        !           581:     }
        !           582:     res <<= (count - 1);
        !           583:     flags = (res >> (8 - 1));
        !           584:     flags *= TME_M68K_FLAG_C;
        !           585:     flags |= (flags * TME_M68K_FLAG_X);
        !           586:     res <<= 1;
        !           587:     if (count != 8 - 1) {
        !           588:       if (count < 8) {
        !           589:         sign_bits >>= ((8 - 1) - count);
        !           590:       }
        !           591:       else {
        !           592:         sign_bits |= (sign_bits << 1);
        !           593:         sign_bits &= -2;
        !           594:       }
        !           595:     }
        !           596:     if ((sign_bits + 1) & sign_bits) {
        !           597:       flags |= TME_M68K_FLAG_V;
        !           598:     }
        !           599:   }
        !           600: 
        !           601:   /* store the result: */
        !           602:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           603: 
        !           604:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           605:      know the bit we want is within the range of the type, to try
        !           606:      to affect the generated assembly: */
        !           607:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           608: 
        !           609:   /* generate the Z flag: */
        !           610:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           611: 
        !           612:   /* store the flags: */
        !           613:   ic->tme_m68k_ireg_ccr = flags;
        !           614:   TME_M68K_INSN_OK;
        !           615: }
        !           616: 
        !           617: /* the asr function on a 8-byte EA: */
        !           618: TME_M68K_INSN(tme_m68k_asr8)
        !           619: {
        !           620:   unsigned int count;
        !           621:   tme_int8_t res;
        !           622:   tme_uint8_t flags;
        !           623: 
        !           624:   /* get the count and operand: */
        !           625:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           626:   res = TME_M68K_INSN_OP1(tme_int8_t);
        !           627: 
        !           628:   /* generate the X, V, and C flags assuming the count is zero: */
        !           629:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           630: 
        !           631:   /* if the count is nonzero, update the result and
        !           632:      generate the X, V, and C flags: */
        !           633:   if (count > 0) {
        !           634:     if (63 > SHIFTMAX_INT8_T
        !           635:         && count > 8) {
        !           636:       res = 0;
        !           637:     }
        !           638:     res >>= (count - 1);
        !           639:     flags = (res & 1);
        !           640:     flags *= TME_M68K_FLAG_C;
        !           641:     flags |= (flags * TME_M68K_FLAG_X);
        !           642:     res >>= 1;
        !           643:   }
        !           644: 
        !           645:   /* store the result: */
        !           646:   TME_M68K_INSN_OP1(tme_int8_t) = res;
        !           647: 
        !           648:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           649:      know the bit we want is within the range of the type, to try
        !           650:      to affect the generated assembly: */
        !           651:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           652: 
        !           653:   /* generate the Z flag: */
        !           654:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           655: 
        !           656:   /* store the flags: */
        !           657:   ic->tme_m68k_ireg_ccr = flags;
        !           658:   TME_M68K_INSN_OK;
        !           659: }
        !           660: 
        !           661: /* the lsl function on a 8-byte EA: */
        !           662: TME_M68K_INSN(tme_m68k_lsl8)
        !           663: {
        !           664:   unsigned int count;
        !           665:   tme_uint8_t res;
        !           666:   tme_uint8_t flags;
        !           667: 
        !           668:   /* get the count and operand: */
        !           669:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           670:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           671: 
        !           672:   /* generate the X, V, and C flags assuming the count is zero: */
        !           673:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           674: 
        !           675:   /* if the count is nonzero, update the result and
        !           676:      generate the X, V, and C flags: */
        !           677:   if (count > 0) {
        !           678:     if (63 > SHIFTMAX_INT8_T
        !           679:         && count > 8) {
        !           680:       res = 0;
        !           681:     }
        !           682:     res <<= (count - 1);
        !           683:     flags = (res >> (8 - 1));
        !           684:     flags *= TME_M68K_FLAG_C;
        !           685:     flags |= (flags * TME_M68K_FLAG_X);
        !           686:     res <<= 1;
        !           687:   }
        !           688: 
        !           689:   /* store the result: */
        !           690:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           691: 
        !           692:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           693:      know the bit we want is within the range of the type, to try
        !           694:      to affect the generated assembly: */
        !           695:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           696: 
        !           697:   /* generate the Z flag: */
        !           698:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           699: 
        !           700:   /* store the flags: */
        !           701:   ic->tme_m68k_ireg_ccr = flags;
        !           702:   TME_M68K_INSN_OK;
        !           703: }
        !           704: 
        !           705: /* the lsr function on a 8-byte EA: */
        !           706: TME_M68K_INSN(tme_m68k_lsr8)
        !           707: {
        !           708:   unsigned int count;
        !           709:   tme_uint8_t res;
        !           710:   tme_uint8_t flags;
        !           711: 
        !           712:   /* get the count and operand: */
        !           713:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           714:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           715: 
        !           716:   /* generate the X, V, and C flags assuming the count is zero: */
        !           717:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           718: 
        !           719:   /* if the count is nonzero, update the result and
        !           720:      generate the X, V, and C flags: */
        !           721:   if (count > 0) {
        !           722:     if (63 > SHIFTMAX_INT8_T
        !           723:         && count > 8) {
        !           724:       res = 0;
        !           725:     }
        !           726:     res >>= (count - 1);
        !           727:     flags = (res & 1);
        !           728:     flags *= TME_M68K_FLAG_C;
        !           729:     flags |= (flags * TME_M68K_FLAG_X);
        !           730:     res >>= 1;
        !           731:   }
        !           732: 
        !           733:   /* store the result: */
        !           734:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           735: 
        !           736:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           737:      know the bit we want is within the range of the type, to try
        !           738:      to affect the generated assembly: */
        !           739:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           740: 
        !           741:   /* generate the Z flag: */
        !           742:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           743: 
        !           744:   /* store the flags: */
        !           745:   ic->tme_m68k_ireg_ccr = flags;
        !           746:   TME_M68K_INSN_OK;
        !           747: }
        !           748: 
        !           749: /* the rol function on a 8-byte EA: */
        !           750: TME_M68K_INSN(tme_m68k_rol8)
        !           751: {
        !           752:   unsigned int count;
        !           753:   tme_uint8_t res;
        !           754:   tme_uint8_t flags;
        !           755: 
        !           756:   /* get the count and operand: */
        !           757:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           758:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           759: 
        !           760:   /* generate the X, V, and C flags assuming the count is zero: */
        !           761:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           762: 
        !           763:   /* if the count is nonzero, update the result and
        !           764:      generate the X, V, and C flags: */
        !           765:   if (count > 0) {
        !           766:     count &= (8 - 1);
        !           767:     res = (res << count) | (res >> (8 - count));
        !           768:     flags |= ((res & 1) * TME_M68K_FLAG_C);
        !           769:   }
        !           770: 
        !           771:   /* store the result: */
        !           772:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           773: 
        !           774:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           775:      know the bit we want is within the range of the type, to try
        !           776:      to affect the generated assembly: */
        !           777:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           778: 
        !           779:   /* generate the Z flag: */
        !           780:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           781: 
        !           782:   /* store the flags: */
        !           783:   ic->tme_m68k_ireg_ccr = flags;
        !           784:   TME_M68K_INSN_OK;
        !           785: }
        !           786: 
        !           787: /* the ror function on a 8-byte EA: */
        !           788: TME_M68K_INSN(tme_m68k_ror8)
        !           789: {
        !           790:   unsigned int count;
        !           791:   tme_uint8_t res;
        !           792:   tme_uint8_t flags;
        !           793: 
        !           794:   /* get the count and operand: */
        !           795:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           796:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           797: 
        !           798:   /* generate the X, V, and C flags assuming the count is zero: */
        !           799:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           800: 
        !           801:   /* if the count is nonzero, update the result and
        !           802:      generate the X, V, and C flags: */
        !           803:   if (count > 0) {
        !           804:     count &= (8 - 1);
        !           805:     res = (res << (8 - count)) | (res >> count);
        !           806:     flags |= ((res >> (8 - 1)) * TME_M68K_FLAG_C);
        !           807:   }
        !           808: 
        !           809:   /* store the result: */
        !           810:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           811: 
        !           812:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           813:      know the bit we want is within the range of the type, to try
        !           814:      to affect the generated assembly: */
        !           815:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           816: 
        !           817:   /* generate the Z flag: */
        !           818:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           819: 
        !           820:   /* store the flags: */
        !           821:   ic->tme_m68k_ireg_ccr = flags;
        !           822:   TME_M68K_INSN_OK;
        !           823: }
        !           824: 
        !           825: /* the roxl function on a 8-byte EA: */
        !           826: TME_M68K_INSN(tme_m68k_roxl8)
        !           827: {
        !           828:   unsigned int count;
        !           829:   tme_uint8_t xbit;
        !           830:   tme_uint8_t res;
        !           831:   tme_uint8_t flags;
        !           832: 
        !           833:   /* get the count and operand: */
        !           834:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           835:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           836: 
        !           837:   /* generate the X, V, and C flags assuming the count is zero: */
        !           838:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           839:   xbit = (flags / TME_M68K_FLAG_X);
        !           840:   flags |= (xbit * TME_M68K_FLAG_C);
        !           841: 
        !           842:   /* if the count is nonzero, update the result and
        !           843:      generate the X, V, and C flags: */
        !           844:   if (count > 0) {
        !           845:     count %= (8 + 1);
        !           846:     flags = xbit;
        !           847:     if (count > 0) {
        !           848:       flags = (res >> (8 - count)) & 1;
        !           849:       if (8 > SHIFTMAX_INT8_T
        !           850:           && count == 8) {
        !           851:         res = 0 | (xbit << (8 - 1)) | (res >> ((8 + 1) - 8));
        !           852:       }
        !           853:       else if (8 > SHIFTMAX_INT8_T
        !           854:                && count == 1) {
        !           855:         res = (res << 1) | (xbit << (1 - 1)) | 0;
        !           856:       }
        !           857:       else {
        !           858:         res = (res << count) | (xbit << (count - 1)) | (res >> ((8 + 1) - count));
        !           859:       }
        !           860:     }
        !           861:     flags *= TME_M68K_FLAG_C;
        !           862:     flags |= (flags * TME_M68K_FLAG_X);
        !           863:   }
        !           864: 
        !           865:   /* store the result: */
        !           866:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           867: 
        !           868:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           869:      know the bit we want is within the range of the type, to try
        !           870:      to affect the generated assembly: */
        !           871:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           872: 
        !           873:   /* generate the Z flag: */
        !           874:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           875: 
        !           876:   /* store the flags: */
        !           877:   ic->tme_m68k_ireg_ccr = flags;
        !           878:   TME_M68K_INSN_OK;
        !           879: }
        !           880: 
        !           881: /* the roxr function on a 8-byte EA: */
        !           882: TME_M68K_INSN(tme_m68k_roxr8)
        !           883: {
        !           884:   unsigned int count;
        !           885:   tme_uint8_t xbit;
        !           886:   tme_uint8_t res;
        !           887:   tme_uint8_t flags;
        !           888: 
        !           889:   /* get the count and operand: */
        !           890:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !           891:   res = TME_M68K_INSN_OP1(tme_uint8_t);
        !           892: 
        !           893:   /* generate the X, V, and C flags assuming the count is zero: */
        !           894:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !           895:   xbit = (flags / TME_M68K_FLAG_X);
        !           896:   flags |= (xbit * TME_M68K_FLAG_C);
        !           897: 
        !           898:   /* if the count is nonzero, update the result and
        !           899:      generate the X, V, and C flags: */
        !           900:   if (count > 0) {
        !           901:     count %= (8 + 1);
        !           902:     flags = xbit;
        !           903:     if (count > 0) {
        !           904:       flags = (res >> (count - 1)) & 1;
        !           905:       if (8 > SHIFTMAX_INT8_T
        !           906:           && count == 8) {
        !           907:         res = (res << ((8 + 1) - 8)) | (xbit << (8 - 8)) | 0;
        !           908:       }
        !           909:       else if (8 > SHIFTMAX_INT8_T
        !           910:                && count == 1) {
        !           911:         res = 0 | (xbit << (8 - 1)) | (res >> 1);
        !           912:       }
        !           913:       else {
        !           914:         res = (res << ((8 + 1) - count)) | (xbit << (8 - count)) | (res >> count);
        !           915:       }
        !           916:     }
        !           917:     flags *= TME_M68K_FLAG_C;
        !           918:     flags |= (flags * TME_M68K_FLAG_X);
        !           919:   }
        !           920: 
        !           921:   /* store the result: */
        !           922:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !           923: 
        !           924:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !           925:      know the bit we want is within the range of the type, to try
        !           926:      to affect the generated assembly: */
        !           927:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
        !           928: 
        !           929:   /* generate the Z flag: */
        !           930:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !           931: 
        !           932:   /* store the flags: */
        !           933:   ic->tme_m68k_ireg_ccr = flags;
        !           934:   TME_M68K_INSN_OK;
        !           935: }
        !           936: 
        !           937: /* cas8: */
        !           938: TME_M68K_INSN(tme_m68k_cas8)
        !           939: {
        !           940:   struct tme_m68k_tlb *tlb;
        !           941:   int ireg_dc, ireg_du;
        !           942:   int do_write;
        !           943:   tme_uint16_t specopx = ic->_tme_m68k_insn_specop;
        !           944: 
        !           945:   /* start the read/modify/write cycle: */
        !           946:   tlb = tme_m68k_rmw_start(ic);
        !           947:   if (tlb == NULL) {
        !           948:     TME_M68K_INSN_OK;
        !           949:   }
        !           950: 
        !           951:   /* read: */
        !           952:   tme_m68k_read8(ic, tlb,
        !           953:                   &ic->_tme_m68k_ea_function_code,
        !           954:                   &ic->_tme_m68k_ea_address,
        !           955:                   &ic->tme_m68k_ireg_memx8,
        !           956:                   TME_M68K_BUS_CYCLE_RMW);
        !           957: 
        !           958:   /* modify: */
        !           959:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !           960:   tme_m68k_cmp8(ic, &ic->tme_m68k_ireg_uint8(ireg_dc), &ic->tme_m68k_ireg_memx8);
        !           961: 
        !           962:   /* write: */
        !           963:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !           964:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
        !           965:     ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg_du);
        !           966:     tme_m68k_write8(ic, tlb,
        !           967:                      &ic->_tme_m68k_ea_function_code,
        !           968:                      &ic->_tme_m68k_ea_address,
        !           969:                      &ic->tme_m68k_ireg_memx8,
        !           970:                      TME_M68K_BUS_CYCLE_RMW);
        !           971:   }
        !           972:   else {
        !           973:     /* XXX the 68040 always does a write to finish its cycle: */
        !           974:     do_write = FALSE;
        !           975:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !           976:     if (do_write) {
        !           977:       tme_m68k_write8(ic, tlb,
        !           978:                        &ic->_tme_m68k_ea_function_code,
        !           979:                        &ic->_tme_m68k_ea_address,
        !           980:                        &ic->tme_m68k_ireg_memx8,
        !           981:                        TME_M68K_BUS_CYCLE_RMW);
        !           982:       do_write = FALSE;
        !           983:     }
        !           984:     ic->tme_m68k_ireg_uint8(ireg_dc) = ic->tme_m68k_ireg_memx8;
        !           985:   }
        !           986: 
        !           987:   /* finish the read/modify/write cycle: */
        !           988:   tme_m68k_rmw_finish(ic, tlb);
        !           989: 
        !           990:   TME_M68K_INSN_OK;
        !           991: }
        !           992: 
        !           993: /* moves8: */
        !           994: TME_M68K_INSN(tme_m68k_moves8)
        !           995: {
        !           996:   int ireg;
        !           997:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
        !           998:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
        !           999:     ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg << 2);
        !          1000:   }
        !          1001:   else {
        !          1002:     if (ireg >= TME_M68K_IREG_A0) {
        !          1003:       ic->tme_m68k_ireg_uint32(ireg) = 
        !          1004:         TME_EXT_S8_U32((tme_int8_t) ic->tme_m68k_ireg_memx8);
        !          1005:     }
        !          1006:     else
        !          1007:       ic->tme_m68k_ireg_uint8(ireg << 2) = ic->tme_m68k_ireg_memx8;
        !          1008:   }
        !          1009:   TME_M68K_INSN_OK;
        !          1010: }
        !          1011: 
        !          1012: /* this does a 16-bit "add SRC, DST": */
        !          1013: TME_M68K_INSN(tme_m68k_add16)
        !          1014: {
        !          1015:   tme_uint16_t res, op0, op1;
        !          1016:   tme_uint8_t flags;
        !          1017: 
        !          1018:   /* load the operand(s): */
        !          1019:   op0 = *((tme_uint16_t *) _op0);
        !          1020:   op1 = *((tme_uint16_t *) _op1);
        !          1021: 
        !          1022:   /* perform the operation: */
        !          1023:   res = op1 + op0;
        !          1024: 
        !          1025:   /* store the result: */
        !          1026:   *((tme_uint16_t *) _op1) = res;
        !          1027: 
        !          1028:   /* set the flags: */
        !          1029:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1030:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1031:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1032:   if (op0 > (op1 ^ 0xffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1033:   ic->tme_m68k_ireg_ccr = flags;
        !          1034: 
        !          1035:   TME_M68K_INSN_OK;
        !          1036: }
        !          1037: 
        !          1038: /* this does a 16-bit "sub SRC, DST": */
        !          1039: TME_M68K_INSN(tme_m68k_sub16)
        !          1040: {
        !          1041:   tme_uint16_t res, op0, op1;
        !          1042:   tme_uint8_t flags;
        !          1043: 
        !          1044:   /* load the operand(s): */
        !          1045:   op0 = *((tme_uint16_t *) _op0);
        !          1046:   op1 = *((tme_uint16_t *) _op1);
        !          1047: 
        !          1048:   /* perform the operation: */
        !          1049:   res = op1 - op0;
        !          1050: 
        !          1051:   /* store the result: */
        !          1052:   *((tme_uint16_t *) _op1) = res;
        !          1053: 
        !          1054:   /* set the flags: */
        !          1055:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1056:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1057:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1058:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1059:   ic->tme_m68k_ireg_ccr = flags;
        !          1060: 
        !          1061:   TME_M68K_INSN_OK;
        !          1062: }
        !          1063: 
        !          1064: /* this does a 16-bit "cmp SRC, DST": */
        !          1065: TME_M68K_INSN(tme_m68k_cmp16)
        !          1066: {
        !          1067:   tme_uint16_t res, op0, op1;
        !          1068:   tme_uint8_t flags;
        !          1069: 
        !          1070:   /* load the operand(s): */
        !          1071:   op0 = *((tme_uint16_t *) _op0);
        !          1072:   op1 = *((tme_uint16_t *) _op1);
        !          1073: 
        !          1074:   /* perform the operation: */
        !          1075:   res = op1 - op0;
        !          1076: 
        !          1077:   /* set the flags: */
        !          1078:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1079:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1080:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1081:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !          1082:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1083:   ic->tme_m68k_ireg_ccr = flags;
        !          1084: 
        !          1085:   TME_M68K_INSN_OK;
        !          1086: }
        !          1087: 
        !          1088: /* this does a 16-bit "neg DST": */
        !          1089: TME_M68K_INSN(tme_m68k_neg16)
        !          1090: {
        !          1091:   tme_uint16_t res, op1;
        !          1092:   tme_uint8_t flags;
        !          1093: 
        !          1094:   /* load the operand(s): */
        !          1095:   op1 = *((tme_uint16_t *) _op1);
        !          1096: 
        !          1097:   /* perform the operation: */
        !          1098:   res = 0 - op1;
        !          1099: 
        !          1100:   /* store the result: */
        !          1101:   *((tme_uint16_t *) _op1) = res;
        !          1102: 
        !          1103:   /* set the flags: */
        !          1104:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1105:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1106:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1107:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1108:   ic->tme_m68k_ireg_ccr = flags;
        !          1109: 
        !          1110:   TME_M68K_INSN_OK;
        !          1111: }
        !          1112: 
        !          1113: /* this does a 16-bit "or SRC, DST": */
        !          1114: TME_M68K_INSN(tme_m68k_or16)
        !          1115: {
        !          1116:   tme_uint16_t res, op0, op1;
        !          1117:   tme_uint8_t flags;
        !          1118: 
        !          1119:   /* load the operand(s): */
        !          1120:   op0 = *((tme_uint16_t *) _op0);
        !          1121:   op1 = *((tme_uint16_t *) _op1);
        !          1122: 
        !          1123:   /* perform the operation: */
        !          1124:   res = op1 | op0;
        !          1125: 
        !          1126:   /* store the result: */
        !          1127:   *((tme_uint16_t *) _op1) = res;
        !          1128: 
        !          1129:   /* set the flags: */
        !          1130:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1131:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1132:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1133:   ic->tme_m68k_ireg_ccr = flags;
        !          1134: 
        !          1135:   TME_M68K_INSN_OK;
        !          1136: }
        !          1137: 
        !          1138: /* this does a 16-bit "and SRC, DST": */
        !          1139: TME_M68K_INSN(tme_m68k_and16)
        !          1140: {
        !          1141:   tme_uint16_t res, op0, op1;
        !          1142:   tme_uint8_t flags;
        !          1143: 
        !          1144:   /* load the operand(s): */
        !          1145:   op0 = *((tme_uint16_t *) _op0);
        !          1146:   op1 = *((tme_uint16_t *) _op1);
        !          1147: 
        !          1148:   /* perform the operation: */
        !          1149:   res = op1 & op0;
        !          1150: 
        !          1151:   /* store the result: */
        !          1152:   *((tme_uint16_t *) _op1) = res;
        !          1153: 
        !          1154:   /* set the flags: */
        !          1155:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1156:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1157:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1158:   ic->tme_m68k_ireg_ccr = flags;
        !          1159: 
        !          1160:   TME_M68K_INSN_OK;
        !          1161: }
        !          1162: 
        !          1163: /* this does a 16-bit "eor SRC, DST": */
        !          1164: TME_M68K_INSN(tme_m68k_eor16)
        !          1165: {
        !          1166:   tme_uint16_t res, op0, op1;
        !          1167:   tme_uint8_t flags;
        !          1168: 
        !          1169:   /* load the operand(s): */
        !          1170:   op0 = *((tme_uint16_t *) _op0);
        !          1171:   op1 = *((tme_uint16_t *) _op1);
        !          1172: 
        !          1173:   /* perform the operation: */
        !          1174:   res = op1 ^ op0;
        !          1175: 
        !          1176:   /* store the result: */
        !          1177:   *((tme_uint16_t *) _op1) = res;
        !          1178: 
        !          1179:   /* set the flags: */
        !          1180:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1181:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1182:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1183:   ic->tme_m68k_ireg_ccr = flags;
        !          1184: 
        !          1185:   TME_M68K_INSN_OK;
        !          1186: }
        !          1187: 
        !          1188: /* this does a 16-bit "not DST": */
        !          1189: TME_M68K_INSN(tme_m68k_not16)
        !          1190: {
        !          1191:   tme_uint16_t res, op1;
        !          1192:   tme_uint8_t flags;
        !          1193: 
        !          1194:   /* load the operand(s): */
        !          1195:   op1 = *((tme_uint16_t *) _op1);
        !          1196: 
        !          1197:   /* perform the operation: */
        !          1198:   res = ~ op1;
        !          1199: 
        !          1200:   /* store the result: */
        !          1201:   *((tme_uint16_t *) _op1) = res;
        !          1202: 
        !          1203:   /* set the flags: */
        !          1204:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1205:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1206:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1207:   ic->tme_m68k_ireg_ccr = flags;
        !          1208: 
        !          1209:   TME_M68K_INSN_OK;
        !          1210: }
        !          1211: 
        !          1212: /* this does a 16-bit "tst DST": */
        !          1213: TME_M68K_INSN(tme_m68k_tst16)
        !          1214: {
        !          1215:   tme_uint16_t res, op1;
        !          1216:   tme_uint8_t flags;
        !          1217: 
        !          1218:   /* load the operand(s): */
        !          1219:   op1 = *((tme_uint16_t *) _op1);
        !          1220: 
        !          1221:   /* perform the operation: */
        !          1222:   res = op1;
        !          1223: 
        !          1224:   /* set the flags: */
        !          1225:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1226:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1227:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1228:   ic->tme_m68k_ireg_ccr = flags;
        !          1229: 
        !          1230:   TME_M68K_INSN_OK;
        !          1231: }
        !          1232: 
        !          1233: /* this does a 16-bit "move DST": */
        !          1234: TME_M68K_INSN(tme_m68k_move16)
        !          1235: {
        !          1236:   tme_uint16_t res, op1;
        !          1237:   tme_uint8_t flags;
        !          1238: 
        !          1239:   /* load the operand(s): */
        !          1240:   op1 = *((tme_uint16_t *) _op1);
        !          1241: 
        !          1242:   /* perform the operation: */
        !          1243:   res = op1;
        !          1244: 
        !          1245:   /* store the result: */
        !          1246:   *((tme_uint16_t *) _op0) = res;
        !          1247: 
        !          1248:   /* set the flags: */
        !          1249:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1250:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1251:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1252:   ic->tme_m68k_ireg_ccr = flags;
        !          1253: 
        !          1254:   TME_M68K_INSN_OK;
        !          1255: }
        !          1256: 
        !          1257: /* this does a 16-bit "clr DST": */
        !          1258: TME_M68K_INSN(tme_m68k_clr16)
        !          1259: {
        !          1260:   tme_uint16_t res;
        !          1261:   tme_uint8_t flags;
        !          1262: 
        !          1263:   /* load the operand(s): */
        !          1264: 
        !          1265:   /* perform the operation: */
        !          1266:   res = 0;
        !          1267: 
        !          1268:   /* store the result: */
        !          1269:   *((tme_uint16_t *) _op1) = res;
        !          1270: 
        !          1271:   /* set the flags: */
        !          1272:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1273:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1274:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1275:   ic->tme_m68k_ireg_ccr = flags;
        !          1276: 
        !          1277:   TME_M68K_INSN_OK;
        !          1278: }
        !          1279: 
        !          1280: /* this does a 16-bit "cmpa SRC, DST": */
        !          1281: TME_M68K_INSN(tme_m68k_cmpa16)
        !          1282: {
        !          1283:   tme_uint32_t res, op0, op1;
        !          1284:   tme_uint8_t flags;
        !          1285: 
        !          1286:   /* load the operand(s): */
        !          1287:   op0 = (tme_uint32_t) ((tme_int32_t) *((tme_int16_t *) _op0));
        !          1288:   op1 = *((tme_uint32_t *) _op1);
        !          1289: 
        !          1290:   /* perform the operation: */
        !          1291:   res = op1 - op0;
        !          1292: 
        !          1293:   /* set the flags: */
        !          1294:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          1295:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1296:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          1297:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !          1298:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1299:   ic->tme_m68k_ireg_ccr = flags;
        !          1300: 
        !          1301:   TME_M68K_INSN_OK;
        !          1302: }
        !          1303: 
        !          1304: /* this does a 16-bit "negx DST": */
        !          1305: TME_M68K_INSN(tme_m68k_negx16)
        !          1306: {
        !          1307:   tme_uint16_t res, op1;
        !          1308:   tme_uint8_t flags;
        !          1309: 
        !          1310:   /* load the operand(s): */
        !          1311:   op1 = *((tme_uint16_t *) _op1);
        !          1312: 
        !          1313:   /* perform the operation: */
        !          1314:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          1315: 
        !          1316:   /* store the result: */
        !          1317:   *((tme_uint16_t *) _op1) = res;
        !          1318: 
        !          1319:   /* set the flags: */
        !          1320:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1321:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          1322:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1323:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1324:   ic->tme_m68k_ireg_ccr = flags;
        !          1325: 
        !          1326:   TME_M68K_INSN_OK;
        !          1327: }
        !          1328: 
        !          1329: /* this does a 16-bit "addx SRC, DST": */
        !          1330: TME_M68K_INSN(tme_m68k_addx16)
        !          1331: {
        !          1332:   tme_uint16_t res, op0, op1;
        !          1333:   tme_uint8_t flags;
        !          1334: 
        !          1335:   /* load the operand(s): */
        !          1336:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          1337:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          1338:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          1339:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
        !          1340:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
        !          1341:   tme_uint16_t memory;
        !          1342: 
        !          1343:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !          1344:   if (memory) {
        !          1345:     TME_M68K_INSN_CANFAULT;
        !          1346:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1347:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !          1348:       ic->_tme_m68k_ea_function_code = function_code;
        !          1349:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          1350:     }
        !          1351:     tme_m68k_read_memx16(ic);
        !          1352:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1353:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !          1354:       ic->_tme_m68k_ea_function_code = function_code;
        !          1355:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          1356:     }
        !          1357:     tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
        !          1358:     op1 = ic->tme_m68k_ireg_memx16;
        !          1359:     op0 = ic->tme_m68k_ireg_memy16;
        !          1360:   }
        !          1361:   else {
        !          1362:     op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1);
        !          1363:     op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1);
        !          1364:   }
        !          1365: 
        !          1366:   /* perform the operation: */
        !          1367:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          1368: 
        !          1369:   /* store the result: */
        !          1370:   if (memory) {
        !          1371:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1372:       ic->tme_m68k_ireg_memx16 = res;
        !          1373:       ic->_tme_m68k_ea_function_code = function_code;
        !          1374:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          1375:     }
        !          1376:     tme_m68k_write_memx16(ic);
        !          1377:   }
        !          1378:   else {
        !          1379:     ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res;
        !          1380:   }
        !          1381: 
        !          1382:   /* set the flags: */
        !          1383:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1384:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          1385:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1386:   if (op0 > (op1 ^ 0xffff) || (op0 == (op1 ^ 0xffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1387:   ic->tme_m68k_ireg_ccr = flags;
        !          1388: 
        !          1389:   TME_M68K_INSN_OK;
        !          1390: }
        !          1391: 
        !          1392: /* this does a 16-bit "subx SRC, DST": */
        !          1393: TME_M68K_INSN(tme_m68k_subx16)
        !          1394: {
        !          1395:   tme_uint16_t res, op0, op1;
        !          1396:   tme_uint8_t flags;
        !          1397: 
        !          1398:   /* load the operand(s): */
        !          1399:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          1400:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          1401:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          1402:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
        !          1403:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
        !          1404:   tme_uint16_t memory;
        !          1405: 
        !          1406:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !          1407:   if (memory) {
        !          1408:     TME_M68K_INSN_CANFAULT;
        !          1409:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1410:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !          1411:       ic->_tme_m68k_ea_function_code = function_code;
        !          1412:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          1413:     }
        !          1414:     tme_m68k_read_memx16(ic);
        !          1415:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1416:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !          1417:       ic->_tme_m68k_ea_function_code = function_code;
        !          1418:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          1419:     }
        !          1420:     tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
        !          1421:     op1 = ic->tme_m68k_ireg_memx16;
        !          1422:     op0 = ic->tme_m68k_ireg_memy16;
        !          1423:   }
        !          1424:   else {
        !          1425:     op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1);
        !          1426:     op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1);
        !          1427:   }
        !          1428: 
        !          1429:   /* perform the operation: */
        !          1430:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          1431: 
        !          1432:   /* store the result: */
        !          1433:   if (memory) {
        !          1434:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1435:       ic->tme_m68k_ireg_memx16 = res;
        !          1436:       ic->_tme_m68k_ea_function_code = function_code;
        !          1437:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          1438:     }
        !          1439:     tme_m68k_write_memx16(ic);
        !          1440:   }
        !          1441:   else {
        !          1442:     ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res;
        !          1443:   }
        !          1444: 
        !          1445:   /* set the flags: */
        !          1446:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1447:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          1448:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1449:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          1450:   ic->tme_m68k_ireg_ccr = flags;
        !          1451: 
        !          1452:   TME_M68K_INSN_OK;
        !          1453: }
        !          1454: 
        !          1455: /* this does a 16-bit "cmpm SRC, DST": */
        !          1456: TME_M68K_INSN(tme_m68k_cmpm16)
        !          1457: {
        !          1458:   tme_uint16_t res, op0, op1;
        !          1459:   tme_uint8_t flags;
        !          1460: 
        !          1461:   /* load the operand(s): */
        !          1462:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          1463:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          1464:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          1465:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
        !          1466:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
        !          1467: 
        !          1468:   TME_M68K_INSN_CANFAULT;
        !          1469: 
        !          1470:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1471:     ic->_tme_m68k_ea_function_code = function_code;
        !          1472:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          1473:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
        !          1474:   }
        !          1475:   tme_m68k_read_memx16(ic);
        !          1476:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1477:     ic->_tme_m68k_ea_function_code = function_code;
        !          1478:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          1479:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
        !          1480:   }
        !          1481:   tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
        !          1482:   op1 = ic->tme_m68k_ireg_memx16;
        !          1483:   op0 = ic->tme_m68k_ireg_memy16;
        !          1484: 
        !          1485:   /* perform the operation: */
        !          1486:   res = op1 - op0;
        !          1487: 
        !          1488:   /* set the flags: */
        !          1489:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1490:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1491:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
        !          1492:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !          1493:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          1494:   ic->tme_m68k_ireg_ccr = flags;
        !          1495: 
        !          1496:   TME_M68K_INSN_OK;
        !          1497: }
        !          1498: 
        !          1499: /* the suba function on a 16-byte EA: */
        !          1500: TME_M68K_INSN(tme_m68k_suba16)
        !          1501: {
        !          1502:   *((tme_int32_t *) _op1) -= *((tme_int16_t *) _op0);
        !          1503:   TME_M68K_INSN_OK;
        !          1504: }
        !          1505: 
        !          1506: /* the adda function on a 16-byte EA: */
        !          1507: TME_M68K_INSN(tme_m68k_adda16)
        !          1508: {
        !          1509:   *((tme_int32_t *) _op1) += *((tme_int16_t *) _op0);
        !          1510:   TME_M68K_INSN_OK;
        !          1511: }
        !          1512: 
        !          1513: /* the movea function on a 16-byte EA: */
        !          1514: TME_M68K_INSN(tme_m68k_movea16)
        !          1515: {
        !          1516:   *((tme_int32_t *) _op0) = *((tme_int16_t *) _op1);
        !          1517:   TME_M68K_INSN_OK;
        !          1518: }
        !          1519: 
        !          1520: /* the asl function on a 16-byte EA: */
        !          1521: TME_M68K_INSN(tme_m68k_asl16)
        !          1522: {
        !          1523:   unsigned int count;
        !          1524:   tme_uint16_t sign_bits;
        !          1525:   tme_uint16_t res;
        !          1526:   tme_uint8_t flags;
        !          1527: 
        !          1528:   /* get the count and operand: */
        !          1529:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1530:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1531: 
        !          1532:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1533:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1534: 
        !          1535:   /* if the count is nonzero, update the result and
        !          1536:      generate the X, V, and C flags: */
        !          1537:   if (count > 0) {
        !          1538: 
        !          1539:     /* we need to see how the sign of the result will change during
        !          1540:        shifting in order to generate V.
        !          1541: 
        !          1542:        in general, the idea is to get all of the bits that will ever
        !          1543:        appear in the sign position into sign_bits; if sign_bits is
        !          1544:        all-bits-one or all-bits zero, clear V, else set V.  a good trick
        !          1545:        is that ((sign_bits + 1) & sign_bits) is nonzero iff all of the
        !          1546:        bits in sign_bits are the same.
        !          1547: 
        !          1548:        start by loading all of the operand into sign_bits.
        !          1549: 
        !          1550:        if the shift count is exactly 16 - 1, then all of the bits
        !          1551:        of the operand will appear in the sign position.
        !          1552: 
        !          1553:        if the shift count is less than 16 - 1, then some of the
        !          1554:        less significant bits of the operand will never appear in the
        !          1555:        sign position, so we can shift them off of sign_bits now.
        !          1556: 
        !          1557:        if the shift count is greater than 16 - 1, then all of the
        !          1558:        bits in the operand, plus at least one zero bit, will appear in
        !          1559:        the sign position.  the only way that the sign bit will never
        !          1560:        change during the shift is if the operand was zero to begin with.
        !          1561:        we need to change sign_bits such that ((sign_bits + 1) &
        !          1562:        sign_bits) will be zero iff the operand was zero to begin with.
        !          1563:        the magic below does just that: */
        !          1564:     sign_bits = res;
        !          1565:     if (63 > SHIFTMAX_INT16_T
        !          1566:         && count > 16) {
        !          1567:       res = 0;
        !          1568:     }
        !          1569:     res <<= (count - 1);
        !          1570:     flags = (res >> (16 - 1));
        !          1571:     flags *= TME_M68K_FLAG_C;
        !          1572:     flags |= (flags * TME_M68K_FLAG_X);
        !          1573:     res <<= 1;
        !          1574:     if (count != 16 - 1) {
        !          1575:       if (count < 16) {
        !          1576:         sign_bits >>= ((16 - 1) - count);
        !          1577:       }
        !          1578:       else {
        !          1579:         sign_bits |= (sign_bits << 1);
        !          1580:         sign_bits &= -2;
        !          1581:       }
        !          1582:     }
        !          1583:     if ((sign_bits + 1) & sign_bits) {
        !          1584:       flags |= TME_M68K_FLAG_V;
        !          1585:     }
        !          1586:   }
        !          1587: 
        !          1588:   /* store the result: */
        !          1589:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1590: 
        !          1591:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1592:      know the bit we want is within the range of the type, to try
        !          1593:      to affect the generated assembly: */
        !          1594:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1595: 
        !          1596:   /* generate the Z flag: */
        !          1597:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1598: 
        !          1599:   /* store the flags: */
        !          1600:   ic->tme_m68k_ireg_ccr = flags;
        !          1601:   TME_M68K_INSN_OK;
        !          1602: }
        !          1603: 
        !          1604: /* the asr function on a 16-byte EA: */
        !          1605: TME_M68K_INSN(tme_m68k_asr16)
        !          1606: {
        !          1607:   unsigned int count;
        !          1608:   tme_int16_t res;
        !          1609:   tme_uint8_t flags;
        !          1610: 
        !          1611:   /* get the count and operand: */
        !          1612:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1613:   res = TME_M68K_INSN_OP1(tme_int16_t);
        !          1614: 
        !          1615:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1616:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1617: 
        !          1618:   /* if the count is nonzero, update the result and
        !          1619:      generate the X, V, and C flags: */
        !          1620:   if (count > 0) {
        !          1621:     if (63 > SHIFTMAX_INT16_T
        !          1622:         && count > 16) {
        !          1623:       res = 0;
        !          1624:     }
        !          1625:     res >>= (count - 1);
        !          1626:     flags = (res & 1);
        !          1627:     flags *= TME_M68K_FLAG_C;
        !          1628:     flags |= (flags * TME_M68K_FLAG_X);
        !          1629:     res >>= 1;
        !          1630:   }
        !          1631: 
        !          1632:   /* store the result: */
        !          1633:   TME_M68K_INSN_OP1(tme_int16_t) = res;
        !          1634: 
        !          1635:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1636:      know the bit we want is within the range of the type, to try
        !          1637:      to affect the generated assembly: */
        !          1638:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1639: 
        !          1640:   /* generate the Z flag: */
        !          1641:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1642: 
        !          1643:   /* store the flags: */
        !          1644:   ic->tme_m68k_ireg_ccr = flags;
        !          1645:   TME_M68K_INSN_OK;
        !          1646: }
        !          1647: 
        !          1648: /* the lsl function on a 16-byte EA: */
        !          1649: TME_M68K_INSN(tme_m68k_lsl16)
        !          1650: {
        !          1651:   unsigned int count;
        !          1652:   tme_uint16_t res;
        !          1653:   tme_uint8_t flags;
        !          1654: 
        !          1655:   /* get the count and operand: */
        !          1656:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1657:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1658: 
        !          1659:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1660:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1661: 
        !          1662:   /* if the count is nonzero, update the result and
        !          1663:      generate the X, V, and C flags: */
        !          1664:   if (count > 0) {
        !          1665:     if (63 > SHIFTMAX_INT16_T
        !          1666:         && count > 16) {
        !          1667:       res = 0;
        !          1668:     }
        !          1669:     res <<= (count - 1);
        !          1670:     flags = (res >> (16 - 1));
        !          1671:     flags *= TME_M68K_FLAG_C;
        !          1672:     flags |= (flags * TME_M68K_FLAG_X);
        !          1673:     res <<= 1;
        !          1674:   }
        !          1675: 
        !          1676:   /* store the result: */
        !          1677:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1678: 
        !          1679:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1680:      know the bit we want is within the range of the type, to try
        !          1681:      to affect the generated assembly: */
        !          1682:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1683: 
        !          1684:   /* generate the Z flag: */
        !          1685:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1686: 
        !          1687:   /* store the flags: */
        !          1688:   ic->tme_m68k_ireg_ccr = flags;
        !          1689:   TME_M68K_INSN_OK;
        !          1690: }
        !          1691: 
        !          1692: /* the lsr function on a 16-byte EA: */
        !          1693: TME_M68K_INSN(tme_m68k_lsr16)
        !          1694: {
        !          1695:   unsigned int count;
        !          1696:   tme_uint16_t res;
        !          1697:   tme_uint8_t flags;
        !          1698: 
        !          1699:   /* get the count and operand: */
        !          1700:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1701:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1702: 
        !          1703:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1704:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1705: 
        !          1706:   /* if the count is nonzero, update the result and
        !          1707:      generate the X, V, and C flags: */
        !          1708:   if (count > 0) {
        !          1709:     if (63 > SHIFTMAX_INT16_T
        !          1710:         && count > 16) {
        !          1711:       res = 0;
        !          1712:     }
        !          1713:     res >>= (count - 1);
        !          1714:     flags = (res & 1);
        !          1715:     flags *= TME_M68K_FLAG_C;
        !          1716:     flags |= (flags * TME_M68K_FLAG_X);
        !          1717:     res >>= 1;
        !          1718:   }
        !          1719: 
        !          1720:   /* store the result: */
        !          1721:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1722: 
        !          1723:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1724:      know the bit we want is within the range of the type, to try
        !          1725:      to affect the generated assembly: */
        !          1726:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1727: 
        !          1728:   /* generate the Z flag: */
        !          1729:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1730: 
        !          1731:   /* store the flags: */
        !          1732:   ic->tme_m68k_ireg_ccr = flags;
        !          1733:   TME_M68K_INSN_OK;
        !          1734: }
        !          1735: 
        !          1736: /* the rol function on a 16-byte EA: */
        !          1737: TME_M68K_INSN(tme_m68k_rol16)
        !          1738: {
        !          1739:   unsigned int count;
        !          1740:   tme_uint16_t res;
        !          1741:   tme_uint8_t flags;
        !          1742: 
        !          1743:   /* get the count and operand: */
        !          1744:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1745:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1746: 
        !          1747:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1748:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1749: 
        !          1750:   /* if the count is nonzero, update the result and
        !          1751:      generate the X, V, and C flags: */
        !          1752:   if (count > 0) {
        !          1753:     count &= (16 - 1);
        !          1754:     res = (res << count) | (res >> (16 - count));
        !          1755:     flags |= ((res & 1) * TME_M68K_FLAG_C);
        !          1756:   }
        !          1757: 
        !          1758:   /* store the result: */
        !          1759:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1760: 
        !          1761:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1762:      know the bit we want is within the range of the type, to try
        !          1763:      to affect the generated assembly: */
        !          1764:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1765: 
        !          1766:   /* generate the Z flag: */
        !          1767:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1768: 
        !          1769:   /* store the flags: */
        !          1770:   ic->tme_m68k_ireg_ccr = flags;
        !          1771:   TME_M68K_INSN_OK;
        !          1772: }
        !          1773: 
        !          1774: /* the ror function on a 16-byte EA: */
        !          1775: TME_M68K_INSN(tme_m68k_ror16)
        !          1776: {
        !          1777:   unsigned int count;
        !          1778:   tme_uint16_t res;
        !          1779:   tme_uint8_t flags;
        !          1780: 
        !          1781:   /* get the count and operand: */
        !          1782:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1783:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1784: 
        !          1785:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1786:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1787: 
        !          1788:   /* if the count is nonzero, update the result and
        !          1789:      generate the X, V, and C flags: */
        !          1790:   if (count > 0) {
        !          1791:     count &= (16 - 1);
        !          1792:     res = (res << (16 - count)) | (res >> count);
        !          1793:     flags |= ((res >> (16 - 1)) * TME_M68K_FLAG_C);
        !          1794:   }
        !          1795: 
        !          1796:   /* store the result: */
        !          1797:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1798: 
        !          1799:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1800:      know the bit we want is within the range of the type, to try
        !          1801:      to affect the generated assembly: */
        !          1802:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1803: 
        !          1804:   /* generate the Z flag: */
        !          1805:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1806: 
        !          1807:   /* store the flags: */
        !          1808:   ic->tme_m68k_ireg_ccr = flags;
        !          1809:   TME_M68K_INSN_OK;
        !          1810: }
        !          1811: 
        !          1812: /* the roxl function on a 16-byte EA: */
        !          1813: TME_M68K_INSN(tme_m68k_roxl16)
        !          1814: {
        !          1815:   unsigned int count;
        !          1816:   tme_uint8_t xbit;
        !          1817:   tme_uint16_t res;
        !          1818:   tme_uint8_t flags;
        !          1819: 
        !          1820:   /* get the count and operand: */
        !          1821:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1822:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1823: 
        !          1824:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1825:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1826:   xbit = (flags / TME_M68K_FLAG_X);
        !          1827:   flags |= (xbit * TME_M68K_FLAG_C);
        !          1828: 
        !          1829:   /* if the count is nonzero, update the result and
        !          1830:      generate the X, V, and C flags: */
        !          1831:   if (count > 0) {
        !          1832:     count %= (16 + 1);
        !          1833:     flags = xbit;
        !          1834:     if (count > 0) {
        !          1835:       flags = (res >> (16 - count)) & 1;
        !          1836:       if (16 > SHIFTMAX_INT16_T
        !          1837:           && count == 16) {
        !          1838:         res = 0 | (xbit << (16 - 1)) | (res >> ((16 + 1) - 16));
        !          1839:       }
        !          1840:       else if (16 > SHIFTMAX_INT16_T
        !          1841:                && count == 1) {
        !          1842:         res = (res << 1) | (xbit << (1 - 1)) | 0;
        !          1843:       }
        !          1844:       else {
        !          1845:         res = (res << count) | (xbit << (count - 1)) | (res >> ((16 + 1) - count));
        !          1846:       }
        !          1847:     }
        !          1848:     flags *= TME_M68K_FLAG_C;
        !          1849:     flags |= (flags * TME_M68K_FLAG_X);
        !          1850:   }
        !          1851: 
        !          1852:   /* store the result: */
        !          1853:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1854: 
        !          1855:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1856:      know the bit we want is within the range of the type, to try
        !          1857:      to affect the generated assembly: */
        !          1858:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1859: 
        !          1860:   /* generate the Z flag: */
        !          1861:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1862: 
        !          1863:   /* store the flags: */
        !          1864:   ic->tme_m68k_ireg_ccr = flags;
        !          1865:   TME_M68K_INSN_OK;
        !          1866: }
        !          1867: 
        !          1868: /* the roxr function on a 16-byte EA: */
        !          1869: TME_M68K_INSN(tme_m68k_roxr16)
        !          1870: {
        !          1871:   unsigned int count;
        !          1872:   tme_uint8_t xbit;
        !          1873:   tme_uint16_t res;
        !          1874:   tme_uint8_t flags;
        !          1875: 
        !          1876:   /* get the count and operand: */
        !          1877:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          1878:   res = TME_M68K_INSN_OP1(tme_uint16_t);
        !          1879: 
        !          1880:   /* generate the X, V, and C flags assuming the count is zero: */
        !          1881:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          1882:   xbit = (flags / TME_M68K_FLAG_X);
        !          1883:   flags |= (xbit * TME_M68K_FLAG_C);
        !          1884: 
        !          1885:   /* if the count is nonzero, update the result and
        !          1886:      generate the X, V, and C flags: */
        !          1887:   if (count > 0) {
        !          1888:     count %= (16 + 1);
        !          1889:     flags = xbit;
        !          1890:     if (count > 0) {
        !          1891:       flags = (res >> (count - 1)) & 1;
        !          1892:       if (16 > SHIFTMAX_INT16_T
        !          1893:           && count == 16) {
        !          1894:         res = (res << ((16 + 1) - 16)) | (xbit << (16 - 16)) | 0;
        !          1895:       }
        !          1896:       else if (16 > SHIFTMAX_INT16_T
        !          1897:                && count == 1) {
        !          1898:         res = 0 | (xbit << (16 - 1)) | (res >> 1);
        !          1899:       }
        !          1900:       else {
        !          1901:         res = (res << ((16 + 1) - count)) | (xbit << (16 - count)) | (res >> count);
        !          1902:       }
        !          1903:     }
        !          1904:     flags *= TME_M68K_FLAG_C;
        !          1905:     flags |= (flags * TME_M68K_FLAG_X);
        !          1906:   }
        !          1907: 
        !          1908:   /* store the result: */
        !          1909:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
        !          1910: 
        !          1911:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          1912:      know the bit we want is within the range of the type, to try
        !          1913:      to affect the generated assembly: */
        !          1914:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
        !          1915: 
        !          1916:   /* generate the Z flag: */
        !          1917:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          1918: 
        !          1919:   /* store the flags: */
        !          1920:   ic->tme_m68k_ireg_ccr = flags;
        !          1921:   TME_M68K_INSN_OK;
        !          1922: }
        !          1923: 
        !          1924: /* the movep_rm function on a 16-bit dreg: */
        !          1925: TME_M68K_INSN(tme_m68k_movep_rm16)
        !          1926: {
        !          1927:   unsigned int function_code;
        !          1928:   tme_uint32_t linear_address;
        !          1929:   tme_uint16_t value;
        !          1930:   int dreg;
        !          1931: 
        !          1932:   TME_M68K_INSN_CANFAULT;
        !          1933: 
        !          1934:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          1935:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
        !          1936:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
        !          1937:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          1938:   value = ic->tme_m68k_ireg_uint16(dreg << 1);
        !          1939:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1940:     ic->_tme_m68k_ea_function_code = function_code;
        !          1941:     ic->_tme_m68k_ea_address = linear_address;
        !          1942:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8);
        !          1943:   }
        !          1944:   tme_m68k_write_memx8(ic);
        !          1945:   linear_address += 2;
        !          1946:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1947:     ic->_tme_m68k_ea_function_code = function_code;
        !          1948:     ic->_tme_m68k_ea_address = linear_address;
        !          1949:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8);
        !          1950:   }
        !          1951:   tme_m68k_write_memx8(ic);
        !          1952:   linear_address += 2;
        !          1953:   TME_M68K_INSN_OK;
        !          1954: }
        !          1955: 
        !          1956: /* the movem_rm function on 16-bit registers: */
        !          1957: TME_M68K_INSN(tme_m68k_movem_rm16)
        !          1958: {
        !          1959:   int ireg, direction;
        !          1960:   tme_uint16_t mask, bit;
        !          1961:   unsigned int ea_mode;
        !          1962:   tme_uint32_t addend;
        !          1963: 
        !          1964:   TME_M68K_INSN_CANFAULT;
        !          1965: 
        !          1966:   /* figure out what direction to move in, and where to start from: */
        !          1967:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
        !          1968:   direction = 1;
        !          1969:   ireg = TME_M68K_IREG_D0;
        !          1970:   if (ea_mode == 4) {
        !          1971:     direction = -1;
        !          1972:     ireg = TME_M68K_IREG_A7;
        !          1973:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1974:       ic->_tme_m68k_ea_address -= sizeof(tme_uint16_t);
        !          1975:     }
        !          1976:   }
        !          1977:   addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t));
        !          1978: 
        !          1979:   /* do the transfer: */
        !          1980:   mask = TME_M68K_INSN_SPECOP;
        !          1981:   for (bit = 1; bit != 0; bit <<= 1) {
        !          1982:     if (mask & bit) {
        !          1983:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1984:         ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1);
        !          1985:       }
        !          1986:       tme_m68k_write_memx16(ic);
        !          1987:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          1988:         ic->_tme_m68k_ea_address += addend;
        !          1989:       }
        !          1990:     }
        !          1991:     ireg += direction;
        !          1992:   }
        !          1993: 
        !          1994:   /* if this is the predecrement mode, update the address register: */
        !          1995:   if (ea_mode == 4) {
        !          1996:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
        !          1997:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
        !          1998:       = (ic->_tme_m68k_ea_address + sizeof(tme_uint16_t));
        !          1999:   }
        !          2000:   TME_M68K_INSN_OK;
        !          2001: }
        !          2002: 
        !          2003: /* the movep_mr function on a 16-bit dreg: */
        !          2004: TME_M68K_INSN(tme_m68k_movep_mr16)
        !          2005: {
        !          2006:   unsigned int function_code;
        !          2007:   tme_uint32_t linear_address;
        !          2008:   int dreg;
        !          2009: 
        !          2010:   TME_M68K_INSN_CANFAULT;
        !          2011: 
        !          2012:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          2013:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2014:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
        !          2015:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          2016:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2017:     ic->_tme_m68k_ea_function_code = function_code;
        !          2018:     ic->_tme_m68k_ea_address = linear_address;
        !          2019:   }
        !          2020:   tme_m68k_read_memx8(ic);
        !          2021:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2022:     TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 8, 8, ic->tme_m68k_ireg_memx8);
        !          2023:   }
        !          2024:   linear_address += 2;
        !          2025:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2026:     ic->_tme_m68k_ea_function_code = function_code;
        !          2027:     ic->_tme_m68k_ea_address = linear_address;
        !          2028:   }
        !          2029:   tme_m68k_read_memx8(ic);
        !          2030:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2031:     TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 0, 8, ic->tme_m68k_ireg_memx8);
        !          2032:   }
        !          2033:   linear_address += 2;
        !          2034:   TME_M68K_INSN_OK;
        !          2035: }
        !          2036: 
        !          2037: /* the movem_mr function on 16-bit registers: */
        !          2038: TME_M68K_INSN(tme_m68k_movem_mr16)
        !          2039: {
        !          2040:   int ireg, direction;
        !          2041:   tme_uint16_t mask, bit;
        !          2042:   unsigned int ea_mode;
        !          2043:   tme_uint32_t addend;
        !          2044: 
        !          2045:   TME_M68K_INSN_CANFAULT;
        !          2046: 
        !          2047:   /* figure out what direction to move in, and where to start from: */
        !          2048:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
        !          2049:   direction = 1;
        !          2050:   ireg = TME_M68K_IREG_D0;
        !          2051:   addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t));
        !          2052: 
        !          2053:   /* do the transfer: */
        !          2054:   mask = TME_M68K_INSN_SPECOP;
        !          2055:   for (bit = 1; bit != 0; bit <<= 1) {
        !          2056:     if (mask & bit) {
        !          2057:       tme_m68k_read_memx16(ic);
        !          2058:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2059:         ic->tme_m68k_ireg_uint32(ireg) = TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16);
        !          2060:         ic->_tme_m68k_ea_address += addend;
        !          2061:       }
        !          2062:     }
        !          2063:     ireg += direction;
        !          2064:   }
        !          2065: 
        !          2066:   /* if this is the postincrement mode, update the address register: */
        !          2067:   if (ea_mode == 3) {
        !          2068:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
        !          2069:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
        !          2070:       = ic->_tme_m68k_ea_address;
        !          2071:   }
        !          2072:   TME_M68K_INSN_OK;
        !          2073: }
        !          2074: 
        !          2075: /* chk16: */
        !          2076: TME_M68K_INSN(tme_m68k_chk16)
        !          2077: {
        !          2078:   if (*((tme_int16_t *) _op0) < 0) {
        !          2079:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N;
        !          2080:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          2081:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
        !          2082:   }
        !          2083:   if (*((tme_int16_t *) _op0) > *((tme_int16_t *) _op1)) {
        !          2084:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N;
        !          2085:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          2086:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
        !          2087:   }
        !          2088:   TME_M68K_INSN_OK;
        !          2089: }
        !          2090: 
        !          2091: /* cas16: */
        !          2092: TME_M68K_INSN(tme_m68k_cas16)
        !          2093: {
        !          2094:   struct tme_m68k_tlb *tlb;
        !          2095:   int ireg_dc, ireg_du;
        !          2096:   int do_write;
        !          2097:   tme_uint16_t specopx = ic->_tme_m68k_insn_specop;
        !          2098: 
        !          2099:   /* start the read/modify/write cycle: */
        !          2100:   tlb = tme_m68k_rmw_start(ic);
        !          2101:   if (tlb == NULL) {
        !          2102:     TME_M68K_INSN_OK;
        !          2103:   }
        !          2104: 
        !          2105:   /* read: */
        !          2106:   tme_m68k_read16(ic, tlb,
        !          2107:                   &ic->_tme_m68k_ea_function_code,
        !          2108:                   &ic->_tme_m68k_ea_address,
        !          2109:                   &ic->tme_m68k_ireg_memx16,
        !          2110:                   TME_M68K_BUS_CYCLE_RMW);
        !          2111: 
        !          2112:   /* modify: */
        !          2113:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          2114:   tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memx16);
        !          2115: 
        !          2116:   /* write: */
        !          2117:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          2118:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
        !          2119:     ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_du);
        !          2120:     tme_m68k_write16(ic, tlb,
        !          2121:                      &ic->_tme_m68k_ea_function_code,
        !          2122:                      &ic->_tme_m68k_ea_address,
        !          2123:                      &ic->tme_m68k_ireg_memx16,
        !          2124:                      TME_M68K_BUS_CYCLE_RMW);
        !          2125:   }
        !          2126:   else {
        !          2127:     /* XXX the 68040 always does a write to finish its cycle: */
        !          2128:     do_write = FALSE;
        !          2129:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          2130:     if (do_write) {
        !          2131:       tme_m68k_write16(ic, tlb,
        !          2132:                        &ic->_tme_m68k_ea_function_code,
        !          2133:                        &ic->_tme_m68k_ea_address,
        !          2134:                        &ic->tme_m68k_ireg_memx16,
        !          2135:                        TME_M68K_BUS_CYCLE_RMW);
        !          2136:       do_write = FALSE;
        !          2137:     }
        !          2138:     ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memx16;
        !          2139:   }
        !          2140: 
        !          2141:   /* finish the read/modify/write cycle: */
        !          2142:   tme_m68k_rmw_finish(ic, tlb);
        !          2143: 
        !          2144:   TME_M68K_INSN_OK;
        !          2145: }
        !          2146: 
        !          2147: /* cas2_16: */
        !          2148: TME_M68K_INSN(tme_m68k_cas2_16)
        !          2149: {
        !          2150:   struct tme_m68k_tlb *tlb;
        !          2151:   int ireg_dc, ireg_du;
        !          2152:   int do_write;
        !          2153:   tme_uint16_t specopx = ic->_tme_m68k_insn_specop;
        !          2154:   tme_uint16_t specopy = ic->_tme_m68k_insn_specop2;
        !          2155:   tme_uint32_t addrx;
        !          2156:   tme_uint32_t addry;
        !          2157: 
        !          2158:   /* get the function code and addresses we'll be dealing with: */
        !          2159:   ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          2160:   addrx = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
        !          2161:                                    + TME_FIELD_EXTRACTU(specopx, 12, 4));
        !          2162:   addry = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
        !          2163:                                    + TME_FIELD_EXTRACTU(specopy, 12, 4));
        !          2164: 
        !          2165:   /* start the read/modify/write cycle: */
        !          2166:   tlb = tme_m68k_rmw_start(ic);
        !          2167:   if (tlb == NULL) {
        !          2168:     TME_M68K_INSN_OK;
        !          2169:   }
        !          2170: 
        !          2171:   /* read: */
        !          2172:   ic->_tme_m68k_ea_address = addrx;
        !          2173:   tme_m68k_read16(ic, tlb,
        !          2174:                   &ic->_tme_m68k_ea_function_code,
        !          2175:                   &ic->_tme_m68k_ea_address,
        !          2176:                   &ic->tme_m68k_ireg_memx16,
        !          2177:                   TME_M68K_BUS_CYCLE_RMW);
        !          2178:   ic->_tme_m68k_ea_address = addry;
        !          2179:   tme_m68k_read16(ic, tlb,
        !          2180:                   &ic->_tme_m68k_ea_function_code,
        !          2181:                   &ic->_tme_m68k_ea_address,
        !          2182:                   &ic->tme_m68k_ireg_memy16,
        !          2183:                   TME_M68K_BUS_CYCLE_RMW);
        !          2184: 
        !          2185:   /* modify: */
        !          2186:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          2187:   tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memx16);
        !          2188:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          2189:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
        !          2190:     tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memy16);
        !          2191:   }
        !          2192: 
        !          2193:   /* write: */
        !          2194:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          2195:     ic->_tme_m68k_ea_address = addrx;
        !          2196:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
        !          2197:     ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_du);
        !          2198:     tme_m68k_write16(ic, tlb,
        !          2199:                      &ic->_tme_m68k_ea_function_code,
        !          2200:                      &ic->_tme_m68k_ea_address,
        !          2201:                      &ic->tme_m68k_ireg_memx16,
        !          2202:                      TME_M68K_BUS_CYCLE_RMW);
        !          2203:     ic->_tme_m68k_ea_address = addry;
        !          2204:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3);
        !          2205:     ic->tme_m68k_ireg_memy16 = ic->tme_m68k_ireg_uint16(ireg_du);
        !          2206:     tme_m68k_write16(ic, tlb,
        !          2207:                      &ic->_tme_m68k_ea_function_code,
        !          2208:                      &ic->_tme_m68k_ea_address,
        !          2209:                      &ic->tme_m68k_ireg_memy16,
        !          2210:                      TME_M68K_BUS_CYCLE_RMW);
        !          2211:   }
        !          2212:   else {
        !          2213:     /* XXX the 68040 always does a write to finish its cycle: */
        !          2214:     do_write = FALSE;
        !          2215:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          2216:     if (do_write
        !          2217:         && ic->tme_m68k_ireg_memx16 != ic->tme_m68k_ireg_uint16(ireg_dc)) {
        !          2218:       ic->_tme_m68k_ea_address = addrx;
        !          2219:       tme_m68k_write16(ic, tlb,
        !          2220:                        &ic->_tme_m68k_ea_function_code,
        !          2221:                        &ic->_tme_m68k_ea_address,
        !          2222:                        &ic->tme_m68k_ireg_memx16,
        !          2223:                        TME_M68K_BUS_CYCLE_RMW);
        !          2224:       do_write = FALSE;
        !          2225:     }
        !          2226:     ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memx16;
        !          2227:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
        !          2228:     if (do_write
        !          2229:         && ic->tme_m68k_ireg_memy16 != ic->tme_m68k_ireg_uint16(ireg_dc)) {
        !          2230:       ic->_tme_m68k_ea_address = addry;
        !          2231:       tme_m68k_write16(ic, tlb,
        !          2232:                        &ic->_tme_m68k_ea_function_code,
        !          2233:                        &ic->_tme_m68k_ea_address,
        !          2234:                        &ic->tme_m68k_ireg_memy16,
        !          2235:                        TME_M68K_BUS_CYCLE_RMW);
        !          2236:       do_write = FALSE;
        !          2237:     }
        !          2238:     ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memy16;
        !          2239:   }
        !          2240: 
        !          2241:   /* finish the read/modify/write cycle: */
        !          2242:   tme_m68k_rmw_finish(ic, tlb);
        !          2243: 
        !          2244:   TME_M68K_INSN_OK;
        !          2245: }
        !          2246: 
        !          2247: /* moves16: */
        !          2248: TME_M68K_INSN(tme_m68k_moves16)
        !          2249: {
        !          2250:   int ireg;
        !          2251:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
        !          2252:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
        !          2253:     ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1);
        !          2254:   }
        !          2255:   else {
        !          2256:     if (ireg >= TME_M68K_IREG_A0) {
        !          2257:       ic->tme_m68k_ireg_uint32(ireg) = 
        !          2258:         TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16);
        !          2259:     }
        !          2260:     else
        !          2261:       ic->tme_m68k_ireg_uint16(ireg << 1) = ic->tme_m68k_ireg_memx16;
        !          2262:   }
        !          2263:   TME_M68K_INSN_OK;
        !          2264: }
        !          2265: 
        !          2266: /* this does a 32-bit "add SRC, DST": */
        !          2267: TME_M68K_INSN(tme_m68k_add32)
        !          2268: {
        !          2269:   tme_uint32_t res, op0, op1;
        !          2270:   tme_uint8_t flags;
        !          2271: 
        !          2272:   /* load the operand(s): */
        !          2273:   op0 = *((tme_uint32_t *) _op0);
        !          2274:   op1 = *((tme_uint32_t *) _op1);
        !          2275: 
        !          2276:   /* perform the operation: */
        !          2277:   res = op1 + op0;
        !          2278: 
        !          2279:   /* store the result: */
        !          2280:   *((tme_uint32_t *) _op1) = res;
        !          2281: 
        !          2282:   /* set the flags: */
        !          2283:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2284:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2285:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2286:   if (op0 > (op1 ^ 0xffffffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2287:   ic->tme_m68k_ireg_ccr = flags;
        !          2288: 
        !          2289:   TME_M68K_INSN_OK;
        !          2290: }
        !          2291: 
        !          2292: /* this does a 32-bit "sub SRC, DST": */
        !          2293: TME_M68K_INSN(tme_m68k_sub32)
        !          2294: {
        !          2295:   tme_uint32_t res, op0, op1;
        !          2296:   tme_uint8_t flags;
        !          2297: 
        !          2298:   /* load the operand(s): */
        !          2299:   op0 = *((tme_uint32_t *) _op0);
        !          2300:   op1 = *((tme_uint32_t *) _op1);
        !          2301: 
        !          2302:   /* perform the operation: */
        !          2303:   res = op1 - op0;
        !          2304: 
        !          2305:   /* store the result: */
        !          2306:   *((tme_uint32_t *) _op1) = res;
        !          2307: 
        !          2308:   /* set the flags: */
        !          2309:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2310:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2311:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2312:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2313:   ic->tme_m68k_ireg_ccr = flags;
        !          2314: 
        !          2315:   TME_M68K_INSN_OK;
        !          2316: }
        !          2317: 
        !          2318: /* this does a 32-bit "cmp SRC, DST": */
        !          2319: TME_M68K_INSN(tme_m68k_cmp32)
        !          2320: {
        !          2321:   tme_uint32_t res, op0, op1;
        !          2322:   tme_uint8_t flags;
        !          2323: 
        !          2324:   /* load the operand(s): */
        !          2325:   op0 = *((tme_uint32_t *) _op0);
        !          2326:   op1 = *((tme_uint32_t *) _op1);
        !          2327: 
        !          2328:   /* perform the operation: */
        !          2329:   res = op1 - op0;
        !          2330: 
        !          2331:   /* set the flags: */
        !          2332:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2333:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2334:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2335:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !          2336:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2337:   ic->tme_m68k_ireg_ccr = flags;
        !          2338: 
        !          2339:   TME_M68K_INSN_OK;
        !          2340: }
        !          2341: 
        !          2342: /* this does a 32-bit "neg DST": */
        !          2343: TME_M68K_INSN(tme_m68k_neg32)
        !          2344: {
        !          2345:   tme_uint32_t res, op1;
        !          2346:   tme_uint8_t flags;
        !          2347: 
        !          2348:   /* load the operand(s): */
        !          2349:   op1 = *((tme_uint32_t *) _op1);
        !          2350: 
        !          2351:   /* perform the operation: */
        !          2352:   res = 0 - op1;
        !          2353: 
        !          2354:   /* store the result: */
        !          2355:   *((tme_uint32_t *) _op1) = res;
        !          2356: 
        !          2357:   /* set the flags: */
        !          2358:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2359:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2360:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2361:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2362:   ic->tme_m68k_ireg_ccr = flags;
        !          2363: 
        !          2364:   TME_M68K_INSN_OK;
        !          2365: }
        !          2366: 
        !          2367: /* this does a 32-bit "or SRC, DST": */
        !          2368: TME_M68K_INSN(tme_m68k_or32)
        !          2369: {
        !          2370:   tme_uint32_t res, op0, op1;
        !          2371:   tme_uint8_t flags;
        !          2372: 
        !          2373:   /* load the operand(s): */
        !          2374:   op0 = *((tme_uint32_t *) _op0);
        !          2375:   op1 = *((tme_uint32_t *) _op1);
        !          2376: 
        !          2377:   /* perform the operation: */
        !          2378:   res = op1 | op0;
        !          2379: 
        !          2380:   /* store the result: */
        !          2381:   *((tme_uint32_t *) _op1) = res;
        !          2382: 
        !          2383:   /* set the flags: */
        !          2384:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2385:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2386:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2387:   ic->tme_m68k_ireg_ccr = flags;
        !          2388: 
        !          2389:   TME_M68K_INSN_OK;
        !          2390: }
        !          2391: 
        !          2392: /* this does a 32-bit "and SRC, DST": */
        !          2393: TME_M68K_INSN(tme_m68k_and32)
        !          2394: {
        !          2395:   tme_uint32_t res, op0, op1;
        !          2396:   tme_uint8_t flags;
        !          2397: 
        !          2398:   /* load the operand(s): */
        !          2399:   op0 = *((tme_uint32_t *) _op0);
        !          2400:   op1 = *((tme_uint32_t *) _op1);
        !          2401: 
        !          2402:   /* perform the operation: */
        !          2403:   res = op1 & op0;
        !          2404: 
        !          2405:   /* store the result: */
        !          2406:   *((tme_uint32_t *) _op1) = res;
        !          2407: 
        !          2408:   /* set the flags: */
        !          2409:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2410:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2411:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2412:   ic->tme_m68k_ireg_ccr = flags;
        !          2413: 
        !          2414:   TME_M68K_INSN_OK;
        !          2415: }
        !          2416: 
        !          2417: /* this does a 32-bit "eor SRC, DST": */
        !          2418: TME_M68K_INSN(tme_m68k_eor32)
        !          2419: {
        !          2420:   tme_uint32_t res, op0, op1;
        !          2421:   tme_uint8_t flags;
        !          2422: 
        !          2423:   /* load the operand(s): */
        !          2424:   op0 = *((tme_uint32_t *) _op0);
        !          2425:   op1 = *((tme_uint32_t *) _op1);
        !          2426: 
        !          2427:   /* perform the operation: */
        !          2428:   res = op1 ^ op0;
        !          2429: 
        !          2430:   /* store the result: */
        !          2431:   *((tme_uint32_t *) _op1) = res;
        !          2432: 
        !          2433:   /* set the flags: */
        !          2434:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2435:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2436:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2437:   ic->tme_m68k_ireg_ccr = flags;
        !          2438: 
        !          2439:   TME_M68K_INSN_OK;
        !          2440: }
        !          2441: 
        !          2442: /* this does a 32-bit "not DST": */
        !          2443: TME_M68K_INSN(tme_m68k_not32)
        !          2444: {
        !          2445:   tme_uint32_t res, op1;
        !          2446:   tme_uint8_t flags;
        !          2447: 
        !          2448:   /* load the operand(s): */
        !          2449:   op1 = *((tme_uint32_t *) _op1);
        !          2450: 
        !          2451:   /* perform the operation: */
        !          2452:   res = ~ op1;
        !          2453: 
        !          2454:   /* store the result: */
        !          2455:   *((tme_uint32_t *) _op1) = res;
        !          2456: 
        !          2457:   /* set the flags: */
        !          2458:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2459:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2460:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2461:   ic->tme_m68k_ireg_ccr = flags;
        !          2462: 
        !          2463:   TME_M68K_INSN_OK;
        !          2464: }
        !          2465: 
        !          2466: /* this does a 32-bit "tst DST": */
        !          2467: TME_M68K_INSN(tme_m68k_tst32)
        !          2468: {
        !          2469:   tme_uint32_t res, op1;
        !          2470:   tme_uint8_t flags;
        !          2471: 
        !          2472:   /* load the operand(s): */
        !          2473:   op1 = *((tme_uint32_t *) _op1);
        !          2474: 
        !          2475:   /* perform the operation: */
        !          2476:   res = op1;
        !          2477: 
        !          2478:   /* set the flags: */
        !          2479:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2480:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2481:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2482:   ic->tme_m68k_ireg_ccr = flags;
        !          2483: 
        !          2484:   TME_M68K_INSN_OK;
        !          2485: }
        !          2486: 
        !          2487: /* this does a 32-bit "move DST": */
        !          2488: TME_M68K_INSN(tme_m68k_move32)
        !          2489: {
        !          2490:   tme_uint32_t res, op1;
        !          2491:   tme_uint8_t flags;
        !          2492: 
        !          2493:   /* load the operand(s): */
        !          2494:   op1 = *((tme_uint32_t *) _op1);
        !          2495: 
        !          2496:   /* perform the operation: */
        !          2497:   res = op1;
        !          2498: 
        !          2499:   /* store the result: */
        !          2500:   *((tme_uint32_t *) _op0) = res;
        !          2501: 
        !          2502:   /* set the flags: */
        !          2503:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2504:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2505:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2506:   ic->tme_m68k_ireg_ccr = flags;
        !          2507: 
        !          2508:   TME_M68K_INSN_OK;
        !          2509: }
        !          2510: 
        !          2511: /* this does a 32-bit "moveq DST": */
        !          2512: TME_M68K_INSN(tme_m68k_moveq32)
        !          2513: {
        !          2514:   tme_uint32_t res;
        !          2515:   tme_uint8_t flags;
        !          2516: 
        !          2517:   /* load the operand(s): */
        !          2518: 
        !          2519:   /* perform the operation: */
        !          2520:   res = TME_EXT_S8_U32((tme_int8_t) (TME_M68K_INSN_OPCODE & 0xff));
        !          2521: 
        !          2522:   /* store the result: */
        !          2523:   *((tme_uint32_t *) _op1) = res;
        !          2524: 
        !          2525:   /* set the flags: */
        !          2526:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2527:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2528:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2529:   ic->tme_m68k_ireg_ccr = flags;
        !          2530: 
        !          2531:   TME_M68K_INSN_OK;
        !          2532: }
        !          2533: 
        !          2534: /* this does a 32-bit "clr DST": */
        !          2535: TME_M68K_INSN(tme_m68k_clr32)
        !          2536: {
        !          2537:   tme_uint32_t res;
        !          2538:   tme_uint8_t flags;
        !          2539: 
        !          2540:   /* load the operand(s): */
        !          2541: 
        !          2542:   /* perform the operation: */
        !          2543:   res = 0;
        !          2544: 
        !          2545:   /* store the result: */
        !          2546:   *((tme_uint32_t *) _op1) = res;
        !          2547: 
        !          2548:   /* set the flags: */
        !          2549:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2550:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2551:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2552:   ic->tme_m68k_ireg_ccr = flags;
        !          2553: 
        !          2554:   TME_M68K_INSN_OK;
        !          2555: }
        !          2556: 
        !          2557: /* this does a 32-bit "negx DST": */
        !          2558: TME_M68K_INSN(tme_m68k_negx32)
        !          2559: {
        !          2560:   tme_uint32_t res, op1;
        !          2561:   tme_uint8_t flags;
        !          2562: 
        !          2563:   /* load the operand(s): */
        !          2564:   op1 = *((tme_uint32_t *) _op1);
        !          2565: 
        !          2566:   /* perform the operation: */
        !          2567:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          2568: 
        !          2569:   /* store the result: */
        !          2570:   *((tme_uint32_t *) _op1) = res;
        !          2571: 
        !          2572:   /* set the flags: */
        !          2573:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2574:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          2575:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2576:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2577:   ic->tme_m68k_ireg_ccr = flags;
        !          2578: 
        !          2579:   TME_M68K_INSN_OK;
        !          2580: }
        !          2581: 
        !          2582: /* this does a 32-bit "addx SRC, DST": */
        !          2583: TME_M68K_INSN(tme_m68k_addx32)
        !          2584: {
        !          2585:   tme_uint32_t res, op0, op1;
        !          2586:   tme_uint8_t flags;
        !          2587: 
        !          2588:   /* load the operand(s): */
        !          2589:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          2590:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          2591:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          2592:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
        !          2593:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
        !          2594:   tme_uint16_t memory;
        !          2595: 
        !          2596:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !          2597:   if (memory) {
        !          2598:     TME_M68K_INSN_CANFAULT;
        !          2599:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2600:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !          2601:       ic->_tme_m68k_ea_function_code = function_code;
        !          2602:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          2603:     }
        !          2604:     tme_m68k_read_memx32(ic);
        !          2605:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2606:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !          2607:       ic->_tme_m68k_ea_function_code = function_code;
        !          2608:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          2609:     }
        !          2610:     tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
        !          2611:     op1 = ic->tme_m68k_ireg_memx32;
        !          2612:     op0 = ic->tme_m68k_ireg_memy32;
        !          2613:   }
        !          2614:   else {
        !          2615:     op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src));
        !          2616:     op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst));
        !          2617:   }
        !          2618: 
        !          2619:   /* perform the operation: */
        !          2620:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          2621: 
        !          2622:   /* store the result: */
        !          2623:   if (memory) {
        !          2624:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2625:       ic->tme_m68k_ireg_memx32 = res;
        !          2626:       ic->_tme_m68k_ea_function_code = function_code;
        !          2627:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          2628:     }
        !          2629:     tme_m68k_write_memx32(ic);
        !          2630:   }
        !          2631:   else {
        !          2632:     ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res;
        !          2633:   }
        !          2634: 
        !          2635:   /* set the flags: */
        !          2636:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2637:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          2638:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2639:   if (op0 > (op1 ^ 0xffffffff) || (op0 == (op1 ^ 0xffffffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2640:   ic->tme_m68k_ireg_ccr = flags;
        !          2641: 
        !          2642:   TME_M68K_INSN_OK;
        !          2643: }
        !          2644: 
        !          2645: /* this does a 32-bit "subx SRC, DST": */
        !          2646: TME_M68K_INSN(tme_m68k_subx32)
        !          2647: {
        !          2648:   tme_uint32_t res, op0, op1;
        !          2649:   tme_uint8_t flags;
        !          2650: 
        !          2651:   /* load the operand(s): */
        !          2652:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          2653:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          2654:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          2655:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
        !          2656:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
        !          2657:   tme_uint16_t memory;
        !          2658: 
        !          2659:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
        !          2660:   if (memory) {
        !          2661:     TME_M68K_INSN_CANFAULT;
        !          2662:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2663:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
        !          2664:       ic->_tme_m68k_ea_function_code = function_code;
        !          2665:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          2666:     }
        !          2667:     tme_m68k_read_memx32(ic);
        !          2668:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2669:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
        !          2670:       ic->_tme_m68k_ea_function_code = function_code;
        !          2671:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          2672:     }
        !          2673:     tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
        !          2674:     op1 = ic->tme_m68k_ireg_memx32;
        !          2675:     op0 = ic->tme_m68k_ireg_memy32;
        !          2676:   }
        !          2677:   else {
        !          2678:     op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src));
        !          2679:     op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst));
        !          2680:   }
        !          2681: 
        !          2682:   /* perform the operation: */
        !          2683:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
        !          2684: 
        !          2685:   /* store the result: */
        !          2686:   if (memory) {
        !          2687:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2688:       ic->tme_m68k_ireg_memx32 = res;
        !          2689:       ic->_tme_m68k_ea_function_code = function_code;
        !          2690:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          2691:     }
        !          2692:     tme_m68k_write_memx32(ic);
        !          2693:   }
        !          2694:   else {
        !          2695:     ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res;
        !          2696:   }
        !          2697: 
        !          2698:   /* set the flags: */
        !          2699:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2700:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
        !          2701:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2702:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          2703:   ic->tme_m68k_ireg_ccr = flags;
        !          2704: 
        !          2705:   TME_M68K_INSN_OK;
        !          2706: }
        !          2707: 
        !          2708: /* this does a 32-bit "cmpm SRC, DST": */
        !          2709: TME_M68K_INSN(tme_m68k_cmpm32)
        !          2710: {
        !          2711:   tme_uint32_t res, op0, op1;
        !          2712:   tme_uint8_t flags;
        !          2713: 
        !          2714:   /* load the operand(s): */
        !          2715:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          2716:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          2717:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          2718:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
        !          2719:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
        !          2720: 
        !          2721:   TME_M68K_INSN_CANFAULT;
        !          2722: 
        !          2723:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2724:     ic->_tme_m68k_ea_function_code = function_code;
        !          2725:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
        !          2726:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
        !          2727:   }
        !          2728:   tme_m68k_read_memx32(ic);
        !          2729:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          2730:     ic->_tme_m68k_ea_function_code = function_code;
        !          2731:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
        !          2732:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
        !          2733:   }
        !          2734:   tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
        !          2735:   op1 = ic->tme_m68k_ireg_memx32;
        !          2736:   op0 = ic->tme_m68k_ireg_memy32;
        !          2737: 
        !          2738:   /* perform the operation: */
        !          2739:   res = op1 - op0;
        !          2740: 
        !          2741:   /* set the flags: */
        !          2742:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2743:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2744:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
        !          2745:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
        !          2746:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
        !          2747:   ic->tme_m68k_ireg_ccr = flags;
        !          2748: 
        !          2749:   TME_M68K_INSN_OK;
        !          2750: }
        !          2751: 
        !          2752: /* the suba function on a 32-byte EA: */
        !          2753: TME_M68K_INSN(tme_m68k_suba32)
        !          2754: {
        !          2755:   *((tme_int32_t *) _op1) -= *((tme_int32_t *) _op0);
        !          2756:   TME_M68K_INSN_OK;
        !          2757: }
        !          2758: 
        !          2759: /* the adda function on a 32-byte EA: */
        !          2760: TME_M68K_INSN(tme_m68k_adda32)
        !          2761: {
        !          2762:   *((tme_int32_t *) _op1) += *((tme_int32_t *) _op0);
        !          2763:   TME_M68K_INSN_OK;
        !          2764: }
        !          2765: 
        !          2766: /* the movea function on a 32-byte EA: */
        !          2767: TME_M68K_INSN(tme_m68k_movea32)
        !          2768: {
        !          2769:   *((tme_int32_t *) _op0) = *((tme_int32_t *) _op1);
        !          2770:   TME_M68K_INSN_OK;
        !          2771: }
        !          2772: 
        !          2773: /* the btst function on a 32-byte EA: */
        !          2774: TME_M68K_INSN(tme_m68k_btst32)
        !          2775: {
        !          2776:   tme_uint32_t value, bit;
        !          2777:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
        !          2778:   value = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2779:   if (value & bit) {
        !          2780:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !          2781:   }
        !          2782:   else {
        !          2783:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !          2784:   }
        !          2785:   TME_M68K_INSN_OK;
        !          2786: }
        !          2787: 
        !          2788: /* the bchg function on a 32-byte EA: */
        !          2789: TME_M68K_INSN(tme_m68k_bchg32)
        !          2790: {
        !          2791:   tme_uint32_t value, bit;
        !          2792:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
        !          2793:   value = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2794:   if (value & bit) {
        !          2795:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !          2796:   }
        !          2797:   else {
        !          2798:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !          2799:   }
        !          2800:   TME_M68K_INSN_OP1(tme_uint32_t) = value ^ bit;
        !          2801:   TME_M68K_INSN_OK;
        !          2802: }
        !          2803: 
        !          2804: /* the bclr function on a 32-byte EA: */
        !          2805: TME_M68K_INSN(tme_m68k_bclr32)
        !          2806: {
        !          2807:   tme_uint32_t value, bit;
        !          2808:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
        !          2809:   value = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2810:   if (value & bit) {
        !          2811:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !          2812:   }
        !          2813:   else {
        !          2814:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !          2815:   }
        !          2816:   TME_M68K_INSN_OP1(tme_uint32_t) = value & ~bit;
        !          2817:   TME_M68K_INSN_OK;
        !          2818: }
        !          2819: 
        !          2820: /* the bset function on a 32-byte EA: */
        !          2821: TME_M68K_INSN(tme_m68k_bset32)
        !          2822: {
        !          2823:   tme_uint32_t value, bit;
        !          2824:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
        !          2825:   value = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2826:   if (value & bit) {
        !          2827:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
        !          2828:   }
        !          2829:   else {
        !          2830:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
        !          2831:   }
        !          2832:   TME_M68K_INSN_OP1(tme_uint32_t) = value | bit;
        !          2833:   TME_M68K_INSN_OK;
        !          2834: }
        !          2835: 
        !          2836: /* the asl function on a 32-byte EA: */
        !          2837: TME_M68K_INSN(tme_m68k_asl32)
        !          2838: {
        !          2839:   unsigned int count;
        !          2840:   tme_uint32_t sign_bits;
        !          2841:   tme_uint32_t res;
        !          2842:   tme_uint8_t flags;
        !          2843: 
        !          2844:   /* get the count and operand: */
        !          2845:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          2846:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2847: 
        !          2848:   /* generate the X, V, and C flags assuming the count is zero: */
        !          2849:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          2850: 
        !          2851:   /* if the count is nonzero, update the result and
        !          2852:      generate the X, V, and C flags: */
        !          2853:   if (count > 0) {
        !          2854: 
        !          2855:     /* we need to see how the sign of the result will change during
        !          2856:        shifting in order to generate V.
        !          2857: 
        !          2858:        in general, the idea is to get all of the bits that will ever
        !          2859:        appear in the sign position into sign_bits; if sign_bits is
        !          2860:        all-bits-one or all-bits zero, clear V, else set V.  a good trick
        !          2861:        is that ((sign_bits + 1) & sign_bits) is nonzero iff all of the
        !          2862:        bits in sign_bits are the same.
        !          2863: 
        !          2864:        start by loading all of the operand into sign_bits.
        !          2865: 
        !          2866:        if the shift count is exactly 32 - 1, then all of the bits
        !          2867:        of the operand will appear in the sign position.
        !          2868: 
        !          2869:        if the shift count is less than 32 - 1, then some of the
        !          2870:        less significant bits of the operand will never appear in the
        !          2871:        sign position, so we can shift them off of sign_bits now.
        !          2872: 
        !          2873:        if the shift count is greater than 32 - 1, then all of the
        !          2874:        bits in the operand, plus at least one zero bit, will appear in
        !          2875:        the sign position.  the only way that the sign bit will never
        !          2876:        change during the shift is if the operand was zero to begin with.
        !          2877:        we need to change sign_bits such that ((sign_bits + 1) &
        !          2878:        sign_bits) will be zero iff the operand was zero to begin with.
        !          2879:        the magic below does just that: */
        !          2880:     sign_bits = res;
        !          2881:     if (63 > SHIFTMAX_INT32_T
        !          2882:         && count > 32) {
        !          2883:       res = 0;
        !          2884:     }
        !          2885:     res <<= (count - 1);
        !          2886:     flags = (res >> (32 - 1));
        !          2887:     flags *= TME_M68K_FLAG_C;
        !          2888:     flags |= (flags * TME_M68K_FLAG_X);
        !          2889:     res <<= 1;
        !          2890:     if (count != 32 - 1) {
        !          2891:       if (count < 32) {
        !          2892:         sign_bits >>= ((32 - 1) - count);
        !          2893:       }
        !          2894:       else {
        !          2895:         sign_bits |= (sign_bits << 1);
        !          2896:         sign_bits &= -2;
        !          2897:       }
        !          2898:     }
        !          2899:     if ((sign_bits + 1) & sign_bits) {
        !          2900:       flags |= TME_M68K_FLAG_V;
        !          2901:     }
        !          2902:   }
        !          2903: 
        !          2904:   /* store the result: */
        !          2905:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          2906: 
        !          2907:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          2908:      know the bit we want is within the range of the type, to try
        !          2909:      to affect the generated assembly: */
        !          2910:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2911: 
        !          2912:   /* generate the Z flag: */
        !          2913:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2914: 
        !          2915:   /* store the flags: */
        !          2916:   ic->tme_m68k_ireg_ccr = flags;
        !          2917:   TME_M68K_INSN_OK;
        !          2918: }
        !          2919: 
        !          2920: /* the asr function on a 32-byte EA: */
        !          2921: TME_M68K_INSN(tme_m68k_asr32)
        !          2922: {
        !          2923:   unsigned int count;
        !          2924:   tme_int32_t res;
        !          2925:   tme_uint8_t flags;
        !          2926: 
        !          2927:   /* get the count and operand: */
        !          2928:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          2929:   res = TME_M68K_INSN_OP1(tme_int32_t);
        !          2930: 
        !          2931:   /* generate the X, V, and C flags assuming the count is zero: */
        !          2932:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          2933: 
        !          2934:   /* if the count is nonzero, update the result and
        !          2935:      generate the X, V, and C flags: */
        !          2936:   if (count > 0) {
        !          2937:     if (63 > SHIFTMAX_INT32_T
        !          2938:         && count > 32) {
        !          2939:       res = 0;
        !          2940:     }
        !          2941:     res >>= (count - 1);
        !          2942:     flags = (res & 1);
        !          2943:     flags *= TME_M68K_FLAG_C;
        !          2944:     flags |= (flags * TME_M68K_FLAG_X);
        !          2945:     res >>= 1;
        !          2946:   }
        !          2947: 
        !          2948:   /* store the result: */
        !          2949:   TME_M68K_INSN_OP1(tme_int32_t) = res;
        !          2950: 
        !          2951:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          2952:      know the bit we want is within the range of the type, to try
        !          2953:      to affect the generated assembly: */
        !          2954:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2955: 
        !          2956:   /* generate the Z flag: */
        !          2957:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          2958: 
        !          2959:   /* store the flags: */
        !          2960:   ic->tme_m68k_ireg_ccr = flags;
        !          2961:   TME_M68K_INSN_OK;
        !          2962: }
        !          2963: 
        !          2964: /* the lsl function on a 32-byte EA: */
        !          2965: TME_M68K_INSN(tme_m68k_lsl32)
        !          2966: {
        !          2967:   unsigned int count;
        !          2968:   tme_uint32_t res;
        !          2969:   tme_uint8_t flags;
        !          2970: 
        !          2971:   /* get the count and operand: */
        !          2972:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          2973:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          2974: 
        !          2975:   /* generate the X, V, and C flags assuming the count is zero: */
        !          2976:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          2977: 
        !          2978:   /* if the count is nonzero, update the result and
        !          2979:      generate the X, V, and C flags: */
        !          2980:   if (count > 0) {
        !          2981:     if (63 > SHIFTMAX_INT32_T
        !          2982:         && count > 32) {
        !          2983:       res = 0;
        !          2984:     }
        !          2985:     res <<= (count - 1);
        !          2986:     flags = (res >> (32 - 1));
        !          2987:     flags *= TME_M68K_FLAG_C;
        !          2988:     flags |= (flags * TME_M68K_FLAG_X);
        !          2989:     res <<= 1;
        !          2990:   }
        !          2991: 
        !          2992:   /* store the result: */
        !          2993:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          2994: 
        !          2995:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          2996:      know the bit we want is within the range of the type, to try
        !          2997:      to affect the generated assembly: */
        !          2998:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          2999: 
        !          3000:   /* generate the Z flag: */
        !          3001:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3002: 
        !          3003:   /* store the flags: */
        !          3004:   ic->tme_m68k_ireg_ccr = flags;
        !          3005:   TME_M68K_INSN_OK;
        !          3006: }
        !          3007: 
        !          3008: /* the lsr function on a 32-byte EA: */
        !          3009: TME_M68K_INSN(tme_m68k_lsr32)
        !          3010: {
        !          3011:   unsigned int count;
        !          3012:   tme_uint32_t res;
        !          3013:   tme_uint8_t flags;
        !          3014: 
        !          3015:   /* get the count and operand: */
        !          3016:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          3017:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3018: 
        !          3019:   /* generate the X, V, and C flags assuming the count is zero: */
        !          3020:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          3021: 
        !          3022:   /* if the count is nonzero, update the result and
        !          3023:      generate the X, V, and C flags: */
        !          3024:   if (count > 0) {
        !          3025:     if (63 > SHIFTMAX_INT32_T
        !          3026:         && count > 32) {
        !          3027:       res = 0;
        !          3028:     }
        !          3029:     res >>= (count - 1);
        !          3030:     flags = (res & 1);
        !          3031:     flags *= TME_M68K_FLAG_C;
        !          3032:     flags |= (flags * TME_M68K_FLAG_X);
        !          3033:     res >>= 1;
        !          3034:   }
        !          3035: 
        !          3036:   /* store the result: */
        !          3037:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          3038: 
        !          3039:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          3040:      know the bit we want is within the range of the type, to try
        !          3041:      to affect the generated assembly: */
        !          3042:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          3043: 
        !          3044:   /* generate the Z flag: */
        !          3045:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3046: 
        !          3047:   /* store the flags: */
        !          3048:   ic->tme_m68k_ireg_ccr = flags;
        !          3049:   TME_M68K_INSN_OK;
        !          3050: }
        !          3051: 
        !          3052: /* the rol function on a 32-byte EA: */
        !          3053: TME_M68K_INSN(tme_m68k_rol32)
        !          3054: {
        !          3055:   unsigned int count;
        !          3056:   tme_uint32_t res;
        !          3057:   tme_uint8_t flags;
        !          3058: 
        !          3059:   /* get the count and operand: */
        !          3060:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          3061:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3062: 
        !          3063:   /* generate the X, V, and C flags assuming the count is zero: */
        !          3064:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          3065: 
        !          3066:   /* if the count is nonzero, update the result and
        !          3067:      generate the X, V, and C flags: */
        !          3068:   if (count > 0) {
        !          3069:     count &= (32 - 1);
        !          3070:     res = (res << count) | (res >> (32 - count));
        !          3071:     flags |= ((res & 1) * TME_M68K_FLAG_C);
        !          3072:   }
        !          3073: 
        !          3074:   /* store the result: */
        !          3075:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          3076: 
        !          3077:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          3078:      know the bit we want is within the range of the type, to try
        !          3079:      to affect the generated assembly: */
        !          3080:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          3081: 
        !          3082:   /* generate the Z flag: */
        !          3083:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3084: 
        !          3085:   /* store the flags: */
        !          3086:   ic->tme_m68k_ireg_ccr = flags;
        !          3087:   TME_M68K_INSN_OK;
        !          3088: }
        !          3089: 
        !          3090: /* the ror function on a 32-byte EA: */
        !          3091: TME_M68K_INSN(tme_m68k_ror32)
        !          3092: {
        !          3093:   unsigned int count;
        !          3094:   tme_uint32_t res;
        !          3095:   tme_uint8_t flags;
        !          3096: 
        !          3097:   /* get the count and operand: */
        !          3098:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          3099:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3100: 
        !          3101:   /* generate the X, V, and C flags assuming the count is zero: */
        !          3102:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          3103: 
        !          3104:   /* if the count is nonzero, update the result and
        !          3105:      generate the X, V, and C flags: */
        !          3106:   if (count > 0) {
        !          3107:     count &= (32 - 1);
        !          3108:     res = (res << (32 - count)) | (res >> count);
        !          3109:     flags |= ((res >> (32 - 1)) * TME_M68K_FLAG_C);
        !          3110:   }
        !          3111: 
        !          3112:   /* store the result: */
        !          3113:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          3114: 
        !          3115:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          3116:      know the bit we want is within the range of the type, to try
        !          3117:      to affect the generated assembly: */
        !          3118:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          3119: 
        !          3120:   /* generate the Z flag: */
        !          3121:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3122: 
        !          3123:   /* store the flags: */
        !          3124:   ic->tme_m68k_ireg_ccr = flags;
        !          3125:   TME_M68K_INSN_OK;
        !          3126: }
        !          3127: 
        !          3128: /* the roxl function on a 32-byte EA: */
        !          3129: TME_M68K_INSN(tme_m68k_roxl32)
        !          3130: {
        !          3131:   unsigned int count;
        !          3132:   tme_uint8_t xbit;
        !          3133:   tme_uint32_t res;
        !          3134:   tme_uint8_t flags;
        !          3135: 
        !          3136:   /* get the count and operand: */
        !          3137:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          3138:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3139: 
        !          3140:   /* generate the X, V, and C flags assuming the count is zero: */
        !          3141:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          3142:   xbit = (flags / TME_M68K_FLAG_X);
        !          3143:   flags |= (xbit * TME_M68K_FLAG_C);
        !          3144: 
        !          3145:   /* if the count is nonzero, update the result and
        !          3146:      generate the X, V, and C flags: */
        !          3147:   if (count > 0) {
        !          3148:     count %= (32 + 1);
        !          3149:     flags = xbit;
        !          3150:     if (count > 0) {
        !          3151:       flags = (res >> (32 - count)) & 1;
        !          3152:       if (32 > SHIFTMAX_INT32_T
        !          3153:           && count == 32) {
        !          3154:         res = 0 | (xbit << (32 - 1)) | (res >> ((32 + 1) - 32));
        !          3155:       }
        !          3156:       else if (32 > SHIFTMAX_INT32_T
        !          3157:                && count == 1) {
        !          3158:         res = (res << 1) | (xbit << (1 - 1)) | 0;
        !          3159:       }
        !          3160:       else {
        !          3161:         res = (res << count) | (xbit << (count - 1)) | (res >> ((32 + 1) - count));
        !          3162:       }
        !          3163:     }
        !          3164:     flags *= TME_M68K_FLAG_C;
        !          3165:     flags |= (flags * TME_M68K_FLAG_X);
        !          3166:   }
        !          3167: 
        !          3168:   /* store the result: */
        !          3169:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          3170: 
        !          3171:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          3172:      know the bit we want is within the range of the type, to try
        !          3173:      to affect the generated assembly: */
        !          3174:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          3175: 
        !          3176:   /* generate the Z flag: */
        !          3177:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3178: 
        !          3179:   /* store the flags: */
        !          3180:   ic->tme_m68k_ireg_ccr = flags;
        !          3181:   TME_M68K_INSN_OK;
        !          3182: }
        !          3183: 
        !          3184: /* the roxr function on a 32-byte EA: */
        !          3185: TME_M68K_INSN(tme_m68k_roxr32)
        !          3186: {
        !          3187:   unsigned int count;
        !          3188:   tme_uint8_t xbit;
        !          3189:   tme_uint32_t res;
        !          3190:   tme_uint8_t flags;
        !          3191: 
        !          3192:   /* get the count and operand: */
        !          3193:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
        !          3194:   res = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3195: 
        !          3196:   /* generate the X, V, and C flags assuming the count is zero: */
        !          3197:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          3198:   xbit = (flags / TME_M68K_FLAG_X);
        !          3199:   flags |= (xbit * TME_M68K_FLAG_C);
        !          3200: 
        !          3201:   /* if the count is nonzero, update the result and
        !          3202:      generate the X, V, and C flags: */
        !          3203:   if (count > 0) {
        !          3204:     count %= (32 + 1);
        !          3205:     flags = xbit;
        !          3206:     if (count > 0) {
        !          3207:       flags = (res >> (count - 1)) & 1;
        !          3208:       if (32 > SHIFTMAX_INT32_T
        !          3209:           && count == 32) {
        !          3210:         res = (res << ((32 + 1) - 32)) | (xbit << (32 - 32)) | 0;
        !          3211:       }
        !          3212:       else if (32 > SHIFTMAX_INT32_T
        !          3213:                && count == 1) {
        !          3214:         res = 0 | (xbit << (32 - 1)) | (res >> 1);
        !          3215:       }
        !          3216:       else {
        !          3217:         res = (res << ((32 + 1) - count)) | (xbit << (32 - count)) | (res >> count);
        !          3218:       }
        !          3219:     }
        !          3220:     flags *= TME_M68K_FLAG_C;
        !          3221:     flags |= (flags * TME_M68K_FLAG_X);
        !          3222:   }
        !          3223: 
        !          3224:   /* store the result: */
        !          3225:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
        !          3226: 
        !          3227:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
        !          3228:      know the bit we want is within the range of the type, to try
        !          3229:      to affect the generated assembly: */
        !          3230:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
        !          3231: 
        !          3232:   /* generate the Z flag: */
        !          3233:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          3234: 
        !          3235:   /* store the flags: */
        !          3236:   ic->tme_m68k_ireg_ccr = flags;
        !          3237:   TME_M68K_INSN_OK;
        !          3238: }
        !          3239: 
        !          3240: /* the movep_rm function on a 32-bit dreg: */
        !          3241: TME_M68K_INSN(tme_m68k_movep_rm32)
        !          3242: {
        !          3243:   unsigned int function_code;
        !          3244:   tme_uint32_t linear_address;
        !          3245:   tme_uint32_t value;
        !          3246:   int dreg;
        !          3247: 
        !          3248:   TME_M68K_INSN_CANFAULT;
        !          3249: 
        !          3250:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          3251:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3252:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
        !          3253:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          3254:   value = ic->tme_m68k_ireg_uint32(dreg);
        !          3255:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3256:     ic->_tme_m68k_ea_function_code = function_code;
        !          3257:     ic->_tme_m68k_ea_address = linear_address;
        !          3258:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 24, 8);
        !          3259:   }
        !          3260:   tme_m68k_write_memx8(ic);
        !          3261:   linear_address += 2;
        !          3262:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3263:     ic->_tme_m68k_ea_function_code = function_code;
        !          3264:     ic->_tme_m68k_ea_address = linear_address;
        !          3265:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 16, 8);
        !          3266:   }
        !          3267:   tme_m68k_write_memx8(ic);
        !          3268:   linear_address += 2;
        !          3269:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3270:     ic->_tme_m68k_ea_function_code = function_code;
        !          3271:     ic->_tme_m68k_ea_address = linear_address;
        !          3272:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8);
        !          3273:   }
        !          3274:   tme_m68k_write_memx8(ic);
        !          3275:   linear_address += 2;
        !          3276:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3277:     ic->_tme_m68k_ea_function_code = function_code;
        !          3278:     ic->_tme_m68k_ea_address = linear_address;
        !          3279:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8);
        !          3280:   }
        !          3281:   tme_m68k_write_memx8(ic);
        !          3282:   linear_address += 2;
        !          3283:   TME_M68K_INSN_OK;
        !          3284: }
        !          3285: 
        !          3286: /* the movem_rm function on 32-bit registers: */
        !          3287: TME_M68K_INSN(tme_m68k_movem_rm32)
        !          3288: {
        !          3289:   int ireg, direction;
        !          3290:   tme_uint16_t mask, bit;
        !          3291:   unsigned int ea_mode;
        !          3292:   tme_uint32_t addend;
        !          3293: 
        !          3294:   TME_M68K_INSN_CANFAULT;
        !          3295: 
        !          3296:   /* figure out what direction to move in, and where to start from: */
        !          3297:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
        !          3298:   direction = 1;
        !          3299:   ireg = TME_M68K_IREG_D0;
        !          3300:   if (ea_mode == 4) {
        !          3301:     direction = -1;
        !          3302:     ireg = TME_M68K_IREG_A7;
        !          3303:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3304:       ic->_tme_m68k_ea_address -= sizeof(tme_uint32_t);
        !          3305:     }
        !          3306:   }
        !          3307:   addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t));
        !          3308: 
        !          3309:   /* do the transfer: */
        !          3310:   mask = TME_M68K_INSN_SPECOP;
        !          3311:   for (bit = 1; bit != 0; bit <<= 1) {
        !          3312:     if (mask & bit) {
        !          3313:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3314:         ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg);
        !          3315:       }
        !          3316:       tme_m68k_write_memx32(ic);
        !          3317:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3318:         ic->_tme_m68k_ea_address += addend;
        !          3319:       }
        !          3320:     }
        !          3321:     ireg += direction;
        !          3322:   }
        !          3323: 
        !          3324:   /* if this is the predecrement mode, update the address register: */
        !          3325:   if (ea_mode == 4) {
        !          3326:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
        !          3327:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
        !          3328:       = (ic->_tme_m68k_ea_address + sizeof(tme_uint32_t));
        !          3329:   }
        !          3330:   TME_M68K_INSN_OK;
        !          3331: }
        !          3332: 
        !          3333: /* the movep_mr function on a 32-bit dreg: */
        !          3334: TME_M68K_INSN(tme_m68k_movep_mr32)
        !          3335: {
        !          3336:   unsigned int function_code;
        !          3337:   tme_uint32_t linear_address;
        !          3338:   int dreg;
        !          3339: 
        !          3340:   TME_M68K_INSN_CANFAULT;
        !          3341: 
        !          3342:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          3343:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
        !          3344:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
        !          3345:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          3346:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3347:     ic->_tme_m68k_ea_function_code = function_code;
        !          3348:     ic->_tme_m68k_ea_address = linear_address;
        !          3349:   }
        !          3350:   tme_m68k_read_memx8(ic);
        !          3351:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3352:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 24, 8, ic->tme_m68k_ireg_memx8);
        !          3353:   }
        !          3354:   linear_address += 2;
        !          3355:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3356:     ic->_tme_m68k_ea_function_code = function_code;
        !          3357:     ic->_tme_m68k_ea_address = linear_address;
        !          3358:   }
        !          3359:   tme_m68k_read_memx8(ic);
        !          3360:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3361:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 16, 8, ic->tme_m68k_ireg_memx8);
        !          3362:   }
        !          3363:   linear_address += 2;
        !          3364:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3365:     ic->_tme_m68k_ea_function_code = function_code;
        !          3366:     ic->_tme_m68k_ea_address = linear_address;
        !          3367:   }
        !          3368:   tme_m68k_read_memx8(ic);
        !          3369:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3370:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 8, 8, ic->tme_m68k_ireg_memx8);
        !          3371:   }
        !          3372:   linear_address += 2;
        !          3373:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3374:     ic->_tme_m68k_ea_function_code = function_code;
        !          3375:     ic->_tme_m68k_ea_address = linear_address;
        !          3376:   }
        !          3377:   tme_m68k_read_memx8(ic);
        !          3378:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3379:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 0, 8, ic->tme_m68k_ireg_memx8);
        !          3380:   }
        !          3381:   linear_address += 2;
        !          3382:   TME_M68K_INSN_OK;
        !          3383: }
        !          3384: 
        !          3385: /* the movem_mr function on 32-bit registers: */
        !          3386: TME_M68K_INSN(tme_m68k_movem_mr32)
        !          3387: {
        !          3388:   int ireg, direction;
        !          3389:   tme_uint16_t mask, bit;
        !          3390:   unsigned int ea_mode;
        !          3391:   tme_uint32_t addend;
        !          3392: 
        !          3393:   TME_M68K_INSN_CANFAULT;
        !          3394: 
        !          3395:   /* figure out what direction to move in, and where to start from: */
        !          3396:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
        !          3397:   direction = 1;
        !          3398:   ireg = TME_M68K_IREG_D0;
        !          3399:   addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t));
        !          3400: 
        !          3401:   /* do the transfer: */
        !          3402:   mask = TME_M68K_INSN_SPECOP;
        !          3403:   for (bit = 1; bit != 0; bit <<= 1) {
        !          3404:     if (mask & bit) {
        !          3405:       tme_m68k_read_memx32(ic);
        !          3406:       if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          3407:         ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32;
        !          3408:         ic->_tme_m68k_ea_address += addend;
        !          3409:       }
        !          3410:     }
        !          3411:     ireg += direction;
        !          3412:   }
        !          3413: 
        !          3414:   /* if this is the postincrement mode, update the address register: */
        !          3415:   if (ea_mode == 3) {
        !          3416:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
        !          3417:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
        !          3418:       = ic->_tme_m68k_ea_address;
        !          3419:   }
        !          3420:   TME_M68K_INSN_OK;
        !          3421: }
        !          3422: 
        !          3423: /* chk32: */
        !          3424: TME_M68K_INSN(tme_m68k_chk32)
        !          3425: {
        !          3426:   if (*((tme_int32_t *) _op0) < 0) {
        !          3427:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N;
        !          3428:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          3429:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
        !          3430:   }
        !          3431:   if (*((tme_int32_t *) _op0) > *((tme_int32_t *) _op1)) {
        !          3432:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N;
        !          3433:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          3434:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
        !          3435:   }
        !          3436:   TME_M68K_INSN_OK;
        !          3437: }
        !          3438: 
        !          3439: /* cas32: */
        !          3440: TME_M68K_INSN(tme_m68k_cas32)
        !          3441: {
        !          3442:   struct tme_m68k_tlb *tlb;
        !          3443:   int ireg_dc, ireg_du;
        !          3444:   int do_write;
        !          3445:   tme_uint16_t specopx = ic->_tme_m68k_insn_specop;
        !          3446: 
        !          3447:   /* start the read/modify/write cycle: */
        !          3448:   tlb = tme_m68k_rmw_start(ic);
        !          3449:   if (tlb == NULL) {
        !          3450:     TME_M68K_INSN_OK;
        !          3451:   }
        !          3452: 
        !          3453:   /* read: */
        !          3454:   tme_m68k_read32(ic, tlb,
        !          3455:                   &ic->_tme_m68k_ea_function_code,
        !          3456:                   &ic->_tme_m68k_ea_address,
        !          3457:                   &ic->tme_m68k_ireg_memx32,
        !          3458:                   TME_M68K_BUS_CYCLE_RMW);
        !          3459: 
        !          3460:   /* modify: */
        !          3461:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          3462:   tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memx32);
        !          3463: 
        !          3464:   /* write: */
        !          3465:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          3466:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
        !          3467:     ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_du);
        !          3468:     tme_m68k_write32(ic, tlb,
        !          3469:                      &ic->_tme_m68k_ea_function_code,
        !          3470:                      &ic->_tme_m68k_ea_address,
        !          3471:                      &ic->tme_m68k_ireg_memx32,
        !          3472:                      TME_M68K_BUS_CYCLE_RMW);
        !          3473:   }
        !          3474:   else {
        !          3475:     /* XXX the 68040 always does a write to finish its cycle: */
        !          3476:     do_write = FALSE;
        !          3477:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          3478:     if (do_write) {
        !          3479:       tme_m68k_write32(ic, tlb,
        !          3480:                        &ic->_tme_m68k_ea_function_code,
        !          3481:                        &ic->_tme_m68k_ea_address,
        !          3482:                        &ic->tme_m68k_ireg_memx32,
        !          3483:                        TME_M68K_BUS_CYCLE_RMW);
        !          3484:       do_write = FALSE;
        !          3485:     }
        !          3486:     ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memx32;
        !          3487:   }
        !          3488: 
        !          3489:   /* finish the read/modify/write cycle: */
        !          3490:   tme_m68k_rmw_finish(ic, tlb);
        !          3491: 
        !          3492:   TME_M68K_INSN_OK;
        !          3493: }
        !          3494: 
        !          3495: /* cas2_32: */
        !          3496: TME_M68K_INSN(tme_m68k_cas2_32)
        !          3497: {
        !          3498:   struct tme_m68k_tlb *tlb;
        !          3499:   int ireg_dc, ireg_du;
        !          3500:   int do_write;
        !          3501:   tme_uint16_t specopx = ic->_tme_m68k_insn_specop;
        !          3502:   tme_uint16_t specopy = ic->_tme_m68k_insn_specop2;
        !          3503:   tme_uint32_t addrx;
        !          3504:   tme_uint32_t addry;
        !          3505: 
        !          3506:   /* get the function code and addresses we'll be dealing with: */
        !          3507:   ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          3508:   addrx = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
        !          3509:                                    + TME_FIELD_EXTRACTU(specopx, 12, 4));
        !          3510:   addry = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
        !          3511:                                    + TME_FIELD_EXTRACTU(specopy, 12, 4));
        !          3512: 
        !          3513:   /* start the read/modify/write cycle: */
        !          3514:   tlb = tme_m68k_rmw_start(ic);
        !          3515:   if (tlb == NULL) {
        !          3516:     TME_M68K_INSN_OK;
        !          3517:   }
        !          3518: 
        !          3519:   /* read: */
        !          3520:   ic->_tme_m68k_ea_address = addrx;
        !          3521:   tme_m68k_read32(ic, tlb,
        !          3522:                   &ic->_tme_m68k_ea_function_code,
        !          3523:                   &ic->_tme_m68k_ea_address,
        !          3524:                   &ic->tme_m68k_ireg_memx32,
        !          3525:                   TME_M68K_BUS_CYCLE_RMW);
        !          3526:   ic->_tme_m68k_ea_address = addry;
        !          3527:   tme_m68k_read32(ic, tlb,
        !          3528:                   &ic->_tme_m68k_ea_function_code,
        !          3529:                   &ic->_tme_m68k_ea_address,
        !          3530:                   &ic->tme_m68k_ireg_memy32,
        !          3531:                   TME_M68K_BUS_CYCLE_RMW);
        !          3532: 
        !          3533:   /* modify: */
        !          3534:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          3535:   tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memx32);
        !          3536:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          3537:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
        !          3538:     tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memy32);
        !          3539:   }
        !          3540: 
        !          3541:   /* write: */
        !          3542:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
        !          3543:     ic->_tme_m68k_ea_address = addrx;
        !          3544:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
        !          3545:     ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_du);
        !          3546:     tme_m68k_write32(ic, tlb,
        !          3547:                      &ic->_tme_m68k_ea_function_code,
        !          3548:                      &ic->_tme_m68k_ea_address,
        !          3549:                      &ic->tme_m68k_ireg_memx32,
        !          3550:                      TME_M68K_BUS_CYCLE_RMW);
        !          3551:     ic->_tme_m68k_ea_address = addry;
        !          3552:     ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3);
        !          3553:     ic->tme_m68k_ireg_memy32 = ic->tme_m68k_ireg_uint32(ireg_du);
        !          3554:     tme_m68k_write32(ic, tlb,
        !          3555:                      &ic->_tme_m68k_ea_function_code,
        !          3556:                      &ic->_tme_m68k_ea_address,
        !          3557:                      &ic->tme_m68k_ireg_memy32,
        !          3558:                      TME_M68K_BUS_CYCLE_RMW);
        !          3559:   }
        !          3560:   else {
        !          3561:     /* XXX the 68040 always does a write to finish its cycle: */
        !          3562:     do_write = FALSE;
        !          3563:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
        !          3564:     if (do_write
        !          3565:         && ic->tme_m68k_ireg_memx32 != ic->tme_m68k_ireg_uint32(ireg_dc)) {
        !          3566:       ic->_tme_m68k_ea_address = addrx;
        !          3567:       tme_m68k_write32(ic, tlb,
        !          3568:                        &ic->_tme_m68k_ea_function_code,
        !          3569:                        &ic->_tme_m68k_ea_address,
        !          3570:                        &ic->tme_m68k_ireg_memx32,
        !          3571:                        TME_M68K_BUS_CYCLE_RMW);
        !          3572:       do_write = FALSE;
        !          3573:     }
        !          3574:     ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memx32;
        !          3575:     ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
        !          3576:     if (do_write
        !          3577:         && ic->tme_m68k_ireg_memy32 != ic->tme_m68k_ireg_uint32(ireg_dc)) {
        !          3578:       ic->_tme_m68k_ea_address = addry;
        !          3579:       tme_m68k_write32(ic, tlb,
        !          3580:                        &ic->_tme_m68k_ea_function_code,
        !          3581:                        &ic->_tme_m68k_ea_address,
        !          3582:                        &ic->tme_m68k_ireg_memy32,
        !          3583:                        TME_M68K_BUS_CYCLE_RMW);
        !          3584:       do_write = FALSE;
        !          3585:     }
        !          3586:     ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memy32;
        !          3587:   }
        !          3588: 
        !          3589:   /* finish the read/modify/write cycle: */
        !          3590:   tme_m68k_rmw_finish(ic, tlb);
        !          3591: 
        !          3592:   TME_M68K_INSN_OK;
        !          3593: }
        !          3594: 
        !          3595: /* moves32: */
        !          3596: TME_M68K_INSN(tme_m68k_moves32)
        !          3597: {
        !          3598:   int ireg;
        !          3599:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
        !          3600:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
        !          3601:     ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg);
        !          3602:   }
        !          3603:   else {
        !          3604:     ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32;
        !          3605:   }
        !          3606:   TME_M68K_INSN_OK;
        !          3607: }
        !          3608: 
        !          3609: /* this reads a 8-bit memx value: */
        !          3610: void
        !          3611: tme_m68k_read_memx8(struct tme_m68k *ic) 
        !          3612: {
        !          3613:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3614:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
        !          3615:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address);
        !          3616: 
        !          3617:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3618:      the emulator memory allocator and TLB filler must guarantee
        !          3619:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3620:      aligned, so that a 16-bit-aligned linear address gets a
        !          3621:      16-bit-aligned emulator address: */
        !          3622:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3623:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3624:                                                       function_code,
        !          3625:                                                       linear_address,
        !          3626:                                                       linear_address))) {
        !          3627: 
        !          3628:     /* for an 8-bit transfer we can always do a simple 
        !          3629:        assignment.  the rdlock is unnecessary, since we assume
        !          3630:        that 8-bit accesses are always atomic: */
        !          3631:     ic->tme_m68k_ireg_memx8 = *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address));
        !          3632:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3633:   }
        !          3634: 
        !          3635:   /* otherwise, do the bus cycles the slow way: */
        !          3636:   else {
        !          3637:     tme_m68k_read8(ic, tlb,
        !          3638:                     &ic->_tme_m68k_ea_function_code,
        !          3639:                     &ic->_tme_m68k_ea_address,
        !          3640:                     &ic->tme_m68k_ireg_memx8,
        !          3641:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3642:   }
        !          3643: 
        !          3644:   /* log the value read: */
        !          3645:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_READ);
        !          3646:   tme_m68k_log(ic, 1000, TME_OK,
        !          3647:                (TME_M68K_LOG_HANDLE(ic),
        !          3648:                 _("read_memx8\t%d:0x%08x:\t0x%02x"),
        !          3649:                 ic->_tme_m68k_ea_function_code,
        !          3650:                 ic->_tme_m68k_ea_address,
        !          3651:                 ic->tme_m68k_ireg_memx8));
        !          3652: }
        !          3653: 
        !          3654: /* this reads a 8-bit mem value: */
        !          3655: void
        !          3656: tme_m68k_read_mem8(struct tme_m68k *ic, int ireg) 
        !          3657: {
        !          3658:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3659:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
        !          3660:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address);
        !          3661: 
        !          3662:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3663:      the emulator memory allocator and TLB filler must guarantee
        !          3664:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3665:      aligned, so that a 16-bit-aligned linear address gets a
        !          3666:      16-bit-aligned emulator address: */
        !          3667:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3668:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3669:                                                       function_code,
        !          3670:                                                       linear_address,
        !          3671:                                                       linear_address))) {
        !          3672: 
        !          3673:     /* for an 8-bit transfer we can always do a simple 
        !          3674:        assignment.  the rdlock is unnecessary, since we assume
        !          3675:        that 8-bit accesses are always atomic: */
        !          3676:     ic->tme_m68k_ireg_uint8(ireg) = *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address));
        !          3677:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3678:   }
        !          3679: 
        !          3680:   /* otherwise, do the bus cycles the slow way: */
        !          3681:   else {
        !          3682:     tme_m68k_read8(ic, tlb,
        !          3683:                     &ic->_tme_m68k_ea_function_code,
        !          3684:                     &ic->_tme_m68k_ea_address,
        !          3685:                     &ic->tme_m68k_ireg_uint8(ireg),
        !          3686:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3687:   }
        !          3688: 
        !          3689:   /* log the value read: */
        !          3690:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_READ);
        !          3691:   tme_m68k_log(ic, 1000, TME_OK,
        !          3692:                (TME_M68K_LOG_HANDLE(ic),
        !          3693:                 _("read_mem8\t%d:0x%08x:\t0x%02x"),
        !          3694:                 ic->_tme_m68k_ea_function_code,
        !          3695:                 ic->_tme_m68k_ea_address,
        !          3696:                 ic->tme_m68k_ireg_uint8(ireg)));
        !          3697: }
        !          3698: 
        !          3699: /* this writes a 8-bit memx value: */
        !          3700: void
        !          3701: tme_m68k_write_memx8(struct tme_m68k *ic) 
        !          3702: {
        !          3703:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3704:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
        !          3705:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address);
        !          3706: 
        !          3707:   /* log the value written: */
        !          3708:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_WRITE);
        !          3709:   tme_m68k_log(ic, 1000, TME_OK, 
        !          3710:                (TME_M68K_LOG_HANDLE(ic),
        !          3711:                 _("write_memx8\t%d:0x%08x:\t0x%02x"),
        !          3712:                 ic->_tme_m68k_ea_function_code,
        !          3713:                 ic->_tme_m68k_ea_address,
        !          3714:                 ic->tme_m68k_ireg_memx8));
        !          3715: 
        !          3716:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3717:      the emulator memory allocator and TLB filler must guarantee
        !          3718:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          3719:      aligned, so that a 16-bit-aligned linear address gets a
        !          3720:      16-bit-aligned emulator address: */
        !          3721:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3722:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          3723:                                                       function_code,
        !          3724:                                                       linear_address,
        !          3725:                                                       linear_address))) {
        !          3726: 
        !          3727:     /* for an 8-bit transfer we can always do a simple 
        !          3728:        assignment.  the wrlock is unnecessary, since we assume
        !          3729:        that 8-bit accesses are always atomic: */
        !          3730:     *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address)) = ic->tme_m68k_ireg_memx8;
        !          3731:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3732:   }
        !          3733: 
        !          3734:   /* otherwise, do the bus cycles the slow way: */
        !          3735:   else {
        !          3736:     tme_m68k_write8(ic, tlb,
        !          3737:                     &ic->_tme_m68k_ea_function_code,
        !          3738:                     &ic->_tme_m68k_ea_address,
        !          3739:                     &ic->tme_m68k_ireg_memx8,
        !          3740:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3741:   }
        !          3742: }
        !          3743: 
        !          3744: /* this writes a 8-bit mem value: */
        !          3745: void
        !          3746: tme_m68k_write_mem8(struct tme_m68k *ic, int ireg) 
        !          3747: {
        !          3748:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3749:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
        !          3750:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address);
        !          3751: 
        !          3752:   /* log the value written: */
        !          3753:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_WRITE);
        !          3754:   tme_m68k_log(ic, 1000, TME_OK, 
        !          3755:                (TME_M68K_LOG_HANDLE(ic),
        !          3756:                 _("write_mem8\t%d:0x%08x:\t0x%02x"),
        !          3757:                 ic->_tme_m68k_ea_function_code,
        !          3758:                 ic->_tme_m68k_ea_address,
        !          3759:                 ic->tme_m68k_ireg_uint8(ireg)));
        !          3760: 
        !          3761:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3762:      the emulator memory allocator and TLB filler must guarantee
        !          3763:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          3764:      aligned, so that a 16-bit-aligned linear address gets a
        !          3765:      16-bit-aligned emulator address: */
        !          3766:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3767:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          3768:                                                       function_code,
        !          3769:                                                       linear_address,
        !          3770:                                                       linear_address))) {
        !          3771: 
        !          3772:     /* for an 8-bit transfer we can always do a simple 
        !          3773:        assignment.  the wrlock is unnecessary, since we assume
        !          3774:        that 8-bit accesses are always atomic: */
        !          3775:     *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address)) = ic->tme_m68k_ireg_uint8(ireg);
        !          3776:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3777:   }
        !          3778: 
        !          3779:   /* otherwise, do the bus cycles the slow way: */
        !          3780:   else {
        !          3781:     tme_m68k_write8(ic, tlb,
        !          3782:                     &ic->_tme_m68k_ea_function_code,
        !          3783:                     &ic->_tme_m68k_ea_address,
        !          3784:                     &ic->tme_m68k_ireg_uint8(ireg),
        !          3785:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3786:   }
        !          3787: }
        !          3788: 
        !          3789: /* this reads a 16-bit memx value: */
        !          3790: void
        !          3791: tme_m68k_read_memx16(struct tme_m68k *ic) 
        !          3792: {
        !          3793:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3794:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          3795:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          3796:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          3797: 
        !          3798:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3799:      the emulator memory allocator and TLB filler must guarantee
        !          3800:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3801:      aligned, so that a 16-bit-aligned linear address gets a
        !          3802:      16-bit-aligned emulator address: */
        !          3803:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3804:                          && !(linear_address_first & 1)
        !          3805:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3806:                                                       function_code,
        !          3807:                                                       linear_address_first,
        !          3808:                                                       linear_address_last))) {
        !          3809: 
        !          3810:     /* for a 16-bit transfer we can always do a simple
        !          3811:        assignment - we tested that the linear address
        !          3812:        is 16-bit aligned, which, since the TLB emulator
        !          3813:        offset is guaranteed to be 32-bit aligned, guarantees
        !          3814:        that the final emulator address is 16-bit aligned.
        !          3815: 
        !          3816:        we need the rdlock if we're on an architecture
        !          3817:        where an aligned access may not be atomic: */
        !          3818:     tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3819:     ic->tme_m68k_ireg_memx16 = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          3820:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3821:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3822:   }
        !          3823: 
        !          3824:   /* otherwise, do the bus cycles the slow way: */
        !          3825:   else {
        !          3826:     tme_m68k_read16(ic, tlb,
        !          3827:                     &ic->_tme_m68k_ea_function_code,
        !          3828:                     &ic->_tme_m68k_ea_address,
        !          3829:                     &ic->tme_m68k_ireg_memx16,
        !          3830:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3831:   }
        !          3832: 
        !          3833:   /* log the value read: */
        !          3834:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_READ);
        !          3835:   tme_m68k_log(ic, 1000, TME_OK,
        !          3836:                (TME_M68K_LOG_HANDLE(ic),
        !          3837:                 _("read_memx16\t%d:0x%08x:\t0x%04x"),
        !          3838:                 ic->_tme_m68k_ea_function_code,
        !          3839:                 ic->_tme_m68k_ea_address,
        !          3840:                 ic->tme_m68k_ireg_memx16));
        !          3841: }
        !          3842: 
        !          3843: /* this reads a 16-bit mem value: */
        !          3844: void
        !          3845: tme_m68k_read_mem16(struct tme_m68k *ic, int ireg) 
        !          3846: {
        !          3847:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          3848:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          3849:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          3850:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          3851: 
        !          3852:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3853:      the emulator memory allocator and TLB filler must guarantee
        !          3854:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3855:      aligned, so that a 16-bit-aligned linear address gets a
        !          3856:      16-bit-aligned emulator address: */
        !          3857:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3858:                          && !(linear_address_first & 1)
        !          3859:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3860:                                                       function_code,
        !          3861:                                                       linear_address_first,
        !          3862:                                                       linear_address_last))) {
        !          3863: 
        !          3864:     /* for a 16-bit transfer we can always do a simple
        !          3865:        assignment - we tested that the linear address
        !          3866:        is 16-bit aligned, which, since the TLB emulator
        !          3867:        offset is guaranteed to be 32-bit aligned, guarantees
        !          3868:        that the final emulator address is 16-bit aligned.
        !          3869: 
        !          3870:        we need the rdlock if we're on an architecture
        !          3871:        where an aligned access may not be atomic: */
        !          3872:     tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3873:     ic->tme_m68k_ireg_uint16(ireg) = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          3874:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3875:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3876:   }
        !          3877: 
        !          3878:   /* otherwise, do the bus cycles the slow way: */
        !          3879:   else {
        !          3880:     tme_m68k_read16(ic, tlb,
        !          3881:                     &ic->_tme_m68k_ea_function_code,
        !          3882:                     &ic->_tme_m68k_ea_address,
        !          3883:                     &ic->tme_m68k_ireg_uint16(ireg),
        !          3884:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3885:   }
        !          3886: 
        !          3887:   /* log the value read: */
        !          3888:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_READ);
        !          3889:   tme_m68k_log(ic, 1000, TME_OK,
        !          3890:                (TME_M68K_LOG_HANDLE(ic),
        !          3891:                 _("read_mem16\t%d:0x%08x:\t0x%04x"),
        !          3892:                 ic->_tme_m68k_ea_function_code,
        !          3893:                 ic->_tme_m68k_ea_address,
        !          3894:                 ic->tme_m68k_ireg_uint16(ireg)));
        !          3895: }
        !          3896: 
        !          3897: /* this reads a 16-bit inst value: */
        !          3898: tme_uint16_t
        !          3899: tme_m68k_fetch16(struct tme_m68k *ic, tme_uint32_t pc) 
        !          3900: {
        !          3901:   unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic);
        !          3902:   tme_uint32_t linear_address_first = pc;
        !          3903:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          3904:   struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb);
        !          3905:   unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint16_t));
        !          3906: 
        !          3907:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3908:      the emulator memory allocator and TLB filler must guarantee
        !          3909:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3910:      aligned, so that a 16-bit-aligned linear address gets a
        !          3911:      16-bit-aligned emulator address: */
        !          3912:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3913:                          && !(linear_address_first & 1)
        !          3914:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3915:                                                       function_code,
        !          3916:                                                       linear_address_first,
        !          3917:                                                       linear_address_last))) {
        !          3918: 
        !          3919:     /* for a 16-bit transfer we can always do a simple
        !          3920:        assignment - we tested that the linear address
        !          3921:        is 16-bit aligned, which, since the TLB emulator
        !          3922:        offset is guaranteed to be 32-bit aligned, guarantees
        !          3923:        that the final emulator address is 16-bit aligned.
        !          3924: 
        !          3925:        we need the rdlock if we're on an architecture
        !          3926:        where an aligned access may not be atomic: */
        !          3927:     tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3928:     *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          3929:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3930:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3931:   }
        !          3932: 
        !          3933:   /* otherwise, do the bus cycles the slow way: */
        !          3934:   else {
        !          3935:     tme_m68k_read16(ic, tlb,
        !          3936:                     &function_code,
        !          3937:                     &pc,
        !          3938:                     ((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]),
        !          3939:                     TME_M68K_BUS_CYCLE_FETCH);
        !          3940:   }
        !          3941: 
        !          3942:   /* log the value read: */
        !          3943:   tme_m68k_verify_mem16(ic, function_code, pc, *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), TME_BUS_CYCLE_READ);
        !          3944:   tme_m68k_log(ic, 1000, TME_OK,
        !          3945:                (TME_M68K_LOG_HANDLE(ic),
        !          3946:                 _("fetch16\t%d:0x%08x:\t0x%04x"),
        !          3947:                 function_code,
        !          3948:                 pc,
        !          3949:                 *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off])));
        !          3950:   ic->_tme_m68k_insn_buffer_off = insn_buffer_off + sizeof(tme_uint16_t);
        !          3951:   return(*((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]));
        !          3952: }
        !          3953: 
        !          3954: /* this reads a 16-bit stack value: */
        !          3955: void
        !          3956: tme_m68k_pop16(struct tme_m68k *ic, tme_uint16_t *_value) 
        !          3957: {
        !          3958:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          3959:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7;
        !          3960:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          3961:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          3962: 
        !          3963:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          3964:      the emulator memory allocator and TLB filler must guarantee
        !          3965:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          3966:      aligned, so that a 16-bit-aligned linear address gets a
        !          3967:      16-bit-aligned emulator address: */
        !          3968:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          3969:                          && !(linear_address_first & 1)
        !          3970:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          3971:                                                       function_code,
        !          3972:                                                       linear_address_first,
        !          3973:                                                       linear_address_last))) {
        !          3974: 
        !          3975:     /* for a 16-bit transfer we can always do a simple
        !          3976:        assignment - we tested that the linear address
        !          3977:        is 16-bit aligned, which, since the TLB emulator
        !          3978:        offset is guaranteed to be 32-bit aligned, guarantees
        !          3979:        that the final emulator address is 16-bit aligned.
        !          3980: 
        !          3981:        we need the rdlock if we're on an architecture
        !          3982:        where an aligned access may not be atomic: */
        !          3983:     tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3984:     *_value = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          3985:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          3986:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          3987:   }
        !          3988: 
        !          3989:   /* otherwise, do the bus cycles the slow way: */
        !          3990:   else {
        !          3991:     tme_m68k_read16(ic, tlb,
        !          3992:                     &function_code,
        !          3993:                     &ic->tme_m68k_ireg_a7,
        !          3994:                     _value,
        !          3995:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          3996:   }
        !          3997: 
        !          3998:   /* log the value read: */
        !          3999:   tme_m68k_verify_mem16(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ);
        !          4000:   tme_m68k_log(ic, 1000, TME_OK,
        !          4001:                (TME_M68K_LOG_HANDLE(ic),
        !          4002:                 _("pop16\t%d:0x%08x:\t0x%04x"),
        !          4003:                 function_code,
        !          4004:                 ic->tme_m68k_ireg_a7,
        !          4005:                 *_value));
        !          4006:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          4007:     ic->tme_m68k_ireg_a7 += sizeof(tme_uint16_t);
        !          4008:   }
        !          4009: }
        !          4010: 
        !          4011: /* this writes a 16-bit memx value: */
        !          4012: void
        !          4013: tme_m68k_write_memx16(struct tme_m68k *ic) 
        !          4014: {
        !          4015:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4016:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4017:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          4018:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4019: 
        !          4020:   /* log the value written: */
        !          4021:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_WRITE);
        !          4022:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4023:                (TME_M68K_LOG_HANDLE(ic),
        !          4024:                 _("write_memx16\t%d:0x%08x:\t0x%04x"),
        !          4025:                 ic->_tme_m68k_ea_function_code,
        !          4026:                 ic->_tme_m68k_ea_address,
        !          4027:                 ic->tme_m68k_ireg_memx16));
        !          4028: 
        !          4029:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4030:      the emulator memory allocator and TLB filler must guarantee
        !          4031:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4032:      aligned, so that a 16-bit-aligned linear address gets a
        !          4033:      16-bit-aligned emulator address: */
        !          4034:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4035:                          && !(linear_address_first & 1)
        !          4036:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4037:                                                       function_code,
        !          4038:                                                       linear_address_first,
        !          4039:                                                       linear_address_last))) {
        !          4040: 
        !          4041:     /* for a 16-bit transfer we can always do a simple
        !          4042:        assignment - we tested that the linear address
        !          4043:        is 16-bit aligned, which, since the TLB emulator
        !          4044:        offset is guaranteed to be 32-bit aligned, guarantees
        !          4045:        that the final emulator address is 16-bit aligned.
        !          4046: 
        !          4047:        we need the wrlock if we're on an architecture
        !          4048:        where an aligned access may not be atomic: */
        !          4049:     tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4050:     *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(ic->tme_m68k_ireg_memx16);
        !          4051:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4052:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4053:   }
        !          4054: 
        !          4055:   /* otherwise, do the bus cycles the slow way: */
        !          4056:   else {
        !          4057:     tme_m68k_write16(ic, tlb,
        !          4058:                     &ic->_tme_m68k_ea_function_code,
        !          4059:                     &ic->_tme_m68k_ea_address,
        !          4060:                     &ic->tme_m68k_ireg_memx16,
        !          4061:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4062:   }
        !          4063: }
        !          4064: 
        !          4065: /* this writes a 16-bit mem value: */
        !          4066: void
        !          4067: tme_m68k_write_mem16(struct tme_m68k *ic, int ireg) 
        !          4068: {
        !          4069:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4070:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4071:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          4072:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4073: 
        !          4074:   /* log the value written: */
        !          4075:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_WRITE);
        !          4076:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4077:                (TME_M68K_LOG_HANDLE(ic),
        !          4078:                 _("write_mem16\t%d:0x%08x:\t0x%04x"),
        !          4079:                 ic->_tme_m68k_ea_function_code,
        !          4080:                 ic->_tme_m68k_ea_address,
        !          4081:                 ic->tme_m68k_ireg_uint16(ireg)));
        !          4082: 
        !          4083:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4084:      the emulator memory allocator and TLB filler must guarantee
        !          4085:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4086:      aligned, so that a 16-bit-aligned linear address gets a
        !          4087:      16-bit-aligned emulator address: */
        !          4088:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4089:                          && !(linear_address_first & 1)
        !          4090:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4091:                                                       function_code,
        !          4092:                                                       linear_address_first,
        !          4093:                                                       linear_address_last))) {
        !          4094: 
        !          4095:     /* for a 16-bit transfer we can always do a simple
        !          4096:        assignment - we tested that the linear address
        !          4097:        is 16-bit aligned, which, since the TLB emulator
        !          4098:        offset is guaranteed to be 32-bit aligned, guarantees
        !          4099:        that the final emulator address is 16-bit aligned.
        !          4100: 
        !          4101:        we need the wrlock if we're on an architecture
        !          4102:        where an aligned access may not be atomic: */
        !          4103:     tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4104:     *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(ic->tme_m68k_ireg_uint16(ireg));
        !          4105:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4106:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4107:   }
        !          4108: 
        !          4109:   /* otherwise, do the bus cycles the slow way: */
        !          4110:   else {
        !          4111:     tme_m68k_write16(ic, tlb,
        !          4112:                     &ic->_tme_m68k_ea_function_code,
        !          4113:                     &ic->_tme_m68k_ea_address,
        !          4114:                     &ic->tme_m68k_ireg_uint16(ireg),
        !          4115:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4116:   }
        !          4117: }
        !          4118: 
        !          4119: /* this writes a 16-bit stack value: */
        !          4120: void
        !          4121: tme_m68k_push16(struct tme_m68k *ic, tme_uint16_t value) 
        !          4122: {
        !          4123:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          4124:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint16_t);
        !          4125:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
        !          4126:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4127: 
        !          4128:   /* log the value written: */
        !          4129:   tme_m68k_verify_mem16(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE);
        !          4130:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4131:                (TME_M68K_LOG_HANDLE(ic),
        !          4132:                 _("push16\t%d:0x%08x:\t0x%04x"),
        !          4133:                 function_code,
        !          4134:                 linear_address_first,
        !          4135:                 value));
        !          4136: 
        !          4137:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4138:      the emulator memory allocator and TLB filler must guarantee
        !          4139:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4140:      aligned, so that a 16-bit-aligned linear address gets a
        !          4141:      16-bit-aligned emulator address: */
        !          4142:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4143:                          && !(linear_address_first & 1)
        !          4144:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4145:                                                       function_code,
        !          4146:                                                       linear_address_first,
        !          4147:                                                       linear_address_last))) {
        !          4148: 
        !          4149:     /* for a 16-bit transfer we can always do a simple
        !          4150:        assignment - we tested that the linear address
        !          4151:        is 16-bit aligned, which, since the TLB emulator
        !          4152:        offset is guaranteed to be 32-bit aligned, guarantees
        !          4153:        that the final emulator address is 16-bit aligned.
        !          4154: 
        !          4155:        we need the wrlock if we're on an architecture
        !          4156:        where an aligned access may not be atomic: */
        !          4157:     tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4158:     *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(value);
        !          4159:     tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4160:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4161:   }
        !          4162: 
        !          4163:   /* otherwise, do the bus cycles the slow way: */
        !          4164:   else {
        !          4165:     tme_m68k_write16(ic, tlb,
        !          4166:                     &function_code,
        !          4167:                     &linear_address_first,
        !          4168:                     &value,
        !          4169:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4170:   }
        !          4171:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          4172:     ic->tme_m68k_ireg_a7 -= sizeof(tme_uint16_t);
        !          4173:   }
        !          4174: }
        !          4175: 
        !          4176: /* this reads a 32-bit memx value: */
        !          4177: void
        !          4178: tme_m68k_read_memx32(struct tme_m68k *ic) 
        !          4179: {
        !          4180:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4181:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4182:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4183:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4184: 
        !          4185:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4186:      the emulator memory allocator and TLB filler must guarantee
        !          4187:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          4188:      aligned, so that a 16-bit-aligned linear address gets a
        !          4189:      16-bit-aligned emulator address: */
        !          4190:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4191:                          && !(linear_address_first & 1)
        !          4192:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          4193:                                                       function_code,
        !          4194:                                                       linear_address_first,
        !          4195:                                                       linear_address_last))) {
        !          4196: 
        !          4197:     /* if the emulator host allows 32-bit quantities to be
        !          4198:        transferred from 16-bit aligned addresses, or if this
        !          4199:        address is 32-bit aligned, do the transfer as a simple
        !          4200:        assignment, otherwise transfer two 16-bit words.
        !          4201: 
        !          4202:        we need the rdlock if we're on an architecture where
        !          4203:        an aligned access may not be atomic, or if we're doing
        !          4204:        an unaligned access on an architecture where they may
        !          4205:        not be atomic: */
        !          4206: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4207: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4208:     ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4209: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4210:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4211:       tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4212:       ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4213:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4214:     }
        !          4215:     else {
        !          4216:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4217:       ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4218:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4219:     }
        !          4220: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4221: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4222:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4223:       tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4224: #ifdef WORDS_BIGENDIAN
        !          4225:       ic->tme_m68k_ireg_memx32 = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1];
        !          4226: #else  /* !WORDS_BIGENDIAN */
        !          4227:       ic->tme_m68k_ireg_memx32 = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]);
        !          4228: #endif /* !WORDS_BIGENDIAN */
        !          4229:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4230:     }
        !          4231:     else {
        !          4232:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4233:       ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4234:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4235:     }
        !          4236: #endif /* ALIGNOF_INT32_T != 1 */
        !          4237:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4238:   }
        !          4239: 
        !          4240:   /* otherwise, do the bus cycles the slow way: */
        !          4241:   else {
        !          4242:     tme_m68k_read32(ic, tlb,
        !          4243:                     &ic->_tme_m68k_ea_function_code,
        !          4244:                     &ic->_tme_m68k_ea_address,
        !          4245:                     &ic->tme_m68k_ireg_memx32,
        !          4246:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4247:   }
        !          4248: 
        !          4249:   /* log the value read: */
        !          4250:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_READ);
        !          4251:   tme_m68k_log(ic, 1000, TME_OK,
        !          4252:                (TME_M68K_LOG_HANDLE(ic),
        !          4253:                 _("read_memx32\t%d:0x%08x:\t0x%08x"),
        !          4254:                 ic->_tme_m68k_ea_function_code,
        !          4255:                 ic->_tme_m68k_ea_address,
        !          4256:                 ic->tme_m68k_ireg_memx32));
        !          4257: }
        !          4258: 
        !          4259: /* this reads a 32-bit mem value: */
        !          4260: void
        !          4261: tme_m68k_read_mem32(struct tme_m68k *ic, int ireg) 
        !          4262: {
        !          4263:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4264:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4265:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4266:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4267: 
        !          4268:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4269:      the emulator memory allocator and TLB filler must guarantee
        !          4270:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          4271:      aligned, so that a 16-bit-aligned linear address gets a
        !          4272:      16-bit-aligned emulator address: */
        !          4273:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4274:                          && !(linear_address_first & 1)
        !          4275:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          4276:                                                       function_code,
        !          4277:                                                       linear_address_first,
        !          4278:                                                       linear_address_last))) {
        !          4279: 
        !          4280:     /* if the emulator host allows 32-bit quantities to be
        !          4281:        transferred from 16-bit aligned addresses, or if this
        !          4282:        address is 32-bit aligned, do the transfer as a simple
        !          4283:        assignment, otherwise transfer two 16-bit words.
        !          4284: 
        !          4285:        we need the rdlock if we're on an architecture where
        !          4286:        an aligned access may not be atomic, or if we're doing
        !          4287:        an unaligned access on an architecture where they may
        !          4288:        not be atomic: */
        !          4289: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4290: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4291:     ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4292: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4293:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4294:       tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4295:       ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4296:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4297:     }
        !          4298:     else {
        !          4299:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4300:       ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4301:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4302:     }
        !          4303: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4304: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4305:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4306:       tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4307: #ifdef WORDS_BIGENDIAN
        !          4308:       ic->tme_m68k_ireg_uint32(ireg) = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1];
        !          4309: #else  /* !WORDS_BIGENDIAN */
        !          4310:       ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]);
        !          4311: #endif /* !WORDS_BIGENDIAN */
        !          4312:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4313:     }
        !          4314:     else {
        !          4315:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4316:       ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4317:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4318:     }
        !          4319: #endif /* ALIGNOF_INT32_T != 1 */
        !          4320:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4321:   }
        !          4322: 
        !          4323:   /* otherwise, do the bus cycles the slow way: */
        !          4324:   else {
        !          4325:     tme_m68k_read32(ic, tlb,
        !          4326:                     &ic->_tme_m68k_ea_function_code,
        !          4327:                     &ic->_tme_m68k_ea_address,
        !          4328:                     &ic->tme_m68k_ireg_uint32(ireg),
        !          4329:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4330:   }
        !          4331: 
        !          4332:   /* log the value read: */
        !          4333:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_READ);
        !          4334:   tme_m68k_log(ic, 1000, TME_OK,
        !          4335:                (TME_M68K_LOG_HANDLE(ic),
        !          4336:                 _("read_mem32\t%d:0x%08x:\t0x%08x"),
        !          4337:                 ic->_tme_m68k_ea_function_code,
        !          4338:                 ic->_tme_m68k_ea_address,
        !          4339:                 ic->tme_m68k_ireg_uint32(ireg)));
        !          4340: }
        !          4341: 
        !          4342: /* this reads a 32-bit inst value: */
        !          4343: tme_uint32_t
        !          4344: tme_m68k_fetch32(struct tme_m68k *ic, tme_uint32_t pc) 
        !          4345: {
        !          4346:   unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic);
        !          4347:   tme_uint32_t linear_address_first = pc;
        !          4348:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4349:   struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb);
        !          4350:   unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint32_t));
        !          4351: 
        !          4352:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4353:      the emulator memory allocator and TLB filler must guarantee
        !          4354:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          4355:      aligned, so that a 16-bit-aligned linear address gets a
        !          4356:      16-bit-aligned emulator address: */
        !          4357:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4358:                          && !(linear_address_first & 1)
        !          4359:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          4360:                                                       function_code,
        !          4361:                                                       linear_address_first,
        !          4362:                                                       linear_address_last))) {
        !          4363: 
        !          4364:     /* if the emulator host allows 32-bit quantities to be
        !          4365:        transferred from 16-bit aligned addresses, or if this
        !          4366:        address is 32-bit aligned, do the transfer as a simple
        !          4367:        assignment, otherwise transfer two 16-bit words.
        !          4368: 
        !          4369:        we need the rdlock if we're on an architecture where
        !          4370:        an aligned access may not be atomic, or if we're doing
        !          4371:        an unaligned access on an architecture where they may
        !          4372:        not be atomic: */
        !          4373: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4374: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4375:     *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4376: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4377:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4378:       tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4379:       *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4380:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4381:     }
        !          4382:     else {
        !          4383:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4384:       *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4385:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4386:     }
        !          4387: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4388: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4389:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4390:       tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4391: #ifdef WORDS_BIGENDIAN
        !          4392:       *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1];
        !          4393: #else  /* !WORDS_BIGENDIAN */
        !          4394:       *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]);
        !          4395: #endif /* !WORDS_BIGENDIAN */
        !          4396:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4397:     }
        !          4398:     else {
        !          4399:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4400:       *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4401:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4402:     }
        !          4403: #endif /* ALIGNOF_INT32_T != 1 */
        !          4404:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4405:   }
        !          4406: 
        !          4407:   /* otherwise, do the bus cycles the slow way: */
        !          4408:   else {
        !          4409:     tme_m68k_read32(ic, tlb,
        !          4410:                     &function_code,
        !          4411:                     &pc,
        !          4412:                     ((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]),
        !          4413:                     TME_M68K_BUS_CYCLE_FETCH);
        !          4414:   }
        !          4415: 
        !          4416:   /* log the value read: */
        !          4417:   tme_m68k_verify_mem32(ic, function_code, pc, *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), TME_BUS_CYCLE_READ);
        !          4418:   tme_m68k_log(ic, 1000, TME_OK,
        !          4419:                (TME_M68K_LOG_HANDLE(ic),
        !          4420:                 _("fetch32\t%d:0x%08x:\t0x%08x"),
        !          4421:                 function_code,
        !          4422:                 pc,
        !          4423:                 *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off])));
        !          4424:   ic->_tme_m68k_insn_buffer_off = insn_buffer_off + sizeof(tme_uint32_t);
        !          4425:   return(*((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]));
        !          4426: }
        !          4427: 
        !          4428: /* this reads a 32-bit stack value: */
        !          4429: void
        !          4430: tme_m68k_pop32(struct tme_m68k *ic, tme_uint32_t *_value) 
        !          4431: {
        !          4432:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          4433:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7;
        !          4434:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4435:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4436: 
        !          4437:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4438:      the emulator memory allocator and TLB filler must guarantee
        !          4439:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          4440:      aligned, so that a 16-bit-aligned linear address gets a
        !          4441:      16-bit-aligned emulator address: */
        !          4442:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4443:                          && !(linear_address_first & 1)
        !          4444:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          4445:                                                       function_code,
        !          4446:                                                       linear_address_first,
        !          4447:                                                       linear_address_last))) {
        !          4448: 
        !          4449:     /* if the emulator host allows 32-bit quantities to be
        !          4450:        transferred from 16-bit aligned addresses, or if this
        !          4451:        address is 32-bit aligned, do the transfer as a simple
        !          4452:        assignment, otherwise transfer two 16-bit words.
        !          4453: 
        !          4454:        we need the rdlock if we're on an architecture where
        !          4455:        an aligned access may not be atomic, or if we're doing
        !          4456:        an unaligned access on an architecture where they may
        !          4457:        not be atomic: */
        !          4458: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4459: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4460:     *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4461: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4462:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4463:       tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4464:       *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4465:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4466:     }
        !          4467:     else {
        !          4468:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4469:       *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4470:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4471:     }
        !          4472: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4473: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4474:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4475:       tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4476: #ifdef WORDS_BIGENDIAN
        !          4477:       *_value = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1];
        !          4478: #else  /* !WORDS_BIGENDIAN */
        !          4479:       *_value = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]);
        !          4480: #endif /* !WORDS_BIGENDIAN */
        !          4481:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4482:     }
        !          4483:     else {
        !          4484:       tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4485:       *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first)));
        !          4486:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4487:     }
        !          4488: #endif /* ALIGNOF_INT32_T != 1 */
        !          4489:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4490:   }
        !          4491: 
        !          4492:   /* otherwise, do the bus cycles the slow way: */
        !          4493:   else {
        !          4494:     tme_m68k_read32(ic, tlb,
        !          4495:                     &function_code,
        !          4496:                     &ic->tme_m68k_ireg_a7,
        !          4497:                     _value,
        !          4498:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4499:   }
        !          4500: 
        !          4501:   /* log the value read: */
        !          4502:   tme_m68k_verify_mem32(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ);
        !          4503:   tme_m68k_log(ic, 1000, TME_OK,
        !          4504:                (TME_M68K_LOG_HANDLE(ic),
        !          4505:                 _("pop32\t%d:0x%08x:\t0x%08x"),
        !          4506:                 function_code,
        !          4507:                 ic->tme_m68k_ireg_a7,
        !          4508:                 *_value));
        !          4509:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          4510:     ic->tme_m68k_ireg_a7 += sizeof(tme_uint32_t);
        !          4511:   }
        !          4512: }
        !          4513: 
        !          4514: /* this writes a 32-bit memx value: */
        !          4515: void
        !          4516: tme_m68k_write_memx32(struct tme_m68k *ic) 
        !          4517: {
        !          4518:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4519:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4520:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4521:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4522: 
        !          4523:   /* log the value written: */
        !          4524:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_WRITE);
        !          4525:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4526:                (TME_M68K_LOG_HANDLE(ic),
        !          4527:                 _("write_memx32\t%d:0x%08x:\t0x%08x"),
        !          4528:                 ic->_tme_m68k_ea_function_code,
        !          4529:                 ic->_tme_m68k_ea_address,
        !          4530:                 ic->tme_m68k_ireg_memx32));
        !          4531: 
        !          4532:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4533:      the emulator memory allocator and TLB filler must guarantee
        !          4534:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4535:      aligned, so that a 16-bit-aligned linear address gets a
        !          4536:      16-bit-aligned emulator address: */
        !          4537:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4538:                          && !(linear_address_first & 1)
        !          4539:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4540:                                                       function_code,
        !          4541:                                                       linear_address_first,
        !          4542:                                                       linear_address_last))) {
        !          4543: 
        !          4544:     /* if the emulator host allows 32-bit quantities to be
        !          4545:        transferred to 16-bit aligned addresses, or if this
        !          4546:        address is 32-bit aligned, do the transfer as a simple
        !          4547:        assignment, otherwise transfer two 16-bit words.
        !          4548: 
        !          4549:        we need the wrlock if we're on an architecture where
        !          4550:        an aligned access may not be atomic, or if we're doing
        !          4551:        an unaligned access on an architecture where they may
        !          4552:        not be atomic: */
        !          4553: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4554: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4555:     *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32);
        !          4556: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4557:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4558:       tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4559:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32);
        !          4560:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4561:     }
        !          4562:     else {
        !          4563:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4564:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32);
        !          4565:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4566:     }
        !          4567: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4568: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4569:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4570:       tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4571:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(ic->tme_m68k_ireg_memx32 >> 16);
        !          4572:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(ic->tme_m68k_ireg_memx32 & 0xffff);
        !          4573:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4574:     }
        !          4575:     else {
        !          4576:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4577:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32);
        !          4578:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4579:     }
        !          4580: #endif /* ALIGNOF_INT32_T != 1 */
        !          4581:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4582:   }
        !          4583: 
        !          4584:   /* otherwise, do the bus cycles the slow way: */
        !          4585:   else {
        !          4586:     tme_m68k_write32(ic, tlb,
        !          4587:                     &ic->_tme_m68k_ea_function_code,
        !          4588:                     &ic->_tme_m68k_ea_address,
        !          4589:                     &ic->tme_m68k_ireg_memx32,
        !          4590:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4591:   }
        !          4592: }
        !          4593: 
        !          4594: /* this writes a 32-bit mem value: */
        !          4595: void
        !          4596: tme_m68k_write_mem32(struct tme_m68k *ic, int ireg) 
        !          4597: {
        !          4598:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4599:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4600:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4601:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4602: 
        !          4603:   /* log the value written: */
        !          4604:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_WRITE);
        !          4605:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4606:                (TME_M68K_LOG_HANDLE(ic),
        !          4607:                 _("write_mem32\t%d:0x%08x:\t0x%08x"),
        !          4608:                 ic->_tme_m68k_ea_function_code,
        !          4609:                 ic->_tme_m68k_ea_address,
        !          4610:                 ic->tme_m68k_ireg_uint32(ireg)));
        !          4611: 
        !          4612:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4613:      the emulator memory allocator and TLB filler must guarantee
        !          4614:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4615:      aligned, so that a 16-bit-aligned linear address gets a
        !          4616:      16-bit-aligned emulator address: */
        !          4617:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4618:                          && !(linear_address_first & 1)
        !          4619:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4620:                                                       function_code,
        !          4621:                                                       linear_address_first,
        !          4622:                                                       linear_address_last))) {
        !          4623: 
        !          4624:     /* if the emulator host allows 32-bit quantities to be
        !          4625:        transferred to 16-bit aligned addresses, or if this
        !          4626:        address is 32-bit aligned, do the transfer as a simple
        !          4627:        assignment, otherwise transfer two 16-bit words.
        !          4628: 
        !          4629:        we need the wrlock if we're on an architecture where
        !          4630:        an aligned access may not be atomic, or if we're doing
        !          4631:        an unaligned access on an architecture where they may
        !          4632:        not be atomic: */
        !          4633: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4634: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4635:     *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg));
        !          4636: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4637:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4638:       tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4639:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg));
        !          4640:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4641:     }
        !          4642:     else {
        !          4643:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4644:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg));
        !          4645:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4646:     }
        !          4647: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4648: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4649:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4650:       tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4651:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(ic->tme_m68k_ireg_uint32(ireg) >> 16);
        !          4652:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(ic->tme_m68k_ireg_uint32(ireg) & 0xffff);
        !          4653:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4654:     }
        !          4655:     else {
        !          4656:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4657:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg));
        !          4658:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4659:     }
        !          4660: #endif /* ALIGNOF_INT32_T != 1 */
        !          4661:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4662:   }
        !          4663: 
        !          4664:   /* otherwise, do the bus cycles the slow way: */
        !          4665:   else {
        !          4666:     tme_m68k_write32(ic, tlb,
        !          4667:                     &ic->_tme_m68k_ea_function_code,
        !          4668:                     &ic->_tme_m68k_ea_address,
        !          4669:                     &ic->tme_m68k_ireg_uint32(ireg),
        !          4670:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4671:   }
        !          4672: }
        !          4673: 
        !          4674: /* this writes a 32-bit stack value: */
        !          4675: void
        !          4676: tme_m68k_push32(struct tme_m68k *ic, tme_uint32_t value) 
        !          4677: {
        !          4678:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          4679:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint32_t);
        !          4680:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
        !          4681:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4682: 
        !          4683:   /* log the value written: */
        !          4684:   tme_m68k_verify_mem32(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE);
        !          4685:   tme_m68k_log(ic, 1000, TME_OK, 
        !          4686:                (TME_M68K_LOG_HANDLE(ic),
        !          4687:                 _("push32\t%d:0x%08x:\t0x%08x"),
        !          4688:                 function_code,
        !          4689:                 linear_address_first,
        !          4690:                 value));
        !          4691: 
        !          4692:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4693:      the emulator memory allocator and TLB filler must guarantee
        !          4694:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          4695:      aligned, so that a 16-bit-aligned linear address gets a
        !          4696:      16-bit-aligned emulator address: */
        !          4697:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4698:                          && !(linear_address_first & 1)
        !          4699:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          4700:                                                       function_code,
        !          4701:                                                       linear_address_first,
        !          4702:                                                       linear_address_last))) {
        !          4703: 
        !          4704:     /* if the emulator host allows 32-bit quantities to be
        !          4705:        transferred to 16-bit aligned addresses, or if this
        !          4706:        address is 32-bit aligned, do the transfer as a simple
        !          4707:        assignment, otherwise transfer two 16-bit words.
        !          4708: 
        !          4709:        we need the wrlock if we're on an architecture where
        !          4710:        an aligned access may not be atomic, or if we're doing
        !          4711:        an unaligned access on an architecture where they may
        !          4712:        not be atomic: */
        !          4713: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T
        !          4714: #ifdef TME_UNALIGNED_ACCESS_ATOMIC
        !          4715:     *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value);
        !          4716: #else  /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4717:     if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4718:       tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4719:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value);
        !          4720:       tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4721:     }
        !          4722:     else {
        !          4723:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4724:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value);
        !          4725:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4726:     }
        !          4727: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */
        !          4728: #else  /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */
        !          4729:     if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) {
        !          4730:       tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4731:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(value >> 16);
        !          4732:       ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(value & 0xffff);
        !          4733:       tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4734:     }
        !          4735:     else {
        !          4736:       tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4737:       *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value);
        !          4738:       tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 
        !          4739:     }
        !          4740: #endif /* ALIGNOF_INT32_T != 1 */
        !          4741:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4742:   }
        !          4743: 
        !          4744:   /* otherwise, do the bus cycles the slow way: */
        !          4745:   else {
        !          4746:     tme_m68k_write32(ic, tlb,
        !          4747:                     &function_code,
        !          4748:                     &linear_address_first,
        !          4749:                     &value,
        !          4750:                     TME_M68K_BUS_CYCLE_NORMAL);
        !          4751:   }
        !          4752:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          4753:     ic->tme_m68k_ireg_a7 -= sizeof(tme_uint32_t);
        !          4754:   }
        !          4755: }
        !          4756: 
        !          4757: /* this reads a any-bit mem value: */
        !          4758: void
        !          4759: tme_m68k_read_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 
        !          4760: {
        !          4761:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          4762:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          4763:   tme_uint32_t linear_address_last = linear_address_first + count - 1;
        !          4764:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          4765: 
        !          4766:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          4767:      the emulator memory allocator and TLB filler must guarantee
        !          4768:      that all tme_m68k_tlb_emulator_off_read pointers be 32-bit
        !          4769:      aligned, so that a 16-bit-aligned linear address gets a
        !          4770:      16-bit-aligned emulator address: */
        !          4771:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          4772:                          && !(linear_address_first & 1)
        !          4773:                          && TME_M68K_TLB_OK_FAST_READ(tlb,
        !          4774:                                                       function_code,
        !          4775:                                                       linear_address_first,
        !          4776:                                                       linear_address_last))) {
        !          4777: 
        !          4778:     tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4779:     memcpy(buffer, (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first), count);
        !          4780:     tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          4781:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4782:   }
        !          4783: 
        !          4784:   /* otherwise, do the bus cycles the slow way: */
        !          4785:   else {
        !          4786:     tme_m68k_read(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW);
        !          4787:   }
        !          4788: 
        !          4789:   /* log the value read: */
        !          4790:   tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_READ);
        !          4791:   tme_m68k_log_start(ic, 1000, TME_OK) {
        !          4792:     unsigned int byte_i;
        !          4793:     tme_log_part(TME_M68K_LOG_HANDLE(ic),
        !          4794:                  _("read_mem %d:0x%08x count %d:"),
        !          4795:                  ic->_tme_m68k_ea_function_code,
        !          4796:                  ic->_tme_m68k_ea_address,
        !          4797:                  count);
        !          4798:     for (byte_i = 0; byte_i < count ; byte_i++) {
        !          4799:       tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]);
        !          4800:     }
        !          4801:   } tme_m68k_log_finish(ic);
        !          4802: }
        !          4803: 
        !          4804: /* this reads a region of address space using actual bus cycles: */
        !          4805: void
        !          4806: tme_m68k_read(struct tme_m68k *ic, 
        !          4807:               struct tme_m68k_tlb *tlb,
        !          4808:               unsigned int *_function_code, 
        !          4809:               tme_uint32_t *_linear_address, 
        !          4810:               tme_uint8_t *reg,
        !          4811:               unsigned int reg_size,
        !          4812:               unsigned int flags)
        !          4813: {
        !          4814:   unsigned int function_code;
        !          4815:   tme_uint32_t linear_address;
        !          4816:   tme_bus_addr_t physical_address;
        !          4817:   int shift;
        !          4818:   struct tme_bus_cycle cycle;
        !          4819:   unsigned int transferred, resid, cycle_size;
        !          4820:   int exception;
        !          4821:   tme_rwlock_t *rmw_rwlock;
        !          4822:   int err;
        !          4823: #ifndef WORDS_BIGENDIAN
        !          4824:   tme_uint8_t *reg_p;
        !          4825:   unsigned int buffer_i;
        !          4826: #endif /* !WORDS_BIGENDIAN */
        !          4827: 
        !          4828:   /* if we're not restarting, everything is fresh: */
        !          4829:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          4830:     function_code = *_function_code;
        !          4831:     linear_address = *_linear_address;
        !          4832:     transferred = 0;
        !          4833:   }
        !          4834: 
        !          4835:   /* otherwise, if this is the transfer that faulted, restore
        !          4836:      our state to the cycle that faulted, then take into account
        !          4837:      any data provided by a software rerun of the faulted cycle: */
        !          4838:   else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted
        !          4839:            == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) {
        !          4840:     function_code = *_function_code = ic->_tme_m68k_group0_function_code;
        !          4841:     linear_address = ic->_tme_m68k_group0_address;
        !          4842:     transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after;
        !          4843:     if (transferred >= reg_size) abort();
        !          4844:     *_linear_address = linear_address - transferred;
        !          4845:     resid = reg_size - transferred;
        !          4846:     if (ic->_tme_m68k_group0_buffer_read_size > resid) abort();
        !          4847:     if (ic->_tme_m68k_group0_buffer_read_softrr > resid) abort();
        !          4848:     if (ic->_tme_m68k_group0_buffer_read_softrr > 0) {
        !          4849: #ifdef WORDS_BIGENDIAN
        !          4850:       memcpy(reg + transferred, 
        !          4851:              ic->_tme_m68k_group0_buffer_read,
        !          4852:              ic->_tme_m68k_group0_buffer_read_size);
        !          4853: #else  /* !WORDS_BIGENDIAN */
        !          4854:       reg_p = (reg + reg_size - 1) - transferred;
        !          4855:       for (buffer_i = 0;
        !          4856:            buffer_i < ic->_tme_m68k_group0_buffer_read_size;
        !          4857:            buffer_i++) {
        !          4858:         *(reg_p--) = ic->_tme_m68k_group0_buffer_read[buffer_i];
        !          4859:       }
        !          4860: #endif /* !WORDS_BIGENDIAN */
        !          4861:     }
        !          4862:     transferred += ic->_tme_m68k_group0_buffer_read_softrr;
        !          4863:   }
        !          4864: 
        !          4865:   /* otherwise, a later transfer has faulted.  just step the
        !          4866:      transfer number and return: */
        !          4867:   else {
        !          4868:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          4869:     return;
        !          4870:   }
        !          4871: 
        !          4872:   /* do as many bus cycles as needed to complete the transfer: */
        !          4873:   rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock;
        !          4874:   exception = TME_M68K_EXCEPTION_NONE;
        !          4875:   cycle_size = 0;
        !          4876:   for(; transferred < reg_size; ) {
        !          4877:     resid = reg_size - transferred;
        !          4878: 
        !          4879:     /* start the bus cycle structure: */
        !          4880:     cycle.tme_bus_cycle_type = TME_BUS_CYCLE_READ;
        !          4881:     if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
        !          4882:         || (flags & TME_M68K_BUS_CYCLE_RAW)) {
        !          4883:       cycle.tme_bus_cycle_buffer = reg + transferred;
        !          4884:       cycle.tme_bus_cycle_buffer_increment = 1;
        !          4885:     }
        !          4886:     else {
        !          4887:       cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred);
        !          4888:       cycle.tme_bus_cycle_buffer_increment = -1;
        !          4889:     }
        !          4890: 
        !          4891:     /* if we're emulating a CPU with a 16-bit bus interface: */
        !          4892:     if (ic->_tme_m68k_bus_16bit) {
        !          4893: 
        !          4894:       /* if we're trying to transfer a non-power-of-two
        !          4895:          number of bytes, either the CPU is broken (no
        !          4896:          instructions ever transfer a non-power-of-two
        !          4897:          number of bytes), or this function allowed an
        !          4898:          unaligned transfer: */
        !          4899:       assert((resid & (resid - 1)) == 0
        !          4900:              || (flags & TME_M68K_BUS_CYCLE_RAW));
        !          4901: 
        !          4902:       /* only byte transfers can be unaligned: */
        !          4903:       if (resid > sizeof(tme_uint8_t)
        !          4904:           && (linear_address & 1)) {
        !          4905:           exception = TME_M68K_EXCEPTION_GROUP0_AERR;
        !          4906:           break;
        !          4907:       }
        !          4908: 
        !          4909:       /* set the bus-size specific parts of the bus cycle structure: */
        !          4910:       cycle_size = TME_MIN(resid, sizeof(tme_uint16_t));
        !          4911:       cycle.tme_bus_cycle_size = cycle_size;
        !          4912:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2);
        !          4913:       cycle.tme_bus_cycle_lane_routing = 
        !          4914:         &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)];
        !          4915:     }
        !          4916: 
        !          4917:     /* otherwise we're emulating a CPU with a 32-bit bus interface: */
        !          4918:     else {
        !          4919: 
        !          4920:       /* an instruction fetch must be aligned: */
        !          4921:       if (flags & TME_M68K_BUS_CYCLE_FETCH) {
        !          4922:         if (linear_address & 1) {
        !          4923:           exception = TME_M68K_EXCEPTION_GROUP0_AERR;
        !          4924:           break;
        !          4925:         }
        !          4926:         assert(!(resid & 1));
        !          4927:       }
        !          4928: 
        !          4929:       /* set the bus-size specific parts of the bus cycle structure: */
        !          4930:       cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1)));
        !          4931:       cycle.tme_bus_cycle_size = cycle_size;
        !          4932:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
        !          4933:       cycle.tme_bus_cycle_lane_routing = 
        !          4934:         &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)];
        !          4935:     }
        !          4936: 
        !          4937:     /* reload the TLB entry: */
        !          4938:     if (!TME_M68K_TLB_OK_SLOW_READ(tlb, function_code, linear_address)) {
        !          4939:       tme_m68k_tlb_fill(ic, tlb,
        !          4940:                         function_code,
        !          4941:                         linear_address,
        !          4942:                         TME_BUS_CYCLE_READ);
        !          4943:     }
        !          4944: 
        !          4945:     /* if this is a part of a read/modify/write cycle: */
        !          4946:     if (flags & TME_M68K_BUS_CYCLE_RMW) {
        !          4947: 
        !          4948:       /* if this TLB entry doesn't support fast reads, or
        !          4949:          if the TLB lock has changed, that's a bus error.
        !          4950:          see the discussion in tme_m68k_rmw_start: */
        !          4951:       if (!TME_M68K_TLB_OK_FAST_READ(tlb, function_code, linear_address, linear_address)
        !          4952:           || (rmw_rwlock != NULL
        !          4953:               && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) {
        !          4954:         exception = TME_M68K_EXCEPTION_GROUP0_BERR;
        !          4955:         break;
        !          4956:       }
        !          4957: 
        !          4958:       /* if we haven't locked this memory yet, do so: */
        !          4959:       if (rmw_rwlock == NULL) {
        !          4960:         rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock;
        !          4961:         tme_rwlock_wrlock(rmw_rwlock);
        !          4962:       }
        !          4963:     }
        !          4964: 
        !          4965:     /* form the physical address for the bus cycle handler: */
        !          4966:     physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address;
        !          4967:     shift = tlb->tme_m68k_tlb_addr_shift;
        !          4968:     if (shift < 0) {
        !          4969:       physical_address <<= (0 - shift);
        !          4970:     }
        !          4971:     else if (shift > 0) {
        !          4972:       physical_address >>= shift;
        !          4973:     }
        !          4974:     cycle.tme_bus_cycle_address = physical_address;
        !          4975: 
        !          4976:     /* run the bus cycle: */
        !          4977:     err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle)
        !          4978:          (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
        !          4979: 
        !          4980:     /* if we deadlocked, we have no locks to release
        !          4981:        ourselves, so sleep a while waiting for things
        !          4982:        to clear up, then try again: */
        !          4983:     if (err == TME_EDEADLK) {
        !          4984:       TME_THREAD_DEADLOCK_SLEEP();
        !          4985:       cycle.tme_bus_cycle_address = physical_address;
        !          4986:     }
        !          4987: 
        !          4988:     /* otherwise, any other error might be a bus error: */
        !          4989:     else if (err != TME_OK) {
        !          4990:       err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err);
        !          4991:       if (err != TME_OK) {
        !          4992:         exception = TME_M68K_EXCEPTION_GROUP0_BERR;
        !          4993:         break;
        !          4994:       }
        !          4995:     }
        !          4996: 
        !          4997:     /* update: */
        !          4998:     linear_address += cycle.tme_bus_cycle_size;
        !          4999:     transferred += cycle.tme_bus_cycle_size;
        !          5000:   }
        !          5001: 
        !          5002:   /* if we got an exception and there is a locked
        !          5003:      read/modify/write rwlock, unlock it: */
        !          5004:   if (exception != TME_M68K_EXCEPTION_NONE
        !          5005:       && (flags & TME_M68K_BUS_CYCLE_RMW)
        !          5006:       && rmw_rwlock != NULL) {
        !          5007:     tme_rwlock_unlock(rmw_rwlock);
        !          5008:   }
        !          5009: 
        !          5010:   /* if we faulted, stash the information the fault stacker
        !          5011:      will need and start exception processing: */
        !          5012:   if (exception != TME_M68K_EXCEPTION_NONE) {
        !          5013:     ic->_tme_m68k_group0_flags = flags | TME_M68K_BUS_CYCLE_READ;
        !          5014:     ic->_tme_m68k_group0_function_code = function_code;
        !          5015:     ic->_tme_m68k_group0_address = linear_address;
        !          5016:     ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence;
        !          5017:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred;
        !          5018:     ic->_tme_m68k_group0_buffer_read_size = cycle_size;
        !          5019:     if (ic->_tme_m68k_group0_hook != NULL) {
        !          5020:       (*ic->_tme_m68k_group0_hook)(ic);
        !          5021:     }
        !          5022:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 
        !          5023:       ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next;
        !          5024:     tme_m68k_exception(ic, exception);
        !          5025:   }
        !          5026: 
        !          5027:   /* otherwise, this transfer has now completed: */
        !          5028:   TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          5029: }
        !          5030: 
        !          5031: /* this writes a any-bit mem value: */
        !          5032: void
        !          5033: tme_m68k_write_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 
        !          5034: {
        !          5035:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
        !          5036:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
        !          5037:   tme_uint32_t linear_address_last = linear_address_first + count - 1;
        !          5038:   struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first);
        !          5039: 
        !          5040:   /* log the value written: */
        !          5041:   tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_WRITE);
        !          5042:   tme_m68k_log_start(ic, 1000, TME_OK) {
        !          5043:     unsigned int byte_i;
        !          5044:     tme_log_part(TME_M68K_LOG_HANDLE(ic),
        !          5045:                  _("write_mem %d:0x%08x count %d:"),
        !          5046:                  ic->_tme_m68k_ea_function_code,
        !          5047:                  ic->_tme_m68k_ea_address,
        !          5048:                  count);
        !          5049:     for (byte_i = 0; byte_i < count ; byte_i++) {
        !          5050:       tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]);
        !          5051:     }
        !          5052:   } tme_m68k_log_finish(ic);
        !          5053: 
        !          5054:   /* do the bus cycle(s) ourselves from emulator memory if we can.
        !          5055:      the emulator memory allocator and TLB filler must guarantee
        !          5056:      that all tme_m68k_tlb_emulator_off_write pointers be 32-bit
        !          5057:      aligned, so that a 16-bit-aligned linear address gets a
        !          5058:      16-bit-aligned emulator address: */
        !          5059:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
        !          5060:                          && !(linear_address_first & 1)
        !          5061:                          && TME_M68K_TLB_OK_FAST_WRITE(tlb,
        !          5062:                                                       function_code,
        !          5063:                                                       linear_address_first,
        !          5064:                                                       linear_address_last))) {
        !          5065: 
        !          5066:     tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          5067:     memcpy((tlb->tme_m68k_tlb_emulator_off_write + linear_address_first), buffer, count);
        !          5068:     tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock);
        !          5069:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          5070:   }
        !          5071: 
        !          5072:   /* otherwise, do the bus cycles the slow way: */
        !          5073:   else {
        !          5074:     tme_m68k_write(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW);
        !          5075:   }
        !          5076: }
        !          5077: 
        !          5078: /* this writes a region of address space using actual bus cycles: */
        !          5079: void
        !          5080: tme_m68k_write(struct tme_m68k *ic, 
        !          5081:               struct tme_m68k_tlb *tlb,
        !          5082:               unsigned int *_function_code, 
        !          5083:               tme_uint32_t *_linear_address, 
        !          5084:               tme_uint8_t *reg,
        !          5085:               unsigned int reg_size,
        !          5086:               unsigned int flags)
        !          5087: {
        !          5088:   unsigned int function_code;
        !          5089:   tme_uint32_t linear_address;
        !          5090:   tme_bus_addr_t physical_address;
        !          5091:   int shift;
        !          5092:   struct tme_bus_cycle cycle;
        !          5093:   unsigned int transferred, resid, cycle_size;
        !          5094:   int exception;
        !          5095:   tme_rwlock_t *rmw_rwlock;
        !          5096:   int err;
        !          5097: #ifndef WORDS_BIGENDIAN
        !          5098:   tme_uint8_t *reg_p;
        !          5099:   unsigned int buffer_i;
        !          5100: #endif /* !WORDS_BIGENDIAN */
        !          5101: 
        !          5102:   /* if we're not restarting, everything is fresh: */
        !          5103:   if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5104:     function_code = *_function_code;
        !          5105:     linear_address = *_linear_address;
        !          5106:     transferred = 0;
        !          5107:   }
        !          5108: 
        !          5109:   /* otherwise, if this is the transfer that faulted, restore
        !          5110:      our state to the cycle that faulted, then take into account
        !          5111:      any data provided by a software rerun of the faulted cycle: */
        !          5112:   else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted
        !          5113:            == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) {
        !          5114:     function_code = *_function_code = ic->_tme_m68k_group0_function_code;
        !          5115:     linear_address = ic->_tme_m68k_group0_address;
        !          5116:     transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after;
        !          5117:     if (transferred >= reg_size) abort();
        !          5118:     *_linear_address = linear_address - transferred;
        !          5119:     resid = reg_size - transferred;
        !          5120:     if (ic->_tme_m68k_group0_buffer_write_size > resid) abort();
        !          5121:     if (ic->_tme_m68k_group0_buffer_write_softrr > resid) abort();
        !          5122:     if (ic->_tme_m68k_group0_buffer_write_softrr == 0) {
        !          5123: #ifdef WORDS_BIGENDIAN
        !          5124:       memcpy(reg + transferred, 
        !          5125:              ic->_tme_m68k_group0_buffer_write,
        !          5126:              ic->_tme_m68k_group0_buffer_write_size);
        !          5127: #else  /* !WORDS_BIGENDIAN */
        !          5128:       reg_p = (reg + reg_size - 1) - transferred;
        !          5129:       for (buffer_i = 0;
        !          5130:            buffer_i < ic->_tme_m68k_group0_buffer_write_size;
        !          5131:            buffer_i++) {
        !          5132:         *(reg_p--) = ic->_tme_m68k_group0_buffer_write[buffer_i];
        !          5133:       }
        !          5134: #endif /* !WORDS_BIGENDIAN */
        !          5135:     }
        !          5136:     transferred += ic->_tme_m68k_group0_buffer_write_softrr;
        !          5137:   }
        !          5138: 
        !          5139:   /* otherwise, a later transfer has faulted.  just step the
        !          5140:      transfer number and return: */
        !          5141:   else {
        !          5142:     TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          5143:     return;
        !          5144:   }
        !          5145: 
        !          5146:   /* do as many bus cycles as needed to complete the transfer: */
        !          5147:   rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock;
        !          5148:   exception = TME_M68K_EXCEPTION_NONE;
        !          5149:   cycle_size = 0;
        !          5150:   for(; transferred < reg_size; ) {
        !          5151:     resid = reg_size - transferred;
        !          5152: 
        !          5153:     /* start the bus cycle structure: */
        !          5154:     cycle.tme_bus_cycle_type = TME_BUS_CYCLE_WRITE;
        !          5155:     if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
        !          5156:         || (flags & TME_M68K_BUS_CYCLE_RAW)) {
        !          5157:       cycle.tme_bus_cycle_buffer = reg + transferred;
        !          5158:       cycle.tme_bus_cycle_buffer_increment = 1;
        !          5159:     }
        !          5160:     else {
        !          5161:       cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred);
        !          5162:       cycle.tme_bus_cycle_buffer_increment = -1;
        !          5163:     }
        !          5164: 
        !          5165:     /* if we're emulating a CPU with a 16-bit bus interface: */
        !          5166:     if (ic->_tme_m68k_bus_16bit) {
        !          5167: 
        !          5168:       /* if we're trying to transfer a non-power-of-two
        !          5169:          number of bytes, either the CPU is broken (no
        !          5170:          instructions ever transfer a non-power-of-two
        !          5171:          number of bytes), or this function allowed an
        !          5172:          unaligned transfer: */
        !          5173:       assert((resid & (resid - 1)) == 0
        !          5174:              || (flags & TME_M68K_BUS_CYCLE_RAW));
        !          5175: 
        !          5176:       /* only byte transfers can be unaligned: */
        !          5177:       if (resid > sizeof(tme_uint8_t)
        !          5178:           && (linear_address & 1)) {
        !          5179:           exception = TME_M68K_EXCEPTION_GROUP0_AERR;
        !          5180:           break;
        !          5181:       }
        !          5182: 
        !          5183:       /* set the bus-size specific parts of the bus cycle structure: */
        !          5184:       cycle_size = TME_MIN(resid, sizeof(tme_uint16_t));
        !          5185:       cycle.tme_bus_cycle_size = cycle_size;
        !          5186:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2);
        !          5187:       cycle.tme_bus_cycle_lane_routing = 
        !          5188:         &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)];
        !          5189:     }
        !          5190: 
        !          5191:     /* otherwise we're emulating a CPU with a 32-bit bus interface: */
        !          5192:     else {
        !          5193: 
        !          5194:       /* set the bus-size specific parts of the bus cycle structure: */
        !          5195:       cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1)));
        !          5196:       cycle.tme_bus_cycle_size = cycle_size;
        !          5197:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
        !          5198:       cycle.tme_bus_cycle_lane_routing = 
        !          5199:         &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)];
        !          5200:     }
        !          5201: 
        !          5202:     /* reload the TLB entry: */
        !          5203:     if (!TME_M68K_TLB_OK_SLOW_WRITE(tlb, function_code, linear_address)) {
        !          5204:       tme_m68k_tlb_fill(ic, tlb,
        !          5205:                         function_code,
        !          5206:                         linear_address,
        !          5207:                         TME_BUS_CYCLE_WRITE);
        !          5208:     }
        !          5209: 
        !          5210:     /* if this is a part of a read/modify/write cycle: */
        !          5211:     if (flags & TME_M68K_BUS_CYCLE_RMW) {
        !          5212: 
        !          5213:       /* if this TLB entry doesn't support fast writes, or
        !          5214:          if the TLB lock has changed, that's a bus error.
        !          5215:          see the discussion in tme_m68k_rmw_start: */
        !          5216:       if (!TME_M68K_TLB_OK_FAST_WRITE(tlb, function_code, linear_address, linear_address)
        !          5217:           || (rmw_rwlock != NULL
        !          5218:               && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) {
        !          5219:         exception = TME_M68K_EXCEPTION_GROUP0_BERR;
        !          5220:         break;
        !          5221:       }
        !          5222: 
        !          5223:       /* if we haven't locked this memory yet, do so: */
        !          5224:       if (rmw_rwlock == NULL) {
        !          5225:         rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock;
        !          5226:         tme_rwlock_wrlock(rmw_rwlock);
        !          5227:       }
        !          5228:     }
        !          5229: 
        !          5230:     /* form the physical address for the bus cycle handler: */
        !          5231:     physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address;
        !          5232:     shift = tlb->tme_m68k_tlb_addr_shift;
        !          5233:     if (shift < 0) {
        !          5234:       physical_address <<= (0 - shift);
        !          5235:     }
        !          5236:     else if (shift > 0) {
        !          5237:       physical_address >>= shift;
        !          5238:     }
        !          5239:     cycle.tme_bus_cycle_address = physical_address;
        !          5240: 
        !          5241:     /* run the bus cycle: */
        !          5242:     err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle)
        !          5243:          (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
        !          5244: 
        !          5245:     /* if we deadlocked, we have no locks to release
        !          5246:        ourselves, so sleep a while waiting for things
        !          5247:        to clear up, then try again: */
        !          5248:     if (err == TME_EDEADLK) {
        !          5249:       TME_THREAD_DEADLOCK_SLEEP();
        !          5250:       cycle.tme_bus_cycle_address = physical_address;
        !          5251:     }
        !          5252: 
        !          5253:     /* otherwise, any other error might be a bus error: */
        !          5254:     else if (err != TME_OK) {
        !          5255:       err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err);
        !          5256:       if (err != TME_OK) {
        !          5257:         exception = TME_M68K_EXCEPTION_GROUP0_BERR;
        !          5258:         break;
        !          5259:       }
        !          5260:     }
        !          5261: 
        !          5262:     /* update: */
        !          5263:     linear_address += cycle.tme_bus_cycle_size;
        !          5264:     transferred += cycle.tme_bus_cycle_size;
        !          5265:   }
        !          5266: 
        !          5267:   /* if we got an exception and there is a locked
        !          5268:      read/modify/write rwlock, unlock it: */
        !          5269:   if (exception != TME_M68K_EXCEPTION_NONE
        !          5270:       && (flags & TME_M68K_BUS_CYCLE_RMW)
        !          5271:       && rmw_rwlock != NULL) {
        !          5272:     tme_rwlock_unlock(rmw_rwlock);
        !          5273:   }
        !          5274: 
        !          5275:   /* if we faulted, stash the information the fault stacker
        !          5276:      will need and start exception processing: */
        !          5277:   if (exception != TME_M68K_EXCEPTION_NONE) {
        !          5278:     ic->_tme_m68k_group0_flags = flags;
        !          5279:     ic->_tme_m68k_group0_function_code = function_code;
        !          5280:     ic->_tme_m68k_group0_address = linear_address;
        !          5281:     ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence;
        !          5282:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred;
        !          5283:     ic->_tme_m68k_group0_buffer_write_size = cycle_size;
        !          5284: #ifdef WORDS_BIGENDIAN
        !          5285:     memcpy(ic->_tme_m68k_group0_buffer_write,
        !          5286:            reg + transferred,
        !          5287:            ic->_tme_m68k_group0_buffer_write_size);
        !          5288: #else  /* !WORDS_BIGENDIAN */
        !          5289:       reg_p = (reg + reg_size - 1) - transferred;
        !          5290:       for (buffer_i = 0;
        !          5291:            buffer_i < ic->_tme_m68k_group0_buffer_write_size;
        !          5292:            buffer_i++) {
        !          5293:         ic->_tme_m68k_group0_buffer_write[buffer_i] = *(reg_p--);
        !          5294:       }
        !          5295: #endif /* !WORDS_BIGENDIAN */
        !          5296:     if (ic->_tme_m68k_group0_hook != NULL) {
        !          5297:       (*ic->_tme_m68k_group0_hook)(ic);
        !          5298:     }
        !          5299:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 
        !          5300:       ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next;
        !          5301:     tme_m68k_exception(ic, exception);
        !          5302:   }
        !          5303: 
        !          5304:   /* otherwise, this transfer has now completed: */
        !          5305:   TME_M68K_SEQUENCE_TRANSFER_STEP;
        !          5306: }
        !          5307: 
        !          5308: TME_M68K_INSN(tme_m68k_abcd)
        !          5309: {
        !          5310:   tme_uint8_t dst, dst_msd, dst_lsd;
        !          5311:   tme_uint8_t src, src_msd, src_lsd;
        !          5312:   tme_uint8_t res, res_msd, res_lsd;
        !          5313:   tme_uint8_t flags;
        !          5314:   int memory;
        !          5315:   int rx, ry, function_code;
        !          5316: 
        !          5317:   TME_M68K_INSN_CANFAULT;
        !          5318: 
        !          5319:   /* load the operands: */
        !          5320:   rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          5321:   ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          5322:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0;
        !          5323:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          5324:   if (memory) {
        !          5325:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5326:       ic->_tme_m68k_ea_function_code = function_code;
        !          5327:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx);
        !          5328:     }
        !          5329:     tme_m68k_read_memx8(ic);
        !          5330:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5331:       ic->_tme_m68k_ea_function_code = function_code;
        !          5332:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
        !          5333:     }
        !          5334:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32);
        !          5335:     src = ic->tme_m68k_ireg_memx8;
        !          5336:     dst = ic->tme_m68k_ireg_memy8;
        !          5337:   }
        !          5338:   else {
        !          5339:     src = ic->tme_m68k_ireg_uint8(rx << 2);
        !          5340:     dst = ic->tme_m68k_ireg_uint8(ry << 2);
        !          5341:   }
        !          5342:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
        !          5343:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
        !          5344:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
        !          5345:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
        !          5346: 
        !          5347:   /* perform the operation: */
        !          5348:   res_lsd = dst_lsd + src_lsd + ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
        !          5349:   res_msd = dst_msd + src_msd;
        !          5350:   flags = 0;
        !          5351:   if (res_lsd > 9) {
        !          5352:     res_lsd -= 10;
        !          5353:     res_msd += 1;
        !          5354:   }
        !          5355:   if (res_msd > 9) {
        !          5356:     res_msd -= 10;
        !          5357:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          5358:   }
        !          5359:   res = (res_msd << 4) + (res_lsd & 0xf);
        !          5360:   if (res == 0) flags |= TME_M68K_FLAG_N;
        !          5361: 
        !          5362:   /* store the result and set the flags: */
        !          5363:   if (memory) {
        !          5364:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5365:       ic->tme_m68k_ireg_memx8 = res;
        !          5366:       ic->_tme_m68k_ea_function_code = function_code;
        !          5367:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
        !          5368:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) += sizeof(tme_uint8_t) + ((rx + 1) >> 3);
        !          5369:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) += sizeof(tme_uint8_t) + ((ry + 1) >> 3);
        !          5370:       ic->tme_m68k_ireg_ccr = flags;
        !          5371:      }
        !          5372:      tme_m68k_write_memx8(ic);
        !          5373:   }
        !          5374:   else {
        !          5375:     ic->tme_m68k_ireg_uint8(ry << 2) = res;
        !          5376:     ic->tme_m68k_ireg_ccr = flags;
        !          5377:   }
        !          5378: 
        !          5379:   TME_M68K_INSN_OK;
        !          5380: }
        !          5381: 
        !          5382: TME_M68K_INSN(tme_m68k_sbcd)
        !          5383: {
        !          5384:   tme_uint8_t dst, dst_msd, dst_lsd;
        !          5385:   tme_uint8_t src, src_msd, src_lsd;
        !          5386:   tme_uint8_t res, res_msd, res_lsd;
        !          5387:   tme_uint8_t flags;
        !          5388:   int memory;
        !          5389:   int rx, ry, function_code;
        !          5390: 
        !          5391:   TME_M68K_INSN_CANFAULT;
        !          5392: 
        !          5393:   /* load the operands: */
        !          5394:   rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
        !          5395:   ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
        !          5396:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0;
        !          5397:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
        !          5398:   if (memory) {
        !          5399:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5400:       ic->_tme_m68k_ea_function_code = function_code;
        !          5401:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx);
        !          5402:     }
        !          5403:     tme_m68k_read_memx8(ic);
        !          5404:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5405:       ic->_tme_m68k_ea_function_code = function_code;
        !          5406:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
        !          5407:     }
        !          5408:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32);
        !          5409:     src = ic->tme_m68k_ireg_memx8;
        !          5410:     dst = ic->tme_m68k_ireg_memy8;
        !          5411:   }
        !          5412:   else {
        !          5413:     src = ic->tme_m68k_ireg_uint8(rx << 2);
        !          5414:     dst = ic->tme_m68k_ireg_uint8(ry << 2);
        !          5415:   }
        !          5416:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
        !          5417:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
        !          5418:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
        !          5419:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
        !          5420: 
        !          5421:   /* perform the operation: */
        !          5422:   res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
        !          5423:   res_msd = dst_msd - src_msd;
        !          5424:   flags = 0;
        !          5425:   if (res_lsd > 9) {
        !          5426:     res_lsd += 10;
        !          5427:     res_msd -= 1;
        !          5428:   }
        !          5429:   if (res_msd > 9) {
        !          5430:     res_msd += 10;
        !          5431:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          5432:   }
        !          5433:   res = (res_msd << 4) + (res_lsd & 0xf);
        !          5434:   if (res == 0) flags |= TME_M68K_FLAG_N;
        !          5435: 
        !          5436:   /* store the result and set the flags: */
        !          5437:   if (memory) {
        !          5438:     if (!TME_M68K_SEQUENCE_RESTARTING) {
        !          5439:       ic->tme_m68k_ireg_memx8 = res;
        !          5440:       ic->_tme_m68k_ea_function_code = function_code;
        !          5441:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
        !          5442:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) += sizeof(tme_uint8_t) + ((rx + 1) >> 3);
        !          5443:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) += sizeof(tme_uint8_t) + ((ry + 1) >> 3);
        !          5444:       ic->tme_m68k_ireg_ccr = flags;
        !          5445:      }
        !          5446:      tme_m68k_write_memx8(ic);
        !          5447:   }
        !          5448:   else {
        !          5449:     ic->tme_m68k_ireg_uint8(ry << 2) = res;
        !          5450:     ic->tme_m68k_ireg_ccr = flags;
        !          5451:   }
        !          5452: 
        !          5453:   TME_M68K_INSN_OK;
        !          5454: }
        !          5455: 
        !          5456: TME_M68K_INSN(tme_m68k_nbcd)
        !          5457: {
        !          5458:   tme_uint8_t dst, dst_msd, dst_lsd;
        !          5459:   tme_uint8_t src, src_msd, src_lsd;
        !          5460:   tme_uint8_t res, res_msd, res_lsd;
        !          5461:   tme_uint8_t flags;
        !          5462: 
        !          5463:   dst = 0x00;
        !          5464:   src = TME_M68K_INSN_OP1(tme_uint8_t);
        !          5465:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
        !          5466:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
        !          5467:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
        !          5468:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
        !          5469: 
        !          5470:   /* perform the operation: */
        !          5471:   res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
        !          5472:   res_msd = dst_msd - src_msd;
        !          5473:   flags = 0;
        !          5474:   if (res_lsd > 9) {
        !          5475:     res_lsd += 10;
        !          5476:     res_msd -= 1;
        !          5477:   }
        !          5478:   if (res_msd > 9) {
        !          5479:     res_msd += 10;
        !          5480:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
        !          5481:   }
        !          5482:   res = (res_msd << 4) + (res_lsd & 0xf);
        !          5483:   if (res == 0) flags |= TME_M68K_FLAG_N;
        !          5484: 
        !          5485:   /* store the result and set the flags: */
        !          5486:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
        !          5487:   ic->tme_m68k_ireg_ccr = flags;
        !          5488: 
        !          5489:   TME_M68K_INSN_OK;
        !          5490: }
        !          5491: 
        !          5492: TME_M68K_INSN(tme_m68k_ori_ccr)
        !          5493: {
        !          5494:   tme_uint8_t reg;
        !          5495:   reg = ic->tme_m68k_ireg_ccr | (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
        !          5496:   ic->tme_m68k_ireg_ccr = reg;
        !          5497:   TME_M68K_INSN_OK;
        !          5498: }
        !          5499: 
        !          5500: TME_M68K_INSN(tme_m68k_andi_ccr)
        !          5501: {
        !          5502:   tme_uint8_t reg;
        !          5503:   reg = ic->tme_m68k_ireg_ccr & (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
        !          5504:   ic->tme_m68k_ireg_ccr = reg;
        !          5505:   TME_M68K_INSN_OK;
        !          5506: }
        !          5507: 
        !          5508: TME_M68K_INSN(tme_m68k_eori_ccr)
        !          5509: {
        !          5510:   tme_uint8_t reg;
        !          5511:   reg = ic->tme_m68k_ireg_ccr ^ (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
        !          5512:   ic->tme_m68k_ireg_ccr = reg;
        !          5513:   TME_M68K_INSN_OK;
        !          5514: }
        !          5515: 
        !          5516: TME_M68K_INSN(tme_m68k_move_to_ccr)
        !          5517: {
        !          5518:   tme_uint8_t reg;
        !          5519:   reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_CCR);
        !          5520:   ic->tme_m68k_ireg_ccr = reg;
        !          5521:   TME_M68K_INSN_OK;
        !          5522: }
        !          5523: 
        !          5524: TME_M68K_INSN(tme_m68k_ori_sr)
        !          5525: {
        !          5526:   tme_uint16_t reg;
        !          5527:   reg = ic->tme_m68k_ireg_sr | (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
        !          5528:   TME_M68K_INSN_PRIV;
        !          5529:   TME_M68K_INSN_CHANGE_SR(reg);
        !          5530:   TME_M68K_INSN_OK;
        !          5531: }
        !          5532: 
        !          5533: TME_M68K_INSN(tme_m68k_andi_sr)
        !          5534: {
        !          5535:   tme_uint16_t reg;
        !          5536:   reg = ic->tme_m68k_ireg_sr & (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
        !          5537:   TME_M68K_INSN_PRIV;
        !          5538:   TME_M68K_INSN_CHANGE_SR(reg);
        !          5539:   TME_M68K_INSN_OK;
        !          5540: }
        !          5541: 
        !          5542: TME_M68K_INSN(tme_m68k_eori_sr)
        !          5543: {
        !          5544:   tme_uint16_t reg;
        !          5545:   reg = ic->tme_m68k_ireg_sr ^ (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
        !          5546:   TME_M68K_INSN_PRIV;
        !          5547:   TME_M68K_INSN_CHANGE_SR(reg);
        !          5548:   TME_M68K_INSN_OK;
        !          5549: }
        !          5550: 
        !          5551: TME_M68K_INSN(tme_m68k_move_to_sr)
        !          5552: {
        !          5553:   tme_uint16_t reg;
        !          5554:   reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_SR);
        !          5555:   TME_M68K_INSN_PRIV;
        !          5556:   TME_M68K_INSN_CHANGE_SR(reg);
        !          5557:   TME_M68K_INSN_OK;
        !          5558: }
        !          5559: 
        !          5560: TME_M68K_INSN(tme_m68k_mulu)
        !          5561: {
        !          5562:   int ireg_dl;
        !          5563:   tme_uint32_t res;
        !          5564:   tme_uint8_t flags;
        !          5565: 
        !          5566:   /* get the register containing the factor: */
        !          5567:   ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
        !          5568: 
        !          5569:   /* perform the multiplication: */
        !          5570:   res = (((tme_uint32_t) ic->tme_m68k_ireg_uint16(ireg_dl << 1))
        !          5571:          * TME_M68K_INSN_OP1(tme_uint16_t));
        !          5572: 
        !          5573:   /* store the result: */
        !          5574:   ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res;
        !          5575: 
        !          5576:   /* set the flags: */
        !          5577:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5578:   if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N;
        !          5579:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          5580:   ic->tme_m68k_ireg_ccr = flags;
        !          5581: 
        !          5582:   TME_M68K_INSN_OK;
        !          5583: }
        !          5584: 
        !          5585: TME_M68K_INSN(tme_m68k_divu)
        !          5586: {
        !          5587:   int ireg_dq;
        !          5588:   tme_uint32_t dividend, quotient;
        !          5589:   tme_uint16_t divisor, remainder;
        !          5590:   tme_uint8_t flags;
        !          5591: 
        !          5592:   /* get the register(s): */
        !          5593:   ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
        !          5594: 
        !          5595:   /* form the dividend and the divisor: */
        !          5596:   dividend = (tme_uint32_t) ic->tme_m68k_ireg_uint32(ireg_dq);
        !          5597:   divisor = TME_M68K_INSN_OP1(tme_uint16_t);
        !          5598:   if (divisor == 0) {
        !          5599:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          5600:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5));
        !          5601:   }
        !          5602: 
        !          5603:   /* do the division: */
        !          5604:   quotient = dividend / divisor;
        !          5605:   remainder = dividend % divisor;
        !          5606: 
        !          5607:   /* set the flags and return the quotient and remainder: */
        !          5608:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5609:   if (quotient > 0xffff) {
        !          5610:     flags |= TME_M68K_FLAG_V;
        !          5611:   }
        !          5612:   else {
        !          5613:     if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
        !          5614:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
        !          5615:     ic->tme_m68k_ireg_uint16(ireg_dq << 1) = (tme_uint16_t) quotient;
        !          5616:     ic->tme_m68k_ireg_uint16((ireg_dq << 1) + 1) = remainder;
        !          5617:   }
        !          5618:   ic->tme_m68k_ireg_ccr = flags;
        !          5619: 
        !          5620:   TME_M68K_INSN_OK;
        !          5621: }
        !          5622: 
        !          5623: TME_M68K_INSN(tme_m68k_mulul)
        !          5624: {
        !          5625: #ifndef HAVE_UINT64_T
        !          5626:   abort();
        !          5627: #else /* HAVE_UINT64_T */
        !          5628:   unsigned int flag_v;
        !          5629:   int ireg_dh;
        !          5630:   int ireg_dl;
        !          5631:   tme_uint64_t res;
        !          5632:   tme_uint8_t flags;
        !          5633: 
        !          5634:   /* get the register containing the factor: */
        !          5635:   ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
        !          5636: 
        !          5637:   /* perform the multiplication: */
        !          5638:   res = (((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dl))
        !          5639:          * TME_M68K_INSN_OP1(tme_uint32_t));
        !          5640: 
        !          5641:   /* store the result: */
        !          5642:   ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res;
        !          5643:   flag_v = TME_M68K_FLAG_V;
        !          5644:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
        !          5645:     flag_v = 0;
        !          5646:     ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
        !          5647:     ic->tme_m68k_ireg_uint32(ireg_dh) = (tme_uint32_t) (res >> 32);
        !          5648:   }
        !          5649: 
        !          5650:   /* set the flags: */
        !          5651:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5652:   if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N;
        !          5653:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          5654:   if (res > 0xffffffff) flags |= flag_v;
        !          5655:   ic->tme_m68k_ireg_ccr = flags;
        !          5656: 
        !          5657:   TME_M68K_INSN_OK;
        !          5658: #endif /* HAVE_UINT64_T */
        !          5659: }
        !          5660: 
        !          5661: TME_M68K_INSN(tme_m68k_divul)
        !          5662: {
        !          5663: #ifndef HAVE_UINT64_T
        !          5664:   abort();
        !          5665: #else /* HAVE_UINT64_T */
        !          5666:   int ireg_dr;
        !          5667:   int ireg_dq;
        !          5668:   tme_uint64_t dividend, quotient;
        !          5669:   tme_uint32_t divisor, remainder;
        !          5670:   tme_uint8_t flags;
        !          5671: 
        !          5672:   /* get the register(s): */
        !          5673:   ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
        !          5674:   ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
        !          5675: 
        !          5676:   /* form the dividend and the divisor: */
        !          5677:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
        !          5678:     dividend = (tme_uint64_t)
        !          5679:                ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32)
        !          5680:                 | ic->tme_m68k_ireg_uint32(ireg_dq));
        !          5681:   }
        !          5682:   else
        !          5683:     dividend = (tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dq);
        !          5684:   divisor = TME_M68K_INSN_OP1(tme_uint32_t);
        !          5685:   if (divisor == 0) {
        !          5686:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          5687:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5));
        !          5688:   }
        !          5689: 
        !          5690:   /* do the division: */
        !          5691:   quotient = dividend / divisor;
        !          5692:   remainder = dividend % divisor;
        !          5693: 
        !          5694:   /* set the flags and return the quotient and remainder: */
        !          5695:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5696:   if (quotient > 0xffffffff) {
        !          5697:     flags |= TME_M68K_FLAG_V;
        !          5698:   }
        !          5699:   else {
        !          5700:     if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
        !          5701:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
        !          5702:     ic->tme_m68k_ireg_uint32(ireg_dq) = (tme_uint32_t) quotient;
        !          5703:     if (ireg_dr != ireg_dq) {
        !          5704:       ic->tme_m68k_ireg_uint32(ireg_dr) = remainder;
        !          5705:     }
        !          5706:   }
        !          5707:   ic->tme_m68k_ireg_ccr = flags;
        !          5708: 
        !          5709:   TME_M68K_INSN_OK;
        !          5710: #endif /* HAVE_UINT64_T */
        !          5711: }
        !          5712: 
        !          5713: TME_M68K_INSN(tme_m68k_muls)
        !          5714: {
        !          5715:   int ireg_dl;
        !          5716:   tme_int32_t res;
        !          5717:   tme_uint8_t flags;
        !          5718: 
        !          5719:   /* get the register containing the factor: */
        !          5720:   ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
        !          5721: 
        !          5722:   /* perform the multiplication: */
        !          5723:   res = (((tme_int32_t) ic->tme_m68k_ireg_int16(ireg_dl << 1))
        !          5724:          * TME_M68K_INSN_OP1(tme_int16_t));
        !          5725: 
        !          5726:   /* store the result: */
        !          5727:   ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res;
        !          5728: 
        !          5729:   /* set the flags: */
        !          5730:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5731:   if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N;
        !          5732:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          5733:   ic->tme_m68k_ireg_ccr = flags;
        !          5734: 
        !          5735:   TME_M68K_INSN_OK;
        !          5736: }
        !          5737: 
        !          5738: TME_M68K_INSN(tme_m68k_divs)
        !          5739: {
        !          5740:   int ireg_dq;
        !          5741:   tme_int32_t dividend, quotient;
        !          5742:   tme_int16_t divisor, remainder;
        !          5743:   tme_uint8_t flags;
        !          5744: 
        !          5745:   /* get the register(s): */
        !          5746:   ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
        !          5747: 
        !          5748:   /* form the dividend and the divisor: */
        !          5749:   dividend = (tme_int32_t) ic->tme_m68k_ireg_int32(ireg_dq);
        !          5750:   divisor = TME_M68K_INSN_OP1(tme_int16_t);
        !          5751:   if (divisor == 0) {
        !          5752:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          5753:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5));
        !          5754:   }
        !          5755: 
        !          5756:   /* do the division: */
        !          5757:   quotient = dividend / divisor;
        !          5758:   remainder = dividend % divisor;
        !          5759: 
        !          5760:   /* set the flags and return the quotient and remainder: */
        !          5761:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5762:   if (quotient > 0xffff || quotient < -32768) {
        !          5763:     flags |= TME_M68K_FLAG_V;
        !          5764:   }
        !          5765:   else {
        !          5766:     if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
        !          5767:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
        !          5768:     ic->tme_m68k_ireg_int16(ireg_dq << 1) = (tme_int16_t) quotient;
        !          5769:     ic->tme_m68k_ireg_int16((ireg_dq << 1) + 1) = remainder;
        !          5770:   }
        !          5771:   ic->tme_m68k_ireg_ccr = flags;
        !          5772: 
        !          5773:   TME_M68K_INSN_OK;
        !          5774: }
        !          5775: 
        !          5776: TME_M68K_INSN(tme_m68k_mulsl)
        !          5777: {
        !          5778: #ifndef HAVE_UINT64_T
        !          5779:   abort();
        !          5780: #else /* HAVE_UINT64_T */
        !          5781:   unsigned int flag_v;
        !          5782:   int ireg_dh;
        !          5783:   int ireg_dl;
        !          5784:   tme_int64_t res;
        !          5785:   tme_uint8_t flags;
        !          5786: 
        !          5787:   /* get the register containing the factor: */
        !          5788:   ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
        !          5789: 
        !          5790:   /* perform the multiplication: */
        !          5791:   res = (((tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dl))
        !          5792:          * TME_M68K_INSN_OP1(tme_int32_t));
        !          5793: 
        !          5794:   /* store the result: */
        !          5795:   ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res;
        !          5796:   flag_v = TME_M68K_FLAG_V;
        !          5797:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
        !          5798:     flag_v = 0;
        !          5799:     ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
        !          5800:     ic->tme_m68k_ireg_int32(ireg_dh) = (tme_int32_t) (res >> 32);
        !          5801:   }
        !          5802: 
        !          5803:   /* set the flags: */
        !          5804:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5805:   if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N;
        !          5806:   if (res == 0) flags |= TME_M68K_FLAG_Z;
        !          5807:   if (res > 0xffffffff || res < -2147483648) flags |= flag_v;
        !          5808:   ic->tme_m68k_ireg_ccr = flags;
        !          5809: 
        !          5810:   TME_M68K_INSN_OK;
        !          5811: #endif /* HAVE_UINT64_T */
        !          5812: }
        !          5813: 
        !          5814: TME_M68K_INSN(tme_m68k_divsl)
        !          5815: {
        !          5816: #ifndef HAVE_UINT64_T
        !          5817:   abort();
        !          5818: #else /* HAVE_UINT64_T */
        !          5819:   int ireg_dr;
        !          5820:   int ireg_dq;
        !          5821:   tme_int64_t dividend, quotient;
        !          5822:   tme_int32_t divisor, remainder;
        !          5823:   tme_uint8_t flags;
        !          5824: 
        !          5825:   /* get the register(s): */
        !          5826:   ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
        !          5827:   ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
        !          5828: 
        !          5829:   /* form the dividend and the divisor: */
        !          5830:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
        !          5831:     dividend = (tme_int64_t)
        !          5832:                ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32)
        !          5833:                 | ic->tme_m68k_ireg_uint32(ireg_dq));
        !          5834:   }
        !          5835:   else
        !          5836:     dividend = (tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dq);
        !          5837:   divisor = TME_M68K_INSN_OP1(tme_int32_t);
        !          5838:   if (divisor == 0) {
        !          5839:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
        !          5840:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5));
        !          5841:   }
        !          5842: 
        !          5843:   /* do the division: */
        !          5844:   quotient = dividend / divisor;
        !          5845:   remainder = dividend % divisor;
        !          5846: 
        !          5847:   /* set the flags and return the quotient and remainder: */
        !          5848:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
        !          5849:   if (quotient > 0xffffffff || quotient < -2147483648) {
        !          5850:     flags |= TME_M68K_FLAG_V;
        !          5851:   }
        !          5852:   else {
        !          5853:     if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
        !          5854:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
        !          5855:     ic->tme_m68k_ireg_int32(ireg_dq) = (tme_int32_t) quotient;
        !          5856:     if (ireg_dr != ireg_dq) {
        !          5857:       ic->tme_m68k_ireg_int32(ireg_dr) = remainder;
        !          5858:     }
        !          5859:   }
        !          5860:   ic->tme_m68k_ireg_ccr = flags;
        !          5861: 
        !          5862:   TME_M68K_INSN_OK;
        !          5863: #endif /* HAVE_UINT64_T */
        !          5864: }
        !          5865: /* automatically generated by m68k-misc-auto.sh, do not edit! */
        !          5866: 
        !          5867: /* the flags->conditions mapping: */
        !          5868: const tme_uint16_t _tme_m68k_conditions[32] = {
        !          5869: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5870: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5871: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5872: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5873: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5874: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5875: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5876: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5877: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5878: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5879: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5880: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5881: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5882: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5883: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5884: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5885: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5886: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5887: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5888: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5889: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5890: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5891: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5892: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5893: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5894: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5895: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5896: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
        !          5897: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5898: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
        !          5899: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5900: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
        !          5901: };

unix.superglobalmegacorp.com

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