diff options
author | karoly <karoly@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-02-21 23:00:41 +0000 |
---|---|---|
committer | karoly <karoly@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-02-21 23:00:41 +0000 |
commit | 793b74f37cdd56bb39180236a8685a1b1d1f8993 (patch) | |
tree | 57ed7eb69709ab153931d99dcb1e7e6b28aa7314 /compiler/ngtcon.pas | |
parent | 2d7ec7fc67221993e4ff25b22437ba2565aabbff (diff) | |
download | fpc-793b74f37cdd56bb39180236a8685a1b1d1f8993.tar.gz |
* attempt to fix bitpacked records with qwords in them (tw36156) when cross-compiling to big endian targets from x86. essentially the x86 shifting workarounds in the code already weren't covering all corner cases.
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@48773 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ngtcon.pas')
-rw-r--r-- | compiler/ngtcon.pas | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/compiler/ngtcon.pas b/compiler/ngtcon.pas index f08ec07c21..930ca5fa38 100644 --- a/compiler/ngtcon.pas +++ b/compiler/ngtcon.pas @@ -328,6 +328,25 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis {$push} {$r-} {$q-} + { to work around broken x86 shifting, while generating bitmask } + function getbitmask(len: byte): aword; + begin + if len >= (sizeof(result) * 8) then + result:=0 + else + result:=aword(1) shl len; + result:=aword(result-1); + end; + + { shift left, and always pad the right bits with zeroes } + function shiftleft(value: aword; count: byte): aword; + begin + if count >= (sizeof(result) * 8) then + result:=0 + else + result:=(value shl count) and (not getbitmask(count)); + end; + { (values between quotes below refer to fields of bp; fields not } { mentioned are unused by this routine) } { bitpacks "value" as bitpacked value of bitsize "packedbitsize" into } @@ -342,16 +361,15 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis if (target_info.endian=endian_big) then begin { bitpacked format: left-aligned (i.e., "big endian bitness") } - { work around broken x86 shifting } - if (AIntBits<>bp.packedbitsize) and + if (bp.packedbitsize<AIntBits) and (bp.curbitoffset<AIntBits) then - bp.curval:=bp.curval or ((value shl (AIntBits-bp.packedbitsize)) shr bp.curbitoffset); + bp.curval:=bp.curval or (shiftleft(value,AIntBits-bp.packedbitsize) shr bp.curbitoffset); shiftcount:=((AIntBits-bp.packedbitsize)-bp.curbitoffset); { carry-over to the next element? } if (shiftcount<0) then begin if shiftcount>=-AIntBits then - bp.nextval:=(value and ((aword(1) shl (-shiftcount))-1)) shl + bp.nextval:=(value and getbitmask(-shiftcount)) shl (AIntBits+shiftcount) else bp.nextval:=0; |