* parameter alignment fixes

This commit is contained in:
peter 2003-10-03 22:00:33 +00:00
parent 8457961ba6
commit 3a92a2a25a
12 changed files with 136 additions and 90 deletions

View File

@ -138,7 +138,7 @@ interface
{ directory where the utils can be found (options -FD) }
utilsdirectory : dirstr;
{ targetname specific prefix used by these utils (options -XP<path>) }
utilsprefix : dirstr;
utilsprefix : dirstr;
{ some flags for global compiler switches }
do_build,
@ -1513,8 +1513,6 @@ implementation
b.recordalignmin:=l
else if tok='RECORDMAX' then
b.recordalignmax:=l
else if tok='PARAALIGN' then
b.paraalign:=l
else { Error }
UpdateAlignmentStr:=false;
until false;
@ -1528,6 +1526,7 @@ implementation
var_align := used_align(siz,aktalignment.varalignmin,aktalignment.varalignmax);
end;
function const_align(siz: longint): longint;
begin
siz := size_2_align(siz);
@ -1611,7 +1610,7 @@ implementation
{ Utils directory }
utilsdirectory:='';
utilsprefix:='';
utilsprefix:='';
{ Search Paths }
librarysearchpath:=TSearchPathList.Create;
@ -1707,7 +1706,10 @@ implementation
end.
{
$Log$
Revision 1.106 2003-10-03 14:16:48 marco
Revision 1.107 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.106 2003/10/03 14:16:48 marco
* -XP<prefix> support
Revision 1.105 2003/10/02 21:16:18 peter

View File

@ -44,6 +44,7 @@ unit cpupara;
ti386paramanager = class(tparamanager)
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function get_para_align(calloption : tproccalloption):byte;override;
function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;override;
function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;override;
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
@ -141,6 +142,20 @@ unit cpupara;
end;
function ti386paramanager.get_para_align(calloption : tproccalloption):byte;
begin
if calloption=pocall_oldfpccall then
begin
if target_info.system in [system_i386_go32v2,system_i386_watcom] then
result:=2
else
result:=4;
end
else
result:=std_param_align;
end;
function ti386paramanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;
begin
case calloption of
@ -266,6 +281,7 @@ unit cpupara;
else
paraloc.size:=def_cgsize(hp.paratype.def);
paraloc.loc:=LOC_REFERENCE;
paraloc.alignment:=p.paraalign;
paraloc.reference.index:=NR_FRAME_POINTER_REG;
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
varalign:=size_2_align(l);
@ -304,6 +320,7 @@ unit cpupara;
paraloc.size:=OS_ADDR
else
paraloc.size:=def_cgsize(hp.paratype.def);
paraloc.alignment:=p.paraalign;
is_64bit:=(paraloc.size in [OS_64,OS_S64,OS_F64]);
{
EAX
@ -326,6 +343,7 @@ unit cpupara;
subreg:=R_SUBWHOLE
else
subreg:=cgsize2subreg(paraloc.size);
paraloc.alignment:=p.paraalign;
paraloc.register:=newreg(R_INTREGISTER,parasupregs[parareg],subreg);
inc(parareg);
end
@ -381,7 +399,10 @@ begin
end.
{
$Log$
Revision 1.35 2003-10-01 20:34:49 peter
Revision 1.36 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.35 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose

View File

@ -33,20 +33,36 @@ unit cpupi;
type
ti386procinfo = class(tcgprocinfo)
function calc_stackframe_size:longint;override;
end;
implementation
uses
cutils,
globals,
tgobj,
procinfo;
function ti386procinfo.calc_stackframe_size:longint;
begin
{ align to 4 bytes at least
otherwise all those subl $2,%esp are meaningless PM }
result:=Align(tg.direction*tg.lasttemp,min(aktalignment.localalignmin,4));
end;
begin
cprocinfo:=ti386procinfo;
end.
{
$Log$
Revision 1.14 2003-10-01 20:34:49 peter
Revision 1.15 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.14 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose

View File

@ -160,7 +160,7 @@ interface
procedure insert_typeconv(do_count : boolean);
procedure det_registers;
procedure firstcallparan(do_count : boolean);
procedure secondcallparan(calloption:tproccalloption;alignment:byte);virtual;abstract;
procedure secondcallparan;virtual;abstract;
function docompare(p: tnode): boolean; override;
procedure printnodetree(var t:text);override;
end;
@ -2544,7 +2544,10 @@ begin
end.
{
$Log$
Revision 1.187 2003-10-03 14:44:38 peter
Revision 1.188 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.187 2003/10/03 14:44:38 peter
* fix IE when callnode was firstpassed twice
Revision 1.186 2003/10/02 21:13:46 peter

View File

@ -37,9 +37,9 @@ interface
tempparaloc : tparalocation;
procedure allocate_tempparaloc;
procedure push_addr_para;
procedure push_value_para(calloption:tproccalloption;alignment:byte);
procedure push_value_para;
public
procedure secondcallparan(calloption:tproccalloption;alignment:byte);override;
procedure secondcallparan;override;
end;
tcgcallnode = class(tcallnode)
@ -120,10 +120,11 @@ implementation
location_release(exprasmlist,left.location);
allocate_tempparaloc;
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
inc(pushedparasize,POINTER_SIZE);
end;
procedure tcgcallparanode.push_value_para(calloption:tproccalloption;alignment:byte);
procedure tcgcallparanode.push_value_para;
var
href : treference;
{$ifdef i386}
@ -173,7 +174,7 @@ implementation
begin
if tempparaloc.loc<>LOC_REFERENCE then
internalerror(200309291);
size:=align(tfloatdef(left.resulttype.def).size,alignment);
size:=align(tfloatdef(left.resulttype.def).size,aktcallnode.procdefinition.paraalign);
inc(pushedparasize,size);
cg.g_stackpointer_alloc(exprasmlist,size);
reference_reset_base(href,NR_STACK_POINTER_REG,0);
@ -182,12 +183,12 @@ implementation
LOC_REFERENCE,
LOC_CREFERENCE :
begin
sizetopush:=align(left.resulttype.def.size,alignment);
sizetopush:=align(left.resulttype.def.size,aktcallnode.procdefinition.paraalign);
tempreference:=left.location.reference;
inc(tempreference.offset,sizetopush);
while (sizetopush>0) do
begin
if sizetopush>=4 then
if (sizetopush>=4) or (aktcallnode.procdefinition.paraalign>=4) then
begin
cgsize:=OS_32;
inc(pushedparasize,4);
@ -224,7 +225,8 @@ implementation
else
begin
{ copy the value on the stack or use normal parameter push? }
if paramanager.copy_value_on_stack(paraitem.paratyp,left.resulttype.def,calloption) then
if paramanager.copy_value_on_stack(paraitem.paratyp,left.resulttype.def,
aktcallnode.procdefinition.proccalloption) then
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
@ -234,7 +236,7 @@ implementation
if not (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
internalerror(200204241);
{ push on stack }
size:=align(left.resulttype.def.size,alignment);
size:=align(left.resulttype.def.size,aktcallnode.procdefinition.paraalign);
inc(pushedparasize,size);
cg.g_stackpointer_alloc(exprasmlist,size);
reference_reset_base(href,NR_STACK_POINTER_REG,0);
@ -278,7 +280,7 @@ implementation
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
inc(pushedparasize,alignment);
inc(pushedparasize,aktcallnode.procdefinition.paraalign);
(*
if calloption=pocall_inline then
begin
@ -323,7 +325,7 @@ implementation
procedure tcgcallparanode.secondcallparan(calloption:tproccalloption;alignment:byte);
procedure tcgcallparanode.secondcallparan;
var
otlabel,
oflabel : tasmlabel;
@ -334,8 +336,8 @@ implementation
{ push from left to right if specified }
if assigned(right) and
(calloption in pushleftright_pocalls) then
tcallparanode(right).secondcallparan(calloption,alignment);
(aktcallnode.procdefinition.proccalloption in pushleftright_pocalls) then
tcallparanode(right).secondcallparan;
otlabel:=truelabel;
oflabel:=falselabel;
@ -346,10 +348,11 @@ implementation
{ handle varargs first, because defcoll is not valid }
if (nf_varargs_para in flags) then
begin
if paramanager.push_addr_param(vs_value,left.resulttype.def,calloption) then
if paramanager.push_addr_param(vs_value,left.resulttype.def,
aktcallnode.procdefinition.proccalloption) then
push_addr_para
else
push_value_para(calloption,alignment);
push_value_para;
end
{ hidden parameters }
else if paraitem.is_hidden then
@ -358,10 +361,11 @@ implementation
by address for implicit hidden parameters }
if (vo_is_funcret in tvarsym(paraitem.parasym).varoptions) or
(not(left.resulttype.def.deftype in [pointerdef,classrefdef]) and
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
aktcallnode.procdefinition.proccalloption)) then
push_addr_para
else
push_value_para(calloption,alignment);
push_value_para;
end
{ filter array of const c styled args }
else if is_array_of_const(left.resulttype.def) and (nf_cargs in left.flags) then
@ -398,7 +402,8 @@ implementation
paraitem.is_hidden and
(left.resulttype.def.deftype in [pointerdef,classrefdef])
) and
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,
aktcallnode.procdefinition.proccalloption)) then
begin
{ Check for passing a constant to var,out parameter }
if (paraitem.paratyp in [vs_var,vs_out]) and
@ -416,7 +421,7 @@ implementation
push_addr_para;
end
else
push_value_para(calloption,alignment);
push_value_para;
end;
truelabel:=otlabel;
falselabel:=oflabel;
@ -428,8 +433,8 @@ implementation
{ push from right to left }
if assigned(right) and
not(calloption in pushleftright_pocalls) then
tcallparanode(right).secondcallparan(calloption,alignment);
not(aktcallnode.procdefinition.proccalloption in pushleftright_pocalls) then
tcallparanode(right).secondcallparan;
end;
@ -624,7 +629,6 @@ implementation
iolabel : tasmlabel;
{ help reference pointer }
href : treference;
para_alignment,
pop_size : longint;
pvreg,
vmtreg,vmtreg2 : tregister;
@ -712,12 +716,6 @@ implementation
end;
end;
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
para_alignment:=4
else
para_alignment:=aktalignment.paraalign;
regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
@ -753,7 +751,7 @@ implementation
oldaktcallnode:=aktcallnode;
aktcallnode:=self;
if assigned(left) then
tcallparanode(left).secondcallparan(procdefinition.proccalloption,procdefinition.paraalign);
tcallparanode(left).secondcallparan;
aktcallnode:=oldaktcallnode;
{ Align stack if required }
@ -1161,7 +1159,7 @@ implementation
oldaktcallnode:=aktcallnode;
aktcallnode:=self;
if assigned(left) then
tcallparanode(left).secondcallparan(procdefinition.proccalloption,0);
tcallparanode(left).secondcallparan;
aktcallnode:=oldaktcallnode;
// rg.saveotherregvars(exprasmlist,regs_to_push_other);
@ -1309,7 +1307,10 @@ begin
end.
{
$Log$
Revision 1.123 2003-10-01 20:34:48 peter
Revision 1.124 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.123 2003/10/01 20:34:48 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose

View File

@ -70,6 +70,7 @@ unit paramgr;
@param(list Current assembler list)
@param(nr Parameter number of routine, starting from 1)
}
function get_para_align(calloption : tproccalloption):byte;virtual;
function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;virtual;
function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;virtual;
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;virtual;abstract;
@ -248,6 +249,12 @@ implementation
end;
function tparamanager.get_para_align(calloption : tproccalloption):byte;
begin
result:=std_param_align;
end;
function tparamanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;
begin
result:=[];
@ -411,7 +418,10 @@ end.
{
$Log$
Revision 1.58 2003-10-01 20:34:49 peter
Revision 1.59 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.58 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose

View File

@ -967,7 +967,7 @@ begin
begin
Message1(parser_w_not_supported_for_inline,'array of const');
Message(parser_w_inlining_disabled);
pd.proccalloption:=pocall_default;
pd.set_calloption(pocall_default);
end;
end;
hp:=tparaitem(hp.next);
@ -1583,7 +1583,7 @@ const
proccalloptionStr[pd.proccalloption],
proccalloptionStr[proc_direcdata[p].pocall]);
end;
pd.proccalloption:=proc_direcdata[p].pocall;
pd.set_calloption(proc_direcdata[p].pocall);
include(pd.procoptions,po_hascallingconvention);
end;
@ -1647,7 +1647,7 @@ const
begin
{ set the default calling convention if none provided }
if not(po_hascallingconvention in pd.procoptions) then
pd.proccalloption:=aktdefproccall
pd.set_calloption(aktdefproccall)
else
begin
if pd.proccalloption=pocall_none then
@ -1670,8 +1670,6 @@ const
end;
{ check C cdecl para types }
pd.parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_c_para,nil);
{ Adjust alignment to match cdecl or stdcall }
pd.paraalign:=std_param_align;
end;
end;
pocall_cppdecl :
@ -1683,16 +1681,6 @@ const
tprocdef(pd).setmangledname(target_info.Cprefix+tprocdef(pd).cplusplusmangledname);
{ check C cdecl para types }
pd.parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_c_para,nil);
{ Adjust alignment to match cdecl or stdcall }
pd.paraalign:=std_param_align;
end;
end;
pocall_stdcall :
begin
if (pd.deftype=procdef) then
begin
{ Adjust alignment to match cdecl or stdcall }
pd.paraalign:=std_param_align;
end;
end;
pocall_compilerproc :
@ -1701,30 +1689,17 @@ const
internalerror(200110232);
tprocdef(pd).setmangledname(lower(tprocdef(pd).procsym.name));
end;
pocall_register :
begin
{ Adjust alignment to match cdecl or stdcall }
pd.paraalign:=std_param_align;
end;
pocall_far16 :
begin
{ Temporary stub, must be rewritten to support OS/2 far16 }
Message1(parser_w_proc_directive_ignored,'FAR16');
end;
pocall_palmossyscall :
begin
if (pd.deftype=procdef) then
begin
{ Adjust positions of args for cdecl or stdcall }
pd.paraalign:=std_param_align;
end;
end;
pocall_inline :
begin
if not(cs_support_inline in aktmoduleswitches) then
begin
Message(parser_e_proc_inline_not_supported);
pd.proccalloption:=pocall_default;
pd.set_calloption(pocall_default);
end;
end;
end;
@ -2151,7 +2126,10 @@ const
end.
{
$Log$
Revision 1.143 2003-10-02 21:13:09 peter
Revision 1.144 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.143 2003/10/02 21:13:09 peter
* procvar directive parsing fixes
Revision 1.142 2003/10/01 19:05:33 peter

View File

@ -199,15 +199,8 @@ implementation
function tprocinfo.calc_stackframe_size:longint;
var
_align : longint;
begin
{ align to 4 bytes at least
otherwise all those subl $2,%esp are meaningless PM }
_align:=target_info.alignment.localalignmin;
if _align<4 then
_align:=4;
result:=Align(tg.direction*tg.lasttemp,_align);
result:=Align(tg.direction*tg.lasttemp,aktalignment.localalignmin);
end;
@ -227,7 +220,10 @@ implementation
end.
{
$Log$
Revision 1.1 2003-10-01 20:34:49 peter
Revision 1.2 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.1 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose

View File

@ -440,6 +440,7 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure deref;override;
procedure releasemem;
procedure set_calloption(calloption:tproccalloption);
function concatpara(afterpara:tparaitem;const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
function insertpara(const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
procedure removepara(currpara:tparaitem);
@ -3093,7 +3094,7 @@ implementation
parast.defowner:=self;
parast.next:=owner;
para:=TLinkedList.Create;
paraalign:=aktalignment.paraalign;
paraalign:=std_param_align;
minparacount:=0;
maxparacount:=0;
proctypeoption:=potype_none;
@ -3133,6 +3134,14 @@ implementation
end;
procedure tabstractprocdef.set_calloption(calloption:tproccalloption);
begin
proccalloption:=calloption;
{ Update parameter alignment }
paraalign:=paramanager.get_para_align(proccalloption);
end;
function tabstractprocdef.concatpara(afterpara:tparaitem;const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
var
hp : TParaItem;
@ -5900,7 +5909,10 @@ implementation
end.
{
$Log$
Revision 1.169 2003-10-02 21:19:42 peter
Revision 1.170 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.169 2003/10/02 21:19:42 peter
* protected visibility fixes
Revision 1.168 2003/10/01 20:34:49 peter

View File

@ -186,7 +186,6 @@ interface
varalignmax,
localalignmin,
localalignmax,
paraalign,
recordalignmin,
recordalignmax,
maxCrecordalign : longint;
@ -489,8 +488,6 @@ begin
if (localalignmax=0) or
((s.localalignmax>0) and (s.localalignmax<localalignmax)) then
localalignmax:=s.localalignmax;
if s.paraalign>paraalign then
paraalign:=s.paraalign;
if s.recordalignmin>recordalignmin then
recordalignmin:=s.recordalignmin;
if (recordalignmax=0) or
@ -696,7 +693,10 @@ finalization
end.
{
$Log$
Revision 1.69 2003-10-02 21:17:08 peter
Revision 1.70 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.69 2003/10/02 21:17:08 peter
* use as,ld,ar instead of asw,ldw,arw for win32
Revision 1.68 2003/09/05 17:41:13 florian

View File

@ -347,7 +347,7 @@ unit cgx86;
OS_8,OS_S8,
OS_16,OS_S16:
begin
if target_info.alignment.paraalign = 2 then
if locpara.alignment = 2 then
list.concat(taicpu.op_reg(A_PUSH,S_W,rg.makeregsize(r,OS_16)))
else
list.concat(taicpu.op_reg(A_PUSH,S_L,rg.makeregsize(r,OS_32)));
@ -379,7 +379,7 @@ unit cgx86;
case size of
OS_8,OS_S8,OS_16,OS_S16:
begin
if target_info.alignment.paraalign = 2 then
if locpara.alignment = 2 then
list.concat(taicpu.op_const(A_PUSH,S_W,a))
else
list.concat(taicpu.op_const(A_PUSH,S_L,a));
@ -412,7 +412,7 @@ unit cgx86;
OS_8,OS_S8,
OS_16,OS_S16:
begin
if target_info.alignment.paraalign = 2 then
if locpara.alignment = 2 then
pushsize:=OS_16
else
pushsize:=OS_32;
@ -1601,7 +1601,10 @@ unit cgx86;
end.
{
$Log$
Revision 1.71 2003-10-03 14:45:37 peter
Revision 1.72 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.71 2003/10/03 14:45:37 peter
* save ESP after pusha and restore before popa for save all registers
Revision 1.70 2003/10/01 20:34:51 peter

View File

@ -263,6 +263,7 @@ uses
tparalocation = packed record
size : TCGSize;
loc : TCGLoc;
alignment : byte;
case TCGLoc of
LOC_REFERENCE : (reference : tparareference);
{ segment in reference at the same place as in loc_register }
@ -558,7 +559,10 @@ implementation
end.
{
$Log$
Revision 1.22 2003-10-01 20:34:51 peter
Revision 1.23 2003-10-03 22:00:33 peter
* parameter alignment fixes
Revision 1.22 2003/10/01 20:34:51 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose