|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = " dofloat.c 4.3 88/04/24 "; ! 3: #endif ! 4: ! 5: /* From Lou Salkind: compat/RCS/dofloat.c,v 1.2 84/01/31 13:33:53 */ ! 6: ! 7: /* ! 8: * Partial PDP-11 floating-point simulator. Always in double mode, ! 9: * chop mode. All arithmetic done in double-precision. Storing longs ! 10: * into or taking longs from general registers doesn't work. ! 11: * Overflow is never detected. ! 12: */ ! 13: ! 14: #include <stdio.h> ! 15: #include "defs.h" ! 16: ! 17: #define TRUE 1 ! 18: #define FALSE 0 ! 19: ! 20: #define ABSD 0170600 ! 21: #define ADDD 0172000 ! 22: #define CFCC 0170000 ! 23: #define CLRD 0170400 ! 24: #define CMPD 0173400 ! 25: #define DIVD 0174400 ! 26: #define LDCFD 0177400 ! 27: #define LDCLD 0177000 ! 28: #define LDD 0172400 ! 29: #define LDEXP 0176400 ! 30: #define MODD 0171400 ! 31: #define MULD 0171000 ! 32: #define NEGD 0170700 ! 33: #define SETD 0170011 ! 34: #define SETI 0170002 ! 35: #define SETL 0170012 ! 36: #define STCDL 0175400 ! 37: #define STCDF 0176000 ! 38: #define STD 0174000 ! 39: #define STEXP 0175000 ! 40: #define SUBD 0173000 ! 41: #define TSTD 0170500 ! 42: ! 43: static struct { ! 44: unsigned fc :1; ! 45: unsigned fv :1; ! 46: unsigned fz :1; ! 47: unsigned fn :1; ! 48: unsigned fmm :1; ! 49: unsigned ft :1; ! 50: unsigned fl :1; ! 51: unsigned fd :1; ! 52: } fps; ! 53: ! 54: #define FZ fps.fz ! 55: #define FN fps.fn ! 56: #define FL fps.fl ! 57: #define FD fps.fd ! 58: ! 59: #define LMODE FL ! 60: #define IMODE (!LMODE) ! 61: ! 62: static double fregs[6]; ! 63: ! 64: dofloat(instr) ! 65: unsigned int instr; ! 66: { ! 67: int mode, reg, ac; ! 68: unsigned short * x, * resolve(); ! 69: long fliplong(); ! 70: #define DOUBLE (*((double *)x)) ! 71: #define FLOAT (*(float *)x) ! 72: #define LONG (*(long *)x) ! 73: #define SHORT (*(short *)x) ! 74: #define GETDOUBLE (x = resolve(mode, reg, 8, TRUE)) ! 75: #define GETFLOAT (x = resolve(mode, reg, 4, TRUE)) ! 76: #define GETLONG (x = resolve(mode, reg, 4, FALSE)) ! 77: #define GETSHORT (x = resolve(mode, reg, 2, FALSE)) ! 78: #define FREG fregs[ac] ! 79: double temp; ! 80: union { ! 81: double d; ! 82: short s; ! 83: } bits; ! 84: ! 85: switch (instr & 0170000) { ! 86: case 0170000: ! 87: break; ! 88: default: ! 89: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 90: return (-1); ! 91: } ! 92: ! 93: switch (instr & 07000) { ! 94: case 0: ! 95: switch (instr & 0700) { ! 96: case 0: ! 97: switch (instr) { ! 98: case CFCC: ! 99: psl &= ~017; ! 100: if (FN) { ! 101: psl |= 010; ! 102: } ! 103: if (FZ) { ! 104: psl |= 04; ! 105: } ! 106: return (0); ! 107: case SETD: ! 108: FD = TRUE; ! 109: return (0); ! 110: case SETI: ! 111: FL = FALSE; ! 112: return (0); ! 113: case SETL: ! 114: FL = TRUE; ! 115: return (0); ! 116: default: ! 117: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 118: return (-1); ! 119: } ! 120: default: ! 121: break; ! 122: } ! 123: ! 124: mode = (instr & 070) >> 3; ! 125: reg = instr & 07; ! 126: ! 127: switch (instr & 0177700) { ! 128: case ABSD: ! 129: GETDOUBLE; ! 130: if (DOUBLE < 0.0) { ! 131: DOUBLE = -DOUBLE; ! 132: } ! 133: FZ = (DOUBLE == 0.0); ! 134: FN = (DOUBLE < 0.0); ! 135: return (0); ! 136: case CLRD: ! 137: GETDOUBLE; ! 138: DOUBLE = 0.0; ! 139: FZ = TRUE; ! 140: FN = FALSE; ! 141: return (0); ! 142: case NEGD: ! 143: GETDOUBLE; ! 144: DOUBLE = -DOUBLE; ! 145: FZ = (DOUBLE == 0.0); ! 146: FN = (DOUBLE < 0.0); ! 147: return (0); ! 148: case TSTD: ! 149: GETDOUBLE; ! 150: FZ = (DOUBLE == 0.0); ! 151: FN = (DOUBLE < 0.0); ! 152: return (0); ! 153: default: ! 154: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 155: return (-1); ! 156: } ! 157: default: ! 158: break; ! 159: } ! 160: ! 161: ac = (instr & 0300) >> 6; ! 162: mode = (instr & 070) >> 3; ! 163: reg = instr & 07; ! 164: ! 165: switch (instr & 0177400) { ! 166: case ADDD: ! 167: GETDOUBLE; ! 168: FREG += DOUBLE; ! 169: FZ = (FREG == 0.0); ! 170: FN = (FREG < 0.0); ! 171: return (0); ! 172: case CMPD: ! 173: GETDOUBLE; ! 174: FZ = (DOUBLE == FREG); ! 175: FN = (DOUBLE < FREG); ! 176: return (0); ! 177: case DIVD: ! 178: GETDOUBLE; ! 179: FREG /= DOUBLE; ! 180: FZ = (FREG == 0.0); ! 181: FN = (FREG < 0.0); ! 182: return (0); ! 183: case LDCFD: ! 184: GETFLOAT; ! 185: FREG = FLOAT; ! 186: FZ = (FREG == 0.0); ! 187: FN = (FREG < 0.0); ! 188: return (0); ! 189: case LDCLD: ! 190: if (IMODE) { ! 191: GETSHORT; ! 192: FREG = SHORT; ! 193: } else { ! 194: GETLONG; ! 195: FREG = fliplong(LONG); ! 196: } ! 197: FZ = (FREG == 0.0); ! 198: FN = (FREG < 0.0); ! 199: return (0); ! 200: case LDD: ! 201: GETDOUBLE; ! 202: FREG = DOUBLE; ! 203: FZ = (FREG == 0.0); ! 204: FN = (FREG < 0.0); ! 205: return (0); ! 206: case LDEXP: ! 207: GETSHORT; ! 208: bits.d = FREG; ! 209: bits.s &= ~077600; ! 210: bits.s |= (SHORT + 0200) << 7; ! 211: FREG = bits.d; ! 212: FZ = (SHORT == 0); ! 213: FN = (FREG < 0.0); ! 214: return (0); ! 215: case MODD: ! 216: GETDOUBLE; ! 217: temp = FREG * DOUBLE; ! 218: fregs[ac|1] = (long) temp; ! 219: FREG = temp - (long) temp; ! 220: FZ = (FREG == 0.0); ! 221: FN = (FREG < 0.0); ! 222: return (0); ! 223: case MULD: ! 224: GETDOUBLE; ! 225: FREG = FREG * DOUBLE; ! 226: FZ = (FREG == 0.0); ! 227: FN = (FREG < 0.0); ! 228: return (0); ! 229: case STCDF: ! 230: GETFLOAT; ! 231: FLOAT = FREG; ! 232: FZ = (FREG == 0.0); ! 233: FN = (FREG < 0.0); ! 234: return (0); ! 235: case STCDL: ! 236: if (IMODE) { ! 237: GETSHORT; ! 238: SHORT = FREG; ! 239: psl &= ~017; ! 240: if (SHORT == 0) { ! 241: psl |= 04; ! 242: } ! 243: if (SHORT < 0) { ! 244: psl |= 010; ! 245: } ! 246: } else { ! 247: GETLONG; ! 248: LONG = fliplong((long) FREG); ! 249: psl &= ~017; ! 250: if (fliplong(LONG) == 0) { ! 251: psl |= 04; ! 252: } ! 253: if (fliplong(LONG) < 0) { ! 254: psl |= 010; ! 255: } ! 256: } ! 257: FZ = (FREG == 0.0); ! 258: FN = (FREG < 0.0); ! 259: return (0); ! 260: case STD: ! 261: GETDOUBLE; ! 262: DOUBLE = FREG; ! 263: return (0); ! 264: case STEXP: ! 265: GETSHORT; ! 266: bits.d = FREG; ! 267: SHORT = ((bits.s & 077600) >> 7) - 0200; ! 268: FZ = (SHORT == 0); ! 269: FN = (SHORT < 0); ! 270: psl &= ~017; ! 271: if (FZ) { ! 272: psl |= 04; ! 273: } ! 274: if (FN) { ! 275: psl |= 010; ! 276: } ! 277: return (0); ! 278: case SUBD: ! 279: GETDOUBLE; ! 280: FREG -= DOUBLE; ! 281: FZ = (FREG == 0.0); ! 282: FN = (FREG < 0.0); ! 283: return (0); ! 284: default: ! 285: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 286: return (-1); ! 287: } ! 288: } ! 289: ! 290: unsigned short * ! 291: resolve(mode, reg, bytes, floating) ! 292: { ! 293: static unsigned short *x; ! 294: static union { ! 295: double d; ! 296: unsigned short s; ! 297: } bits; ! 298: ! 299: switch (mode) { ! 300: case 0: ! 301: if (floating) { ! 302: if (bytes != 8) { ! 303: fprintf(stderr, "Bad length in dofloat\n"); ! 304: return ((unsigned short *) -1); ! 305: } ! 306: x = (unsigned short *) &fregs[reg]; ! 307: } else { ! 308: if (bytes != 2) { ! 309: fprintf(stderr, "Bad length in dofloat\n"); ! 310: return ((unsigned short *) -1); ! 311: } ! 312: x = (unsigned short *) ®s[reg]; ! 313: } ! 314: break; ! 315: case 1: ! 316: x = (unsigned short *) regs[reg]; ! 317: break; ! 318: case 2: ! 319: if (reg == 7 && floating) { ! 320: bits.d = 0.0; ! 321: bits.s = *(unsigned short *) regs[7]; ! 322: x = (unsigned short *) &bits; ! 323: regs[7] += 2; ! 324: pc = (unsigned short *) regs[7]; ! 325: } else { ! 326: x = (unsigned short *) regs[reg]; ! 327: regs[reg] += bytes; ! 328: if (reg == 7) { ! 329: if (bytes != 2) { ! 330: return((unsigned short *) -1); ! 331: } ! 332: pc = (unsigned short *) regs[7]; ! 333: } ! 334: } ! 335: break; ! 336: case 3: ! 337: x = (unsigned short *) regs[reg]; ! 338: x = (unsigned short *) *x; ! 339: regs[reg] += 2; ! 340: if (reg == 7) { ! 341: pc = (unsigned short *) regs[7]; ! 342: } ! 343: break; ! 344: case 4: ! 345: regs[reg] -= bytes; ! 346: if (reg == 7) { ! 347: pc = (unsigned short *) regs[7]; ! 348: } ! 349: x = (unsigned short *) regs[reg]; ! 350: break; ! 351: case 5: ! 352: regs[reg] -= 2; ! 353: if (reg == 7) { ! 354: pc = (unsigned short *) regs[7]; ! 355: } ! 356: x = (unsigned short *) regs[reg]; ! 357: x = (unsigned short *) *x; ! 358: break; ! 359: case 6: ! 360: x = (unsigned short *) (unsigned short) (regs[reg] + *(pc++)); ! 361: if (reg == 7) { ! 362: ++x; ! 363: } ! 364: break; ! 365: case 7: ! 366: x = (unsigned short *) (unsigned short) (regs[reg] + *(pc++)); ! 367: if (reg == 7) { ! 368: ++x; ! 369: } ! 370: x = (unsigned short *) *x; ! 371: break; ! 372: } ! 373: ! 374: return (x); ! 375: } ! 376: ! 377: long ! 378: fliplong(l) ! 379: long l; ! 380: { ! 381: union { ! 382: long l; ! 383: short s[2]; ! 384: } bits[2]; ! 385: ! 386: bits[0].l = l; ! 387: bits[1].s[1] = bits[0].s[0]; ! 388: bits[1].s[0] = bits[0].s[1]; ! 389: return (bits[1].l); ! 390: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.