c00.o c01.o c02.o c03.o c04.o c05.o: c0.h
-c1: c10.o c11.o c12.o c13.o pdp11_atof.o pdp11_fp.o pdp11_ldexp.o table.o
- ${CC} ${LDC1FLAGS} ${CFLAGS} -o c1 c10.o c11.o c12.o c13.o pdp11_atof.o pdp11_fp.o pdp11_ldexp.o table.o
+c1: c10.o c11.o c12.o c13.o fp.o fp_atof.o table.o
+ ${CC} ${LDC1FLAGS} ${CFLAGS} -o c1 c10.o c11.o c12.o c13.o fp.o fp_atof.o table.o
c10.o c11.o c12.o c13.o: c1.h
#define _C0_H 1
#include <stdio.h>
-#include "krcompat.h"
#ifdef pdp11
-#define _INT int
-#define _LONG long
-#define _UNSIGNED_INT unsigned int
-#define _UNSIGNED_LONG unsigned long
+typedef int _INT;
+typedef long _LONG;
+typedef unsigned int _UNSIGNED_INT;
+typedef unsigned long _UNSIGNED_LONG;
+typedef float _FLOAT;
+typedef double _DOUBLE;
#else
#include <stdint.h>
-#define _INT int16_t
-#define _LONG int32_t
-#define _UNSIGNED_INT uint16_t
-#define _UNSIGNED_LONG uint32_t
+typedef int16_t _INT;
+typedef int32_t _LONG;
+typedef uint16_t _UNSIGNED_INT;
+typedef uint32_t _UNSIGNED_LONG;
+typedef struct { uint32_t h; } _FLOAT;
+typedef struct { uint32_t l; uint32_t h; } _DOUBLE;
#endif
/*
#define FINIT 040
#define FLABL 0100
+#ifndef __P
+#ifdef __STDC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif
+
/* c00.c */
-int main PARAMS((int argc, char *argv[]));
-int lookup PARAMS((void));
-int findkw PARAMS((void));
-int symbol PARAMS((void));
-int getnum PARAMS((void));
-int subseq PARAMS((int c, int a, int b));
-void putstr PARAMS((int lab, register int max));
-void cntstr PARAMS((void));
-int getcc PARAMS((void));
-int mapch PARAMS((int ac));
-union tree *tree PARAMS((int eflag));
-union tree *xprtype PARAMS((void));
-char *copnum PARAMS((int len));
+int main __P((int argc, char *argv[]));
+int lookup __P((void));
+int findkw __P((void));
+int symbol __P((void));
+int getnum __P((void));
+int subseq __P((int c, int a, int b));
+void putstr __P((int lab, register int max));
+void cntstr __P((void));
+int getcc __P((void));
+int mapch __P((int ac));
+union tree *tree __P((int eflag));
+union tree *xprtype __P((void));
+char *copnum __P((int len));
+
/* c01.c */
-void build PARAMS((int op));
-union tree *structident PARAMS((register union tree *p1, register union tree *p2));
-union tree *convert PARAMS((union tree *p, int t, int cvn, int len));
-void setype PARAMS((register union tree *p, register int t, register union tree *newp));
-union tree *chkfun PARAMS((register union tree *p));
-union tree *disarray PARAMS((register union tree *p));
-void chkw PARAMS((union tree *p, int okt));
-int lintyp PARAMS((int t));
-void werror PARAMS((char *s, ...));
-void error PARAMS((char *s, ...));
-union tree *block PARAMS((int op, int t, int *subs, union str *str, union tree *p1, union tree *p2));
-union tree *nblock PARAMS((register struct nmlist *ds));
-union tree *cblock PARAMS((int v));
-union tree *fblock PARAMS((int t, char *string));
-char *Tblock PARAMS((int n));
-char *starttree PARAMS((void));
-void endtree PARAMS((char *tp));
-char *Dblock PARAMS((int n));
-void chklval PARAMS((register union tree *p));
-int fold PARAMS((int op, register union tree *p1, union tree *p2));
-int conexp PARAMS((void));
-void assignop PARAMS((int op, register union tree *p1, register union tree *p2));
-struct nmlist *gentemp PARAMS((int type));
+void build __P((int op));
+union tree *structident __P((register union tree *p1, register union tree *p2));
+union tree *convert __P((union tree *p, int t, int cvn, int len));
+void setype __P((register union tree *p, register int t, register union tree *newp));
+union tree *chkfun __P((register union tree *p));
+union tree *disarray __P((register union tree *p));
+void chkw __P((union tree *p, int okt));
+int lintyp __P((int t));
+void werror __P((char *s, ...));
+void error __P((char *s, ...));
+union tree *block __P((int op, int t, int *subs, union str *str, union tree *p1, union tree *p2));
+union tree *nblock __P((register struct nmlist *ds));
+union tree *cblock __P((int v));
+union tree *fblock __P((int t, char *string));
+char *Tblock __P((int n));
+char *starttree __P((void));
+void endtree __P((char *tp));
+char *Dblock __P((int n));
+void chklval __P((register union tree *p));
+int fold __P((int op, register union tree *p1, union tree *p2));
+int conexp __P((void));
+void assignop __P((int op, register union tree *p1, register union tree *p2));
+struct nmlist *gentemp __P((int type));
+
/* c02.c */
-void extdef PARAMS((void));
-void cfunc PARAMS((void));
-int cinit PARAMS((struct nmlist *anp, int flex, int sclass));
-void strinit PARAMS((struct nmlist *np, int sclass));
-void setinit PARAMS((register struct nmlist *np));
-void statement PARAMS((void));
-int forstmt PARAMS((void));
-union tree *pexpr PARAMS((int eflag));
-void pswitch PARAMS((void));
-void funchead PARAMS((void));
-void blockhead PARAMS((void));
-void blkend PARAMS((void));
-void nameconflict PARAMS((register struct nmlist *ocs, register struct nmlist *cs));
-void prste PARAMS((struct nmlist *cs));
-void errflush PARAMS((int ao));
+void extdef __P((void));
+void cfunc __P((void));
+int cinit __P((struct nmlist *anp, int flex, int sclass));
+void strinit __P((struct nmlist *np, int sclass));
+void setinit __P((register struct nmlist *np));
+void statement __P((void));
+int forstmt __P((void));
+union tree *pexpr __P((int eflag));
+void pswitch __P((void));
+void funchead __P((void));
+void blockhead __P((void));
+void blkend __P((void));
+void nameconflict __P((register struct nmlist *ocs, register struct nmlist *cs));
+void prste __P((struct nmlist *cs));
+void errflush __P((int ao));
+
/* c03.c */
-int declist PARAMS((int sclass));
-int getkeywords PARAMS((int *scptr, struct nmlist *tptr));
-union str *strdec PARAMS((int mosf, int kind));
-int declare PARAMS((int askw, struct nmlist *tptr, int offset));
-int decl1 PARAMS((int askw, struct nmlist *atptr, int offset, struct nmlist *absname));
-struct nmlist *pushdecl PARAMS((register struct nmlist *sp));
-int getype PARAMS((register struct tdim *dimp, struct nmlist *absname));
-void typov PARAMS((void));
-int align PARAMS((int type, int offset, int aflen));
-void decsyn PARAMS((int o));
-void redec PARAMS((void));
-int goodreg PARAMS((struct nmlist *hp));
+int declist __P((int sclass));
+int getkeywords __P((int *scptr, struct nmlist *tptr));
+union str *strdec __P((int mosf, int kind));
+int declare __P((int askw, struct nmlist *tptr, int offset));
+int decl1 __P((int askw, struct nmlist *atptr, int offset, struct nmlist *absname));
+struct nmlist *pushdecl __P((register struct nmlist *sp));
+int getype __P((register struct tdim *dimp, struct nmlist *absname));
+void typov __P((void));
+int align __P((int type, int offset, int aflen));
+void decsyn __P((int o));
+void redec __P((void));
+int goodreg __P((struct nmlist *hp));
+
/* c04.c */
-int decref PARAMS((register int t));
-int incref PARAMS((register int t));
-void cbranch PARAMS((union tree *t, int lbl, int cond));
-void rcexpr PARAMS((register union tree *tp));
-void treeout PARAMS((register union tree *tp, int isstruct));
-void branch PARAMS((int lab));
-void label PARAMS((int l));
-int plength PARAMS((register union tree *p));
-int length PARAMS((union tree *cs));
-int rlength PARAMS((union tree *cs));
-int simplegoto PARAMS((void));
-int nextchar PARAMS((void));
-int spnextchar PARAMS((void));
-void chconbrk PARAMS((int l));
-void dogoto PARAMS((void));
-void doret PARAMS((void));
-void outcode PARAMS((char *s, ...));
-unsigned int hash PARAMS((register char *sp));
-int main PARAMS((int argc, char *argv[]));
-int lookup PARAMS((void));
-int findkw PARAMS((void));
-int symbol PARAMS((void));
-int getnum PARAMS((void));
-int subseq PARAMS((int c, int a, int b));
-void putstr PARAMS((int lab, register int max));
-void cntstr PARAMS((void));
-int getcc PARAMS((void));
-int mapch PARAMS((int ac));
-union tree *tree PARAMS((int eflag));
-union tree *xprtype PARAMS((void));
-char *copnum PARAMS((int len));
-void build PARAMS((int op));
-union tree *structident PARAMS((register union tree *p1, register union tree *p2));
-union tree *convert PARAMS((union tree *p, int t, int cvn, int len));
-void setype PARAMS((register union tree *p, register int t, register union tree *newp));
-union tree *chkfun PARAMS((register union tree *p));
-union tree *disarray PARAMS((register union tree *p));
-void chkw PARAMS((union tree *p, int okt));
-int lintyp PARAMS((int t));
-void werror PARAMS((char *s, ...));
-void error PARAMS((char *s, ...));
-union tree *block PARAMS((int op, int t, int *subs, union str *str, union tree *p1, union tree *p2));
-union tree *nblock PARAMS((register struct nmlist *ds));
-union tree *cblock PARAMS((int v));
-union tree *fblock PARAMS((int t, char *string));
-char *Tblock PARAMS((int n));
-char *starttree PARAMS((void));
-void endtree PARAMS((char *tp));
-char *Dblock PARAMS((int n));
-void chklval PARAMS((register union tree *p));
-int fold PARAMS((int op, register union tree *p1, union tree *p2));
-int conexp PARAMS((void));
-void assignop PARAMS((int op, register union tree *p1, register union tree *p2));
-struct nmlist *gentemp PARAMS((int type));
-void extdef PARAMS((void));
-void cfunc PARAMS((void));
-int cinit PARAMS((struct nmlist *anp, int flex, int sclass));
-void strinit PARAMS((struct nmlist *np, int sclass));
-void setinit PARAMS((register struct nmlist *np));
-void statement PARAMS((void));
-int forstmt PARAMS((void));
-union tree *pexpr PARAMS((int eflag));
-void pswitch PARAMS((void));
-void funchead PARAMS((void));
-void blockhead PARAMS((void));
-void blkend PARAMS((void));
-void nameconflict PARAMS((register struct nmlist *ocs, register struct nmlist *cs));
-void prste PARAMS((struct nmlist *cs));
-void errflush PARAMS((int ao));
-int declist PARAMS((int sclass));
-int getkeywords PARAMS((int *scptr, struct nmlist *tptr));
-union str *strdec PARAMS((int mosf, int kind));
-int declare PARAMS((int askw, struct nmlist *tptr, int offset));
-int decl1 PARAMS((int askw, struct nmlist *atptr, int offset, struct nmlist *absname));
-struct nmlist *pushdecl PARAMS((register struct nmlist *sp));
-int getype PARAMS((register struct tdim *dimp, struct nmlist *absname));
-void typov PARAMS((void));
-int align PARAMS((int type, int offset, int aflen));
-void decsyn PARAMS((int o));
-void redec PARAMS((void));
-int goodreg PARAMS((struct nmlist *hp));
-int decref PARAMS((register int t));
-int incref PARAMS((register int t));
-void cbranch PARAMS((union tree *t, int lbl, int cond));
-void rcexpr PARAMS((register union tree *tp));
-void treeout PARAMS((register union tree *tp, int isstruct));
-void branch PARAMS((int lab));
-void label PARAMS((int l));
-int plength PARAMS((register union tree *p));
-int length PARAMS((union tree *cs));
-int rlength PARAMS((union tree *cs));
-int simplegoto PARAMS((void));
-int nextchar PARAMS((void));
-int spnextchar PARAMS((void));
-void chconbrk PARAMS((int l));
-void dogoto PARAMS((void));
-void doret PARAMS((void));
-void outcode PARAMS((char *s, ...));
-unsigned int hash PARAMS((register char *sp));
+int decref __P((register int t));
+int incref __P((register int t));
+void cbranch __P((union tree *t, int lbl, int cond));
+void rcexpr __P((register union tree *tp));
+void treeout __P((register union tree *tp, int isstruct));
+void branch __P((int lab));
+void label __P((int l));
+int plength __P((register union tree *p));
+int length __P((union tree *cs));
+int rlength __P((union tree *cs));
+int simplegoto __P((void));
+int nextchar __P((void));
+int spnextchar __P((void));
+void chconbrk __P((int l));
+void dogoto __P((void));
+void doret __P((void));
+void outcode __P((char *s, ...));
+unsigned int hash __P((register char *sp));
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#define _va_start(ap, arg) va_start(ap, arg)
+#else
+#include <varargs.h>
+#define _va_start(ap, arg) va_start(ap)
+#endif
#include "c0.h"
/*
if (filename[0])
fprintf(stderr, "%s:", filename);
fprintf(stderr, "%d: warning: ", line);
- VA_START(ap, s);
+ _va_start(ap, s);
vfprintf(stderr, s, ap);
va_end(ap);
fprintf(stderr, "\n");
if (filename[0])
fprintf(stderr, "%s:", filename);
fprintf(stderr, "%d: ", line);
- VA_START(ap, s);
+ _va_start(ap, s);
vfprintf(stderr, s, ap);
va_end(ap);
fprintf(stderr, "\n");
*/
#include <stdlib.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#define _va_start(ap, arg) va_start(ap, arg)
+#else
+#include <varargs.h>
+#define _va_start(ap, arg) va_start(ap)
+#endif
#include "c0.h"
/*
bufp = stdout;
if (strflg)
bufp = sbufp;
- VA_START(ap, s);
+ _va_start(ap, s);
for (;;) switch(*s++) {
case 'B':
ni = va_arg(ap, int);
#include <stdio.h>
#include <setjmp.h>
-#include "krcompat.h"
#ifdef pdp11
-#define _INT int
-#define _LONG long
-#define _UNSIGNED_INT unsigned int
-#define _UNSIGNED_LONG unsigned long
+typedef int _INT;
+typedef long _LONG;
+typedef unsigned int _UNSIGNED_INT;
+typedef unsigned long _UNSIGNED_LONG;
+typedef float _FLOAT;
+typedef double _DOUBLE;
#else
#include <stdint.h>
-#define _INT int16_t
-#define _LONG int32_t
-#define _UNSIGNED_INT uint16_t
-#define _UNSIGNED_LONG uint32_t
+typedef int16_t _INT;
+typedef int32_t _LONG;
+typedef uint16_t _UNSIGNED_INT;
+typedef uint32_t _UNSIGNED_LONG;
+typedef struct { uint32_t h; } _FLOAT;
+typedef struct { uint32_t l; uint32_t h; } _DOUBLE;
#endif
#ifndef NULL
int op;
int type;
int value;
-#ifdef pdp11
- double fvalue;
-#else
- uint16_t fvalue[4];
-#endif
+ _DOUBLE fvalue;
};
/*
};
#endif
-#ifndef pdp11
-extern int32_t FEC;
-extern int32_t FPS;
-extern int N, Z, V, C;
-extern int R[8];
+#ifndef __P
+#ifdef __STDC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
#endif
/* c10.c */
-int main PARAMS((int argc, char *argv[]));
-struct optab *match PARAMS((union tree *tree, struct table *table, int nrleft, int nocvt));
-int rcexpr PARAMS((union tree *atree, struct table *atable, int reg));
-int cexpr PARAMS((register union tree *tree, struct table *table, int areg));
-int reorder PARAMS((union tree **treep, struct table *table, int reg));
-int sreorder PARAMS((union tree **treep, struct table *table, int reg, int recurf));
-int delay PARAMS((union tree **treep, struct table *table, int reg));
-union tree *sdelay PARAMS((union tree **ap));
-union tree *paint PARAMS((register union tree *tp, register int type));
-union tree *ncopy PARAMS((register union tree *p));
-int chkleaf PARAMS((register union tree *tree, struct table *table, int reg));
-int comarg PARAMS((register union tree *tree, int *flagp));
-union tree *strfunc PARAMS((register union tree *tp));
-void doinit PARAMS((register int type, register union tree *tree));
-void movreg PARAMS((int r0, int r1, union tree *tree));
+int main __P((int argc, char *argv[]));
+struct optab *match __P((union tree *tree, struct table *table, int nrleft, int nocvt));
+int rcexpr __P((union tree *atree, struct table *atable, int reg));
+int cexpr __P((register union tree *tree, struct table *table, int areg));
+int reorder __P((union tree **treep, struct table *table, int reg));
+int sreorder __P((union tree **treep, struct table *table, int reg, int recurf));
+int delay __P((union tree **treep, struct table *table, int reg));
+union tree *sdelay __P((union tree **ap));
+union tree *paint __P((register union tree *tp, register int type));
+union tree *ncopy __P((register union tree *p));
+int chkleaf __P((register union tree *tree, struct table *table, int reg));
+int comarg __P((register union tree *tree, int *flagp));
+union tree *strfunc __P((register union tree *tp));
+void doinit __P((register int type, register union tree *tree));
+void movreg __P((int r0, int r1, union tree *tree));
+
/* c11.c */
-int degree PARAMS((register union tree *t));
-void pname PARAMS((register union tree *p, int flag));
-void pbase PARAMS((register union tree *p));
-int xdcalc PARAMS((register union tree *p, int nrleft));
-int dcalc PARAMS((register union tree *p, int nrleft));
-int notcompat PARAMS((register union tree *p, int ast, int deg, int op));
-int prins PARAMS((int op, int c, struct instab *itable, int lbl));
-int collcon PARAMS((register union tree *p));
-int isfloat PARAMS((register union tree *t));
-int oddreg PARAMS((register union tree *t, register int reg));
-int arlength PARAMS((int t));
-void pswitch PARAMS((struct swtab *afp, struct swtab *alp, int deflab));
-void breq PARAMS((int v, int l));
-int sort PARAMS((struct swtab *afp, struct swtab *alp));
-int ispow2 PARAMS((register union tree *tree));
-union tree *pow2 PARAMS((register union tree *tree));
-void cbranch PARAMS((union tree *atree, register int lbl, int cond, register int reg));
-void branch PARAMS((int lbl, int aop, int c));
-void longrel PARAMS((union tree *atree, int lbl, int cond, int reg));
-int xlongrel PARAMS((int f));
-void label PARAMS((int l));
-void popstk PARAMS((int a));
-void werror PARAMS((char *s));
-void error PARAMS((char *s, ...));
-void psoct PARAMS((int an));
-void getree PARAMS((void));
-int geti PARAMS((void));
-void strasg PARAMS((union tree *atp));
-int decref PARAMS((register int t));
-int incref PARAMS((register int t));
+int degree __P((register union tree *t));
+void pname __P((register union tree *p, int flag));
+void pbase __P((register union tree *p));
+int xdcalc __P((register union tree *p, int nrleft));
+int dcalc __P((register union tree *p, int nrleft));
+int notcompat __P((register union tree *p, int ast, int deg, int op));
+int prins __P((int op, int c, struct instab *itable, int lbl));
+int collcon __P((register union tree *p));
+int isfloat __P((register union tree *t));
+int oddreg __P((register union tree *t, register int reg));
+int arlength __P((int t));
+void pswitch __P((struct swtab *afp, struct swtab *alp, int deflab));
+void breq __P((int v, int l));
+int sort __P((struct swtab *afp, struct swtab *alp));
+int ispow2 __P((register union tree *tree));
+union tree *pow2 __P((register union tree *tree));
+void cbranch __P((union tree *atree, register int lbl, int cond, register int reg));
+void branch __P((int lbl, int aop, int c));
+void longrel __P((union tree *atree, int lbl, int cond, int reg));
+int xlongrel __P((int f));
+void label __P((int l));
+void popstk __P((int a));
+void werror __P((char *s));
+void error __P((char *s, ...));
+void psoct __P((int an));
+void getree __P((void));
+int geti __P((void));
+void strasg __P((union tree *atp));
+int decref __P((register int t));
+int incref __P((register int t));
+
/* c12.c */
-union tree *optim PARAMS((register union tree *tree));
-union tree *unoptim PARAMS((register union tree *tree));
-union tree *lvfield PARAMS((register union tree *t));
-union tree *acommute PARAMS((register union tree *tree));
-int sideeffects PARAMS((register union tree *tp));
-void distrib PARAMS((struct acl *list));
-void squash PARAMS((union tree **p, union tree **maxp));
-void _const PARAMS((int op, register _INT *vp, _INT v, int type));
-union tree *lconst PARAMS((int op, register union tree *lp, register union tree *rp));
-void insert PARAMS((int op, register union tree *tree, register struct acl *list));
-union tree *tnode PARAMS((int op, int type, union tree *tr1, union tree *tr2));
-union tree *tconst PARAMS((int val, int type));
-union tree *getblk PARAMS((int size));
-int islong PARAMS((int t));
-union tree *isconstant PARAMS((register union tree *t));
-union tree *hardlongs PARAMS((register union tree *t));
-int uns PARAMS((union tree *tp));
+union tree *optim __P((register union tree *tree));
+union tree *unoptim __P((register union tree *tree));
+union tree *lvfield __P((register union tree *t));
+union tree *acommute __P((register union tree *tree));
+int sideeffects __P((register union tree *tp));
+void distrib __P((struct acl *list));
+void squash __P((union tree **p, union tree **maxp));
+void _const __P((int op, register _INT *vp, _INT v, int type));
+union tree *lconst __P((int op, register union tree *lp, register union tree *rp));
+void insert __P((int op, register union tree *tree, register struct acl *list));
+union tree *tnode __P((int op, int type, union tree *tr1, union tree *tr2));
+union tree *tconst __P((int val, int type));
+union tree *getblk __P((int size));
+int islong __P((int t));
+union tree *isconstant __P((register union tree *t));
+union tree *hardlongs __P((register union tree *t));
+int uns __P((union tree *tp));
+
#ifndef pdp11
-/* pdp11_atof.c */
-void pdp11_atof PARAMS((char *p));
-/* pdp11_fp.c */
-void pdp11_cfcc PARAMS((void));
-void pdp11_seti PARAMS((void));
-void pdp11_setl PARAMS((void));
-void pdp11_clrf PARAMS((uint16_t *va, int dstspec));
-void pdp11_negf PARAMS((uint16_t *va, int dstspec));
-void pdp11_ldf PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_stf PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_ldcfo PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_stcfo PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_cmpf PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_movie PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_movei PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_movif PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_movfi PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_mulf PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_addf PARAMS((int ac, uint16_t *va, int dstspec));
-void pdp11_divf PARAMS((int ac, uint16_t *va, int dstspec));
-int32_t fpnotrap PARAMS((int32_t code));
-/* pdp11_ldexp.c */
-void pdp11_ldexp PARAMS((uint16_t *value, int exp));
+/* fp.c */
+int fp_tst __P((_DOUBLE val));
+_DOUBLE fp_abs __P((_DOUBLE val));
+_DOUBLE fp_neg __P((_DOUBLE val));
+int fp_le __P((_DOUBLE val0, _DOUBLE val1));
+int fp_ge __P((_DOUBLE val0, _DOUBLE val1));
+int fp_gt __P((_DOUBLE val0, _DOUBLE val1));
+int fp_lt __P((_DOUBLE val0, _DOUBLE val1));
+_INT fp_double_to_int __P((_DOUBLE val));
+_LONG fp_double_to_long __P((_DOUBLE val));
+_FLOAT fp_double_to_float __P((_DOUBLE val));
+_DOUBLE fp_int_to_double __P((_INT val));
+_DOUBLE fp_long_to_double __P((_LONG val));
+_DOUBLE fp_float_to_double __P((_FLOAT val));
+_DOUBLE fp_add __P((_DOUBLE val0, _DOUBLE val1));
+_DOUBLE fp_sub __P((_DOUBLE val0, _DOUBLE val1));
+_DOUBLE fp_mul __P((_DOUBLE val0, _DOUBLE val1));
+_DOUBLE fp_div __P((_DOUBLE val0, _DOUBLE val1));
+_DOUBLE fp_ldexp __P((_DOUBLE val, _INT exp));
+
+/* fp_atof.c */
+_DOUBLE fp_atof __P((register char *p));
#endif
#endif
((_UNSIGNED_INT *)&(p1->f.fvalue))[3] );
#else
printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value,
- p1->f.fvalue[0],
- p1->f.fvalue[1],
- p1->f.fvalue[2],
- p1->f.fvalue[3] );
+ (int)(p1->f.fvalue.h >> 16) & 0xffff,
+ (int)p1->f.fvalue.h & 0xffff,
+ (int)(p1->f.fvalue.l >> 16) & 0xffff,
+ (int)p1->f.fvalue.l & 0xffff );
#endif
p1->f/*c*/.value = -p1->f/*c*/.value;
}
((_UNSIGNED_INT *)&(p2->f.fvalue))[3] );
#else
printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value,
- p2->f.fvalue[0],
- p2->f.fvalue[1],
- p2->f.fvalue[2],
- p2->f.fvalue[3] );
+ (int)(p2->f.fvalue.h >> 16) & 0xffff,
+ (int)p2->f.fvalue.h & 0xffff,
+ (int)(p2->f.fvalue.l >> 16) & 0xffff,
+ (int)p2->f.fvalue.l & 0xffff );
#endif
p2->f.value = -p2->f.value;
}
* Compile an initializing expression
*/
void doinit(type, tree) register int type; register union tree *tree; {
-#ifdef pdp11
- float sfval;
- double fval;
-#else
- uint16_t temp[2];
- uint16_t sfval[2];
- uint16_t fval[4];
-#endif
+ _FLOAT sfval;
+ _DOUBLE fval;
_LONG lval;
if (type==CHAR || type==UNCHAR) {
#ifdef pdp11
tree->c.value = tree->f.fvalue;
#else
- /* movf 6(r3),r0 */
- pdp11_ldf(0, tree->f.fvalue, 063);
- /* movfi r0, 4(r3) */
- pdp11_movfi(0, temp, 063);
- tree->c.value = (int16_t)temp[0];
+ tree->c.value = fp_double_to_int(tree->f.fvalue);
#endif
tree->t.op = CON;
} else if (tree->t.op==LTOI) {
#ifdef pdp11
fval = tree->t.tr1->c.value;
#else
- /* movif 4(r0),r0 */
- temp[0] = (uint16_t)tree->t.tr1->c.value;
- pdp11_movif(0, temp, 060);
- /* movf r0,-24(r5) */
- pdp11_stf(0, fval, 065);
+ fval = fp_int_to_double(tree->t.tr1->c.value);
#endif
} else
goto illinit;
} else if (tree->t.op==FCON || tree->t.op==SFCON) {
-#ifdef pdp11
fval = tree->f.fvalue;
-#else
- /* movf 6(r3),r0 */
- pdp11_ldf(0, tree->f.fvalue, 063);
- /* movf r0,-24(r5) */
- pdp11_stf(0, fval, 065);
-#endif
} else if (tree->t.op==LTOF) {
if (tree->t.tr1->t.op!=LCON)
goto illinit;
#ifdef pdp11
fval = tree->t.tr1->l.lvalue;
#else
- /* setl */
- pdp11_setl();
- /* movif 4(r0),r0 */
- temp[0] = (uint16_t)((tree->t.tr1->l.lvalue >> 16) & 0xffff);
- temp[1] = (uint16_t)(tree->t.tr1->l.lvalue & 0xffff);
- pdp11_movif(0, temp, 060);
- /* seti */
- pdp11_seti();
- /* movf r0,-24(r5) */
- pdp11_stf(0, fval, 065);
+ fval = fp_long_to_double(tree->t.tr1->l.lvalue);
#endif
} else
goto illinit;
((_UNSIGNED_INT *)&sfval)[0],
((_UNSIGNED_INT *)&sfval)[1]);
#else
- /* movfo r0,-14(r5) */
- pdp11_stcfo(0, sfval, 065);
+ sfval = fp_double_to_float(fval);
printf("%o; %o\n",
- sfval[0],
- sfval[1]);
+ (int)(sfval.h >> 16) & 0xffff,
+ (int)sfval.h & 0xffff);
#endif
} else {
#ifdef pdp11
((_UNSIGNED_INT *)&fval)[3]);
#else
printf("%o; %o; %o; %o\n",
- fval[0],
- fval[1],
- fval[2],
- fval[3]);
+ (int)(fval.h >> 16) & 0xffff,
+ (int)fval.h & 0xffff,
+ (int)(fval.l >> 16) & 0xffff,
+ (int)fval.l & 0xffff);
#endif
}
return;
#ifdef pdp11
lval = tree->f.fvalue;
#else
- /* movf 6(r3),r0 */
- pdp11_ldf(0, tree->f.fvalue, 063);
- /* setl */
- pdp11_setl();
- /* movfi r0,-30(r5) */
- pdp11_movfi(0, temp, 065);
- lval = ((temp[0] & 0xffffL) << 16) | (temp[1] & 0xffffL);
- /* seti */
- pdp11_seti();
+ lval = fp_double_to_long(tree->f.fvalue);
#endif
} else if (tree->t.op==ITOL) {
if (tree->t.tr1->t.op != CON)
#include <math.h>
#include <stdlib.h>
#include <string.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#define _va_start(ap, arg) va_start(ap, arg)
+#else
+#include <varargs.h>
+#define _va_start(ap, arg) va_start(ap)
+#endif
#include "c1.h"
-static void outname PARAMS((char *s));
+static void outname __P((char *s));
int degree(t) register union tree *t; {
register union tree *t1;
nerror++;
fprintf(stderr, "%d: ", line);
- VA_START(ap, s);
+ _va_start(ap, s);
vfprintf(stderr, s, ap);
va_end(ap);
putc('\n', stderr);
#ifdef pdp11
tp->f.fvalue = atof(s);
#else
- pdp11_atof(s);
- /* movf r0,6(r4) */
- pdp11_stf(0, tp->f.fvalue, 064);
+ fprintf(stderr, "%s\n", s);
+ tp->f.fvalue = fp_atof(s);
#endif
*sp++ = tp;
break;
tree->f.value = fp11.iv[0];
}
#else
- if (tree->f.fvalue[1]==0
- && tree->f.fvalue[2]==0
- && tree->f.fvalue[3]==0) {
+ if (tree->f.fvalue.l==0
+ && (tree->f.fvalue.h & 0xffff)==0) {
tree->t.op = SFCON;
- tree->f.value = tree->f.fvalue[0];
+ tree->f.value = (int)(tree->f.fvalue.h >> 16) & 0xffff;
}
#endif
}
#ifdef pdp11
tree->f.fvalue = subtre->l.lvalue;
#else
- /* setl */
- pdp11_setl();
- /* movif 4(r3),r0 */
- temp[0] = (uint16_t)((subtre->l.lvalue >> 16) & 0xffff);
- temp[1] = (uint16_t)(subtre->l.lvalue & 0xffff);
- pdp11_movif(0, temp, 063);
- /* seti */
- pdp11_seti();
- /* movf r0,6(r4) */
- pdp11_stf(0, tree->f.fvalue, 064);
+ tree->f.fvalue = fp_long_to_double(subtre->l.lvalue);
#endif
return(optim(tree));
}
else
tree->f.fvalue = subtre->c.value;
#else
+ /* revisit the unsigned case */
if (uns(subtre))
- temp_long = (_UNSIGNED_INT)subtre->c.value;
+ tree->f.fvalue = fp_long_to_double((_LONG)(_UNSIGNED_INT)subtre->c.value);
else
- temp_long = subtre->c.value;
- temp[0] = (uint16_t)((temp_long >> 16) & 0xffff);
- temp[1] = (uint16_t)(temp_long & 0xffff);
- /* setl */
- pdp11_setl();
- /* movif (sp)+,r0 */
- pdp11_movif(0, temp, 026);
- /* seti */
- pdp11_seti();
- /* movf r0,6(r4) */
- pdp11_stf(0, tree->f.fvalue, 064);
+ tree->f.fvalue = fp_int_to_double(subtre->c.value);
#endif
return(optim(tree));
}
#ifdef pdp11
subtre->f.fvalue = -subtre->f.fvalue;
#else
- pdp11_negf(subtre->f.fvalue, 065);
+ subtre->f.fvalue = fp_neg(subtre->f.fvalue);
#endif
return(subtre);
}
#ifdef pdp11
subtre->f.fvalue = -subtre->f.fvalue;
#else
- pdp11_negf(subtre->f.fvalue, 065);
+ subtre->f.fvalue = fp_neg(subtre->f.fvalue);
#endif
return(subtre);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "krcompat.h"
int tabflg;
int labno = 1;
char lbuf[BUFSIZ];
char *lbufp = lbuf;
-int main PARAMS((int argc, char **argv));
-int flag PARAMS((void));
-void put PARAMS((int c));
-void comment PARAMS((int c));
+#ifndef __P
+#ifdef __STDC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif
+
+int main __P((int argc, char **argv));
+int flag __P((void));
+void put __P((int c));
+void comment __P((int c));
int main(argc, argv) int argc; char **argv; {
/*
--- /dev/null
+#ifndef pdp11
+#include <errno.h>
+#include <stdlib.h>
+#include "c1.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 1
+#endif
+
+/* Floating point accumulators */
+
+#if 0
+/* PSW */
+
+#define PSW_V_C 0 /* condition codes */
+#define PSW_V_V 1
+#define PSW_V_Z 2
+#define PSW_V_N 3
+#endif
+
+/* FPS */
+
+#define FPS_V_C 0 /* condition codes */
+#define FPS_V_V 1
+#define FPS_V_Z 2
+#define FPS_V_N 3
+#define FPS_V_T 5 /* truncate */
+#define FPS_V_L 6 /* long */
+#define FPS_V_D 7 /* double */
+#define FPS_V_IC 8 /* ic err int */
+#define FPS_V_IV 9 /* overflo err int */
+#define FPS_V_IU 10 /* underflo err int */
+#define FPS_V_IUV 11 /* undef var err int */
+#define FPS_V_ID 14 /* int disable */
+#define FPS_V_ER 15 /* error */
+
+/* Floating point status register */
+
+#define FPS_ER (1u << FPS_V_ER) /* error */
+#define FPS_ID (1u << FPS_V_ID) /* interrupt disable */
+#define FPS_IUV (1u << FPS_V_IUV) /* int on undef var */
+#define FPS_IU (1u << FPS_V_IU) /* int on underflow */
+#define FPS_IV (1u << FPS_V_IV) /* int on overflow */
+#define FPS_IC (1u << FPS_V_IC) /* int on conv error */
+#define FPS_D (1u << FPS_V_D) /* single/double */
+#define FPS_L (1u << FPS_V_L) /* word/long */
+#define FPS_T (1u << FPS_V_T) /* round/truncate */
+#define FPS_N (1u << FPS_V_N)
+#define FPS_Z (1u << FPS_V_Z)
+#define FPS_V (1u << FPS_V_V)
+#define FPS_C (1u << FPS_V_C)
+#define FPS_CC (FPS_N + FPS_Z + FPS_V + FPS_C)
+#define FPS_RW (FPS_ER + FPS_ID + FPS_IUV + FPS_IU + FPS_IV + \
+ FPS_IC + FPS_D + FPS_L + FPS_T + FPS_CC)
+
+/* Floating point exception codes */
+
+#define FEC_OP 2 /* illegal op/mode */
+#define FEC_DZRO 4 /* divide by zero */
+#define FEC_ICVT 6 /* conversion error */
+#define FEC_OVFLO 8 /* overflow */
+#define FEC_UNFLO 10 /* underflow */
+#define FEC_UNDFV 12 /* undef variable */
+
+/* Floating point format, all assignments 32b relative */
+
+#define FP_V_SIGN (63 - 32) /* high lw: sign */
+#define FP_V_EXP (55 - 32) /* exponent */
+#define FP_V_HB FP_V_EXP /* hidden bit */
+#define FP_V_F0 (48 - 32) /* fraction 0 */
+#define FP_V_F1 (32 - 32) /* fraction 1 */
+#define FP_V_FROUND (31 - 32) /* f round point */
+#define FP_V_F2 16 /* low lw: fraction 2 */
+#define FP_V_F3 0 /* fraction 3 */
+#define FP_V_DROUND (-1) /* d round point */
+#define FP_M_EXP 0377
+#define FP_SIGN (1u << FP_V_SIGN)
+#define FP_EXP (FP_M_EXP << FP_V_EXP)
+#define FP_HB (1u << FP_V_HB)
+#define FP_FRACH ((1u << FP_V_HB) - 1)
+#define FP_FRACL 0xFFFFFFFF
+#define FP_BIAS 0200 /* exponent bias */
+#define FP_GUARD 3 /* guard bits */
+
+#if 0
+/* Data lengths */
+
+#define _WORD 2
+#define _LONG 4
+#define _QUAD 8
+#endif
+
+/* Double precision operations on 64b quantities */
+
+#define F_LOAD(qd,ac,ds) ds.h = ac.h; ds.l = (qd)? ac.l: 0
+#define F_LOAD_P(qd,ac,ds) ds->h = ac.h; ds->l = (qd)? ac.l: 0
+#define F_LOAD_FRAC(qd,ac,ds) ds.h = (ac.h & FP_FRACH) | FP_HB; \
+ ds.l = (qd)? ac.l: 0
+#define F_STORE(qd,sr,ac) ac.h = sr.h; if ((qd)) ac.l = sr.l
+#define F_STORE_P(qd,sr,ac) ac.h = sr->h; if ((qd)) ac.l = sr->l
+#define F_GET_FRAC_P(sr,ds) ds.l = sr->l; \
+ ds.h = (sr->h & FP_FRACH) | FP_HB
+#define F_ADD(s2,s1,ds) ds.l = (s1.l + s2.l) & 0xFFFFFFFF; \
+ ds.h = (s1.h + s2.h + (ds.l < s2.l)) & 0xFFFFFFFF
+#define F_SUB(s2,s1,ds) ds.h = (s1.h - s2.h - (s1.l < s2.l)) & 0xFFFFFFFF; \
+ ds.l = (s1.l - s2.l) & 0xFFFFFFFF
+#define F_LT(x,y) ((x.h < y.h) || ((x.h == y.h) && (x.l < y.l)))
+#define F_LT_AP(x,y) (((x->h & ~FP_SIGN) < (y->h & ~FP_SIGN)) || \
+ (((x->h & ~FP_SIGN) == (y->h & ~FP_SIGN)) && (x->l < y->l)))
+#define F_LSH_V(sr,n,ds) \
+ ds.h = (((n) >= 32)? (sr.l << ((n) - 32)): \
+ (sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
+ & 0xFFFFFFFF; \
+ ds.l = ((n) >= 32)? 0: (sr.l << (n)) & 0xFFFFFFFF
+#define F_RSH_V(sr,n,ds) \
+ ds.l = (((n) >= 32)? (sr.h >> ((n) - 32)) & and_mask[64 - (n)]: \
+ ((sr.l >> (n)) & and_mask[32 - (n)]) | \
+ (sr.h << (32 - (n)))) & 0xFFFFFFFF; \
+ ds.h = ((n) >= 32)? 0: \
+ ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
+
+/* For the constant shift macro, arguments must in the range [2,31] */
+
+#define F_LSH_1(ds) ds.h = ((ds.h << 1) | ((ds.l >> 31) & 1)) & 0xFFFFFFFF; \
+ ds.l = (ds.l << 1) & 0xFFFFFFFF
+#define F_RSH_1(ds) ds.l = ((ds.l >> 1) & 0x7FFFFFFF) | ((ds.h & 1) << 31); \
+ ds.h = ((ds.h >> 1) & 0x7FFFFFFF)
+#define F_LSH_K(sr,n,ds) \
+ ds.h = ((sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
+ & 0xFFFFFFFF; \
+ ds.l = (sr.l << (n)) & 0xFFFFFFFF
+#define F_RSH_K(sr,n,ds) \
+ ds.l = (((sr.l >> (n)) & and_mask[32 - (n)]) | \
+ (sr.h << (32 - (n)))) & 0xFFFFFFFF; \
+ ds.h = ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
+#define F_LSH_GUARD(ds) F_LSH_K(ds,FP_GUARD,ds)
+#define F_RSH_GUARD(ds) F_RSH_K(ds,FP_GUARD,ds)
+
+#define GET_BIT(ir,n) (((ir) >> (n)) & 1)
+#define GET_SIGN(ir) GET_BIT((ir), FP_V_SIGN)
+#define GET_EXP(ir) (((ir) >> FP_V_EXP) & FP_M_EXP)
+#define GET_SIGN_L(ir) GET_BIT((ir), 31)
+#define GET_SIGN_W(ir) GET_BIT((ir), 15)
+
+int32_t FEC = 0;
+int32_t FPS = FPS_D; /* default to double precision */
+
+_DOUBLE zero_fac = { 0, 0 };
+_DOUBLE one_fac = { 1, 0 };
+_DOUBLE fround_fac = { (1u << (FP_V_FROUND + 32)), 0 };
+_DOUBLE fround_guard_fac = { 0, (1u << (FP_V_FROUND + FP_GUARD)) };
+_DOUBLE dround_guard_fac = { (1u << (FP_V_DROUND + FP_GUARD)), 0 };
+_DOUBLE fmask_fac = { 0xFFFFFFFF, (1u << (FP_V_HB + FP_GUARD + 1)) - 1 };
+static const uint32_t and_mask[33] = { 0,
+ 0x1, 0x3, 0x7, 0xF,
+ 0x1F, 0x3F, 0x7F, 0xFF,
+ 0x1FF, 0x3FF, 0x7FF, 0xFFF,
+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
+ 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
+ 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
+ 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
+ 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF };
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(params) params
+#else
+#define __P(params) ()
+#endif
+#endif
+
+static void tstfp11 __P((_DOUBLE *fsrc));
+static void absfp11 __P((_DOUBLE *fsrc));
+static void negfp11 __P((_DOUBLE *fsrc));
+static void cmpfp11 __P((_DOUBLE *fac, _DOUBLE *fsrc));
+static int32_t moviefp11 __P((int32_t val, _DOUBLE *fac));
+static int32_t moveifp11 __P((_DOUBLE *val));
+static int32_t moviffp11 __P((int32_t val, _DOUBLE *fac));
+static int32_t movfifp11 __P((_DOUBLE *val, int32_t *dst));
+static int32_t addfp11 __P((_DOUBLE *facp, _DOUBLE *fsrcp));
+static int32_t mulfp11 __P((_DOUBLE *facp, _DOUBLE *fsrcp));
+static void frac_mulfp11 __P((_DOUBLE *f1p, _DOUBLE *f2p));
+static int32_t divfp11 __P((_DOUBLE *facp, _DOUBLE *fsrcp));
+static int32_t roundfp11 __P((_DOUBLE *fptr));
+static int32_t round_and_pack __P((_DOUBLE *facp, int32_t exp, _DOUBLE *fracp, int r));
+static int32_t fpnotrap __P((int32_t code));
+
+int fp_tst(val) _DOUBLE val; {
+ tstfp11(&val);
+ return (FPS & FPS_Z) != 0;
+}
+
+_DOUBLE fp_abs(val) _DOUBLE val; {
+ absfp11(&val);
+ return val;
+}
+
+_DOUBLE fp_neg(val) _DOUBLE val; {
+ negfp11(&val);
+ return val;
+}
+
+int fp_le(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ cmpfp11(&val0, &val1);
+ return (FPS & FPS_N) == 0;
+}
+
+int fp_ge(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ cmpfp11(&val1, &val0);
+ return (FPS & FPS_N) == 0;
+}
+
+int fp_gt(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ cmpfp11(&val0, &val1);
+ return (FPS & FPS_N) != 0;
+}
+
+int fp_lt(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ cmpfp11(&val1, &val0);
+ return (FPS & FPS_N) != 0;
+}
+
+_INT fp_double_to_int(val) _DOUBLE val; {
+ int32_t res;
+
+ if (movfifp11(&val, &res))
+ abort();
+ return (_INT)res;
+}
+
+_LONG fp_double_to_long(val) _DOUBLE val; {
+ int32_t res;
+
+ FPS |= FPS_L;
+ if (movfifp11(&val, &res))
+ abort();
+ FPS &= ~FPS_L;
+ return (_LONG)res;
+}
+
+_FLOAT fp_double_to_float(val) _DOUBLE val; {
+ _FLOAT res;
+
+ if (roundfp11(&val))
+ abort();
+ res.h = val.h;
+ return res;
+}
+
+_DOUBLE fp_int_to_double(val) _INT val; {
+ _DOUBLE res;
+
+ if (moviffp11((int32_t)val << 16, &res))
+ abort();
+ return res;
+}
+
+_DOUBLE fp_long_to_double(val) _LONG val; {
+ _DOUBLE res;
+
+ FPS |= FPS_L;
+ if (moviffp11((int32_t)val, &res))
+ abort();
+ FPS &= ~FPS_L;
+ return res;
+}
+
+_DOUBLE fp_float_to_double(val) _FLOAT val; {
+ _DOUBLE res;
+
+ res.h = val.h;
+ res.l = 0;
+ return res;
+}
+
+_DOUBLE fp_add(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ if (addfp11(&val0, &val1))
+ abort();
+ return val0;
+}
+
+_DOUBLE fp_sub(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ negfp11(&val1);
+ if (addfp11(&val0, &val1))
+ abort();
+ return val0;
+}
+
+_DOUBLE fp_mul(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ if (mulfp11(&val0, &val1))
+ abort();
+ return val0;
+}
+
+_DOUBLE fp_div(val0, val1) _DOUBLE val0; _DOUBLE val1; {
+ if (divfp11(&val0, &val1))
+ abort();
+ return val0;
+}
+
+_DOUBLE fp_ldexp(val, exp) _DOUBLE val; _INT exp; {
+ tstfp11(&val);
+ if ((FPS & FPS_Z) == 0 && moviefp11(moveifp11(&val) + (int32_t)exp, &val)) {
+ val.l = 0xFFFFFFFF;
+ val.h = ((FPS << (31 - FPS_V_N)) | 0x7FFFFFFF) & 0xFFFFFFFF;
+ errno = ERANGE;
+ }
+ return val;
+}
+
+/* cut-down routines by Nick, previously inline to instruction decode */
+static void tstfp11(fsrc) _DOUBLE *fsrc; {
+ FPS = FPS & ~FPS_CC;
+ if (GET_SIGN (fsrc->h)) FPS = FPS | FPS_N;
+ if (GET_EXP (fsrc->h) == 0) FPS = FPS | FPS_Z;
+}
+
+static void absfp11(fsrc) _DOUBLE *fsrc; {
+ if (GET_EXP (fsrc->h) == 0) *fsrc = zero_fac;
+ else fsrc->h = fsrc->h & ~FP_SIGN;
+}
+
+static void negfp11(fsrc) _DOUBLE *fsrc; {
+ if (GET_EXP (fsrc->h) == 0) *fsrc = zero_fac;
+ else fsrc->h = fsrc->h ^ FP_SIGN;
+}
+
+/* from PDP-11/70 processor manual:
+ * FC <- 0.
+ * FV <- 0.
+ * FZ <- 1 If (FSRC) - (AC) = 0, else FZ <- 0.
+ * FN <- 1 If (FSRC) - (AC) < 0, else FN <- 0.
+ * (backwards compared to what I expected)
+ */
+static void cmpfp11(fac, fsrc) _DOUBLE *fac; _DOUBLE *fsrc; {
+ if (GET_EXP (fsrc->h) == 0) *fsrc = zero_fac;
+ if (GET_EXP (fac->h) == 0) *fac = zero_fac;
+ if ((fsrc->h == fac->h) && (fsrc->l == fac->l)) { /* equal? */
+ FPS = (FPS & ~FPS_CC) | FPS_Z;
+ return; }
+ FPS = (FPS & ~FPS_CC) | ((fsrc->h >> (FP_V_SIGN - FPS_V_N)) & FPS_N);
+ if ((GET_SIGN (fsrc->h ^ fac->h) == 0) && (fac->h != 0) &&
+ F_LT ((*fsrc), (*fac))) FPS = FPS ^ FPS_N;
+}
+
+static int32_t moviefp11(val, fac) int32_t val; _DOUBLE *fac; {
+ fac->h = (fac->h & ~FP_EXP) | (((val + FP_BIAS) & FP_M_EXP) << FP_V_EXP);
+ if ((val > 0177) && (val <= 0177600)) {
+ if (val < 0100000) {
+ if (fpnotrap (FEC_OVFLO)) *fac = zero_fac;
+ return FPS_V; }
+ if (fpnotrap (FEC_UNFLO)) *fac = zero_fac; }
+ return 0;
+}
+
+static int32_t moveifp11(val) _DOUBLE *val; {
+ return (GET_EXP (val->h) - FP_BIAS) & 0177777;
+}
+
+static int32_t moviffp11(val, fac) int32_t val; _DOUBLE *fac; {
+ int32_t i, qdouble, leni;
+ int32_t exp, sign;
+
+ qdouble = FPS & FPS_D;
+ fac->l = val;
+ fac->h = 0;
+ if (fac->l) {
+ if (sign = GET_SIGN_L (fac->l)) fac->l = (fac->l ^ 0xFFFFFFFF) + 1;
+ for (i = 0; GET_SIGN_L (fac->l) == 0; i++) fac->l = fac->l << 1;
+ exp = ((FPS & FPS_L)? FP_BIAS + 32: FP_BIAS + 16) - i;
+ fac->h = (sign << FP_V_SIGN) | (exp << FP_V_EXP) |
+ ((fac->l >> (31 - FP_V_HB)) & FP_FRACH);
+ fac->l = (fac->l << (FP_V_HB + 1)) & FP_FRACL;
+ if ((FPS & (FPS_D + FPS_T)) == 0) return roundfp11 (fac); }
+ return 0;
+}
+
+static int32_t movfifp11(val, dst) _DOUBLE *val; int32_t *dst; {
+ int32_t i, qdouble, tolong;
+ int32_t exp, sign;
+ _DOUBLE fac, fsrc;
+ static const uint32_t i_limit[2][2] =
+ { { 0x80000000, 0x80010000 }, { 0x80000000, 0x80000001 } };
+
+ qdouble = FPS & FPS_D;
+ sign = GET_SIGN (val->h); /* get sign, */
+ exp = GET_EXP (val->h); /* exponent, */
+ F_LOAD_FRAC (qdouble, (*val), fac); /* fraction */
+ if (FPS & FPS_L) {
+ tolong = 1;
+ i = FP_BIAS + 32; }
+ else {
+ tolong = 0;
+ i = FP_BIAS + 16; }
+ if (exp <= FP_BIAS) *dst = 0;
+ else if (exp > i) {
+ *dst = 0;
+ fpnotrap (FEC_ICVT);
+ return FPS_V; }
+ F_RSH_V (fac, FP_V_HB + 1 + i - exp, fsrc);
+ if (!tolong) fsrc.l = fsrc.l & ~0177777;
+ if (fsrc.l >= i_limit[tolong][sign]) {
+ *dst = 0;
+ fpnotrap (FEC_ICVT);
+ return FPS_V; }
+ *dst = fsrc.l;
+ if (sign) *dst = -*dst;
+ return 0;
+}
+
+/* Floating point add
+
+ Inputs:
+ facp = pointer to src1 (output)
+ fsrcp = pointer to src2
+ Outputs:
+ ovflo = overflow variable
+*/
+
+static int32_t addfp11(facp, fsrcp) _DOUBLE *facp; _DOUBLE *fsrcp; {
+int32_t facexp, fsrcexp, ediff;
+_DOUBLE facfrac, fsrcfrac;
+
+if (F_LT_AP (facp, fsrcp)) { /* if !fac! < !fsrc! */
+ facfrac = *facp;
+ *facp = *fsrcp; /* swap operands */
+ *fsrcp = facfrac; }
+facexp = GET_EXP (facp->h); /* get exponents */
+fsrcexp = GET_EXP (fsrcp->h);
+if (facexp == 0) { /* fac = 0? */
+ *facp = fsrcexp? *fsrcp: zero_fac; /* result fsrc or 0 */
+ return 0; }
+if (fsrcexp == 0) return 0; /* fsrc = 0? no op */
+ediff = facexp - fsrcexp; /* exponent diff */
+if (ediff >= 60) return 0; /* too big? no op */
+F_GET_FRAC_P (facp, facfrac); /* get fractions */
+F_GET_FRAC_P (fsrcp, fsrcfrac);
+F_LSH_GUARD (facfrac); /* guard fractions */
+F_LSH_GUARD (fsrcfrac);
+if (GET_SIGN (facp->h) != GET_SIGN (fsrcp->h)) { /* signs different? */
+ if (ediff) { F_RSH_V (fsrcfrac, ediff, fsrcfrac); } /* sub, shf fsrc */
+ F_SUB (fsrcfrac, facfrac, facfrac); /* sub fsrc from fac */
+ if ((facfrac.h | facfrac.l) == 0) { /* result zero? */
+ *facp = zero_fac; /* no overflow */
+ return 0; }
+ if (ediff <= 1) { /* big normalize? */
+ if ((facfrac.h & (0x00FFFFFF << FP_GUARD)) == 0) {
+ F_LSH_K (facfrac, 24, facfrac);
+ facexp = facexp - 24; }
+ if ((facfrac.h & (0x00FFF000 << FP_GUARD)) == 0) {
+ F_LSH_K (facfrac, 12, facfrac);
+ facexp = facexp - 12; }
+ if ((facfrac.h & (0x00FC0000 << FP_GUARD)) == 0) {
+ F_LSH_K (facfrac, 6, facfrac);
+ facexp = facexp - 6; } }
+ while (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD) == 0) {
+ F_LSH_1 (facfrac);
+ facexp = facexp - 1; } }
+else { if (ediff) { F_RSH_V (fsrcfrac, ediff, fsrcfrac); } /* add, shf fsrc */
+ F_ADD (fsrcfrac, facfrac, facfrac); /* add fsrc to fac */
+ if (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD + 1)) {
+ F_RSH_1 (facfrac); /* carry out, shift */
+ facexp = facexp + 1; } }
+return round_and_pack (facp, facexp, &facfrac, 1);
+}
+
+/* Floating point multiply
+
+ Inputs:
+ facp = pointer to src1 (output)
+ fsrcp = pointer to src2
+ Outputs:
+ ovflo = overflow indicator
+*/
+
+static int32_t mulfp11(facp, fsrcp) _DOUBLE *facp; _DOUBLE *fsrcp; {
+int32_t facexp, fsrcexp;
+_DOUBLE facfrac, fsrcfrac;
+
+facexp = GET_EXP (facp->h); /* get exponents */
+fsrcexp = GET_EXP (fsrcp->h);
+if ((facexp == 0) || (fsrcexp == 0)) { /* test for zero */
+ *facp = zero_fac;
+ return 0; }
+F_GET_FRAC_P (facp, facfrac); /* get fractions */
+F_GET_FRAC_P (fsrcp, fsrcfrac);
+facexp = facexp + fsrcexp - FP_BIAS; /* calculate exp */
+facp->h = facp->h ^ fsrcp->h; /* calculate sign */
+frac_mulfp11 (&facfrac, &fsrcfrac); /* multiply fracs */
+
+/* Multiplying two numbers in the range [.5,1) produces a result in the
+ range [.25,1). Therefore, at most one bit of normalization is required
+ to bring the result back to the range [.5,1).
+*/
+
+if (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD) == 0) {
+ F_LSH_1 (facfrac);
+ facexp = facexp - 1; }
+return round_and_pack (facp, facexp, &facfrac, 1);
+}
+
+/* Fraction multiply
+
+ Inputs:
+ f1p = pointer to multiplier (output)
+ f2p = pointer to multiplicand fraction
+
+ Note: the inputs are unguarded; the output is guarded.
+
+ This routine performs a classic shift-and-add multiply. The low
+ order bit of the multiplier is tested; if 1, the multiplicand is
+ added into the high part of the double precision result. The
+ result and the multiplier are both shifted right 1.
+
+ For the 24b x 24b case, this routine develops 48b of result.
+ For the 56b x 56b case, this routine only develops the top 64b
+ of the the result. Because the inputs are normalized fractions,
+ the interesting part of the result is the high 56+guard bits.
+ Everything shifted off to the right, beyond 64b, plays no part
+ in rounding or the result.
+
+ There are many possible optimizations in this routine: scanning
+ for groups of zeroes, particularly in the 56b x 56b case; using
+ "extended multiply" capability if available in the hardware.
+*/
+
+static void frac_mulfp11(f1p, f2p) _DOUBLE *f1p; _DOUBLE *f2p; {
+_DOUBLE result, mpy, mpc;
+int32_t i;
+
+result = zero_fac; /* clear result */
+mpy = *f1p; /* get operands */
+mpc = *f2p;
+F_LSH_GUARD (mpc); /* guard multipicand */
+if ((mpy.l | mpc.l) == 0) { /* 24b x 24b? */
+ for (i = 0; i < 24; i++) {
+ if (mpy.h & 1) result.h = result.h + mpc.h;
+ F_RSH_1 (result);
+ mpy.h = mpy.h >> 1; } }
+else { if (mpy.l != 0) { /* 24b x 56b? */
+ for (i = 0; i < 32; i++) {
+ if (mpy.l & 1) { F_ADD (mpc, result, result); }
+ F_RSH_1 (result);
+ mpy.l = mpy.l >> 1; } }
+ for (i = 0; i < 24; i++) {
+ if (mpy.h & 1) { F_ADD (mpc, result, result); }
+ F_RSH_1 (result);
+ mpy.h = mpy.h >> 1; } }
+*f1p = result;
+return;
+}
+
+/* Floating point divide
+
+ Inputs:
+ facp = pointer to dividend (output)
+ fsrcp = pointer to divisor
+ Outputs:
+ ovflo = overflow indicator
+
+ Source operand must be checked for zero by caller!
+*/
+
+static int32_t divfp11(facp, fsrcp) _DOUBLE *facp; _DOUBLE *fsrcp; {
+int32_t facexp, fsrcexp, i, count, qd;
+_DOUBLE facfrac, fsrcfrac, quo;
+
+fsrcexp = GET_EXP (fsrcp->h); /* get divisor exp */
+facexp = GET_EXP (facp->h); /* get dividend exp */
+if (facexp == 0) { /* test for zero */
+ *facp = zero_fac; /* result zero */
+ return 0; }
+F_GET_FRAC_P (facp, facfrac); /* get fractions */
+F_GET_FRAC_P (fsrcp, fsrcfrac);
+F_LSH_GUARD (facfrac); /* guard fractions */
+F_LSH_GUARD (fsrcfrac);
+facexp = facexp - fsrcexp + FP_BIAS + 1; /* calculate exp */
+facp->h = facp->h ^ fsrcp->h; /* calculate sign */
+qd = FPS & FPS_D;
+count = FP_V_HB + FP_GUARD + (qd? 33: 1); /* count = 56b/24b */
+
+quo = zero_fac;
+for (i = count; (i > 0) && ((facfrac.h | facfrac.l) != 0); i--) {
+ F_LSH_1 (quo); /* shift quotient */
+ if (!F_LT (facfrac, fsrcfrac)) { /* divd >= divr? */
+ F_SUB (fsrcfrac, facfrac, facfrac); /* divd - divr */
+ if (qd) quo.l = quo.l | 1; /* double or single? */
+ else quo.h = quo.h | 1; }
+ F_LSH_1 (facfrac); } /* shift divd */
+if (i > 0) { F_LSH_V (quo, i, quo); } /* early exit? */
+
+/* Dividing two numbers in the range [.5,1) produces a result in the
+ range [.5,2). Therefore, at most one bit of normalization is required
+ to bring the result back to the range [.5,1). The choice of counts
+ and quotient bit positions makes this work correctly.
+*/
+
+if (GET_BIT (quo.h, FP_V_HB + FP_GUARD) == 0) {
+ F_LSH_1 (quo);
+ facexp = facexp - 1; }
+return round_and_pack (facp, facexp, &quo, 1);
+}
+
+/* Round (in place) floating point number to f_floating
+
+ Inputs:
+ fptr = pointer to floating number
+ Outputs:
+ ovflow = overflow
+*/
+
+static int32_t roundfp11(fptr) _DOUBLE *fptr; {
+_DOUBLE outf;
+
+outf = *fptr; /* get argument */
+F_ADD (fround_fac, outf, outf); /* round */
+if (GET_SIGN (outf.h ^ fptr->h)) { /* flipped sign? */
+ outf.h = (outf.h ^ FP_SIGN) & 0xFFFFFFFF; /* restore sign */
+ if (fpnotrap (FEC_OVFLO)) *fptr = zero_fac; /* if no int, clear */
+ else *fptr = outf; /* return rounded */
+ return FPS_V; } /* overflow */
+else { *fptr = outf; /* round was ok */
+ return 0; } /* no overflow */
+}
+
+/* Round result of calculation, test overflow, pack
+
+ Input:
+ facp = pointer to result, sign in place
+ exp = result exponent, right justified
+ fracp = pointer to result fraction, right justified with
+ guard bits
+ r = round (1) or truncate (0)
+ Outputs:
+ ovflo = overflow indicator
+*/
+
+static int32_t round_and_pack(facp, exp, fracp, r) _DOUBLE *facp; int32_t exp; _DOUBLE *fracp; int r; {
+_DOUBLE frac;
+
+frac = *fracp; /* get fraction */
+if (r && ((FPS & FPS_T) == 0)) {
+ if (FPS & FPS_D) { F_ADD (dround_guard_fac, frac, frac); }
+ else { F_ADD (fround_guard_fac, frac, frac); }
+ if (GET_BIT (frac.h, FP_V_HB + FP_GUARD + 1)) {
+ F_RSH_1 (frac);
+ exp = exp + 1; } }
+F_RSH_GUARD (frac);
+facp->l = frac.l & FP_FRACL;
+facp->h = (facp->h & FP_SIGN) | ((exp & FP_M_EXP) << FP_V_EXP) |
+ (frac.h & FP_FRACH);
+if (exp > 0377) {
+ if (fpnotrap (FEC_OVFLO)) *facp = zero_fac;
+ return FPS_V; }
+if ((exp <= 0) && (fpnotrap (FEC_UNFLO))) *facp = zero_fac;
+return 0;
+}
+
+/* Process floating point exception
+
+ Inputs:
+ code = exception code
+ Outputs:
+ int = FALSE if interrupt enabled, TRUE if disabled
+*/
+
+static int32_t fpnotrap(code) int32_t code; {
+static const int32_t test_code[] = { 0, 0, 0, FPS_IC, FPS_IV, FPS_IU, FPS_IUV };
+
+if ((code >= FEC_ICVT) && (code <= FEC_UNDFV) &&
+ ((FPS & test_code[code >> 1]) == 0)) return TRUE;
+FPS = FPS | FPS_ER;
+FEC = code;
+/*FEA = (backup_PC - 2) & 0177777;*/
+/*if ((FPS & FPS_ID) == 0) setTRAP (TRAP_FPE);*/
+return FALSE;
+}
+#endif
--- /dev/null
+#ifndef pdp11
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)atof.c 2.2 (Berkeley) 1/22/87";
+#endif
+
+/*
+ * C library - ascii to floating
+ */
+
+#include <ctype.h>
+#include "c1.h"
+
+/*#define HUGE 1.701411733192644270e38*/
+#define LOGHUGE 39
+
+_DOUBLE fp_atof(p) register char *p; {
+ register int c;
+ _DOUBLE fl, flexp, exp5;
+ _DOUBLE big = { 0, 056200 << 16 }; /*= 72057594037927936.;*/ /*2^56*/
+ _DOUBLE ten = { 0, 041040 << 16 }; /*= 10.;*/
+ /*_DOUBLE fp_ldexp();*/
+ int nd;
+ register int eexp, exp, neg, negexp, bexp;
+
+ neg = 1;
+ while((c = *p++) == ' ')
+ ;
+ if (c == '-')
+ neg = -1;
+ else if (c=='+')
+ ;
+ else
+ --p;
+
+ exp = 0;
+ /*fl = 0;*/ fl.l = 0; fl.h = 0;
+ nd = 0;
+ while ((c = *p++), isdigit(c)) {
+ if (fp_lt(fl, big))
+ fl = fp_add(fp_mul(ten, fl), fp_int_to_double(c-'0'));
+ else
+ exp++;
+ nd++;
+ }
+
+ if (c == '.') {
+ while ((c = *p++), isdigit(c)) {
+ if (fp_lt(fl, big)) {
+ fl = fp_add(fp_mul(ten, fl), fp_int_to_double(c-'0'));
+ exp--;
+ }
+ nd++;
+ }
+ }
+
+ negexp = 1;
+ eexp = 0;
+ if ((c == 'E') || (c == 'e')) {
+ if ((c= *p++) == '+')
+ ;
+ else if (c=='-')
+ negexp = -1;
+ else
+ --p;
+
+ while ((c = *p++), isdigit(c)) {
+ eexp = 10*eexp+(c-'0');
+ }
+ if (negexp<0)
+ eexp = -eexp;
+ exp = exp + eexp;
+ }
+
+ negexp = 1;
+ if (exp<0) {
+ negexp = -1;
+ exp = -exp;
+ }
+
+
+ if((nd+exp*negexp) < -LOGHUGE){
+ /*fl = 0;*/ fl.l = 0; fl.h = 0;
+ exp = 0;
+ }
+ /*flexp = 1;*/ flexp.l = 0; flexp.h = 040200 << 16;
+ /*exp5 = 5;*/ exp5.l = 0; exp5.h = 040640 << 16;
+ bexp = exp;
+ for (;;) {
+ if (exp&01)
+ flexp = fp_mul(flexp, exp5);
+ exp >>= 1;
+ if (exp==0)
+ break;
+ exp5 = fp_mul(exp5, exp5);
+ }
+ if (negexp<0)
+ fl = fp_div(fl, flexp);
+ else
+ fl = fp_mul(fl, flexp);
+ fl = fp_ldexp(fl, negexp*bexp);
+ if (neg<0)
+ fl = fp_neg(fl);
+ return(fl);
+}
+#endif
+++ /dev/null
-#ifndef _KRCOMPAT_H
-#define _KRCOMPAT_H 1
-
-#undef PARAMS
-#ifdef __STDC__
-#include <stdarg.h>
-#define VA_START(ap, arg) va_start(ap, arg)
-#define PARAMS(args) args
-#else
-#include <varargs.h>
-#define VA_START(ap, arg) va_start(ap)
-#define PARAMS(args) ()
-#endif
-
-#ifdef __GNUC__
-#define NORETURN __attribute__ ((noreturn))
-#else
-#define NORETURN
-#endif
-
-#endif
#!/bin/sh
-ROOT="`pwd |sed -e 's/\/lib\/ccom$//'`"
-HOSTCC="cc -g -I$ROOT/cross/usr/include -L$ROOT/cross/usr/lib/ -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-format -Wno-maybe-uninitialized -Wno-parentheses -Wno-unused-result"
-INSTALL="$ROOT/scripts/install.sh --strip-program=/bin/true"
-MANROFF="nroff -man"
-mkdir --parents "$ROOT/cross/lib"
-make CC="$HOSTCC" MANROFF="$MANROFF" LDC0FLAGS= LDC1FLAGS= PURFLAG= && \
-make INSTALL="$INSTALL" DESTDIR="$ROOT/cross" install
+make CFLAGS=-g LDC0FLAGS= LDC1FLAGS= "$@"
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)atof.c 2.2 (Berkeley) 1/22/87";
-#endif
-
-/*
- * C library - ascii to floating
- */
-
-#ifndef pdp11
-#include <math.h>
-#include <ctype.h>
-#include "c1.h"
-
-/*#define HUGE 1.701411733192644270e38*/
-#define LOGHUGE 39
-
-void pdp11_atof(p) char *p; {
- register int c;
-#if 1
- uint16_t fl[4], flexp[4], exp5[4];
- uint16_t big[4], temp;
-#else
- double fl, flexp, exp5;
- double big = 72057594037927936.; /*2^56*/
-#endif
- int nd;
- register int eexp, exp, neg, negexp, bexp;
-
-#if 1
- /* movf $56200,r0 */
- temp = 056200;
- pdp11_ldf(0, &temp, 027);
- /* movf r0,-50(r5) */
- pdp11_stf(0, big, 065);
-#endif
- neg = 1;
- while((c = *p++) == ' ')
- ;
- if (c == '-')
- neg = -1;
- else if (c=='+')
- ;
- else
- --p;
-
- exp = 0;
-#if 1
- /* clrf -20(r5) */
- pdp11_clrf(fl, 065);
-#else
- fl = 0;
-#endif
- nd = 0;
- while ((c = *p++), isdigit(c)) {
-#if 1
- /* movf -20(r5),r0 */
- pdp11_ldf(0, fl, 065);
- /* cmpf -50(r5),r0 */
- pdp11_cmpf(0, big, 065);
- /* cfcc */
- pdp11_cfcc();
- /* jle L12 */
- if ((Z | (N ^ V)) == 0) {
-#else
- if (fl<big) {
-#endif
-#if 1
- /* movf $41040,r0 */
- temp = 041040;
- pdp11_ldf(0, &temp, 027);
- /* mulf -20(r5),r0 */
- pdp11_mulf(0, fl, 065);
- /* mov r3,r1 */
- /* add $-60,r1 */
- R[1] = c - '0';
- /* movif r1,r1 */
- pdp11_movif(1, NULL, 1);
- /* addf r1,r0 */
- pdp11_addf(0, NULL, 1);
- /* movf r0,-20(r5) */
- pdp11_stf(0, fl, 065);
-#else
- fl = 10*fl + (c-'0');
-#endif
- } else
- exp++;
- nd++;
- }
-
- if (c == '.') {
- while ((c = *p++), isdigit(c)) {
-#if 1
- /* movf -20(r5),r0 */
- pdp11_ldf(0, fl, 065);
- /* cmpf -50(r5),r0 */
- pdp11_cmpf(0, big, 065);
- /* cfcc */
- pdp11_cfcc();
- /* jle L17 */
- if ((Z | (N ^ V)) == 0) {
-#else
- if (fl<big) {
-#endif
-#if 1
- /* movf $41040,r0 */
- temp = 041040;
- pdp11_ldf(0, &temp, 027);
- /* mulf -20(r5),r0 */
- pdp11_mulf(0, fl, 065);
- /* mov r3,r1 */
- /* add $-60,r1 */
- R[1] = c - '0';
- /* movif r1,r1 */
- pdp11_movif(1, NULL, 1);
- /* addf r1,r0 */
- pdp11_addf(0, NULL, 1);
- /* movf r0,-20(r5) */
- pdp11_stf(0, fl, 065);
-#else
- fl = 10*fl + (c-'0');
-#endif
- exp--;
- }
- nd++;
- }
- }
-
- negexp = 1;
- eexp = 0;
- if ((c == 'E') || (c == 'e')) {
- if ((c= *p++) == '+')
- ;
- else if (c=='-')
- negexp = -1;
- else
- --p;
-
- while ((c = *p++), isdigit(c)) {
- eexp = 10*eexp+(c-'0');
- }
- if (negexp<0)
- eexp = -eexp;
- exp = exp + eexp;
- }
-
- negexp = 1;
- if (exp<0) {
- negexp = -1;
- exp = -exp;
- }
-
-
- if((nd+exp*negexp) < -LOGHUGE){
-#if 1
- /* clf -20(r5) */
- pdp11_clrf(fl, 065);
-#else
- fl = 0;
-#endif
- exp = 0;
- }
-#if 1
- /* movf $40200,r0 */
- temp = 040200;
- pdp11_ldf(0, &temp, 027);
- /* movf r0,-30(r5) */
- pdp11_stf(0, flexp, 065);
-#else
- flexp = 1;
-#endif
-#if 1
- /* movf $40640,r0 */
- temp = 040640;
- pdp11_ldf(0, &temp, 027);
- /* movf r0,-40(r5) */
- pdp11_stf(0, exp5, 065);
-#else
- exp5 = 5;
-#endif
- bexp = exp;
- for (;;) {
- if (exp&01) {
-#if 1
- /* movf -30(r5),r0 */
- pdp11_ldf(0, flexp, 065);
- /* mulf -40(r5),r0 */
- pdp11_mulf(0, exp5, 065);
- /* movf r0,-30(r5) */
- pdp11_stf(0, flexp, 065);
-#else
- flexp *= exp5;
-#endif
- }
- exp >>= 1;
- if (exp==0)
- break;
-#if 1
- /* movf -40(r5),r0 */
- pdp11_ldf(0, exp5, 065);
- /* mulf r0,r0 */
- pdp11_mulf(0, NULL, 0);
- /* movf r0,-40(r5) */
- pdp11_stf(0, exp5, 065);
-#else
- exp5 *= exp5;
-#endif
- }
-#if 1
- /* movf -20(r5),r0 */
- pdp11_ldf(0, fl, 065);
-#endif
- if (negexp<0)
-#if 1
- /* divf -30(r5),r0 */
- pdp11_divf(0, flexp, 065);
-#else
- fl /= flexp;
-#endif
- else
-#if 1
- /* mulf -30(r5),r0 */
- pdp11_mulf(0, flexp, 065);
-#else
- fl *= flexp;
-#endif
-#if 1
- /* movf r0,-20(r5) */
- pdp11_stf(0, fl, 065);
-#endif
-#if 1
- pdp11_ldexp(fl, negexp * bexp);
-#else
- fl = ldexp(fl, negexp*bexp);
-#endif
- if (neg<0) {
-#if 1
- /* negf r0 */
- pdp11_negf(NULL, 0);
-#else
- fl = -fl;
-#endif
- }
-#if 0
- return(fl);
-#endif
-}
-#endif
+++ /dev/null
-/* pdp11_fp.c: PDP-11 floating point simulator (32b version)
-
- Copyright (c) 1993-2004, Robert M Supnik
-
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name of Robert M Supnik shall not
- be used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from Robert M Supnik.
-
- 04-Oct-04 RMS Added FIS instructions
- 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict
- 08-Oct-02 RMS Fixed macro definitions
- 05-Jun-98 RMS Fixed implementation specific shift bugs
- 20-Apr-98 RMS Fixed bug in MODf integer truncation
- 17-Apr-98 RMS Fixed bug in STCfi range check
- 16-Apr-98 RMS Fixed bugs in STEXP, STCfi, round/pack
- 09-Apr-98 RMS Fixed bug in LDEXP
- 04-Apr-98 RMS Fixed bug in MODf condition codes
-
- This module simulates the PDP-11 floating point unit (FP11 series).
- It is called from the instruction decoder for opcodes 170000:177777.
-
- The floating point unit recognizes three instruction formats:
-
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ no operand
- | 1 1 1 1| 0 0 0 0 0 0| opcode | 170000:
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 170077
-
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ one operand
- | 1 1 1 1| 0 0 0| opcode | dest spec | 170100:
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 170777
-
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ register + operand
- | 1 1 1 1| opcode | fac | dest spec | 171000:
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 177777
-
- The instruction space is further extended through use of the floating
- point status register (FPS) mode bits. Three mode bits affect how
- instructions are interpreted:
-
- FPS_D if 0, floating registers are single precision
- if 1, floating registers are double precision
-
- FPS_L if 0, integer operands are word
- if 1, integer operands are longword
-
- FPS_T if 0, floating operations are rounded
- if 1, floating operations are truncated
-
- FPS also contains the condition codes for the floating point unit,
- and exception enable bits for individual error conditions. Exceptions
- cause a trap through 0244, unless the individual exception, or all
- exceptions, are disabled. Illegal address mode, undefined variable,
- and divide by zero abort the current instruction; all other exceptions
- permit the instruction to complete. (Aborts are implemented as traps
- that request an "interrupt" trap. If an interrupt is pending, it is
- serviced; if not, trap_req is updated and processing continues.)
-
- Floating point specifiers are similar to integer specifiers, with
- the length of the operand being up to 8 bytes. In two specific cases,
- the floating point unit reads or writes only two bytes, rather than
- the length specified by the operand type:
-
- register for integers, only 16b are accessed; if the
- operand is 32b, these are the high order 16b
- of the operand
-
- immediate for integers or floating point, only 16b are
- accessed; if the operand is 32b or 64b, these
- are the high order 16b of the operand
-*/
-
-#ifndef pdp11
-#include "c1.h"
-
-/* Ultra hacks to be fixed later */
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 1
-#endif
-#define ABORT(arg) return
-
-/* Floating point accumulators */
-
-struct fpac {
- uint32_t l; /* low 32b */
- uint32_t h; /* high 32b */
-};
-typedef struct fpac fpac_t;
-
-/* PSW */
-
-#define PSW_V_C 0 /* condition codes */
-#define PSW_V_V 1
-#define PSW_V_Z 2
-#define PSW_V_N 3
-#
-/* FPS */
-
-#define FPS_V_C 0 /* condition codes */
-#define FPS_V_V 1
-#define FPS_V_Z 2
-#define FPS_V_N 3
-#define FPS_V_T 5 /* truncate */
-#define FPS_V_L 6 /* long */
-#define FPS_V_D 7 /* double */
-#define FPS_V_IC 8 /* ic err int */
-#define FPS_V_IV 9 /* overflo err int */
-#define FPS_V_IU 10 /* underflo err int */
-#define FPS_V_IUV 11 /* undef var err int */
-#define FPS_V_ID 14 /* int disable */
-#define FPS_V_ER 15 /* error */
-
-/* Floating point status register */
-
-#define FPS_ER (1u << FPS_V_ER) /* error */
-#define FPS_ID (1u << FPS_V_ID) /* interrupt disable */
-#define FPS_IUV (1u << FPS_V_IUV) /* int on undef var */
-#define FPS_IU (1u << FPS_V_IU) /* int on underflow */
-#define FPS_IV (1u << FPS_V_IV) /* int on overflow */
-#define FPS_IC (1u << FPS_V_IC) /* int on conv error */
-#define FPS_D (1u << FPS_V_D) /* single/double */
-#define FPS_L (1u << FPS_V_L) /* word/long */
-#define FPS_T (1u << FPS_V_T) /* round/truncate */
-#define FPS_N (1u << FPS_V_N)
-#define FPS_Z (1u << FPS_V_Z)
-#define FPS_V (1u << FPS_V_V)
-#define FPS_C (1u << FPS_V_C)
-#define FPS_CC (FPS_N + FPS_Z + FPS_V + FPS_C)
-#define FPS_RW (FPS_ER + FPS_ID + FPS_IUV + FPS_IU + FPS_IV + \
- FPS_IC + FPS_D + FPS_L + FPS_T + FPS_CC)
-
-/* Floating point exception codes */
-
-#define FEC_OP 2 /* illegal op/mode */
-#define FEC_DZRO 4 /* divide by zero */
-#define FEC_ICVT 6 /* conversion error */
-#define FEC_OVFLO 8 /* overflow */
-#define FEC_UNFLO 10 /* underflow */
-#define FEC_UNDFV 12 /* undef variable */
-
-/* Floating point format, all assignments 32b relative */
-
-#define FP_V_SIGN (63 - 32) /* high lw: sign */
-#define FP_V_EXP (55 - 32) /* exponent */
-#define FP_V_HB FP_V_EXP /* hidden bit */
-#define FP_V_F0 (48 - 32) /* fraction 0 */
-#define FP_V_F1 (32 - 32) /* fraction 1 */
-#define FP_V_FROUND (31 - 32) /* f round point */
-#define FP_V_F2 16 /* low lw: fraction 2 */
-#define FP_V_F3 0 /* fraction 3 */
-#define FP_V_DROUND (-1) /* d round point */
-#define FP_M_EXP 0377
-#define FP_SIGN (1u << FP_V_SIGN)
-#define FP_EXP (FP_M_EXP << FP_V_EXP)
-#define FP_HB (1u << FP_V_HB)
-#define FP_FRACH ((1u << FP_V_HB) - 1)
-#define FP_FRACL 0xFFFFFFFF
-#define FP_BIAS 0200 /* exponent bias */
-#define FP_GUARD 3 /* guard bits */
-
-/* Data lengths */
-
-#define NICK_WORD 2
-#define NICK_LONG 4
-#define NICK_QUAD 8
-
-/* Double precision operations on 64b quantities */
-
-#define F_LOAD(qd,ac,ds) ds.h = ac.h; ds.l = (qd)? ac.l: 0
-#define F_LOAD_P(qd,ac,ds) ds->h = ac.h; ds->l = (qd)? ac.l: 0
-#define F_LOAD_FRAC(qd,ac,ds) ds.h = (ac.h & FP_FRACH) | FP_HB; \
- ds.l = (qd)? ac.l: 0
-#define F_STORE(qd,sr,ac) ac.h = sr.h; if ((qd)) ac.l = sr.l
-#define F_STORE_P(qd,sr,ac) ac.h = sr->h; if ((qd)) ac.l = sr->l
-#define F_GET_FRAC_P(sr,ds) ds.l = sr->l; \
- ds.h = (sr->h & FP_FRACH) | FP_HB
-#define F_ADD(s2,s1,ds) ds.l = (s1.l + s2.l) & 0xFFFFFFFF; \
- ds.h = (s1.h + s2.h + (ds.l < s2.l)) & 0xFFFFFFFF
-#define F_SUB(s2,s1,ds) ds.h = (s1.h - s2.h - (s1.l < s2.l)) & 0xFFFFFFFF; \
- ds.l = (s1.l - s2.l) & 0xFFFFFFFF
-#define F_LT(x,y) ((x.h < y.h) || ((x.h == y.h) && (x.l < y.l)))
-#define F_LT_AP(x,y) (((x->h & ~FP_SIGN) < (y->h & ~FP_SIGN)) || \
- (((x->h & ~FP_SIGN) == (y->h & ~FP_SIGN)) && (x->l < y->l)))
-#define F_LSH_V(sr,n,ds) \
- ds.h = (((n) >= 32)? (sr.l << ((n) - 32)): \
- (sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
- & 0xFFFFFFFF; \
- ds.l = ((n) >= 32)? 0: (sr.l << (n)) & 0xFFFFFFFF
-#define F_RSH_V(sr,n,ds) \
- ds.l = (((n) >= 32)? (sr.h >> ((n) - 32)) & and_mask[64 - (n)]: \
- ((sr.l >> (n)) & and_mask[32 - (n)]) | \
- (sr.h << (32 - (n)))) & 0xFFFFFFFF; \
- ds.h = ((n) >= 32)? 0: \
- ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
-
-/* For the constant shift macro, arguments must in the range [2,31] */
-
-#define F_LSH_1(ds) ds.h = ((ds.h << 1) | ((ds.l >> 31) & 1)) & 0xFFFFFFFF; \
- ds.l = (ds.l << 1) & 0xFFFFFFFF
-#define F_RSH_1(ds) ds.l = ((ds.l >> 1) & 0x7FFFFFFF) | ((ds.h & 1) << 31); \
- ds.h = ((ds.h >> 1) & 0x7FFFFFFF)
-#define F_LSH_K(sr,n,ds) \
- ds.h = ((sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
- & 0xFFFFFFFF; \
- ds.l = (sr.l << (n)) & 0xFFFFFFFF
-#define F_RSH_K(sr,n,ds) \
- ds.l = (((sr.l >> (n)) & and_mask[32 - (n)]) | \
- (sr.h << (32 - (n)))) & 0xFFFFFFFF; \
- ds.h = ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
-#define F_LSH_GUARD(ds) F_LSH_K(ds,FP_GUARD,ds)
-#define F_RSH_GUARD(ds) F_RSH_K(ds,FP_GUARD,ds)
-
-#define GET_BIT(ir,n) (((ir) >> (n)) & 1)
-#define GET_SIGN(ir) GET_BIT((ir), FP_V_SIGN)
-#define GET_EXP(ir) (((ir) >> FP_V_EXP) & FP_M_EXP)
-#define GET_SIGN_L(ir) GET_BIT((ir), 31)
-#define GET_SIGN_W(ir) GET_BIT((ir), 15)
-
-#if 1
-int32_t FEC = 0;
-int32_t FPS = FPS_D; /* default to double precision */
-int N, Z, V, C;
-int R[8];
-fpac_t FR[6];
-#else
-extern jmp_buf save_env;
-extern int32_t cpu_type;
-extern int32_t FEC, FEA, FPS;
-extern int32_t CPUERR, trap_req;
-extern int32_t N, Z, V, C;
-extern int32_t R[8];
-extern int32_t STKLIM;
-extern int32_t cm, isenable, dsenable, MMR0, MMR1;
-extern fpac_t FR[6];
-#endif
-
-fpac_t zero_fac = { 0, 0 };
-fpac_t one_fac = { 1, 0 };
-fpac_t fround_fac = { (1u << (FP_V_FROUND + 32)), 0 };
-fpac_t fround_guard_fac = { 0, (1u << (FP_V_FROUND + FP_GUARD)) };
-fpac_t dround_guard_fac = { (1u << (FP_V_DROUND + FP_GUARD)), 0 };
-fpac_t fmask_fac = { 0xFFFFFFFF, (1u << (FP_V_HB + FP_GUARD + 1)) - 1 };
-static const uint32_t and_mask[33] = { 0,
- 0x1, 0x3, 0x7, 0xF,
- 0x1F, 0x3F, 0x7F, 0xFF,
- 0x1FF, 0x3FF, 0x7FF, 0xFFF,
- 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
- 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
- 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
- 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
- 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF };
-#if 0
-int32_t backup_PC;
-#endif
-int32_t fpnotrap PARAMS((int32_t code));
-int32_t GeteaFP PARAMS((int32_t spec, int32_t len));
-
-static uint32_t ReadI PARAMS((uint16_t *va, int32_t spec, int32_t len));
-static void ReadFP PARAMS((fpac_t *fac, uint16_t *va, int32_t spec, int32_t len));
-static void WriteI PARAMS((int32_t data, uint16_t *va, int32_t spec, int32_t len));
-static void WriteFP PARAMS((fpac_t *data, uint16_t *va, int32_t spec, int32_t len));
-static int32_t setfcc PARAMS((int32_t old_status, int32_t result_high, int32_t newV));
-static int32_t addfp11 PARAMS((fpac_t *src1, fpac_t *src2));
-static int32_t mulfp11 PARAMS((fpac_t *src1, fpac_t *src2));
-static int32_t divfp11 PARAMS((fpac_t *src1, fpac_t *src2));
-#if 0
-static int32_t modfp11 PARAMS((fpac_t *src1, fpac_t *src2, fpac_t *frac));
-#endif
-static void frac_mulfp11 PARAMS((fpac_t *src1, fpac_t *src2));
-static int32_t roundfp11 PARAMS((fpac_t *src));
-static int32_t round_and_pack PARAMS((fpac_t *fac, int32_t exp, fpac_t *frac, int r));
-
-#if 0
-extern int32_t GeteaW (int32_t spec);
-extern int32_t ReadW (int32_t addr);
-extern void WriteW (int32_t data, int32_t addr);
-extern void set_stack_trap (int32_t adr);
-#endif
-
-/* Set up for instruction decode and execution */
-
-#if 0
-void fp11 (int32_t IR)
-{
-int32_t dst, ea, ac, dstspec;
-int32_t i, qdouble, lenf, leni;
-int32_t newV, exp, sign;
-fpac_t fac, fsrc, modfrac;
-static const uint32_t i_limit[2][2] =
- { { 0x80000000, 0x80010000 }, { 0x80000000, 0x80000001 } };
-
-backup_PC = PC; /* save PC for FEA */
-ac = (IR >> 6) & 03; /* fac is IR<7:6> */
-dstspec = IR & 077;
-qdouble = FPS & FPS_D;
-lenf = qdouble? NICK_QUAD: NICK_LONG;
-switch ((IR >> 8) & 017) { /* decode IR<11:8> */
-case 0:
- switch (ac) { /* decode IR<7:6> */
- case 0: /* specials */
- if (IR == 0170000) { /* CFCC */
-#endif
-
-void pdp11_cfcc() {
- N = (FPS >> PSW_V_N) & 1;
- Z = (FPS >> PSW_V_Z) & 1;
- V = (FPS >> PSW_V_V) & 1;
- C = (FPS >> PSW_V_C) & 1;
-}
-
-#if 0
- }
- else if (IR == 0170001) /* SETF */
- FPS = FPS & ~FPS_D;
- else if (IR == 0170002) /* SETI */
-#endif
-
-void pdp11_seti() {
- FPS = FPS & ~FPS_L;
-}
-
-#if 0
- else if (IR == 0170011) /* SETD */
- FPS = FPS | FPS_D;
- else if (IR == 0170012) /* SETL */
-#endif
-
-void pdp11_setl() {
- FPS = FPS | FPS_L;
-}
-
-#if 0
- else fpnotrap (FEC_OP);
- break;
- case 1: /* LDFPS */
- dst = (dstspec <= 07)? R[dstspec]: ReadW (GeteaW (dstspec));
- FPS = dst & FPS_RW;
- break;
- case 2: /* STFPS */
- FPS = FPS & FPS_RW;
- if (dstspec <= 07) R[dstspec] = FPS;
- else WriteW (FPS, GeteaW (dstspec));
- break;
- case 3: /* STST */
- if (dstspec <= 07) R[dstspec] = FEC;
- else WriteI ((FEC << 16) | FEA, GeteaFP (dstspec, NICK_LONG),
- dstspec, NICK_LONG);
- break; } /* end switch <7:6> */
- break; /* end case 0 */
-
-/* "Easy" instructions */
-
-case 1:
- switch (ac) { /* decode IR<7:6> */
- case 0: /* CLRf */
-#endif
-
-void pdp11_clrf(va, dstspec) uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- WriteFP (&zero_fac, va, dstspec, lenf);
- FPS = (FPS & ~FPS_CC) | FPS_Z;
-}
-
-#if 0
- break;
- case 1: /* TSTf */
- ReadFP (&fsrc, GeteaFP (dstspec, lenf), dstspec, lenf);
- FPS = setfcc (FPS, fsrc.h, 0);
- break;
- case 2: /* ABSf */
- ReadFP (&fsrc, ea = GeteaFP (dstspec, lenf), dstspec, lenf);
- if (GET_EXP (fsrc.h) == 0) fsrc = zero_fac;
- else fsrc.h = fsrc.h & ~FP_SIGN;
- WriteFP (&fsrc, ea, dstspec, lenf);
- FPS = setfcc (FPS, fsrc.h, 0);
- break;
- case 3: /* NEGf */
-#endif
-
-void pdp11_negf(va, dstspec) uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- fpac_t fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- if (GET_EXP (fsrc.h) == 0) fsrc = zero_fac;
- else fsrc.h = fsrc.h ^ FP_SIGN;
- WriteFP (&fsrc, va, dstspec, lenf);
- FPS = setfcc (FPS, fsrc.h, 0);
-}
-
-#if 0
- break; } /* end switch <7:6> */
- break; /* end case 1 */
-case 5: /* LDf */
-#endif
-
-void pdp11_ldf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- fpac_t fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- F_STORE (qdouble, fsrc, FR[ac]);
- FPS = setfcc (FPS, fsrc.h, 0);
-}
-
-#if 0
- break;
-case 010: /* STf */
-#endif
-
-void pdp11_stf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- fpac_t fac;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- F_LOAD (qdouble, FR[ac], fac);
- WriteFP (&fac, va, dstspec, lenf);
-}
-
-#if 0
- break;
-case 017: /* LDCff' */
-#endif
-
-void pdp11_ldcfo(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- int32_t newV;
- fpac_t fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, 12 - lenf);
- if (GET_EXP (fsrc.h) == 0) fsrc = zero_fac;
- if ((FPS & (FPS_D + FPS_T)) == 0) newV = roundfp11 (&fsrc);
- else newV = 0;
- F_STORE (qdouble, fsrc, FR[ac]);
- FPS = setfcc (FPS, fsrc.h, newV);
-}
-
-#if 0
- break;
-case 014: /* STCff' */
-#endif
-
-void pdp11_stcfo(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- int32_t newV;
- fpac_t fac;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- F_LOAD (qdouble, FR[ac], fac);
- if (GET_EXP (fac.h) == 0) fac = zero_fac;
- if ((FPS & (FPS_D + FPS_T)) == FPS_D) newV = roundfp11 (&fac);
- else newV = 0;
- WriteFP (&fac, va, dstspec, 12 - lenf);
- FPS = setfcc (FPS, fac.h, newV);
-}
-
-#if 0
- break;
-
-/* Compare instruction */
-
-case 7: /* CMPf */
-#endif
-
-void pdp11_cmpf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- fpac_t fac, fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- if (GET_EXP (fsrc.h) == 0) fsrc = zero_fac;
- if (GET_EXP (fac.h) == 0) fac = zero_fac;
- if ((fsrc.h == fac.h) && (fsrc.l == fac.l)) { /* equal? */
- FPS = (FPS & ~FPS_CC) | FPS_Z;
- if ((fsrc.h | fsrc.l) == 0) { /* zero? */
- F_STORE (qdouble, zero_fac, FR[ac]); }
- return; }
- FPS = (FPS & ~FPS_CC) | ((fsrc.h >> (FP_V_SIGN - PSW_V_N)) & FPS_N);
- if ((GET_SIGN (fsrc.h ^ fac.h) == 0) && (fac.h != 0) &&
- F_LT (fsrc, fac)) FPS = FPS ^ FPS_N;
-}
-
-#if 0
- break;
-
-/* Load and store exponent instructions */
-
-case 015: /* LDEXP */
-#endif
-
-void pdp11_movie(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t dst;
- int32_t qdouble;
- int32_t newV;
- fpac_t fac;
-
- qdouble = FPS & FPS_D;
- dst = (dstspec <= 07)? R[dstspec]: va[0];
- F_LOAD (qdouble, FR[ac], fac);
- fac.h = (fac.h & ~FP_EXP) | (((dst + FP_BIAS) & FP_M_EXP) << FP_V_EXP);
- newV = 0;
- if ((dst > 0177) && (dst <= 0177600)) {
- if (dst < 0100000) {
- if (fpnotrap (FEC_OVFLO)) fac = zero_fac;
- newV = FPS_V; }
- else {
- if (fpnotrap (FEC_UNFLO)) fac = zero_fac; } }
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, newV);
-}
-
-#if 0
- break;
-case 012: /* STEXP */
-#endif
-
-void pdp11_movei(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t dst;
- /*int32_t qdouble;*/
- /*int32_t newV;*/
- /*fpac_t fac;*/
-
- /*qdouble = FPS & FPS_D;*/
- dst = (GET_EXP (FR[ac].h) - FP_BIAS) & 0177777;
- N = GET_SIGN_W (dst);
- Z = (dst == 0);
- V = 0;
- C = 0;
- FPS = (FPS & ~FPS_CC) | (N << PSW_V_N) | (Z << PSW_V_Z);
- if (dstspec <= 07) R[dstspec] = dst;
- else va[0] = dst;
-}
-
-#if 0
- break;
-
-/* Integer convert instructions */
-
-case 016: /* LDCif */
-#endif
-
-void pdp11_movif(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t i, qdouble, leni;
- int32_t exp, sign;
- fpac_t fac;
-
- qdouble = FPS & FPS_D;
- leni = FPS & FPS_L? NICK_LONG: NICK_WORD;
- if (dstspec <= 07) fac.l = R[dstspec] << 16;
- else fac.l = ReadI (va, dstspec, leni);
- fac.h = 0;
- if (fac.l) {
- if (sign = GET_SIGN_L (fac.l)) fac.l = (fac.l ^ 0xFFFFFFFF) + 1;
- for (i = 0; GET_SIGN_L (fac.l) == 0; i++) fac.l = fac.l << 1;
- exp = ((FPS & FPS_L)? FP_BIAS + 32: FP_BIAS + 16) - i;
- fac.h = (sign << FP_V_SIGN) | (exp << FP_V_EXP) |
- ((fac.l >> (31 - FP_V_HB)) & FP_FRACH);
- fac.l = (fac.l << (FP_V_HB + 1)) & FP_FRACL;
- if ((FPS & (FPS_D + FPS_T)) == 0) roundfp11 (&fac); }
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, 0);
-}
-
-#if 0
- break;
-case 013: /* STCfi */
-#endif
-
-void pdp11_movfi(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t dst;
- int32_t i, qdouble, leni;
- int32_t exp, sign;
- fpac_t fac, fsrc;
- static const uint32_t i_limit[2][2] =
- { { 0x80000000, 0x80010000 }, { 0x80000000, 0x80000001 } };
-
- qdouble = FPS & FPS_D;
- sign = GET_SIGN (FR[ac].h); /* get sign, */
- exp = GET_EXP (FR[ac].h); /* exponent, */
- F_LOAD_FRAC (qdouble, FR[ac], fac); /* fraction */
- if (FPS & FPS_L) {
- leni = NICK_LONG;
- i = FP_BIAS + 32; }
- else {
- leni = NICK_WORD;
- i = FP_BIAS + 16; }
- C = 0;
- if (exp <= FP_BIAS) dst = 0;
- else if (exp > i) {
- dst = 0;
- C = 1; }
- else {
- F_RSH_V (fac, FP_V_HB + 1 + i - exp, fsrc);
- if (leni == NICK_WORD) fsrc.l = fsrc.l & ~0177777;
- if (fsrc.l >= i_limit[leni == NICK_LONG][sign]) {
- dst = 0;
- C = 1; }
- else {
- dst = fsrc.l;
- if (sign) dst = -dst; } }
- N = GET_SIGN_L (dst);
- Z = (dst == 0);
- V = 0;
- if (C) fpnotrap (FEC_ICVT);
- FPS = (FPS & ~FPS_CC) | (N << PSW_V_N) |
- (Z << PSW_V_Z) | (C << PSW_V_C);
- if (dstspec <= 07) R[dstspec] = (dst >> 16) & 0177777;
- else WriteI (dst, va, dstspec, leni);
-}
-
-#if 0
- break;
-
-/* Calculation instructions */
-
-case 2: /* MULf */
-#endif
-
-void pdp11_mulf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- int32_t newV;
- fpac_t fac, fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- newV = mulfp11 (&fac, &fsrc);
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, newV);
-}
-
-#if 0
- break;
-case 3: /* MODf */
- ReadFP (&fsrc, GeteaFP (dstspec, lenf), dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- newV = modfp11 (&fac, &fsrc, &modfrac);
- F_STORE (qdouble, fac, FR[ac | 1]);
- F_STORE (qdouble, modfrac, FR[ac]);
- FPS = setfcc (FPS, modfrac.h, newV);
- break;
-case 4: /* ADDf */
-#endif
-
-void pdp11_addf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- int32_t newV;
- fpac_t fac, fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- newV = addfp11 (&fac, &fsrc);
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, newV);
-}
-
-#if 0
- break;
-case 6: /* SUBf */
- ReadFP (&fsrc, GeteaFP (dstspec, lenf), dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- if (GET_EXP (fsrc.h) != 0) fsrc.h = fsrc.h ^ FP_SIGN;
- newV = addfp11 (&fac, &fsrc);
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, newV);
- break;
-case 011: /* DIVf */
-#endif
-
-void pdp11_divf(ac, va, dstspec) int ac; uint16_t *va; int dstspec; {
- int32_t qdouble, lenf;
- int32_t newV;
- fpac_t fac, fsrc;
-
- qdouble = FPS & FPS_D;
- lenf = qdouble? NICK_QUAD: NICK_LONG;
- ReadFP (&fsrc, va, dstspec, lenf);
- F_LOAD (qdouble, FR[ac], fac);
- if (GET_EXP (fsrc.h) == 0) { /* divide by zero? */
- fpnotrap (FEC_DZRO); ABORT (TRAP_INT); }
- newV = divfp11 (&fac, &fsrc);
- F_STORE (qdouble, fac, FR[ac]);
- FPS = setfcc (FPS, fac.h, newV);
-}
-
-#if 0
- break; } /* end switch fop */
-return;
-}
-
-/* Effective address calculation for fp operands
-
- Inputs:
- spec = specifier
- len = length
- Outputs:
- VA = virtual address
-
- Warnings:
- - Do not call this routine for integer mode 0 operands
- - Do not call this routine more than once per instruction
-*/
-
-int32_t GeteaFP(spec, len) int32_t spec; int32_t len; {
-int32_t adr, reg, ds;
-
-reg = spec & 07; /* reg number */
-ds = (reg == 7)? isenable: dsenable; /* dspace if not PC */
-switch (spec >> 3) { /* case on spec */
-case 0: /* floating AC */
- if (reg >= 06) { fpnotrap (FEC_OP); ABORT (TRAP_INT); }
- return 0;
-case 1: /* (R) */
- return (R[reg] | ds);
-case 2: /* (R)+ */
- if (reg == 7) len = 2;
- R[reg] = ((adr = R[reg]) + len) & 0177777;
- if (update_MM) MMR1 = (len << 3) | reg;
- return (adr | ds);
-case 3: /* @(R)+ */
- R[reg] = ((adr = R[reg]) + 2) & 0177777;
- if (update_MM) MMR1 = 020 | reg;
- adr = ReadW (adr | ds);
- return (adr | dsenable);
-case 4: /* -(R) */
- adr = R[reg] = (R[reg] - len) & 0177777;
- if (update_MM) MMR1 = (((-len) & 037) << 3) | reg;
- if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
- set_stack_trap (adr);
- return (adr | ds);
-case 5: /* @-(R) */
- adr = R[reg] = (R[reg] - 2) & 0177777;
- if (update_MM) MMR1 = 0360 | reg;
- if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
- set_stack_trap (adr);
- adr = ReadW (adr | ds);
- return (adr | dsenable);
-case 6: /* d(r) */
- adr = ReadW (PC | isenable);
- PC = (PC + 2) & 0177777;
- return (((R[reg] + adr) & 0177777) | dsenable);
-case 7: /* @d(R) */
- adr = ReadW (PC | isenable);
- PC = (PC + 2) & 0177777;
- adr = ReadW (((R[reg] + adr) & 0177777) | dsenable);
- return (adr | dsenable); } /* end switch */
-return 0;
-}
-#endif
-
-/* Read integer operand
-
- Inputs:
- VA = virtual address, VA<18:16> = mode, I/D space
- spec = specifier
- len = length (2/4 bytes)
- Outputs:
- data = data read from memory or I/O space
-*/
-
-static uint32_t ReadI(va, spec, len) uint16_t *va; int32_t spec; int32_t len; {
-if ((len == NICK_WORD) || (spec == 027)) return ((int32_t)va[0] << 16);
-return (((int32_t)va[0] << 16) | (int32_t)va[1]);
-}
-
-/* Read floating operand
-
- Inputs:
- fptr = pointer to output
- VA = virtual address, VA<18:16> = mode, I/D space
- spec = specifier
- len = length (4/8 bytes)
-*/
-
-static void ReadFP(fptr, va, spec, len) fpac_t *fptr; uint16_t *va; int32_t spec; int32_t len; {
-if (spec <= 07) {
- F_LOAD_P (len == NICK_QUAD, FR[spec], fptr);
- return; }
-if (spec == 027) {
- fptr->h = (va[0] << FP_V_F0);
- fptr->l = 0; }
-else { fptr->h = ((int32_t)va[0] << FP_V_F0) | ((int32_t)va[1] << FP_V_F1);
- if (len == NICK_QUAD) fptr->l =
- ((int32_t)va[2] << FP_V_F2) | ((int32_t)va[3] << FP_V_F3);
- else fptr->l = 0; }
-if ((GET_SIGN (fptr->h) != 0) && (GET_EXP (fptr->h) == 0) &&
- (fpnotrap (FEC_UNDFV) == 0)) ABORT (TRAP_INT);
-return;
-}
-
-/* Write integer result
-
- Inputs:
- data = data to be written
- VA = virtual address, VA<18:16> = mode, I/D space
- spec = specifier
- len = length
- Outputs: none
-*/
-
-static void WriteI(data, va, spec, len) int32_t data; uint16_t *va; int32_t spec; int32_t len; {
-va[0] = (uint16_t)((data >> 16) & 0177777);
-if ((len == NICK_WORD) || (spec == 027)) return;
-va[1] = (uint16_t)(data & 0177777);
-return;
-}
-
-/* Write floating result
-
- Inputs:
- fptr = pointer to data to be written
- VA = virtual address, VA<18:16> = mode, I/D space
- spec = specifier
- len = length
- Outputs: none
-*/
-
-static void WriteFP(fptr, va, spec, len) fpac_t *fptr; uint16_t *va; int32_t spec; int32_t len; {
-if (spec <= 07) {
- F_STORE_P (len == NICK_QUAD, fptr, FR[spec]);
- return; }
-va[0] = (uint16_t)((fptr->h >> FP_V_F0) & 0177777);
-if (spec == 027) return;
-va[1] = (uint16_t)((fptr->h >> FP_V_F1) & 0177777);
-if (len == NICK_LONG) return;
-va[2] = (uint16_t)((fptr->l >> FP_V_F2) & 0177777);
-va[3] = (uint16_t)((fptr->l >> FP_V_F3) & 0177777);
-return;
-}
-
-#if 0
-/* FIS instructions */
-
-t_stat fis11(IR) int32_t IR; {
-int32_t reg, exta;
-fpac_t fac, fsrc;
-
-reg = IR & 07; /* isolate reg */
-if (reg == 7) exta = isenable; /* choose I,D */
-else exta = dsenable;
-if (IR & 000740) { /* defined? */
- if (CPUT (CPUT_03)) ReadW (exta | R[reg]); /* 11/03 reads word */
- ABORT (TRAP_ILL); }
-FEC = 0; /* no errors */
-FPS = FPS_IU|FPS_IV; /* trap ovf,unf */
-
-fsrc.h = (ReadW (exta | R[reg]) << FP_V_F0) |
- (ReadW (exta | ((R[reg] + 2) & 0177777)) << FP_V_F1);
-fsrc.l = 0;
-fac.h = (ReadW (exta | ((R[reg] + 4) & 0177777)) << FP_V_F0) |
- (ReadW (exta | ((R[reg] + 6) & 0177777)) << FP_V_F1);
-fac.l = 0;
-if (GET_SIGN (fsrc.h) && (GET_EXP (fsrc.h) == 0)) /* clean 0's */
- fsrc.h = fsrc.l = 0;
-if (GET_SIGN (fac.h) && (GET_EXP (fac.l) == 0))
- fac.h = fac.l = 0;
-
-N = Z = V = C = 0; /* clear cc's */
-switch ((IR >> 3) & 3) { /* case IR<5:3> */
-
-case 0: /* FAD */
- addfp11 (&fac, &fsrc);
- break;
-case 1: /* FSUB */
- if (fsrc.h != 0) fsrc.h = fsrc.h ^ FP_SIGN; /* invert sign */
- addfp11 (&fac, &fsrc);
- break;
-case 2: /* FMUL */
- mulfp11 (&fac, &fsrc);
- break;
-case 3: /* FDIV */
- if (fsrc.h == 0) { /* div by 0? */
- V = N = C = 1; /* set cc's */
- setTRAP (TRAP_FPE); /* set trap */
- return SCPE_OK; }
- else divfp11 (&fac, &fsrc);
- break; }
-
-if (FEC == 0) { /* no err? */
- WriteW ((fac.h >> FP_V_F0) & 0177777, exta | ((R[reg] + 4) & 0177777));
- WriteW ((fac.h >> FP_V_F1) & 0177777, exta | ((R[reg] + 6) & 0177777));
- R[reg] = (R[reg] + 4) & 0177777; /* pop stack */
- N = (GET_SIGN (fac.h) != 0); /* set N,Z */
- Z = (fac.h == 0); }
-else if (FEC == FEC_OVFLO) V = 1; /* ovf? trap set */
-else if (FEC == FEC_UNFLO) V = N = 1; /* unf? trap set */
-else return SCPE_IERR; /* what??? */
-return SCPE_OK;
-}
-#endif
-
-/* Floating point add
-
- Inputs:
- facp = pointer to src1 (output)
- fsrcp = pointer to src2
- Outputs:
- ovflo = overflow variable
-*/
-
-static int32_t addfp11(facp, fsrcp) fpac_t *facp; fpac_t *fsrcp; {
-int32_t facexp, fsrcexp, ediff;
-fpac_t facfrac, fsrcfrac;
-
-if (F_LT_AP (facp, fsrcp)) { /* if !fac! < !fsrc! */
- facfrac = *facp;
- *facp = *fsrcp; /* swap operands */
- *fsrcp = facfrac; }
-facexp = GET_EXP (facp->h); /* get exponents */
-fsrcexp = GET_EXP (fsrcp->h);
-if (facexp == 0) { /* fac = 0? */
- *facp = fsrcexp? *fsrcp: zero_fac; /* result fsrc or 0 */
- return 0; }
-if (fsrcexp == 0) return 0; /* fsrc = 0? no op */
-ediff = facexp - fsrcexp; /* exponent diff */
-if (ediff >= 60) return 0; /* too big? no op */
-F_GET_FRAC_P (facp, facfrac); /* get fractions */
-F_GET_FRAC_P (fsrcp, fsrcfrac);
-F_LSH_GUARD (facfrac); /* guard fractions */
-F_LSH_GUARD (fsrcfrac);
-if (GET_SIGN (facp->h) != GET_SIGN (fsrcp->h)) { /* signs different? */
- if (ediff) { F_RSH_V (fsrcfrac, ediff, fsrcfrac); } /* sub, shf fsrc */
- F_SUB (fsrcfrac, facfrac, facfrac); /* sub fsrc from fac */
- if ((facfrac.h | facfrac.l) == 0) { /* result zero? */
- *facp = zero_fac; /* no overflow */
- return 0; }
- if (ediff <= 1) { /* big normalize? */
- if ((facfrac.h & (0x00FFFFFF << FP_GUARD)) == 0) {
- F_LSH_K (facfrac, 24, facfrac);
- facexp = facexp - 24; }
- if ((facfrac.h & (0x00FFF000 << FP_GUARD)) == 0) {
- F_LSH_K (facfrac, 12, facfrac);
- facexp = facexp - 12; }
- if ((facfrac.h & (0x00FC0000 << FP_GUARD)) == 0) {
- F_LSH_K (facfrac, 6, facfrac);
- facexp = facexp - 6; } }
- while (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD) == 0) {
- F_LSH_1 (facfrac);
- facexp = facexp - 1; } }
-else { if (ediff) { F_RSH_V (fsrcfrac, ediff, fsrcfrac); } /* add, shf fsrc */
- F_ADD (fsrcfrac, facfrac, facfrac); /* add fsrc to fac */
- if (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD + 1)) {
- F_RSH_1 (facfrac); /* carry out, shift */
- facexp = facexp + 1; } }
-return round_and_pack (facp, facexp, &facfrac, 1);
-}
-
-/* Floating point multiply
-
- Inputs:
- facp = pointer to src1 (output)
- fsrcp = pointer to src2
- Outputs:
- ovflo = overflow indicator
-*/
-
-static int32_t mulfp11(facp, fsrcp) fpac_t *facp; fpac_t *fsrcp; {
-int32_t facexp, fsrcexp;
-fpac_t facfrac, fsrcfrac;
-
-facexp = GET_EXP (facp->h); /* get exponents */
-fsrcexp = GET_EXP (fsrcp->h);
-if ((facexp == 0) || (fsrcexp == 0)) { /* test for zero */
- *facp = zero_fac;
- return 0; }
-F_GET_FRAC_P (facp, facfrac); /* get fractions */
-F_GET_FRAC_P (fsrcp, fsrcfrac);
-facexp = facexp + fsrcexp - FP_BIAS; /* calculate exp */
-facp->h = facp->h ^ fsrcp->h; /* calculate sign */
-frac_mulfp11 (&facfrac, &fsrcfrac); /* multiply fracs */
-
-/* Multiplying two numbers in the range [.5,1) produces a result in the
- range [.25,1). Therefore, at most one bit of normalization is required
- to bring the result back to the range [.5,1).
-*/
-
-if (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD) == 0) {
- F_LSH_1 (facfrac);
- facexp = facexp - 1; }
-return round_and_pack (facp, facexp, &facfrac, 1);
-}
-
-#if 0
-/* Floating point mod
-
- Inputs:
- facp = pointer to src1 (integer result)
- fsrcp = pointer to src2
- fracp = pointer to fractional result
- Outputs:
- ovflo = overflow indicator
-
- See notes on multiply for initial operation
-*/
-
-static int32_t modfp11(facp, fsrcp, fracp) fpac_t *facp; fpac_t *fsrcp; fpac_t *fracp; {
-int32_t facexp, fsrcexp;
-fpac_t facfrac, fsrcfrac, fmask;
-
-facexp = GET_EXP (facp->h); /* get exponents */
-fsrcexp = GET_EXP (fsrcp->h);
-if ((facexp == 0) || (fsrcexp == 0)) { /* test for zero */
- *fracp = zero_fac;
- *facp = zero_fac;
- return 0; }
-F_GET_FRAC_P (facp, facfrac); /* get fractions */
-F_GET_FRAC_P (fsrcp, fsrcfrac);
-facexp = facexp + fsrcexp - FP_BIAS; /* calculate exp */
-fracp->h = facp->h = facp->h ^ fsrcp->h; /* calculate sign */
-frac_mulfp11 (&facfrac, &fsrcfrac); /* multiply fracs */
-
-/* Multiplying two numbers in the range [.5,1) produces a result in the
- range [.25,1). Therefore, at most one bit of normalization is required
- to bring the result back to the range [.5,1).
-*/
-
-if (GET_BIT (facfrac.h, FP_V_HB + FP_GUARD) == 0) {
- F_LSH_1 (facfrac);
- facexp = facexp - 1; }
-
-/* There are three major cases of MODf:
-
- 1. Exp <= FP_BIAS (all fraction). Return 0 as integer, product as
- fraction. Underflow can occur.
- 2. Exp > FP_BIAS + #fraction bits (all integer). Return product as
- integer, 0 as fraction. Overflow can occur.
- 3. FP_BIAS < exp <= FP_BIAS + #fraction bits. Separate integer and
- fraction and return both. Neither overflow nor underflow can occur.
-*/
-
- if (facexp <= FP_BIAS) { /* case 1 */
- *facp = zero_fac;
- return round_and_pack (fracp, facexp, &facfrac, 1); }
- if (facexp > ((FPS & FPS_D)? FP_BIAS + 56: FP_BIAS + 24)) {
- *fracp = zero_fac; /* case 2 */
- return round_and_pack (facp, facexp, &facfrac, 0); }
- F_RSH_V (fmask_fac, facexp - FP_BIAS, fmask); /* shift mask */
- fsrcfrac.l = facfrac.l & fmask.l; /* extract fraction */
- fsrcfrac.h = facfrac.h & fmask.h;
- if ((fsrcfrac.h | fsrcfrac.l) == 0) *fracp = zero_fac;
- else {
- F_LSH_V (fsrcfrac, facexp - FP_BIAS, fsrcfrac);
- fsrcexp = FP_BIAS;
- if ((fsrcfrac.h & (0x00FFFFFF << FP_GUARD)) == 0) {
- F_LSH_K (fsrcfrac, 24, fsrcfrac);
- fsrcexp = fsrcexp - 24; }
- if ((fsrcfrac.h & (0x00FFF000 << FP_GUARD)) == 0) {
- F_LSH_K (fsrcfrac, 12, fsrcfrac);
- fsrcexp = fsrcexp - 12; }
- if ((fsrcfrac.h & (0x00FC0000 << FP_GUARD)) == 0) {
- F_LSH_K (fsrcfrac, 6, fsrcfrac);
- fsrcexp = fsrcexp - 6; }
- while (GET_BIT (fsrcfrac.h, FP_V_HB + FP_GUARD) == 0) {
- F_LSH_1 (fsrcfrac);
- fsrcexp = fsrcexp - 1; }
- round_and_pack (fracp, fsrcexp, &fsrcfrac, 1); }
- facfrac.l = facfrac.l & ~fmask.l;
- facfrac.h = facfrac.h & ~fmask.h;
- return round_and_pack (facp, facexp, &facfrac, 0);
-}
-#endif
-
-/* Fraction multiply
-
- Inputs:
- f1p = pointer to multiplier (output)
- f2p = pointer to multiplicand fraction
-
- Note: the inputs are unguarded; the output is guarded.
-
- This routine performs a classic shift-and-add multiply. The low
- order bit of the multiplier is tested; if 1, the multiplicand is
- added into the high part of the double precision result. The
- result and the multiplier are both shifted right 1.
-
- For the 24b x 24b case, this routine develops 48b of result.
- For the 56b x 56b case, this routine only develops the top 64b
- of the the result. Because the inputs are normalized fractions,
- the interesting part of the result is the high 56+guard bits.
- Everything shifted off to the right, beyond 64b, plays no part
- in rounding or the result.
-
- There are many possible optimizations in this routine: scanning
- for groups of zeroes, particularly in the 56b x 56b case; using
- "extended multiply" capability if available in the hardware.
-*/
-
-static void frac_mulfp11(f1p, f2p) fpac_t *f1p; fpac_t *f2p; {
-fpac_t result, mpy, mpc;
-int32_t i;
-
-result = zero_fac; /* clear result */
-mpy = *f1p; /* get operands */
-mpc = *f2p;
-F_LSH_GUARD (mpc); /* guard multipicand */
-if ((mpy.l | mpc.l) == 0) { /* 24b x 24b? */
- for (i = 0; i < 24; i++) {
- if (mpy.h & 1) result.h = result.h + mpc.h;
- F_RSH_1 (result);
- mpy.h = mpy.h >> 1; } }
-else { if (mpy.l != 0) { /* 24b x 56b? */
- for (i = 0; i < 32; i++) {
- if (mpy.l & 1) { F_ADD (mpc, result, result); }
- F_RSH_1 (result);
- mpy.l = mpy.l >> 1; } }
- for (i = 0; i < 24; i++) {
- if (mpy.h & 1) { F_ADD (mpc, result, result); }
- F_RSH_1 (result);
- mpy.h = mpy.h >> 1; } }
-*f1p = result;
-return;
-}
-
-/* Floating point divide
-
- Inputs:
- facp = pointer to dividend (output)
- fsrcp = pointer to divisor
- Outputs:
- ovflo = overflow indicator
-
- Source operand must be checked for zero by caller!
-*/
-
-static int32_t divfp11(facp, fsrcp) fpac_t *facp; fpac_t *fsrcp; {
-int32_t facexp, fsrcexp, i, count, qd;
-fpac_t facfrac, fsrcfrac, quo;
-
-fsrcexp = GET_EXP (fsrcp->h); /* get divisor exp */
-facexp = GET_EXP (facp->h); /* get dividend exp */
-if (facexp == 0) { /* test for zero */
- *facp = zero_fac; /* result zero */
- return 0; }
-F_GET_FRAC_P (facp, facfrac); /* get fractions */
-F_GET_FRAC_P (fsrcp, fsrcfrac);
-F_LSH_GUARD (facfrac); /* guard fractions */
-F_LSH_GUARD (fsrcfrac);
-facexp = facexp - fsrcexp + FP_BIAS + 1; /* calculate exp */
-facp->h = facp->h ^ fsrcp->h; /* calculate sign */
-qd = FPS & FPS_D;
-count = FP_V_HB + FP_GUARD + (qd? 33: 1); /* count = 56b/24b */
-
-quo = zero_fac;
-for (i = count; (i > 0) && ((facfrac.h | facfrac.l) != 0); i--) {
- F_LSH_1 (quo); /* shift quotient */
- if (!F_LT (facfrac, fsrcfrac)) { /* divd >= divr? */
- F_SUB (fsrcfrac, facfrac, facfrac); /* divd - divr */
- if (qd) quo.l = quo.l | 1; /* double or single? */
- else quo.h = quo.h | 1; }
- F_LSH_1 (facfrac); } /* shift divd */
-if (i > 0) { F_LSH_V (quo, i, quo); } /* early exit? */
-
-/* Dividing two numbers in the range [.5,1) produces a result in the
- range [.5,2). Therefore, at most one bit of normalization is required
- to bring the result back to the range [.5,1). The choice of counts
- and quotient bit positions makes this work correctly.
-*/
-
-if (GET_BIT (quo.h, FP_V_HB + FP_GUARD) == 0) {
- F_LSH_1 (quo);
- facexp = facexp - 1; }
-return round_and_pack (facp, facexp, &quo, 1);
-}
-
-/* Update floating condition codes
- Note that FC is only set by STCfi via the integer condition codes
-
- Inputs:
- oldst = current status
- result = high result
- newV = new V
- Outputs:
- newst = new status
-*/
-
-static int32_t setfcc(oldst, result, newV) int32_t oldst; int32_t result; int32_t newV; {
-oldst = (oldst & ~FPS_CC) | newV;
-if (GET_SIGN (result)) oldst = oldst | FPS_N;
-if (GET_EXP (result) == 0) oldst = oldst | FPS_Z;
-return oldst;
-}
-
-/* Round (in place) floating point number to f_floating
-
- Inputs:
- fptr = pointer to floating number
- Outputs:
- ovflow = overflow
-*/
-
-static int32_t roundfp11(fptr) fpac_t *fptr; {
-fpac_t outf;
-
-outf = *fptr; /* get argument */
-F_ADD (fround_fac, outf, outf); /* round */
-if (GET_SIGN (outf.h ^ fptr->h)) { /* flipped sign? */
- outf.h = (outf.h ^ FP_SIGN) & 0xFFFFFFFF; /* restore sign */
- if (fpnotrap (FEC_OVFLO)) *fptr = zero_fac; /* if no int, clear */
- else *fptr = outf; /* return rounded */
- return FPS_V; } /* overflow */
-else { *fptr = outf; /* round was ok */
- return 0; } /* no overflow */
-}
-
-/* Round result of calculation, test overflow, pack
-
- Input:
- facp = pointer to result, sign in place
- exp = result exponent, right justified
- fracp = pointer to result fraction, right justified with
- guard bits
- r = round (1) or truncate (0)
- Outputs:
- ovflo = overflow indicator
-*/
-
-static int32_t round_and_pack(facp, exp, fracp, r) fpac_t *facp; int32_t exp; fpac_t *fracp; int r; {
-fpac_t frac;
-
-frac = *fracp; /* get fraction */
-if (r && ((FPS & FPS_T) == 0)) {
- if (FPS & FPS_D) { F_ADD (dround_guard_fac, frac, frac); }
- else { F_ADD (fround_guard_fac, frac, frac); }
- if (GET_BIT (frac.h, FP_V_HB + FP_GUARD + 1)) {
- F_RSH_1 (frac);
- exp = exp + 1; } }
-F_RSH_GUARD (frac);
-facp->l = frac.l & FP_FRACL;
-facp->h = (facp->h & FP_SIGN) | ((exp & FP_M_EXP) << FP_V_EXP) |
- (frac.h & FP_FRACH);
-if (exp > 0377) {
- if (fpnotrap (FEC_OVFLO)) *facp = zero_fac;
- return FPS_V; }
-if ((exp <= 0) && (fpnotrap (FEC_UNFLO))) *facp = zero_fac;
-return 0;
-}
-
-/* Process floating point exception
-
- Inputs:
- code = exception code
- Outputs:
- int = FALSE if interrupt enabled, TRUE if disabled
-*/
-
-int32_t fpnotrap(code) int32_t code; {
-static const int32_t test_code[] = { 0, 0, 0, FPS_IC, FPS_IV, FPS_IU, FPS_IUV };
-
-if ((code >= FEC_ICVT) && (code <= FEC_UNDFV) &&
- ((FPS & test_code[code >> 1]) == 0)) return TRUE;
-FPS = FPS | FPS_ER;
-FEC = code;
-/*FEA = (backup_PC - 2) & 0177777;*/
-/*if ((FPS & FPS_ID) == 0) setTRAP (TRAP_FPE);*/
-return FALSE;
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ldexp.c 2.3 (Berkeley) 6/12/88";
-#endif
-
-/*
- * double
- * ldexp (value, exp)
- * double value;
- * int exp;
- *
- * Ldexp returns value*2**exp, if that result is in range.
- * If underflow occurs, it returns zero. If overflow occurs,
- * it returns a value of appropriate sign and largest
- * possible magnitude. In case of either overflow or underflow,
- * errno is set to ERANGE. Note that errno is not modified if
- * no error occurs. Note also that the code assumes that both
- * FIV and FIU are disabled in the floating point processor:
- * FIV disabled prevents a trap from ocurring on floating overflow;
- * FIU disabled cause a floating zero to be generated on floating underflow.
- */
-
-/* #include "DEFS.h" */
-
-/* ERANGE = 34. / can't include <errno.h> because of the */
-/* .comm _errno,2 / comments on each line ... (sigh) */
-
-#ifndef pdp11
-#include <math.h>
-#include <errno.h>
-#include "c1.h"
-
-/* .data */
-/* huge: 077777; 0177777; 0177777; 0177777 */
-uint16_t huge[4] = { 077777, 0177777, 0177777, 0177777 };
-/* .text */
-
-
-/* ENTRY(ldexp) */
-void pdp11_ldexp(value, exp) uint16_t *value; int exp; {
- /* movf 2(sp),fr0 */
- /* / fr0 = value */
- pdp11_ldf(0, value, 066);
- /* cfcc */
- pdp11_cfcc();
- /* beq 2f */
- /* / done if zero */
- if (Z == 0) {
- /* movei fr0,r0 */
- /* / r0 = log2(value) */
- pdp11_movei(0, NULL, 0);
- /* add 10.(sp),r0 */
- /* / add exp to log2(value) and stuff result */
- R[0] += exp;
- /* movie r0,fr0 */
- /* / back as new exponent for fr0 */
- pdp11_movie(0, NULL, 0);
- /* cfcc */
- /* / Overflow? */
- pdp11_cfcc();
- /* bvc 2f */
- if (V) {
- /* movf huge,fr0 */
- /* / yes, fr0 = (value < 0.0) ? -huge : huge; */
- pdp11_ldf(0, huge, 067);
- /* bpl 1f */
- if (N)
- /* negf fr0 */
- pdp11_negf(NULL, 0);
- /* 1: */
- /* mov $ERANGE,_errno */
- /* / and errno = ERANGE */
- errno = ERANGE;
- }
- }
- /* 2: */
- /* rts pc */
-}
-#endif
#include "cross/cross.h"
-void cross_read_float(res, buf) cross_float_t *res; char *buf; {
- res->data[0] = (buf[0] & 0xff) | ((buf[1] & 0xff) << 8);
- res->data[1] = (buf[2] & 0xff) | ((buf[3] & 0xff) << 8);
+cross_float_t cross_read_float(res, buf) char *buf; {
+ cross_float_t res;
+ res.h = (((uint32_t)buf[0] & 0xff) << 16) | (((uint32_t)buf[1] & 0xff) << 24) |
+ ((uint32_t)buf[2] & 0xff) | (((uint32_t)buf[3] & 0xff) << 8);
+ return res;
}
-void cross_read_double(res, buf) cross_double_t *res; char *buf; {
- res->data[0] = (buf[0] & 0xff) | ((buf[1] & 0xff) << 8);
- res->data[1] = (buf[2] & 0xff) | ((buf[3] & 0xff) << 8);
- res->data[2] = (buf[4] & 0xff) | ((buf[5] & 0xff) << 8);
- res->data[3] = (buf[6] & 0xff) | ((buf[7] & 0xff) << 8);
+cross_double_t cross_read_double(res, buf) char *buf; {
+ cross_double_t res;
+ res.h = (((uint32_t)buf[0] & 0xff) << 16) | (((uint32_t)buf[1] & 0xff) << 24) |
+ ((uint32_t)buf[2] & 0xff) | (((uint32_t)buf[3] & 0xff) << 8);
+ res.l = (((uint32_t)buf[4] & 0xff) << 16) | (((uint32_t)buf[5] & 0xff) << 24) |
+ ((uint32_t)buf[6] & 0xff) | (((uint32_t)buf[7] & 0xff) << 8);
+ return res;
}
/* XXX we assume char is signed here */
}
unsigned long cross_read_ulong(buf) char *buf; {
- return (((long)buf[0] & 0xff) << 16) | (((long)buf[1] & 0xff) << 24) |
- ((long)buf[2] & 0xff) | (((long)buf[3] & 0xff) << 8);
+ return (((unsigned long)buf[0] & 0xff) << 16) | (((unsigned long)buf[1] & 0xff) << 24) |
+ ((unsigned long)buf[2] & 0xff) | (((unsigned long)buf[3] & 0xff) << 8);
}
-void cross_write_float(buf, val) char *buf; cross_float_t *val; {
- buf[0] = val->data[0] & 0xff;
- buf[1] = (val->data[0] >> 8) & 0xff;
- buf[2] = val->data[1] & 0xff;
- buf[3] = (val->data[1] >> 8) & 0xff;
+void cross_write_float(buf, val) char *buf; cross_float_t val; {
+ buf[0] = (val.h >> 16) & 0xff;
+ buf[1] = (val.h >> 24) & 0xff;
+ buf[2] = val.h & 0xff;
+ buf[3] = (val.h >> 8) & 0xff;
}
-void cross_write_double(buf, val) char *buf; cross_double_t *val; {
- buf[0] = val->data[0] & 0xff;
- buf[1] = (val->data[0] >> 8) & 0xff;
- buf[2] = val->data[1] & 0xff;
- buf[3] = (val->data[1] >> 8) & 0xff;
- buf[4] = val->data[2] & 0xff;
- buf[5] = (val->data[2] >> 8) & 0xff;
- buf[6] = val->data[3] & 0xff;
- buf[7] = (val->data[3] >> 8) & 0xff;
+void cross_write_double(buf, val) char *buf; cross_double_t val; {
+ buf[0] = (val.h >> 16) & 0xff;
+ buf[1] = (val.h >> 24) & 0xff;
+ buf[2] = val.h & 0xff;
+ buf[3] = (val.h >> 8) & 0xff;
+ buf[4] = (val.l >> 16) & 0xff;
+ buf[5] = (val.l >> 24) & 0xff;
+ buf[6] = val.l & 0xff;
+ buf[7] = (val.l >> 8) & 0xff;
}
void cross_write_short(buf, val) char *buf; int val; {
typedef unsigned short cross_ushort_t;
#else
#include <stdint.h>
-typedef struct { uint16_t data[4]; } cross_double_t;
-typedef struct { uint16_t data[2]; } cross_float_t;
+typedef struct { uint32_t l; uint32_t h; } cross_double_t;
+typedef struct { uint32_t h; } cross_float_t;
typedef int16_t cross_int_t;
typedef int32_t cross_long_t;
typedef int16_t cross_short_t;
#endif
/* cross.c */
-void cross_read_float __P((cross_float_t *res, char *buf));
-void cross_read_double __P((cross_double_t *res, char *buf));
+cross_float_t cross_read_float __P((char *buf));
+cross_double_t cross_read_double __P((char *buf));
short cross_read_short __P((char *buf));
unsigned short cross_read_ushort __P((char *buf));
long cross_read_long __P((char *buf));
unsigned long cross_read_ulong __P((char *buf));
-void cross_write_float __P((char *buf, cross_float_t *val));
-void cross_write_double __P((char *buf, cross_double_t *val));
+void cross_write_float __P((char *buf, cross_float_t val));
+void cross_write_double __P((char *buf, cross_double_t val));
void cross_write_short __P((char *buf, int val));
void cross_write_ushort __P((char *buf, unsigned int val));
void cross_write_long __P((char *buf, long val));