home *** CD-ROM | disk | FTP | other *** search
- /*-
- * Copyright (c) 1980 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)gen.c 5.2 (Berkeley) 4/16/91";
- #endif /* not lint */
-
- #include "whoami.h"
- #ifdef OBJ
- /*
- * and the rest of the file
- */
- #include "0.h"
- #include "tree.h"
- #include "opcode.h"
- #include "objfmt.h"
-
- /*
- * This array tells the type
- * returned by an arithmetic
- * operation. It is indexed
- * by the logarithm of the
- * lengths base 2.
- */
- #ifndef DEBUG
- char arret[] = {
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
- };
- #else
- char arret0[] = {
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
- };
- char arret1[] = {
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- T4INT, T4INT, T4INT, TDOUBLE,
- TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
- };
- char *arret = arret0;
- #endif
-
- /*
- * These array of arithmetic and set
- * operators are indexed by the
- * tree nodes and is highly dependent
- * on their order. They thus take
- * on the flavor of magic.
- */
- int arop[] = {
- 0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2,
- O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2
- };
- int setop[] = {
- O_MULT, O_ADDT, O_SUBT,
- O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT,
- };
-
- /*
- * The following array is
- * used when operating on
- * two reals since they are
- * shoved off in a corner in
- * the interpreter table.
- */
- int ar8op[] = {
- O_DVD8, O_MUL8, O_ADD8, O_SUB8,
- O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8,
- };
-
- /*
- * The following arrays, which are linearizations
- * of two dimensional arrays, are the offsets for
- * arithmetic, relational and assignment operations
- * indexed by the logarithms of the argument widths.
- */
- #ifndef DEBUG
- char artab[] = {
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
- O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2,
- O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1
- };
- #else
- char artab0[] = {
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
- O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2,
- O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1
- };
- char artab1[] = {
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2,
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2,
- O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD84-O_ADD2,
- O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD28-O_ADD2, -1
- };
- char *artab = artab0;
- #endif
- #ifndef DEBUG
- char reltab[] = {
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
- O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2,
- O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2
- };
- #else
- char reltab0[] = {
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
- O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2,
- O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2
- };
- char reltab1[] = {
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
- O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
- O_REL28-O_REL2, O_REL28-O_REL2, O_REL28-O_REL2, O_REL8-O_REL2
- };
- char *reltab = reltab0;
- #endif
-
- #ifndef DEBUG
- char asgntab[] = {
- O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1,
- O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1,
- O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1,
- O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2,
- };
- #else
- char asgntb0[] = {
- O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1,
- O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1,
- O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1,
- O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2,
- };
- char asgntb1[] = {
- O_AS21-O_AS2, O_AS21-O_AS2, O_AS21-O_AS2, -1,
- O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1,
- O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1,
- O_AS28-O_AS2, O_AS28-O_AS2, O_AS28-O_AS2, O_AS4-O_AS2,
- };
- char *asgntab = asgntb0;
- #endif
-
- #ifdef DEBUG
- genmx()
- {
-
- arret = arret1;
- artab = artab1;
- reltab = reltab1;
- asgntab = asgntb1;
- }
- #endif
-
- /*
- * Gen generates code for assignments,
- * and arithmetic and string operations
- * and comparisons.
- */
- struct nl *
- gen(p, o, w1, w2)
- int p, o, w1, w2;
- {
- register i, j;
- int op;
-
- switch (p) {
- default:
- panic("gen");
- case O_AS2:
- case NIL:
- i = j = -1;
- /*
- * Take the log2 of the widths
- * and linearize them for indexing.
- * width for indexing.
- */
- #ifdef DEBUG
- if (hp21mx) {
- if (w1 == 4)
- w1 = 8;
- if (w2 == 4)
- w2 = 8;
- }
- #endif
- do i++; while (w1 >>= 1);
- do j++; while (w2 >>= 1);
- i <<= 2;
- i |= j;
- if (p == O_AS2) {
- (void) put(1, O_AS2 + asgntab[i]);
- return (NIL);
- }
- op = arop[o];
- if (op == O_REL2) {
- (void) put(1, (op + reltab[i]) | (o - T_EQ) << 8+INDX);
- return (nl+TBOOL);
- }
- (void) put(1, i == 15 ? ar8op[o-T_DIVD] : op | artab[i]);
- return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]);
- case TREC:
- case TSTR:
- (void) put(2, O_RELG | (o - T_EQ) << 8+INDX, w1);
- return (nl+TBOOL);
- case TSET:
- op = setop[o-T_MULT];
- if (op == O_RELT)
- op |= (o - T_EQ)<<8+INDX;
- (void) put(2, op, w1);
- return (o >= T_EQ ? nl+TBOOL : nl+TSET);
- }
- }
- #endif OBJ
-