📄 interp.c
字号:
tmp <<= 24; tmp >>= 24; cpu.gr[RD] = tmp; } break; case 0x6: /* zexth */ cpu.gr[RD] &= 0x0000FFFF; break; case 0x7: /* sexth */ { long tmp; tmp = cpu.gr[RD]; tmp <<= 16; tmp >>= 16; cpu.gr[RD] = tmp; } break; case 0x8: /* declt */ --cpu.gr[RD]; NEW_C ((long)cpu.gr[RD] < 0); break; case 0x9: /* tstnbz */ { word tmp = cpu.gr[RD]; NEW_C ((tmp & 0xFF000000) != 0 && (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 && (tmp & 0x000000FF) != 0); } break; case 0xA: /* decgt */ --cpu.gr[RD]; NEW_C ((long)cpu.gr[RD] > 0); break; case 0xB: /* decne */ --cpu.gr[RD]; NEW_C ((long)cpu.gr[RD] != 0); break; case 0xC: /* clrt */ if (C_ON()) cpu.gr[RD] = 0; break; case 0xD: /* clrf */ if (C_OFF()) cpu.gr[RD] = 0; break; case 0xE: /* abs */ if (cpu.gr[RD] & 0x80000000) cpu.gr[RD] = ~cpu.gr[RD] + 1; break; case 0xF: /* not */ cpu.gr[RD] = ~cpu.gr[RD]; break; } break; case 0x02: /* movt */ if (C_ON()) cpu.gr[RD] = cpu.gr[RS]; break; case 0x03: /* mult */ /* consume 2 bits per cycle from rs, until rs is 0 */ { unsigned int t = cpu.gr[RS]; int ticks; for (ticks = 0; t != 0 ; t >>= 2) ticks++; bonus_cycles += ticks; } bonus_cycles += 2; /* min. is 3, so add 2, plus ticks above */ if (tracing) fprintf (stderr, " mult %x by %x to give %x", cpu.gr[RD], cpu.gr[RS], cpu.gr[RD] * cpu.gr[RS]); cpu.gr[RD] = cpu.gr[RD] * cpu.gr[RS]; break; case 0x04: /* loopt */ if (C_ON()) { pc += (IMM4 << 1) - 32; bonus_cycles ++; needfetch = 1; } --cpu.gr[RS]; /* not RD! */ NEW_C (((long)cpu.gr[RS]) > 0); break; case 0x05: /* subu */ cpu.gr[RD] -= cpu.gr[RS]; break; case 0x06: /* addc */ { unsigned long tmp, a, b; a = cpu.gr[RD]; b = cpu.gr[RS]; cpu.gr[RD] = a + b + C_VALUE (); tmp = iu_carry (a, b, C_VALUE ()); NEW_C (tmp); } break; case 0x07: /* subc */ { unsigned long tmp, a, b; a = cpu.gr[RD]; b = cpu.gr[RS]; cpu.gr[RD] = a - b + C_VALUE () - 1; tmp = iu_carry (a,~b, C_VALUE ()); NEW_C (tmp); } break; case 0x08: /* illegal */ case 0x09: /* illegal*/ cpu.asregs.exception = SIGILL; break; case 0x0A: /* movf */ if (C_OFF()) cpu.gr[RD] = cpu.gr[RS]; break; case 0x0B: /* lsr */ { unsigned long dst, src; dst = cpu.gr[RD]; src = cpu.gr[RS]; /* We must not rely solely upon the native shift operations, since they may not match the M*Core's behaviour on boundary conditions. */ dst = src > 31 ? 0 : dst >> src; cpu.gr[RD] = dst; } break; case 0x0C: /* cmphs */ NEW_C ((unsigned long )cpu.gr[RD] >= (unsigned long)cpu.gr[RS]); break; case 0x0D: /* cmplt */ NEW_C ((long)cpu.gr[RD] < (long)cpu.gr[RS]); break; case 0x0E: /* tst */ NEW_C ((cpu.gr[RD] & cpu.gr[RS]) != 0); break; case 0x0F: /* cmpne */ NEW_C (cpu.gr[RD] != cpu.gr[RS]); break; case 0x10: case 0x11: /* mfcr */ { unsigned r; r = IMM5; if (r <= LAST_VALID_CREG) cpu.gr[RD] = cpu.cr[r]; else cpu.asregs.exception = SIGILL; } break; case 0x12: /* mov */ cpu.gr[RD] = cpu.gr[RS]; if (tracing) fprintf (stderr, "MOV %x into reg %d", cpu.gr[RD], RD); break; case 0x13: /* bgenr */ if (cpu.gr[RS] & 0x20) cpu.gr[RD] = 0; else cpu.gr[RD] = 1 << (cpu.gr[RS] & 0x1F); break; case 0x14: /* rsub */ cpu.gr[RD] = cpu.gr[RS] - cpu.gr[RD]; break; case 0x15: /* ixw */ cpu.gr[RD] += cpu.gr[RS]<<2; break; case 0x16: /* and */ cpu.gr[RD] &= cpu.gr[RS]; break; case 0x17: /* xor */ cpu.gr[RD] ^= cpu.gr[RS]; break; case 0x18: case 0x19: /* mtcr */ { unsigned r; r = IMM5; if (r <= LAST_VALID_CREG) cpu.cr[r] = cpu.gr[RD]; else cpu.asregs.exception = SIGILL; /* we might have changed register sets... */ if (SR_AF ()) cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0]; else cpu.asregs.active_gregs = & cpu.asregs.gregs[0]; } break; case 0x1A: /* asr */ /* We must not rely solely upon the native shift operations, since they may not match the M*Core's behaviour on boundary conditions. */ if (cpu.gr[RS] > 30) cpu.gr[RD] = ((long) cpu.gr[RD]) < 0 ? -1 : 0; else cpu.gr[RD] = (long) cpu.gr[RD] >> cpu.gr[RS]; break; case 0x1B: /* lsl */ /* We must not rely solely upon the native shift operations, since they may not match the M*Core's behaviour on boundary conditions. */ cpu.gr[RD] = cpu.gr[RS] > 31 ? 0 : cpu.gr[RD] << cpu.gr[RS]; break; case 0x1C: /* addu */ cpu.gr[RD] += cpu.gr[RS]; break; case 0x1D: /* ixh */ cpu.gr[RD] += cpu.gr[RS] << 1; break; case 0x1E: /* or */ cpu.gr[RD] |= cpu.gr[RS]; break; case 0x1F: /* andn */ cpu.gr[RD] &= ~cpu.gr[RS]; break; case 0x20: case 0x21: /* addi */ cpu.gr[RD] = cpu.gr[RD] + (IMM5 + 1); break; case 0x22: case 0x23: /* cmplti */ { int tmp = (IMM5 + 1); if (cpu.gr[RD] < tmp) { SET_C(); } else { CLR_C(); } } break; case 0x24: case 0x25: /* subi */ cpu.gr[RD] = cpu.gr[RD] - (IMM5 + 1); break; case 0x26: case 0x27: /* illegal */ cpu.asregs.exception = SIGILL; break; case 0x28: case 0x29: /* rsubi */ cpu.gr[RD] = IMM5 - cpu.gr[RD]; break; case 0x2A: case 0x2B: /* cmpnei */ if (cpu.gr[RD] != IMM5) { SET_C(); } else { CLR_C(); } break; case 0x2C: case 0x2D: /* bmaski, divu */ { unsigned imm = IMM5; if (imm == 1) { int exe; int rxnlz, r1nlz; unsigned int rx, r1; rx = cpu.gr[RD]; r1 = cpu.gr[1]; exe = 0; /* unsigned divide */ cpu.gr[RD] = (word) ((unsigned int) cpu.gr[RD] / (unsigned int)cpu.gr[1] ); /* compute bonus_cycles for divu */ for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++) r1 = r1 << 1; for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32); rxnlz ++) rx = rx << 1; if (r1nlz < rxnlz) exe += 4; else exe += 5 + r1nlz - rxnlz; if (exe >= (2 * memcycles - 1)) { bonus_cycles += exe - (2 * memcycles) + 1; } } else if (imm == 0 || imm >= 8) { /* bmaski */ if (imm == 0) cpu.gr[RD] = -1; else cpu.gr[RD] = (1 << imm) - 1; } else { /* illegal */ cpu.asregs.exception = SIGILL; } } break; case 0x2E: case 0x2F: /* andi */ cpu.gr[RD] = cpu.gr[RD] & IMM5; break; case 0x30: case 0x31: /* bclri */ cpu.gr[RD] = cpu.gr[RD] & ~(1<<IMM5); break; case 0x32: case 0x33: /* bgeni, divs */ { unsigned imm = IMM5; if (imm == 1) { int exe,sc; int rxnlz, r1nlz; signed int rx, r1; /* compute bonus_cycles for divu */ rx = cpu.gr[RD]; r1 = cpu.gr[1]; exe = 0; if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0))) sc = 1; else sc = 0; rx = abs (rx); r1 = abs (r1); /* signed divide, general registers are of type int, so / op is OK */ cpu.gr[RD] = cpu.gr[RD] / cpu.gr[1]; for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ ) r1 = r1 << 1; for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ ) rx = rx << 1; if (r1nlz < rxnlz) exe += 5; else exe += 6 + r1nlz - rxnlz + sc; if (exe >= (2 * memcycles - 1)) { bonus_cycles += exe - (2 * memcycles) + 1; } } else if (imm >= 7) { /* bgeni */ cpu.gr[RD] = (1 << IMM5); } else { /* illegal */ cpu.asregs.exception = SIGILL; } break; } case 0x34: case 0x35: /* bseti */ cpu.gr[RD] = cpu.gr[RD] | (1 << IMM5); break; case 0x36: case 0x37: /* btsti */ NEW_C (cpu.gr[RD] >> IMM5); break; case 0x38: case 0x39: /* xsr, rotli */ { unsigned imm = IMM5; unsigned long tmp = cpu.gr[RD]; if (imm == 0) { word cbit; cbit = C_VALUE(); NEW_C (tmp); cpu.gr[RD] = (cbit << 31) | (tmp >> 1); } else cpu.gr[RD] = (tmp << imm) | (tmp >> (32 - imm)); } break; case 0x3A: case 0x3B: /* asrc, asri */ { unsigned imm = IMM5; long tmp = cpu.gr[RD]; if (imm == 0) { NEW_C (tmp); cpu.gr[RD] = tmp >> 1; } else cpu.gr[RD] = tmp >> imm; } break; case 0x3C: case 0x3D: /* lslc, lsli */ { unsigned imm = IMM5; unsigned long tmp = cpu.gr[RD]; if (imm == 0) { NEW_C (tmp >> 31); cpu.gr[RD] = tmp << 1; } else cpu.gr[RD] = tmp << imm; } break; case 0x3E: case 0x3F: /* lsrc, lsri */ { unsigned imm = IMM5; unsigned long tmp = cpu.gr[RD]; if (imm == 0) { NEW_C (tmp); cpu.gr[RD] = tmp >> 1; } else cpu.gr[RD] = tmp >> imm; } break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F: cpu.asregs.exception = SIGILL; break; case 0x50: util (inst & 0xFF); break; case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: cpu.asregs.exception = SIGILL; break; case 0x60: case 0x61: case 0x62: case 0x63: /* movi */ case 0x64: case 0x65: case 0x66: case 0x67: cpu.gr[RD] = (inst >> 4) & 0x7F; break; case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F: /* illegal */ cpu.asregs.exception = SIGILL; break; case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: /* lrw */ cpu.gr[RX] = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC); if (tracing) fprintf (stderr, "LRW of 0x%x from 0x%x to reg %d", rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC), (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX); memops++; break; case 0x7F: /* jsri */ cpu.gr[15] = pc; if (tracing) fprintf (stderr, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n", cpu.gr[2], cpu.gr[3], cpu.gr[4], cpu.gr[5], cpu.gr[6], cpu.gr[7]); case 0x70: /* jmpi */ pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC); memops++; bonus_cycles++; needfetch = 1; break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* ld */ cpu.gr[RX] = rlat (cpu.gr[RD] + ((inst >> 2) & 0x003C)); if (tracing) fprintf (stderr, "load reg %d from 0x%x with 0x%x", RX, cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]); memops++; break; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F: /* st */ wlat (cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]); if (tracing) fprintf (stderr, "store reg %d (containing 0x%x) to 0x%x", RX, cpu.gr[RX], cpu.gr[RD] + ((inst >> 2) & 0x003C)); memops++; break; case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7: case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* ld.b */ cpu.gr[RX] = rbat (cpu.gr[RD] + RS); memops++; break; case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* st.b */ wbat (cpu.gr[RD] + RS, cpu.gr[RX]); memops++; break; case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* ld.h */ cpu.gr[RX] = rhat (cpu.gr[RD] + ((inst >> 3) & 0x001E)); memops++; break; case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* st.h */ what (cpu.gr[RD] + ((inst >> 3) & 0x001E), cpu.gr[RX]); memops++; break; case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF: /* bf */ if (C_OFF()) { int disp; disp = inst & 0x03FF; if (inst & 0x0400) disp |= 0xFFFFFC00; pc += disp<<1; bonus_cycles++; needfetch = 1; } break; case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: /* bt */ if (C_ON()) { int disp; disp = inst & 0x03FF; if (inst & 0x0400) disp |= 0xFFFFFC00; pc += disp<<1; bonus_cycles++; needfetch = 1; } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -