ReactOS  0.4.15-dev-2956-g61e7ea5
__rt_div.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: BSD - See COPYING.ARM in the top level directory
3  * PROJECT: ReactOS CRT library
4  * FILE: lib/sdk/crt/math/arm/__rt_div.c
5  * PURPOSE: Implementation of __rt_udiv
6  * PROGRAMMER: Timo Kreuzer
7  * REFERENCE: http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md/arm/_div10.s.htm
8  * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md/arm/_udiv.c.htm
9  */
10 
11 typedef struct _ARM_UDIVRESULT
12 {
13  unsigned int quotient; /* to be returned in R0 */
14  unsigned int modulus; /* to be returned in R1 */
16 
17 __forceinline
18 void
19 __brkdiv0(void)
20 {
21  __emit(0xDEF9);
22 }
23 
24 __forceinline
25 void
28  unsigned int divisor,
29  unsigned int dividend)
30 {
31  unsigned int shift;
32  unsigned int mask;
33  unsigned int quotient;
34 
35  if (divisor == 0)
36  {
37  /* Raise divide by zero error */
38  __brkdiv0();
39  }
40 
41  if (divisor > dividend)
42  {
43  result->quotient = 0;
44  result->modulus = divisor;
45  return;
46  }
47 
48  /* Get the difference in count of leading zeros between dividend and divisor */
50  shift -= _CountLeadingZeros(dividend);
51 
52  /* Shift the divisor to the left, so that it's highest bit is the same
53  as the highest bit of the dividend */
54  divisor <<= shift;
55 
56  mask = 1 << shift;
57 
58  quotient = 0;
59  do
60  {
61  if (dividend >= divisor)
62  {
63  quotient |= mask;
64  dividend -= divisor;
65  }
66  divisor >>= 1;
67  mask >>= 1;
68  }
69  while (mask);
70 
71  result->quotient = quotient;
72  result->modulus = dividend;
73  return;
74 }
75 
78  unsigned int divisor,
79  unsigned int dividend)
80 {
82 
83  __rt_udiv_internal(&result, divisor, dividend);
84  return result;
85 }
86 
87 typedef struct _ARM_SDIVRESULT
88 {
89  int quotient; /* to be returned in R0 */
90  int modulus; /* to be returned in R1 */
92 
95  int divisor,
96  int dividend)
97 {
99  int divisor_sign, dividend_sign;
100 
101  dividend_sign = divisor & 0x80000000;
102  if (dividend_sign)
103  {
104  dividend = -dividend;
105  }
106 
107  divisor_sign = divisor & 0x80000000;
108  if (divisor_sign)
109  {
110  divisor = -divisor;
111  }
112 
114 
115  if (dividend_sign ^ divisor_sign)
116  {
117  result.quotient = -result.quotient;
118  }
119 
120  if (dividend_sign)
121  {
122  result.modulus = -result.modulus;
123  }
124 
125  return result;
126 }
#define shift
Definition: input.c:1756
ARM_SDIVRESULT __rt_sdiv(int divisor, int dividend)
Definition: __rt_div.c:94
GLuint64EXT * result
Definition: glext.h:11304
struct _ARM_UDIVRESULT ARM_UDIVRESULT
__INTRIN_INLINE unsigned _CountLeadingZeros(long Mask)
Definition: intrin_arm.h:47
unsigned int quotient
Definition: __rt_div.c:13
GLenum GLint GLuint mask
Definition: glext.h:6028
__forceinline void __rt_udiv_internal(ARM_UDIVRESULT *result, unsigned int divisor, unsigned int dividend)
Definition: __rt_div.c:26
unsigned int modulus
Definition: __rt_div.c:14
__forceinline void __brkdiv0(void)
Definition: __rt_div.c:19
ARM_UDIVRESULT __rt_udiv(unsigned int divisor, unsigned int dividend)
Definition: __rt_div.c:77
GLuint divisor
Definition: glext.h:6313
struct _ARM_SDIVRESULT ARM_SDIVRESULT