1 /* label.c - label handling routines for bcc */
2
3 /* Copyright (C) 1992 Bruce Evans */
4
5 #include "bcc.h"
6 #include "condcode.h"
7 #include "gencode.h"
8 #include "label.h"
9 #include "output.h"
10 #include "sc.h"
11 #include "scan.h"
12 #include "sizes.h"
13 #include "type.h"
14
15 #ifdef I8088
16 # define outlbranch() outop3str( "b")
17 # define outsbranch() outop2str( "j")
18 #endif
19 #ifdef MC6809
20 # define outlbranch() outop3str( "LB")
21 # define outsbranch() outop2str( "B")
22 #endif
23
24 #define MAXVISLAB 32
25
26 struct labdatstruct
27 {
28 label_no labnum; /* 0 if not active */
29 offset_T lablc; /* location counter for branch or label */
30 char *labpatch; /* buffer ptr for branch, NULL for label */
31 ccode_t labcond; /* condition code for branch */
32 };
33
34 #ifdef I8088
35 PRIVATE char lcondnames[][2] = /* names of long condition codes */
36 {
37 { 'e', 'q', }, { 'n', 'e', }, { 'r', ' ', }, { 'r', 'n', },
38 { 'l', 't', }, { 'g', 'e', }, { 'l', 'e', }, { 'g', 't', },
39 { 'l', 'o', }, { 'h', 'i', }, { 'l', 'o', }, { 'h', 'i' },
40 };
41 PRIVATE char scondnames[][2] = /* names of short condition codes */
42 {
43 { 'e', ' ', }, { 'n', 'e', }, { 'm', 'p', }, { 'n', 0, },
44 { 'l', ' ', }, { 'g', 'e', }, { 'l', 'e', }, { 'g', ' ', },
45 { 'b', ' ', }, { 'a', 'e', }, { 'b', 'e', }, { 'a', ' ', },
46 };
47 #endif
48
49 #ifdef MC6809
50 PRIVATE char condnames[][2] = /* names of condition codes */
51 {
52 { 'E', 'Q', }, { 'N', 'E', }, { 'R', 'A', }, { 'R', 'N', },
53 { 'L', 'T', }, { 'G', 'E', }, { 'L', 'E', }, { 'G', 'T', },
54 { 'L', 'O', }, { 'H', 'S', }, { 'L', 'S', }, { 'H', 'I', },
55 };
56 #endif
57
58 PRIVATE label_no lasthighlab = 0xFFFF+1; /* temp & temp init so labels fixed */
59 /* lint */
60 PRIVATE label_no lastlab; /* bss init to 0 */
61 PRIVATE offset_T lc; /* bss init to 0 */
62
63 PRIVATE struct labdatstruct vislab[MAXVISLAB]; /* bss, all labnum's init 0 */
64 PRIVATE smalin_t nextvislab; /* bss init to NULL */
65 PRIVATE struct symstruct *namedfirst; /* bss init to NULL */
66 PRIVATE struct symstruct *namedlast; /* bss init to NULL */
67
68 FORWARD void addlabel P((ccode_pt cond, label_no label, char *patch));
69 FORWARD struct labdatstruct *findlabel P((label_no label));
70
71 /* add label to circular list */
72
addlabel(cond,label,patch)73 PRIVATE void addlabel(cond, label, patch)
74 ccode_pt cond;
75 label_no label;
76 char *patch;
77 {
78 register struct labdatstruct *labptr;
79
80 labptr = &vislab[(int)nextvislab];
81 labptr->labcond = cond;
82 labptr->labnum = label;
83 labptr->lablc = lc;
84 labptr->labpatch = patch;
85 if (++nextvislab == MAXVISLAB)
86 nextvislab = 0;
87 }
88
89 /* bump location counter */
90
bumplc()91 PUBLIC void bumplc()
92 {
93 ++lc;
94 }
95
96 /* bump location counter by 2 */
97
bumplc2()98 PUBLIC void bumplc2()
99 {
100 lc += 2;
101 }
102
103 /* bump location counter by 3 */
104
bumplc3()105 PUBLIC void bumplc3()
106 {
107 lc += 3;
108 }
109
110 /* clear out labels in function */
111
clearfunclabels()112 PUBLIC void clearfunclabels()
113 {
114 register struct symstruct *symptr;
115 register struct symstruct *tmp;
116
117 for (symptr = namedfirst; symptr != NULL;)
118 {
119 if (symptr->indcount == 2)
120 error("undefined label");
121 symptr->indcount = 0;
122 tmp = symptr;
123 symptr = (struct symstruct *) symptr->type;
124 tmp->type = NULL;
125 }
126 namedlast = namedfirst = NULL;
127 }
128
129 /* clear out labels no longer in buffer */
130
clearlabels(patchbuf,patchtop)131 PUBLIC void clearlabels(patchbuf, patchtop)
132 char *patchbuf;
133 char *patchtop;
134 {
135 register struct labdatstruct *labptr;
136 struct labdatstruct *labtop;
137 register char *labpatch;
138
139 for (labptr = &vislab[0], labtop = &vislab[MAXVISLAB];
140 labptr < labtop; ++labptr)
141 if ((labpatch = labptr->labpatch) >= patchbuf && labpatch < patchtop)
142 labptr->labnum = 0;
143 }
144
145 /* clear out labels in switch statement */
146
clearswitchlabels()147 PUBLIC void clearswitchlabels()
148 {
149 register struct symstruct *symptr;
150
151 for (symptr = namedfirst; symptr != NULL;
152 symptr = (struct symstruct *) symptr->type)
153 if (symptr->indcount == 3)
154 {
155 equlab(symptr->offset.offlabel, lowsp);
156 symptr->indcount = 4;
157 }
158 }
159
160 /* return location counter */
161
getlc()162 PUBLIC uoffset_T getlc()
163 {
164 return (uoffset_T) lc;
165 }
166
167 /* define location of label and backpatch references to it */
168
deflabel(label)169 PUBLIC void deflabel(label)
170 label_no label;
171 {
172 char *cnameptr;
173 struct labdatstruct *labmin;
174 struct labdatstruct *labmax;
175 struct labdatstruct *labmid;
176 struct labdatstruct *labptrsave;
177 offset_T nlonger;
178
179 outnlabel(label);
180 {
181 register struct labdatstruct *labptr;
182 register char *labpatch;
183
184 labmin = &vislab[0];
185 labmax = &vislab[MAXVISLAB];
186 labptr = labmid = &vislab[(int)nextvislab];
187 if (!watchlc)
188 do
189 {
190 if (labptr == labmin)
191 labptr = &vislab[MAXVISLAB];
192 --labptr;
193 if (labptr->labnum == label)
194 {
195 if ((labpatch = labptr->labpatch) != NULL &&
196 isshortbranch(lc - labptr->lablc))
197 {
198 #ifdef I8088 /* patch "bcc(c) to j(c)(c)( ) */
199 *labpatch = 'j';
200 *(labpatch + 1) =
201 *(cnameptr = scondnames[(int)labptr->labcond]);
202 #endif
203 #ifdef MC6809
204 # ifdef NEW_MC6809 /* patch JMP\t> or LBCC\t to BCC \t */
205 *labpatch = 'B';
206 *(labpatch + 4) = '\t'; /* redundant unless JMP */
207 *(labpatch + 1) =
208 *(cnameptr = condnames[labptr->labcond]);
209 # else
210 if (labptr->labcond == RA)
211 strncpy(labpatch, "BRA\t\t", 5);
212 else
213 *labpatch = '\t';
214 goto over;
215 # endif
216 #endif
217 *(labpatch + 2) = *(cnameptr + 1);
218 *(labpatch + 3) = ' ';
219 #ifdef MC6809
220 # ifndef NEW_MC6809 /* patch JMP\t> or LBCC\t to BCC \t */
221 over: ; /* temp regression test kludge */
222 # endif
223 #endif
224 nlonger = jcclonger;
225 if (labptr->labcond == RA)
226 nlonger = jmplonger;
227 lc -= nlonger;
228 labptrsave = labptr;
229 while (++labptr != labmid)
230 if (labptr == labmax)
231 labptr = &vislab[-1];
232 else
233 labptr->lablc -= nlonger;
234 labptr = labptrsave;
235 }
236 }
237 }
238 while (labptr != labmid);
239 }
240 addlabel((ccode_pt) 0, label, (char *) NULL);
241 }
242
findlabel(label)243 PRIVATE struct labdatstruct *findlabel(label)
244 label_no label;
245 {
246 register struct labdatstruct *labptr;
247 struct labdatstruct *labtop;
248
249 for (labptr = &vislab[0], labtop = &vislab[MAXVISLAB];
250 labptr < labtop; ++labptr)
251 if (labptr->labnum == label)
252 {
253 if (labptr->labpatch != 0)
254 break;
255 return labptr;
256 }
257 return (struct labdatstruct *) NULL;
258 }
259
260 /* reserve a new label, from top down to temp avoid renumbering low labels */
261
gethighlabel()262 PUBLIC label_no gethighlabel()
263 {
264 return --lasthighlab;
265 }
266
267 /* reserve a new label */
268
getlabel()269 PUBLIC label_no getlabel()
270 {
271 return ++lastlab;
272 }
273
274 /* jump to label */
275
jump(label)276 PUBLIC void jump(label)
277 label_no label;
278 {
279 lbranch(RA, label);
280 }
281
282 /* long branch on condition to label */
283
lbranch(cond,label)284 PUBLIC void lbranch(cond, label)
285 ccode_pt cond;
286 label_no label;
287 {
288 #ifdef I8088
289 char *cnameptr;
290
291 #endif
292 struct labdatstruct *labptr;
293 char *oldoutptr;
294
295 if ((ccode_t) cond == RN)
296 return;
297 if ((labptr = findlabel(label)) != NULL &&
298 isshortbranch(lc - labptr->lablc + 2))
299 {
300 sbranch(cond, label);
301 return;
302 }
303 oldoutptr = outbufptr;
304 if (cond == RA)
305 outjumpstring();
306 else
307 {
308 outlbranch();
309 #ifdef I8088
310 outbyte(*(cnameptr = lcondnames[(int) cond]));
311 outbyte(*(cnameptr + 1));
312 if ((ccode_t) cond == LS || (ccode_t) cond == HS)
313 outbyte('s'); /* "blos" or "bhis" */
314 else
315 outbyte(' ');
316 outtab();
317 bumplc2();
318 #ifdef I80386
319 if (i386_32)
320 bumplc();
321 #endif
322 #endif
323 #ifdef MC6809
324 outcond(cond);
325 bumplc();
326 #endif
327 }
328 outlabel(label);
329 outnl();
330 if (labptr == NULL && oldoutptr < outbufptr) /* no wrap-around */
331 addlabel(cond, label, oldoutptr);
332 }
333
334 /* look up the name gsname in label space, install it if new */
335
namedlabel()336 PUBLIC struct symstruct *namedlabel()
337 {
338 struct symstruct *symptr;
339
340 gs2name[1] = 0xFF;
341 if ((symptr = findlorg(gs2name + 1)) == NULL)
342 {
343 symptr = addglb(gs2name + 1, vtype);
344 symptr->flags = LABELLED;
345 }
346 if (symptr->indcount < 2)
347 {
348 symptr->indcount = 2;
349 symptr->offset.offlabel = gethighlabel();
350 if (namedfirst == NULL)
351 namedfirst = symptr;
352 else
353 namedlast->type = (struct typestruct *) symptr;
354 namedlast = symptr;
355 symptr->type = NULL;
356 }
357 return symptr;
358 }
359
360 #ifdef MC6809
361
362 /* print condition code name */
363
outcond(cond)364 PUBLIC void outcond(cond)
365 ccode_pt cond;
366 {
367 char *cnameptr;
368
369 outbyte(*(cnameptr = condnames[(ccode_t) cond]));
370 outbyte(*(cnameptr + 1));
371 outtab();
372 }
373
374 #endif
375
376 /* print label */
377
outlabel(label)378 PUBLIC void outlabel(label)
379 label_no label;
380 {
381 outbyte(LABELSTARTCHAR);
382 outhexdigs((uoffset_T) label);
383 }
384
385 /* print label and newline */
386
outnlabel(label)387 PUBLIC void outnlabel(label)
388 label_no label;
389 {
390 outlabel(label);
391 #ifdef LABELENDCHAR
392 outnbyte(LABELENDCHAR);
393 #else
394 outnl();
395 #endif
396 }
397
398 /* short branch on condition to label */
399
sbranch(cond,label)400 PUBLIC void sbranch(cond, label)
401 ccode_pt cond;
402 label_no label;
403 {
404 #ifdef I8088
405 char *cnameptr;
406
407 if ((ccode_t) cond != RN)
408 {
409 outsbranch();
410 outbyte(*(cnameptr = scondnames[(int) cond]));
411 outbyte(*(cnameptr + 1));
412 outtab();
413 outlabel(label);
414 outnl();
415 }
416 #endif
417 #ifdef MC6809
418 outsbranch();
419 outcond(cond);
420 outlabel(label);
421 outnl();
422 #endif
423 }
424
425 /* reverse bump location counter */
426
unbumplc()427 PUBLIC void unbumplc()
428 {
429 --lc;
430 }
431