Browse Source

* qword div/mod fixed
+ int64 mod/div/* fully implemented
* int_str(qword) fixed
+ dummies for read/write(qword)

florian 26 years ago
parent
commit
02b83c15a5
1 changed files with 119 additions and 79 deletions
  1. 119 79
      rtl/inc/int64.inc

+ 119 - 79
rtl/inc/int64.inc

@@ -64,9 +64,8 @@
 
       begin
          divqword:=0;
-         one:=1;
-         if n=divqword then
-           runerror(200);
+         if n=0 then
+           runerror(200); //!!!!!!!!! must push the address
          lzz:=count_leading_zeros(z);
          lzn:=count_leading_zeros(n);
          { if the denominator contains less zeros }
@@ -76,72 +75,86 @@
            exit;
          shift:=lzn-lzz;
          n:=n shl shift;
-         repeat                                
+         repeat
            if z>=n then
              begin
                 z:=z-n;
-                divqword:=divqword+(one shl shift);                
+                divqword:=divqword+(qword(1) shl shift);
              end;
            dec(shift);
            n:=n shr 1;
-         until shift<=0;
+         until shift<0;
       end;
 
-    function modqword(z,n : qword) : qword;[public,alias: 'FPC_MOD_QWORD'];
+    function modqword(n,z : qword) : qword;[public,alias: 'FPC_MOD_QWORD'];
 
       var
          shift,lzz,lzn : longint;
 
       begin
-         modqword:=z;
+         modqword:=0;
+         if n=0 then
+           runerror(200);   //!!!!!!!!! must push the address
          lzz:=count_leading_zeros(z);
          lzn:=count_leading_zeros(n);
          { if the denominator contains less zeros }
+         { then the numerator                     }
          { the d is greater than the n            }
          if lzn<lzz then
-           exit;
+           begin
+              modqword:=z;
+              exit;
+           end;
          shift:=lzn-lzz;
          n:=n shl shift;
-         repeat                                
-           if z>n then
+         repeat
+           if z>=n then
              z:=z-n;
            dec(shift);
            n:=n shr 1;
-         until shift<=0;
+         until shift<0;
          modqword:=z;
       end;
 
-    function divint64(z,n : int64) : int64;[public,alias: 'FPC_DIV_INT64'];
+    function divint64(n,z : int64) : int64;[public,alias: 'FPC_DIV_INT64'];
 
       var
          sign : boolean;
          q1,q2 : qword;
 
       begin
-         sign:=false;
-         if z<0 then
-           begin
-              sign:=not(sign);
-              q1:=qword(-z);
-           end
+         if n=0 then
+           runerror(200); //!!!!!!!!!!!! must get the right address
+         { can the fpu do the work? }
+         if fpuint64 then
+           //!!!!!!!!!!! divint64:=comp(z)/comp(n)
          else
-           q1:=z;
-         if n<0 then
            begin
-              sign:=not(sign);
-              q2:=qword(-n);
-           end
-         else
-           q2:=n;
-
-         { the div is coded by the compiler as call to divqword }
-         if sign then
-           divint64:=-q1 div q2
-         else
-           divint64:=q1 div q2;
+              sign:=false;
+              if z<0 then
+                begin
+                   sign:=not(sign);
+                   q1:=qword(-z);
+                end
+              else
+                q1:=z;
+              if n<0 then
+                begin
+                   sign:=not(sign);
+                   q2:=qword(-n);
+                end
+              else
+                q2:=n;
+
+              { the div is coded by the compiler as call to divqword }
+              if sign then
+                divint64:=-(q1 div q2)
+              else
+                divint64:=q1 div q2;
+           end;
       end;
 
-    { multiplies two qwords 
+    { multiplies two qwords
       the longbool for checkoverflow avoids a misaligned stack
     }
     function mulqword(f1,f2 : qword;checkoverflow : longbool) : qword;[public,alias: 'FPC_MUL_QWORD'];
@@ -152,36 +165,28 @@
 
 
       begin
+         zero:=0;
+         mulqword:=0;
          { we can't write currently qword constants directly :( }
-         zero:=zero xor zero;
-         mulqword:=zero;
          tqwordrec(bitpos64).high:=$80000000;
          tqwordrec(bitpos64).low:=0;
-         tqwordrec(bitpos).high:=0;
-         tqwordrec(bitpos).low:=1;
+         bitpos:=1;
 
          for l:=0 to 63 do
            begin
-              { if the highest bit of f1 is set and it isn't the
-                last run, then an overflow occcurs!
-              }
-              if checkoverflow and (l<>63) and
-                ((tqwordrec(f1).high and $80000000)<>0)  then
-                int_overflow;
-
               if (f2 and bitpos)<>zero then
-                begin
-                   if checkoverflow then
-{$Q+}                
-                     mulqword:=mulqword+f1
-{$Q-}
-                   else
-                     mulqword:=mulqword+f1;
-                end;
+                mulqword:=mulqword+f1;
 
               f1:=f1 shl 1;
               bitpos:=bitpos shl 1;
            end;
+
+         { if one of the operands is greater than the result an }
+         { overflow occurs                                      }
+         if checkoverflow and ((f1>mulqword) or (f2>mulqword)) then
+           begin
+              int_overflow;
+           end;
       end;
 
     {    multiplies two int64 ....
@@ -198,33 +203,42 @@
          q1,q2,q3 : qword;
 
       begin
-         sign:=false;
-         if f1<0 then
-           begin
-              sign:=not(sign);
-              q1:=qword(-f1);
-           end
+         { can the fpu do the work ? }
+         if fpuint64 and not(checkoverflow) then
+           // !!!!!!! multint64:=comp(f1)*comp(f2)
          else
-           q1:=f1;
-         if f2<0 then
            begin
-              sign:=not(sign);
-              q2:=qword(-f2);
-           end
-         else
-           q2:=f2;
-         { the q1*q2 is coded as call to mulqword }
-         if checkoverflow then
-{$Q+}
-           q3:=q1*q2 
-         else
-{$Q-}
-           q3:=q1*q2;
-
-         if sign then
-           mulint64:=-q3
-         else
-           mulint64:=q3;
+              sign:=false;
+              if f1<0 then
+                begin
+                   sign:=not(sign);
+                   q1:=qword(-f1);
+                end
+              else
+                q1:=f1;
+              if f2<0 then
+                begin
+                   sign:=not(sign);
+                   q2:=qword(-f2);
+                end
+              else
+                q2:=f2;
+              { the q1*q2 is coded as call to mulqword }
+              q3:=q1*q2;
+
+              if checkoverflow and ((q1>q3) or (q2>q3) or
+                { the bit 63 can be only set if we have $80000000 00000000 }
+                { and sign is true                                         }
+                ((tqwordrec(q3).high and $80000000)<>0) and
+                 ((q3<>(qword(1) shl 63)) or not(sign))
+                ) then
+                runerror(202); {!!!!!!!!! must be overflow }
+
+              if sign then
+                mulint64:=-q3
+              else
+                mulint64:=q3;
+           end;
       end;
 
     procedure int_str(value : qword;var s : string);
@@ -233,7 +247,6 @@
          hs : string;
 
       begin
-         {!!!!!!!!!!!      }
          hs:='';
          repeat
            hs:=chr(longint(value mod 10)+48)+hs;
@@ -259,9 +272,36 @@
            int_str(qword(value),s);
       end;
 
+    { should be moved to text.inc!!!!!!!!! }
+    procedure write_qword(len : longint;{!!!!!var t : textrec;}q : qword);[public,alias:'FPC_WRITE_TEXT_QWORD'];
+
+      var
+         s : string;
+
+      begin
+         {
+         if (InOutRes<>0) then
+           exit;
+         int_str(q,s);
+         write_str(len,t,s);
+         }
+      end;
+
+    procedure read_qword(len : longint;{!!!!!var t : textrec;}q : qword);[public,alias:'FPC_READ_TEXT_QWORD'];
+
+      begin
+         {!!!!!!!!}
+      end;
+
 {
   $Log$
-  Revision 1.8  1999-06-28 22:25:25  florian
+  Revision 1.9  1999-06-30 22:12:40  florian
+    * qword div/mod fixed
+    + int64 mod/div/* fully implemented
+    * int_str(qword) fixed
+    + dummies for read/write(qword)
+
+  Revision 1.8  1999/06/28 22:25:25  florian
     * fixed qword division
 
   Revision 1.7  1999/06/25 12:24:44  pierre