|
|
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.