|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = " dofloat.c 4.2 84/05/05 "; ! 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 = FALSE; ! 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: #define DOUBLE (*((double *)x)) ! 70: #define FLOAT (*(float *)x) ! 71: #define LONG (*(long *)x) ! 72: #define SHORT (*(short *)x) ! 73: #define GETDOUBLE (x = resolve(mode, reg, 8, TRUE)) ! 74: #define GETFLOAT (x = resolve(mode, reg, 4, TRUE)) ! 75: #define GETLONG (x = resolve(mode, reg, 4, FALSE)) ! 76: #define GETSHORT (x = resolve(mode, reg, 2, FALSE)) ! 77: #define FREG fregs[ac] ! 78: double temp; ! 79: union { ! 80: double d; ! 81: short s; ! 82: } bits; ! 83: ! 84: switch (instr & 0170000) { ! 85: case 0170000: ! 86: break; ! 87: default: ! 88: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 89: return (-1); ! 90: } ! 91: ! 92: switch (instr & 07000) { ! 93: case 0: ! 94: switch (instr & 0700) { ! 95: case 0: ! 96: switch (instr) { ! 97: case CFCC: ! 98: psl &= ~017; ! 99: if (FN) { ! 100: psl |= 010; ! 101: } ! 102: if (FZ) { ! 103: psl |= 04; ! 104: } ! 105: return (0); ! 106: case SETD: ! 107: FD = TRUE; ! 108: return (0); ! 109: case SETI: ! 110: FL = FALSE; ! 111: return (0); ! 112: case SETL: ! 113: FL = TRUE; ! 114: return (0); ! 115: default: ! 116: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 117: return (-1); ! 118: } ! 119: default: ! 120: break; ! 121: } ! 122: ! 123: mode = (instr & 070) >> 3; ! 124: reg = instr & 07; ! 125: ! 126: switch (instr & 0177700) { ! 127: case ABSD: ! 128: GETDOUBLE; ! 129: if (DOUBLE < 0.0) { ! 130: DOUBLE = -DOUBLE; ! 131: } ! 132: FZ = (DOUBLE == 0.0); ! 133: FN = (DOUBLE < 0.0); ! 134: return (0); ! 135: case CLRD: ! 136: GETDOUBLE; ! 137: DOUBLE = 0.0; ! 138: FZ = TRUE; ! 139: FN = FALSE; ! 140: return (0); ! 141: case NEGD: ! 142: GETDOUBLE; ! 143: DOUBLE = -DOUBLE; ! 144: FZ = (DOUBLE == 0.0); ! 145: FN = (DOUBLE < 0.0); ! 146: return (0); ! 147: case TSTD: ! 148: GETDOUBLE; ! 149: FZ = (DOUBLE == 0.0); ! 150: FN = (DOUBLE < 0.0); ! 151: return (0); ! 152: default: ! 153: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 154: return (-1); ! 155: } ! 156: default: ! 157: break; ! 158: } ! 159: ! 160: ac = (instr & 0300) >> 6; ! 161: mode = (instr & 070) >> 3; ! 162: reg = instr & 07; ! 163: ! 164: switch (instr & 0177400) { ! 165: case ADDD: ! 166: GETDOUBLE; ! 167: FREG += DOUBLE; ! 168: FZ = (FREG == 0.0); ! 169: FN = (FREG < 0.0); ! 170: return (0); ! 171: case CMPD: ! 172: GETDOUBLE; ! 173: FZ = (DOUBLE == FREG); ! 174: FN = (DOUBLE < FREG); ! 175: return (0); ! 176: case DIVD: ! 177: GETDOUBLE; ! 178: FREG /= DOUBLE; ! 179: FZ = (FREG == 0.0); ! 180: FN = (FREG < 0.0); ! 181: return (0); ! 182: case LDCFD: ! 183: GETFLOAT; ! 184: FREG = FLOAT; ! 185: FZ = (FREG == 0.0); ! 186: FN = (FREG < 0.0); ! 187: return (0); ! 188: case LDCLD: ! 189: if (IMODE) { ! 190: GETSHORT; ! 191: FREG = SHORT; ! 192: } else { ! 193: GETLONG; ! 194: FREG = fliplong(LONG); ! 195: } ! 196: FZ = (FREG == 0.0); ! 197: FN = (FREG < 0.0); ! 198: return (0); ! 199: case LDD: ! 200: GETDOUBLE; ! 201: FREG = DOUBLE; ! 202: FZ = (FREG == 0.0); ! 203: FN = (FREG < 0.0); ! 204: return (0); ! 205: case LDEXP: ! 206: GETSHORT; ! 207: bits.d = FREG; ! 208: bits.s &= ~077600; ! 209: bits.s |= (SHORT + 0200) << 7; ! 210: FREG = bits.d; ! 211: FZ = (SHORT == 0); ! 212: FN = (FREG < 0.0); ! 213: return (0); ! 214: case MODD: ! 215: GETDOUBLE; ! 216: temp = FREG * DOUBLE; ! 217: fregs[ac|1] = (long) temp; ! 218: FREG = temp - (long) temp; ! 219: FZ = (FREG == 0.0); ! 220: FN = (FREG < 0.0); ! 221: return (0); ! 222: case MULD: ! 223: GETDOUBLE; ! 224: FREG = FREG * DOUBLE; ! 225: FZ = (FREG == 0.0); ! 226: FN = (FREG < 0.0); ! 227: return (0); ! 228: case STCDF: ! 229: GETFLOAT; ! 230: FLOAT = FREG; ! 231: FZ = (FREG == 0.0); ! 232: FN = (FREG < 0.0); ! 233: return (0); ! 234: case STCDL: ! 235: if (IMODE) { ! 236: GETSHORT; ! 237: SHORT = FREG; ! 238: psl &= ~017; ! 239: if (SHORT == 0) { ! 240: psl |= 04; ! 241: } ! 242: if (SHORT < 0) { ! 243: psl |= 010; ! 244: } ! 245: } else { ! 246: GETLONG; ! 247: LONG = fliplong((long) FREG); ! 248: psl &= ~017; ! 249: if (fliplong(LONG) == 0) { ! 250: psl |= 04; ! 251: } ! 252: if (fliplong(LONG) < 0) { ! 253: psl |= 010; ! 254: } ! 255: } ! 256: FZ = (FREG == 0.0); ! 257: FN = (FREG < 0.0); ! 258: return (0); ! 259: case STD: ! 260: GETDOUBLE; ! 261: DOUBLE = FREG; ! 262: return (0); ! 263: case STEXP: ! 264: GETSHORT; ! 265: bits.d = FREG; ! 266: SHORT = ((bits.s & 077600) >> 7) - 0200; ! 267: FZ = (SHORT == 0); ! 268: FN = (SHORT < 0); ! 269: psl &= ~017; ! 270: if (FZ) { ! 271: psl |= 04; ! 272: } ! 273: if (FN) { ! 274: psl |= 010; ! 275: } ! 276: return (0); ! 277: case SUBD: ! 278: GETDOUBLE; ! 279: FREG -= DOUBLE; ! 280: FZ = (FREG == 0.0); ! 281: FN = (FREG < 0.0); ! 282: return (0); ! 283: default: ! 284: fprintf(stderr, "Unrecognized instr in dofloat %0o\n", instr); ! 285: return (-1); ! 286: } ! 287: } ! 288: ! 289: unsigned short * ! 290: resolve(mode, reg, bytes, floating) ! 291: { ! 292: static unsigned short *x; ! 293: static union { ! 294: double d; ! 295: unsigned short s; ! 296: } bits; ! 297: ! 298: switch (mode) { ! 299: case 0: ! 300: if (floating) { ! 301: if (bytes != 8) { ! 302: fprintf(stderr, "Bad length in dofloat\n"); ! 303: return ((unsigned short *) -1); ! 304: } ! 305: x = (unsigned short *) &fregs[reg]; ! 306: } else { ! 307: if (bytes != 2) { ! 308: fprintf(stderr, "Bad length in dofloat\n"); ! 309: return ((unsigned short *) -1); ! 310: } ! 311: x = (unsigned short *) ®s[reg]; ! 312: } ! 313: break; ! 314: case 1: ! 315: x = (unsigned short *) regs[reg]; ! 316: break; ! 317: case 2: ! 318: if (reg == 7 && floating) { ! 319: bits.d = 0.0; ! 320: bits.s = *(unsigned short *) regs[7]; ! 321: x = (unsigned short *) &bits; ! 322: regs[7] += 2; ! 323: pc = (unsigned short *) regs[7]; ! 324: } else { ! 325: x = (unsigned short *) regs[reg]; ! 326: regs[reg] += bytes; ! 327: if (reg == 7) { ! 328: if (bytes != 2) { ! 329: return((unsigned short *) -1); ! 330: } ! 331: pc = (unsigned short *) regs[7]; ! 332: } ! 333: } ! 334: break; ! 335: case 3: ! 336: x = (unsigned short *) regs[reg]; ! 337: x = (unsigned short *) *x; ! 338: regs[reg] += 2; ! 339: if (reg == 7) { ! 340: pc = (unsigned short *) regs[7]; ! 341: } ! 342: break; ! 343: case 4: ! 344: regs[reg] -= bytes; ! 345: if (reg == 7) { ! 346: pc = (unsigned short *) regs[7]; ! 347: } ! 348: x = (unsigned short *) regs[reg]; ! 349: break; ! 350: case 5: ! 351: regs[reg] -= 2; ! 352: if (reg == 7) { ! 353: pc = (unsigned short *) regs[7]; ! 354: } ! 355: x = (unsigned short *) regs[reg]; ! 356: x = (unsigned short *) *x; ! 357: break; ! 358: case 6: ! 359: x = (unsigned short *) (unsigned short) (regs[reg] + *(pc++)); ! 360: if (reg == 7) { ! 361: ++x; ! 362: } ! 363: break; ! 364: case 7: ! 365: x = (unsigned short *) (unsigned short) (regs[reg] + *(pc++)); ! 366: if (reg == 7) { ! 367: ++x; ! 368: } ! 369: x = (unsigned short *) *x; ! 370: break; ! 371: } ! 372: ! 373: return (x); ! 374: } ! 375: ! 376: long ! 377: fliplong(l) ! 378: long l; ! 379: { ! 380: union { ! 381: long l; ! 382: short s[2]; ! 383: } bits[2]; ! 384: ! 385: bits[0].l = l; ! 386: bits[1].s[1] = bits[0].s[0]; ! 387: bits[1].s[0] = bits[0].s[1]; ! 388: return (bits[1].l); ! 389: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.