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.
|