xref: /openbsd-src/sys/arch/hppa/spmath/divsir.c (revision c2feb25228e11b3c285a2d9400475896f2dd1562)
1*c2feb252Smickey /*	$OpenBSD: divsir.c,v 1.6 2002/05/07 22:19:30 mickey Exp $	*/
28a472b3eSmickey /*
3*c2feb252Smickey   (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4*c2feb252Smickey   To anyone who acknowledges that this file is provided "AS IS"
5*c2feb252Smickey   without any express or implied warranty:
6*c2feb252Smickey       permission to use, copy, modify, and distribute this file
7*c2feb252Smickey   for any purpose is hereby granted without fee, provided that
8*c2feb252Smickey   the above copyright notice and this notice appears in all
9*c2feb252Smickey   copies, and that the name of Hewlett-Packard Company not be
10*c2feb252Smickey   used in advertising or publicity pertaining to distribution
11*c2feb252Smickey   of the software without specific, written prior permission.
12*c2feb252Smickey   Hewlett-Packard Company makes no representations about the
13*c2feb252Smickey   suitability of this software for any purpose.
148a472b3eSmickey */
15*c2feb252Smickey /* @(#)divsir.c: Revision: 1.6.88.1 Date: 93/12/07 15:05:58 */
168a472b3eSmickey 
174f9f21c7Smickey #include "md.h"
188a472b3eSmickey 
19b94afd46Smickey void
divsir(opnd1,opnd2,result)20b94afd46Smickey divsir(opnd1,opnd2,result)
218a472b3eSmickey 	int opnd1, opnd2;
228a472b3eSmickey 	struct mdsfu_register *result;
238a472b3eSmickey {
248a472b3eSmickey 	int sign, op1_sign;
258a472b3eSmickey 
268a472b3eSmickey 	/* check divisor for zero */
278a472b3eSmickey 	if (opnd2 == 0) {
288a472b3eSmickey 		overflow = TRUE;
298a472b3eSmickey 		return;
308a472b3eSmickey 	}
318a472b3eSmickey 
328a472b3eSmickey 	/* get sign of result */
338a472b3eSmickey 	sign = opnd1 ^ opnd2;
348a472b3eSmickey 
358a472b3eSmickey 	/* get absolute value of operands */
368a472b3eSmickey 	if (opnd1 < 0) {
378a472b3eSmickey 		opnd1 = -opnd1;
388a472b3eSmickey 		op1_sign = TRUE;
398a472b3eSmickey 	}
408a472b3eSmickey 	else op1_sign = FALSE;
418a472b3eSmickey 	if (opnd2 < 0) opnd2 = -opnd2;
428a472b3eSmickey 
438a472b3eSmickey 	/* check for opnd2 = -2**31 */
448a472b3eSmickey 	if (opnd2 + opnd2 == 0) {
458a472b3eSmickey 		if (opnd1 == opnd2) {
468a472b3eSmickey 			result_hi = 0;    /* remainder = 0 */
478a472b3eSmickey 			result_lo = 1;
488a472b3eSmickey 		}
498a472b3eSmickey 		else {
508a472b3eSmickey 			result_hi = opnd1;  /* remainder = opnd1 */
518a472b3eSmickey 			result_lo = 0;
528a472b3eSmickey 		}
538a472b3eSmickey 	}
548a472b3eSmickey 	else {
558a472b3eSmickey 		/* do the divide */
568a472b3eSmickey 		divu(0,opnd1,opnd2,result);
578a472b3eSmickey 
588a472b3eSmickey 		/*
598a472b3eSmickey 		 * check for overflow
608a472b3eSmickey 		 *
618a472b3eSmickey 		 * at this point, the only way we can get overflow
628a472b3eSmickey 		 * is with opnd1 = -2**31 and opnd2 = -1
638a472b3eSmickey 		 */
648a472b3eSmickey 		if (sign>0 && result_lo<0) {
658a472b3eSmickey 			overflow = TRUE;
668a472b3eSmickey 			return;
678a472b3eSmickey 		}
688a472b3eSmickey 	}
698a472b3eSmickey 	overflow = FALSE;
708a472b3eSmickey 
718a472b3eSmickey 	/* return appropriately signed remainder and result */
728a472b3eSmickey 	if (op1_sign) result_hi = -result_hi;
738a472b3eSmickey 	if (sign<0) result_lo = -result_lo;
748a472b3eSmickey 	return;
758a472b3eSmickey }
76