tprec23.pp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // http://lists.freepascal.org/lists/fpc-devel/2008-June/013919.html
  2. uses SysUtils;
  3. {$ASSERTIONS ON}
  4. type
  5. bit = 0..1;
  6. t6bit = 0..63;
  7. ByteBoundary = bitpacked record
  8. bit0 : bit;
  9. bit1_8 : byte;
  10. bit9_15 : t6bit;
  11. end;
  12. TestByteBoundary = record
  13. case boolean of
  14. false : (AsWord : word);
  15. true : (AsBits : ByteBoundary);
  16. end;
  17. procedure TestBits(b0 : bit; b1_8 : byte; b9_15 : t6bit);
  18. var
  19. Test : TestByteBoundary;
  20. w : word;
  21. begin
  22. {$ifdef fpc_little_endian}
  23. w := b0 + b1_8 shl 1 + b9_15 shl 9;
  24. {$else}
  25. w := b0 shl (16-1) + b1_8 shl (15-8) + b9_15 shl 1;
  26. {$endif}
  27. with Test, asBits do begin
  28. bit0 := b0;
  29. bit1_8 := b1_8;
  30. bit9_15 := b9_15;
  31. {$ifdef fpc_little_endian}
  32. Writeln('Test : $', b0, ' + $', IntToHex(b1_8,2), ' << 1 + $',IntToHex(b9_15,2),' << 9');
  33. write(' Expected : $',IntToHex(w,4),' Got : $',IntToHex((AsWord and $7fff),4));
  34. if w = (Asword and $7fff) then
  35. {$else}
  36. Writeln('Test : $', b0, '<< 15 + $', IntToHex(b1_8,2), ' << 6 + $',IntToHex(b9_15,2),' << 1');
  37. write(' Expected : $',IntToHex(w,4),' Got : $',IntToHex((AsWord and $fffe),4));
  38. if w = (Asword and $fffe) then
  39. {$endif}
  40. writeln(' OK')
  41. else
  42. begin
  43. writeln(' <--- Fail');
  44. halt(1);
  45. end;
  46. end;
  47. end;
  48. procedure testproc;
  49. var
  50. Test : TestByteBoundary;
  51. begin
  52. Test.AsBits.bit0 := 0;
  53. Test.AsBits.bit1_8 := $FF;
  54. Test.AsBits.bit9_15 := 0;
  55. writeln(IntToHex(Test.AsWord,4));
  56. TestBits($1, $80, $00);
  57. TestBits($1, $FE, $00);
  58. TestBits($1, $FF, $00);
  59. // These work
  60. Test.AsBits.bit0 := 1;
  61. Test.AsBits.bit1_8 := $80;
  62. Test.AsBits.bit9_15 := 0;
  63. {$ifdef fpc_little_endian}
  64. assert((Test.AsWord and $7fff) = $0101, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $0101');
  65. Test.AsBits.bit1_8 := $FE;
  66. assert((Test.AsWord and $7fff) = $01FD, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $01FD');
  67. // DOES NOT WORK ...
  68. Test.AsBits.bit1_8 := 255;
  69. assert((Test.AsWord and $7fff) = $01FF, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $01FF');
  70. // Rest OK
  71. Test.AsWord := 0;
  72. Test.AsBits.bit9_15 := 1;
  73. assert((Test.AsWord and $7fff) = $0200, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $0200');
  74. Test.AsBits.bit9_15 := 32;
  75. assert((Test.AsWord and $7fff) = $4000, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $4000');
  76. Test.AsBits.bit9_15 := 62;
  77. assert((Test.AsWord and $7fff) = $7C00, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $7C00');
  78. Test.AsBits.bit9_15 := 63; // Correct
  79. assert((Test.AsWord and $7fff) = $7E00, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $7E00');
  80. Test.AsBits.bit0 := 1;
  81. Test.AsBits.bit1_8 := 255;
  82. Test.AsBits.bit9_15 := 63;
  83. assert((Test.AsWord and $7fff) = $7FFF, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $7FFF');
  84. {$else}
  85. assert((Test.AsWord and $fffe) = $c000, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $C001');
  86. Test.AsBits.bit1_8 := $FE;
  87. assert((Test.AsWord and $fffe) = $FF00, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $FF00');
  88. // DOES NOT WORK ...
  89. Test.AsBits.bit1_8 := 255;
  90. assert((Test.AsWord and $fffe) = $FF80, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $FF80');
  91. // Rest OK
  92. Test.AsWord := 0;
  93. Test.AsBits.bit9_15 := 1;
  94. assert((Test.AsWord and $fffe) = $0002, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $0002');
  95. Test.AsBits.bit9_15 := 32;
  96. assert((Test.AsWord and $fffe) = $0040, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $0040');
  97. Test.AsBits.bit9_15 := 62;
  98. assert((Test.AsWord and $fffe) = $007C, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $007C');
  99. Test.AsBits.bit9_15 := 63; // Correct
  100. assert((Test.AsWord and $fffe) = $007E, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $007E');
  101. Test.AsBits.bit0 := 1;
  102. Test.AsBits.bit1_8 := 255;
  103. Test.AsBits.bit9_15 := 63;
  104. assert((Test.AsWord and $fffe) = $FFFE, 'Is: ' + IntToHex(Test.AsWord,4) + ' Should be $FFFE');
  105. {$endif}
  106. end;
  107. var
  108. Test : TestByteBoundary;
  109. begin
  110. with Test, AsBits do begin
  111. bit0 := 0;
  112. bit1_8 := $FF;
  113. bit9_15 := 0;
  114. writeln(IntToHex(AsWord,4));
  115. TestBits($1, $80, $00);
  116. TestBits($1, $FE, $00);
  117. TestBits($1, $FF, $00);
  118. TestBits($0, $00, $01);
  119. // These work
  120. bit0 := 1;
  121. bit1_8 := $80;
  122. bit9_15 := 0;
  123. {$ifdef fpc_little_endian}
  124. assert((AsWord and $7fff) = $0101, 'Is: ' + IntToHex(Asword,4) + ' Should be $0101');
  125. bit1_8 := $FE;
  126. assert((AsWord and $7fff) = $01FD, 'Is: ' + IntToHex(Asword,4) + ' Should be $01FD');
  127. // DOES NOT WORK ...
  128. bit1_8 := 255;
  129. assert((AsWord and $7fff) = $01FF, 'Is: ' + IntToHex(Asword,4) + ' Should be $01FF');
  130. // Rest OK
  131. AsWord := 0;
  132. bit9_15 := 1;
  133. assert((AsWord and $7fff) = $0200, 'Is: ' + IntToHex(Asword,4) + ' Should be $0200');
  134. bit9_15 := 32;
  135. assert((AsWord and $7fff) = $4000, 'Is: ' + IntToHex(Asword,4) + ' Should be $4000');
  136. bit9_15 := 62;
  137. assert((AsWord and $7fff) = $7C00, 'Is: ' + IntToHex(Asword,4) + ' Should be $7C00');
  138. bit9_15 := 63; // Correct
  139. assert((AsWord and $7fff) = $7E00, 'Is: ' + IntToHex(Asword,4) + ' Should be $7E00');
  140. bit0 := 1;
  141. bit1_8 := 255;
  142. bit9_15 := 63;
  143. assert((AsWord and $7fff) = $7FFF, 'Is: ' + IntToHex(Asword,4) + ' Should be $7FFF');
  144. {$else}
  145. assert((AsWord and $fffe) = $c000, 'Is: ' + IntToHex(Asword,4) + ' Should be $C001');
  146. bit1_8 := $FE;
  147. assert((AsWord and $fffe) = $FF00, 'Is: ' + IntToHex(Asword,4) + ' Should be $FF00');
  148. // DOES NOT WORK ...
  149. bit1_8 := 255;
  150. assert((AsWord and $fffe) = $FF80, 'Is: ' + IntToHex(Asword,4) + ' Should be $FF80');
  151. // Rest OK
  152. AsWord := 0;
  153. bit9_15 := 1;
  154. assert((AsWord and $fffe) = $0002, 'Is: ' + IntToHex(Asword,4) + ' Should be $0002');
  155. bit9_15 := 32;
  156. assert((AsWord and $fffe) = $0040, 'Is: ' + IntToHex(Asword,4) + ' Should be $0040');
  157. bit9_15 := 62;
  158. assert((AsWord and $fffe) = $007C, 'Is: ' + IntToHex(Asword,4) + ' Should be $007C');
  159. bit9_15 := 63; // Correct
  160. assert((AsWord and $fffe) = $007E, 'Is: ' + IntToHex(Asword,4) + ' Should be $007E');
  161. bit0 := 1;
  162. bit1_8 := 255;
  163. bit9_15 := 63;
  164. assert((AsWord and $fffe) = $FFFE, 'Is: ' + IntToHex(Asword,4) + ' Should be $FFFE');
  165. {$endif}
  166. end;
  167. testproc;
  168. end.