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

1.1.1.3 ! root        1: /* $Id: m68k-insns.c,v 1.14 2005/03/23 11:53:02 fredette Exp $ */
1.1       root        2: 
1.1.1.2   root        3: /* ic/m68k/m68k-insns.c - m68k instruction functions: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2002, 2003 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
1.1       root       35: 
                     36: /* includes: */
                     37: #include "m68k-impl.h"
                     38: 
1.1.1.3 ! root       39: _TME_RCSID("$Id: m68k-insns.c,v 1.14 2005/03/23 11:53:02 fredette Exp $");
1.1       root       40: 
                     41: #define TME_M68K_STD_FLAGS \
                     42: do { \
                     43:   ic->tme_m68k_ireg_ccr = ((ic->tme_m68k_ireg_ccr \
                     44:                             & TME_M68K_FLAG_X) \
                     45:                            | (res < 0 ? TME_M68K_FLAG_N : 0) \
                     46:                            | (res == 0 ? TME_M68K_FLAG_Z : 0)); \
                     47: } while (/* CONSTCOND */ 0)
                     48: 
                     49: /* this cannot fault: */
                     50: TME_M68K_INSN(tme_m68k_exg)
                     51: {
                     52:   tme_uint32_t tmp;
                     53:   tmp = TME_M68K_INSN_OP0(tme_uint32_t);
                     54:   TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
                     55:   TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
                     56:   TME_M68K_INSN_OK;
                     57: }
                     58: 
                     59: /* this cannot fault: */
                     60: TME_M68K_INSN(tme_m68k_extw)
                     61: {
                     62:   tme_int16_t res;
                     63:   res = TME_EXT_S8_S16((tme_int8_t) TME_M68K_INSN_OP1(tme_int16_t));
                     64:   TME_M68K_INSN_OP1(tme_int16_t) = res;
                     65:   TME_M68K_STD_FLAGS;
                     66:   TME_M68K_INSN_OK;
                     67: }
                     68: 
                     69: /* this cannot fault: */
                     70: TME_M68K_INSN(tme_m68k_extl)
                     71: {
                     72:   tme_int32_t res;
                     73:   res = TME_EXT_S16_S32((tme_int16_t) TME_M68K_INSN_OP1(tme_int32_t));
                     74:   TME_M68K_INSN_OP1(tme_int32_t) = res;
                     75:   TME_M68K_STD_FLAGS;
                     76:   TME_M68K_INSN_OK;
                     77: }
                     78: 
                     79: /* this cannot fault: */
                     80: TME_M68K_INSN(tme_m68k_extbl)
                     81: {
                     82:   tme_int32_t res;
                     83:   res = TME_EXT_S8_S32((tme_int8_t) TME_M68K_INSN_OP1(tme_int32_t));
                     84:   TME_M68K_INSN_OP1(tme_int32_t) = res;
                     85:   TME_M68K_STD_FLAGS;
                     86:   TME_M68K_INSN_OK;
                     87: }
                     88: 
                     89: /* this cannot fault: */
                     90: TME_M68K_INSN(tme_m68k_lea)
                     91: {
                     92:   TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
                     93:   TME_M68K_INSN_OK;
                     94: }
                     95: 
                     96: /* this cannot fault: */
                     97: TME_M68K_INSN(tme_m68k_move_from_ccr)
                     98: {
                     99:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_ccr;
                    100:   TME_M68K_INSN_OK;
                    101: }
                    102: 
                    103: /* this cannot fault: */
                    104: TME_M68K_INSN(tme_m68k_move_from_sr)
                    105: {
                    106:   TME_M68K_INSN_PRIV;
                    107:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
                    108:   TME_M68K_INSN_OK;
                    109: }
                    110: 
                    111: /* this cannot fault: */
                    112: /* this is the 68000 version, which isn't privileged: */
                    113: TME_M68K_INSN(tme_m68k_move_from_sr0)
                    114: {
                    115:   TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
                    116:   TME_M68K_INSN_OK;
                    117: }
                    118: 
                    119: /* this cannot fault: */
                    120: TME_M68K_INSN(tme_m68k_swap)
                    121: {
                    122:   tme_uint32_t tmp;
                    123:   tme_int32_t res;
                    124:   tmp = TME_M68K_INSN_OP1(tme_uint32_t);
                    125:   tmp = (TME_FIELD_EXTRACTU(tmp, 0, 16) << 16) | TME_FIELD_EXTRACTU(tmp, 16, 16);
                    126:   TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
                    127:   res = (tme_int32_t) tmp;
                    128:   TME_M68K_STD_FLAGS;
                    129:   TME_M68K_INSN_OK;
                    130: }
                    131: 
                    132: /* this cannot fault: */
                    133: TME_M68K_INSN(tme_m68k_nop)
                    134: {
                    135:   TME_M68K_INSN_OK;
                    136: }
                    137: 
                    138: /* this cannot fault: */
                    139: TME_M68K_INSN(tme_m68k_scc)
                    140: {
                    141:   TME_M68K_INSN_OP1(tme_uint8_t) =
                    142:     (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))
                    143:      ? 0xff
                    144:      : 0x00);
                    145:   TME_M68K_INSN_OK;
                    146: }
                    147: 
                    148: /* this cannot fault: */
                    149: TME_M68K_INSN(tme_m68k_dbcc)
                    150: {
                    151:   if (!TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
                    152:     if (--TME_M68K_INSN_OP0(tme_int16_t) != -1) {
                    153:       TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc
                    154:                           + 2
                    155:                           + TME_EXT_S16_U32(TME_M68K_INSN_OP1(tme_int16_t)));
                    156:     }
                    157:   }
                    158:   TME_M68K_INSN_OK;
                    159: }
                    160: 
                    161: /* this cannot fault: */
