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 *) &regs[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: }

Defined functions

dofloat defined in line 64; used 2 times
fliplong defined in line 376; used 4 times
resolve defined in line 289; used 5 times

Defined variables

fregs defined in line 62; used 3 times
sccsid defined in line 2; never used

Defined macros

ABSD defined in line 20; never used
ADDD defined in line 21; never used
CFCC defined in line 22; never used
CLRD defined in line 23; never used
CMPD defined in line 24; never used
DIVD defined in line 25; never used
DOUBLE defined in line 69; used 21 times
FALSE defined in line 18; used 5 times
FD defined in line 57; used 1 times
FL defined in line 56; used 3 times
FLOAT defined in line 70; used 2 times
FN defined in line 55; used 19 times
FREG defined in line 77; used 41 times
FZ defined in line 54; used 19 times
GETDOUBLE defined in line 73; used 12 times
GETFLOAT defined in line 74; used 2 times
GETLONG defined in line 75; used 2 times
GETSHORT defined in line 76; used 4 times
IMODE defined in line 60; used 2 times
LDCFD defined in line 26; never used
LDCLD defined in line 27; never used
LDD defined in line 28; never used
LDEXP defined in line 29; never used
LMODE defined in line 59; used 1 times
  • in line 60
LONG defined in line 71; used 4 times
MODD defined in line 30; never used
MULD defined in line 31; never used
NEGD defined in line 32; never used
SETD defined in line 33; never used
SETI defined in line 34; never used
SETL defined in line 35; never used
SHORT defined in line 72; used 9 times
STCDF defined in line 37; never used
STCDL defined in line 36; never used
STD defined in line 38; never used
STEXP defined in line 39; never used
SUBD defined in line 40; never used
TRUE defined in line 17; used 5 times
TSTD defined in line 41; never used
Last modified: 1984-05-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1593
Valid CSS Valid XHTML 1.0 Strict