1*d72340ffSskrll /* $NetBSD: divsim.c,v 1.5 2012/02/04 17:03:09 skrll Exp $ */
2f4f0d8a3Sfredette
3f4f0d8a3Sfredette /* $OpenBSD: divsim.c,v 1.4 2001/03/29 03:58:18 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: divsim.c,v 1.5 2012/02/04 17:03:09 skrll Exp $");
46f4f0d8a3Sfredette
47f4f0d8a3Sfredette #include "md.h"
48f4f0d8a3Sfredette
49f4f0d8a3Sfredette void
divsim(int opnd1,int opnd2,struct mdsfu_register * result)50*d72340ffSskrll divsim(int opnd1, int opnd2, struct mdsfu_register *result)
51f4f0d8a3Sfredette {
52f4f0d8a3Sfredette 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 /* check for opnd2 == -2**31 */
72f4f0d8a3Sfredette if (opnd2 < 0) {
73f4f0d8a3Sfredette if (opnd1 == opnd2) {
74f4f0d8a3Sfredette result_hi = 0; /* remainder = 0 */
75f4f0d8a3Sfredette result_lo = 1;
76f4f0d8a3Sfredette }
77f4f0d8a3Sfredette else {
78f4f0d8a3Sfredette result_hi = opnd1; /* remainder = opnd1 */
79f4f0d8a3Sfredette result_lo = 0;
80f4f0d8a3Sfredette }
81f4f0d8a3Sfredette }
82f4f0d8a3Sfredette else {
83f4f0d8a3Sfredette /* do the divide */
84f4f0d8a3Sfredette divu(0,opnd1,opnd2,result);
85f4f0d8a3Sfredette
86f4f0d8a3Sfredette /*
87f4f0d8a3Sfredette * check for overflow
88f4f0d8a3Sfredette *
89f4f0d8a3Sfredette * at this point, the only way we can get overflow
90f4f0d8a3Sfredette * is with opnd1 = -2**31 and opnd2 = -1
91f4f0d8a3Sfredette */
92f4f0d8a3Sfredette if (sign>0 && result_lo<0) {
93f5d6b882Sthorpej overflow = true;
94f4f0d8a3Sfredette return;
95f4f0d8a3Sfredette }
96f4f0d8a3Sfredette }
97f5d6b882Sthorpej overflow = false;
98f4f0d8a3Sfredette
99f4f0d8a3Sfredette /* return positive residue */
100f4f0d8a3Sfredette if (op1_sign && result_hi) {
101f4f0d8a3Sfredette result_hi = opnd2 - result_hi;
102f4f0d8a3Sfredette if (++result_lo < 0) {
103f5d6b882Sthorpej overflow = true;
104f4f0d8a3Sfredette return;
105f4f0d8a3Sfredette }
106f4f0d8a3Sfredette }
107f4f0d8a3Sfredette
108f4f0d8a3Sfredette /* return appropriately signed result */
109f4f0d8a3Sfredette if (sign<0) result_lo = -result_lo;
110f4f0d8a3Sfredette return;
111f4f0d8a3Sfredette }
112