koreth@panarthea.ebay.sun.com (Steven Grimm) (10/25/89)
Submitted-by: ncar.ucar.edu!dunike!onecom!wldrdg!hans (Johann Ruegg)
Posting-number: Volume 2, Issue 96
Archive-name: sozobon1.2/part05
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 5 (of 9)."
# Contents: hcc/FUN.C hcc/G2.C hcc/GEN.C
# Wrapped by koreth@panarthea on Tue Oct 24 18:40:46 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'hcc/FUN.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hcc/FUN.C'\"
else
echo shar: Extracting \"'hcc/FUN.C'\" \(11588 characters\)
sed "s/^X//" >'hcc/FUN.C' <<'END_OF_FILE'
X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
X *
X * Permission is granted to anyone to use this software for any purpose
X * on any computer system, and to redistribute it freely, with the
X * following restrictions:
X * 1) No charge may be made other than reasonable charges for reproduction.
X * 2) Modified versions must be clearly marked as such.
X * 3) The authors are not responsible for any harmful consequences
X * of using this software, even if they result from defects in it.
X *
X * fun.c
X *
X * Handle function entry, exit, etc.
X * Parse statements.
X * Also, general syntax error recovery strategy.
X */
X
X#include <stdio.h>
X#include "param.h"
X#include "tok.h"
X#include "nodes.h"
X#include "cookie.h"
X
X#if MMCC
Xoverlay "pass2"
X#endif
X
Xextern NODE *cur;
X
Xint level;
XNODE *blktab;
XNODE *labels;
X
Xstruct swittbl {
X NODEP caselist;
X int deflbl;
X} *curswit;
X
Xint curbrk, curcont;
Xint funtopl, funbotl, funretl, funstrl;
XNODEP funtyp;
Xint maxregs;
Xlong maxlocs;
X
Xint skipon;
X
XNODEP glb_decls();
X
Xextern int oflags[];
X#define debugl oflags['l'-'a']
X#define debugs oflags['s'-'a']
X#define debugv oflags['v'-'a']
X
Xfindtok(x)
X{
X while (cur->e_token != EOFTOK && cur->e_token != x)
X fadvnode();
X if (cur->e_token == EOFTOK)
X exit(1);
X}
X
Xprogram()
X{
X extern NODEP symtab[];
X NODEP last;
X
X skipon = 0;
Xmore:
X last = glb_decls();
X if (cur->e_token == EOFTOK)
X return;
X if (last) skipon = 0; /* saw something valid */
X if (last && last->n_tptr && last->n_tptr->t_token == '(') {
X /* possible function definition */
X if (debugs) {
X printf("FUN ");
X put_nnm(last);
X }
X out_fstart(last);
X#ifdef OUT_AZ
X last->e_sc = HERE_SC;
X#else
X last->e_sc = K_EXTERN;
X#endif
X fun_start(last->n_tptr);
X args_blk(last->n_tptr->n_right);
X sub_block();
X fun_end();
X clr_lvl(); /* for args block */
X goto more;
X }
X /* error if get to here */
X if (last) {
X error("missing ;");
X goto more;
X } else {
X skip();
X goto more;
X }
X}
X
Xfun_start(np)
XNODEP np;
X{
X NODEP functy();
X
X funtyp = functy(np);
X curbrk = curcont = -1;
X funtopl = new_lbl();
X funbotl = new_lbl();
X funretl = new_lbl();
X switch (funtyp->t_token) {
X case K_STRUCT:
X case K_UNION:
X funstrl = new_lbl();
X break;
X default:
X funstrl = 0;
X }
X maxregs = 0;
X maxlocs = 0;
X out_br(funbotl);
X def_lbl(funtopl);
X}
X
Xfun_end()
X{
X NODEP np;
X
X if (labels) {
X for (np = labels; np; np = np->n_next)
X if (np->c_defined == 0)
X errorn("undefined label", np);
X freenode(labels);
X labels = NULL;
X }
X def_lbl(funretl);
X out_fret(maxregs, funstrl);
X def_lbl(funbotl);
X out_fend(maxregs, maxlocs);
X out_br(funtopl);
X if (funstrl)
X out_fs(funstrl, funtyp->t_size);
X}
X
Xskip()
X{
X if (skipon == 0) {
X error("syntax (try skipping...)");
X skipon = 1;
X }
X fadvnode();
X}
X
Xblock()
X{
X int some;
X int sawsome;
X
X some = loc_decls();
X if (cur->e_token == EOFTOK)
X return;
X if (some) skipon = 0;
Xmore:
X sawsome = stmts();
X if (sawsome) skipon = 0;
X if (cur->e_token == '}') {
X if (blktab->b_regs > maxregs)
X maxregs = blktab->b_regs;
X if (blktab->b_size + blktab->b_tsize > maxlocs)
X maxlocs = blktab->b_size + blktab->b_tsize;
X return;
X }
X
X /* error if get to here */
X if (cur->e_token == EOFTOK || is_tykw(cur->e_token))
X /* get out of block */
X return;
X else {
X skip();
X goto more;
X }
X}
X
Xclr_lvl()
X{
X NODE *bp;
X
X level--;
X bp = blktab;
X blktab = bp->n_next;
X bp->n_next = NULL;
X if (debugl && bp->b_syms) {
X printf("local syms %d", level);
X printlist(bp->b_syms);
X }
X#ifdef OUT_AZ
X xrefl(bp->b_syms);
X#endif
X freenode(bp->b_syms);
X if (debugl && bp->b_tags) {
X printf("local tags %d", level);
X printlist(bp->b_tags);
X }
X freenode(bp->b_tags);
X freenode(bp);
X}
X
Xeat(c)
X{
X char *p = "assume X";
X
X if (cur->e_token == c)
X fadvnode();
X else {
X p[strlen(p) - 1] = c;
X error(p);
X }
X}
X
Xsub_block()
X{
X register NODE *new;
X
X if (debugs)
X printf("{ ");
X eat('{');
X level++;
X new = allocnode();
X new->n_next = blktab;
X sprintf(new->n_name, "sub{");
X blktab = new;
X block();
X clr_lvl();
X eat('}');
X if (debugs)
X printf("}\n");
X}
X
Xargs_blk(np)
XNODEP np;
X{
X register NODE *p;
X register NODE *new;
X NODE *tp;
X NODEP llook();
X long size;
X int rmask;
X
X size = 0;
X rmask = 0;
X new = allocnode();
X new->n_next = blktab;
X sprintf(new->n_name, "arg{");
X blktab = new;
X level++;
X loc_decls();
X /* make sure all decls were in arg list */
X for (p=new->b_syms; p != NULL; p = p->n_next)
X if (llook(np, p) == NULL)
X errorn("ID not param", p);
X /* now make any names not mentioned INT */
X /* and generate offsets and alloc regs */
X for (p=np; p != NULL; p = p->n_next) {
X if ((tp=llook(new->b_syms, p)) == NULL) {
X def_arg(&new->b_syms, p);
X tp = new->b_syms;
X }
X lc_size(&size, &rmask, tp);
X if (tp->e_sc == K_REGISTER)
X reg_arg(&rmask, tp);
X if (debugv) {
X printf("final o%ld r%d ", tp->e_offs, tp->e_rno);
X put_nnm(tp);
X putchar('\n');
X }
X out_advice(tp);
X }
X new->b_regs = rmask;
X}
X
Xreg_arg(rp, xp)
Xint *rp;
XNODEP xp;
X{
X if (lc_reg(rp, xp) == 0) { /* out of regs? */
X xp->e_sc = K_AUTO;
X return;
X }
X out_argreg(xp);
X}
X
X
Xstmts()
X{
X int didsome;
X
X didsome = 0;
X while (stmt())
X didsome++;
X return didsome;
X}
X
Xstmt_bc(brk,cont)
X{
X int svb, svc;
X
X svb = curbrk;
X svc = curcont;
X curbrk = brk;
X curcont = cont;
X
X stmt();
X
X curbrk = svb;
X curcont = svc;
X}
X
Xstmt_b(brk)
X{
X int svb;
X
X svb = curbrk;
X curbrk = brk;
X
X stmt();
X
X curbrk = svb;
X}
X
X/* do a single statement */
Xstmt()
X{
X register tok;
X NODEP np;
X NODEP getexpr();
X int i;
X
Xmore:
X tok = cur->e_token;
X if (is_stkw(tok)) {
X if (is_blkst(tok)) {
X i = blk_stmt();
X } else if (is_brast(tok)) {
X i = bra_stmt();
X } else if (is_lblst(tok)) {
X i = lbl_stmt();
X } else {
X asm_stmt();
X return 1;
X }
X if (i == 0)
X goto more;
X return 1;
X }
X else if (tok == '{') {
X sub_block();
X return 1;
X } else if (tok == ';') {
X fadvnode();
X return 1;
X }
X np = getexpr();
X if (np) {
X if (cur->e_token == ':') {
X fadvnode();
X label(np);
X goto more;
X }
X expr_stmt(np);
X if (cur->e_token != ';')
X error("missing ;");
X else
X fadvnode();
X return 1;
X }
X return 0;
X}
X
Xexpr_stmt(np)
XNODEP np;
X{
X if (debugs) {
X printf("E_STMT ");
X if (debugs > 1)
X printnode(np);
X }
X do_expr(np, FORSIDE);
X}
X
Xlabel(np)
XNODEP np;
X{
X register NODEP tp;
X NODEP llook();
X
X if (debugs) {
X printf("LABEL ");
X if (debugs > 1)
X printnode(np);
X }
X if (np->e_token != ID) {
X error("weird label");
X return;
X }
X tp = llook(labels, np);
X if (tp) {
X freenode(np);
X if (tp->c_defined) {
X error("duplicate label");
X return;
X }
X } else {
X putlist(&labels, np);
X tp = np;
X tp->c_casel = new_lbl();
X }
X tp->c_defined = 1;
X def_lbl(tp->c_casel);
X}
X
Xblk_stmt()
X{
X register tok;
X int l1, l2, l3;
X NODEP e1, e2, e3;
X NODEP opt_expr(), paren_expr(), def_type();
X struct swittbl locswit, *oldp;
X extern int lineno;
X int svline, svline2;
X
X tok = cur->e_token;
X fadvnode();
X switch (tok) {
X case K_IF:
X if (debugs)
X printf("IF ");
X l1 = new_lbl();
X e1 = paren_expr();
X gen_brf(e1, l1);
X eat(')');
X stmt();
X opt_else(l1);
X return 1;
X case K_WHILE:
X if (debugs)
X printf("WHILE ");
X e1 = paren_expr();
X l1 = new_lbl();
X l2 = new_lbl();
X
X def_lbl(l1);
X gen_brf(e1,l2);
X eat(')');
X
X stmt_bc(l2,l1);
X
X out_br(l1);
X def_lbl(l2);
X return 1;
X case K_DO:
X if (debugs)
X printf("DO ");
X l1 = new_lbl();
X l2 = new_lbl();
X l3 = new_lbl();
X def_lbl(l1);
X
X stmt_bc(l3,l2);
X
X def_lbl(l2);
X eat(K_WHILE);
X e1 = paren_expr();
X gen_brt(e1, l1);
X eat(')');
X eat(';');
X def_lbl(l3);
X return 1;
X case K_FOR:
X if (debugs)
X printf("FOR ");
X l1 = new_lbl();
X l2 = new_lbl();
X l3 = new_lbl();
X eat('(');
X e1 = opt_expr();
X expr_stmt(e1);
X eat(';');
X def_lbl(l1);
X e2 = opt_expr();
X if (e2)
X gen_brf(e2,l3);
X eat(';');
X e3 = opt_expr(); /* save for later */
X svline = lineno;
X eat(')');
X
X stmt_bc(l3,l2);
X
X def_lbl(l2);
X
X svline2 = lineno;
X lineno = svline;
X expr_stmt(e3);
X lineno = svline2;
X
X out_br(l1);
X def_lbl(l3);
X return 1;
X case K_SWITCH:
X if (debugs)
X printf("SWITCH ");
X e1 = paren_expr();
X l1 = new_lbl();
X l2 = new_lbl();
X to_d0(e1, def_type());
X eat(')');
X
X out_br(l2);
X oldp = curswit;
X curswit = &locswit;
X locswit.caselist = NULL;
X locswit.deflbl = -1;
X
X stmt_b(l1);
X
X out_br(l1);
X def_lbl(l2);
X gen_switch(locswit.caselist, locswit.deflbl);
X curswit = oldp;
X def_lbl(l1);
X return 1;
X case K_ELSE:
X error("unexpected 'else'");
X fadvnode();
X return 0;
X }
X}
X
XNODEP
Xparen_expr()
X{
X NODEP np;
X NODEP need_expr();
X
X eat('(');
X np = need_expr();
X return np;
X}
X
Xbra_stmt()
X{
X register tok;
X NODEP np, tp;
X NODEP opt_expr(), llook();
X
X tok = cur->e_token;
X fadvnode();
X switch (tok) {
X case K_BREAK:
X if (debugs)
X printf("BRK");
X eat(';');
X out_br(curbrk);
X return 1;
X case K_CONTINUE:
X if (debugs)
X printf("CONT ");
X eat(';');
X out_br(curcont);
X return 1;
X case K_RETURN:
X if (debugs)
X printf("RETURN ");
X np = opt_expr();
X if (np) {
X if (funstrl)
X ret_stru(np);
X else
X to_d0(np, funtyp);
X }
X out_br(funretl);
X eat(';');
X return 1;
X case K_GOTO:
X if (debugs)
X printf("GOTO ");
X np = cur; advnode();
X if (np->e_token != ID)
X error("bad goto");
X else {
X tp = llook(labels, np);
X if (tp) {
X freenode(np);
X } else {
X tp = np;
X putlist(&labels, tp);
X tp->c_casel = new_lbl();
X }
X out_br(tp->c_casel);
X }
X eat(';');
X return 1;
X }
X}
X
Xlbl_stmt()
X{
X register tok;
X NODEP need_expr(), np;
X int l1, i;
X
X l1 = new_lbl();
X tok = cur->e_token;
Xagain:
X fadvnode();
X switch (tok) {
X case K_CASE:
X if (debugs)
X printf("CASE ");
X np = need_expr();
X i = conxval(np);
X if (curswit)
X add_case(i,l1);
X else
X error("'case' outside switch");
X eat(':');
X break;
X case K_DEFAULT:
X if (debugs)
X printf("DEFAULT ");
X if (curswit) {
X if (curswit->deflbl >= 0)
X error("multiple 'default'");
X curswit->deflbl = l1;
X } else
X error("'default' outside switch");
X eat(':');
X }
X tok = cur->e_token; /* lookahead for more cases */
X if (tok == K_CASE || tok == K_DEFAULT)
X goto again;
X def_lbl(l1);
X return 0;
X}
X
Xasm_stmt()
X{
X NODEP np, getexpr();
X
X fadvnode();
X np = getexpr();
X if (np == NULL || np->e_token != SCON) {
X error("bad asm() func");
X } else {
X out_asm(np);
X freenode(np);
X }
X eat(';');
X}
X
XNODEP
Xopt_expr()
X{
X NODE *np, *getexpr();
X
X np = getexpr();
X if (np) {
X if (debugs) {
X printf("OXPR ");
X if (debugs > 1)
X printnode(np);
X }
X }
X return np;
X}
X
XNODEP
Xneed_expr()
X{
X NODE *np, *getexpr();
X
X np = getexpr();
X if (np) {
X if (debugs) {
X printf("NXPR ");
X if (debugs > 1)
X printnode(np);
X }
X } else
X error("need expr");
X return np;
X}
X
Xopt_else(l1)
X{
X int l2;
X
X if (cur->e_token == K_ELSE) {
X if (debugs)
X printf("ELSE ");
X fadvnode();
X l2 = new_lbl();
X out_br(l2);
X def_lbl(l1);
X stmt();
X def_lbl(l2);
X } else
X def_lbl(l1);
X}
X
Xadd_case(val, lbl)
X{
X NODEP np, last, p;
X
X np = allocnode();
X np->c_casev = val;
X np->c_casel = lbl;
X sprintf(np->n_name, "%d:%d", val, lbl);
X
X last = NULL;
X for (p = curswit->caselist; p; last=p, p=p->n_next)
X if (p->c_casev == val) {
X error("duplicate case");
X return;
X } else if (p->c_casev > val)
X break;
X if (last) {
X last->n_next = np;
X np->n_next = p;
X } else {
X curswit->caselist = np;
X np->n_next = p;
X }
X if (debugs) {
X printf("CASELIST\n");
X printnode(curswit->caselist);
X }
X}
X
Xto_d0(np, typ)
XNODEP np, typ;
X{
X NODEP tp;
X
X tp = allocnode();
X tp->e_token = TCONV;
X tp->n_tptr = typ;
X tp->n_flags |= N_COPYT;
X tp->n_left = np;
X tp->e_type = E_UNARY;
X strcpy(tp->n_name, "r cast");
X
X do_expr(tp, IND0);
X}
X
Xret_stru(np)
XNODEP np;
X{
X p2_expr(&np);
X if (same_type(np->n_tptr, funtyp) == 0) {
X error("bad struct return type");
X return;
X }
X genx(np, RETSTRU);
X}
END_OF_FILE
if test 11588 -ne `wc -c <'hcc/FUN.C'`; then
echo shar: \"'hcc/FUN.C'\" unpacked with wrong size!
fi
# end of 'hcc/FUN.C'
fi
if test -f 'hcc/G2.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hcc/G2.C'\"
else
echo shar: Extracting \"'hcc/G2.C'\" \(11766 characters\)
sed "s/^X//" >'hcc/G2.C' <<'END_OF_FILE'
X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
X *
X * Permission is granted to anyone to use this software for any purpose
X * on any computer system, and to redistribute it freely, with the
X * following restrictions:
X * 1) No charge may be made other than reasonable charges for reproduction.
X * 2) Modified versions must be clearly marked as such.
X * 3) The authors are not responsible for any harmful consequences
X * of using this software, even if they result from defects in it.
X *
X * g2.c
X *
X * Generate code for binary nodes.
X */
X
X#include <stdio.h>
X#include "param.h"
X#include "nodes.h"
X#include "flags.h"
X#include "bstok.h"
X#include "gen.h"
X#include "ops.h"
X
X#define FAIL 0
X#define OKAY 1
X
Xextern int cookflags[];
X
X#define isimmed(np) ((np)->g_flags & IMMEDID)
X#define isareg(np) ((np)->g_token == REGVAR && (np)->g_rno >= AREG)
X
Xstruct bop {
X char *s_op, *u_op;
X int opflags;
X} bops[] = {
X {"muls", "mulu", EOPD |ASSOC},
X {"divs", "divu", EOPD},
X {"divs", "divu", EOPD},
X {"and", "and", EOPD|DOPE|IOPE |ASSOC},
X {"or", "or", EOPD|DOPE|IOPE |ASSOC},
X {"eor", "eor", DOPE|IOPE |ASSOC},
X {"add", "add", EOPD|DOPE|EOPA|IOPE|AOPA|AOPD |ASSOC},
X {"sub", "sub", EOPD|DOPE|EOPA|IOPE|AOPA|AOPD},
X {"asl", "lsl", DOPD|QOPD|ONEOPM},
X {"asr", "lsr", DOPD|QOPD|ONEOPM},
X};
X
Xchar *tstnm[] = {
X "lt", /* < */
X "gt", /* > */
X "le", /* <= */
X "ge", /* >= */
X "eq", /* == */
X "ne", /* != */
X};
X
Xint tstx[] = {
X B_LT, B_GT, B_LE, B_GE, B_EQ, B_NE
X};
X
Xchar *utstnm[] = {
X "cs", /* < */
X "hi", /* > */
X "ls", /* <= */
X "cc", /* >= */
X "eq", /* == */
X "ne", /* != */
X};
X
Xint utstx[] = {
X B_ULT, B_UGT, B_ULE, B_UGE, B_EQ, B_NE
X};
X
Xb_eval(np, cookie)
Xregister NODEP np;
X{
X NODEP lp = np->n_left, rp = np->n_right;
X NODEP tp;
X int lcook = FORADR, rcook = FORADR;
X
X switch (np->g_token) { /* special cookies */
X case DOUBLE '&':
X case DOUBLE '|':
X lcook = rcook = FORCC;
X break;
X case '?':
X lcook = FORCC;
X break;
X case '(':
X rcook = FORPUSH;
X break;
X case ',':
X if (np->g_offs) /* function args */
X lcook = rcook = FORPUSH;
X else {
X lcook = FORSIDE;
X rcook = cookie;
X }
X break;
X case '=':
X rcook = FORIMA;
X break;
X case '+':
X case '-':
X tp = rp;
X while (tp->g_token == TCONV && tp->g_ty != ET_F)
X tp = tp->n_left;
X if (tp->g_token == ICON)
X lcook = FORIMA;
X break;
X }
X
X if (np->g_type == EV_LR) {
X if (eval(lp,lcook) == FAIL)
X return FAIL;
X freetmps(lp);
X if (eval(rp,rcook) == FAIL)
X return FAIL;
X freetmps(rp);
X } else if (np->g_type == EV_RL) {
X if (eval(rp,rcook) == FAIL)
X return FAIL;
X freetmps(rp);
X if (eval(lp,lcook) == FAIL)
X return FAIL;
X freetmps(lp);
X } else { /* EV_LRSEP */
X if (eval(lp,lcook) == FAIL)
X return FAIL;
X freetmps(lp);
X free1(NULL, lp);
X if (eval(rp,rcook) == FAIL)
X return FAIL;
X freetmps(rp);
X }
X return b_sube(np, cookflags[cookie]);
X}
X
Xb_sube(np, flags)
Xregister NODEP np;
X{
X NODEP lp = np->n_left, rp = np->n_right;
X register int i, r;
X int argsize;
X char buf[40];
X
X if (isassign(np->g_token))
X return as_eval(np);
X
X switch (np->g_token) {
X case '=':
X if (specasn(np, flags) || strasn(np))
X return OKAY;
X inherit(np);
X addcode(np, "\tmove.S\t>A,<A\n");
X return OKAY;
X
X case '(':
X argsize = argmod(rp);
X free1(NULL,rp);
X if (np->g_ty == ET_A) { /* struct returned */
X frc_ral(AREG);
X indir(np, AREG);
X } else {
X frc_ral(0);
X retreg(np, 0);
X }
X sprintf(buf, "\tjsr\t<A\n\tadd.w\t#%d,sp\n", argsize);
X addcode(np, buf);
X return OKAY;
X
X case ',':
X if (np->g_offs == 0) /* normal ',' */
X rinherit(np);
X return OKAY;
X
X case DOUBLE '&':
X free1(NULL, rp);
X r = ralloc(0);
X retreg(np, r);
X holdlbls(np);
X np->g_betw = iscc(lp) ? "<FL1\n" :
X "<Q\tbeq\tL1\n";
X addcode(np, iscc(rp) ? ">FL1\n" :
X ">Q\tbeq\tL1\n");
X addcode(np, "\tmoveq\t#1,A\n");
X addcode(np, "\tbra\tL2\nL1:\tclr\tA\nL2:\n");
X return OKAY;
X
X case DOUBLE '|':
X free1(NULL, rp);
X r = ralloc(0);
X retreg(np, r);
X holdlbls(np);
X np->g_betw = iscc(lp) ? "<TL1\n" :
X "<Q\tbne\tL1\n";
X addcode(np, iscc(rp) ? ">TL1\n" :
X ">Q\tbne\tL1\n");
X addcode(np, "\tclr\tA\n");
X addcode(np, "\tbra\tL2\nL1:\tmoveq\t#1,A\nL2:\n");
X return OKAY;
X
X case '?':
X rinherit(np);
X rinhlbls(np);
X np->g_betw = iscc(lp) ? "<FL1\n" : "<Q\tbeq\tL1\n";
X return OKAY;
X
X case ':':
X free1(NULL, rp);
X r = ralloc(0);
X retreg(np, r);
X holdlbls(np);
X np->g_betw = same_a(np, lp) ?
X "\tbra\tL2\nL1:\n" :
X "\tmove.S\t<A,A\n\tbra\tL2\nL1:\n";
X if (!same_a(np, rp))
X addcode(np, "\tmove.S\t>A,A\n");
X addcode(np, "L2:\n");
X return OKAY;
X
X case '<':
X i = 0; goto dotst;
X case '>':
X i = 1; goto dotst;
X case LTEQ:
X i = 2; goto dotst;
X case GTEQ:
X i = 3; goto dotst;
X case DOUBLE '=':
X i = 4; goto dotst;
X case NOTEQ:
X i = 5;
Xdotst:
X fix_cmp(np, EOPD|EOPA|IOPE|AOPA|AOPD);
X if (flags & CC_OK) {
X np->g_token = (lp->g_ty == ET_U ?
X utstx[i] : tstx[i]) + BR_TOK;
X } else {
X strcpy(np->n_name, lp->g_ty == ET_U ?
X utstnm[i] : tstnm[i]);
X r = ralloc(0);
X retreg(np, r);
X addcode(np, "\tsN\tA\n\tand.w\t#1,A\n");
X }
X return OKAY;
X
X case '*':
X return fixmul(np, bops[0].opflags);
X case '/':
X return fixdiv(np, bops[1].opflags);
X case '%':
X return fixmod(np, bops[2].opflags);
X case '&': i = 3; goto doop;
X case '|': i = 4; goto doop;
X case '^': i = 5; goto doop;
X case '+':
X if (optadd(np, flags, 1))
X return OKAY;
X i = 6; goto doop;
X case '-':
X if (optadd(np, flags, -1))
X return OKAY;
X i = 7; goto doop;
X case DOUBLE '<':i = 8; goto doop;
X case DOUBLE '>':i = 9;
Xdoop:
X strcpy(np->n_name, np->g_ty == ET_U ?
X bops[i].u_op : bops[i].s_op);
X r = fix2ops(np, bops[i].opflags);
X cc_hack(np);
X return r;
X case FIELDAS:
X return fldasn(np, flags);
X default:
X printf("Weird b_eval %s ", np->n_name);
X return FAIL;
X }
X}
X
Xas_eval(np)
Xregister NODEP np;
X{
X NODEP rp = np->n_right;
X register int op, i, r;
X
X rp = np->n_right;
X
X op = np->g_token;
X op -= ASSIGN 0;
X switch (op) {
X
X /* these get unfolded now */
X case '*':
X return fixamul(np, bops[0].opflags);
X case '/':
X return fixadiv(np, bops[1].opflags);
X case '%':
X return fixamod(np, bops[2].opflags);
X case '&': i = 3; goto doop;
X case '|': i = 4; goto doop;
X case '^': i = 5; goto doop;
X case '+': i = 6; goto doop;
X case '-': i = 7; goto doop;
X case DOUBLE '<':i = 8; goto doop;
X case DOUBLE '>':i = 9;
Xdoop:
X strcpy(np->n_name, np->g_ty == ET_U ?
X bops[i].u_op : bops[i].s_op);
X r = fix_asn(np, bops[i].opflags);
X cc_hack(np);
X return r;
X
X default:
X printf("Weird as_eval %s ", np->n_name);
X return FAIL;
X }
X}
X
Xrinherit(np)
Xregister NODEP np;
X{
X register NODEP rp = np->n_right;
X
X np->g_token = rp->g_token;
X np->g_offs = rp->g_offs;
X np->g_rno = rp->g_rno;
X np->g_flags |= RCHILDNM | (rp->g_flags & IMMEDID);
X}
X
Xargmod(np)
Xregister NODEP np;
X{
X int size = 0;
X
X if (np->g_token == ',') {
X np->g_type = EV_RL;
X size += argmod(np->n_right);
X size += argmod(np->n_left);
X return size;
X }
X size += onearg(np);
X return size;
X}
X
Xonearg(np)
Xregister NODEP np;
X{
X int rv;
X
X /* hack small ICON */
X if (np->g_sz == 1 && np->g_token == ICON)
X np->g_sz = 2;
X /* hack push of 0 */
X if (np->g_token == ICON && np->g_offs == 0 && isimmed(np)) {
X addcode(np, "\tclr.S\t-(sp)\n");
X return (int)np->g_sz;
X }
X /* hack push of #OREG */
X if (np->g_token == OREG && isimmed(np)) {
X np->g_flags &= ~IMMEDID;
X addcode(np, "\tpea\tA\n");
X return 4;
X }
X
X if (np->g_ty == ET_A) {
X rv = strpush(np);
X freetmps(np);
X free1(NULL,np);
X return rv;
X }
X
X switch (np->g_sz) {
X case 1:
X addcode(np, (np->g_ty == ET_U) ?
X "\tclr.w\td0\n\tmove.b\tA,d0\n\tmove.w\td0,-(sp)\n" :
X "\tmove.b\tA,d0\n\text.w\td0\n\tmove.w\td0,-(sp)\n" );
X return 2;
X case 2:
X addcode(np,
X "\tmove.w\tA,-(sp)\n");
X return 2;
X default:
X addcode(np,
X "\tmove.l\tA,-(sp)\n");
X return 4;
X }
X}
X
X#define MAXD DRV_START
X#define MAXA (ARV_START-AREG)
X#define NEEDALL (MAXA*AREG + MAXD)
X
Xorder(np)
Xregister NODEP np;
X{
X int l, r;
X
X switch (np->g_type) {
X case E_BIN:
X order(np->n_right);
X r = np->n_right->g_needs;
X case E_UNARY:
X order(np->n_left);
X l = np->n_left->g_needs;
X break;
X default: /* leaf */
X np->g_type = EV_NONE;
X np->g_needs = 0;
X return;
X }
X
X if (np->g_type == E_UNARY) {
X switch (np->g_token) {
X case STAR:
X case UNARY '&':
X np->g_needs = merge(l,AREG);
X break;
X case '(':
X np->g_needs = NEEDALL;
X break;
X case POSTINC:
X case POSTDEC:
X case '!':
X case TCONV:
X np->g_needs = merge(l,1);
X break;
X case '.':
X if (np->g_fldw) {
X np->g_needs = merge(l,1);
X break;
X }
X /* else fall through */
X default:
X np->g_needs = l;
X }
X np->g_type = EV_LEFT;
X return;
X }
X
X/* at this point, have binary node */
X
X switch (np->g_token) {
X case DOUBLE '&':
X case DOUBLE '|':
X case '?':
X case ':':
X /* always left-right, no extra regs */
X np->g_type = EV_LRSEP;
X np->g_needs = merge(1, merge(l,r));
X return;
X case ',':
X np->g_needs = merge(l, r);
X np->g_type = EV_LRSEP;
X return;
X case '(':
X np->g_needs = NEEDALL;
X break;
X case '^':
X case DOUBLE '<':
X case DOUBLE '>':
X case ASSIGN '/':
X case ASSIGN DOUBLE '<':
X case ASSIGN DOUBLE '>':
X np->g_needs = merge(bin(l,r), 2);
X break;
X default:
X if (isassign(np->g_token) || np->g_token == '=')
X np->g_needs = merge(rbin(l,r), 1);
X else
X np->g_needs = merge(bin(l,r), 1);
X }
X
X if (isassign(np->g_token) || np->g_token == '=')
X np->g_type = EV_RL; /* NO PUSHER's on L */
X else
X np->g_type = worst_1st(l, r);
X flag_saves(np, l, r);
X}
X
Xflag_saves(np, l, r)
XNODEP np;
X{
X NODEP *cpp;
X register int other;
X
X if (np->g_type == EV_LR) {
X cpp = &np->n_left;
X other = r;
X } else {
X cpp = &np->n_right;
X other = l;
X }
X if ((other & 7) >= MAXD || (other/AREG) >= MAXA)
X addtmp(np, cpp);
X}
X
Xaddtmp(np, cpp)
XNODEP np, *cpp;
X{
X NODEP cp, tp;
X NODEP copyone();
X
X cp = *cpp;
X tp = copyone(cp);
X tp->n_left = cp;
X *cpp = tp;
X tp->g_token = PUSHER;
X strcpy(tp->n_name, "pusher");
X tp->g_type = EV_LEFT;
X}
X
Xworst_1st(l,r)
X{
X int ld, rd;
X
X ld = l & 7;
X rd = r & 7;
X if (rd > ld)
X return EV_RL;
X if (r > l)
X return EV_RL;
X return EV_LR;
X}
X
Xbin(l,r)
X{
X int la, ra, na;
X int ld, rd, nd;
X int rfirst;
X
X la = l/AREG;
X ra = r/AREG;
X ld = l & 7;
X rd = r & 7;
X rfirst = (ra > la) || (rd > ld);
X return rfirst ? rbin(l,r) : rbin(r,l);
X}
X
Xrbin(last,first)
X{
X int la, fa, na;
X int ld, fd, nd;
X
X la = last/AREG;
X fa = first/AREG;
X ld = last & 7;
X fd = first & 7;
X na = fa > la ? fa : la + (fa ? 1 : 0);
X if (na > MAXA)
X na = MAXA;
X nd = fd > ld ? fd : ld + (fd ? 1 : 0);
X if (nd > MAXD)
X nd = MAXD;
X return na*AREG + nd;
X}
X
Xmerge(need, have)
X{
X int na, nd, ha, hd, xa, xd;
X
X na = need/AREG;
X ha = have/AREG;
X nd = need & 7;
X hd = have & 7;
X xa = na > ha ? na : ha;
X xd = nd > hd ? nd : hd;
X return xa*AREG + xd;
X}
X
Xholdlbls(np)
XNODEP np;
X{
X np->g_bsize = new_lbl();
X new_lbl();
X}
X
Xrinhlbls(np)
XNODEP np;
X{
X np->g_bsize = np->n_right->g_bsize;
X}
X
X/* limited version of same address check
X assume one of these is a temp register */
Xsame_a(p1, p2)
XNODEP p1, p2;
X{
X if (p1->g_token != p2->g_token)
X return 0;
X if (p1->g_rno != p2->g_rno)
X return 0;
X return 1;
X}
X
Xoptadd(np, flags, sign)
Xregister NODEP np;
X{
X NODEP lp = np->n_left, rp = np->n_right;
X
X if (rp->g_token != ICON)
X return 0;
X if (isimmed(lp) && isimmed(rp)) {
X switch (lp->g_token) {
X case OREG:
X case ONAME:
X inherit(np);
X if (sign == -1)
X rp->g_offs = -rp->g_offs;
X np->g_offs += rp->g_offs;
X
X if ((flags & IMMA_OK) == 0)
X imm_oreg(np);
X return 1;
X default:
X return 0;
X }
X }
X return 0;
X}
X
Xiscc(np)
XNODEP np;
X{
X return (np->g_token >= BR_TOK) || (np->g_flags & SIDE_CC);
X}
X
Xcc_hack(np)
XNODEP np;
X{
X if (isareg(np))
X return;
X np->g_flags |= SIDE_CC;
X}
X
Xcctok(np)
XNODEP np;
X{
X if (np->g_token >= BR_TOK)
X return np->g_token - BR_TOK;
X if (np->g_flags & SIDE_CC)
X return B_NE;
X printf("cctok error ");
X return 0;
X}
END_OF_FILE
if test 11766 -ne `wc -c <'hcc/G2.C'`; then
echo shar: \"'hcc/G2.C'\" unpacked with wrong size!
fi
# end of 'hcc/G2.C'
fi
if test -f 'hcc/GEN.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hcc/GEN.C'\"
else
echo shar: Extracting \"'hcc/GEN.C'\" \(11959 characters\)
sed "s/^X//" >'hcc/GEN.C' <<'END_OF_FILE'
X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
X *
X * Permission is granted to anyone to use this software for any purpose
X * on any computer system, and to redistribute it freely, with the
X * following restrictions:
X * 1) No charge may be made other than reasonable charges for reproduction.
X * 2) Modified versions must be clearly marked as such.
X * 3) The authors are not responsible for any harmful consequences
X * of using this software, even if they result from defects in it.
X *
X * gen.c
X *
X * Generate code.
X * Includes main routine and code generation for unary nodes
X * and leafs.
X */
X
X#include <stdio.h>
X#include "param.h"
X#include "bstok.h"
X#include "tytok.h"
X#include "flags.h"
X#include "nodes.h"
X#include "gen.h"
X
XNODEP strsave;
Xint cctest;
Xstatic int reserve;
Xstatic int tmpused;
X
Xextern xflags[];
X#define debug xflags['g'-'a']
X
X#define FAIL 0
X#define OKAY 1
X
X#define isimmed(np) ((np)->g_flags & IMMEDID)
X#define isareg(np) ((np)->g_token == REGVAR && (np)->g_rno >= AREG)
X#define isdreg(np) ((np)->g_token == REGVAR && (np)->g_rno < AREG)
X#define istdreg(np) ((np)->g_token == REGVAR && (np)->g_rno < DRV_START)
X
Xint cookflags[] = {
X 0,
X NOVAL_OK|CC_OK|IMMA_OK, /* FORSIDE */
X IMMA_OK, /* FORPUSH */
X CC_OK, /* FORCC */
X IMMA_OK, /* FORIMA */
X 0, /* FORADR */
X IMMA_OK, /* FORINIT */
X 0, /* IND0 */
X 0, /* RETSTRU */
X};
X
Xgenx(np, cookie)
Xregister NODEP np;
X{
X extern nmerrors;
X int rv;
X extern NODE *blktab;
X
X if (np == NULL) return;
X if (nmerrors)
X goto bad;
X if (debug) {
X printf("GEN enter");
X printnode(np);
X }
X
X untype(np);
X if (debug>1) {
X printf("after UNTYPE");
X printnode(np);
X }
X
X tmpused = 0;
X gunk(np);
X if (tmpused && tmpused > blktab->b_tsize)
X blktab->b_tsize = tmpused;
X if (debug > 1) {
X printf("after gunk");
X printnode(np);
X }
X order(np);
X
X reserve = 0;
X rv = eval(np, cookie);
X if (rv == OKAY && debug) {
X printf("GEN exit");
X codeprint(np);
X }
X if (rv == OKAY)
X rv = cookmon(np, cookie);
X else
X error("couldnt eval node");
X freenode(np);
X return rv;
Xbad:
X freenode(np);
X return FAIL;
X}
X
Xeval(np, cookie)
Xregister NODEP np;
X{
X int rv;
X
X np->g_r1 = np->g_r2 = -1;
X
X if (np == NULL) return FAIL;
X
X switch (np->g_type) {
X
X default:
X rv = b_eval(np, cookie);
X /* already did freetmps */
X free1(np, np->n_left);
X free1(np, np->n_right);
X break;
X
X case EV_LEFT:
X rv = u_eval(np, cookie);
X freetmps(np);
X free1(np, np->n_left);
X break;
X
X case EV_NONE:
X rv = l_eval(np);
X break;
X }
X return rv;
X}
X
Xu_eval(np, cookie)
Xregister NODEP np;
X{
X int subcook = FORADR;
X
X switch (np->g_token) {
X case STAR:
X subcook = FORIMA;
X break;
X case '!':
X subcook = FORCC;
X break;
X }
X
X if (eval(np->n_left, subcook) == FAIL)
X return FAIL;
X return u_sube(np, cookflags[cookie]);
X}
X
Xu_sube(np, flags)
Xregister NODEP np;
X{
X register NODEP lp = np->n_left;
X long offs;
X int i;
X
X switch (np->g_token) {
X case '.':
X if (np->g_fldw)
X return fldget(np, flags);
X offs = np->g_offs;
X inherit(np);
X np->g_offs += offs;
X return OKAY;
X case STAR:
X if (isimmed(lp)) {
X inherit(np);
X np->g_flags &= ~IMMEDID;
X } else if (isareg(lp)) {
X indir(np, lp->g_rno);
X } else { /* NEED A temp */
X if (lp->g_token == OREG && istemp(lp->g_rno))
X i = lp->g_rno;
X else
X i = ralloc(AREG);
X addcode(np, "\tmove.l\t<A,R0\n");
X indir(np, i);
X }
X return OKAY;
X case UNARY '&':
X if (isimmed(lp))
X warn("& ignored");
X else if (lp->g_token == REGVAR)
X return FAIL;
X inherit(np);
X np->g_flags |= IMMEDID;
X if ((flags & IMMA_OK) == 0)
X imm_oreg(np);
X return OKAY;
X case '~':
X utemp(np);
X addcode(np, "\tnot.S\tA\n");
X cc_hack(np);
X return OKAY;
X case UNARY '-':
X utemp(np);
X addcode(np, "\tneg.S\tA\n");
X cc_hack(np);
X return OKAY;
X case TCONV:
X castgen(np);
X return OKAY;
X case PUSHER: /* must not be on left of assign or asn-op */
X if ((lp->g_token != OREG && lp->g_token != REGVAR) ||
X istemp(lp->g_rno) == 0) {
X inherit(np);
X return OKAY;
X }
X if (lp->g_ty == ET_A)
X strxpush(np);
X else
X addcode(np, "\tmove.S\t<A,-(sp)\n");
X return OKAY;
X case '(':
X if (np->g_ty == ET_A) { /* struct returned */
X frc_ral(AREG);
X indir(np, AREG);
X } else {
X frc_ral(0);
X retreg(np, 0);
X }
X addcode(np, "\tjsr\t<A\n");
X return OKAY;
X case DOUBLE '+':
X holdcon(np);
X inherit(np);
X addcode(np, "\tadd.S\t#K,A\n");
X cc_hack(np);
X return OKAY;
X case DOUBLE '-':
X holdcon(np);
X inherit(np);
X addcode(np, "\tsub.S\t#K,A\n");
X cc_hack(np);
X return OKAY;
X case POSTINC:
X if ((flags & NOVAL_OK) == 0) {
X i = ralloc(0);
X retreg(np, i);
X addcode(np, "\tmove.S\t<A,A\n");
X }
X addcode(np, "\tadd.S\t#O,<A\n");
X return OKAY;
X case POSTDEC:
X if ((flags & NOVAL_OK) == 0) {
X i = ralloc(0);
X retreg(np, i);
X addcode(np, "\tmove.S\t<A,A\n");
X }
X addcode(np, "\tsub.S\t#O,<A\n");
X return OKAY;
X case CMPBR:
X i = ralloc(0);
X retreg(np, i);
X addcode(np, "\tsN\tA\n\tand.w\t#1,A\n");
X cc_hack(np);
X return OKAY;
X case '!':
X if (flags & CC_OK) {
X if (iscc(lp)) {
X i = cctok(lp);
X i = (i&1) ? i+1 : i-1; /* reverse truth */
X } else {
X i = B_EQ;
X addcode(np, "<Q");
X }
X np->g_token = i + BR_TOK;
X } else {
X if (istdreg(lp))
X i = lp->g_rno;
X else
X i = ralloc(0);
X retreg(np, i);
X if (iscc(lp)) {
X addcode(np, "<EA\n\tand.w\t#1,A\n");
X } else {
X addcode(np, "<Q");
X addcode(np, "\tseq\tA\n\tand.w\t#1,A\n");
X }
X }
X return OKAY;
X default:
X printf("Weird u_eval %s ", np->n_name);
X return FAIL;
X }
X}
X
Xholdcon(np)
XNODEP np;
X{
X np->g_bsize = np->g_offs;
X}
X
Xretreg(np, rno)
XNODEP np;
X{
X np->g_token = REGVAR;
X np->g_rno = rno;
X}
X
Xindir(np, rno)
Xregister NODEP np;
X{
X np->g_token = OREG;
X np->g_offs = 0;
X np->g_rno = rno;
X}
X
Xinherit(np)
Xregister NODEP np;
X{
X NODEP lp = np->n_left;
X
X np->g_token = lp->g_token;
X np->g_offs = lp->g_offs;
X np->g_rno = lp->g_rno;
X np->g_flags |= CHILDNM | (lp->g_flags & IMMEDID);
X}
X
Xcookmon(np, cookie)
Xregister NODEP np;
X{
X extern FILE *output;
X
X if (np == NULL) return FAIL;
X
X switch (cookie) {
X case FORCC:
X if (iscc(np)) {
X outcode(np);
X cctest = cctok(np);
X } else {
X if (np->g_token == ICON && isimmed(np)) {
X cctest = np->g_offs ? B_YES : B_NO;
X return OKAY;
X }
X outcode(np);
X outsub("Q", np);
X cctest = B_NE;
X }
X return OKAY;
X case FORINIT:
X if (anycode(np) == 0 && (np->g_flags & IMMEDID)) {
X out_a(np, output);
X return OKAY;
X }
X error("bad INIT expr");
X return FAIL;
X case IND0:
X outcode(np);
X if (np->g_token != REGVAR ||
X np->g_rno != 0)
X if (np->g_token == ICON && np->g_offs == 0 &&
X isimmed(np))
X outsub("\tclr.S\td0\n", np);
X else
X outsub("\tmove.S\tA,d0\n", np);
X return OKAY;
X case RETSTRU:
X freetmps(np);
X strret(np);
X outcode(np);
X return OKAY;
X }
X outcode(np);
X return OKAY;
X}
X
Xanycode(np)
Xregister NODEP np;
X{
X if (np->g_code)
X return 1;
X switch (np->g_type) {
X case EV_NONE:
X return 0;
X case EV_LEFT:
X return anycode(np->n_left);
X case EV_RIGHT:
X return anycode(np->n_right);
X case EV_LR:
X case EV_RL:
X return anycode(np->n_left) || anycode(np->n_right);
X }
X}
X
Xl_eval(np)
Xregister NODEP np;
X{
X int l1;
X
X switch (np->g_token) {
X case ID:
X switch (np->g_sc) {
X default: /* EXTERN or HERE */
X np->g_token = ONAME;
X np->g_offs = 0;
X if (np->n_name[0] != '%')
X nnmins(np, "_");
X else /* hack for inline name */
X strcpy(np->n_name, &np->n_name[1]);
X return OKAY; /* dont free n_nmx */
X case K_STATIC:
X sprintf(np->n_name, "L%d", (int)np->g_offs);
X np->g_offs = 0;
X np->g_token = ONAME;
X break;
X case K_AUTO:
X np->g_rno = FRAMEP;
X np->g_token = OREG;
X break;
X case K_REGISTER:
X np->g_token = REGVAR;
X break;
X }
X if (np->n_nmx) {
X freenode(np->n_nmx);
X np->n_nmx = NULL;
X }
X return OKAY;
X case ICON:
X np->g_flags |= IMMEDID;
X return OKAY;
X case FCON:
X np->g_flags |= IMMEDID;
X return OKAY;
X case SCON:
X np->g_flags |= IMMEDID;
X np->g_token = ONAME;
X l1 = new_lbl();
X save_scon(np, l1);
X sprintf(np->n_name, "L%d", l1);
X return OKAY;
X case OREG:
X return OKAY;
X }
X return FAIL;
X}
X
Xsave_scon(np, lbl)
XNODEP np;
X{
X NODEP tp, copyone();
X
X tp = copyone(np);
X tp->g_offs = lbl;
X if (np->n_nmx) {
X freenode(np->n_nmx);
X np->n_nmx = NULL;
X }
X putlist(&strsave, tp);
X}
X
Xutemp(np)
XNODEP np;
X{
X NODEP lp = np->n_left;
X int i;
X
X if (lp->g_token == REGVAR &&
X istemp(lp->g_rno)) {
X inherit(np);
X return;
X }
X i = ralloc(0);
X retreg(np, i);
X addcode(np, "\tmove.S\t<A,A\n");
X}
X
Xfreetmps(np)
Xregister NODEP np;
X{
X if (np->g_r1 != -1)
X rfree(np->g_r1);
X if (np->g_r2 != -1)
X rfree(np->g_r2);
X}
X
Xfree1(np, cp)
XNODEP np, cp;
X{
X int cr;
X
X if (cp->g_token != OREG && cp->g_token != REGVAR)
X return;
X cr = cp->g_rno;
X if (np && cr == np->g_rno &&
X (np->g_token == OREG || np->g_token == REGVAR))
X return;
X if (istemp(cr))
X rfree(cr);
X}
X
Xistemp(rno)
X{
X return (rno < DRV_START ||
X (rno >= AREG && rno < ARV_START));
X}
X
Xrfree(rno)
X{
X reserve &= ~(1<<rno);
X}
X
Xfrc_ral(rno)
X{
X int i;
X
X i = (1<<rno);
X if (reserve & i)
X error("rno reserved! ");
X reserve |= i;
X}
X
Xtempr(np, type)
XNODEP np;
X{
X int i;
X
X i = ralloc(type);
X if (np->g_r1 == -1)
X np->g_r1 = i;
X else
X np->g_r2 = i;
X return i;
X}
X
Xralloc(type)
X{
X int starti, endi;
X register int i;
X
X if (type == AREG) {
X starti = AREG;
X endi = ARV_START;
X } else {
X starti = 0;
X endi = DRV_START;
X }
X for (i=starti; i<endi; i++)
X if ((reserve & (1<<i)) == 0) {
X reserve |= (1<<i);
X return i;
X }
X error("Compiler failure - rallo");
X return -1;
X}
X
Xtmp_alloc(sz)
X{
X extern NODE *blktab;
X
X tmpused += sz;
X return blktab->b_size + tmpused;
X}
X
X/* fixes nodes with no code or aX is temp that are #d(aX) */
Ximm_oreg(np)
XNODEP np;
X{
X char *regnm(), buf[30];
X int i;
X
X if (np->g_token != OREG)
X return;
X if ((np->g_flags & IMMEDID) == 0)
X return;
X np->g_flags &= ~IMMEDID;
X if (np->g_offs == 0) { /* #(a0) -> a0 */
X np->g_token = REGVAR;
X return;
X }
X if (istemp(np->g_rno)) {
X holdcon(np);
X addcode(np, "\tadd\t#K,A\n");
X np->g_token = REGVAR;
X return;
X }
X sprintf(buf, "\tlea\t%d(%s),A\n", (int)np->g_offs, regnm(np->g_rno));
X addcode(np, buf);
X i = ralloc(AREG);
X retreg(np, i);
X}
X
Xcastgen(tp)
Xregister NODEP tp;
X{
X register NODEP np = tp->n_left;
X int sz = tp->g_sz;
X int i;
X
X if (np->g_token == ICON && isimmed(np)) {
X if (tp->g_ty == ET_F) {
X tp->g_token = FCON;
X *(float *)&tp->g_offs = (float)np->g_offs;
X tp->g_flags |= IMMEDID;
X } else {
X inherit(tp);
X i_exp(tp, np->g_sz, np->g_ty);
X squish(tp);
X }
X } else if (np->g_token == FCON && isimmed(np)) {
X if (tp->g_ty != ET_F) {
X tp->g_token = ICON;
X tp->g_offs = (long)*(float *)&np->g_offs;
X tp->g_flags |= IMMEDID;
X squish(tp);
X } else {
X inherit(tp);
X }
X } else if (sz > np->g_sz) {
X if (np->g_ty == ET_U) {
X i = ralloc(0);
X retreg(tp, i);
X addcode(tp, "\tclr.S\tA\n\tmove.<S\t<A,A\n");
X } else {
X if (isdreg(np)) {
X inherit(tp);
X } else {
X i = ralloc(0);
X retreg(tp, i);
X addcode(tp, "\tmove.<S\t<A,A\n");
X }
X if (sz == 4 && np->g_sz == 1)
X addcode(tp, "\text.w\tA\n\text.l\tA\n");
X else
X addcode(tp, "\text.S\tA\n");
X }
X return;
X }
X else if (sz < np->g_sz) {
X switch (np->g_token) {
X case ONAME:
X case OREG:
X if (isimmed(np)) {
Xsmfudge:
X i = ralloc(0);
X retreg(tp, i);
X addcode(tp, "\tmove.<S\t<A,A\n");
X return;
X }
X inherit(tp);
X tp->g_offs = np->g_offs + (np->g_sz - sz);
X break;
X case REGVAR:
X if (sz == 1 && np->g_rno >= AREG)
X goto smfudge;
X /* fall through */
X default:
X inherit(tp);
X }
X } else
X inherit(tp);
X}
X
Xsquish(np)
XNODEP np;
X{
X int neg;
X
X neg = (np->g_ty == ET_S && np->g_offs < 0);
X
X switch (np->g_sz) {
X case 1:
X if (neg)
X np->g_offs |= 0xffffff00L;
X else
X np->g_offs &= 0xff;
X break;
X case 2:
X if (neg)
X np->g_offs |= 0xffff0000L;
X else
X np->g_offs &= 0xffffL;
X break;
X }
X}
X
Xi_exp(np, osz, oty)
XNODEP np;
X{
X long l;
X
X if (oty == ET_S && osz < np->g_sz) {
X l = np->g_offs;
X switch (osz) {
X case 1:
X l = (char) l;
X break;
X case 2:
X l = (short) l;
X break;
X }
X np->g_offs = l;
X }
X}
END_OF_FILE
if test 11959 -ne `wc -c <'hcc/GEN.C'`; then
echo shar: \"'hcc/GEN.C'\" unpacked with wrong size!
fi
# end of 'hcc/GEN.C'
fi
echo shar: End of archive 5 \(of 9\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 9 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0