simlib.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. {
  2. This file is part of the Free Pascal simulator environment
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. This unit implemements routines for data types which aren't
  5. support by commonly used compilers
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$N+}
  13. { we do some strange things here }
  14. {$O-}
  15. {$R-}
  16. unit simlib;
  17. interface
  18. uses
  19. simbase;
  20. procedure byte_zap(q : qword;b : byte;var r : qword);
  21. { shifts q b bytes left }
  22. procedure shift_left_q(q : qword;b : byte;var r : qword);
  23. { shifts q b bytes right }
  24. procedure shift_right_q(q : qword;b : byte;var r : qword);
  25. { returns true if i1<i2 assuming that c1 and c2 are unsigned !}
  26. function ltu(c1,c2 : qword) : boolean;
  27. { returns true if i1=<i2 assuming that c1 and c2 are unsigned !}
  28. function leu(c1,c2 : qword) : boolean;
  29. { adds to owords, returns true if an overflow occurs }
  30. function addoword(o1,o2 : oword;var r : oword) : boolean;
  31. { adds two words, returns true if an overflow occurs }
  32. function addword(w1,w2 : word;var r : word) : boolean;
  33. { sets an oword to zero }
  34. procedure zerooword(var o : oword);
  35. { multiplies two qwords into a full oword }
  36. procedure mulqword(q1,q2 : qword;var r : oword);
  37. implementation
  38. procedure byte_zap(q : qword;b : byte;var r : qword);
  39. var
  40. i : tindex;
  41. begin
  42. for i:=0 to 7 do
  43. if ((1 shl i) and b)=0 then
  44. tqwordrec(r).bytes[i]:=tqwordrec(q).bytes[i]
  45. else
  46. tqwordrec(r).bytes[i]:=0;
  47. end;
  48. { shifts q b bytes left }
  49. procedure shift_left_q(q : qword;b : byte;var r : qword);
  50. var
  51. i : tindex;
  52. begin
  53. r:=0;
  54. if b>63 then
  55. else if b>31 then
  56. tqwordrec(r).high32:=tqwordrec(q).low32 shl (b-32)
  57. else
  58. begin
  59. { bad solution! A qword shift would be nice! }
  60. r:=q;
  61. for i:=1 to b do
  62. begin
  63. tqwordrec(r).high32:=tqwordrec(r).high32 shl 1;
  64. if (tqwordrec(r).low32 and $80000000)<>0 then
  65. tqwordrec(r).high32:=tqwordrec(r).high32 or 1;
  66. tqwordrec(r).low32:=tqwordrec(r).low32 shl 1;
  67. end;
  68. end;
  69. end;
  70. { shifts q b bytes right }
  71. procedure shift_right_q(q : qword;b : byte;var r : qword);
  72. var
  73. i : tindex;
  74. begin
  75. r:=0;
  76. if b>63 then
  77. else if b>31 then
  78. tqwordrec(r).low32:=tqwordrec(q).high32 shr (b-32)
  79. else
  80. begin
  81. { bad solution! A qword shift would be nice! }
  82. r:=q;
  83. for i:=1 to b do
  84. begin
  85. tqwordrec(r).low32:=tqwordrec(r).low32 shr 1;
  86. if (tqwordrec(r).high32 and 1)<>0 then
  87. tqwordrec(r).low32:=tqwordrec(r).low32 or
  88. $80000000;
  89. tqwordrec(r).high32:=tqwordrec(r).high32 shr 1;
  90. end;
  91. end;
  92. end;
  93. { returns true if i1<i2 assuming that c1 and c2 are unsigned !}
  94. function ltu(c1,c2 : qword) : boolean;
  95. begin
  96. if (c1>=0) and (c2>=0) then
  97. ltu:=c1<c2
  98. else if (c1<0) and (c2>=0) then
  99. ltu:=false
  100. else if (c1>=0) and (c2<0) then
  101. ltu:=true
  102. else
  103. ltu:=c1<c2
  104. end;
  105. { returns true if i1=<i2 assuming that c1 and c2 are unsigned !}
  106. function leu(c1,c2 : qword) : boolean;
  107. begin
  108. if (c1>=0) and (c2>=0) then
  109. leu:=c1<=c2
  110. else if (c1<0) and (c2>=0) then
  111. leu:=false
  112. else if (c1>=0) and (c2<0) then
  113. leu:=true
  114. else
  115. leu:=c1<=c2
  116. end;
  117. { "ands" two qwords }
  118. procedure andqword(w1,w2 : qword;var r : qword);
  119. begin
  120. tqwordrec(r).low32:=tqwordrec(w1).low32 and tqwordrec(w2).low32;
  121. tqwordrec(r).high32:=tqwordrec(w1).high32 and tqwordrec(w2).high32;
  122. end;
  123. { adds two words, returns true if an overflow occurs }
  124. function addword(w1,w2 : word;var r : word) : boolean;
  125. var
  126. l : longint;
  127. begin
  128. l:=w1+w2;
  129. addword:=(l and $10000)<>0;
  130. r:=l and $ffff;
  131. end;
  132. { adds two owords, returns true if an overflow occurs }
  133. function addoword(o1,o2 : oword;var r : oword) : boolean;
  134. var
  135. i : tindex;
  136. carry : word;
  137. begin
  138. carry:=0;
  139. for i:=0 to 7 do
  140. begin
  141. r[i]:=o1[i]+o2[i]+carry;
  142. { an overflow has occured, if the r is less
  143. than one of the summands
  144. }
  145. if (r[i]<o1[i]) or (r[i]<o2[i]) then
  146. carry:=1
  147. else
  148. carry:=0;
  149. end;
  150. addoword:=carry=1;
  151. end;
  152. { sets an oword to zero }
  153. procedure zerooword(var o : oword);
  154. begin
  155. fillchar(o,sizeof(o),0);
  156. end;
  157. { multiplies two qwords into a full oword }
  158. procedure mulqword(q1,q2 : qword;var r : oword);
  159. var
  160. i : tindex;
  161. h,bitpos : qword;
  162. ho1 : oword;
  163. begin
  164. { r is zero }
  165. zerooword(ho1);
  166. r:=ho1;
  167. towordrec(ho1).low64:=q1;
  168. bitpos:=1;
  169. for i:=0 to 63 do
  170. begin
  171. andqword(q2,bitpos,h);
  172. if h<>0 then
  173. addoword(r,ho1,r);
  174. { ho1:=2*ho1 }
  175. addoword(ho1,ho1,ho1);
  176. shift_left_q(bitpos,1,bitpos);
  177. end;
  178. end;
  179. end.