1.1.1.3 ! root      162: static void
        !           163: _tme_m68k_bcc(struct tme_m68k *ic, tme_int32_t disp)
1.1       root      164: {
                    165:   if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
1.1.1.3 ! root      166:     TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + disp);
1.1       root      167:   }
                    168:   TME_M68K_INSN_OK;
                    169: }
1.1.1.3 ! root      170: TME_M68K_INSN(tme_m68k_bcc)
        !           171: {
        !           172:   _tme_m68k_bcc(ic, TME_EXT_S8_S32((tme_int8_t) TME_M68K_INSN_OPCODE));
        !           173: }
        !           174: TME_M68K_INSN(tme_m68k_bccl)
        !           175: {
        !           176:   _tme_m68k_bcc(ic, TME_M68K_INSN_OP0(tme_int32_t));
        !           177: }
1.1       root      178:     
                    179: /* this can fault: */
1.1.1.3 ! root      180: static void
        !           181: _tme_m68k_bsr(struct tme_m68k *ic, tme_int32_t disp)
1.1       root      182: {
                    183:   TME_M68K_INSN_CANFAULT;
                    184:   tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
                    185:   /* while the above push can fault, we don't have to worry about
                    186:      restarting here, because after this point, nothing can fault for
                    187:      the remainder of this instruction (the executor makes no stores
                    188:      on behalf of a bsr): */
1.1.1.3 ! root      189:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + disp);
1.1       root      190:   TME_M68K_INSN_OK;
                    191: }
1.1.1.3 ! root      192: TME_M68K_INSN(tme_m68k_bsr)
        !           193: {
        !           194:   _tme_m68k_bsr(ic, TME_EXT_S8_S32((tme_int8_t) TME_M68K_INSN_OPCODE));
        !           195: }
        !           196: TME_M68K_INSN(tme_m68k_bsrl)
        !           197: {
        !           198:   _tme_m68k_bsr(ic, TME_M68K_INSN_OP0(tme_int32_t));
        !           199: }
