Annotation of tme/ic/m68k/m68k-insns.c, revision 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.