xref: /csrg-svn/old/as.vax/asjxxx.c (revision 680)
1595Sbill /* Copyright (c) 1980 Regents of the University of California */
2*680Shenry static	char sccsid[] = "@(#)asjxxx.c 4.5 08/20/80";
3595Sbill #include	<stdio.h>
4595Sbill #include	"as.h"
5595Sbill #include	"assyms.h"
6595Sbill 
7636Shenry #define	JBR	0x11
8636Shenry #define	BRW	0x31
9636Shenry #define	JMP	0x17
10595Sbill 
11595Sbill /*
12595Sbill  *	The number of bytes to add if the jxxx must be "exploded"
13595Sbill  *	into the long form
14595Sbill  */
15636Shenry #define	JBRDELTA	1	/* brb <byte> ==> brw <byte> <byte> */
16636Shenry #define	JXXXDELTA	3	/* brb <byte> ==> brb <byte> brw <byte> <byte> */
17636Shenry #define	JBRJDELTA	d124	/* brb <byte> ==> jmp L^(pc) <byte>*d124 */
18636Shenry #define	JXXXJDELTA	d124+2	/* brb <byte> ==> brb <byte> jmp L^(pc) <byte>*d124 */
19595Sbill 
20636Shenry int	jbrfsize = JBRDELTA;
21636Shenry int	jxxxfsize = JXXXDELTA;
22636Shenry 
23595Sbill /*
24595Sbill  *	These variables are filled by asscan.c with the
25595Sbill  *	last name encountered (a pointer buried in the intermediate file),
26595Sbill  *	and the last jxxx symbol table entry encountered.
27595Sbill  */
28595Sbill struct 	symtab	*lastnam;
29595Sbill struct	symtab	*lastjxxx;
30595Sbill 
31636Shenry initijxxx()
32636Shenry {
33636Shenry 	jbrfsize = jxxxJUMP ? JBRJDELTA : JBRDELTA;
34636Shenry 	jxxxfsize = jxxxJUMP ? JXXXJDELTA : JXXXDELTA;
35636Shenry 	/*
36636Shenry 	 *	Note: ifjxxxJUMP is set, then we do NOT do any tunnelling;
37636Shenry 	 *	this was too complicated to figure out, and in the first
38636Shenry 	 *	version of the assembler, tunnelling proved to be the hardest
39636Shenry 	 *	to get to work!
40636Shenry 	 */
41636Shenry }
42595Sbill /*
43595Sbill  *	Handle jxxx instructions
44595Sbill  */
45595Sbill ijxout(op,ap,nact)
46595Sbill 	struct arg *ap;
47595Sbill {
48595Sbill 	if (passno == 1){
49595Sbill 		/*
50595Sbill 		 *	READ THIS BEFORE LOOKING AT jxxxfix()
51595Sbill 		 *
52595Sbill 		 *	Record the jxxx in a special symbol table entry
53595Sbill 		 */
54595Sbill 		register struct symtab *jumpfrom;
55595Sbill 
56595Sbill 		/*
57595Sbill 		 *	We assume the MINIMAL length
58595Sbill 		 */
59595Sbill 		putins(op,ap,nact);
60595Sbill 		jumpfrom = lastjxxx;
61630Shenry 		jumpfrom->s_tag = JXACTIVE;
62630Shenry 		jumpfrom->s_jxbump = 0;
63595Sbill 		if (op == JBR)
64636Shenry 			jumpfrom->s_jxfear = jbrfsize;
65595Sbill 		else
66636Shenry 			jumpfrom->s_jxfear = jxxxfsize;
67595Sbill 		if (lastnam == 0)
68595Sbill 			yyerror("jxxx destination not a label");
69630Shenry 		jumpfrom->s_dest = lastnam;
70630Shenry 		jumpfrom->s_type = dotp->e_xtype;	/*only TEXT or DATA*/
71630Shenry 		jumpfrom->s_index = dotp-usedot;
72595Sbill 		/*
73595Sbill 		 *	value ALWAYS (ALWAYS!!!) indexes the next instruction
74595Sbill 		 *	after the jump, even in the jump must be exploded
75595Sbill 		 *	(bumped)
76595Sbill 		 */
77630Shenry 		jumpfrom->s_value = dotp->e_xvalue;
78595Sbill 		njxxx++;
79595Sbill 	} else {/* pass2, resolve */
80595Sbill 		/*
81595Sbill 		 *	READ THIS AFTER LOOKING AT jxxxfix()
82595Sbill 		 */
83595Sbill 		register long		oxvalue;
84595Sbill 		register struct	exp 	*xp;
85595Sbill 		register struct symtab	*tunnel;
86595Sbill 		register struct arg	*aplast;
87595Sbill 
88595Sbill 		aplast = ap + nact - 1;
89630Shenry 		xp = aplast->a_xp;
90630Shenry 		if (lastjxxx->s_tag == JXTUNNEL){
91630Shenry 			lastjxxx->s_tag = JXINACTIVE;
92630Shenry 			tunnel = lastjxxx->s_dest;
93630Shenry 			xp->e_xvalue = tunnel->s_value	/*index of instruction following*/
94595Sbill 				    - 3			/* size of brw + word*/
95636Shenry 				    + ( ( (tunnel->s_jxfear == jbrfsize) &&
96630Shenry 					  (tunnel->s_jxbump == 0))?1:0);
97595Sbill 							/*non bumped branch byteis only 2 back*/
98595Sbill 		}
99630Shenry 		if (lastjxxx->s_jxbump == 0){	/*wasn't bumped, so is short form*/
100595Sbill 			putins(op, ap, nact);
101595Sbill 		} else {
102595Sbill 			if (op != JBR){	/*branch reverse conditional byte over
103595Sbill 					  branch unconditional word*/
104630Shenry 				oxvalue = xp->e_xvalue;
105630Shenry 				xp->e_xvalue = lastjxxx->s_value;
106595Sbill 				putins(op^1, ap, nact);
107630Shenry 				xp->e_xvalue = oxvalue;
108595Sbill 			}
109636Shenry 			putins(jxxxJUMP ? JMP : BRW, aplast, 1);
110595Sbill 		}
111595Sbill 	}
112595Sbill }	/*end of ijxout*/
113595Sbill 
114595Sbill jalign(xp, sp)
115595Sbill 	register struct exp *xp;
116595Sbill 	register struct symtab *sp;
117595Sbill {
118595Sbill 	register	int	mask;
119*680Shenry 	/*
120*680Shenry 	 *	Problem with .align
121*680Shenry 	 *
122*680Shenry 	 *	When the loader constructs an executable file from
123*680Shenry 	 *	a number of objects, it effectively concatnates
124*680Shenry 	 *	together all of the text segments from all objects,
125*680Shenry 	 *	and then all of the data segments.
126*680Shenry 	 *
127*680Shenry 	 *	If we do an align by a large value, we can align
128*680Shenry 	 *	within the a.out this assembly produces, but
129*680Shenry 	 *	after the loader concatnates, the alignment can't
130*680Shenry 	 *	be guaranteed if the objects preceding this one
131*680Shenry 	 *	in the load are also aligned to the same size.
132*680Shenry 	 *
133*680Shenry 	 *	Currently, the loader guarantees full word alignment.
134*680Shenry 	 *	So, ridiculous aligns are caught here and converted
135*680Shenry 	 *	to a .align 2, if possible.
136*680Shenry 	 */
137678Shenry 	if (   (xp->e_xtype != XABS)
138678Shenry 	    || (xp->e_xvalue < 0)
139678Shenry 	    || (xp->e_xvalue > 16)
140678Shenry 	    ) {
141595Sbill 		yyerror("Illegal `align' argument");
142595Sbill 		return;
143595Sbill 	}
144*680Shenry 	if (xp->e_xvalue > 2){
145*680Shenry 		if (passno == 1){
146*680Shenry 		  yywarning(".align %d in any segment is NOT preserved by the loader",
147*680Shenry 			xp->e_xvalue);
148*680Shenry 		  yywarning(".align %d converted to .align 2",
149*680Shenry 			xp->e_xvalue);
150*680Shenry 		}
151*680Shenry 		xp->e_xvalue = 2;
152678Shenry 	}
153595Sbill 	flushfield(NBPW/4);
154595Sbill 	if (passno == 1) {
155630Shenry 		sp->s_tag = JXALIGN;
156630Shenry 		sp->s_jxfear = (1 << xp->e_xvalue) - 1;
157630Shenry 		sp->s_type = dotp->e_xtype;
158630Shenry 		sp->s_index = dotp-usedot;
159595Sbill 		/*
160595Sbill 		 *	We guess that the align will take up at least one
161595Sbill 		 *	byte in the code output.  We will correct for this
162595Sbill 		 *	initial high guess when we explode (bump) aligns
163595Sbill 		 *	when we fix the jxxxes.  We must do this guess
164595Sbill 		 *	so that the symbol table is sorted correctly
165595Sbill 		 *	and labels declared to fall before the align
166595Sbill 		 *	really get their, instead of guessing zero size
167595Sbill 		 *	and have the label (incorrectly) fall after the jxxx.
168595Sbill 		 *	This is a quirk of our requirement that indices into
169595Sbill 		 *	the code stream point to the next byte following
170595Sbill 		 *	the logical entry in the symbol table
171595Sbill 		 */
172630Shenry 		dotp->e_xvalue += 1;
173630Shenry 		sp->s_value = dotp->e_xvalue;
174595Sbill 		njxxx++;
175595Sbill 	} else {
176630Shenry 		mask = (1 << xp->e_xvalue) - 1;
177630Shenry 		while (dotp->e_xvalue & mask){
178595Sbill #ifdef UNIX
179595Sbill 			outb(0);
180595Sbill #endif UNIX
181595Sbill #ifdef VMS
182595Sbill 			*vms_obj_ptr++ = -1;
183595Sbill 			*vms_obj_ptr++ = 0;
184630Shenry 			dotp->e_xvalue += 1;
185595Sbill #endif VMS
186595Sbill 		}
187595Sbill 	}
188595Sbill }
189595Sbill 
190595Sbill /*
191595Sbill  *	Pass 1.5, resolve jxxx instructions and .align in .text
192595Sbill  */
193595Sbill jxxxfix()
194595Sbill {
195595Sbill 	register struct symtab 	*jumpfrom;
196595Sbill 		 struct symtab	**cojumpfrom, *ubjumpfrom;
197595Sbill 	register struct symtab 	*dest;
198595Sbill 	register struct symtab	*intdest;	/*intermediate dest*/
199595Sbill 	register struct symtab	**cointdest, *ubintdest;
200595Sbill 
201595Sbill 	register struct symtab 	*tunnel;
202595Sbill 	 	 int 		displ,nchange;
203595Sbill 		 int		badjxalign;	/*if jump across an align*/
204595Sbill 		 int		stillactives;	/*if still active jxxxes*/
205595Sbill 		 int		segno;		/*current segment number*/
206595Sbill 		 int		topono;		/*which iteration in the topo sort*/
207595Sbill 	register unsigned char	tag;
208595Sbill 	/*
209595Sbill 	 *	consider each segment in turn...
210595Sbill 	 */
211595Sbill 	for (segno = 0; segno < NLOC + NLOC; segno++){
212595Sbill 	    badjxalign = 0;		/*done on a per segment basis*/
213595Sbill 	    /*
214595Sbill 	     *	Do a lazy topological sort.
215595Sbill 	     */
216595Sbill 	    for (topono = 1, nchange = 1; nchange != 0; topono++){
217595Sbill #ifdef DEBUG
218595Sbill 		if (debug)
219595Sbill 			printf("\nSegment %d, topo iteration %d\n",
220595Sbill 				segno, topono);
221595Sbill #endif
222595Sbill 		nchange = 0;
223595Sbill 		stillactives = 0;
224595Sbill 		/*
225595Sbill 		 *	We keep track of one possible tunnel location.
226595Sbill 		 *	A tunnel will eventually be an unconditional
227595Sbill 		 *	branch to the same place that another jxxx
228595Sbill 		 *	will want to branch to.  We will turn a
229595Sbill 		 *	branch conditional/unconditional (word) that would
230595Sbill 		 *	have to get bumped because its destination is too
231595Sbill 		 *	far away, into a branch conditional/unconditional
232595Sbill 		 *	byte to the tunnel branch conditional/unconditional.
233595Sbill 		 *	Of course, the tunnel must branch to the same place
234595Sbill 		 *	as we want to go.
235595Sbill 		 */
236595Sbill 		tunnel = 0;	/*initially, no tunnel*/
237595Sbill 		SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom, ubjumpfrom, ++){
238630Shenry 			tag = jumpfrom->s_tag;
239595Sbill 			if (tag <= IGNOREBOUND)
240595Sbill 				continue;	/*just an ordinary symbol*/
241595Sbill 			if (tag == JXALIGN){
242595Sbill 				tunnel = 0;	/*avoid tunneling across a flex alocation*/
243595Sbill 				continue;	/*we take care of these later*/
244595Sbill 			}
245636Shenry 			if (   jumpfrom->s_jxfear == jbrfsize	/*unconditional*/
246595Sbill 			    || (   tag == JXINACTIVE		/*inactive bumped*/
247630Shenry 				&& (jumpfrom->s_jxbump != 0)
248595Sbill 			       )
249595Sbill 			   ) tunnel = jumpfrom;
250595Sbill 			if (tag != JXACTIVE)
251595Sbill 				continue;
252630Shenry 			dest = jumpfrom->s_dest;
253630Shenry 			if (jumpfrom->s_index != dest->s_index){
254595Sbill 				yyerror("Intersegment jxxx");
255595Sbill 				continue;
256595Sbill 			}
257630Shenry 			displ = dest->s_value - jumpfrom->s_value;
258595Sbill 			if (displ < MINBYTE || displ > MAXBYTE) {
259595Sbill 				/*
260595Sbill 				 *	This is an immediate lose!
261595Sbill 				 *
262595Sbill 				 *	We first attempt to tunnel
263595Sbill 				 *	by finding an intervening jump that
264595Sbill 				 *	has  the same destination.
265595Sbill 				 *	The tunnel is always the first preceeding
266595Sbill 				 *	jxxx instruction, so the displacement
267595Sbill 				 *	to the tunnel is less than zero, and
268595Sbill 				 *	its relative position will be unaffected
269595Sbill 				 *	by future jxxx expansions.
270636Shenry 				 *
271636Shenry 				 *	No tunnels if doing jumps...
272595Sbill 				 */
273636Shenry 				if (    (!jxxxJUMP)
274636Shenry 				     && (jumpfrom->s_jxfear > jbrfsize)
275595Sbill 				     && (tunnel)
276630Shenry 				     && (tunnel->s_dest == jumpfrom->s_dest)
277630Shenry 				     && (tunnel->s_index == jumpfrom->s_index)
278630Shenry 				     && (tunnel->s_value - jumpfrom->s_value >=
279636Shenry 						MINBYTE + jxxxfsize)
280595Sbill 				   ) {
281595Sbill 						/*
282595Sbill 						 *	tunnelling is OK
283595Sbill 						 */
284630Shenry 						jumpfrom->s_dest = tunnel;
285595Sbill 						/*
286595Sbill 						 * no bumping needed, this
287595Sbill 						 * is now effectively inactive
288595Sbill 						 * but must be remembered
289595Sbill 						 */
290630Shenry 						jumpfrom->s_tag = JXTUNNEL;
291595Sbill #ifdef DEBUG
292595Sbill 						if(debug)
293595Sbill 						printf("Tunnel from %s from line %d\n",
294630Shenry 							jumpfrom->s_name, lineno);
295595Sbill #endif
296595Sbill 						continue;
297595Sbill 				} else {	/*tunneling not possible*/
298595Sbill 					/*
299595Sbill 					 *	since this will be turned
300595Sbill 					 *	into a bumped jump, we can
301595Sbill 					 *	use the unconditional jump
302595Sbill 					 *	as a tunnel
303595Sbill 					 */
304595Sbill 					tunnel = jumpfrom;
305630Shenry 					jumpfrom->s_tag = JXNOTYET;
306595Sbill 					++nchange;
307595Sbill 					continue;
308595Sbill 				}
309595Sbill 			}	/*end of immediate lose*/
310595Sbill 			/*
311595Sbill 			 *	Do a forward search for an intervening jxxx
312595Sbill 			 */
313595Sbill 			if (displ >= 0) {
314595Sbill 				SEGITERATE(segno, cojumpfrom + 1,0,cointdest,
315595Sbill 						intdest, ubintdest, ++){
316630Shenry 					if (intdest->s_value > dest->s_value)
317595Sbill 						break; /* beyond destination */
318630Shenry 					if (intdest->s_tag <= JXQUESTIONABLE)
319595Sbill 						continue;	/*frozen solid*/
320630Shenry 					if (intdest->s_tag == JXALIGN){
321630Shenry 						jumpfrom->s_jxoveralign = 1;
322595Sbill 						badjxalign++;
323595Sbill 					}
324595Sbill 					/*
325595Sbill 					 *	we assume the worst case
326595Sbill 					 *	for unfrozen jxxxxes
327595Sbill 					 */
328630Shenry 					displ += intdest->s_jxfear;
329595Sbill 				}
330595Sbill 				if (displ <= MAXBYTE){
331595Sbill 					/*
332595Sbill 					 *	the worst possible conditions
333595Sbill 					 *	can't hurt us, so forget about
334595Sbill 					 *	this jump
335595Sbill 					 */
336630Shenry 					jumpfrom->s_tag = JXINACTIVE;
337595Sbill 				} else {
338595Sbill 					stillactives++;
339595Sbill 				}
340595Sbill 			} else {
341595Sbill 			/*
342595Sbill 			 *	backward search for intervening jxxx
343595Sbill 			 */
344595Sbill 				SEGITERATE(segno, cojumpfrom - 1,1,cointdest,
345595Sbill 				  intdest, ubintdest, --){
346630Shenry 					if (intdest->s_value <= dest->s_value)
347595Sbill 						break; /* beyond destination */
348630Shenry 					if (intdest->s_tag <= JXQUESTIONABLE)
349595Sbill 						continue;	/*frozen solid*/
350630Shenry 					if (intdest->s_tag == JXALIGN){
351630Shenry 						jumpfrom->s_jxoveralign = 1;
352595Sbill 						badjxalign++;
353595Sbill 					}
354630Shenry 					displ -= intdest->s_jxfear;
355595Sbill 				}
356595Sbill 				if (displ >= MINBYTE) {
357630Shenry 					jumpfrom->s_tag = JXINACTIVE;
358595Sbill 				} else {
359595Sbill 					stillactives++;
360595Sbill 				}
361595Sbill 			}	/*end of backwards search*/
362595Sbill 		}	/*end of iterating through all symbols in this seg*/
363595Sbill 
364595Sbill 		if (nchange == 0) {
365595Sbill 			/*
366595Sbill 			 *	Now, if there are still active jxxx entries,
367595Sbill 			 *	we are partially deadlocked.  We can leave
368595Sbill 			 *	these jxxx entries in their assumed short jump
369595Sbill 			 *	form, as all initial displacement calcualtions
370595Sbill 			 *	are hanging on unresolved jxxx instructions
371595Sbill 			 *	that might explode into a long form, causing
372595Sbill 			 *	other jxxxes jumping across the first set of
373595Sbill 			 *	jxxxes to explode, etc.
374595Sbill 			 *	However, if a jxxx jumps across a .align,
375595Sbill 			 *	we assume the worst for the deadlock cycle,
376595Sbill 			 *	and resolve all of them towards the long
377595Sbill 			 *	jump.
378595Sbill 			 *	Currently, the C compiler does not produce
379595Sbill 			 *	jumps across aligns, as aligns are only used
380595Sbill 			 *	in data segments, or in text segments to align
381595Sbill 			 *	functions.
382595Sbill 			 */
383595Sbill 			if (stillactives){
384595Sbill 				SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
385595Sbill 				    ubjumpfrom, ++){
386630Shenry 					if (jumpfrom->s_tag == JXACTIVE){
387630Shenry 						jumpfrom->s_tag =
388595Sbill 						  badjxalign?JXNOTYET:JXINACTIVE;
389595Sbill 					}
390595Sbill 				}
391595Sbill 				if (badjxalign){
392595Sbill 					jxxxbump(segno, (struct symtab **)0);
393595Sbill 				}
394595Sbill 			}
395595Sbill 			/*
396595Sbill 			 *	Handle  all of the .align s
397595Sbill 			 */
398595Sbill 			SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
399595Sbill 			   ubjumpfrom, ++){
400630Shenry 			    if (jumpfrom->s_tag == JXALIGN){
401595Sbill 				/*
402595Sbill 				 *	Predict the true displacement
403595Sbill 				 *	needed, irregardless of the
404595Sbill 				 *	fact that we guessed 1
405595Sbill 				 */
406630Shenry 				displ = (jumpfrom->s_value - 1) & (unsigned)jumpfrom->s_jxfear;
407595Sbill 				if (displ == 0){	/*no virtual displacement*/
408630Shenry 					jumpfrom->s_jxfear = -1;
409595Sbill 				} else {
410630Shenry 					jumpfrom->s_jxfear = (jumpfrom->s_jxfear + 1) - displ;
411595Sbill 					/*
412630Shenry 					 *	assert jumpfrom->s_jxfear > 0
413595Sbill 					 */
414630Shenry 					if (jumpfrom->s_jxfear == 1){
415595Sbill 						/*our prediction was correct*/
416595Sbill 						continue;
417595Sbill 					}
418595Sbill 					/*
419630Shenry 					 *	assert jumpfrom->s_jxfear > 1
420595Sbill 					 */
421630Shenry 					jumpfrom->s_jxfear -= 1;	/*correct guess*/
422595Sbill 				}
423595Sbill 				/*
424630Shenry 				 *	assert jumpfrom->s_jxfear = -1, +1...2**n-1
425595Sbill 				 */
426630Shenry 				jumpfrom->s_tag = JXNOTYET;	/*signal*/
427595Sbill 				jxxxbump(segno, cojumpfrom);
428630Shenry 				jumpfrom->s_tag = JXINACTIVE;
429595Sbill 				/*
430595Sbill 				 *	Assert jxfrom->jxvalue indexes the first
431595Sbill 				 *	code byte after the added bytes, and
432595Sbill 				 *	has n low order zeroes.
433595Sbill 				 */
434595Sbill 			  }
435595Sbill 			}	/*end of walking through each segment*/
436595Sbill 	    	}	/*end of no changes */
437595Sbill 		else {	/*changes, and still have to try another pass*/
438595Sbill 			jxxxbump(segno, (struct symtab **)0);
439595Sbill 		}
440595Sbill 	   }	/*end of doing the topologic sort*/
441595Sbill 	}	/*end of iterating through all segments*/
442595Sbill }	/*end of jxxxfix*/
443595Sbill 
444595Sbill /*
445595Sbill  *	Go through the symbols in a given segment number,
446595Sbill  *	and see which entries are jxxx entries that have
447595Sbill  *	been logically "exploded" (expanded), but for which
448595Sbill  *	the value of textually following symbols has not been
449595Sbill  *	increased
450595Sbill  */
451595Sbill 
452595Sbill jxxxbump(segno, starthint)
453595Sbill 	int	segno;
454595Sbill 	struct	symtab **starthint;
455595Sbill {
456595Sbill 	register	struct	symtab	**cosp, *sp;
457595Sbill 	register	struct	symtab		*ub;
458595Sbill 	register	int	cum_bump;
459595Sbill 	register	unsigned	char	tag;
460595Sbill 
461595Sbill 	cum_bump = 0;
462595Sbill 	SEGITERATE(segno, starthint, 0, cosp, sp, ub, ++){
463630Shenry 		tag = sp->s_tag;
464595Sbill 		if (tag == JXNOTYET){
465595Sbill #ifdef DEBUG
466595Sbill 			if (debug){
467630Shenry 			if (sp->s_dest != 0)
468595Sbill 				printf("Explode jump to %s on line %d\n",
469630Shenry 					sp->s_dest->s_name, lineno);
470595Sbill 			else
471595Sbill 				printf("Explode an align!\n");
472595Sbill 			}
473595Sbill #endif
474630Shenry 			sp->s_tag = JXINACTIVE;
475630Shenry 			sp->s_jxbump = 1;
476630Shenry 			cum_bump += sp->s_jxfear;
477595Sbill 		}
478595Sbill 		/*
479595Sbill 		 *	Only bump labels and jxxxes. Ignored entries can
480595Sbill 		 *	be incremented, as they are thrown away later on.
481595Sbill 		 *	Stabds are given their final value in the second
482595Sbill 		 *	pass.
483595Sbill 		 */
484595Sbill 		if (tag >= OKTOBUMP)	/*only bump labels and jxxxes and floating stabs*/
485630Shenry 			sp->s_value += cum_bump;
486595Sbill 	}
487630Shenry 	usedot[segno].e_xvalue += cum_bump;
488595Sbill }
489