|
|
1.1 root 1: /*
2: * Debug table management.
3: */
4: #ifdef vax
5: #include "INC$LIB:cc2.h"
6: #else
7: #include "cc2.h"
8: #endif
9:
10: #define NDHASH 16
11: #define hash(p) ((((int)(p))>>4)&15)
12:
13: struct dline {
14: struct dline *d_dp; /* List link */
15: INS *d_ip; /* Referenced instruction */
16: int d_nv; /* Vector size */
17: int d_dv[]; /* Vector of drefnum numbers */
18: };
19:
20: struct dline *dhash[NDHASH]; /* Hash table */
21:
22: struct dline *newdn();
23: struct dline *mrgdlin();
24: struct dline **getdlin();
25: extern int vflag;
26:
27: /*
28: * Generate a debug table entry during first pass.
29: * level == 0 called from outside a function body.
30: * level == 1 called from inside a function body.
31: * The label information is invariably copied to output
32: * either via outdlab or tcpy.
33: * DC_LINE and DC_LAB items are hashed to the current ins node
34: * so their ultimate locations can be known.
35: */
36: gendbgt(level)
37: register int level;
38: {
39: static int drefnum;
40: int nline, class;
41:
42: /* Read class */
43: class = bget();
44:
45: /* Output the information in some form */
46: if (isvariant(VASM)) {
47: bput(DLABEL);
48: tcpy(class);
49: } else
50: outdlab(0, class);
51: if (class == DC_LINE || class == DC_LAB) {
52: if (level == 0) {
53: if (isvariant(VASM)) {
54: bput(DLOCAT);
55: iput(drefnum);
56: } else
57: outdloc(drefnum);
58: } else
59: newdlin(drefnum);
60: }
61: drefnum += 1;
62: }
63:
64: /*
65: * Enter a new dline item into the initial list.
66: * dline records are initially stored in a list starting at
67: * dhash[0].
68: */
69: newdlin(drefnum)
70: {
71: register struct dline *dp;
72:
73: dp = newdn(1);
74: dp->d_ip = ins.i_bp;
75: dp->d_dv[0] = drefnum;
76: if (dhash[0] == NULL || ins.i_bp != dhash[0]->d_ip) {
77: dp->d_dp = dhash[0];
78: dhash[0] = dp;
79: } else {
80: dhash[0] = mrgdlin(dp, dhash[0]);
81: }
82: }
83:
84: /*
85: * Merge two dline items into a single item.
86: * Retain the link's of dp2.
87: */
88: struct dline *
89: mrgdlin(dp1, dp2)
90: struct dline *dp1, *dp2;
91: {
92: struct dline *dp;
93: int nv1, nv2, nv;
94: register int *ip1, *ip2, *ip;
95:
96: nv1 = dp1->d_nv;
97: nv2 = dp2->d_nv;
98: nv = nv1 + nv2;
99: dp = newdn(nv);
100: dp->d_dp = dp2->d_dp;
101: dp->d_ip = dp2->d_ip;
102: ip = dp->d_dv;
103: ip1 = dp1->d_dv;
104: ip2 = dp2->d_dv;
105: while (--nv >= 0) {
106: if (nv1 == 0) {
107: cp2: *ip++ = *ip2++;
108: --nv2;
109: } else if (nv2 == 0) {
110: cp1: *ip++ = *ip1++;
111: --nv1;
112: } else if (*ip2 < *ip1) {
113: goto cp2;
114: } else {
115: goto cp1;
116: }
117: }
118: free(dp1);
119: free(dp2);
120: return (dp);
121: }
122:
123: /*
124: * Allocate a dline record for n items.
125: */
126: struct dline *
127: newdn(n)
128: register int n;
129: {
130: register struct dline *dp;
131: register int size;
132:
133: size = n * sizeof(int);
134: size += sizeof(struct dline);
135: dp = (struct dline *)malloc(size);
136: if (dp == NULL)
137: cnomem("newdn");
138: dp->d_dp = NULL;
139: dp->d_ip = NULL;
140: dp->d_nv = n;
141: return (dp);
142: }
143:
144: /*
145: * Advance the ip field of each debug table item
146: * and enter into hash table based off the ip field.
147: */
148: fixdbgt()
149: {
150: register struct dline *dp, *ddp, **dpp;
151: int seg = SCODE;
152:
153: dp = dhash[0];
154: dhash[0] = NULL;
155: while (dp != NULL) {
156: int t;
157: register INS *ip;
158:
159: do {
160: ip = dp->d_ip = dp->d_ip->i_fp;
161: if ((t=ip->i_type) == ENTER)
162: seg = ip->i_seg;
163: } while (seg!=SCODE
164: || t!=PROLOG && t!=EPILOG && t!=CODE && t!=JUMP);
165: ddp = dp->d_dp;
166: dp->d_dp = NULL;
167: dpp = getdlin(ip);
168: *dpp = *dpp!=NULL ? mrgdlin(dp, *dpp) : dp;
169: dp = ddp;
170: }
171: }
172:
173: /*
174: * Search dhash for a dp referencing instruction ip.
175: * Return a pointer to the link to that ip.
176: */
177: struct dline **
178: getdlin(ip)
179: register INS *ip;
180: {
181: register struct dline *dp, **dpp;
182:
183: dpp = &dhash[hash(ip)];
184: while ((dp = *dpp) != NULL && dp->d_ip != ip)
185: dpp = &dp->d_dp;
186: return (dpp);
187: }
188:
189: /*
190: * Merge the debug table entries on ip1, if any, onto ip2.
191: * called from within optim loop.
192: */
193: mrgdbgt(ip1, ip2)
194: INS *ip1, *ip2;
195: {
196: register struct dline *dp, **dpp1, **dpp2;
197:
198: dpp1 = getdlin(ip1);
199: if ((dp = *dpp1) != NULL) {
200: *dpp1 = dp->d_dp;
201: dpp2 = getdlin(ip2);
202: if (*dpp2 == NULL) {
203: dp->d_dp = NULL;
204: dp->d_ip = ip2;
205: *dpp2 = dp;
206: } else {
207: *dpp2 = mrgdlin(dp, *dpp2);
208: }
209: }
210: }
211:
212: /*
213: * Assemble the debug table entries associated with ip1.
214: * called from assembler loop.
215: */
216: asmdbgt(ip1)
217: INS *ip1;
218: {
219: register struct dline *dp, **dpp;
220: register int *ip;
221:
222: dpp = getdlin(ip1);
223: if ((dp = *dpp) != NULL) {
224: ip = dp->d_dv;
225: while (--dp->d_nv >= 0) {
226: if (isvariant(VASM)) {
227: bput(DLOCAT);
228: iput(ip[0]);
229: } else {
230: outdloc(ip[0]);
231: }
232: ip += 1;
233: }
234: *dpp = dp->d_dp;
235: free(dp);
236: }
237: }
238:
239: #if !TINY
240: /*
241: * Compiler debugging printout.
242: */
243: dprint(ip)
244: INS *ip;
245: {
246: ddprint(*getdlin(ip));
247: }
248:
249:
250: ddprint(dp)
251: register struct dline *dp;
252: {
253: register int *vp;
254: register int nv;
255:
256: if (dp != NULL) {
257: vp = dp->d_dv;
258: nv = dp->d_nv;
259: while (--nv >= 0) {
260: printf(" %d", *vp++);
261: }
262: printf("\n");
263: }
264: }
265: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.