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

1.1       root        1: /* m68k-insns.c - m68k instruction functions: */
                      2: 
                      3: /* $Header: /aquery/home0/fredette/project/tme/TME-CVS-LOCAL/tme/ic/m68k/m68k-insns.c,v 1.6 2003/05/09 17:45:06 fredette Exp $ */
                      4: 
                      5: /* includes: */
                      6: #include "m68k-impl.h"
                      7: 
                      8: _TME_RCSID("$Id: m68k-insns.c,v 1.6 2003/05/09 17:45:06 fredette Exp $");
                      9: 
                     10: #define TME_M68K_STD_FLAGS \
                     11: do { \
                     12:   ic->tme_m68k_ireg_ccr = ((ic->tme_m68k_ireg_ccr \
                     13:                             & TME_M68K_FLAG_X) \
                     14:                            | (res < 0 ? TME_M68K_FLAG_N : 0) \
                     15:                            | (res == 0 ? TME_M68K_FLAG_Z : 0)); \
                     16: } while (/* CONSTCOND */ 0)
                     17: 
                     18: /* this cannot fault: */
                     19: TME_M68K_INSN(tme_m68k_exg)
                     20: {
                     21:   tme_uint32_t tmp;
                     22:   tmp = TME_M68K_INSN_OP0(tme_uint32_t);
                     23:   TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
                     24:   TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
                     25:   TME_M68K_INSN_OK;
                     26: }
                     27: 
                     28: /* this cannot fault: */
                     29: TME_M68K_INSN(tme_m68k_extw)
                     30: {
                     31:   tme_int16_t res;
                     32:   res = TME_EXT_S8_S16((tme_int8_t) TME_M68K_INSN_OP1(tme_int16_t));
                     33:   TME_M68K_INSN_OP1(tme_int16_t) = res;
                     34:   TME_M68K_STD_FLAGS;
                     35:   TME_M68K_INSN_OK;
                     36: }
                     37: 
                     38: /* this cannot fault: */
                     39: TME_M68K_INSN(tme_m68k_extl)
                     40: {
                     41:   tme_int32_t res;
                     42:   res = TME_EXT_S16_S32((tme_int16_t) TME_M68K_INSN_OP1(tme_int32_t));
                     43:   TME_M68K_INSN_OP1(tme_int32_t) = res;
                     44:   TME_M68K_STD_FLAGS;
                     45:   TME_M68K_INSN_OK;
                     46: }
                     47: 
                     48: /* this cannot fault: */
                     49: TME_M68K_INSN(tme_m68k_extbl)
                     50: {
                     51:   tme_int32_t res;
                     52:   res = TME_EXT_S8_S32((tme_int8_t) TME_M68K_INSN_OP1(tme_int32_t));
                     53:   TME_M68K_INSN_OP1(tme_int32_t) = res;
                     54:   TME_M68K_STD_FLAGS;
                     55:   TME_M68K_INSN_OK;
                     56: }
                     57: 
                     58: /* this cannot fault: */
                     59: TME_M68K_INSN(tme_m68k_lea)
                     60: {
                     61:   TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
                     62:   TME_M68K_INSN_OK;
                     63: }
                     64: 
                     65: /* this cannot fault: */
                     66: TME_M68K_INSN(tme_m68k_move_from_ccr)
                     67: {
                     68:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_ccr;
                     69:   TME_M68K_INSN_OK;
                     70: }
                     71: 
                     72: /* this cannot fault: */
                     73: TME_M68K_INSN(tme_m68k_move_from_sr)
                     74: {
                     75:   TME_M68K_INSN_PRIV;
                     76:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
                     77:   TME_M68K_INSN_OK;
                     78: }
                     79: 
                     80: /* this cannot fault: */
                     81: /* this is the 68000 version, which isn't privileged: */
                     82: TME_M68K_INSN(tme_m68k_move_from_sr0)
                     83: {
                     84:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
                     85:   TME_M68K_INSN_OK;
                     86: }
                     87: 
                     88: /* this cannot fault: */
                     89: TME_M68K_INSN(tme_m68k_swap)
                     90: {
                     91:   tme_uint32_t tmp;
                     92:   tme_int32_t res;
                     93:   tmp = TME_M68K_INSN_OP1(tme_uint32_t);
                     94:   tmp = (TME_FIELD_EXTRACTU(tmp, 0, 16) << 16) | TME_FIELD_EXTRACTU(tmp, 16, 16);
                     95:   TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
                     96:   res = (tme_int32_t) tmp;
                     97:   TME_M68K_STD_FLAGS;
                     98:   TME_M68K_INSN_OK;
                     99: }
                    100: 
                    101: /* this cannot fault: */
                    102: TME_M68K_INSN(tme_m68k_nop)
                    103: {
                    104:   TME_M68K_INSN_OK;
                    105: }
                    106: 
                    107: /* this cannot fault: */
                    108: TME_M68K_INSN(tme_m68k_scc)
                    109: {
                    110:   TME_M68K_INSN_OP1(tme_uint8_t) =
                    111:     (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))
                    112:      ? 0xff
                    113:      : 0x00);
                    114:   TME_M68K_INSN_OK;
                    115: }
                    116: 
                    117: /* this cannot fault: */
                    118: TME_M68K_INSN(tme_m68k_dbcc)
                    119: {
                    120:   if (!TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
                    121:     if (--TME_M68K_INSN_OP0(tme_int16_t) != -1) {
                    122:       TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc
                    123:                           + 2
                    124:                           + TME_EXT_S16_U32(TME_M68K_INSN_OP1(tme_int16_t)));
                    125:     }
                    126:   }
                    127:   TME_M68K_INSN_OK;
                    128: }
                    129: 
                    130: /* this cannot fault: */
                    131: TME_M68K_INSN(tme_m68k_bcc)
                    132: {
                    133:   if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
                    134:     TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + TME_M68K_INSN_OP0(tme_uint32_t));
                    135:   }
                    136:   TME_M68K_INSN_OK;
                    137: }
                    138:     
                    139: /* this can fault: */
                    140: TME_M68K_INSN(tme_m68k_bsr)
                    141: {
                    142:   TME_M68K_INSN_CANFAULT;
                    143:   tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
                    144:   /* while the above push can fault, we don't have to worry about
                    145:      restarting here, because after this point, nothing can fault for
                    146:      the remainder of this instruction (the executor makes no stores
                    147:      on behalf of a bsr): */
                    148:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + TME_M68K_INSN_OP0(tme_uint32_t));
                    149:   TME_M68K_INSN_OK;
                    150: }
                    151: 
                    152: /* this can fault: */
                    153: TME_M68K_INSN(tme_m68k_pea)
                    154: {
                    155:   TME_M68K_INSN_CANFAULT;
                    156:   tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
                    157:   /* while the above push can fault, we don't have to worry about
                    158:      restarting here, because after this point, nothing can fault for
                    159:      the remainder of this instruction (the executor makes no stores
                    160:      on behalf of a pea): */
                    161:   TME_M68K_INSN_OK;
                    162: }
                    163: 
                    164: /* this cannot fault: */
                    165: TME_M68K_INSN(tme_m68k_bkpt)
                    166: {
                    167:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL);
                    168: }
                    169: 
                    170: /* this cannot fault: */
                    171: TME_M68K_INSN(tme_m68k_illegal)
                    172: {
                    173:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL);
                    174: }
                    175: 
                    176: /* this can fault: */
                    177: TME_M68K_INSN(tme_m68k_tas)
                    178: {
                    179:   struct tme_m68k_tlb *tlb;
                    180:   tme_uint8_t flags;
                    181:   tme_int8_t value;
                    182: 
                    183:   TME_M68K_INSN_CANFAULT;
                    184: 
                    185:   /* start the read/modify/write cycle: */
                    186:   tlb = tme_m68k_rmw_start(ic);
                    187:   if (tlb == NULL)
                    188:     TME_M68K_INSN_OK;
                    189: 
                    190:   /* the read part of the read/modify/write cycle: */
                    191:   tme_m68k_read8(ic, tlb,
                    192:                 &ic->_tme_m68k_ea_function_code,
                    193:                 &ic->_tme_m68k_ea_address,
                    194:                 &ic->tme_m68k_ireg_memx8,
                    195:                 TME_M68K_BUS_CYCLE_RMW);
                    196: 
                    197:   /* the modify part of the read/modify/write cycle: */
                    198:   value = ic->tme_m68k_ireg_memx8;
                    199:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    200:   if (value < 0) flags |= TME_M68K_FLAG_N;
                    201:   if (value == 0) flags |= TME_M68K_FLAG_Z;
                    202:   ic->tme_m68k_ireg_ccr = flags;
                    203:   ic->tme_m68k_ireg_memx8 |= 0x80;
                    204: 
                    205:   /* the write part of the read/modify/write cycle: */
                    206:   tme_m68k_write8(ic, tlb,
                    207:                  &ic->_tme_m68k_ea_function_code,
                    208:                  &ic->_tme_m68k_ea_address,
                    209:                  &ic->tme_m68k_ireg_memx8,
                    210:                  TME_M68K_BUS_CYCLE_RMW);
                    211: 
                    212:   /* finish the read/modify/write cycle: */
                    213:   tme_m68k_rmw_finish(ic, tlb);
                    214: 
                    215:   TME_M68K_INSN_OK;
                    216: }
                    217: 
                    218: /* this cannot fault: */
                    219: TME_M68K_INSN(tme_m68k_tas_r)
                    220: {
                    221:   tme_uint8_t flags;
                    222:   tme_int8_t value;
                    223:   value = TME_M68K_INSN_OP1(tme_int8_t);
                    224:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    225:   if (value < 0) flags |= TME_M68K_FLAG_N;
                    226:   if (value == 0) flags |= TME_M68K_FLAG_Z;
                    227:   ic->tme_m68k_ireg_ccr = flags;
                    228:   TME_M68K_INSN_OP1(tme_int8_t) = value | 0x80;
                    229:   TME_M68K_INSN_OK;
                    230: }
                    231: 
                    232: /* this cannot fault: */
                    233: TME_M68K_INSN(tme_m68k_move_usp)
                    234: {
                    235:   TME_M68K_INSN_PRIV;
                    236:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    237:     TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_usp;
                    238:   }
                    239:   else {
                    240:     ic->tme_m68k_ireg_usp = TME_M68K_INSN_OP1(tme_uint32_t);
                    241:   }
                    242:   TME_M68K_INSN_OK;
                    243: }
                    244: 
                    245: /* this cannot fault: */
                    246: TME_M68K_INSN(tme_m68k_trap)
                    247: {
                    248:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    249:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(32 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 4)));
                    250: }
                    251: 
                    252: /* this cannot fault: */
                    253: TME_M68K_INSN(tme_m68k_trapv)
                    254: {
                    255:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_V) {
                    256:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    257:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(7));
                    258:   }
                    259:   TME_M68K_INSN_OK;
                    260: }
                    261: 
                    262: /* this can fault: */
                    263: TME_M68K_INSN(tme_m68k_link)
                    264: {
                    265:   TME_M68K_INSN_CANFAULT;
                    266:   tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
                    267:   TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_a7;
                    268:   ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
                    269:   TME_M68K_INSN_OK;
                    270: }
                    271:   
                    272: /* this can fault: */
                    273: TME_M68K_INSN(tme_m68k_unlk)
                    274: {
                    275:   TME_M68K_INSN_CANFAULT;
                    276:   ic->tme_m68k_ireg_a7 = TME_M68K_INSN_OP0(tme_uint32_t);
                    277:   tme_m68k_pop32(ic, &TME_M68K_INSN_OP0(tme_uint32_t));
                    278:   TME_M68K_INSN_OK;
                    279: }
                    280:   
                    281: /* this cannot fault: */
                    282: TME_M68K_INSN(tme_m68k_movec)
                    283: {
                    284:   int ireg;
                    285:   tme_uint32_t *creg;
                    286:   TME_M68K_INSN_PRIV;
                    287:   /* in case we're reading the msp or isp and we're on that stack,
                    288:      this flushes %a7 to that register: */
                    289:   tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
                    290:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
                    291:   switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 12)) {
                    292:   case 0x000: creg = &ic->tme_m68k_ireg_sfc; break;
                    293:   case 0x001: creg = &ic->tme_m68k_ireg_dfc; break;
                    294:   case 0x800: creg = &ic->tme_m68k_ireg_usp; break;
                    295:   case 0x801: creg = &ic->tme_m68k_ireg_vbr; break;
                    296:   default: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL); creg = NULL;
                    297:   }
                    298:   if (TME_M68K_INSN_OPCODE & TME_BIT(0)) {
                    299:     *creg = ic->tme_m68k_ireg_uint32(ireg);
                    300:   }
                    301:   else {
                    302:     ic->tme_m68k_ireg_uint32(ireg) = *creg;
                    303:   }
                    304:   /* in case we're writing the msp or isp and we're on that stack,
                    305:      this flushes that register to %a7: */
                    306:   tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
                    307:   TME_M68K_INSN_OK;    
                    308: }
                    309: 
                    310: /* this cannot fault: */
                    311: TME_M68K_INSN(tme_m68k_reset)
                    312: {
                    313:   TME_M68K_INSN_PRIV;
                    314:   abort();
                    315: }
                    316: 
                    317: /* this can fault: */
                    318: TME_M68K_INSN(tme_m68k_rtd)
                    319: {
                    320:   TME_M68K_INSN_CANFAULT;
                    321:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    322:   /* while the above pop can fault, we don't have to worry about
                    323:      restarting here, because after this point, nothing can fault for
                    324:      the remainder of this instruction (the executor makes no stores
                    325:      on behalf of an rtd): */
                    326:   ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
                    327:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    328:   TME_M68K_INSN_OK;
                    329: }
                    330: 
                    331: /* this can fault: */
                    332: TME_M68K_INSN(tme_m68k_rtr)
                    333: {
                    334:   TME_M68K_INSN_CANFAULT;
                    335:   tme_m68k_pop16(ic, &ic->tme_m68k_ireg_memx16);
                    336:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    337:     ic->tme_m68k_ireg_ccr = ic->tme_m68k_ireg_memx8 & TME_M68K_FLAG_CCR;
                    338:   }
                    339:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    340:   /* while the above pop can fault, we don't have to worry about
                    341:      restarting here, because after this point, nothing can fault for
                    342:      the remainder of this instruction (the executor makes no stores
                    343:      on behalf of an rtr): */
                    344:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    345:   TME_M68K_INSN_OK;
                    346: }
                    347: 
                    348: /* this can fault: */
                    349: TME_M68K_INSN(tme_m68k_rts)
                    350: {
                    351:   TME_M68K_INSN_CANFAULT;
                    352:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    353:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    354:   TME_M68K_INSN_OK;
                    355: }
                    356: 
                    357: /* this can fault: */
                    358: TME_M68K_INSN(tme_m68k_jsr)
                    359: {
                    360:   TME_M68K_INSN_CANFAULT;
                    361:   tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
                    362:   TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
                    363:   TME_M68K_INSN_OK;
                    364: }
                    365: 
                    366: /* this cannot fault: */
                    367: TME_M68K_INSN(tme_m68k_jmp)
                    368: {
                    369:   TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
                    370:   TME_M68K_INSN_OK;
                    371: }
                    372: 
                    373: /* this cannot fault: */
                    374: TME_M68K_INSN(tme_m68k_rte)
                    375: {
                    376:   TME_M68K_INSN_PRIV;
                    377:   ic->_tme_m68k_mode = TME_M68K_MODE_RTE;
                    378:   TME_M68K_SEQUENCE_START;
                    379:   tme_m68k_redispatch(ic);
                    380: }
                    381: 
                    382: /* this cannot fault: */
                    383: TME_M68K_INSN(tme_m68k_stop)
                    384: {
                    385:   TME_M68K_INSN_PRIV;
                    386:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    387:   ic->tme_m68k_ireg_sr = TME_M68K_INSN_SPECOP;
                    388:   ic->_tme_m68k_mode = TME_M68K_MODE_STOP;
                    389:   TME_M68K_SEQUENCE_START;
                    390:   tme_m68k_redispatch(ic);
                    391: }
                    392: 
                    393: /* this cannot fault: */
                    394: TME_M68K_INSN(tme_m68k_priv)
                    395: {
                    396:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_PRIV);
                    397: }
                    398: 
                    399: /* this can fault: */
                    400: TME_M68K_INSN(tme_m68k_cmp2_chk2)
                    401: {
                    402:   tme_uint32_t ireg;
                    403:   unsigned int size_bytes, size_name, size_ireg;
                    404:   tme_uint32_t uvalue, ulower, uupper;
                    405:   tme_int32_t value, lower, upper;
                    406: 
                    407:   TME_M68K_INSN_CANFAULT;
                    408: 
                    409:   /* get the register to check and the operand size: */
                    410:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
                    411:   size_bytes = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 2);
                    412:   size_ireg = 2 - size_bytes;
                    413:   size_name = TME_M68K_SIZE_8 + size_bytes;
                    414:   size_bytes = 1 << size_bytes;
                    415: 
                    416:   /* read in the two bounds: */
                    417:   (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMX32 << size_ireg);
                    418:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    419:     ic->_tme_m68k_ea_address += size_bytes;
                    420:   }
                    421:   (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMY32 << size_ireg);
                    422: 
                    423:   /* if we have an address register, sign-extend the bounds to 32
                    424:      bits: */
                    425:   if (ireg >= TME_M68K_IREG_A0) {
                    426:     if (size_name == TME_M68K_SIZE_8) {
                    427:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8));
                    428:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8));
                    429:     }
                    430:     else if (size_name == TME_M68K_SIZE_16) {
                    431:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16));
                    432:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16));
                    433:     }
                    434:     size_bytes = sizeof(tme_uint32_t);
                    435:     size_name = TME_M68K_SIZE_32;
                    436:   }
                    437: 
                    438:   /* get the values to check: */
                    439:   switch (size_name) {
                    440:   case TME_M68K_SIZE_8:
                    441:     uvalue = ic->tme_m68k_ireg_uint8(ireg);
                    442:     ulower = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMX8);
                    443:     uupper = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMY8);
                    444:     value = ic->tme_m68k_ireg_int8(ireg);
                    445:     lower = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8);
                    446:     upper = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8);
                    447:     break;
                    448:   case TME_M68K_SIZE_16:
                    449:     uvalue = ic->tme_m68k_ireg_uint16(ireg);
                    450:     ulower = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMX16);
                    451:     uupper = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMY16);
                    452:     value = ic->tme_m68k_ireg_int16(ireg);
                    453:     lower = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16);
                    454:     upper = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16);
                    455:     break;
                    456:   case TME_M68K_SIZE_32:
                    457:     uvalue = ic->tme_m68k_ireg_uint32(ireg);
                    458:     ulower = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMX32);
                    459:     uupper = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMY32);
                    460:     value = ic->tme_m68k_ireg_int32(ireg);
                    461:     lower = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32);
                    462:     upper = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32);
                    463:     break;
                    464:   default: abort();
                    465:   }
                    466: 
                    467:   /* do the comparison.  if the value is out-of-bounds and this is
                    468:      a chk2 instruction, trap: */
                    469:   ic->tme_m68k_ireg_ccr = (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    470:   if (uvalue == ulower
                    471:       || uvalue == uupper) {
                    472:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    473:   }
                    474:   else if ((ulower > uupper)
                    475:           /* signed comparison: */
                    476:           ? (value < lower || value > upper)
                    477:           /* unsigned comparison: */
                    478:           : (uvalue < ulower || uvalue > uupper)) {
                    479:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_C;
                    480:     if (TME_M68K_INSN_OPCODE & TME_BIT(11)) {
                    481:       ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    482:       TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
                    483:     }
                    484:   }
                    485: 
                    486:   TME_M68K_INSN_OK;
                    487: }
                    488: 
                    489: TME_M68K_INSN(tme_m68k_callm)
                    490: {
                    491:   /* TBD */
                    492:   abort();
                    493: }
                    494: 
                    495: TME_M68K_INSN(tme_m68k_rtm)
                    496: {
                    497:   /* TBD */
                    498:   abort();
                    499: }
                    500: 
                    501: /* this cannot fault: */
                    502: TME_M68K_INSN(tme_m68k_trapcc)
                    503: {
                    504:   if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
                    505:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    506:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(7));
                    507:   }
                    508:   TME_M68K_INSN_OK;
                    509: }
                    510: 
                    511: /* the bitfield helper functions handle faults: */
                    512: TME_M68K_INSN(tme_m68k_bfchg)
                    513: {
                    514:   tme_uint32_t bf_value;
                    515:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    516:   tme_m68k_bitfield_write_unsigned(ic, ~bf_value, FALSE);
                    517:   TME_M68K_INSN_OK;
                    518: }
                    519: 
                    520: /* the bitfield helper functions handle faults: */
                    521: TME_M68K_INSN(tme_m68k_bfclr)
                    522: {
                    523:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    524:   tme_m68k_bitfield_write_unsigned(ic, 0, FALSE);
                    525:   TME_M68K_INSN_OK;
                    526: }
                    527: 
                    528: /* the bitfield helper functions handle faults: */
                    529: TME_M68K_INSN(tme_m68k_bfexts)
                    530: {
                    531:   tme_int32_t bf_value;
                    532:   bf_value = tme_m68k_bitfield_read_signed(ic);
                    533:   ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
                    534:     = bf_value;
                    535:   TME_M68K_INSN_OK;
                    536: }
                    537: 
                    538: /* the bitfield helper functions handle faults: */
                    539: TME_M68K_INSN(tme_m68k_bfextu)
                    540: {
                    541:   tme_uint32_t bf_value;
                    542:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    543:   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
                    544:     = bf_value;
                    545:   TME_M68K_INSN_OK;
                    546: }
                    547: 
                    548: /* the bitfield helper functions handle faults: */
                    549: TME_M68K_INSN(tme_m68k_bfffo)
                    550: {
                    551:   tme_int16_t specop;
                    552:   tme_int32_t bf_offset;
                    553:   unsigned int bf_width;
                    554:   tme_uint32_t bf_value;
                    555:     
                    556:   /* get the bitfield offset from a data register or as an immediate: */
                    557:   specop = TME_M68K_INSN_SPECOP;
                    558:   bf_offset = ((specop & TME_BIT(11))
                    559:               ? ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 6, 3))
                    560:               : (tme_int32_t) TME_FIELD_EXTRACTU(specop, 6, 5));
                    561: 
                    562:   /* get the bitfield width: */
                    563:   bf_width = tme_m68k_bitfield_width(ic);
                    564: 
                    565:   /* get the bitfield value: */
                    566:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    567: 
                    568:   /* set the result: */
                    569:   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 12, 3))
                    570:     = bf_offset + bf_width - ffs((int) bf_value);
                    571: 
                    572:   TME_M68K_INSN_OK;
                    573: }
                    574: 
                    575: /* the bitfield helper functions handle faults: */
                    576: TME_M68K_INSN(tme_m68k_bfins)
                    577: {
                    578:   tme_m68k_bitfield_write_unsigned(ic, 
                    579:                                   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                    580:                                                            + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3)),
                    581:                                   TRUE);
                    582:   TME_M68K_INSN_OK;
                    583: }
                    584: 
                    585: /* the bitfield helper functions handle faults: */
                    586: TME_M68K_INSN(tme_m68k_bfset)
                    587: {
                    588:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    589:   tme_m68k_bitfield_write_unsigned(ic, 0xffffffff, FALSE);
                    590:   TME_M68K_INSN_OK;
                    591: }
                    592: 
                    593: /* the bitfield helper functions handle faults: */
                    594: TME_M68K_INSN(tme_m68k_bftst)
                    595: {
                    596:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    597:   TME_M68K_INSN_OK;
                    598: }
                    599: 
                    600: /* this can fault: */
                    601: TME_M68K_INSN(tme_m68k_pack)
                    602: {
                    603:   int ireg_x, ireg_y;
                    604:   tme_uint16_t value;
                    605: 
                    606:   TME_M68K_INSN_CANFAULT;
                    607: 
                    608:   /* get the two registers: */
                    609:   ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    610:   ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    611: 
                    612:   /* if this is a memory pack: */
                    613:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    614:     ireg_x += TME_M68K_IREG_A0;
                    615:     ireg_y += TME_M68K_IREG_A0;
                    616: 
                    617:     /* do the predecrement read of two bytes: */
                    618:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    619:       ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint16_t);
                    620:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    621:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
                    622:     }
                    623:     tme_m68k_read_memx16(ic);
                    624: 
                    625:     /* get the two bytes and add the extension: */
                    626:     value = ic->tme_m68k_ireg_memx16 + TME_M68K_INSN_SPECOP;
                    627: 
                    628:     /* do the predecrement write of one byte: */
                    629:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    630:       ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint8_t);
                    631:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    632:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
                    633:       ic->tme_m68k_ireg_memx8 = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
                    634:     }
                    635:     tme_m68k_write_memx8(ic);
                    636:   }
                    637: 
                    638:   /* if this is a register pack: */
                    639:   else {
                    640:     ireg_x += TME_M68K_IREG_D0;
                    641:     ireg_y += TME_M68K_IREG_D0;
                    642:     value = ic->tme_m68k_ireg_uint16(ireg_x << 1) + TME_M68K_INSN_SPECOP;
                    643:     ic->tme_m68k_ireg_uint8(ireg_y << 2) = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
                    644:   }
                    645: 
                    646:   TME_M68K_INSN_OK;
                    647: }
                    648: 
                    649: /* this can fault: */
                    650: TME_M68K_INSN(tme_m68k_unpk)
                    651: {
                    652:   int ireg_x, ireg_y;
                    653:   tme_uint16_t value;
                    654: 
                    655:   TME_M68K_INSN_CANFAULT;
                    656: 
                    657:   /* get the two registers: */
                    658:   ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    659:   ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    660: 
                    661:   /* if this is a memory pack: */
                    662:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    663:     ireg_x += TME_M68K_IREG_A0;
                    664:     ireg_y += TME_M68K_IREG_A0;
                    665: 
                    666:     /* do the predecrement read of one byte: */
                    667:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    668:       ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint8_t);
                    669:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    670:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
                    671:     }
                    672:     tme_m68k_read_memx8(ic);
                    673: 
                    674:     /* unpack the byte and add the extension: */
                    675:     value = ic->tme_m68k_ireg_memx8;
                    676:     value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
                    677: 
                    678:     /* do the predecrement write of two bytes: */
                    679:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    680:       ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint16_t);
                    681:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    682:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
                    683:       ic->tme_m68k_ireg_memx16 = value;
                    684:     }
                    685:     tme_m68k_write_memx16(ic);
                    686:   }
                    687: 
                    688:   /* if this is a register pack: */
                    689:   else {
                    690:     ireg_x += TME_M68K_IREG_D0;
                    691:     ireg_y += TME_M68K_IREG_D0;
                    692:     value = ic->tme_m68k_ireg_uint8(ireg_x << 2);
                    693:     value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
                    694:     ic->tme_m68k_ireg_uint16(ireg_y << 1) = value;
                    695:   }
                    696: 
                    697:   TME_M68K_INSN_OK;
                    698: }
                    699: 
                    700: #include "m68k-bus-auto.c"
                    701: 
                    702: #include "m68k-insns-auto.c"

unix.superglobalmegacorp.com

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