+ padalgingment field for recordsymtables (saved by recorddefs)

+ support for Macintosh PowerPC alignment (if the first field of a record
    or union has an alignment > 4, then the record or union size must be
    padded to a multiple of this size)
This commit is contained in:
Jonas Maebe 2004-08-17 16:29:21 +00:00
parent 0c65f27b35
commit c7544e69de
4 changed files with 106 additions and 19 deletions

View File

@ -686,7 +686,8 @@ implementation
{ startvarrec contains the start of the variant part of a record }
maxsize, startvarrecsize : longint;
usedalign,
maxalignment,startvarrecalign : byte;
maxalignment,startvarrecalign,
maxpadalign, startpadalign: shortint;
hp,pt : tnode;
vs,vs2 : tvarsym;
srsym : tsym;
@ -699,7 +700,14 @@ implementation
uniontype : ttype;
dummysymoptions : tsymoptions;
semicolonatend: boolean;
{$ifdef powerpc}
tempdef: tdef;
is_first_field: boolean;
{$endif powerpc}
begin
{$ifdef powerpc}
is_first_field := true;
{$endif powerpc}
old_current_object_option:=current_object_option;
{ all variables are public if not in a object declaration }
if not is_object then
@ -760,6 +768,36 @@ implementation
tt.def.typesym:=nil;
newtype.free;
end;
{$ifdef powerpc}
{ from gcc/gcc/config/rs6000/rs6000.h:
/* APPLE LOCAL begin Macintosh alignment 2002-1-22 ff */
/* Return the alignment of a struct based on the Macintosh PowerPC
alignment rules. In general the alignment of a struct is
determined by the greatest alignment of its elements. However, the
PowerPC rules cause the alignment of a struct to peg at word
alignment except when the first field has greater than word
(32-bit) alignment, in which case the alignment is determined by
the alignment of the first field. */
}
if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
is_record and
is_first_field and
(trecordsymtable(symtablestack).usefieldalignment = -1) then
begin
tempdef := tt.def;
while tempdef.deftype = arraydef do
tempdef := tarraydef(tempdef).elementtype.def;
if tempdef.deftype <> recorddef then
maxpadalign := tempdef.alignment
else
maxpadalign := trecorddef(tempdef).padalignment;
if (maxpadalign > 4) and
(maxpadalign > trecordsymtable(symtablestack).padalignment) then
trecordsymtable(symtablestack).padalignment := maxpadalign;
is_first_field := false;
end;
{$endif powerpc}
{ types that use init/final are not allowed in variant parts, but
classes are allowed }
if (variantrecordlevel>0) and
@ -1125,6 +1163,7 @@ implementation
begin
maxsize:=0;
maxalignment:=0;
maxpadalign:=0;
consume(_CASE);
sorg:=orgpattern;
hs:=pattern;
@ -1169,6 +1208,7 @@ implementation
registerdef:=true;
startvarrecsize:=UnionSymtable.datasize;
startvarrecalign:=UnionSymtable.fieldalignment;
startpadalign:=Unionsymtable.padalignment;
symtablestack:=UnionSymtable;
repeat
repeat
@ -1192,9 +1232,11 @@ implementation
{ calculates maximal variant size }
maxsize:=max(maxsize,unionsymtable.datasize);
maxalignment:=max(maxalignment,unionsymtable.fieldalignment);
maxpadalign:=max(maxpadalign,unionsymtable.padalignment);
{ the items of the next variant are overlayed }
unionsymtable.datasize:=startvarrecsize;
unionsymtable.fieldalignment:=startvarrecalign;
unionsymtable.padalignment:=startpadalign;
if (token<>_END) and (token<>_RKLAMMER) then
consume(_SEMICOLON)
else
@ -1207,6 +1249,15 @@ implementation
uniontype.sym:=nil;
UnionSym:=tvarsym.create('$case',vs_value,uniontype);
symtablestack:=symtablestack.next;
unionsymtable.addalignmentpadding;
{$ifdef powerpc}
{ parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
if (target_info.system in [system_powerpc_darwin, system_powerpc_macos]) and
is_first_field and
(trecordsymtable(symtablestack).usefieldalignment = -1) and
(maxpadalign > trecordsymtable(symtablestack).padalignment) then
trecordsymtable(symtablestack).padalignment:=maxpadalign;
{$endif powerpc}
{ Align the offset where the union symtable is added }
if (trecordsymtable(symtablestack).usefieldalignment=-1) then
usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
@ -1229,12 +1280,21 @@ implementation
current_object_option:=old_current_object_option;
{ free the list }
sc.free;
{$ifdef powerpc}
is_first_field := false;
{$endif powerpc}
end;
end.
{
$Log$
Revision 1.78 2004-08-15 13:30:18 florian
Revision 1.79 2004-08-17 16:29:21 jonas
+ padalgingment field for recordsymtables (saved by recorddefs)
+ support for Macintosh PowerPC alignment (if the first field of a record
or union has an alignment > 4, then the record or union size must be
padded to a multiple of this size)
Revision 1.78 2004/08/15 13:30:18 florian
* fixed alignment of variant records
* more alignment problems fixed

View File

@ -45,9 +45,9 @@ type
const
{$ifdef ansistring_bits}
CurrentPPUVersion=42;
CurrentPPUVersion=43;
{$else}
CurrentPPUVersion=42;
CurrentPPUVersion=43;
{$endif}
{ buffer sizes }
@ -1053,7 +1053,13 @@ end;
end.
{
$Log$
Revision 1.53 2004-07-12 09:14:04 jonas
Revision 1.54 2004-08-17 16:29:21 jonas
+ padalgingment field for recordsymtables (saved by recorddefs)
+ support for Macintosh PowerPC alignment (if the first field of a record
or union has an alignment > 4, then the record or union size must be
padded to a multiple of this size)
Revision 1.53 2004/07/12 09:14:04 jonas
* inline procedures at the node tree level, but only under some very
limited circumstances for now (only procedures, and only if they have
no or only vs_out/vs_var parameters).

View File

@ -244,6 +244,7 @@ interface
procedure deref;override;
function size:longint;override;
function alignment : longint;override;
function padalignment: longint;
function gettypename:string;override;
{ debug }
{$ifdef GDB}
@ -3112,8 +3113,9 @@ implementation
deftype:=recorddef;
symtable:=trecordsymtable.create(0);
trecordsymtable(symtable).datasize:=ppufile.getlongint;
trecordsymtable(symtable).fieldalignment:=ppufile.getbyte;
trecordsymtable(symtable).recordalignment:=ppufile.getbyte;
trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).ppuload(ppufile);
symtable.defowner:=self;
isunion:=false;
@ -3171,8 +3173,9 @@ implementation
begin
inherited ppuwritedef(ppufile);
ppufile.putlongint(trecordsymtable(symtable).datasize);
ppufile.putbyte(trecordsymtable(symtable).fieldalignment);
ppufile.putbyte(trecordsymtable(symtable).recordalignment);
ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
ppufile.writeentry(ibrecorddef);
trecordsymtable(symtable).ppuwrite(ppufile);
end;
@ -3190,6 +3193,11 @@ implementation
end;
function trecorddef.padalignment:longint;
begin
padalignment := trecordsymtable(symtable).padalignment;
end;
{$ifdef GDB}
function trecorddef.stabstring : pchar;
var
@ -6146,7 +6154,13 @@ implementation
end.
{
$Log$
Revision 1.251 2004-08-15 15:05:16 peter
Revision 1.252 2004-08-17 16:29:21 jonas
+ padalgingment field for recordsymtables (saved by recorddefs)
+ support for Macintosh PowerPC alignment (if the first field of a record
or union has an alignment > 4, then the record or union size must be
padded to a multiple of this size)
Revision 1.251 2004/08/15 15:05:16 peter
* fixed padding of records to alignment
Revision 1.250 2004/08/14 14:50:42 florian

View File

@ -90,7 +90,8 @@ interface
datasize : longint;
usefieldalignment, { alignment to use for fields (PACKRECORDS value), -1 is C style }
recordalignment, { alignment required when inserting this record }
fieldalignment : shortint; { alignment current alignment used when fields are inserted }
fieldalignment, { alignment current alignment used when fields are inserted }
padalignment : shortint; { size to a multiple of which the symtable has to be rounded up }
constructor create(const n:string;usealign:shortint);
procedure ppuload(ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
@ -908,6 +909,7 @@ implementation
datasize:=0;
recordalignment:=1;
usefieldalignment:=usealign;
padalignment:=1;
{ recordalign -1 means C record packing, that starts
with an alignment of 1 }
if usealign=-1 then
@ -1044,18 +1046,17 @@ implementation
procedure tabstractrecordsymtable.addalignmentpadding;
var
padalign : shortint;
begin
{ make the record size aligned correctly so it can be
used as elements in an array. For C records we
use the fieldalignment, because that is updated with the
used alignment. }
if usefieldalignment=-1 then
padalign:=fieldalignment
else
padalign:=recordalignment;
datasize:=align(datasize,padalign);
if (padalignment = 1) then
if usefieldalignment=-1 then
padalignment:=fieldalignment
else
padalignment:=recordalignment;
datasize:=align(datasize,padalignment);
end;
@ -2314,7 +2315,13 @@ implementation
end.
{
$Log$
Revision 1.154 2004-08-15 15:05:16 peter
Revision 1.155 2004-08-17 16:29:21 jonas
+ padalgingment field for recordsymtables (saved by recorddefs)
+ support for Macintosh PowerPC alignment (if the first field of a record
or union has an alignment > 4, then the record or union size must be
padded to a multiple of this size)
Revision 1.154 2004/08/15 15:05:16 peter
* fixed padding of records to alignment
Revision 1.153 2004/08/15 13:30:18 florian