mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-01 20:29:24 +01:00
+ 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:
parent
0c65f27b35
commit
c7544e69de
@ -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
|
||||
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user