xref: /csrg-svn/old/as.vax/asjxxx.c (revision 32984)
15825Srrh /*
219823Sdist  * Copyright (c) 1982 Regents of the University of California.
319823Sdist  * All rights reserved.  The Berkeley software License Agreement
419823Sdist  * specifies the terms and conditions for redistribution.
55825Srrh  */
619823Sdist 
75825Srrh #ifndef lint
8*32984Sdonn static char sccsid[] = "@(#)asjxxx.c	5.4 (Berkeley) 12/11/87";
95825Srrh #endif not lint
105825Srrh 
11595Sbill #include	<stdio.h>
12595Sbill #include	"as.h"
13595Sbill #include	"assyms.h"
14595Sbill 
15636Shenry #define	JBR	0x11
16636Shenry #define	BRW	0x31
17636Shenry #define	JMP	0x17
18595Sbill 
19595Sbill /*
20595Sbill  *	The number of bytes to add if the jxxx must be "exploded"
21595Sbill  *	into the long form
22595Sbill  */
23636Shenry #define	JBRDELTA	1	/* brb <byte> ==> brw <byte> <byte> */
24636Shenry #define	JXXXDELTA	3	/* brb <byte> ==> brb <byte> brw <byte> <byte> */
25636Shenry #define	JBRJDELTA	d124	/* brb <byte> ==> jmp L^(pc) <byte>*d124 */
26636Shenry #define	JXXXJDELTA	d124+2	/* brb <byte> ==> brb <byte> jmp L^(pc) <byte>*d124 */
27595Sbill 
28636Shenry int	jbrfsize = JBRDELTA;
29636Shenry int	jxxxfsize = JXXXDELTA;
30636Shenry 
31595Sbill /*
32595Sbill  *	These variables are filled by asscan.c with the
33595Sbill  *	last name encountered (a pointer buried in the intermediate file),
34595Sbill  *	and the last jxxx symbol table entry encountered.
35595Sbill  */
36595Sbill struct 	symtab	*lastnam;
37595Sbill struct	symtab	*lastjxxx;
38595Sbill 
initijxxx()39636Shenry initijxxx()
40636Shenry {
41636Shenry 	jbrfsize = jxxxJUMP ? JBRJDELTA : JBRDELTA;
42636Shenry 	jxxxfsize = jxxxJUMP ? JXXXJDELTA : JXXXDELTA;
43636Shenry 	/*
44636Shenry 	 *	Note: ifjxxxJUMP is set, then we do NOT do any tunnelling;
45636Shenry 	 *	this was too complicated to figure out, and in the first
46636Shenry 	 *	version of the assembler, tunnelling proved to be the hardest
47636Shenry 	 *	to get to work!
48636Shenry 	 */
49636Shenry }
50595Sbill /*
51595Sbill  *	Handle jxxx instructions
52595Sbill  */
535825Srrh ijxout(opcode, ap, nact)
545825Srrh 	struct	Opcode	opcode;
555825Srrh 	struct	arg	*ap;
565825Srrh 	int	nact;
57595Sbill {
58595Sbill 	if (passno == 1){
59595Sbill 		/*
60595Sbill 		 *	READ THIS BEFORE LOOKING AT jxxxfix()
61595Sbill 		 *
62595Sbill 		 *	Record the jxxx in a special symbol table entry
63595Sbill 		 */
64595Sbill 		register struct symtab *jumpfrom;
65595Sbill 
66595Sbill 		/*
67595Sbill 		 *	We assume the MINIMAL length
68595Sbill 		 */
695825Srrh 		putins(opcode, ap, nact);
70595Sbill 		jumpfrom = lastjxxx;
71630Shenry 		jumpfrom->s_tag = JXACTIVE;
72630Shenry 		jumpfrom->s_jxbump = 0;
735825Srrh 		if (opcode.Op_popcode == JBR)
74636Shenry 			jumpfrom->s_jxfear = jbrfsize;
75595Sbill 		else
76636Shenry 			jumpfrom->s_jxfear = jxxxfsize;
77595Sbill 		if (lastnam == 0)
78595Sbill 			yyerror("jxxx destination not a label");
79630Shenry 		jumpfrom->s_dest = lastnam;
80630Shenry 		jumpfrom->s_type = dotp->e_xtype;	/*only TEXT or DATA*/
81630Shenry 		jumpfrom->s_index = dotp-usedot;
8215234Sralph #ifdef DEBUG
8315234Sralph 		jumpfrom->s_name = ITABFETCH(opcode)->i_name;
8415234Sralph 		jumpfrom->s_jxline = lineno;
8515234Sralph #endif
86595Sbill 		/*
87595Sbill 		 *	value ALWAYS (ALWAYS!!!) indexes the next instruction
8815234Sralph 		 *	after the jump, even if the jump must be exploded
89595Sbill 		 *	(bumped)
90595Sbill 		 */
91630Shenry 		jumpfrom->s_value = dotp->e_xvalue;
92595Sbill 		njxxx++;
93595Sbill 	} else {/* pass2, resolve */
94595Sbill 		/*
95595Sbill 		 *	READ THIS AFTER LOOKING AT jxxxfix()
96595Sbill 		 */
975825Srrh 		reg	long		oxvalue;
985825Srrh 		reg	struct	exp 	*xp;
995825Srrh 		reg	struct	symtab	*tunnel;
1005825Srrh 		reg	struct	arg	*aplast;
1015825Srrh 			struct	Opcode	nopcode;
102595Sbill 
103595Sbill 		aplast = ap + nact - 1;
104630Shenry 		xp = aplast->a_xp;
105630Shenry 		if (lastjxxx->s_tag == JXTUNNEL){
106630Shenry 			lastjxxx->s_tag = JXINACTIVE;
107630Shenry 			tunnel = lastjxxx->s_dest;
108630Shenry 			xp->e_xvalue = tunnel->s_value	/*index of instruction following*/
109595Sbill 				    - 3			/* size of brw + word*/
110636Shenry 				    + ( ( (tunnel->s_jxfear == jbrfsize) &&
111630Shenry 					  (tunnel->s_jxbump == 0))?1:0);
112595Sbill 							/*non bumped branch byteis only 2 back*/
113595Sbill 		}
114630Shenry 		if (lastjxxx->s_jxbump == 0){	/*wasn't bumped, so is short form*/
1155825Srrh 			putins(opcode, ap, nact);
116595Sbill 		} else {
1175825Srrh 			if (opcode.Op_popcode != JBR){
1185825Srrh 				/*
1195825Srrh 				 *	branch reverse conditional byte over
1205825Srrh 				 *	branch unconditional word
1215825Srrh 				 */
122630Shenry 				oxvalue = xp->e_xvalue;
123630Shenry 				xp->e_xvalue = lastjxxx->s_value;
1245825Srrh 				nopcode = opcode;
1255825Srrh 				nopcode.Op_popcode ^= 1;
1265825Srrh 				putins(nopcode, ap, nact);
127630Shenry 				xp->e_xvalue = oxvalue;
128595Sbill 			}
1295825Srrh 			nopcode.Op_eopcode = CORE;
1305825Srrh 			nopcode.Op_popcode = jxxxJUMP ? JMP : BRW;
1315825Srrh 			putins(nopcode, aplast, 1);
132595Sbill 		}
133595Sbill 	}
1345825Srrh }
135595Sbill 
jalign(xp,sp)136595Sbill jalign(xp, sp)
137595Sbill 	register struct exp *xp;
138595Sbill 	register struct symtab *sp;
139595Sbill {
140595Sbill 	register	int	mask;
14115234Sralph #ifdef DEBUG
14215234Sralph 	static struct strdesc noname;
14315234Sralph #endif
144680Shenry 	/*
145680Shenry 	 *	Problem with .align
146680Shenry 	 *
147680Shenry 	 *	When the loader constructs an executable file from
148680Shenry 	 *	a number of objects, it effectively concatnates
149680Shenry 	 *	together all of the text segments from all objects,
150680Shenry 	 *	and then all of the data segments.
151680Shenry 	 *
152680Shenry 	 *	If we do an align by a large value, we can align
153680Shenry 	 *	within the a.out this assembly produces, but
154680Shenry 	 *	after the loader concatnates, the alignment can't
155680Shenry 	 *	be guaranteed if the objects preceding this one
156680Shenry 	 *	in the load are also aligned to the same size.
157680Shenry 	 *
158680Shenry 	 *	Currently, the loader guarantees full word alignment.
159680Shenry 	 *	So, ridiculous aligns are caught here and converted
16015559Srrh 	 *	to a .align (maxalign), if possible, where maxalign
16115559Srrh 	 *	is set in the command line, and defaults to 2.
162680Shenry 	 */
1635825Srrh 	if (   ( (xp->e_xtype & XTYPE) != XABS)
164678Shenry 	    || (xp->e_xvalue < 0)
165678Shenry 	    || (xp->e_xvalue > 16)
166678Shenry 	    ) {
167595Sbill 		yyerror("Illegal `align' argument");
168595Sbill 		return;
169595Sbill 	}
17015559Srrh 	if (xp->e_xvalue > maxalign){
171680Shenry 		if (passno == 1){
1725825Srrh 			yywarning(".align %d is NOT preserved by the loader",
1735825Srrh 				xp->e_xvalue);
17415559Srrh 			yywarning(".align %d converted to .align %d",
17515559Srrh 				xp->e_xvalue, maxalign);
176680Shenry 		}
17715559Srrh 		xp->e_xvalue = maxalign;
178678Shenry 	}
17923579Smckusick 	flushfield(NBWD/4);
180595Sbill 	if (passno == 1) {
181630Shenry 		sp->s_tag = JXALIGN;
182630Shenry 		sp->s_jxfear = (1 << xp->e_xvalue) - 1;
183630Shenry 		sp->s_type = dotp->e_xtype;
184630Shenry 		sp->s_index = dotp-usedot;
18515234Sralph #ifdef DEBUG
18615234Sralph 		sp->s_name = (char *)&noname;
18715234Sralph 		sp->s_jxline = lineno;
18815234Sralph #endif
189595Sbill 		/*
190595Sbill 		 *	We guess that the align will take up at least one
191595Sbill 		 *	byte in the code output.  We will correct for this
192595Sbill 		 *	initial high guess when we explode (bump) aligns
193595Sbill 		 *	when we fix the jxxxes.  We must do this guess
194595Sbill 		 *	so that the symbol table is sorted correctly
195595Sbill 		 *	and labels declared to fall before the align
196595Sbill 		 *	really get their, instead of guessing zero size
197595Sbill 		 *	and have the label (incorrectly) fall after the jxxx.
198595Sbill 		 *	This is a quirk of our requirement that indices into
199595Sbill 		 *	the code stream point to the next byte following
200595Sbill 		 *	the logical entry in the symbol table
201595Sbill 		 */
202630Shenry 		dotp->e_xvalue += 1;
203630Shenry 		sp->s_value = dotp->e_xvalue;
204595Sbill 		njxxx++;
205595Sbill 	} else {
206630Shenry 		mask = (1 << xp->e_xvalue) - 1;
2075825Srrh 		while (dotp->e_xvalue & mask)
2085825Srrh 			Outb(0);
209595Sbill 	}
210595Sbill }
211595Sbill 
212595Sbill /*
213595Sbill  *	Pass 1.5, resolve jxxx instructions and .align in .text
214595Sbill  */
jxxxfix()215595Sbill jxxxfix()
216595Sbill {
217595Sbill 	register struct symtab 	*jumpfrom;
218595Sbill 		 struct symtab	**cojumpfrom, *ubjumpfrom;
219595Sbill 	register struct symtab 	*dest;
220595Sbill 	register struct symtab	*intdest;	/*intermediate dest*/
221595Sbill 	register struct symtab	**cointdest, *ubintdest;
222595Sbill 
223595Sbill 	register struct symtab 	*tunnel;
224595Sbill 	 	 int 		displ,nchange;
225595Sbill 		 int		badjxalign;	/*if jump across an align*/
226595Sbill 		 int		stillactives;	/*if still active jxxxes*/
227595Sbill 		 int		segno;		/*current segment number*/
228595Sbill 		 int		topono;		/*which iteration in the topo sort*/
229595Sbill 	register unsigned char	tag;
230595Sbill 	/*
231595Sbill 	 *	consider each segment in turn...
232595Sbill 	 */
233595Sbill 	for (segno = 0; segno < NLOC + NLOC; segno++){
234595Sbill 	    badjxalign = 0;		/*done on a per segment basis*/
235595Sbill 	    /*
236595Sbill 	     *	Do a lazy topological sort.
237595Sbill 	     */
238595Sbill 	    for (topono = 1, nchange = 1; nchange != 0; topono++){
2395825Srrh #ifdef lint
2405825Srrh 		topno = topno;
2415825Srrh #endif lint
242595Sbill #ifdef DEBUG
243595Sbill 		if (debug)
244595Sbill 			printf("\nSegment %d, topo iteration %d\n",
245595Sbill 				segno, topono);
246595Sbill #endif
247595Sbill 		nchange = 0;
248595Sbill 		stillactives = 0;
249595Sbill 		/*
250595Sbill 		 *	We keep track of one possible tunnel location.
251595Sbill 		 *	A tunnel will eventually be an unconditional
252595Sbill 		 *	branch to the same place that another jxxx
253595Sbill 		 *	will want to branch to.  We will turn a
254595Sbill 		 *	branch conditional/unconditional (word) that would
255595Sbill 		 *	have to get bumped because its destination is too
256595Sbill 		 *	far away, into a branch conditional/unconditional
257595Sbill 		 *	byte to the tunnel branch conditional/unconditional.
258595Sbill 		 *	Of course, the tunnel must branch to the same place
259595Sbill 		 *	as we want to go.
260595Sbill 		 */
261595Sbill 		tunnel = 0;	/*initially, no tunnel*/
262595Sbill 		SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom, ubjumpfrom, ++){
263630Shenry 			tag = jumpfrom->s_tag;
264595Sbill 			if (tag <= IGNOREBOUND)
265595Sbill 				continue;	/*just an ordinary symbol*/
266595Sbill 			if (tag == JXALIGN){
267595Sbill 				tunnel = 0;	/*avoid tunneling across a flex alocation*/
268595Sbill 				continue;	/*we take care of these later*/
269595Sbill 			}
270636Shenry 			if (   jumpfrom->s_jxfear == jbrfsize	/*unconditional*/
271595Sbill 			    || (   tag == JXINACTIVE		/*inactive bumped*/
272630Shenry 				&& (jumpfrom->s_jxbump != 0)
273595Sbill 			       )
274595Sbill 			   ) tunnel = jumpfrom;
275595Sbill 			if (tag != JXACTIVE)
276595Sbill 				continue;
277630Shenry 			dest = jumpfrom->s_dest;
278630Shenry 			if (jumpfrom->s_index != dest->s_index){
279595Sbill 				yyerror("Intersegment jxxx");
280595Sbill 				continue;
281595Sbill 			}
282630Shenry 			displ = dest->s_value - jumpfrom->s_value;
283595Sbill 			if (displ < MINBYTE || displ > MAXBYTE) {
284595Sbill 				/*
285595Sbill 				 *	This is an immediate lose!
286595Sbill 				 *
287595Sbill 				 *	We first attempt to tunnel
288595Sbill 				 *	by finding an intervening jump that
289595Sbill 				 *	has  the same destination.
290595Sbill 				 *	The tunnel is always the first preceeding
291595Sbill 				 *	jxxx instruction, so the displacement
292595Sbill 				 *	to the tunnel is less than zero, and
293595Sbill 				 *	its relative position will be unaffected
294595Sbill 				 *	by future jxxx expansions.
295636Shenry 				 *
296636Shenry 				 *	No tunnels if doing jumps...
297595Sbill 				 */
298636Shenry 				if (    (!jxxxJUMP)
299636Shenry 				     && (jumpfrom->s_jxfear > jbrfsize)
300595Sbill 				     && (tunnel)
301630Shenry 				     && (tunnel->s_dest == jumpfrom->s_dest)
302630Shenry 				     && (tunnel->s_index == jumpfrom->s_index)
303630Shenry 				     && (tunnel->s_value - jumpfrom->s_value >=
304636Shenry 						MINBYTE + jxxxfsize)
305595Sbill 				   ) {
306595Sbill 						/*
307595Sbill 						 *	tunnelling is OK
308595Sbill 						 */
309630Shenry 						jumpfrom->s_dest = tunnel;
310595Sbill 						/*
311595Sbill 						 * no bumping needed, this
312595Sbill 						 * is now effectively inactive
313595Sbill 						 * but must be remembered
314595Sbill 						 */
315630Shenry 						jumpfrom->s_tag = JXTUNNEL;
316595Sbill #ifdef DEBUG
317595Sbill 						if(debug)
318595Sbill 						printf("Tunnel from %s from line %d\n",
31913512Srrh 							FETCHNAME(jumpfrom),
32015234Sralph 							jumpfrom->s_jxline);
321595Sbill #endif
322595Sbill 						continue;
323595Sbill 				} else {	/*tunneling not possible*/
324595Sbill 					/*
325595Sbill 					 *	since this will be turned
326595Sbill 					 *	into a bumped jump, we can
327595Sbill 					 *	use the unconditional jump
328595Sbill 					 *	as a tunnel
329595Sbill 					 */
330595Sbill 					tunnel = jumpfrom;
331630Shenry 					jumpfrom->s_tag = JXNOTYET;
332595Sbill 					++nchange;
333595Sbill 					continue;
334595Sbill 				}
335595Sbill 			}	/*end of immediate lose*/
336595Sbill 			/*
337595Sbill 			 *	Do a forward search for an intervening jxxx
338595Sbill 			 */
339595Sbill 			if (displ >= 0) {
340595Sbill 				SEGITERATE(segno, cojumpfrom + 1,0,cointdest,
341595Sbill 						intdest, ubintdest, ++){
34232983Sdonn 					if (intdest == dest)
343595Sbill 						break; /* beyond destination */
344630Shenry 					if (intdest->s_tag <= JXQUESTIONABLE)
345595Sbill 						continue;	/*frozen solid*/
346630Shenry 					if (intdest->s_tag == JXALIGN){
347630Shenry 						jumpfrom->s_jxoveralign = 1;
348595Sbill 						badjxalign++;
349595Sbill 					}
350595Sbill 					/*
351595Sbill 					 *	we assume the worst case
352595Sbill 					 *	for unfrozen jxxxxes
353595Sbill 					 */
354630Shenry 					displ += intdest->s_jxfear;
355595Sbill 				}
356595Sbill 				if (displ <= MAXBYTE){
357595Sbill 					/*
358595Sbill 					 *	the worst possible conditions
359595Sbill 					 *	can't hurt us, so forget about
360595Sbill 					 *	this jump
361595Sbill 					 */
362630Shenry 					jumpfrom->s_tag = JXINACTIVE;
363595Sbill 				} else {
364595Sbill 					stillactives++;
365595Sbill 				}
366595Sbill 			} else {
367595Sbill 			/*
368595Sbill 			 *	backward search for intervening jxxx
369595Sbill 			 */
370595Sbill 				SEGITERATE(segno, cojumpfrom - 1,1,cointdest,
371595Sbill 				  intdest, ubintdest, --){
37232983Sdonn 					if (intdest == dest)
373595Sbill 						break; /* beyond destination */
374630Shenry 					if (intdest->s_tag <= JXQUESTIONABLE)
375595Sbill 						continue;	/*frozen solid*/
376630Shenry 					if (intdest->s_tag == JXALIGN){
377630Shenry 						jumpfrom->s_jxoveralign = 1;
378595Sbill 						badjxalign++;
379595Sbill 					}
380630Shenry 					displ -= intdest->s_jxfear;
381595Sbill 				}
382595Sbill 				if (displ >= MINBYTE) {
383630Shenry 					jumpfrom->s_tag = JXINACTIVE;
384595Sbill 				} else {
385595Sbill 					stillactives++;
386595Sbill 				}
387595Sbill 			}	/*end of backwards search*/
388595Sbill 		}	/*end of iterating through all symbols in this seg*/
389595Sbill 
390595Sbill 		if (nchange == 0) {
391595Sbill 			/*
392595Sbill 			 *	Now, if there are still active jxxx entries,
393595Sbill 			 *	we are partially deadlocked.  We can leave
394595Sbill 			 *	these jxxx entries in their assumed short jump
395595Sbill 			 *	form, as all initial displacement calcualtions
396595Sbill 			 *	are hanging on unresolved jxxx instructions
397595Sbill 			 *	that might explode into a long form, causing
398595Sbill 			 *	other jxxxes jumping across the first set of
399595Sbill 			 *	jxxxes to explode, etc.
400595Sbill 			 *	However, if a jxxx jumps across a .align,
401595Sbill 			 *	we assume the worst for the deadlock cycle,
402595Sbill 			 *	and resolve all of them towards the long
403595Sbill 			 *	jump.
404595Sbill 			 *	Currently, the C compiler does not produce
405595Sbill 			 *	jumps across aligns, as aligns are only used
406595Sbill 			 *	in data segments, or in text segments to align
407595Sbill 			 *	functions.
408595Sbill 			 */
409595Sbill 			if (stillactives){
410595Sbill 				SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
411595Sbill 				    ubjumpfrom, ++){
412630Shenry 					if (jumpfrom->s_tag == JXACTIVE){
413630Shenry 						jumpfrom->s_tag =
414595Sbill 						  badjxalign?JXNOTYET:JXINACTIVE;
415595Sbill 					}
416595Sbill 				}
417595Sbill 				if (badjxalign){
418595Sbill 					jxxxbump(segno, (struct symtab **)0);
419595Sbill 				}
420595Sbill 			}
421595Sbill 			/*
422595Sbill 			 *	Handle  all of the .align s
423595Sbill 			 */
424595Sbill 			SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
425595Sbill 			   ubjumpfrom, ++){
426630Shenry 			    if (jumpfrom->s_tag == JXALIGN){
427595Sbill 				/*
428595Sbill 				 *	Predict the true displacement
429595Sbill 				 *	needed, irregardless of the
430595Sbill 				 *	fact that we guessed 1
431595Sbill 				 */
432630Shenry 				displ = (jumpfrom->s_value - 1) & (unsigned)jumpfrom->s_jxfear;
433595Sbill 				if (displ == 0){	/*no virtual displacement*/
434630Shenry 					jumpfrom->s_jxfear = -1;
435595Sbill 				} else {
436630Shenry 					jumpfrom->s_jxfear = (jumpfrom->s_jxfear + 1) - displ;
437595Sbill 					/*
438630Shenry 					 *	assert jumpfrom->s_jxfear > 0
439595Sbill 					 */
440630Shenry 					if (jumpfrom->s_jxfear == 1){
441595Sbill 						/*our prediction was correct*/
442595Sbill 						continue;
443595Sbill 					}
444595Sbill 					/*
445630Shenry 					 *	assert jumpfrom->s_jxfear > 1
446595Sbill 					 */
447630Shenry 					jumpfrom->s_jxfear -= 1;	/*correct guess*/
448595Sbill 				}
449595Sbill 				/*
450630Shenry 				 *	assert jumpfrom->s_jxfear = -1, +1...2**n-1
451595Sbill 				 */
452630Shenry 				jumpfrom->s_tag = JXNOTYET;	/*signal*/
453595Sbill 				jxxxbump(segno, cojumpfrom);
454630Shenry 				jumpfrom->s_tag = JXINACTIVE;
455595Sbill 				/*
456595Sbill 				 *	Assert jxfrom->jxvalue indexes the first
457595Sbill 				 *	code byte after the added bytes, and
458595Sbill 				 *	has n low order zeroes.
459595Sbill 				 */
460595Sbill 			  }
461595Sbill 			}	/*end of walking through each segment*/
462595Sbill 	    	}	/*end of no changes */
463595Sbill 		else {	/*changes, and still have to try another pass*/
464595Sbill 			jxxxbump(segno, (struct symtab **)0);
465595Sbill 		}
466595Sbill 	   }	/*end of doing the topologic sort*/
467595Sbill 	}	/*end of iterating through all segments*/
468595Sbill }	/*end of jxxxfix*/
469595Sbill 
470595Sbill /*
471595Sbill  *	Go through the symbols in a given segment number,
472595Sbill  *	and see which entries are jxxx entries that have
473595Sbill  *	been logically "exploded" (expanded), but for which
474595Sbill  *	the value of textually following symbols has not been
475595Sbill  *	increased
476595Sbill  */
477595Sbill 
jxxxbump(segno,starthint)478595Sbill jxxxbump(segno, starthint)
479595Sbill 	int	segno;
480595Sbill 	struct	symtab **starthint;
481595Sbill {
482595Sbill 	register	struct	symtab	**cosp, *sp;
483595Sbill 	register	struct	symtab		*ub;
484595Sbill 	register	int	cum_bump;
485595Sbill 	register	unsigned	char	tag;
486595Sbill 
487595Sbill 	cum_bump = 0;
488595Sbill 	SEGITERATE(segno, starthint, 0, cosp, sp, ub, ++){
489630Shenry 		tag = sp->s_tag;
490595Sbill 		if (tag == JXNOTYET){
491595Sbill #ifdef DEBUG
492595Sbill 			if (debug){
493630Shenry 			if (sp->s_dest != 0)
494595Sbill 				printf("Explode jump to %s on line %d\n",
49515234Sralph 					FETCHNAME(sp->s_dest), sp->s_jxline);
496595Sbill 			else
49715234Sralph 				printf("Explode an align! on line %d\n",
49815234Sralph 					sp->s_jxline);
499595Sbill 			}
500595Sbill #endif
501630Shenry 			sp->s_tag = JXINACTIVE;
502630Shenry 			sp->s_jxbump = 1;
503630Shenry 			cum_bump += sp->s_jxfear;
504595Sbill 		}
505595Sbill 		/*
506595Sbill 		 *	Only bump labels and jxxxes. Ignored entries can
507595Sbill 		 *	be incremented, as they are thrown away later on.
508595Sbill 		 *	Stabds are given their final value in the second
509595Sbill 		 *	pass.
510595Sbill 		 */
511595Sbill 		if (tag >= OKTOBUMP)	/*only bump labels and jxxxes and floating stabs*/
512630Shenry 			sp->s_value += cum_bump;
513595Sbill 	}
514630Shenry 	usedot[segno].e_xvalue += cum_bump;
515595Sbill }
516