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: }
Defined functions
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
- in line 99,
133,
139,
145-150(2),
169-174(2),
180,
186,
197,
203,
212,
220,
226,
232,
257,
268-273(2),
281
FREG
defined in line
77; used 41 times
FZ
defined in line
54; used 19 times
- in line 102,
132,
138,
144-149(2),
168-173(2),
179,
185,
196,
202,
211,
219,
225,
231,
256,
267-270(2),
280
GETDOUBLE
defined in line
73; used 12 times
- in line 128,
136,
142,
148,
166,
172-177(2),
200,
215,
223,
260,
278
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
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