Author: tkreuzer Date: Tue Apr 14 18:42:28 2015 New Revision: 67195
URL: http://svn.reactos.org/svn/reactos?rev=67195&view=rev Log: [CRT] Refactor the code for __rt_div to allow reusing it for __rt_sdiv64 and __rt_udiv64 and implement those as asm wrappers around worker functions (due to the calling convention they cannot be implemented fully in C)
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_div_worker.h (with props) trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv.c (with props) trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64_worker.c (with props) trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv.c (with props) trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64_worker.c (with props) Modified: trunk/reactos/lib/sdk/crt/crt.cmake trunk/reactos/lib/sdk/crt/libcntpr.cmake trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64.s trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64.s
Modified: trunk/reactos/lib/sdk/crt/crt.cmake URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/crt.cmake?rev=6... ============================================================================== --- trunk/reactos/lib/sdk/crt/crt.cmake [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/crt.cmake [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -476,7 +476,10 @@ endif() elseif(ARCH STREQUAL "arm") list(APPEND LIBCNTPR_SOURCE - math/arm/__rt_div.c + math/arm/__rt_sdiv.c + math/arm/__rt_sdiv64_worker.c + math/arm/__rt_udiv.c + math/arm/__rt_udiv64_worker.c ) list(APPEND CRT_ASM_SOURCE math/arm/floor.s
Modified: trunk/reactos/lib/sdk/crt/libcntpr.cmake URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/libcntpr.cmake?... ============================================================================== --- trunk/reactos/lib/sdk/crt/libcntpr.cmake [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/libcntpr.cmake [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -135,7 +135,10 @@ math/sin.c) elseif(ARCH STREQUAL "arm") list(APPEND LIBCNTPR_SOURCE - math/arm/__rt_div.c + math/arm/__rt_sdiv.c + math/arm/__rt_sdiv64_worker.c + math/arm/__rt_udiv.c + math/arm/__rt_udiv64_worker.c ) list(APPEND LIBCNTPR_ASM_SOURCE math/arm/floor.s
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_div_worker.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_d... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_div_worker.h (added) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_div_worker.h [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -0,0 +1,116 @@ +/* + * COPYRIGHT: BSD, see COPYING.ARM in the top level directory + * PROJECT: ReactOS crt library + * FILE: lib/sdk/crt/math/arm/__rt_udiv.c + * PURPOSE: Implementation of __rt_udiv + * PROGRAMMER: Timo Kreuzer + * REFERENCE: http://research.microsoft.com/pubs/70645/tr-2008-141.pdf + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + */ + +#ifdef _USE_64_BITS_ +typedef unsigned long long UINT3264; +typedef long long INT3264; +#define _CountLeadingZeros _CountLeadingZeros64 +#else +typedef unsigned int UINT3264; +typedef int INT3264; +#endif + +__forceinline +void +__brkdiv0(void) +{ + __emit(0xDEF9); +} + +typedef struct _ARM_DIVRESULT +{ + UINT3264 quotient; /* to be returned in R0 */ + UINT3264 modulus; /* to be returned in R1 */ +} ARM_DIVRESULT; + +#ifndef _USE_64_BITS_ +__forceinline +#endif +void +__rt_div_worker( + ARM_DIVRESULT *result, + UINT3264 divisor, + UINT3264 dividend) +{ + UINT3264 shift; + UINT3264 mask; + UINT3264 quotient; +#ifdef _SIGNED_DIV_ + int dividend_sign; + int divisor_sign; +#endif // _SIGNED_DIV_ + + if (divisor == 0) + { + /* Raise divide by zero error */ + __brkdiv0(); + } + +#ifdef _SIGNED_DIV_ + if ((INT3264)dividend < 0) + { + dividend_sign = 1; + dividend = -(INT3264)dividend; + } + + if ((INT3264)divisor < 0) + { + divisor_sign = 1; + divisor = -(INT3264)divisor; + } +#endif // _SIGNED_DIV_ + + if (divisor > dividend) + { + result->quotient = 0; + result->modulus = divisor; + return; + } + + /* Get the difference in count of leading zeros between dividend and divisor */ + shift = _CountLeadingZeros(divisor); + shift -= _CountLeadingZeros(dividend); + + /* Shift the divisor to the left, so that it's highest bit is the same + as the highest bit of the dividend */ + divisor <<= shift; + + mask = (UINT3264)1 << shift; + + quotient = 0; + do + { + if (dividend >= divisor) + { + quotient |= mask; + dividend -= divisor; + } + divisor >>= 1; + mask >>= 1; + } + while (mask); + +#ifdef _SIGNED_DIV_ + if (dividend_sign ^ divisor_sign) + { + quotient = -(INT3264)quotient; + } + + if (dividend_sign) + { + dividend = -(INT3264)dividend; + } +#endif // _SIGNED_DIV_ + + result->quotient = quotient; + result->modulus = dividend; + return; +}
Propchange: trunk/reactos/lib/sdk/crt/math/arm/__rt_div_worker.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_s... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv.c (added) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv.c [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -0,0 +1,26 @@ +/* + * COPYRIGHT: BSD, see COPYING.ARM in the top level directory + * PROJECT: ReactOS crt library + * FILE: lib/sdk/crt/math/arm/__rt_sdiv.c + * PURPOSE: Implementation of __rt_sdiv + * PROGRAMMER: Timo Kreuzer + * REFERENCE: http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + */ + +#define __rt_div_worker __rt_sdiv_worker +#define _SIGNED_DIV_ + +#include "__rt_div_worker.h" + +ARM_DIVRESULT +__rt_sdiv( + int divisor, + int dividend) +{ + ARM_DIVRESULT result; + + __rt_sdiv_worker(&result, divisor, dividend); + return result; +} +
Propchange: trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_s... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64.s [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64.s [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -9,12 +9,28 @@
#include <kxarm.h>
+ IMPORT __rt_sdiv64_worker + /* CODE **********************************************************************/ TEXTAREA
- LEAF_ENTRY __rt_sdiv64 + NESTED_ENTRY __rt_sdiv64
- LEAF_END __rt_sdiv64 + /* Allocate stack space and store parameters there */ + stmdb sp!,{r0,r1,r2,r3,lr} + PROLOG_END + + /* Load pointer to stack structure into R0 */ + mov r0, sp + + /* Call the C worker function */ + adr lr, Return + b __rt_sdiv64_worker + +Return + /* Move result data into the appropriate registers and return */ + ldmia sp!,{r0,r1,r2,r3,pc} + ENTRY_END __rt_sdiv64
END /* EOF */
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64_worker.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_s... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64_worker.c (added) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64_worker.c [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -0,0 +1,17 @@ +/* + * COPYRIGHT: BSD, see COPYING.ARM in the top level directory + * PROJECT: ReactOS crt library + * FILE: lib/sdk/crt/math/arm/__rt_sdiv_worker.c + * PURPOSE: Implementation of __rt_sdiv_worker + * PROGRAMMER: Timo Kreuzer + * REFERENCE: http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + */ + +#define __rt_div_worker __rt_sdiv64_worker +#define _SIGNED_DIV_ +#define _USE_64_BITS_ + +#include "__rt_div_worker.h" + +/* __rt_sdiv64 is implemented in __rt_sdiv64.s */
Propchange: trunk/reactos/lib/sdk/crt/math/arm/__rt_sdiv64_worker.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_u... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv.c (added) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv.c [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -0,0 +1,25 @@ +/* + * COPYRIGHT: BSD, see COPYING.ARM in the top level directory + * PROJECT: ReactOS crt library + * FILE: lib/sdk/crt/math/arm/__rt_udiv.c + * PURPOSE: Implementation of __rt_udiv + * PROGRAMMER: Timo Kreuzer + * REFERENCE: http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + */ + +#define __rt_div_worker __rt_udiv_worker + +#include "__rt_div_worker.h" + +ARM_DIVRESULT +__rt_udiv( + unsigned int divisor, + unsigned int dividend) +{ + ARM_DIVRESULT result; + + __rt_udiv_worker(&result, divisor, dividend); + return result; +} +
Propchange: trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_u... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64.s [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64.s [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -9,12 +9,28 @@
#include <kxarm.h>
+ IMPORT __rt_udiv64_worker + /* CODE **********************************************************************/ TEXTAREA
- LEAF_ENTRY __rt_udiv64 + NESTED_ENTRY __rt_udiv64
- LEAF_END __rt_udiv64 + /* Allocate stack space and store parameters there */ + stmdb sp!,{r0,r1,r2,r3,lr} + PROLOG_END + + /* Load pointer to stack structure into R0 */ + mov r0, sp + + /* Call the C worker function */ + adr lr, Return + b __rt_udiv64_worker + +Return + /* Move result data into the appropriate registers and return */ + ldmia sp!,{r0,r1,r2,r3,pc} + ENTRY_END __rt_udiv64
END /* EOF */
Added: trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64_worker.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/arm/__rt_u... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64_worker.c (added) +++ trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64_worker.c [iso-8859-1] Tue Apr 14 18:42:28 2015 @@ -0,0 +1,16 @@ +/* + * COPYRIGHT: BSD, see COPYING.ARM in the top level directory + * PROJECT: ReactOS crt library + * FILE: lib/sdk/crt/math/arm/__rt_udiv64_worker.c + * PURPOSE: Implementation of __rt_udiv64_worker + * PROGRAMMER: Timo Kreuzer + * REFERENCE: http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + * http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md... + */ + +#define __rt_div_worker __rt_udiv64_worker +#define _USE_64_BITS_ + +#include "__rt_div_worker.h" + +/* __rt_udiv64 is implemented in __rt_udiv64.s */
Propchange: trunk/reactos/lib/sdk/crt/math/arm/__rt_udiv64_worker.c ------------------------------------------------------------------------------ svn:eol-style = native