Actually provide __aulldiv code.
authorBrandon Turner <turnerb7@msu.edu>
Tue, 6 Dec 2005 16:41:53 +0000 (16:41 +0000)
committerBrandon Turner <turnerb7@msu.edu>
Tue, 6 Dec 2005 16:41:53 +0000 (16:41 +0000)
svn path=/trunk/; revision=19931

reactos/lib/rtl/i386/aulldiv_asm.s [new file with mode: 0644]
reactos/lib/rtl/rtl.xml

diff --git a/reactos/lib/rtl/i386/aulldiv_asm.s b/reactos/lib/rtl/i386/aulldiv_asm.s
new file mode 100644 (file)
index 0000000..537ffd6
--- /dev/null
@@ -0,0 +1,180 @@
+/*\r
+ * COPYRIGHT:         See COPYING in the top level directory\r
+ * PROJECT:           ReactOS kernel\r
+ * PURPOSE:           Run-Time Library\r
+ * FILE:              lib/rtl/i386/aulldiv_asm.S\r
+ * PROGRAMER:         Alex Ionescu (alex@relsoft.net)\r
+ *                    Eric Kohl (ekohl@rz-online.de)\r
+ *\r
+ * Copyright (C) 2002 Michael Ringgaard.\r
+ * All rights reserved. \r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * \r
+ * 1. Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer.  \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.  \r
+ * 3. Neither the name of the project nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission. \r
+\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES// LOSS OF USE, DATA, OR PROFITS// OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+ * SUCH DAMAGE.\r
+ */\r
\r
+ .globl __aulldiv\r
+\r
+.intel_syntax noprefix\r
+\r
+/* FUNCTIONS ***************************************************************/\r
+\r
+//\r
+// ulldiv - unsigned long divide\r
+//\r
+// Purpose:\r
+//       Does a unsigned long divide of the arguments.  Arguments are\r
+//       not changed.\r
+//\r
+// Entry:\r
+//       Arguments are passed on the stack:\r
+//               1st pushed: divisor (QWORD)\r
+//               2nd pushed: dividend (QWORD)\r
+//\r
+// Exit:\r
+//       EDX:EAX contains the quotient (dividend/divisor)\r
+//       NOTE: this routine removes the parameters from the stack.\r
+//\r
+// Uses:\r
+//       ECX\r
+//\r
+\r
+__aulldiv:\r
+\r
+        push    ebx\r
+        push    esi\r
+\r
+// Set up the local stack and save the index registers.  When this is done\r
+// the stack frame will look as follows (assuming that the expression a/b will\r
+// generate a call to uldiv(a, b)):\r
+//\r
+//               -----------------\r
+//               |               |\r
+//               |---------------|\r
+//               |               |\r
+//               |--divisor (b)--|\r
+//               |               |\r
+//               |---------------|\r
+//               |               |\r
+//               |--dividend (a)-|\r
+//               |               |\r
+//               |---------------|\r
+//               | return addr** |\r
+//               |---------------|\r
+//               |      EBX      |\r
+//               |---------------|\r
+//       ESP---->|      ESI      |\r
+//               -----------------\r
+//\r
+\r
+#undef DVNDLO\r
+#undef DVNDHI\r
+#undef DVSRLO\r
+#undef DVSRHI\r
+#define DVNDLO  [esp + 12]       // stack address of dividend (a)\r
+#define DVNDHI  [esp + 16]       // stack address of dividend (a)\r
+#define DVSRLO  [esp + 20]      // stack address of divisor (b)\r
+#define DVSRHI  [esp + 24]      // stack address of divisor (b)\r
+\r
+//\r
+// Now do the divide.  First look to see if the divisor is less than 4194304K.\r
+// If so, then we can use a simple algorithm with word divides, otherwise\r
+// things get a little more complex.\r
+//\r
+\r
+        mov     eax,DVSRHI // check to see if divisor < 4194304K\r
+        or      eax,eax\r
+        jnz     short ..L1        // nope, gotta do this the hard way\r
+        mov     ecx,DVSRLO // load divisor\r
+        mov     eax,DVNDHI // load high word of dividend\r
+        xor     edx,edx\r
+        div     ecx             // get high order bits of quotient\r
+        mov     ebx,eax         // save high bits of quotient\r
+        mov     eax,DVNDLO // edx:eax <- remainder:lo word of dividend\r
+        div     ecx             // get low order bits of quotient\r
+        mov     edx,ebx         // edx:eax <- quotient hi:quotient lo\r
+        jmp     short ..L2        // restore stack and return\r
+\r
+//\r
+// Here we do it the hard way.  Remember, eax contains DVSRHI\r
+//\r
+\r
+..L1:\r
+        mov     ecx,eax         // ecx:ebx <- divisor\r
+        mov     ebx,DVSRLO\r
+        mov     edx,DVNDHI // edx:eax <- dividend\r
+        mov     eax,DVNDLO\r
+..L3:\r
+        shr     ecx,1           // shift divisor right one bit// hi bit <- 0\r
+        rcr     ebx,1\r
+        shr     edx,1           // shift dividend right one bit// hi bit <- 0\r
+        rcr     eax,1\r
+        or      ecx,ecx\r
+        jnz     short ..L3        // loop until divisor < 4194304K\r
+        div     ebx             // now divide, ignore remainder\r
+        mov     esi,eax         // save quotient\r
+\r
+//\r
+// We may be off by one, so to check, we will multiply the quotient\r
+// by the divisor and check the result against the orignal dividend\r
+// Note that we must also check for overflow, which can occur if the\r
+// dividend is close to 2**64 and the quotient is off by 1.\r
+//\r
+\r
+        mul     dword ptr DVSRHI // QUOT * DVSRHI\r
+        mov     ecx,eax\r
+        mov     eax,DVSRLO\r
+        mul     esi             // QUOT * DVSRLO\r
+        add     edx,ecx         // EDX:EAX = QUOT * DVSR\r
+        jc      short ..L4        // carry means Quotient is off by 1\r
+\r
+//\r
+// do long compare here between original dividend and the result of the\r
+// multiply in edx:eax.  If original is larger or equal, we are ok, otherwise\r
+// subtract one (1) from the quotient.\r
+//\r
+\r
+        cmp     edx,DVNDHI // compare hi words of result and original\r
+        ja      short ..L4        // if result > original, do subtract\r
+        jb      short ..L5        // if result < original, we are ok\r
+        cmp     eax,DVNDLO // hi words are equal, compare lo words\r
+        jbe     short ..L5        // if less or equal we are ok, else subtract\r
+..L4:\r
+        dec     esi             // subtract 1 from quotient\r
+..L5:\r
+        xor     edx,edx         // edx:eax <- quotient\r
+        mov     eax,esi\r
+\r
+//\r
+// Just the cleanup left to do.  edx:eax contains the quotient.\r
+// Restore the saved registers and return.\r
+//\r
+\r
+..L2:\r
+\r
+        pop     esi\r
+        pop     ebx\r
+\r
+        ret     16\r
index 29f2e74..2ca2cf5 100644 (file)
@@ -15,6 +15,7 @@
                        <file>allshl_asm.s</file>
                        <file>allshr_asm.s</file>
                        <file>atan_asm.s</file>
+                       <file>aulldiv_asm.s</file>
                        <file>aulldvrm_asm.s</file>
                        <file>aullrem_asm.s</file>
                        <file>aullshr_asm.s</file>