+ 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 } { startvarrec contains the start of the variant part of a record }
maxsize, startvarrecsize : longint; maxsize, startvarrecsize : longint;
usedalign, usedalign,
maxalignment,startvarrecalign : byte; maxalignment,startvarrecalign,
maxpadalign, startpadalign: shortint;
hp,pt : tnode; hp,pt : tnode;
vs,vs2 : tvarsym; vs,vs2 : tvarsym;
srsym : tsym; srsym : tsym;
@ -699,7 +700,14 @@ implementation
uniontype : ttype; uniontype : ttype;
dummysymoptions : tsymoptions; dummysymoptions : tsymoptions;
semicolonatend: boolean; semicolonatend: boolean;
{$ifdef powerpc}
tempdef: tdef;
is_first_field: boolean;
{$endif powerpc}
begin begin
{$ifdef powerpc}
is_first_field := true;
{$endif powerpc}
old_current_object_option:=current_object_option; old_current_object_option:=current_object_option;
{ all variables are public if not in a object declaration } { all variables are public if not in a object declaration }
if not is_object then if not is_object then
@ -760,6 +768,36 @@ implementation
tt.def.typesym:=nil; tt.def.typesym:=nil;
newtype.free; newtype.free;
end; 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 { types that use init/final are not allowed in variant parts, but
classes are allowed } classes are allowed }
if (variantrecordlevel>0) and if (variantrecordlevel>0) and
@ -1125,6 +1163,7 @@ implementation
begin begin
maxsize:=0; maxsize:=0;
maxalignment:=0; maxalignment:=0;
maxpadalign:=0;
consume(_CASE); consume(_CASE);
sorg:=orgpattern; sorg:=orgpattern;
hs:=pattern; hs:=pattern;
@ -1169,6 +1208,7 @@ implementation
registerdef:=true; registerdef:=true;
startvarrecsize:=UnionSymtable.datasize; startvarrecsize:=UnionSymtable.datasize;
startvarrecalign:=UnionSymtable.fieldalignment; startvarrecalign:=UnionSymtable.fieldalignment;
startpadalign:=Unionsymtable.padalignment;
symtablestack:=UnionSymtable; symtablestack:=UnionSymtable;
repeat repeat
repeat repeat
@ -1192,9 +1232,11 @@ implementation
{ calculates maximal variant size } { calculates maximal variant size }
maxsize:=max(maxsize,unionsymtable.datasize); maxsize:=max(maxsize,unionsymtable.datasize);
maxalignment:=max(maxalignment,unionsymtable.fieldalignment); maxalignment:=max(maxalignment,unionsymtable.fieldalignment);
maxpadalign:=max(maxpadalign,unionsymtable.padalignment);
{ the items of the next variant are overlayed } { the items of the next variant are overlayed }
unionsymtable.datasize:=startvarrecsize; unionsymtable.datasize:=startvarrecsize;
unionsymtable.fieldalignment:=startvarrecalign; unionsymtable.fieldalignment:=startvarrecalign;
unionsymtable.padalignment:=startpadalign;
if (token<>_END) and (token<>_RKLAMMER) then if (token<>_END) and (token<>_RKLAMMER) then
consume(_SEMICOLON) consume(_SEMICOLON)
else else
@ -1207,6 +1249,15 @@ implementation
uniontype.sym:=nil; uniontype.sym:=nil;
UnionSym:=tvarsym.create('$case',vs_value,uniontype); UnionSym:=tvarsym.create('$case',vs_value,uniontype);
symtablestack:=symtablestack.next; 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 } { Align the offset where the union symtable is added }
if (trecordsymtable(symtablestack).usefieldalignment=-1) then if (trecordsymtable(symtablestack).usefieldalignment=-1) then
usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign) usedalign:=used_align(unionsymtable.recordalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
@ -1229,12 +1280,21 @@ implementation
current_object_option:=old_current_object_option; current_object_option:=old_current_object_option;
{ free the list } { free the list }
sc.free; sc.free;
{$ifdef powerpc}
is_first_field := false;
{$endif powerpc}
end; end;
end. end.
{ {
$Log$ $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 * fixed alignment of variant records
* more alignment problems fixed * more alignment problems fixed

View File

@ -45,9 +45,9 @@ type
const const
{$ifdef ansistring_bits} {$ifdef ansistring_bits}
CurrentPPUVersion=42; CurrentPPUVersion=43;
{$else} {$else}
CurrentPPUVersion=42; CurrentPPUVersion=43;
{$endif} {$endif}
{ buffer sizes } { buffer sizes }
@ -1053,7 +1053,13 @@ end;
end. end.
{ {
$Log$ $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 * inline procedures at the node tree level, but only under some very
limited circumstances for now (only procedures, and only if they have limited circumstances for now (only procedures, and only if they have
no or only vs_out/vs_var parameters). no or only vs_out/vs_var parameters).

View File

@ -244,6 +244,7 @@ interface
procedure deref;override; procedure deref;override;
function size:longint;override; function size:longint;override;
function alignment : longint;override; function alignment : longint;override;
function padalignment: longint;
function gettypename:string;override; function gettypename:string;override;
{ debug } { debug }
{$ifdef GDB} {$ifdef GDB}
@ -3112,8 +3113,9 @@ implementation
deftype:=recorddef; deftype:=recorddef;
symtable:=trecordsymtable.create(0); symtable:=trecordsymtable.create(0);
trecordsymtable(symtable).datasize:=ppufile.getlongint; trecordsymtable(symtable).datasize:=ppufile.getlongint;
trecordsymtable(symtable).fieldalignment:=ppufile.getbyte; trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).recordalignment:=ppufile.getbyte; trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).ppuload(ppufile); trecordsymtable(symtable).ppuload(ppufile);
symtable.defowner:=self; symtable.defowner:=self;
isunion:=false; isunion:=false;
@ -3171,8 +3173,9 @@ implementation
begin begin
inherited ppuwritedef(ppufile); inherited ppuwritedef(ppufile);
ppufile.putlongint(trecordsymtable(symtable).datasize); ppufile.putlongint(trecordsymtable(symtable).datasize);
ppufile.putbyte(trecordsymtable(symtable).fieldalignment); ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
ppufile.putbyte(trecordsymtable(symtable).recordalignment); ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
ppufile.writeentry(ibrecorddef); ppufile.writeentry(ibrecorddef);
trecordsymtable(symtable).ppuwrite(ppufile); trecordsymtable(symtable).ppuwrite(ppufile);
end; end;
@ -3190,6 +3193,11 @@ implementation
end; end;
function trecorddef.padalignment:longint;
begin
padalignment := trecordsymtable(symtable).padalignment;
end;
{$ifdef GDB} {$ifdef GDB}
function trecorddef.stabstring : pchar; function trecorddef.stabstring : pchar;
var var
@ -6146,7 +6154,13 @@ implementation
end. end.
{ {
$Log$ $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 * fixed padding of records to alignment
Revision 1.250 2004/08/14 14:50:42 florian Revision 1.250 2004/08/14 14:50:42 florian

View File

@ -90,7 +90,8 @@ interface
datasize : longint; datasize : longint;
usefieldalignment, { alignment to use for fields (PACKRECORDS value), -1 is C style } usefieldalignment, { alignment to use for fields (PACKRECORDS value), -1 is C style }
recordalignment, { alignment required when inserting this record } 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); constructor create(const n:string;usealign:shortint);
procedure ppuload(ppufile:tcompilerppufile);override; procedure ppuload(ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
@ -908,6 +909,7 @@ implementation
datasize:=0; datasize:=0;
recordalignment:=1; recordalignment:=1;
usefieldalignment:=usealign; usefieldalignment:=usealign;
padalignment:=1;
{ recordalign -1 means C record packing, that starts { recordalign -1 means C record packing, that starts
with an alignment of 1 } with an alignment of 1 }
if usealign=-1 then if usealign=-1 then
@ -1044,18 +1046,17 @@ implementation
procedure tabstractrecordsymtable.addalignmentpadding; procedure tabstractrecordsymtable.addalignmentpadding;
var
padalign : shortint;
begin begin
{ make the record size aligned correctly so it can be { make the record size aligned correctly so it can be
used as elements in an array. For C records we used as elements in an array. For C records we
use the fieldalignment, because that is updated with the use the fieldalignment, because that is updated with the
used alignment. } used alignment. }
if (padalignment = 1) then
if usefieldalignment=-1 then if usefieldalignment=-1 then
padalign:=fieldalignment padalignment:=fieldalignment
else else
padalign:=recordalignment; padalignment:=recordalignment;
datasize:=align(datasize,padalign); datasize:=align(datasize,padalignment);
end; end;
@ -2314,7 +2315,13 @@ implementation
end. end.
{ {
$Log$ $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 * fixed padding of records to alignment
Revision 1.153 2004/08/15 13:30:18 florian Revision 1.153 2004/08/15 13:30:18 florian