* changed {$align mac68k} from an alias for {$packrecords 2} to a proper

implementation for mac68k alignment (mantis #15061)
  * changed {$align power} from an alias for {$packrecords 4} to an alias for
    {$packrecords c}, as Power alignment is the default C alignment for
    PowerPC under Mac OS X (it's close to {$packrecords 4}, but not identical)

git-svn-id: trunk@14577 -
This commit is contained in:
Jonas Maebe 2010-01-08 15:36:22 +00:00
parent 699c07ce7f
commit 9cc211e88e
7 changed files with 182 additions and 75 deletions

2
.gitattributes vendored
View File

@ -10178,6 +10178,8 @@ tests/webtbs/tw14992b.pp svneol=native#text/pascal
tests/webtbs/tw14992c.pp svneol=native#text/pascal
tests/webtbs/tw1501.pp svneol=native#text/plain
tests/webtbs/tw15015.pp svneol=native#text/plain
tests/webtbs/tw15061.pp svneol=native#text/plain
tests/webtbs/tw15061a.pp svneol=native#text/plain
tests/webtbs/tw15088.pp svneol=native#text/plain
tests/webtbs/tw15169.pp svneol=native#text/plain
tests/webtbs/tw15203.pp svneol=native#text/pascal

View File

@ -1613,6 +1613,8 @@ implementation
{ 1 byte alignment if we are bitpacked }
bit_alignment:
usedalign:=1;
mac68k_alignment:
usedalign:=2;
{ otherwise alignment at the packrecords alignment of the }
{ current record }
else

View File

@ -144,9 +144,11 @@ unit scandir;
begin
{ Support switches used in Apples Universal Interfaces}
if (hs='MAC68K') then
current_settings.packrecords:=2
current_settings.packrecords:=mac68k_alignment
{ "power" alignment is the default C packrecords setting on
Mac OS X }
else if (hs='POWER') then
current_settings.packrecords:=4
current_settings.packrecords:=C_alignment
else if (hs='RESET') then
current_settings.packrecords:=0
else

View File

@ -32,6 +32,7 @@ const
C_alignment = -1;
bit_alignment = -2;
mac68k_alignment = -3;
{ if you change one of the following contants, }
{ you have also to change the typinfo unit}

View File

@ -757,7 +757,9 @@ implementation
case usealign of
C_alignment,
bit_alignment:
fieldalignment:=1
fieldalignment:=1;
mac68k_alignment:
fieldalignment:=2;
else
fieldalignment:=usealign;
end;
@ -813,10 +815,14 @@ implementation
var
varalignrecord: shortint;
begin
if (usefieldalignment=C_alignment) then
varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign)
case usefieldalignment of
C_alignment:
varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
mac68k_alignment:
varalignrecord:=2;
else
varalignrecord:=field2recordalignment(fieldoffset,varalign);
end;
recordalignment:=max(recordalignment,varalignrecord);
end;
@ -840,7 +846,8 @@ implementation
vardef:=sym.vardef;
varalign:=vardef.alignment;
if (usefieldalignment=bit_alignment) then
case usefieldalignment of
bit_alignment:
begin
{ bitpacking only happens for ordinals, the rest is aligned at }
{ 1 byte (compatible with GPC/GCC) }
@ -878,7 +885,7 @@ implementation
exit;
end;
{ Calc the alignment size for C style records }
if (usefieldalignment=C_alignment) then
C_alignment:
begin
if (varalign>4) and
((varalign mod 4)<>0) and
@ -904,6 +911,20 @@ implementation
end;
fieldalignment:=min(fieldalignment,current_settings.alignment.maxCrecordalign);
end;
mac68k_alignment:
begin
{ mac68k alignment (C description):
* char is aligned to 1 byte
* everything else (except vector) is aligned to 2 bytes
* vector is aligned to 16 bytes
}
if l>1 then
fieldalignment:=2
else
fieldalignment:=1;
varalign:=2;
end;
end;
if varalign=0 then
varalign:=size_2_align(l);
varalignfield:=used_align(varalign,current_settings.alignment.recordalignmin,fieldalignment);
@ -934,6 +955,9 @@ implementation
{ bitpacked }
bit_alignment:
padalignment:=1;
{ mac68k: always round to multiple of 2 }
mac68k_alignment:
padalignment:=2;
{ default/no packrecords specified }
0:
padalignment:=recordalignment
@ -1062,11 +1086,13 @@ implementation
varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset,varalign);
end;
{ update alignment of this record }
if (usefieldalignment<>C_alignment) then
if (usefieldalignment<>C_alignment) and
(usefieldalignment<>mac68k_alignment) then
recordalignment:=max(recordalignment,varalignrecord);
end;
{ update alignment for C records }
if (usefieldalignment=C_alignment) then
if (usefieldalignment=C_alignment) and
(usefieldalignment<>mac68k_alignment) then
recordalignment:=max(recordalignment,unionst.recordalignment);
{ Register defs in the new record symtable }
for i:=0 to unionst.DefList.Count-1 do

