Author: rgrjr
Date: Sat May 12 08:37:58 2007
New Revision: 18517

Modified:
   trunk/src/pmc/scalar.pmc
   trunk/t/pmc/bigint.t

Log:
* src/pmc/scalar.pmc:
   + (Parrot_BigInt_bitwise_shl_int):  Bug fix: Force overflow for
     "extreme" left shifts, and always underflow to zero for extreme
     right shifts.
* t/pmc/bigint.t:
   + Add a regression test to make sure a 64-bit shl really shifts.
     Tested on i686 and x86_64.


Modified: trunk/src/pmc/scalar.pmc
==============================================================================
--- trunk/src/pmc/scalar.pmc    (original)
+++ trunk/src/pmc/scalar.pmc    Sat May 12 08:37:58 2007
@@ -38,15 +38,23 @@
     int overflow_p = 0;
 
     /* Compute the shift. */
-    if (shift_amount >= 0) {
+    if (shift_amount >= 8*INTVAL_SIZE) {
+        /* Extreme left shift; no need to do an integer shift first. */
+        overflow_p = 1;
+    }
+    else if (shift_amount >= 0) {
         /* Left shift. */
         result = base << shift_amount;
         overflow_p = (result >> shift_amount) != base;
     }
-    else {
+    else if (shift_amount > -8*INTVAL_SIZE) {
         /* Right shift.  By definition, this can never overflow. */
         result = base >> -shift_amount;
     }
+    else {
+        /* Extreme right shift. */
+        result = 0;
+    }
 
     /* Store the result. */
     if (! overflow_p) {

Modified: trunk/t/pmc/bigint.t
==============================================================================
--- trunk/t/pmc/bigint.t        (original)
+++ trunk/t/pmc/bigint.t        Sat May 12 08:37:58 2007
@@ -25,7 +25,7 @@
 =cut
 
 if ( $PConfig{gmp} ) {
-    plan tests => 43;
+    plan tests => 44;
 }
 else {
     plan skip_all => "No BigInt Lib configured";
@@ -902,6 +902,25 @@
 current instr/
 OUT
 
+pir_output_is( <<'CODE', <<'OUT', "shl_int by 64 bits also promotes to 
Bigint");
+## The C << and >> ops take the right arg modulo the word size in bits (at 
least
+## on all the systems I have available), so both 32- and 64-bit systems treat
+## shifting by 64 bits as shifting by zero.
+.sub main :main
+   new $P0, .Integer
+   set $P0, 1000001
+   new $P1, .Integer
+   set $P1, 64
+   n_shl $P2, $P0, $P1
+   $S2 = typeof $P2
+   print $S2
+   print ' '
+   say $P2
+.end
+CODE
+BigInt 18446762520453625325551616
+OUT
+
 pir_output_is( <<'CODE', <<'OUT', "shr_int and i_shr_int with a neg shift 
promote Integer to Bigint");
 .sub main :main
    new $P0, .Integer

Reply via email to