changeset abdcb0389716 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=abdcb0389716
description:
        X86: Finally fix a division corner case.

        When doing an unsigned 64 bit division with a divisor that has its most
        significant bit set, the division code would spill a bit off of the end 
of a
        uint64_t trying to shift the dividend into position. This change adds 
code
        that handles that case specially by purposefully letting it spill and 
then
        going ahead assuming there was a 65th one bit.

diffstat:

 src/arch/x86/isa/microops/regop.isa |  37 +++++++++++++++++++++++++++++--------
 1 files changed, 29 insertions(+), 8 deletions(-)

diffs (48 lines):

diff -r edde97a6ea7c -r abdcb0389716 src/arch/x86/isa/microops/regop.isa
--- a/src/arch/x86/isa/microops/regop.isa       Sun Apr 18 21:33:59 2010 -0700
+++ b/src/arch/x86/isa/microops/regop.isa       Sun May 02 00:39:29 2010 -0700
@@ -612,15 +612,36 @@
             //If we overshot, do nothing. This lets us unrool division loops a
             //little.
             if (remaining) {
-                //Shift in bits from the low order portion of the dividend
-                while(dividend < divisor && remaining) {
-                    dividend = (dividend << 1) | bits(SrcReg1, remaining - 1);
-                    quotient <<= 1;
-                    remaining--;
+                if (divisor & (ULL(1) << 63)) {
+                    while (remaining && !(dividend & (ULL(1) << 63))) {
+                        dividend = (dividend << 1) |
+                            bits(SrcReg1, remaining - 1);
+                        quotient <<= 1;
+                        remaining--;
+                    }
+                    if (dividend & (ULL(1) << 63)) {
+                        if (dividend < divisor && remaining) {
+                            dividend = (dividend << 1) |
+                                bits(SrcReg1, remaining - 1);
+                            quotient <<= 1;
+                            remaining--;
+                        }
+                        quotient++;
+                        dividend -= divisor;
+                    }
+                    remainder = dividend;
+                } else {
+                    //Shift in bits from the low order portion of the dividend
+                    while (dividend < divisor && remaining) {
+                        dividend = (dividend << 1) |
+                            bits(SrcReg1, remaining - 1);
+                        quotient <<= 1;
+                        remaining--;
+                    }
+                    remainder = dividend;
+                    //Do the division.
+                    divide(dividend, divisor, quotient, remainder);
                 }
-                remainder = dividend;
-                //Do the division.
-                divide(dividend, divisor, quotient, remainder);
             }
             //Keep track of how many bits there are still to pull in.
             DestReg = merge(DestReg, remaining, dataSize);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to