📄 utils.c
字号:
lastbit = 63; zero = zeromantissa(longwords, firstbit, lastbit); maxexp = 0x400; minexp = -0x3ff; break; case EXTENDED: /* * Format: * * 1 bit sign * 15 bits exponent (biased by 0x3fff) * 16 bits unused * 1 bit explicit leading bit * left of binary point * <binary point> * 63 bits mantissa (implicit leading bit * left of implied binary point) */ exponent = ((longwords[0] >> (32 - (15+1))) & 0x7fff) - 0x3fff; firstbit = 95 - 62; lastbit = 95; zero = zeromantissa(longwords, firstbit, lastbit); maxexp = 0x4000; minexp = -0x3fff; break; case PACKED: /* * Format: * * 1 bit sign * 1 bit sign of exponent * 2 bits sign of exponent * 12 bits 3-digit exponent * 12 bits unused * 4 bits explicit leading digit left of decimal point * <decimal point> * 64 bits 16-digit (17 with leading digit) mantissa */ zero = 1; firstnonzero = -1; for (i = 0; i < 17; i++) { mantissa[i] = longwords[(i + 7) / 8] >> (((24 - i) % 8) * 4) & 0xf; if (mantissa[i]) { zero = 0; lastnonzero = i; if (firstnonzero == -1) firstnonzero = i; } if (mantissa[i] > 9) rval = -1; } exponent = ((longwords[0] >> 80 % 32) & 0xf) + ((longwords[0] >> 84 % 32) & 0xf) * 10 + ((longwords[0] >> 88 % 32) & 0xf) * 100; if (((longwords[0] >> 80 % 32) & 0xf) > 9 || ((longwords[0] >> 84 % 32) & 0xf) > 9 || ((longwords[0] >> 88 % 32) & 0xf) > 9) rval = -1; if (longwords[0] & 0x40000000) exponent = -exponent; exponent -= firstnonzero; break; } if (type != PACKED && exponent == maxexp || type == PACKED && (longwords[0] & 0x7fff0000) == 0x7fff0000) { if (zero) { /* Infinity */ if (sign) *s++ = '-'; strcpy(s, "INF"); } else { /* NaN */ strcpy(s, "NaN"); } } else if (type != PACKED && exponent == minexp || type == PACKED && zero) { if (zero) { /* Zero */ strcpy(s, "#0"); } else { /* Denormalized */ strcpy(s, "Denormalized"); rval = -1; } } else if (type != PACKED) { /* Normalized */ double dmantissa; dmantissa = stod(longwords, firstbit, lastbit); if (type == EXTENDED && BIT(longwords, firstbit - 1) == 0) { /* Unnormalized */ dmantissa -= 1.0; while (dmantissa < 1.0) { dmantissa *= 2.0; exponent--; } } *s++ = '#'; if (sign) *s++ = '-'; /* * We need to determine if dmantissa * 2^exponent * is within range or not. */ if (exponent < DBL_MAX_EXP && exponent > DBL_MIN_EXP || exponent == DBL_MAX_EXP && dmantissa <= DBL_MAX / pow(2.0, DBL_MAX_EXP) || exponent == DBL_MIN_EXP && dmantissa <= DBL_MIN / pow(2.0, DBL_MIN_EXP) ) { if (exponent) dmantissa *= pow(2.0, exponent); sprintf(s, "%.*g", fdigits, dmantissa); } else { double exp10; double log10value; log10value = log10(dmantissa) + 0.30102999566398119521 * log10(exponent); exp10 = floor(log10value); dmantissa = pow(10.0, log10value - exp10); s += sprintf(s, "%.*g", fdigits, dmantissa); if (exp10) sprintf(s, "e%d", dmantissa, (int)exp10); } } else /* type == PACKED */ { *s++ = '#'; if (sign) *s++ = '-'; s += sprintf(s, "%x", mantissa[firstnonzero]); if (lastnonzero != firstnonzero) *s++ = '.'; for (i = firstnonzero + 1; i <= lastnonzero; i++) s += sprintf(s, "%x", mantissa[i]); if (exponent) sprintf(s, "e%d", exponent); } return rval;}/* * Read input bytes for floating-point constant * of floating-point type ``type''. Put formatted value in ``s''. */static intmemfpoint(char *s, int type){ u32bit_t longwords[3]; size_t nlongwords; int failure; size_t i; switch (type) { case SINGLE: nlongwords = 1; break; case DOUBLE: nlongwords = 2; break; case EXTENDED: case PACKED: nlongwords = 3; break; } for (i = 0; i < nlongwords; i++) { longwords[i] = getval(LONGWORD, &failure); if (failure) return failure; } return fpoint(longwords, type, s);}/* * Find effective address given mode/register combination and instruction size. * Result goes in ``s''. Return 0 for success, else negative. */intgetea(char *s, int reg, int mode, int size){ long longval; m68kaddr savedpc; char creg[3]; int failure; switch (mode) { case 0: /* Data register direct */ sprintf(s, "D%d", reg); break; case 1: /* Address register direct */ sprintf(s, "%2.2s", Areg(reg)); break; case 2: /* Address register indirect */ sprintf(s, "(%2.2s)", Areg(reg)); break; case 3: /* Address register indirect with postincrement */ sprintf(s, "(%2.2s)+", Areg(reg)); break; case 4: /* Address register indirect with predecrement */ sprintf(s, "-(%2.2s)", Areg(reg)); break; case 5: /* Address register indirect with displacement */ longval = getval(WORD, &failure); if (failure) return failure; if (CPU(chip) >= MC68020) sprintf(s, "(%ld,%2.2s)", longval, Areg(reg)); else sprintf(s, "%ld(%2.2s)", longval, Areg(reg)); break; case 6: /* * Address register indirect * with index and displacement */ sprintf(creg, "%2.2s", Areg(reg)); return extended(s, creg, size); break; case 7: switch (reg) { case 0: /* Absolute short */ longval = getval(WORD, &failure); if (failure) return failure; sprintf(s, "$%0*lx.W", 2 * WORDSIZE, longval); break; case 1: /* Absolute long */ longval = getval(LONGWORD, &failure); if (failure) return failure; sprintf(s, "$%0*lx.L", 4 * WORDSIZE, longval); break; case 2: /* Program counter indirect with displacement */ savedpc = pc; longval = getval(WORD, &failure); if (failure) return failure; if (pass == DCLABELSPASS) { if (longval + savedpc >= initialpc && longval + savedpc <= initialpc + maxoffset) { insts[longval + savedpc - initialpc].flags |= ISLABEL; if (!insts[longval + savedpc - initialpc].size && insts[ppc - initialpc].flags & ISFPU) insts[longval + savedpc - initialpc].flags |= ftype2lis(size); } } else if (pass == FIRSTPASS && pcrelative) { required[flags & 3] = longval + savedpc; flags++; } else if (pass == LASTPASS && longval + savedpc >= initialpc && longval + savedpc <= initialpc + maxoffset && insts[longval + savedpc - initialpc].labelnum) sprintf(s, "L%d", insts[longval + savedpc - initialpc].labelnum); else /* if ((pass == FIRSTPASS || pass == LASTPASS) && !pcrelative || pass == DEBUGPASS || pass == LASTPASS && pcrelative && longval + savedpc > initialpc + maxoffset) */ { if (longval == 0) sprintf(s, "(PC)!$%lx", savedpc); else if (CPU(chip) >= MC68020) sprintf(s, "(%ld,PC)!$%lx", longval, longval + savedpc); else sprintf(s, "%ld(PC)!$%lx", longval, longval + savedpc); } break; case 3: /* * Program counter indirect * with index and displacement */ return extended(s, "PC", size); break; case 4: /* Immediate */ switch (size) { case BYTE: /* FALLTHROUGH */ case WORD: /* FALLTHROUGH */ case LONGWORD: /* FALLTHROUGH */ case DOUBLELONGWORD: s[0] = '#'; longval = getval(size == DOUBLELONGWORD ? LONGWORD : size, &failure); if (failure) return failure; s += immsprintf(s + 1, longval) + 1; if (size == DOUBLELONGWORD) { s[0] = '/'; longval = getval(LONGWORD, &failure); if (failure) return failure; immsprintf(s + 1, longval); } break; case SINGLE: /* FALLTHROUGH */ case DOUBLE: /* FALLTHROUGH */ case EXTENDED: /* FALLTHROUGH */ case PACKED: (void)memfpoint(s, size); } break; default: return -1; } } return 0;}/* * If printing is appropriate, print an output line. * The instruction name is given in ``name'' and ``lflags'' tells about * the instruction operands (the ellipsis arguments). */voidinstprint(int lflags, const char *name, ...){ va_list ap; int operands = f2ops(lflags); char *cp; size_t i; int tabs; va_start(ap, name); if (pass == LASTPASS || pass == DEBUGPASS) { fprintf(outfp, "%08x", (int)ppc); if (lower) for (i = 0; i < leninstbuf; i++) instbuf[i] = tolower(instbuf[i]); fprintf(outfp, " %.*s", (int)leninstbuf, instbuf);#define TABSIZE 8 if (leninstbuf > 36 - TABSIZE) tabs = 1; else tabs = (36 - leninstbuf) / TABSIZE; while (tabs--) (void)putc('\t', outfp);#undef TABSIZE if (pass == LASTPASS && insts[ppc - initialpc].labelnum) fprintf(outfp, "L%d", insts[ppc - initialpc].labelnum); (void)putc('\t', outfp); if (lower) { char *newname; size_t len = strlen(name); if (newname = malloc(len + 1)) { for (i = 0; i < len; i++) newname[i] = tolower(name[i]); newname[len] = '\0'; fprintf(outfp, "%s", newname); free(newname); } else fprintf(outfp, "%s", name); } else fprintf(outfp, "%s", name); if (lower) { if (lflags & PBYTE) fprintf(outfp, ".b"); else if (lflags & PWORD) fprintf(outfp, ".w"); else if (lflags & PLONGWORD) fprintf(outfp, ".l"); else if (lflags & PDOUBLELONGWORD) fprintf(outfp, ".dl"); else if (lflags & PSINGLE) fprintf(outfp, ".s"); else if (lflags & PDOUBLE) fprintf(outfp, ".d"); else if (lflags & PEXTENDED) fprintf(outfp, ".x"); else if (lflags & PPACKED) fprintf(outfp, ".p"); } else { if (lflags & PBYTE) fprintf(outfp, ".B"); else if (lflags & PWORD) fprintf(outfp, ".W"); else if (lflags & PLONGWORD) fprintf(outfp, ".L"); else if (lflags & PDOUBLELONGWORD) fprintf(outfp, ".DL"); else if (lflags & PSINGLE) fprintf(outfp, ".S"); else if (lflags & PDOUBLE) fprintf(outfp, ".D"); else if (lflags & PEXTENDED) fprintf(outfp, ".X"); else if (lflags & PPACKED) fprintf(outfp, ".P"); } for (i = 1; i <= operands; i++) { putc(i == 1 ? '\t' : ',', outfp); if (lflags & sharp2f(i)) putc('#', outfp); cp = va_arg(ap, char *); if (lower && (cp[0] != 'L' || !isdigit(cp[1]))) { char *cp2 = cp - 1; while (*++cp2) *cp2 = tolower(*cp2); } fprintf(outfp, "%s", cp); } putc('\n', outfp); } leninstbuf = 0; ppc = pc; va_end(ap);}/* * Format a range of registers (``low'' to ``high'') * into ``s'', beginning with a ``slash'' if necessary. * ``ad'' specifies either address (A) or data (D) registers. */static char *regwrite(char *s, char *ad, int low, int high, int slash){ if (slash) *s++ = '/'; if (high - low > 1) { s += sprintf(s, "%s", ad); *s++ = low + '0'; *s++ = '-'; s += sprintf(s, "%s", ad); *s++ = high + '0'; } else if (high - low == 1) { s += sprintf(s, "%s", ad); *s++ = low + '0'; *s++ = '/'; s += sprintf(s, "%s", ad); *s++ = high + '0'; } else { s += sprintf(s, "%s", ad); *s++ = high + '0'; } *s = '\0'; return s;}/* * Format ``regmask'' into ``s''. ``ad'' is a prefix used to indicate * whether the mask is for address, data, or floating-point registers. */char *regbyte(char *s, unsigned char regmask, char *ad, int doslash){ int i; int last; for (last = -1, i = 0; regmask; i++, regmask >>= 1) if (regmask & 1) { if (last != -1) continue; else last = i; } else if (last != -1) { s = regwrite(s, ad, last, i - 1, doslash); doslash = 1; last = -1; } if (last != -1) s = regwrite(s, ad, last, i - 1, doslash); return s;}/* * Reverse the ``nbits'' bits in ``bits''. * Used to change register masks. */voidrevbits(unsigned long *bits, size_t nbits){ int i; int b1, b2; for (i = 0; i < nbits / 2; i++) { b1 = *bits & (1 << i); b2 = *bits & (1 << (nbits - 1 - i)); if (b1) *bits |= 1 << (nbits - 1 - i); else *bits &= ~(1 << (nbits - 1 - i)); if (b2) *bits |= 1 << i; else *bits &= ~(1 << i); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -