File:  [MW Coherent from dump] / coherent / d / bin / cc / c / n2 / getfun.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * The routines in this file handle
 * the reading in of functions. The internal data
 * structures are built and threaded together.
 */
#ifdef   vax
#include "INC$LIB:cc2.h"
#else
#include "cc2.h"
#endif

/*
 * Read in a function.
 * Pack it into the internal data structure.
 * Copy non shared stuff straight through to save
 * both space and time. Switch tables are in the
 * shared data, so this works w.r.t. label reference
 * counts. The PROLOG item has been already read.
 */
getfunc()
{
	register INS	*ip;

	ins.i_fp = &ins;
	ins.i_bp = &ins;
	for (;;) {
		ip = getins();
		if (dotseg<0 || isshared(dotseg)==0
		|| (ip->i_type==ENTER && isshared(ip->i_seg)==0)) {
			genins(ip);
			free((char *) ip);
			continue;
		}
		ip->i_fp = &ins;
		ip->i_bp = ins.i_bp;
		ins.i_bp->i_fp = ip;
		ins.i_bp = ip;
		if (ip->i_type == EPILOG)
			break;
	}
}

/*
 * This routine reads an item from
 * the input file and constructs and INS node
 * to hold it. A pointer to the INS node is
 * returned. Any format errors are fatal.
 */
INS *
getins()
{
	register INS	*ip;
	register int	op;

loop:
	op = bget();
	switch (op) {

	case ENTER:
		ip = newi(sizeof(INS));
		ip->i_seg = bget();
		break;

	case FNAME:
		sget(file, NFNAME);
		goto loop;

	case LINE:
		line = iget();
		ip = newi(sizeof(INS));
		ip->i_line = line;
		break;

	case DLABEL:
		gendbgt(1);
		goto loop;

	case AUTOS:
		getautos();
		goto loop;

	case BLOCK:
		ip = newi(sizeof(INS));
		ip->i_len = zget();
		break;

	case LLABEL:
		ip = newi(sizeof(INS));
		ip->i_labno = iget();
		ip->i_sp = NULL;
		ip->i_refc = 0;
		break;

#ifdef KLUDGE
	case SGUESS:
	{
		register SYM *sp;
		int seg;
		sget(id, NCSYMB);
		seg = bget();
		sp = glookup(id, 0);
		if ((sp->s_flag&S_DEF) == 0)
			sp->s_seg = seg;
		goto loop;
	}

#endif
	case EPILOG:
		ip = newi(sizeof(INS));
		break;

	case ALIGN:
		ip = newi(sizeof(INS));
		ip->i_align = bget();
		break;

	case CODE:
		return (getcode());

	case EOF:
		cfatal("unexpected EOF");

	default:
		cbotch("bad temporary file opcode %d", op);
	}
	ip->i_type = op;
	ip->i_fp = ip->i_bp = NULL;
	return (ip);
}

/*
 * Return true if segment "s" is
 * shared. All local label references must be
 * in a shared segment, or label reference counting
 * will get screwed up. This includes the dispatch
 * tables of switch statements.
 */
isshared(s)
{
	if (s==SCODE || s==SPURE)
		return (1);
	return (0);
}

/*
 * Allocate a new INS node.
 */
INS *
newi(n)
{
	register INS	*ip;

	if ((ip = (INS *) malloc(n)) == NULL)
		cnomem("newi");
	return (ip);
}

/*
 * Allocate a new INS node with
 * an `n' element `i_af' field on the end.
 */
INS *
newn(n)
{
	return (newi(sizeof(INS)+n*sizeof(struct afield)));
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.