mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-05 13:29:25 +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 }
|
{ 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
|
||||||
|
|
||||||
|
|||||||
@ -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).
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user