xref: /csrg-svn/lib/libc/vax/gen/urem.s (revision 13421)
1*13421Sroot/*	urem.s	4.1	83/06/27	*/
2*13421Sroot
3*13421Sroot/*
4*13421Sroot * urem - unsigned remainder for vax-11
5*13421Sroot *
6*13421Sroot * arguments: dividend, divisor
7*13421Sroot * result: remainder
8*13421Sroot * uses r0-r2
9*13421Sroot *
10*13421Sroot * if 1 < divisor <= 2147483647, zero-extend the dividend
11*13421Sroot * to 64 bits and let ediv do the work.  If the divisor is 1,
12*13421Sroot * ediv will overflow if bit 31 of the dividend is on, so
13*13421Sroot * just return 0.  If the divisor is 0, do the ediv also,
14*13421Sroot * so it will generate the proper exception.  All other values
15*13421Sroot * of the divisor have bit 31 on: in this case the remainder
16*13421Sroot * must be the dividend if divisor > dividend, and the dividend
17*13421Sroot * minus the divisor otherwise.  The comparison must be unsigned.
18*13421Sroot */
19*13421Sroot#include "DEFS.h"
20*13421Sroot
21*13421SrootENTRY(urem)
22*13421Sroot	movl	4(ap),r0	/* dividend */
23*13421Sroot	movl	8(ap),r2	/* divisor */
24*13421Sroot	jeql	1f		/* if divisor=0, force exception */
25*13421Sroot	cmpl	r2,$1		/* if divisor <= 1 (signed), */
26*13421Sroot	jleq	2f		/*  no division is necessary */
27*13421Sroot1:
28*13421Sroot	clrl	r1		/* zero-extend the dividend */
29*13421Sroot	ediv	r2,r0,r2,r0	/* divide.  q->r2 (discarded), r->r0 */
30*13421Sroot	ret
31*13421Sroot2:
32*13421Sroot	jneq	1f		/* if divisor=1, return 0 */
33*13421Sroot	clrl	r0		/*  (because doing the divide will overflow */
34*13421Sroot	ret			/*  if the dividend has its high bit on) */
35*13421Sroot1:
36*13421Sroot	cmpl	r0,r2		/* if dividend < divisor (unsigned) */
37*13421Sroot	jlssu	1f		/*  remainder is dividend */
38*13421Sroot	subl2	r2,r0		/*  else remainder is dividend - divisor */
39*13421Sroot1:
40*13421Sroot	ret
41