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