static char sccsid
[] = " dofloat.c 4.1 82/05/12 ";
* Simulate pdp11 floating point for compatability mode programs.
* Quick and dirty with no big effort at speed since it takes so
* much overhead to get here in the first place.
* I make no claims on the completeness of this simulation.
/* static storage for floating registers */
static union alltypes fregs
[6];
static union alltypes srcdst
;
dofloat(instr
) unsigned int instr
; {
register unsigned short *wptr
;
register unsigned int opcode
, ac
, mode
, fac
, adjust
, output
, ccset
;
unsigned short *locate();
/* indicate what condition codes will be changed by op - assume none */
/* type of memory output - assume none */
/* default adjust to type */
/* chop up instruction to get relevent parts */
opcode
= instr
& 0177700;
/* if the instruction uses a src/dst construct ptr and fetch */
/* special case for mode 0 */
if(mode
== 0) switch(opcode
& 0177400) {
/* special instructions to use cpu regs */
srcdst
.d
= *(double *)wptr
;
srcdst
.f
= *(float *)wptr
;
/* immediate fetches are 16 bits */
if(ac
== 7 && (mode
== 2)) {
fprintf(stderr
,"pc %o sp %o instr %o srcdst %o mode %o reg %o fac %o\n", pc
-1,regs
[6],instr
,srcdst
.s
,mode
,ac
,fac
);
/* catches all fis instructions */
/* last 3 bits are stack pointer register */
/* get pointer to stack words */
wptr
= (unsigned short *)regs
[ac
];
/* getch floating value from stack */
srcdst
.f
= *(float *)wptr
;
/* do appropriate operation */
switch(instr
& 0177770) {
srcdst
.f
+= *(float *)wptr
;
srcdst
.f
= *(float *)wptr
- srcdst
.f
;
srcdst
.f
*= *(float *)wptr
;
srcdst
.f
= *(float *)wptr
/ srcdst
.f
;
*(float *)wptr
= srcdst
.f
;
/* set up condition codes */
if(srcdst
.f
== 0.) psl
|= FZ
;
if(srcdst
.f
< 0.) psl
|= FN
;
/* adjust register to reflect stack change */
regs
[ac
] = (unsigned short)(int)wptr
;
fprintf(stderr
,"CFCC %o\n",psl
);
if(srcdst
.d
< 0.0 ) srcdst
.d
= -srcdst
.d
;
opcode
= instr
& 0177400;
fprintf(stderr
,"STD %o\n",srcdst
.s
);
fprintf(stderr
,"LDD %o\n",srcdst
.s
);
fregs
[fac
].d
+= srcdst
.d
;
fregs
[fac
].d
-= srcdst
.d
;
fregs
[fac
].d
*= srcdst
.d
;
fprintf(stderr
,"DIVD %f by %f gives ",fregs
[fac
].d
,srcdst
.d
);
fregs
[fac
].d
/= srcdst
.d
;
fprintf(stderr
,"-> %f\n",fregs
[fac
].d
);
srcdst
.d
-= fregs
[fac
].d
;
fprintf(stderr
,"LDEXP %o gives %o\n",*wptr
,srcdst
.s
);
srcdst
.d
*= fregs
[fac
].d
;
fregs
[fac
].d
= (double)(long)srcdst
.d
;
if(~fac
& 1) fregs
[fac
+ 1].d
= fregs
[fac
].d
;
srcdst
.d
-= fregs
[fac
].d
;
fprintf(stderr
,"MODD %o %o\n",fregs
[fac
].s
,fregs
[fac
+1].s
);
if(mode
== 0) output
= SHORT
;
fprintf(stderr
,"STCDL %o\n",srcdst
.l
);
fprintf(stderr
,"STEXP of %o gives ",srcdst
.s
);
fprintf(stderr
,"%o\n",srcdst
.s
);
if(srcdst
.d
== 0.0) fps
|= FZ
;
if(!dbl
&& srcdst
.f
== 0.0) fps
|= FZ
;
if(srcdst
.f
< 0.0) fps
|= FN
;
switch(instr
& 0177400) {
*((short *)wptr
) = srcdst
.s
;
*((long *)wptr
) = longrev(srcdst
.l
);
*((float *)wptr
) = srcdst
.f
;
*((double *)wptr
) = srcdst
.d
;
unsigned short *locate(mode
, ac
) {
register unsigned short *wptr
;
/* mode 0 normally implies fregs */
wptr
= (unsigned short *)&fregs
[ac
];
wptr
= (unsigned short *)(int)regs
[ac
];
wptr
= (unsigned short *)regs
[ac
];
wptr
= (unsigned short *)*wptr
;
wptr
= (unsigned short *)regs
[ac
];
wptr
= (unsigned short *)regs
[ac
];
wptr
= (unsigned short *)*wptr
;
wptr
= (unsigned short *)((regs
[ac
] + *pc
) & 0177776);
wptr
= (unsigned short *)((regs
[ac
] + *pc
) & 0177776);
wptr
= (unsigned short *)*wptr
;