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