| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 | {    This file is part of the Free Pascal simulator environment    Copyright (c) 1999-2000 by Florian Klaempfl    This unit implemements routines for data types which aren't    support by commonly used compilers    See the file COPYING.FPC, included in this distribution,    for details about the copyright.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************}{$N+}{ we do some strange things here }{$O-}{$R-}unit simlib;  interface    uses       simbase;    procedure byte_zap(q : qword;b : byte;var r : qword);    { shifts q b bytes left }    procedure shift_left_q(q : qword;b : byte;var r : qword);    { shifts q b bytes right }    procedure shift_right_q(q : qword;b : byte;var r : qword);    { returns true if i1<i2 assuming that c1 and c2 are unsigned !}    function ltu(c1,c2 : qword) : boolean;    { returns true if i1=<i2 assuming that c1 and c2 are unsigned !}    function leu(c1,c2 : qword) : boolean;    { adds to owords, returns true if an overflow occurs }    function addoword(o1,o2 : oword;var r : oword) : boolean;    { adds two words, returns true if an overflow occurs }    function addword(w1,w2 : word;var r : word) : boolean;    { sets an oword to zero }    procedure zerooword(var o : oword);    { multiplies two qwords into a full oword }    procedure mulqword(q1,q2 : qword;var r : oword);  implementation    procedure byte_zap(q : qword;b : byte;var r : qword);      var         i : tindex;      begin         for i:=0 to 7 do           if ((1 shl i) and b)=0 then             tqwordrec(r).bytes[i]:=tqwordrec(q).bytes[i]           else             tqwordrec(r).bytes[i]:=0;      end;    { shifts q b bytes left }    procedure shift_left_q(q : qword;b : byte;var r : qword);      var         i : tindex;      begin         r:=0;         if b>63 then         else if b>31 then           tqwordrec(r).high32:=tqwordrec(q).low32 shl (b-32)         else           begin              { bad solution! A qword shift would be nice! }              r:=q;              for i:=1 to b do                begin                   tqwordrec(r).high32:=tqwordrec(r).high32 shl 1;                   if (tqwordrec(r).low32 and $80000000)<>0 then                     tqwordrec(r).high32:=tqwordrec(r).high32 or 1;                   tqwordrec(r).low32:=tqwordrec(r).low32 shl 1;                end;           end;      end;    { shifts q b bytes right }    procedure shift_right_q(q : qword;b : byte;var r : qword);      var         i : tindex;      begin         r:=0;         if b>63 then         else if b>31 then           tqwordrec(r).low32:=tqwordrec(q).high32 shr (b-32)         else           begin              { bad solution! A qword shift would be nice! }              r:=q;              for i:=1 to b do                begin                   tqwordrec(r).low32:=tqwordrec(r).low32 shr 1;                   if (tqwordrec(r).high32 and 1)<>0 then                     tqwordrec(r).low32:=tqwordrec(r).low32 or                       $80000000;                   tqwordrec(r).high32:=tqwordrec(r).high32 shr 1;                end;           end;      end;    { returns true if i1<i2 assuming that c1 and c2 are unsigned !}    function ltu(c1,c2 : qword) : boolean;      begin         if (c1>=0) and (c2>=0) then           ltu:=c1<c2         else if (c1<0) and (c2>=0) then           ltu:=false         else if (c1>=0) and (c2<0) then           ltu:=true         else           ltu:=c1<c2      end;    { returns true if i1=<i2 assuming that c1 and c2 are unsigned !}    function leu(c1,c2 : qword) : boolean;      begin         if (c1>=0) and (c2>=0) then           leu:=c1<=c2         else if (c1<0) and (c2>=0) then           leu:=false         else if (c1>=0) and (c2<0) then           leu:=true         else           leu:=c1<=c2      end;    { "ands" two qwords }    procedure andqword(w1,w2 : qword;var r : qword);      begin         tqwordrec(r).low32:=tqwordrec(w1).low32 and tqwordrec(w2).low32;         tqwordrec(r).high32:=tqwordrec(w1).high32 and tqwordrec(w2).high32;      end;    { adds two words, returns true if an overflow occurs }    function addword(w1,w2 : word;var r : word) : boolean;      var         l : longint;      begin         l:=w1+w2;         addword:=(l and $10000)<>0;         r:=l and $ffff;      end;    { adds two owords, returns true if an overflow occurs }    function addoword(o1,o2 : oword;var r : oword) : boolean;      var         i : tindex;         carry : word;      begin         carry:=0;         for i:=0 to 7 do           begin              r[i]:=o1[i]+o2[i]+carry;              { an overflow has occured, if the r is less                than one of the summands              }              if (r[i]<o1[i]) or (r[i]<o2[i]) then                carry:=1              else                carry:=0;           end;         addoword:=carry=1;      end;    { sets an oword to zero }    procedure zerooword(var o : oword);      begin         fillchar(o,sizeof(o),0);      end;    { multiplies two qwords into a full oword }    procedure mulqword(q1,q2 : qword;var r : oword);      var         i : tindex;         h,bitpos : qword;         ho1 : oword;      begin         { r is zero }         zerooword(ho1);         r:=ho1;         towordrec(ho1).low64:=q1;         bitpos:=1;         for i:=0 to 63 do           begin              andqword(q2,bitpos,h);              if h<>0 then                addoword(r,ho1,r);              { ho1:=2*ho1 }              addoword(ho1,ho1,ho1);              shift_left_q(bitpos,1,bitpos);           end;      end;end.
 |