* COPYRIGHT: See COPYING in the top level directory\r
* PROJECT: ReactOS kernel\r
* PURPOSE: Run-Time Library\r
- * FILE: lib/rtl/i386/aulldiv.S\r
+ * FILE: lib/rtl/i386/allshr.S\r
* PROGRAMER: Alex Ionescu (alex@relsoft.net)\r
* Eric Kohl (ekohl@rz-online.de)\r
*\r
* SUCH DAMAGE.\r
*/\r
\r
-.globl __aulldiv\r
+.globl __allshr\r
\r
- /* DATA ********************************************************************/\r
-\r
-fzero:\r
- .long 0 // Floating point zero\r
- .long 0 // Floating point zero\r
-\r
-__fltused:\r
- .long 0x9875\r
-\r
.intel_syntax noprefix\r
\r
/* FUNCTIONS ***************************************************************/\r
\r
//\r
-// ulldiv - unsigned long divide\r
+// llshr - long shift right\r
//\r
// Purpose:\r
-// Does a unsigned long divide of the arguments. Arguments are\r
-// not changed.\r
+// Does a signed Long Shift Right\r
+// Shifts a long right any number of bits.\r
//\r
// Entry:\r
-// Arguments are passed on the stack:\r
-// 1st pushed: divisor (QWORD)\r
-// 2nd pushed: dividend (QWORD)\r
+// EDX:EAX - long value to be shifted\r
+// CL - number of bits to shift by\r
//\r
// Exit:\r
-// EDX:EAX contains the quotient (dividend/divisor)\r
-// NOTE: this routine removes the parameters from the stack.\r
+// EDX:EAX - shifted value\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
+// CL is destroyed.\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
+__allshr:\r
\r
//\r
-// Here we do it the hard way. Remember, eax contains DVSRHI\r
+// Handle shifts of 64 bits or more (if shifting 64 bits or more, the result\r
+// depends only on the high order bit of edx).\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
+ cmp cl,64\r
+ jae short .RETSIGN\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
+// Handle shifts of between 0 and 31 bits\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
+ cmp cl, 32\r
+ jae short .MORE32\r
+ shrd eax,edx,cl\r
+ sar edx,cl\r
+ ret\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
+// Handle shifts of between 32 and 63 bits\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
+.MORE32:\r
+ mov eax,edx\r
+ sar edx,31\r
+ and cl,31\r
+ sar eax,cl\r
+ ret\r
\r
//\r
-// Just the cleanup left to do. edx:eax contains the quotient.\r
-// Restore the saved registers and return.\r
+// Return double precision 0 or -1, depending on the sign of edx\r
//\r
-\r
-..L2:\r
-\r
- pop esi\r
- pop ebx\r
-\r
- ret 16\r
+.RETSIGN:\r
+ sar edx,31\r
+ mov eax,edx\r
+ ret\r