|
|
1.1 root 1: /*
2: * The routines in this file
3: * are responsible for managing the pool of
4: * literals. This is needed on a machine that
5: * lacks immediate addressing modes.
6: */
7: #ifdef vax
8: #include "INC$LIB:cc1.h"
9: #else
10: #include "cc1.h"
11: #endif
12:
13: /*
14: * Data structure for
15: * remembering the constants in the pool.
16: * A chain of these is built up as the
17: * compilation proceeds. The pool entries are
18: * written out as new entries are added.
19: */
20: typedef struct pool {
21: struct pool *p_pp; /* Link */
22: int p_op; /* Type of node */
23: int p_lab; /* Literal label */
24: union {
25: ival_t p_ival; /* Value of ICON */
26: lval_t p_lval; /* Value of LCON */
27: dval_t p_dval;
28: struct {
29: int p_label; /* LID t_label */
30: sizeof_t p_loffs; /* LID t_offs */
31: } pl;
32: struct {
33: SYM *p_sp; /* GID t_sp */
34: sizeof_t p_goffs; /* GID t_offs */
35: } pg;
36: } pd;
37: } POOL;
38:
39: static POOL *poolp = NULL; /* The pool */
40:
41: /*
42: * Given a pointer to a tree node with opcode
43: * ICON, LCON, DCON, LID or GID,
44: * build an entry in the literal pool
45: * and rewrite the tree to refer to the label.
46: * The only potential fixups left to the caller
47: * are a change to the type and a call to amd to set tflag.
48: * The pool should ideally be in SLINK without exception,
49: * but it isn't possible so we call poolseg(op)
50: * (defined in cc1mch.h) to determine where we're going.
51: */
52: pool(tp)
53: register TREE *tp;
54: {
55: register POOL *pp;
56: register int i;
57: register int op;
58: register int old;
59:
60: op = tp->t_op;
61: if (op==ICON||op==LCON||op==DCON||op==LID||op==GID||op==ADDR) {
62: pp = poolp;
63: while (pp != NULL) {
64: if (pp->p_op == op) {
65: if (op == ICON) {
66: if (pp->pd.p_ival == tp->t_ival)
67: break;
68: } else if (op == LCON) {
69: if (pp->pd.p_lval == tp->t_lval)
70: break;
71: } else if (op == DCON) {
72: i = 0;
73: while (i < sizeof(dval_t)
74: && pp->pd.p_dval[i] == tp->t_dval[i])
75: ++i;
76: if (i == sizeof(dval_t))
77: break;
78: } else if (op == LID) {
79: if (pp->pd.pl.p_label == tp->t_label
80: && pp->pd.pl.p_loffs == tp->t_offs)
81: break;
82: } else if (op == GID) {
83: if (pp->pd.pg.p_sp == tp->t_sp
84: && pp->pd.pg.p_goffs == tp->t_offs)
85: break;
86: }
87: }
88: pp = pp->p_pp;
89: }
90: if (pp==NULL && (pp=(POOL *)malloc(sizeof(POOL))) != NULL) {
91: pp->p_pp = poolp;
92: poolp = pp;
93: pp->p_op = op;
94: pp->p_lab = newlab();
95: if (op == ICON)
96: pp->pd.p_ival = tp->t_ival;
97: else if (op == LCON)
98: pp->pd.p_lval = tp->t_lval;
99: else if (op == DCON) {
100: for (i=0; i<sizeof(dval_t); ++i)
101: pp->pd.p_dval[i] = tp->t_dval[i];
102: } else if (op == LID) {
103: pp->pd.pl.p_label = tp->t_label;
104: pp->pd.pl.p_loffs = tp->t_offs;
105: } else if (op == GID) {
106: pp->pd.pg.p_sp = tp->t_sp;
107: pp->pd.pg.p_goffs = tp->t_offs;
108: }
109: old = newseg(poolseg(op));
110: genlab(pp->p_lab);
111: if (op==LID || op==GID) {
112: iexpr(tp, iptrtype());
113: } else
114: iexpr(tp, tp->t_type);
115: newseg(old);
116: } else if (pp == NULL) {
117: cnomem("pool malloc");
118: }
119: } else
120: cbotch("unpoolable tree");
121: tp->t_op = LID;
122: tp->t_label = pp->p_lab;
123: tp->t_seg = poolseg(op);
124: tp->t_offs = 0;
125: if (op == ADDR) {
126: poolp = pp->p_pp;
127: free(pp);
128: }
129: }
130:
131: #if OVERLAID
132: /*
133: * Free all of the entries in the
134: * literal pool. Called at the end of the
135: * code generator phase.
136: */
137: freepool()
138: {
139: register POOL *p1;
140: register POOL *p2;
141:
142: p1 = poolp;
143: while (p1 != NULL) {
144: p2 = p1->p_pp;
145: free((char *) p1);
146: p1 = p2;
147: }
148: poolp = NULL;
149: }
150: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.