xref: /csrg-svn/old/adb/adb.vax/opset.c (revision 8912)
1*8912Srrh #ifndef lint
2*8912Srrh static	char sccsid[] = "@(#)opset.c 4.2 10/27/82";
3*8912Srrh #endif lint
43760Sroot /*
53760Sroot  *	UNIX debugger
6*8912Srrh  *	Instruction printing routines.
7*8912Srrh  *	MACHINE DEPENDENT
83760Sroot  */
93760Sroot 
10*8912Srrh #ifdef ADB
113760Sroot #include "defs.h"
12*8912Srrh #endif ADB
13*8912Srrh #ifdef SDB
14*8912Srrh #include "head.h"
15*8912Srrh #endif SDB
163760Sroot 
173760Sroot L_INT		dot;
183760Sroot INT		dotinc;
19*8912Srrh L_INT		insoutvar[36];
20*8912Srrh #ifdef ADB
21*8912Srrh L_INT		var[36];
22*8912Srrh #endif ADB
233760Sroot 
24*8912Srrh #undef	INSTTAB
25*8912Srrh #include "instrs.h"
263760Sroot 
27*8912Srrh STRING	regname[];
28*8912Srrh STRING	fltimm[];
29*8912Srrh POS	type, space, incp;
303760Sroot /*
31*8912Srrh  *	Definitions for registers and for operand classes
323760Sroot  */
33*8912Srrh char	*insregname();	/* how to print a register */
343760Sroot 
35*8912Srrh #define	R_PC		0xF
36*8912Srrh 
37*8912Srrh #define	OC_IMM0		0x0
38*8912Srrh #define	OC_IMM1		0x1
39*8912Srrh #define	OC_IMM2		0x2
40*8912Srrh #define	OC_IMM3		0x3
41*8912Srrh #define	OC_INDEX	0x4
42*8912Srrh #define	OC_REG		0x5
43*8912Srrh #define	OC_DREG		0x6
44*8912Srrh #define	OC_ADREG	0x7
45*8912Srrh #define	OC_AIREG	0x8
46*8912Srrh #define	OC_DAIREG	0x9
47*8912Srrh 
48*8912Srrh #define	OC_BDISP	0xA
49*8912Srrh #define	OC_DBDISP	0xB
50*8912Srrh #define	OC_WDISP	0xC
51*8912Srrh #define	OC_DWDISP	0xD
52*8912Srrh #define	OC_LDISP	0xE
53*8912Srrh #define	OC_DLDISP	0xF
54*8912Srrh 
55*8912Srrh #define	OC_SHIFT	4
56*8912Srrh #define	OC_CONS(oc,reg)	(((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
57*8912Srrh #define	OC_AMEXT(x)	(((x) >> OC_SHIFT) & 0xF)
58*8912Srrh #define	OC_REGEXT(x)	((x) & 0xF)
59*8912Srrh 
603760Sroot /*
61*8912Srrh  *	Definitions for large numbers
623760Sroot  */
63*8912Srrh #include "asnumber.h"
64*8912Srrh typedef	struct	as_number	*numberp;
65*8912Srrh numberp snarf();
66*8912Srrh numberp snarfreloc();
67*8912Srrh /*
68*8912Srrh  *	Definitions for special instructions
69*8912Srrh  */
70*8912Srrh #define	CASEB	0x8F
71*8912Srrh #define	CASEW	0xAF
72*8912Srrh #define	CASEL	0xCF
73*8912Srrh /*
74*8912Srrh  *	Definitions for converting TYP's into numbers, booleans, etc.
75*8912Srrh  *	These are shared with the assembler.
76*8912Srrh  */
77*8912Srrh extern	int	ty_NORELOC[];
78*8912Srrh extern	int	ty_float[];
79*8912Srrh extern	int	ty_nbyte[];
80*8912Srrh extern	int	ty_nlg[];
81*8912Srrh extern	char	*ty_string[];
823760Sroot 
83*8912Srrh short ioptab[3][256];	/* two level index by opcode into insttab */
843760Sroot 
85*8912Srrh int mapescbyte(byte)
86*8912Srrh 	u_char	byte;
87*8912Srrh {
88*8912Srrh 	switch(byte){
89*8912Srrh 	default:	return(0);
90*8912Srrh 	case ESCD:	return(1);
91*8912Srrh 	case ESCF:	return(2);
92*8912Srrh 	}
93*8912Srrh }
943760Sroot 
95*8912Srrh mkioptab()
96*8912Srrh {
97*8912Srrh 	REG	struct insttab *p;
98*8912Srrh 		int	mapchar;
993760Sroot 
100*8912Srrh 	for(p = insttab; p->iname; p++){
101*8912Srrh 		mapchar = mapescbyte(p->eopcode);
102*8912Srrh 		if (ioptab[mapchar][p->popcode])
103*8912Srrh 			continue;
104*8912Srrh 		ioptab[mapchar][p->popcode] = p - insttab;
1053760Sroot 	}
1063760Sroot }
1073760Sroot 
108*8912Srrh u_char snarfuchar();
109*8912Srrh /*
110*8912Srrh  *	Global variables for communicating with the minions and printins
111*8912Srrh  */
112*8912Srrh static	int	idsp;
113*8912Srrh static	short	argno;		/* which argument one is working on */
114*8912Srrh static	char	insoutfmt[2];	/* how to format the relocated symbols */
115*8912Srrh #ifdef SDB
116*8912Srrh static	struct	proct	*procp;
117*8912Srrh #endif SDB
1183760Sroot 
119*8912Srrh static savevar(val)
120*8912Srrh 	long	val;
121*8912Srrh {
122*8912Srrh 	var[argno] = val;
123*8912Srrh 	insoutvar[argno] = val;
124*8912Srrh }
125*8912Srrh 
126*8912Srrh printins(fmt, Idsp, ins)
127*8912Srrh 	char	fmt;
1283760Sroot #ifndef vax
129*8912Srrh 	u_char	ins;
1303760Sroot #else
131*8912Srrh 	u_char	ins;
1323760Sroot #endif
133*8912Srrh 	int	Idsp;
1343760Sroot {
135*8912Srrh 		u_char	mode;		/* mode */
136*8912Srrh 		u_char	ins2;
137*8912Srrh 		char	*indexreg;	/* print of which register indexes */
138*8912Srrh 		char	*indexed;	/* we indexed */
139*8912Srrh 		char	*operandout();
140*8912Srrh 	REG	u_char 	*ap;
141*8912Srrh 	REG	struct insttab *ip;
142*8912Srrh 		u_char	optype;
143*8912Srrh 		int	mapchar;
1443760Sroot 
145*8912Srrh 	idsp = Idsp;
1463760Sroot 	type = DSYM;
1473760Sroot 	space = idsp;
148*8912Srrh #ifdef SDB
149*8912Srrh 	procp = adrtoprocp(dot);
150*8912Srrh 	if (procp->paddr == dot){
151*8912Srrh 		printf("0x%04.4x", ins);
152*8912Srrh 		incp = 2;
153*8912Srrh 		goto ret;
154*8912Srrh 	}
155*8912Srrh #endif SDB
156*8912Srrh 
157*8912Srrh #ifdef ADB
158*8912Srrh 	insoutfmt[0] = 0;
159*8912Srrh #endif ADB
160*8912Srrh #ifdef SDB
161*8912Srrh 	insoutfmt[0] = fmt;
162*8912Srrh #endif SDB
163*8912Srrh 
1643760Sroot 	incp = 1;
165*8912Srrh 	if ((mapchar = mapescbyte(ins)) != 0){
166*8912Srrh 		ins2 = snarfuchar();
167*8912Srrh 		if (ioptab[mapchar][ins2] == 0){
168*8912Srrh 			/*
169*8912Srrh 			 *	Oops; not a defined instruction;
170*8912Srrh 			 *	back over this escape byte.
171*8912Srrh 			 */
172*8912Srrh 			incp -= 1;
173*8912Srrh 			mapchar = 0;
174*8912Srrh 		} else {
175*8912Srrh 			ins = ins2;
1763760Sroot 		}
177*8912Srrh 	}
178*8912Srrh 	if (ioptab[mapchar][ins] == 0){
179*8912Srrh 		printf("<undefined operator byte>: %x", ins);
180*8912Srrh 		goto ret;
181*8912Srrh 	}
182*8912Srrh 	ip = &insttab[ioptab[mapchar][ins]];
183*8912Srrh 	printf("%s\t", ip->iname);
184*8912Srrh 
185*8912Srrh 	for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) {
186*8912Srrh 		savevar(0x80000000);	/* an illegal symbol */
187*8912Srrh 		optype = *ap;
188*8912Srrh 		if (argno != 0)
189*8912Srrh 			printc(',');
190*8912Srrh 		indexreg = 0;
191*8912Srrh 		indexed = 0;
192*8912Srrh 		do{
193*8912Srrh 			if (A_ACCEXT(optype) & ACCB){
194*8912Srrh 				switch(A_TYPEXT(optype)){
195*8912Srrh 				case TYPB:
196*8912Srrh 					mode = OC_CONS(OC_BDISP, R_PC);
1973760Sroot 					break;
198*8912Srrh 				case TYPW:
199*8912Srrh 					mode = OC_CONS(OC_WDISP, R_PC);
2003760Sroot 					break;
201*8912Srrh 				}
202*8912Srrh 			} else {
203*8912Srrh 				mode = snarfuchar();
204*8912Srrh 			}
205*8912Srrh 			indexreg = operandout(mode, optype);
206*8912Srrh 			if (indexed)
207*8912Srrh 				printf("[%s]", indexed);
208*8912Srrh 			indexed = indexreg;
209*8912Srrh 		} while(indexed);
2103760Sroot 	}
211*8912Srrh 	if (mapchar == 0){
212*8912Srrh 		switch(ins){
213*8912Srrh 		case CASEB:
214*8912Srrh 		case CASEW:
215*8912Srrh 		case CASEL:
216*8912Srrh 			casebody(insoutvar[1], insoutvar[2]);
217*8912Srrh 			break;
218*8912Srrh 		default:
219*8912Srrh 			break;
2203760Sroot 		}
2213760Sroot 	}
222*8912Srrh    ret: ;
223*8912Srrh 
224*8912Srrh #ifdef SDB
225*8912Srrh 	oincr = incp;
226*8912Srrh #endif SDB
227*8912Srrh #ifdef ADB
228*8912Srrh 	dotinc = incp;
229*8912Srrh #endif ADB
2303760Sroot }
2313760Sroot 
232*8912Srrh casebody(base, limit)
233*8912Srrh 	long	base;
234*8912Srrh 	long	limit;
235*8912Srrh {
236*8912Srrh 	int	i;
237*8912Srrh 	POS	baseincp;
238*8912Srrh 	POS	advincp;
239*8912Srrh 	struct	as_number	*valuep;
240*8912Srrh #define	OSIZE (sizeof(short))
241*8912Srrh 	argno = 0;
242*8912Srrh 	baseincp = incp;
243*8912Srrh 	for (i = 0; i <= limit; i++) {
244*8912Srrh 		printc(EOR);
245*8912Srrh #ifdef SDB
246*8912Srrh 		printf("    %d:  ", i + base);
247*8912Srrh #endif SDB
248*8912Srrh #ifdef ADB
249*8912Srrh 		printf("    %R:  ", i + base);
250*8912Srrh #endif ADB
251*8912Srrh 		valuep = snarfreloc(OSIZE, 0);
252*8912Srrh 		advincp = incp;
253*8912Srrh 		incp = baseincp;
254*8912Srrh 		dispaddress(valuep, OC_CONS(OC_WDISP, R_PC));
255*8912Srrh 		incp = advincp;
256*8912Srrh 	}
257*8912Srrh }
258*8912Srrh 
2593760Sroot /*
2603760Sroot  *	magic values to mung an offset to a register into
2613760Sroot  *	something that psymoff can understand.. all magic
2623760Sroot  */
2633760Sroot 			      /* 0	1	2	3	4 */
2643760Sroot static long magic_masks[5] =	{0,	0x80,	0x8000,	0,	0};
2653760Sroot static long magic_compl[5] =	{0,	0x100,	0x10000,0,	0};
266*8912Srrh /*
267*8912Srrh  *	Snarf up some bytes, and put in the magic relocation flags
268*8912Srrh  */
269*8912Srrh numberp snarfreloc(nbytes)
270*8912Srrh 	int	nbytes;
271*8912Srrh {
272*8912Srrh 	numberp	back;
273*8912Srrh 	back = snarf(nbytes);
274*8912Srrh 	if (back->num_ulong[0] & magic_masks[nbytes])
275*8912Srrh 		back->num_ulong[0] -= magic_compl[nbytes];
276*8912Srrh 	return(back);
277*8912Srrh }
278*8912Srrh /*
279*8912Srrh  *	The following code is NOT portable from the PDP 11 to the VAX
280*8912Srrh  *	because of the byte ordering problem.
281*8912Srrh  */
282*8912Srrh numberp snarf(nbytes)
283*8912Srrh 	int	nbytes;
284*8912Srrh {
285*8912Srrh 	REG	int	i;
2863760Sroot 
287*8912Srrh 	static	struct	as_number	backnumber;
288*8912Srrh 	static	struct	as_number	znumber;	/* init'ed to 0 */
289*8912Srrh 
290*8912Srrh 	backnumber = znumber;
291*8912Srrh 	for (i = 0; i < nbytes; i++)
292*8912Srrh 		backnumber.num_uchar[i] = snarfuchar();
293*8912Srrh 	return(&backnumber);
294*8912Srrh }
2953760Sroot /*
296*8912Srrh  *	Read one single character, and advance the dot
2973760Sroot  */
298*8912Srrh u_char snarfuchar()
2993760Sroot {
300*8912Srrh 	u_char	back;
301*8912Srrh 	/*
302*8912Srrh 	 *	assert: bchkget and inkdot don't have side effects
303*8912Srrh 	 */
304*8912Srrh 	back = (u_char)bchkget(inkdot(incp), idsp);
305*8912Srrh 	incp += 1;
306*8912Srrh 	return(back);
307*8912Srrh }
308*8912Srrh /*
309*8912Srrh  *	normal operand; return non zero pointer to register
310*8912Srrh  *	name if this is an index instruction.
311*8912Srrh  */
312*8912Srrh char *operandout(mode, optype)
313*8912Srrh 	u_char	mode;
314*8912Srrh 	u_char	optype;
315*8912Srrh {
316*8912Srrh 	char	*r;
317*8912Srrh 	int	regnumber;
318*8912Srrh 	int	nbytes;
3193760Sroot 
320*8912Srrh 	regnumber = OC_REGEXT(mode);
321*8912Srrh 	r = insregname(regnumber);
322*8912Srrh 	switch (OC_AMEXT(mode)){
323*8912Srrh 	case OC_IMM0:
324*8912Srrh 	case OC_IMM1:
325*8912Srrh 	case OC_IMM2:
326*8912Srrh 	case OC_IMM3:
327*8912Srrh 		shortliteral(mode, optype);
328*8912Srrh 		return(0);
329*8912Srrh 	case OC_INDEX:
330*8912Srrh 		return(r);		/* will be printed later */
331*8912Srrh 	case OC_REG:
332*8912Srrh 		printf("%s", r);
333*8912Srrh 		return(0);
334*8912Srrh 	case OC_DREG:
335*8912Srrh 		printf("(%s)", r);
336*8912Srrh 		return(0);
337*8912Srrh 	case OC_ADREG:
338*8912Srrh 		printf("-(%s)", r);
339*8912Srrh 		return(0);
340*8912Srrh 	case OC_DAIREG:
341*8912Srrh 		printc('*');
342*8912Srrh 	case OC_AIREG:
343*8912Srrh 		if (regnumber == R_PC){
344*8912Srrh 			pcimmediate(mode, optype);
345*8912Srrh 		} else {
346*8912Srrh 			printf("(%s)+", r);
347*8912Srrh 		}
348*8912Srrh 		return(0);
349*8912Srrh 	case OC_DBDISP:
350*8912Srrh 		printc('*');
351*8912Srrh 	case OC_BDISP:
352*8912Srrh 		nbytes = 1;
353*8912Srrh 		break;
354*8912Srrh 	case OC_DWDISP:
355*8912Srrh 		printc('*');
356*8912Srrh 	case OC_WDISP:
357*8912Srrh 		nbytes = 2;
358*8912Srrh 		break;
359*8912Srrh 	case OC_DLDISP:
360*8912Srrh 		printc('*');
361*8912Srrh 	case OC_LDISP:
362*8912Srrh 		nbytes = 4;
363*8912Srrh 		break;
3643760Sroot 	}
365*8912Srrh 	dispaddress(snarfreloc(nbytes), mode);
366*8912Srrh 	return(0);
3673760Sroot }
3683760Sroot 
369*8912Srrh dispaddress(valuep, mode)
370*8912Srrh 	numberp	valuep;
371*8912Srrh 	u_char	mode;
3723760Sroot {
373*8912Srrh 	int	regnumber = OC_REGEXT(mode);
3743760Sroot 
375*8912Srrh 	switch(OC_AMEXT(mode)){
376*8912Srrh 	case OC_BDISP:
377*8912Srrh 	case OC_DBDISP:
378*8912Srrh 	case OC_WDISP:
379*8912Srrh 	case OC_DWDISP:
380*8912Srrh 	case OC_LDISP:
381*8912Srrh 	case OC_DLDISP:
382*8912Srrh 		if (regnumber == R_PC){
383*8912Srrh 			/* PC offset addressing */
384*8912Srrh 			valuep->num_ulong[0] += inkdot(incp);
385*8912Srrh 		}
386*8912Srrh 	}
387*8912Srrh #ifdef ADB
388*8912Srrh 	psymoff(valuep->num_ulong[0], type, &insoutfmt[0]);
389*8912Srrh 	if (regnumber != R_PC){		/* } */
390*8912Srrh #endif ADB
391*8912Srrh #ifdef SDB
392*8912Srrh 	if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0])
393*8912Srrh 	   && (regnumber != R_PC)){
394*8912Srrh #endif SDB
395*8912Srrh 		printf("(%s)", insregname(regnumber));
396*8912Srrh 	}
397*8912Srrh 	savevar((long)valuep->num_ulong[0]);
3983760Sroot }
399*8912Srrh /*
400*8912Srrh  *	get a register name
401*8912Srrh  */
402*8912Srrh char *insregname(regnumber)
403*8912Srrh 	int	regnumber;
404*8912Srrh {
405*8912Srrh 	char	*r;
406*8912Srrh 	r = regname[regnumber];
407*8912Srrh #ifdef SDB
408*8912Srrh 	if (   (insoutfmt[0] == 'i')
409*8912Srrh 	    && (regnumber >= 6)
410*8912Srrh 	    && (regnumber <= 11)
411*8912Srrh 	    && (adrtoregvar(regnumber, procp) != -1)) {
412*8912Srrh 		r = sl_name;
413*8912Srrh 	}
414*8912Srrh #endif SDB
415*8912Srrh 	return(r);
416*8912Srrh }
417*8912Srrh /*
418*8912Srrh  *	print out a short literal
419*8912Srrh  */
420*8912Srrh shortliteral(mode, optype)
421*8912Srrh 	u_char	mode;
422*8912Srrh 	u_char	optype;
423*8912Srrh {
424*8912Srrh 	savevar((long)mode);
425*8912Srrh 	switch(A_TYPEXT(optype)){
426*8912Srrh 	case TYPF:
427*8912Srrh 	case TYPD:
428*8912Srrh 	case TYPG:
429*8912Srrh 	case TYPH:
430*8912Srrh 		printf("$%s", fltimm[mode]);
431*8912Srrh 		break;
432*8912Srrh 	default:
433*8912Srrh #ifdef ADB
434*8912Srrh 		printf("$%r", mode);
435*8912Srrh #endif ADB
436*8912Srrh #ifdef SDB
437*8912Srrh 		printf("$%d", mode);
438*8912Srrh #endif SDB
439*8912Srrh 		break;
440*8912Srrh 	}
441*8912Srrh }
4423760Sroot 
443*8912Srrh pcimmediate(mode, optype)
444*8912Srrh 	u_char	mode;
445*8912Srrh 	u_char	optype;
4463760Sroot {
447*8912Srrh 	int	nbytes;
448*8912Srrh 
449*8912Srrh 	printc('$');
450*8912Srrh 	if (mode == OC_DAIREG){	/* PC absolute, always 4 bytes*/
451*8912Srrh 		dispaddress(snarfreloc(4), mode);
452*8912Srrh 		return;
453*8912Srrh 	}
454*8912Srrh 	nbytes = ty_nbyte[A_TYPEXT(optype)];
455*8912Srrh 	if (! ty_NORELOC[A_TYPEXT(optype)]){
456*8912Srrh 		dispaddress(snarfreloc(nbytes), mode);
457*8912Srrh 		return;
458*8912Srrh 	}
459*8912Srrh 	bignumprint(nbytes, optype);
460*8912Srrh }
461*8912Srrh 
462*8912Srrh bignumprint(nbytes, optype)
463*8912Srrh 	int	nbytes;
464*8912Srrh 	u_char	optype;
465*8912Srrh {
466*8912Srrh 	numberp	valuep;
4673760Sroot 	int	leading_zero = 1;
468*8912Srrh 	REG	int	bindex;
469*8912Srrh 	REG	int	nindex;
470*8912Srrh 	REG	int	ch;
4713760Sroot 
472*8912Srrh 	valuep = snarf(nbytes);
473*8912Srrh 	switch(A_TYPEXT(optype)){
474*8912Srrh 	case TYPF:
475*8912Srrh 		printf("0f%f", valuep->num_num.numFf_float.Ff_value);
476*8912Srrh 		break;
477*8912Srrh 	case TYPD:
478*8912Srrh 		printf("0d%f", valuep->num_num.numFd_float.Fd_value);
479*8912Srrh 		break;
480*8912Srrh 	case TYPG:
481*8912Srrh 		printf("0g::"); goto qprint;
482*8912Srrh 	case TYPH:
483*8912Srrh 		printf("0h::"); goto qprint;
484*8912Srrh 	case TYPQ:
485*8912Srrh 	case TYPO:
486*8912Srrh 	qprint:
487*8912Srrh 		for (bindex = nbytes - 1; bindex >= 0; --bindex){
488*8912Srrh 			for (nindex = 4; nindex >= 0; nindex -= 4){
489*8912Srrh 				ch = (valuep->num_uchar[bindex] >> nindex);
490*8912Srrh 				ch &= 0x0F;
491*8912Srrh 				if ( ! (leading_zero &= (ch == 0) ) ){
492*8912Srrh 					if (ch <= 0x09)
493*8912Srrh 						printc(ch + '0');
494*8912Srrh 					else
495*8912Srrh 						printc(ch - 0x0A + 'a');
496*8912Srrh 				}
4973760Sroot 			}
4983760Sroot 		}
499*8912Srrh 		break;
5003760Sroot 	}
5013760Sroot }
502*8912Srrh #ifdef SDB
503*8912Srrh 
504*8912Srrh L_INT inkdot(incr)
505*8912Srrh 	int	incr;
506*8912Srrh {
507*8912Srrh 	L_INT		newdot;
508*8912Srrh 
509*8912Srrh 	newdot = dot + incr;
510*8912Srrh 	return(newdot);
511*8912Srrh }
512*8912Srrh 
513*8912Srrh printc(c)
514*8912Srrh 	char c;
515*8912Srrh {
516*8912Srrh 	printf("%c", c);
517*8912Srrh }
518*8912Srrh 
519*8912Srrh psymoff(v, regnumber, fmt)
520*8912Srrh 	L_INT	v;
521*8912Srrh 	char	*fmt;
522*8912Srrh {
523*8912Srrh 	struct	proct	*procp;
524*8912Srrh 	REG	int diff;
525*8912Srrh 	if (fmt[0] == 'i') {
526*8912Srrh 		switch(regnumber){
527*8912Srrh 		case 12:	/* parameter */
528*8912Srrh 			if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot)))
529*8912Srrh 					!= -1) {
530*8912Srrh 				printf("%s", sl_name);
531*8912Srrh 				prdiff(diff);
532*8912Srrh 				return(0);
533*8912Srrh 			}
534*8912Srrh 			break;
535*8912Srrh 		case 13:	/* local */
536*8912Srrh 			if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot))
537*8912Srrh 					) != -1) {
538*8912Srrh 				printf("%s", sl_name);
539*8912Srrh 				prdiff(diff);
540*8912Srrh 				return(0);
541*8912Srrh 			}
542*8912Srrh 			break;
543*8912Srrh 		default:
544*8912Srrh 			break;
545*8912Srrh 		}
546*8912Srrh 		if (v < firstdata) {
547*8912Srrh 			if ((procp = adrtoprocp((ADDR) v)) != badproc) {
548*8912Srrh 				prlnoff(procp, v);
549*8912Srrh 				return(0);
550*8912Srrh 			}
551*8912Srrh 		} else {
552*8912Srrh 			if ((diff = adrtoext((ADDR) v)) != -1) {
553*8912Srrh 				printf("%s", sl_name);
554*8912Srrh 				prdiff(diff);
555*8912Srrh 				return(0);
556*8912Srrh 			}
557*8912Srrh 		}
558*8912Srrh 	}
559*8912Srrh 	prhex(v);
560*8912Srrh 	return(1);
561*8912Srrh }
562*8912Srrh 
563*8912Srrh prdiff(diff)
564*8912Srrh {
565*8912Srrh 	if (diff) {
566*8912Srrh 		printf("+");
567*8912Srrh 		prhex(diff);
568*8912Srrh 	}
569*8912Srrh }
570*8912Srrh 
571*8912Srrh #endif SDB
572