1.1       root      200: 
                    201: /* this can fault: */
                    202: TME_M68K_INSN(tme_m68k_pea)
                    203: {
                    204:   TME_M68K_INSN_CANFAULT;
                    205:   tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
                    206:   /* while the above push can fault, we don't have to worry about
                    207:      restarting here, because after this point, nothing can fault for
                    208:      the remainder of this instruction (the executor makes no stores
                    209:      on behalf of a pea): */
                    210:   TME_M68K_INSN_OK;
                    211: }
                    212: 
                    213: /* this cannot fault: */
                    214: TME_M68K_INSN(tme_m68k_bkpt)
                    215: {
1.1.1.3 ! root      216:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL);
1.1       root      217: }
                    218: 
                    219: /* this cannot fault: */
                    220: TME_M68K_INSN(tme_m68k_illegal)
                    221: {
1.1.1.3 ! root      222:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL);
1.1       root      223: }
                    224: 
                    225: /* this can fault: */
                    226: TME_M68K_INSN(tme_m68k_tas)
                    227: {
                    228:   struct tme_m68k_tlb *tlb;
                    229:   tme_uint8_t flags;
                    230:   tme_int8_t value;
                    231: 
                    232:   TME_M68K_INSN_CANFAULT;
                    233: 
                    234:   /* start the read/modify/write cycle: */
                    235:   tlb = tme_m68k_rmw_start(ic);
                    236:   if (tlb == NULL)
                    237:     TME_M68K_INSN_OK;
                    238: 
                    239:   /* the read part of the read/modify/write cycle: */
                    240:   tme_m68k_read8(ic, tlb,
                    241:                 &ic->_tme_m68k_ea_function_code,
                    242:                 &ic->_tme_m68k_ea_address,
                    243:                 &ic->tme_m68k_ireg_memx8,
                    244:                 TME_M68K_BUS_CYCLE_RMW);
                    245: 
                    246:   /* the modify part of the read/modify/write cycle: */
                    247:   value = ic->tme_m68k_ireg_memx8;
                    248:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    249:   if (value < 0) flags |= TME_M68K_FLAG_N;
                    250:   if (value == 0) flags |= TME_M68K_FLAG_Z;
                    251:   ic->tme_m68k_ireg_ccr = flags;
                    252:   ic->tme_m68k_ireg_memx8 |= 0x80;
                    253: 
                    254:   /* the write part of the read/modify/write cycle: */
                    255:   tme_m68k_write8(ic, tlb,
                    256:                  &ic->_tme_m68k_ea_function_code,
                    257:                  &ic->_tme_m68k_ea_address,
                    258:                  &ic->tme_m68k_ireg_memx8,
                    259:                  TME_M68K_BUS_CYCLE_RMW);
                    260: 
                    261:   /* finish the read/modify/write cycle: */
                    262:   tme_m68k_rmw_finish(ic, tlb);
                    263: 
                    264:   TME_M68K_INSN_OK;
                    265: }
                    266: 
                    267: /* this cannot fault: */
                    268: TME_M68K_INSN(tme_m68k_tas_r)
                    269: {
                    270:   tme_uint8_t flags;
                    271:   tme_int8_t value;
                    272:   value = TME_M68K_INSN_OP1(tme_int8_t);
                    273:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    274:   if (value < 0) flags |= TME_M68K_FLAG_N;
                    275:   if (value == 0) flags |= TME_M68K_FLAG_Z;
                    276:   ic->tme_m68k_ireg_ccr = flags;
                    277:   TME_M68K_INSN_OP1(tme_int8_t) = value | 0x80;
                    278:   TME_M68K_INSN_OK;
                    279: }
                    280: 
                    281: /* this cannot fault: */
                    282: TME_M68K_INSN(tme_m68k_move_usp)
                    283: {
                    284:   TME_M68K_INSN_PRIV;
                    285:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    286:     TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_usp;
                    287:   }
                    288:   else {
                    289:     ic->tme_m68k_ireg_usp = TME_M68K_INSN_OP1(tme_uint32_t);
                    290:   }
                    291:   TME_M68K_INSN_OK;
                    292: }
                    293: 
                    294: /* this cannot fault: */
                    295: TME_M68K_INSN(tme_m68k_trap)
                    296: {
                    297:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3 ! root      298:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_TRAP_0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 4)));
