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

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

unix.superglobalmegacorp.com

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