37
tests/webtbs/tw15061.pp Normal file
View File

@ -0,0 +1,37 @@
{$ifdef FPC}
{$mode macpas}
{$align mac68k}
{$endif}
{$ifdef __GPC__}
{ maximum-field-alignment=16}
{$endif}
program patbug;
type
{$ifdef FPC}
PtrWord = PtrUInt;
{$endif}
pattern = record pat: array[0..7] of byte end;
patrec = record b: boolean; p: pattern end;
doublerec = record b: boolean; d: double end;
var
gPatRec: patrec;
gDoubleRec: doublerec;
begin
writeln( 'SizeOf( patrec) = ', SizeOf( patrec));
if (sizeof(patrec)<>10) then
halt(1);
writeln( 'Offset of p: pattern = ', PtrWord( @gPatRec.p) - PtrWord( @gPatRec));
if ((PtrWord( @gPatRec.p) - PtrWord( @gPatRec)) <> 2) then
halt(2);
writeln;
writeln( 'SizeOf( doublerec) = ', SizeOf( doublerec));
if (sizeof(doublerec)<>10) then
halt(3);
writeln( 'Offset of d: double = ', PtrWord( @gDoubleRec.d) - PtrWord( @gDoubleRec));
if ((PtrWord( @gDoubleRec.d) - PtrWord( @gDoubleRec))<>2) then
halt(4);
writeln;
end.

37
tests/webtbs/tw15061a.pp Normal file
View File

@ -0,0 +1,37 @@
{$ifdef FPC}
{$mode macpas}
{$align power}
{$endif}
{$ifdef __GPC__}
{ maximum-field-alignment=16}
{$endif}
program patbug;
type
{$ifdef FPC}
PtrWord = PtrUInt;
{$endif}
pattern = record pat: array[0..7] of byte end;
patrec = record b: boolean; p: pattern end;
doublerec = record b: boolean; d: double end;
var
gPatRec: patrec;
gDoubleRec: doublerec;
begin
writeln( 'SizeOf( patrec) = ', SizeOf( patrec));
if (sizeof(patrec)<>9) then
halt(1);
writeln( 'Offset of p: pattern = ', PtrWord( @gPatRec.p) - PtrWord( @gPatRec));
if ((PtrWord( @gPatRec.p) - PtrWord( @gPatRec)) <> 1) then
halt(2);
writeln;
writeln( 'SizeOf( doublerec) = ', SizeOf( doublerec));
if (sizeof(doublerec)<>12) then
halt(3);
writeln( 'Offset of d: double = ', PtrWord( @gDoubleRec.d) - PtrWord( @gDoubleRec));
if ((PtrWord( @gDoubleRec.d) - PtrWord( @gDoubleRec))<>4) then
halt(4);
writeln;
end.