1 /* Math functions for i387. 2 Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, write to the Free 18 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20 */ 21 22 #include <win32k.h> 23 24 INT 25 APIENTRY 26 EngMulDiv( 27 _In_ INT iMultiplicand, 28 _In_ INT iMultiplier, 29 _In_ INT iDivisor) 30 { 31 INT64 i64Multiplied, i64Result; 32 33 /* Check for divide by zero */ 34 if (iDivisor == 0) 35 { 36 /* Quick sign check and return "infinite" */ 37 return ((iMultiplicand ^ iMultiplier) < 0) ? INT_MIN : INT_MAX; 38 } 39 40 /* We want to deal with a positive divisor to simplify the logic. */ 41 if (iDivisor < 0) 42 { 43 iMultiplicand = -iMultiplicand; 44 iDivisor = -iDivisor; 45 } 46 47 /* Do the multiplication */ 48 i64Multiplied = Int32x32To64(iMultiplicand, iMultiplier); 49 50 /* If the result is positive, we add to round, else we subtract to round. */ 51 if (i64Multiplied >= 0) 52 { 53 i64Multiplied += (iDivisor / 2); 54 } 55 else 56 { 57 i64Multiplied -= (iDivisor / 2); 58 } 59 60 /* Now do the divide */ 61 i64Result = i64Multiplied / iDivisor; 62 63 /* Check for positive overflow */ 64 if (i64Result > INT_MAX) 65 { 66 return INT_MAX; 67 } 68 69 /* Check for negative overflow. */ 70 if (i64Result < INT_MIN) 71 { 72 return INT_MIN; 73 } 74 75 return (INT)i64Result; 76 } 77 78