diff --git a/.gitattributes b/.gitattributes index 7387622faa..40f5eec40d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8291,6 +8291,7 @@ tests/webtbf/tw12933.pp svneol=native#text/plain tests/webtbf/tw1306.pp svneol=native#text/plain tests/webtbf/tw1316.pp svneol=native#text/plain tests/webtbf/tw1328.pp svneol=native#text/plain +tests/webtbf/tw13563a.pp svneol=native#text/plain tests/webtbf/tw1365.pp svneol=native#text/plain tests/webtbf/tw1395.pp svneol=native#text/plain tests/webtbf/tw1407.pp svneol=native#text/plain @@ -8823,6 +8824,7 @@ tests/webtbs/tw1348.pp svneol=native#text/plain tests/webtbs/tw1351.pp svneol=native#text/plain tests/webtbs/tw13536.pp svneol=native#text/plain tests/webtbs/tw13553.pp svneol=native#text/plain +tests/webtbs/tw13563.pp svneol=native#text/plain tests/webtbs/tw1364.pp svneol=native#text/plain tests/webtbs/tw1365.pp svneol=native#text/plain tests/webtbs/tw1374.pp svneol=native#text/plain diff --git a/compiler/rautils.pas b/compiler/rautils.pas index e9a8e63a2f..bc2c3c35ab 100644 --- a/compiler/rautils.pas +++ b/compiler/rautils.pas @@ -789,7 +789,12 @@ Begin case sym.typ of fieldvarsym : begin - setconst(tfieldvarsym(sym).fieldoffset); + if not tabstractrecordsymtable(sym.owner).is_packed then + setconst(tfieldvarsym(sym).fieldoffset) + else if tfieldvarsym(sym).fieldoffset mod 8 = 0 then + setconst(tfieldvarsym(sym).fieldoffset div 8) + else + Message(asmr_e_packed_element); hasvar:=true; SetupVar:=true; end; @@ -863,7 +868,7 @@ Begin else begin if (harrdef.elepackedbitsize mod 8) = 0 then - SetSize(harrdef.elepackedbitsize div 8,false); + SetSize(harrdef.elepackedbitsize div 8,false) end; end; end; @@ -1338,7 +1343,12 @@ Begin fieldvarsym : with Tfieldvarsym(sym) do begin - inc(Offset,fieldoffset); + if not tabstractrecordsymtable(sym.owner).is_packed then + inc(Offset,fieldoffset) + else if tfieldvarsym(sym).fieldoffset mod 8 = 0 then + inc(Offset,fieldoffset div 8) + else + Message(asmr_e_packed_element); size:=getsize; case vardef.typ of arraydef : diff --git a/tests/webtbf/tw13563a.pp b/tests/webtbf/tw13563a.pp new file mode 100644 index 0000000000..d13ef0d63d --- /dev/null +++ b/tests/webtbf/tw13563a.pp @@ -0,0 +1,32 @@ +{ %cpu=i386 } +{ %fail } + +program bug; +type + br=bitpacked record //Note! "bitpacked" + l:0..31; + m:0..31; + h:0..63; + end; +var + +test:br; +{$asmmode att} +begin + with test do + begin + l:=4; + m:=8; + l:=$f + end; + asm + movb br.m,%al //eax should be 4,but it is 32. Eight times. error! + movb test.m,%al //eax should be 8,but it is, a strange number. error! + end; + + asm + movb $br.m/8,%al //OK, eax is 4 now, it is the right offset. + movb test+br.m/8,%al //OK, eax is 8 now, it is right, too. + end; +end. + diff --git a/tests/webtbs/tw13563.pp b/tests/webtbs/tw13563.pp new file mode 100644 index 0000000000..d080f99da2 --- /dev/null +++ b/tests/webtbs/tw13563.pp @@ -0,0 +1,48 @@ +{ %cpu=i386 } +{ %opt=-Cg- } + +program bug; +type + br=bitpacked record //Note! "bitpacked" + l:longword; + m:longword; + h:longword; + end; + +var + l, + m, + moffs, + h: longword; + +test:br; + +{$asmmode att} +begin + with test do + begin + l:=4; + m:=8; + h:=$f + end; + asm + movl br.m,%eax //eax should be 4,but it is 32. Eight times. error! + movl %eax, moffs + movl test.m,%eax //eax should be 8,but it is, a strange number. error! + movl %eax, m + movl test.l,%eax + movl %eax, l + movl test.h,%eax + movl %eax, h + end; + + if (moffs<>4) then + halt(1); + if (m<>8) then + halt(2); + if (l<>4) then + halt(3); + if (h<>$f) then + halt(4); +end. +