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

/*
 * n1/pool.c
 * Literal pool management.
 * This is needed for machines which lack immediate addressing modes.
 */

#ifdef   vax
#include "INC$LIB:cc1.h"
#else
#include "cc1.h"
#endif

#include <string.h>

/*
 * Data structure for remembering the constants in the pool.
 * A chain of these is built up as the compilation proceeds.
 * The pool entries are written out as new entries are added.
 */
typedef	struct	pool	{
	struct	pool	*p_pp;			/* Link			*/
	int		p_op;			/* Node op		*/
	int		p_type;			/* Node type		*/
	int		p_lab;			/* Literal label	*/
	union	{
		ival_t	p_ival;			/* Value of ICON	*/
		lval_t	p_lval;			/* Value of LCON	*/
		dval_t	p_dval;			/* Value of DCON	*/
		struct	{
			int	p_label;	/* LID t_label		*/
			sizeof_t p_loffs;	/* LID t_offs		*/
		}	pl;
		struct	{
			SYM	*p_sp;		/* GID t_sp		*/
			sizeof_t p_goffs;	/* GID t_offs		*/
		}	pg;
	}	pd;
}	POOL;

static	POOL	*poolp	= NULL;			/* The pool */

/*
 * Given a pointer to a tree node with opcode
 * ICON, LCON, DCON, LID or GID,
 * build an entry in the literal pool
 * and rewrite the tree to refer to the label.
 * The only potential fixups left to the caller
 * are a change to the type and a call to amd to set tflag.
 * The pool should ideally be in SLINK without exception,
 * but it isn't possible so we call poolseg(op)
 * (defined in cc1mch.h) to determine where we're going.
 */
pool(tp)
register TREE	*tp;
{
	register POOL	*pp;
	register int	op, old, type;

	op  = tp->t_op;
	type = tp->t_type;
	if (op==ICON||op==LCON||op==DCON||op==LID||op==GID||op==ADDR) {
		pp = poolp;
		while (pp != NULL) {
			if (pp->p_op == op && pp->p_type == type) {
				if (op == ICON) {
					if (pp->pd.p_ival == tp->t_ival)
						break;
				} else	if (op == LCON) {
					if (pp->pd.p_lval == tp->t_lval)
						break;
				} else	if (op == DCON) {
					if (memcmp(pp->pd.p_dval,
						   tp->t_dval,
						   sizeof(dval_t)) == 0)
						break;
				} else	if (op == LID) {
					if (pp->pd.pl.p_label == tp->t_label
					&&  pp->pd.pl.p_loffs == tp->t_offs)
						break;
				} else	if (op == GID) {
					if (pp->pd.pg.p_sp == tp->t_sp
					&&  pp->pd.pg.p_goffs == tp->t_offs)
						break;
				}
			}
			pp = pp->p_pp;
		}
		if (pp==NULL && (pp=(POOL *)malloc(sizeof(POOL))) != NULL) {
			pp->p_pp = poolp;
			poolp = pp;
			pp->p_op = op;
			pp->p_lab = newlab();
			pp->p_type = type;
			if (op == ICON)
				pp->pd.p_ival = tp->t_ival;
			else if (op == LCON)
				pp->pd.p_lval = tp->t_lval;
			else if (op == DCON)
				memcpy(pp->pd.p_dval, tp->t_dval, sizeof(dval_t));
			else if (op == LID) {
				pp->pd.pl.p_label = tp->t_label;
				pp->pd.pl.p_loffs = tp->t_offs;
			} else if (op == GID) {
				pp->pd.pg.p_sp = tp->t_sp;
				pp->pd.pg.p_goffs = tp->t_offs;
			}
			old = newseg(poolseg(op));
			genlab(pp->p_lab);
			if (op==LID || op==GID) {
				iexpr(tp, iptrtype());
			} else
				iexpr(tp, type);
			newseg(old);
		} else if (pp == NULL) {
			cnomem("pool malloc");
		}
	} else
		cbotch("unpoolable tree");
	tp->t_op = LID;
	tp->t_label = pp->p_lab;
	tp->t_seg = poolseg(op);
	tp->t_offs = 0;
	if (op == ADDR) {
		poolp = pp->p_pp;
		free(pp);
	}
}

#if OVERLAID
/*
 * Free all of the entries in the literal pool.
 * Called at the end of the code generator phase.
 */
freepool()
{
	register POOL	*p1;
	register POOL	*p2;

	p1 = poolp;
	while (p1 != NULL) {
		p2 = p1->p_pp;
		free((char *) p1);
		p1 = p2;
	}
	poolp = NULL;
}
#endif

/* end of n1/pool.c */

unix.superglobalmegacorp.com

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