1.1       root      299: }
                    300: 
                    301: /* this cannot fault: */
                    302: TME_M68K_INSN(tme_m68k_trapv)
                    303: {
                    304:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_V) {
1.1.1.3 ! root      305:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root      306:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3 ! root      307:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_TRAP));
1.1       root      308:   }
                    309:   TME_M68K_INSN_OK;
                    310: }
                    311: 
                    312: /* this can fault: */
                    313: TME_M68K_INSN(tme_m68k_link)
                    314: {
                    315:   TME_M68K_INSN_CANFAULT;
                    316:   tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
                    317:   TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_a7;
                    318:   ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
                    319:   TME_M68K_INSN_OK;
                    320: }
                    321:   
                    322: /* this can fault: */
                    323: TME_M68K_INSN(tme_m68k_unlk)
                    324: {
                    325:   TME_M68K_INSN_CANFAULT;
                    326:   ic->tme_m68k_ireg_a7 = TME_M68K_INSN_OP0(tme_uint32_t);
                    327:   tme_m68k_pop32(ic, &TME_M68K_INSN_OP0(tme_uint32_t));
                    328:   TME_M68K_INSN_OK;
                    329: }
                    330:   
                    331: /* this cannot fault: */
                    332: TME_M68K_INSN(tme_m68k_movec)
                    333: {
                    334:   int ireg;
                    335:   tme_uint32_t *creg;
1.1.1.2   root      336:   tme_uint32_t mask;
1.1.1.3 ! root      337:   int illegal;
1.1       root      338:   TME_M68K_INSN_PRIV;
                    339:   /* in case we're reading the msp or isp and we're on that stack,
                    340:      this flushes %a7 to that register: */
                    341:   tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
                    342:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
1.1.1.2   root      343:   mask = 0xffffffff;
1.1.1.3 ! root      344:   illegal = FALSE;
1.1       root      345:   switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 12)) {
1.1.1.2   root      346:   case 0x000: creg = &ic->tme_m68k_ireg_sfc; mask = TME_M68K_FC_7; break;
                    347:   case 0x001: creg = &ic->tme_m68k_ireg_dfc; mask = TME_M68K_FC_7; break;
1.1.1.3 ! root      348:   case 0x002: creg = &ic->tme_m68k_ireg_cacr; mask = 0x3; illegal = (ic->tme_m68k_type < TME_M68K_M68020); break;
1.1       root      349:   case 0x800: creg = &ic->tme_m68k_ireg_usp; break;
                    350:   case 0x801: creg = &ic->tme_m68k_ireg_vbr; break;
1.1.1.3 ! root      351:   case 0x802: creg = &ic->tme_m68k_ireg_caar; illegal = (ic->tme_m68k_type != TME_M68K_M68020); break;
        !           352:   case 0x803: creg = &ic->tme_m68k_ireg_msp; illegal = (ic->tme_m68k_type < TME_M68K_M68020); break;
        !           353:   case 0x804: creg = &ic->tme_m68k_ireg_isp; illegal = (ic->tme_m68k_type < TME_M68K_M68020); break;
        !           354:   default: illegal = TRUE; creg = NULL;
        !           355:   }
        !           356:   if (illegal) {
        !           357:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL);
