diff --git a/.gitattributes b/.gitattributes index b7fd3bf6ca..ef3c32da2a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6775,6 +6775,7 @@ tests/test/tparray15.pp svneol=native#text/plain tests/test/tparray16.pp svneol=native#text/plain tests/test/tparray17.pp svneol=native#text/plain tests/test/tparray18.pp svneol=native#text/plain +tests/test/tparray19.pp svneol=native#text/plain tests/test/tparray2.pp svneol=native#text/plain tests/test/tparray3.pp svneol=native#text/plain tests/test/tparray4.pp svneol=native#text/plain diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index e9dafadf85..39daf4d35c 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -917,10 +917,12 @@ implementation {$ifopt r+} {$define rangeon} +{$r-} {$endif} {$ifopt q+} {$define overflowon} +{$q-} {$endif} procedure tcg.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); @@ -930,15 +932,25 @@ implementation stopbit: byte; begin tmpreg:=getintregister(list,sreg.subsetregsize); - a_op_const_reg_reg(list,OP_SHR,sreg.subsetregsize,sreg.startbit,sreg.subsetreg,tmpreg); - stopbit := sreg.startbit + sreg.bitlen; - // on x86(64), 1 shl 32(64) = 1 instead of 0 - // use aword to prevent overflow with 1 shl 31 - if (stopbit - sreg.startbit <> AIntBits) then - bitmask := (aword(1) shl (stopbit - sreg.startbit)) - 1 + if (subsetsize in [OS_S8..OS_S128]) then + begin + { sign extend in case the value has a bitsize mod 8 <> 0 } + { both instructions will be optimized away if not } + a_op_const_reg_reg(list,OP_SHL,sreg.subsetregsize,(tcgsize2size[sreg.subsetregsize]*8)-sreg.startbit-sreg.bitlen,sreg.subsetreg,tmpreg); + a_op_const_reg(list,OP_SAR,sreg.subsetregsize,(tcgsize2size[sreg.subsetregsize]*8)-sreg.bitlen,tmpreg); + end else - bitmask := high(aword); - a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(bitmask),tmpreg); + begin + a_op_const_reg_reg(list,OP_SHR,sreg.subsetregsize,sreg.startbit,sreg.subsetreg,tmpreg); + stopbit := sreg.startbit + sreg.bitlen; + // on x86(64), 1 shl 32(64) = 1 instead of 0 + // use aword to prevent overflow with 1 shl 31 + if (stopbit - sreg.startbit <> AIntBits) then + bitmask := (aword(1) shl (stopbit - sreg.startbit)) - 1 + else + bitmask := high(aword); + a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(bitmask),tmpreg); + end; tmpreg := makeregsize(list,tmpreg,subsetsize); a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,tmpreg,tmpreg); a_load_reg_reg(list,subsetsize,tosize,tmpreg,destreg); @@ -1081,7 +1093,7 @@ implementation (* Subsetrefs are used for (bit)packed arrays and (bit)packed records stored in memory. They are like a regular reference, but contain an extra bit - offset (either constant -startbit- or variable -bitindexreg, always OS_INT) + offset (either constant -startbit- or variable -bitindexreg-, always OS_INT) and a bit length (always constant). Bit packed values are stored differently in memory depending on whether we @@ -1101,7 +1113,7 @@ implementation the right, but the bits in the next byte are all more significant than those in the previous byte (e.g., the 222 in the first byte are the low three bits of that value, while the 22 in the second byte are the upper - three bits. + two bits. Big endian, 9 bit values: 11111111 12222222 22333333 33344444 ... @@ -1171,20 +1183,37 @@ implementation begin { valuereg contains the upper bits, extra_value_reg the lower } restbits := (sref.bitlen - (loadbitsize - sref.startbit)); - a_op_const_reg(list,OP_SHL,OS_INT,restbits,valuereg); - { mask other bits } - if (sref.bitlen <> AIntBits) then - a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + { sign extend } + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-loadbitsize+sref.startbit,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg); + end + else + begin + a_op_const_reg(list,OP_SHL,OS_INT,restbits,valuereg); + { mask other bits } + if (sref.bitlen <> AIntBits) then + a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + end; a_op_const_reg(list,OP_SHR,OS_INT,loadbitsize-restbits,extra_value_reg) end else begin { valuereg contains the lower bits, extra_value_reg the upper } a_op_const_reg(list,OP_SHR,OS_INT,sref.startbit,valuereg); - a_op_const_reg(list,OP_SHL,OS_INT,loadbitsize-sref.startbit,extra_value_reg); - { mask other bits } - if (sref.bitlen <> AIntBits) then - a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),extra_value_reg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-sref.bitlen+loadbitsize-sref.startbit,extra_value_reg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,extra_value_reg); + end + else + begin + a_op_const_reg(list,OP_SHL,OS_INT,loadbitsize-sref.startbit,extra_value_reg); + { mask other bits } + if (sref.bitlen <> AIntBits) then + a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),extra_value_reg); + end; end; { merge } a_op_reg_reg(list,OP_OR,OS_INT,extra_value_reg,valuereg); @@ -1203,10 +1232,18 @@ implementation { get the data in valuereg in the right place } a_op_reg_reg(list,OP_SHL,OS_INT,sref.bitindexreg,valuereg); - a_op_const_reg(list,OP_SHR,OS_INT,loadbitsize-sref.bitlen,valuereg); - if (loadbitsize <> AIntBits) then - { mask left over bits } - a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-loadbitsize,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg) + end + else + begin + a_op_const_reg(list,OP_SHR,OS_INT,loadbitsize-sref.bitlen,valuereg); + if (loadbitsize <> AIntBits) then + { mask left over bits } + a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + end; tmpreg := getintregister(list,OS_INT); { the bits in extra_value_reg (if any) start at the most significant bit => } { extra_value_reg must be shr by (loadbitsize-sref.bitlen)+(loadsize-sref.bitindex) } @@ -1245,8 +1282,14 @@ implementation {$endif x86} { merge } a_op_reg_reg(list,OP_OR,OS_INT,extra_value_reg,valuereg); - { mask other bits } - a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + { sign extend or mask other bits } + if (subsetsize in [OS_S8..OS_S128]) then + begin + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-sref.bitlen,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg); + end + else + a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); end; end; @@ -1292,12 +1335,27 @@ implementation if (target_info.endian = endian_big) then begin a_op_reg_reg(list,OP_SHL,OS_INT,sref.bitindexreg,valuereg); - a_op_const_reg(list,OP_SHR,OS_INT,loadbitsize-sref.bitlen,valuereg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + { sign extend to entire register } + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-loadbitsize,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg); + end + else + a_op_const_reg(list,OP_SHR,OS_INT,loadbitsize-sref.bitlen,valuereg); end else - a_op_reg_reg(list,OP_SHR,OS_INT,sref.bitindexreg,valuereg); - { mask other bits } - a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); + begin + a_op_reg_reg(list,OP_SHR,OS_INT,sref.bitindexreg,valuereg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-sref.bitlen,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg); + end + end; + { mask other bits/sign extend } + if not(subsetsize in [OS_S8..OS_S128]) then + a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),valuereg); end end else @@ -1320,22 +1378,11 @@ implementation end; { store in destination } - { (types with a negative lower bound are always a base type (8, 16, 32, 64 bits) } - if ((sref.bitlen mod 8) = 0) then - begin - { since we know all necessary bits are already masked, avoid unnecessary } - { zero-extensions } - valuereg := makeregsize(list,valuereg,tosize); - a_load_reg_reg(list,tcgsize2unsigned[tosize],tosize,valuereg,destreg) - end - else - begin - { avoid unnecessary sign extension and zeroing } - valuereg := makeregsize(list,valuereg,OS_INT); - destreg := makeregsize(list,destreg,OS_INT); - a_load_reg_reg(list,OS_INT,OS_INT,valuereg,destreg); - destreg := makeregsize(list,destreg,tosize); - end + { avoid unnecessary sign extension and zeroing } + valuereg := makeregsize(list,valuereg,OS_INT); + destreg := makeregsize(list,destreg,OS_INT); + a_load_reg_reg(list,OS_INT,OS_INT,valuereg,destreg); + destreg := makeregsize(list,destreg,tosize); end; @@ -1541,16 +1588,14 @@ implementation if (target_info.endian = endian_big) then begin a_op_const_reg(list,OP_SHL,OS_INT,loadbitsize-sref.bitlen,tmpreg); - if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) and - (loadbitsize <> AIntBits) then + if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then { mask left over bits } a_op_const_reg(list,OP_AND,OS_INT,aint(((aword(1) shl sref.bitlen)-1) shl (loadbitsize-sref.bitlen)),tmpreg); a_op_reg_reg(list,OP_SHR,OS_INT,sref.bitindexreg,tmpreg); end else begin - if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) and - (loadbitsize <> AIntBits) then + if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then { mask left over bits } a_op_const_reg(list,OP_AND,OS_INT,aint((aword(1) shl sref.bitlen)-1),tmpreg); a_op_reg_reg(list,OP_SHL,OS_INT,sref.bitindexreg,tmpreg); @@ -1669,11 +1714,14 @@ implementation tmpreg: tregister; slopt: tsubsetloadopt; begin + { perform masking of the source value in advance } slopt := SL_REGNOSRCMASK; + if (sref.bitlen <> AIntBits) then + aword(a) := aword(a) and ((aword(1) shl sref.bitlen) -1); if ( { broken x86 "x shl regbitsize = x" } ((sref.bitlen <> AIntBits) and - (aword(a) = (aword(1) shl sref.bitlen) -1)) or + ((aword(a) and ((aword(1) shl sref.bitlen) -1)) = (aword(1) shl sref.bitlen) -1)) or ((sref.bitlen = AIntBits) and (a = -1)) ) then diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index 2d770f4f92..dc52410148 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -417,11 +417,17 @@ const list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg, sreg.subsetreg,(32-sreg.startbit) and 31,32-sreg.bitlen,31)); { types with a negative lower bound are always a base type (8, 16, 32 bits) } - if ((sreg.bitlen mod 8) = 0) then - begin - a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg); - a_load_reg_reg(list,subsetsize,tosize,destreg,destreg); - end; + if (subsetsize in [OS_S8..OS_S128]) then + if ((sreg.bitlen mod 8) = 0) then + begin + a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg); + a_load_reg_reg(list,subsetsize,tosize,destreg,destreg); + end + else + begin + a_op_const_reg(list,OP_SHL,OS_INT,32-sreg.bitlen,destreg); + a_op_const_reg(list,OP_SAR,OS_INT,32-sreg.bitlen,destreg); + end; end else a_load_reg_reg(list,subsetsize,tosize,sreg.subsetreg,destreg); diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index 14284f1a16..90cd8eeb77 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/compiler/powerpc64/cgcpu.pas @@ -814,12 +814,20 @@ begin extend the sign correctly. (The latter is actually required only for signed subsets and if that subset is not >= the tosize). } extrdi_startbit := 64 - (sreg.bitlen + sreg.startbit); - if (sreg.startbit <> 0) then begin + if (sreg.startbit <> 0) or + (sreg.bitlen <> tcgsize2size[subsetsize]*8) then begin list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, sreg.subsetreg, sreg.bitlen, extrdi_startbit)); - a_load_reg_reg(list, tcgsize2unsigned[subsetsize], subsetsize, destreg, destreg); - a_load_reg_reg(list, subsetsize, tosize, destreg, destreg); + if (subsetsize in [OS_S8..OS_S128]) then + if ((sreg.bitlen mod 8) = 0) then begin + a_load_reg_reg(list, tcgsize2unsigned[subsetsize], subsetsize, destreg, destreg); + a_load_reg_reg(list, subsetsize, tosize, destreg, destreg); + end else begin + a_op_const_reg(list,OP_SHL,OS_INT,64-sreg.bitlen,destreg); + a_op_const_reg(list,OP_SAR,OS_INT,64-sreg.bitlen,destreg); + end; end else begin a_load_reg_reg(list, tcgsize2unsigned[sreg.subsetregsize], subsetsize, sreg.subsetreg, destreg); + a_load_reg_reg(list, subsetsize, tosize, destreg, destreg); end; end; diff --git a/compiler/ppcgen/cgppc.pas b/compiler/ppcgen/cgppc.pas index 9d03409a96..540283a4f5 100644 --- a/compiler/ppcgen/cgppc.pas +++ b/compiler/ppcgen/cgppc.pas @@ -312,26 +312,29 @@ unit cgppc; restbits: byte; begin restbits := (sref.bitlen - (loadbitsize - sref.startbit)); - a_op_const_reg(list,OP_SHL,OS_INT,restbits,valuereg); - { mask other bits } - if (sref.bitlen <> AIntBits) then - a_op_const_reg(list,OP_AND,OS_INT,(aword(1) shl sref.bitlen)-1,valuereg); + if (subsetsize in [OS_S8..OS_S128]) then + begin + { sign extend } + a_op_const_reg(list,OP_SHL,OS_INT,AIntBits-loadbitsize+sref.startbit,valuereg); + a_op_const_reg(list,OP_SAR,OS_INT,AIntBits-sref.bitlen,valuereg); + end + else + begin + a_op_const_reg(list,OP_SHL,OS_INT,restbits,valuereg); + { mask other bits } + if (sref.bitlen <> AIntBits) then + a_op_const_reg(list,OP_AND,OS_INT,(aword(1) shl sref.bitlen)-1,valuereg); + end; { use subsetreg routine, it may have been overridden with an optimized version } fromsreg.subsetreg := extra_value_reg; fromsreg.subsetregsize := OS_INT; { subsetregs always count bits from right to left } - if (target_info.endian = endian_big) then - fromsreg.startbit := loadbitsize-restbits - else - fromsreg.startbit := 0; + fromsreg.startbit := loadbitsize-restbits; fromsreg.bitlen := restbits; tosreg.subsetreg := valuereg; tosreg.subsetregsize := OS_INT; - if (target_info.endian = endian_big) then - tosreg.startbit := 0 - else - tosreg.startbit := loadbitsize-sref.startbit; + tosreg.startbit := 0; tosreg.bitlen := restbits; a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg); diff --git a/compiler/symdef.pas b/compiler/symdef.pas index a0b6e5d38d..14d973d1bb 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -1331,21 +1331,23 @@ implementation function tenumdef.packedbitsize: aint; var + sizeval: tconstexprint; power: longint; begin result := 0; - if (minval < 0) then - result := inherited packedbitsize + if (minval >= 0) and + (maxval <= 1) then + result := 1 else begin - if (maxval <= 1) then - result := 1 + if (minval>=0) then + sizeval:=maxval else - begin - { 256 must become 512 etc. } - nextpowerof2(maxval+1,power); - result := power; - end; + { don't count 0 twice } + sizeval:=(cutils.max(-minval,maxval)*2)-1; + { 256 must become 512 etc. } + nextpowerof2(sizeval+1,power); + result := power; end; end; @@ -1496,26 +1498,32 @@ implementation function torddef.packedbitsize: aint; var + sizeval: tconstexprint; power: longint; begin result := 0; if ordtype = uvoid then exit; - if (low < 0) then - result := inherited packedbitsize + + if (low >= 0) and + (high <= 1) then + result := 1 + else if (ordtype = u64bit) or + ((ordtype = s64bit) and + ((low <= (system.low(int64) div 2)) or + (high > (system.high(int64) div 2)))) then + result := 64 else begin - if (high <= 1) then - result := 1 - else if (ordtype = u64bit) then - result := 64 + if (low>=0) then + sizeval:=high else - begin - { 256 must become 512 etc. } - nextpowerof2(high+1,power); - result := power; - end; - end; + { don't count 0 twice } + sizeval:=(cutils.max(-low,high)*2)-1; + { 256 must become 512 etc. } + nextpowerof2(sizeval+1,power); + result := power; + end; end; diff --git a/tests/test/tparray19.pp b/tests/test/tparray19.pp new file mode 100644 index 0000000000..5afc86319b --- /dev/null +++ b/tests/test/tparray19.pp @@ -0,0 +1,247 @@ +{$mode macpas} + +{$r-} + +procedure error(l: longint); +begin + writeln('error near ',l); + halt(1); +end; + + +procedure test8bit; +type + ta = -1..0; + tb = packed array[0..999] of ta; + tc = array[0..124] of byte; +const + results: array[0..9] of ta = (-1,0,-1,-1,-1,0,-1,-1,-1,0); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),0); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> 0 then + error(201); + if b[i] <> results[i] then + error(202); + end; + if (b[0] <> results[0]) then + error(1); + if (b[1] <> results[1]) then + error(2); + if (b[2] <> results[2]) then + error(3); + if (b[3] <> results[3]) then + error(4); + if (b[4] <> results[4]) then + error(5); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(7); +end; + + +procedure test8to16bit; +type + ta = -3..3; + tb = packed array[0..1000] of ta; +const + results: array[0..5] of ta = (2,-2,1,-1,-3,1); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),0); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> 0 then + error(211); + if b[i] <> results[i] then + error(212); + end; + if (b[0] <> results[0]) then + error(11); + if (b[1] <> results[1]) then + error(12); + if (b[2] <> results[2]) then + error(13); + if (b[3] <> results[3]) then + error(14); + if (b[4] <> results[4]) then + error(15); + if (b[5] <> results[5]) then + error(155); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(17); +end; + + +procedure test16bit; +type + ta = -255..255; + tb = packed array[0..799] of ta; + tc = array[0..899] of byte; +const + results: array[0..4] of ta = (256-356,39,256-485,100,256-500); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),$ff); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> -1 then + error(221); + if b[i] <> results[i] then + error(222); + end; + if (b[0] <> results[0]) then + error(21); + if (b[1] <> results[1]) then + error(22); + if (b[2] <> results[2]) then + error(23); + if (b[3] <> results[3]) then + error(24); + if (b[4] <> results[4]) then + error(25); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(27); +end; + + +procedure test16to24bit; +type + ta = -1023..1023; + tb = packed array[0..799] of ta; + tc = array[0..1099] of byte; +const + results: array[0..4] of ta = (1000,67-1023,853,512-1023,759); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),0); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> 0 then + error(231); + if b[i] <> results[i] then + error(232); + end; + if (b[0] <> results[0]) then + error(31); + if (b[1] <> results[1]) then + error(32); + if (b[2] <> results[2]) then + error(33); + if (b[3] <> results[3]) then + error(34); + if (b[4] <> results[4]) then + error(35); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(37); +end; + + +procedure test32bit; +type + ta = -((1 shl 18)-1)..(1 shl 18) - 1; + tb = packed array[0..799] of ta; + tc = array[0..1899] of byte; +const + results: array[0..4] of ta = ($0002F687,$00032222-(1 shl 18),$000178EE,$000057970-(1 shl 18),$0007E1D2-(1 shl 18)); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),$00); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> 0 then + error(241); + if b[i] <> results[i] then + error(242); + end; + if (b[0] <> results[0]) then + error(41); + if (b[1] <> results[1]) then + error(42); + if (b[2] <> results[2]) then + error(43); + if (b[3] <> results[3]) then + error(44); + if (b[4] <> results[4]) then + error(45); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(47); +end; + + +procedure test32to40bit; +type + ta = -$3fffffff..$3fffffff; + tb = packed array[0..799] of ta; + tc = array[0..3099] of byte; +const + results: array[0..4] of ta = ($3fffffff-$71567851,$3fffffff-$56789ABD,$3fffffff-$50F11178,$39D68DDC,$3fffffff-$6C7A5A7); +var + a: ta; + b: tb; + i,j: longint; +begin + fillchar(b,sizeof(b),0); + for i := low(results) to high(results) do + begin + b[i] := results[i]; + for j := succ(i) to high(results) do + if b[j] <> 0 then + error(251); + if b[i] <> results[i] then + error(252); + end; + if (b[0] <> results[0]) then + error(51); + if (b[1] <> results[1]) then + error(52); + if (b[2] <> results[2]) then + error(53); + if (b[3] <> results[3]) then + error(54); + if (b[4] <> results[4]) then + error(55); + for i := low(results) to high(results) do + if b[i] <> results[i] then + error(57); +end; + +begin + test8bit; + test8to16bit; + test16bit; + test16to24bit; + test32bit; + test32to40bit; +end.