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