1.1       root      358:   }
                    359:   if (TME_M68K_INSN_OPCODE & TME_BIT(0)) {
1.1.1.2   root      360:     *creg = ic->tme_m68k_ireg_uint32(ireg) & mask;
1.1       root      361:   }
                    362:   else {
                    363:     ic->tme_m68k_ireg_uint32(ireg) = *creg;
                    364:   }
                    365:   /* in case we're writing the msp or isp and we're on that stack,
                    366:      this flushes that register to %a7: */
                    367:   tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
                    368:   TME_M68K_INSN_OK;    
                    369: }
                    370: 
                    371: /* this cannot fault: */
                    372: TME_M68K_INSN(tme_m68k_reset)
                    373: {
1.1.1.2   root      374:   struct tme_bus_connection *conn_bus;
                    375:   int rc;
                    376: 
1.1       root      377:   TME_M68K_INSN_PRIV;
1.1.1.2   root      378:   
                    379:   /* get the bus connection: */
                    380:   conn_bus = &ic->_tme_m68k_bus_connection->tme_m68k_bus_connection;
                    381: 
                    382:   /* assert the RESET line: */
                    383:   rc = (*conn_bus->tme_bus_signal)
                    384:     (conn_bus,
                    385:      (TME_BUS_SIGNAL_RESET
1.1.1.3 ! root      386:       | TME_BUS_SIGNAL_LEVEL_ASSERTED));
1.1.1.2   root      387:   assert (rc == TME_OK);
                    388: 
                    389:   /* XXX RESET is supposed to be asserted for 512 clocks, 
                    390:      so a sleep is needed here: */
                    391: 
                    392:   /* negate the RESET line: */
                    393:   rc = (*conn_bus->tme_bus_signal)
                    394:     (conn_bus,
                    395:      (TME_BUS_SIGNAL_RESET
1.1.1.3 ! root      396:       | TME_BUS_SIGNAL_LEVEL_NEGATED));
1.1.1.2   root      397:   assert (rc == TME_OK);
                    398:   
                    399:   TME_M68K_INSN_OK;
1.1       root      400: }
                    401: 
                    402: /* this can fault: */
                    403: TME_M68K_INSN(tme_m68k_rtd)
                    404: {
                    405:   TME_M68K_INSN_CANFAULT;
                    406:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    407:   /* while the above pop can fault, we don't have to worry about
                    408:      restarting here, because after this point, nothing can fault for
                    409:      the remainder of this instruction (the executor makes no stores
                    410:      on behalf of an rtd): */
                    411:   ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
                    412:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    413:   TME_M68K_INSN_OK;
                    414: }
                    415: 
                    416: /* this can fault: */
                    417: TME_M68K_INSN(tme_m68k_rtr)
                    418: {
                    419:   TME_M68K_INSN_CANFAULT;
                    420:   tme_m68k_pop16(ic, &ic->tme_m68k_ireg_memx16);
                    421:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    422:     ic->tme_m68k_ireg_ccr = ic->tme_m68k_ireg_memx8 & TME_M68K_FLAG_CCR;
                    423:   }
                    424:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    425:   /* while the above pop can fault, we don't have to worry about
                    426:      restarting here, because after this point, nothing can fault for
                    427:      the remainder of this instruction (the executor makes no stores
                    428:      on behalf of an rtr): */
                    429:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    430:   TME_M68K_INSN_OK;
                    431: }
                    432: 
                    433: /* this can fault: */
                    434: TME_M68K_INSN(tme_m68k_rts)
                    435: {
                    436:   TME_M68K_INSN_CANFAULT;
                    437:   tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
                    438:   TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
                    439:   TME_M68K_INSN_OK;
                    440: }
                    441: 
                    442: /* this can fault: */
                    443: TME_M68K_INSN(tme_m68k_jsr)
                    444: {
                    445:   TME_M68K_INSN_CANFAULT;
                    446:   tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
                    447:   TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
                    448:   TME_M68K_INSN_OK;
                    449: }
                    450: 
                    451: /* this cannot fault: */
                    452: TME_M68K_INSN(tme_m68k_jmp)
                    453: {
                    454:   TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
                    455:   TME_M68K_INSN_OK;
                    456: }
                    457: 
                    458: /* this cannot fault: */
                    459: TME_M68K_INSN(tme_m68k_rte)
                    460: {
                    461:   TME_M68K_INSN_PRIV;
                    462:   ic->_tme_m68k_mode = TME_M68K_MODE_RTE;
                    463:   TME_M68K_SEQUENCE_START;
                    464:   tme_m68k_redispatch(ic);
                    465: }
                    466: 
                    467: /* this cannot fault: */
                    468: TME_M68K_INSN(tme_m68k_stop)
                    469: {
                    470:   TME_M68K_INSN_PRIV;
                    471:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    472:   ic->tme_m68k_ireg_sr = TME_M68K_INSN_SPECOP;
                    473:   ic->_tme_m68k_mode = TME_M68K_MODE_STOP;
                    474:   TME_M68K_SEQUENCE_START;
                    475:   tme_m68k_redispatch(ic);
                    476: }
                    477: 
                    478: /* this cannot fault: */
                    479: TME_M68K_INSN(tme_m68k_priv)
                    480: {
1.1.1.3 ! root      481:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV);
1.1       root      482: }
                    483: 
                    484: /* this can fault: */
                    485: TME_M68K_INSN(tme_m68k_cmp2_chk2)
                    486: {
                    487:   tme_uint32_t ireg;
                    488:   unsigned int size_bytes, size_name, size_ireg;
                    489:   tme_uint32_t uvalue, ulower, uupper;
                    490:   tme_int32_t value, lower, upper;
                    491: 
                    492:   TME_M68K_INSN_CANFAULT;
                    493: 
                    494:   /* get the register to check and the operand size: */
                    495:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
                    496:   size_bytes = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 2);
                    497:   size_ireg = 2 - size_bytes;
                    498:   size_name = TME_M68K_SIZE_8 + size_bytes;
                    499:   size_bytes = 1 << size_bytes;
                    500: 
                    501:   /* read in the two bounds: */
                    502:   (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMX32 << size_ireg);
                    503:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    504:     ic->_tme_m68k_ea_address += size_bytes;
                    505:   }
                    506:   (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMY32 << size_ireg);
                    507: 
                    508:   /* if we have an address register, sign-extend the bounds to 32
                    509:      bits: */
                    510:   if (ireg >= TME_M68K_IREG_A0) {
                    511:     if (size_name == TME_M68K_SIZE_8) {
                    512:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8));
                    513:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8));
                    514:     }
                    515:     else if (size_name == TME_M68K_SIZE_16) {
                    516:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16));
                    517:       ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16));
                    518:     }
                    519:     size_bytes = sizeof(tme_uint32_t);
                    520:     size_name = TME_M68K_SIZE_32;
                    521:   }
                    522: 
                    523:   /* get the values to check: */
                    524:   switch (size_name) {
                    525:   case TME_M68K_SIZE_8:
                    526:     uvalue = ic->tme_m68k_ireg_uint8(ireg);
                    527:     ulower = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMX8);
                    528:     uupper = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMY8);
                    529:     value = ic->tme_m68k_ireg_int8(ireg);
                    530:     lower = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8);
                    531:     upper = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8);
                    532:     break;
                    533:   case TME_M68K_SIZE_16:
                    534:     uvalue = ic->tme_m68k_ireg_uint16(ireg);
                    535:     ulower = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMX16);
                    536:     uupper = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMY16);
                    537:     value = ic->tme_m68k_ireg_int16(ireg);
                    538:     lower = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16);
                    539:     upper = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16);
                    540:     break;
                    541:   case TME_M68K_SIZE_32:
                    542:     uvalue = ic->tme_m68k_ireg_uint32(ireg);
                    543:     ulower = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMX32);
                    544:     uupper = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMY32);
                    545:     value = ic->tme_m68k_ireg_int32(ireg);
                    546:     lower = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32);
                    547:     upper = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32);
                    548:     break;
                    549:   default: abort();
                    550:   }
                    551: 
                    552:   /* do the comparison.  if the value is out-of-bounds and this is
                    553:      a chk2 instruction, trap: */
                    554:   ic->tme_m68k_ireg_ccr = (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    555:   if (uvalue == ulower
                    556:       || uvalue == uupper) {
                    557:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    558:   }
                    559:   else if ((ulower > uupper)
                    560:           /* signed comparison: */
                    561:           ? (value < lower || value > upper)
                    562:           /* unsigned comparison: */
                    563:           : (uvalue < ulower || uvalue > uupper)) {
                    564:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_C;
                    565:     if (TME_M68K_INSN_OPCODE & TME_BIT(11)) {
1.1.1.3 ! root      566:       ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root      567:       ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3 ! root      568:       TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK));
1.1       root      569:     }
                    570:   }
                    571: 
                    572:   TME_M68K_INSN_OK;
                    573: }
                    574: 
                    575: TME_M68K_INSN(tme_m68k_callm)
                    576: {
                    577:   /* TBD */
                    578:   abort();
                    579: }
                    580: 
                    581: TME_M68K_INSN(tme_m68k_rtm)
                    582: {
                    583:   /* TBD */
                    584:   abort();
                    585: }
                    586: 
                    587: /* this cannot fault: */
                    588: TME_M68K_INSN(tme_m68k_trapcc)
                    589: {
                    590:   if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
1.1.1.3 ! root      591:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root      592:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3 ! root      593:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_TRAP));
1.1       root      594:   }
                    595:   TME_M68K_INSN_OK;
                    596: }
                    597: 
                    598: /* the bitfield helper functions handle faults: */
                    599: TME_M68K_INSN(tme_m68k_bfchg)
                    600: {
                    601:   tme_uint32_t bf_value;
                    602:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    603:   tme_m68k_bitfield_write_unsigned(ic, ~bf_value, FALSE);
                    604:   TME_M68K_INSN_OK;
                    605: }
                    606: 
                    607: /* the bitfield helper functions handle faults: */
                    608: TME_M68K_INSN(tme_m68k_bfclr)
                    609: {
                    610:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    611:   tme_m68k_bitfield_write_unsigned(ic, 0, FALSE);
                    612:   TME_M68K_INSN_OK;
                    613: }
                    614: 
                    615: /* the bitfield helper functions handle faults: */
                    616: TME_M68K_INSN(tme_m68k_bfexts)
                    617: {
                    618:   tme_int32_t bf_value;
                    619:   bf_value = tme_m68k_bitfield_read_signed(ic);
                    620:   ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
                    621:     = bf_value;
                    622:   TME_M68K_INSN_OK;
                    623: }
                    624: 
                    625: /* the bitfield helper functions handle faults: */
                    626: TME_M68K_INSN(tme_m68k_bfextu)
                    627: {
                    628:   tme_uint32_t bf_value;
                    629:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    630:   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
                    631:     = bf_value;
                    632:   TME_M68K_INSN_OK;
                    633: }
                    634: 
                    635: /* the bitfield helper functions handle faults: */
                    636: TME_M68K_INSN(tme_m68k_bfffo)
                    637: {
                    638:   tme_int16_t specop;
                    639:   tme_int32_t bf_offset;
                    640:   unsigned int bf_width;
                    641:   tme_uint32_t bf_value;
1.1.1.3 ! root      642:   unsigned int bf_pos;
1.1       root      643:     
                    644:   /* get the bitfield offset from a data register or as an immediate: */
                    645:   specop = TME_M68K_INSN_SPECOP;
                    646:   bf_offset = ((specop & TME_BIT(11))
                    647:               ? ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 6, 3))
                    648:               : (tme_int32_t) TME_FIELD_EXTRACTU(specop, 6, 5));
                    649: 
                    650:   /* get the bitfield width: */
                    651:   bf_width = tme_m68k_bitfield_width(ic);
                    652: 
                    653:   /* get the bitfield value: */
                    654:   bf_value = tme_m68k_bitfield_read_unsigned(ic);
                    655: 
