xref: /original-bsd/usr.bin/pascal/src/gen.c (revision 6e17b0ce)
1b85afe43Sbostic /*-
2*6e17b0ceSbostic  * Copyright (c) 1980, 1993
3*6e17b0ceSbostic  *	The Regents of the University of California.  All rights reserved.
4b85afe43Sbostic  *
5b85afe43Sbostic  * %sccs.include.redist.c%
6632c1b80Sdist  */
77b3d68fcSpeter 
89efbcb67Sthien #ifndef lint
9*6e17b0ceSbostic static char sccsid[] = "@(#)gen.c	8.1 (Berkeley) 06/06/93";
10b85afe43Sbostic #endif /* not lint */
117b3d68fcSpeter 
127b3d68fcSpeter #include "whoami.h"
137b3d68fcSpeter #ifdef OBJ
147b3d68fcSpeter     /*
157b3d68fcSpeter      *	and the rest of the file
167b3d68fcSpeter      */
177b3d68fcSpeter #include "0.h"
187b3d68fcSpeter #include "tree.h"
197b3d68fcSpeter #include "opcode.h"
207b3d68fcSpeter #include "objfmt.h"
217b3d68fcSpeter 
227b3d68fcSpeter /*
237b3d68fcSpeter  * This array tells the type
247b3d68fcSpeter  * returned by an arithmetic
257b3d68fcSpeter  * operation.  It is indexed
267b3d68fcSpeter  * by the logarithm of the
277b3d68fcSpeter  * lengths base 2.
287b3d68fcSpeter  */
297b3d68fcSpeter #ifndef	DEBUG
307b3d68fcSpeter char	arret[]	= {
317b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
327b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
337b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
347b3d68fcSpeter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
357b3d68fcSpeter };
367b3d68fcSpeter #else
377b3d68fcSpeter char	arret0[] = {
387b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
397b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
407b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
417b3d68fcSpeter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
427b3d68fcSpeter };
437b3d68fcSpeter char	arret1[] = {
447b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
457b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
467b3d68fcSpeter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
477b3d68fcSpeter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
487b3d68fcSpeter };
497b3d68fcSpeter char	*arret = arret0;
507b3d68fcSpeter #endif
517b3d68fcSpeter 
527b3d68fcSpeter /*
537b3d68fcSpeter  * These array of arithmetic and set
547b3d68fcSpeter  * operators are indexed by the
557b3d68fcSpeter  * tree nodes and is highly dependent
567b3d68fcSpeter  * on their order.  They thus take
577b3d68fcSpeter  * on the flavor of magic.
587b3d68fcSpeter  */
597b3d68fcSpeter int	arop[] = {
607b3d68fcSpeter 	0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2,
617b3d68fcSpeter 	O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2
627b3d68fcSpeter };
637b3d68fcSpeter int	setop[] = {
647b3d68fcSpeter 	O_MULT, O_ADDT, O_SUBT,
657b3d68fcSpeter 	O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT,
667b3d68fcSpeter };
677b3d68fcSpeter 
687b3d68fcSpeter /*
697b3d68fcSpeter  * The following array is
707b3d68fcSpeter  * used when operating on
717b3d68fcSpeter  * two reals since they are
727b3d68fcSpeter  * shoved off in a corner in
737b3d68fcSpeter  * the interpreter table.
747b3d68fcSpeter  */
757b3d68fcSpeter int	ar8op[] = {
767b3d68fcSpeter 	O_DVD8, O_MUL8, O_ADD8, O_SUB8,
777b3d68fcSpeter 	O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8,
787b3d68fcSpeter };
797b3d68fcSpeter 
807b3d68fcSpeter /*
817b3d68fcSpeter  * The following arrays, which are linearizations
827b3d68fcSpeter  * of two dimensional arrays, are the offsets for
837b3d68fcSpeter  * arithmetic, relational and assignment operations
847b3d68fcSpeter  * indexed by the logarithms of the argument widths.
857b3d68fcSpeter  */
867b3d68fcSpeter #ifndef	DEBUG
877b3d68fcSpeter char artab[] = {
887b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
897b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
907b3d68fcSpeter 	O_ADD24-O_ADD2,	O_ADD24-O_ADD2,	O_ADD4-O_ADD2,	O_ADD84-O_ADD2,
917b3d68fcSpeter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD48-O_ADD2,	-1
927b3d68fcSpeter };
937b3d68fcSpeter #else
947b3d68fcSpeter char artab0[] = {
957b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
967b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
977b3d68fcSpeter 	O_ADD24-O_ADD2,	O_ADD24-O_ADD2,	O_ADD4-O_ADD2,	O_ADD84-O_ADD2,
987b3d68fcSpeter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD48-O_ADD2,	-1
997b3d68fcSpeter };
1007b3d68fcSpeter char artab1[] = {
1017b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD82-O_ADD2,
1027b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD82-O_ADD2,
1037b3d68fcSpeter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD84-O_ADD2,
1047b3d68fcSpeter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	-1
1057b3d68fcSpeter };
1067b3d68fcSpeter char	*artab = artab0;
1077b3d68fcSpeter #endif
1087b3d68fcSpeter #ifndef DEBUG
1097b3d68fcSpeter char reltab[] = {
1107b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
1117b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
1127b3d68fcSpeter 	O_REL24-O_REL2,	O_REL24-O_REL2,	O_REL4-O_REL2,	O_REL84-O_REL2,
1137b3d68fcSpeter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL48-O_REL2,	O_REL8-O_REL2
1147b3d68fcSpeter };
1157b3d68fcSpeter #else
1167b3d68fcSpeter char reltab0[] = {
1177b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
1187b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
1197b3d68fcSpeter 	O_REL24-O_REL2,	O_REL24-O_REL2,	O_REL4-O_REL2,	O_REL84-O_REL2,
1207b3d68fcSpeter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL48-O_REL2,	O_REL8-O_REL2
1217b3d68fcSpeter };
1227b3d68fcSpeter char reltab1[] = {
1237b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
1247b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
1257b3d68fcSpeter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
1267b3d68fcSpeter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL8-O_REL2
1277b3d68fcSpeter };
1287b3d68fcSpeter char *reltab = reltab0;
1297b3d68fcSpeter #endif
1307b3d68fcSpeter 
1317b3d68fcSpeter #ifndef DEBUG
1327b3d68fcSpeter char asgntab[] = {
1337b3d68fcSpeter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS41-O_AS2,	-1,
1347b3d68fcSpeter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS42-O_AS2,	-1,
1357b3d68fcSpeter 	O_AS24-O_AS2,	O_AS24-O_AS2,	O_AS4-O_AS2,	-1,
1367b3d68fcSpeter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS48-O_AS2,	O_AS8-O_AS2,
1377b3d68fcSpeter };
1387b3d68fcSpeter #else
1397b3d68fcSpeter char asgntb0[] = {
1407b3d68fcSpeter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS41-O_AS2,	-1,
1417b3d68fcSpeter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS42-O_AS2,	-1,
1427b3d68fcSpeter 	O_AS24-O_AS2,	O_AS24-O_AS2,	O_AS4-O_AS2,	-1,
1437b3d68fcSpeter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS48-O_AS2,	O_AS8-O_AS2,
1447b3d68fcSpeter };
1457b3d68fcSpeter char asgntb1[] = {
1467b3d68fcSpeter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS21-O_AS2,	-1,
1477b3d68fcSpeter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS2-O_AS2,	-1,
1487b3d68fcSpeter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS2-O_AS2,	-1,
1497b3d68fcSpeter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS4-O_AS2,
1507b3d68fcSpeter };
1517b3d68fcSpeter char *asgntab = asgntb0;
1527b3d68fcSpeter #endif
1537b3d68fcSpeter 
1547b3d68fcSpeter #ifdef DEBUG
genmx()1557b3d68fcSpeter genmx()
1567b3d68fcSpeter {
1577b3d68fcSpeter 
1587b3d68fcSpeter 	arret = arret1;
1597b3d68fcSpeter 	artab = artab1;
1607b3d68fcSpeter 	reltab = reltab1;
1617b3d68fcSpeter 	asgntab = asgntb1;
1627b3d68fcSpeter }
1637b3d68fcSpeter #endif
1647b3d68fcSpeter 
1657b3d68fcSpeter /*
1667b3d68fcSpeter  * Gen generates code for assignments,
1677b3d68fcSpeter  * and arithmetic and string operations
1687b3d68fcSpeter  * and comparisons.
1697b3d68fcSpeter  */
1707b3d68fcSpeter struct nl *
gen(p,o,w1,w2)1717b3d68fcSpeter gen(p, o, w1, w2)
1727b3d68fcSpeter 	int p, o, w1, w2;
1737b3d68fcSpeter {
1747b3d68fcSpeter 	register i, j;
1759efbcb67Sthien 	int op;
1767b3d68fcSpeter 
1777b3d68fcSpeter 	switch (p) {
1789efbcb67Sthien 		default:
1799efbcb67Sthien 			panic("gen");
1807b3d68fcSpeter 		case O_AS2:
1817b3d68fcSpeter 		case NIL:
1827b3d68fcSpeter 			i = j = -1;
1837b3d68fcSpeter 			/*
1847b3d68fcSpeter 			 * Take the log2 of the widths
1857b3d68fcSpeter 			 * and linearize them for indexing.
1867b3d68fcSpeter 			 * width for indexing.
1877b3d68fcSpeter 			 */
1887b3d68fcSpeter #ifdef DEBUG
1897b3d68fcSpeter 			if (hp21mx) {
1907b3d68fcSpeter 				if (w1 == 4)
1917b3d68fcSpeter 					w1 = 8;
1927b3d68fcSpeter 				if (w2 == 4)
1937b3d68fcSpeter 					w2 = 8;
1947b3d68fcSpeter 			}
1957b3d68fcSpeter #endif
1967b3d68fcSpeter 			do i++; while (w1 >>= 1);
1977b3d68fcSpeter 			do j++; while (w2 >>= 1);
1987b3d68fcSpeter 			i <<= 2;
1997b3d68fcSpeter 			i |= j;
2007b3d68fcSpeter 			if (p == O_AS2) {
2019efbcb67Sthien 				(void) put(1, O_AS2 + asgntab[i]);
2027b3d68fcSpeter 				return (NIL);
2037b3d68fcSpeter 			}
2047b3d68fcSpeter 			op = arop[o];
2057b3d68fcSpeter 			if (op == O_REL2) {
2069efbcb67Sthien 				(void) put(1, (op + reltab[i]) | (o - T_EQ) << 8+INDX);
2077b3d68fcSpeter 				return (nl+TBOOL);
2087b3d68fcSpeter 			}
2099efbcb67Sthien 			(void) put(1, i == 15 ? ar8op[o-T_DIVD] : op | artab[i]);
2107b3d68fcSpeter 			return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]);
2117b3d68fcSpeter 		case TREC:
2127b3d68fcSpeter 		case TSTR:
2139efbcb67Sthien 			(void) put(2, O_RELG | (o - T_EQ) << 8+INDX, w1);
2147b3d68fcSpeter 			return (nl+TBOOL);
2157b3d68fcSpeter 		case TSET:
2167b3d68fcSpeter 			op = setop[o-T_MULT];
2177b3d68fcSpeter 			if (op == O_RELT)
2187b3d68fcSpeter 				op |= (o - T_EQ)<<8+INDX;
2199efbcb67Sthien 			(void) put(2, op, w1);
2207b3d68fcSpeter 			return (o >= T_EQ ? nl+TBOOL : nl+TSET);
2217b3d68fcSpeter 	}
2227b3d68fcSpeter }
2237b3d68fcSpeter #endif OBJ
224