[net.unix-wizards] pcc and uldiv for V7 PDP11

david@sri-unix (11/15/82)

We run a PDP11/70 with 2.8BSD. When compiling some programs with pcc
(as distributed in V7), I occasionally get uldiv and ulrem (unsigned
long division and remainder?) undefined.  The references are generated
by pcc and those routines are not in the v7 clib, though they are in
System III clib.  Has anyone else run up against this?  What sort
of statements in your source program cause pcc to generate references
to these routines?  Does anyone have versions of uldiv.s and ulrem.s
for v7 (we have source license)?  My alternative is to change the
System III version to run under V7 - it looks to me like the calling
sequence may be different - the System III versions have calls to
different csav and cret routines.

Any information would be appreciated - thanks in advance.

		David Brown
		Varian Instruments
		2700 Mitchell DR
		Walnut Creek Ca 94598
		(415) 939-2400 x288
	...decvax!sytek!zehntel!varian!david

gwyn@Brl@sri-unix (11/22/82)

From:     Doug Gwyn <gwyn@Brl>
Date:     19 Nov 82 14:04:57-EST (Fri)
uldiv & ulrem implement run-time support for unsigned long division & mod.
All of the run-time arithmetic modules were bug-fixed for System III,
and a few were added (uldiv,ulrem,udiv,urem).

The stack frame is the same on PDP-11 System III as on V7, as is cret.
However,
	jsr	r0,csav
is generated instead of the V7
	jsr	r5,csv
in order to solve a problem with interrupting csv (the new one is also
slightly faster).  Support for both is in the System III library, and
both old-compiled and new-compiled object modules can be mixed in one
executable image.

jfw.mit-ccc@Mit-Mc@sri-unix (11/22/82)

Date: 19 Nov 1982 16:12:41-EST
uldiv and ulrem are generated by the PCC when it compiles something involving
unsigned longs.  They are analogous to ldiv and lrem.  If you have floating
point, I long ago wrote the routines to do what uldiv and ulrem are to do.

/**** uldiv.c, by John Woods, October 9, 1982 ****/

unsigned long uldiv(a,b) unsigned long a,b; {
	return((unsigned long)((double)a / (double)b));
}
unsigned long auldiv(a,b) unsigned long *a,b; {
	return(*a = ((unsigned long)((double)*a / (double)b)));
}
unsigned long ulmul(a,b) unsigned long a,b; {
	return((unsigned long)((double)a * (double)b));
}
unsigned long aulmul(a,b) unsigned long *a,b; {
	return(*a = ((unsigned long)((double)*a * (double)b)));
}
/****************/

The following is a massaged assembly language version which avoids some of the
overhead of C procedure discipline:  (It was compiled -S by PCC and -O'd by me).

/**** uldiv.s, by John Woods, October 9, 1982 ****/
 .text
 .globl	uldiv
uldiv:
/	line 2, file "uldiv.c"
	setl
	movif	2.(sp),fr0
	cfcc
	bpl	1f
	addf	$050200,fr0
1:
	movif	6.(sp),fr1
	cfcc
	bpl	1f
	addf	$050200,fr1
1:
	divf	fr1,fr0
	movfi	fr0,-(sp)
	seti
	mov	(sp)+,r0
	mov	(sp)+,r1
	rts	pc
 .globl	fltused
 .globl	auldiv
auldiv:
/	line 5, file "uldiv.c"
	mov	2.(sp),r1
	mov	(r1)+,r0
	mov	(r1),r1
	mov	r1,-(sp)
	mov	r0,-(sp)
	setl
	movif	(sp)+,fr0
	cfcc
	bpl	1f
	addf	$050200,fr0
1:
	movif	4.(sp),fr1
	cfcc
	bpl	1f
	addf	$050200,fr1
1:
	divf	fr1,fr0
	movfi	fr0,-(sp)
	seti
	mov	(sp)+,r0
	mov	(sp)+,r1
	mov	2.(sp),r2
	mov	r0,(r2)+
	mov	r1,(r2)
	rts	pc
 .globl	fltused
 .globl	ulmul
ulmul:
/	line 8, file "uldiv.c"
	setl
	movif	2.(sp),fr0
	seti
	cfcc
	bpl	1f
	addf	$050200,fr0
1:
	setl
	movif	6.(sp),fr1
	cfcc
	bpl	1f
	addf	$050200,fr1
1:
	mulf	fr1,fr0
	movfi	fr0,-(sp)
	seti
	mov	(sp)+,r0
	mov	(sp)+,r1
	rts	pc
 .globl	fltused
 .globl	aulmul
aulmul:
/	line 11, file "uldiv.c"
	mov	2.(sp),r1
	mov	(r1)+,r0
	mov	(r1),r1
	mov	r1,-(sp)
	mov	r0,-(sp)
	setl
	movif	(sp)+,fr0
	cfcc
	bpl	1f
	addf	$050200,fr0
1:
	setl
	movif	4.(sp),fr1
	cfcc
	bpl	1f
	addf	$050200,fr1
1:
	mulf	fr1,fr0
	movfi	fr0,-(sp)
	seti
	mov	(sp)+,r0
	mov	(sp)+,r1
	mov	2.(sp),r2
	mov	r0,(r2)+
	mov	r1,(r2)
	rts	pc
 .globl	fltused
 .data