1.1.1.3 ! root      656:   /* find the first set bit: */
        !           657:   for (bf_pos = 0, bf_value <<= (32 - bf_width);
        !           658:        bf_pos < bf_width && !(bf_value & 0x80000000);
        !           659:        bf_pos++, bf_value <<= 1);
        !           660: 
1.1       root      661:   /* set the result: */
                    662:   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 12, 3))
1.1.1.3 ! root      663:     = bf_offset + bf_pos;
1.1       root      664: 
                    665:   TME_M68K_INSN_OK;
                    666: }
                    667: 
                    668: /* the bitfield helper functions handle faults: */
                    669: TME_M68K_INSN(tme_m68k_bfins)
                    670: {
                    671:   tme_m68k_bitfield_write_unsigned(ic, 
                    672:                                   ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                    673:                                                            + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3)),
                    674:                                   TRUE);
                    675:   TME_M68K_INSN_OK;
                    676: }
                    677: 
                    678: /* the bitfield helper functions handle faults: */
                    679: TME_M68K_INSN(tme_m68k_bfset)
                    680: {
                    681:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    682:   tme_m68k_bitfield_write_unsigned(ic, 0xffffffff, FALSE);
                    683:   TME_M68K_INSN_OK;
                    684: }
                    685: 
                    686: /* the bitfield helper functions handle faults: */
                    687: TME_M68K_INSN(tme_m68k_bftst)
                    688: {
                    689:   (void) tme_m68k_bitfield_read_unsigned(ic);
                    690:   TME_M68K_INSN_OK;
                    691: }
                    692: 
                    693: /* this can fault: */
                    694: TME_M68K_INSN(tme_m68k_pack)
                    695: {
                    696:   int ireg_x, ireg_y;
                    697:   tme_uint16_t value;
                    698: 
                    699:   TME_M68K_INSN_CANFAULT;
                    700: 
                    701:   /* get the two registers: */
                    702:   ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    703:   ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    704: 
                    705:   /* if this is a memory pack: */
                    706:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    707:     ireg_x += TME_M68K_IREG_A0;
                    708:     ireg_y += TME_M68K_IREG_A0;
                    709: 
                    710:     /* do the predecrement read of two bytes: */
                    711:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    712:       ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint16_t);
                    713:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    714:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
                    715:     }
                    716:     tme_m68k_read_memx16(ic);
                    717: 
                    718:     /* get the two bytes and add the extension: */
                    719:     value = ic->tme_m68k_ireg_memx16 + TME_M68K_INSN_SPECOP;
                    720: 
                    721:     /* do the predecrement write of one byte: */
                    722:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    723:       ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint8_t);
                    724:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    725:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
                    726:       ic->tme_m68k_ireg_memx8 = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
                    727:     }
                    728:     tme_m68k_write_memx8(ic);
                    729:   }
                    730: 
                    731:   /* if this is a register pack: */
                    732:   else {
                    733:     ireg_x += TME_M68K_IREG_D0;
                    734:     ireg_y += TME_M68K_IREG_D0;
                    735:     value = ic->tme_m68k_ireg_uint16(ireg_x << 1) + TME_M68K_INSN_SPECOP;
                    736:     ic->tme_m68k_ireg_uint8(ireg_y << 2) = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
                    737:   }
                    738: 
                    739:   TME_M68K_INSN_OK;
                    740: }
                    741: 
                    742: /* this can fault: */
                    743: TME_M68K_INSN(tme_m68k_unpk)
                    744: {
                    745:   int ireg_x, ireg_y;
                    746:   tme_uint16_t value;
                    747: 
                    748:   TME_M68K_INSN_CANFAULT;
                    749: 
                    750:   /* get the two registers: */
                    751:   ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    752:   ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    753: 
                    754:   /* if this is a memory pack: */
                    755:   if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
                    756:     ireg_x += TME_M68K_IREG_A0;
                    757:     ireg_y += TME_M68K_IREG_A0;
                    758: 
                    759:     /* do the predecrement read of one byte: */
                    760:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    761:       ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint8_t);
                    762:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    763:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
                    764:     }
                    765:     tme_m68k_read_memx8(ic);
                    766: 
                    767:     /* unpack the byte and add the extension: */
                    768:     value = ic->tme_m68k_ireg_memx8;
                    769:     value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
                    770: 
                    771:     /* do the predecrement write of two bytes: */
                    772:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    773:       ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint16_t);
                    774:       ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    775:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
                    776:       ic->tme_m68k_ireg_memx16 = value;
                    777:     }
                    778:     tme_m68k_write_memx16(ic);
                    779:   }
                    780: 
                    781:   /* if this is a register pack: */
                    782:   else {
                    783:     ireg_x += TME_M68K_IREG_D0;
                    784:     ireg_y += TME_M68K_IREG_D0;
                    785:     value = ic->tme_m68k_ireg_uint8(ireg_x << 2);
                    786:     value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
                    787:     ic->tme_m68k_ireg_uint16(ireg_y << 1) = value;
                    788:   }
                    789: 
                    790:   TME_M68K_INSN_OK;
                    791: }
                    792: 
1.1.1.3 ! root      793: /* these just redispatch into one of the multiply or divide insns: */
        !           794: TME_M68K_INSN(tme_m68k_mull)
        !           795: {
        !           796:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
        !           797:     tme_m68k_mulsl(ic, _op0, _op1);
        !           798:   }
        !           799:   else {
        !           800:     tme_m68k_mulul(ic, _op0, _op1);
        !           801:   }
        !           802: }
        !           803: TME_M68K_INSN(tme_m68k_divl)
        !           804: {
        !           805:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
        !           806:     tme_m68k_divsl(ic, _op0, _op1);
        !           807:   }
        !           808:   else {
        !           809:     tme_m68k_divul(ic, _op0, _op1);
        !           810:   }
        !           811: }
        !           812: 
1.1       root      813: #include "m68k-bus-auto.c"
                    814: 
                    815: #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.