|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.