xref: /netbsd-src/sys/arch/hppa/spmath/divsfm.c (revision d72340ff8e2fb5c3ca49ab85c798389cda4408d6)
1*d72340ffSskrll /*	$NetBSD: divsfm.c,v 1.5 2012/02/04 17:03:09 skrll Exp $	*/
2f4f0d8a3Sfredette 
3f4f0d8a3Sfredette /*	$OpenBSD: divsfm.c,v 1.4 2001/03/29 03:58:17 mickey Exp $	*/
4f4f0d8a3Sfredette 
5f4f0d8a3Sfredette /*
6f4f0d8a3Sfredette  * Copyright 1996 1995 by Open Software Foundation, Inc.
7f4f0d8a3Sfredette  *              All Rights Reserved
8f4f0d8a3Sfredette  *
9f4f0d8a3Sfredette  * Permission to use, copy, modify, and distribute this software and
10f4f0d8a3Sfredette  * its documentation for any purpose and without fee is hereby granted,
11f4f0d8a3Sfredette  * provided that the above copyright notice appears in all copies and
12f4f0d8a3Sfredette  * that both the copyright notice and this permission notice appear in
13f4f0d8a3Sfredette  * supporting documentation.
14f4f0d8a3Sfredette  *
15f4f0d8a3Sfredette  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16f4f0d8a3Sfredette  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17f4f0d8a3Sfredette  * FOR A PARTICULAR PURPOSE.
18f4f0d8a3Sfredette  *
19f4f0d8a3Sfredette  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20f4f0d8a3Sfredette  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21f4f0d8a3Sfredette  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22f4f0d8a3Sfredette  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23f4f0d8a3Sfredette  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24f4f0d8a3Sfredette  *
25f4f0d8a3Sfredette  */
26f4f0d8a3Sfredette /*
27f4f0d8a3Sfredette  * pmk1.1
28f4f0d8a3Sfredette  */
29f4f0d8a3Sfredette /*
30f4f0d8a3Sfredette  * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
31f4f0d8a3Sfredette  *
32f4f0d8a3Sfredette  * To anyone who acknowledges that this file is provided "AS IS"
33f4f0d8a3Sfredette  * without any express or implied warranty:
34f4f0d8a3Sfredette  *     permission to use, copy, modify, and distribute this file
35f4f0d8a3Sfredette  * for any purpose is hereby granted without fee, provided that
36f4f0d8a3Sfredette  * the above copyright notice and this notice appears in all
37f4f0d8a3Sfredette  * copies, and that the name of Hewlett-Packard Company not be
38f4f0d8a3Sfredette  * used in advertising or publicity pertaining to distribution
39f4f0d8a3Sfredette  * of the software without specific, written prior permission.
40f4f0d8a3Sfredette  * Hewlett-Packard Company makes no representations about the
41f4f0d8a3Sfredette  * suitability of this software for any purpose.
42f4f0d8a3Sfredette  */
43f4f0d8a3Sfredette 
440c82163cSlukem #include <sys/cdefs.h>
45*d72340ffSskrll __KERNEL_RCSID(0, "$NetBSD: divsfm.c,v 1.5 2012/02/04 17:03:09 skrll Exp $");
46f4f0d8a3Sfredette 
47f4f0d8a3Sfredette #include "md.h"
48f4f0d8a3Sfredette 
49f4f0d8a3Sfredette void
divsfm(int opnd1,int opnd2,struct mdsfu_register * result)50*d72340ffSskrll divsfm(int opnd1, int opnd2, struct mdsfu_register *result)
51f4f0d8a3Sfredette {
52f4f0d8a3Sfredette 	register int sign, op1_sign;
53f4f0d8a3Sfredette 
54f4f0d8a3Sfredette 	/* check divisor for zero */
55f4f0d8a3Sfredette 	if (opnd2 == 0) {
56f5d6b882Sthorpej 		overflow = true;
57f4f0d8a3Sfredette 		return;
58f4f0d8a3Sfredette 	}
59f4f0d8a3Sfredette 
60f4f0d8a3Sfredette 	/* get sign of result */
61f4f0d8a3Sfredette 	sign = opnd1 ^ opnd2;
62f4f0d8a3Sfredette 
63f4f0d8a3Sfredette 	/* get absolute value of operands */
64f4f0d8a3Sfredette 	if (opnd1 < 0) {
65f4f0d8a3Sfredette 		opnd1 = -opnd1;
66f5d6b882Sthorpej 		op1_sign = true;
67f4f0d8a3Sfredette 	}
68f5d6b882Sthorpej 	else op1_sign = false;
69f4f0d8a3Sfredette 	if (opnd2 < 0) opnd2 = -opnd2;
70f4f0d8a3Sfredette 
71f4f0d8a3Sfredette 	/*
72f4f0d8a3Sfredette 	 * check for overflow
73f4f0d8a3Sfredette 	 *
74f4f0d8a3Sfredette 	 * if abs(opnd1) < 0, then opnd1 = -2**31
75f4f0d8a3Sfredette 	 * and abs(opnd1) >= abs(opnd2) always
76f4f0d8a3Sfredette 	 */
77f4f0d8a3Sfredette 	if (opnd1 >= opnd2 || opnd1 < 0) {
78f4f0d8a3Sfredette 		/* check for opnd2 = -2**31 */
79f4f0d8a3Sfredette 		if (opnd2 < 0 && opnd1 != opnd2) {
80f4f0d8a3Sfredette 			result_hi = 0;		/* remainder = 0 */
81f4f0d8a3Sfredette 			result_lo = opnd1 << 1;
82f4f0d8a3Sfredette 		}
83f4f0d8a3Sfredette 		else {
84f5d6b882Sthorpej 			overflow = true;
85f4f0d8a3Sfredette 			return;
86f4f0d8a3Sfredette 		}
87f4f0d8a3Sfredette 	}
88f4f0d8a3Sfredette 	else {
89f4f0d8a3Sfredette 		/* do the divide */
90f4f0d8a3Sfredette 		divu(opnd1,0,opnd2,result);
91f4f0d8a3Sfredette 
92f4f0d8a3Sfredette 		/* return positive residue */
93f4f0d8a3Sfredette 		if (op1_sign && result_hi) {
94f4f0d8a3Sfredette 			result_hi = opnd2 - result_hi;
95f4f0d8a3Sfredette 			result_lo++;
96f4f0d8a3Sfredette 		}
97f4f0d8a3Sfredette 	}
98f4f0d8a3Sfredette 
99f4f0d8a3Sfredette 	/* check for overflow */
100f4f0d8a3Sfredette 	if (result_lo < 0) {
101f5d6b882Sthorpej 		overflow = true;
102f4f0d8a3Sfredette 		return;
103f4f0d8a3Sfredette 	}
104f5d6b882Sthorpej 	overflow = false;
105f4f0d8a3Sfredette 
106f4f0d8a3Sfredette 	/* return appropriately signed result */
107f4f0d8a3Sfredette 	if (sign<0) result_lo = -result_lo;
108f4f0d8a3Sfredette 	return;
109f4f0d8a3Sfredette }
110