mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 14:19:28 +02:00
* fix passing of 64bit values when using -Or
This commit is contained in:
parent
2ec108a9c7
commit
dd0664156d
@ -135,15 +135,20 @@ unit cg64f32;
|
||||
{ 2 parameter fields? }
|
||||
if assigned(cgpara.location^.next) then
|
||||
begin
|
||||
if target_info.endian = endian_big then
|
||||
{ Order for multiple locations is always
|
||||
paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ low is in second location }
|
||||
move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
move(cgpara.location^,paralochi^,sizeof(paralochi^));
|
||||
move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ low is in first location }
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next -> high }
|
||||
move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
|
||||
move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
|
||||
end;
|
||||
@ -157,9 +162,9 @@ unit cg64f32;
|
||||
move(cgpara.location^,paralochi^,sizeof(paralochi^));
|
||||
{ for big endian low is at +4, for little endian high }
|
||||
if target_info.endian = endian_big then
|
||||
inc(cgparalo.location^.reference.offset,tcgsize2size[cgparahi.size])
|
||||
inc(cgparalo.location^.reference.offset,4)
|
||||
else
|
||||
inc(cgparahi.location^.reference.offset,tcgsize2size[cgparalo.size]);
|
||||
inc(cgparahi.location^.reference.offset,4);
|
||||
end;
|
||||
{ fix size }
|
||||
paraloclo^.size:=cgparalo.size;
|
||||
@ -488,6 +493,8 @@ unit cg64f32;
|
||||
tmploclo.init;
|
||||
tmplochi.init;
|
||||
splitparaloc64(paraloc,tmploclo,tmplochi);
|
||||
{ Keep this order of first hi before lo to have
|
||||
the correct push order for i386 }
|
||||
cg.a_param_reg(list,OS_32,reg.reghi,tmplochi);
|
||||
cg.a_param_reg(list,OS_32,reg.reglo,tmploclo);
|
||||
tmploclo.done;
|
||||
@ -502,6 +509,8 @@ unit cg64f32;
|
||||
tmploclo.init;
|
||||
tmplochi.init;
|
||||
splitparaloc64(paraloc,tmploclo,tmplochi);
|
||||
{ Keep this order of first hi before lo to have
|
||||
the correct push order for i386 }
|
||||
cg.a_param_const(list,OS_32,aint(hi(value)),tmplochi);
|
||||
cg.a_param_const(list,OS_32,aint(lo(value)),tmploclo);
|
||||
tmploclo.done;
|
||||
@ -523,6 +532,8 @@ unit cg64f32;
|
||||
inc(tmpreflo.offset,4)
|
||||
else
|
||||
inc(tmprefhi.offset,4);
|
||||
{ Keep this order of first hi before lo to have
|
||||
the correct push order for i386 }
|
||||
cg.a_param_ref(list,OS_32,tmprefhi,tmplochi);
|
||||
cg.a_param_ref(list,OS_32,tmpreflo,tmploclo);
|
||||
tmploclo.done;
|
||||
@ -781,7 +792,10 @@ unit cg64f32;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.69 2005-02-14 17:13:06 peter
|
||||
Revision 1.70 2005-02-15 19:16:04 peter
|
||||
* fix passing of 64bit values when using -Or
|
||||
|
||||
Revision 1.69 2005/02/14 17:13:06 peter
|
||||
* truncate log
|
||||
|
||||
Revision 1.68 2005/02/13 18:55:19 florian
|
||||
|
@ -399,6 +399,8 @@ unit cpupara;
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if side=calleeside then
|
||||
inc(paraloc^.reference.offset,target_info.first_parm_offset);
|
||||
parasize:=align(parasize+paralen,varalign);
|
||||
end
|
||||
else
|
||||
@ -421,41 +423,13 @@ unit cpupara;
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if side=calleeside then
|
||||
inc(paraloc^.reference.offset,target_info.first_parm_offset);
|
||||
parasize:=align(parasize+l,varalign);
|
||||
dec(paralen,l);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ Adapt offsets for left-to-right calling }
|
||||
if p.proccalloption in pushleftright_pocalls then
|
||||
begin
|
||||
for i:=0 to paras.count-1 do
|
||||
begin
|
||||
hp:=tparavarsym(paras[i]);
|
||||
l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
l:=align(l,varalign);
|
||||
with hp.paraloc[side].location^ do
|
||||
begin
|
||||
reference.offset:=parasize-reference.offset-l;
|
||||
if side=calleeside then
|
||||
inc(reference.offset,target_info.first_parm_offset);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ Only need to adapt the callee side to include the
|
||||
standard stackframe size }
|
||||
if side=calleeside then
|
||||
begin
|
||||
for i:=0 to paras.count-1 do
|
||||
begin
|
||||
hp:=tparavarsym(paras[i]);
|
||||
inc(hp.paraloc[side].location^.reference.offset,target_info.first_parm_offset);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -529,6 +503,8 @@ unit cpupara;
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if side=calleeside then
|
||||
inc(paraloc^.reference.offset,target_info.first_parm_offset);
|
||||
parasize:=align(parasize+paralen,varalign);
|
||||
end
|
||||
else
|
||||
@ -551,30 +527,14 @@ unit cpupara;
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if side=calleeside then
|
||||
inc(paraloc^.reference.offset,target_info.first_parm_offset);
|
||||
parasize:=align(parasize+l,varalign);
|
||||
dec(paralen,l);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ Register parameters are assigned from left-to-right, adapt offset
|
||||
for calleeside to be reversed }
|
||||
for i:=0 to paras.count-1 do
|
||||
begin
|
||||
hp:=tparavarsym(paras[i]);
|
||||
with hp.paraloc[side].location^ do
|
||||
begin
|
||||
if (loc=LOC_REFERENCE) then
|
||||
begin
|
||||
l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
l:=align(l,varalign);
|
||||
reference.offset:=parasize-reference.offset-l;
|
||||
if side=calleeside then
|
||||
inc(reference.offset,target_info.first_parm_offset);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -639,7 +599,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.67 2005-02-14 19:42:02 peter
|
||||
Revision 1.68 2005-02-15 19:16:04 peter
|
||||
* fix passing of 64bit values when using -Or
|
||||
|
||||
Revision 1.67 2005/02/14 19:42:02 peter
|
||||
win32 stdcall fixes needed for tw3650
|
||||
|
||||
Revision 1.66 2005/02/14 17:13:09 peter
|
||||
|
@ -1332,13 +1332,15 @@ implementation
|
||||
|
||||
var
|
||||
i : longint;
|
||||
sizeleft : aint;
|
||||
currpara : tparavarsym;
|
||||
paraloc : pcgparalocation;
|
||||
paraloc : pcgparalocation;
|
||||
hreflo,
|
||||
hrefhi,
|
||||
href : treference;
|
||||
{$ifdef sparc}
|
||||
tempref,
|
||||
sizeleft : aint;
|
||||
tempref : treference;
|
||||
{$endif sparc}
|
||||
href : treference;
|
||||
begin
|
||||
if (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
exit;
|
||||
@ -1348,7 +1350,6 @@ implementation
|
||||
begin
|
||||
currpara:=tparavarsym(current_procinfo.procdef.paras[i]);
|
||||
paraloc:=currpara.paraloc[calleeside].location;
|
||||
sizeleft:=currpara.paraloc[calleeside].intsize;
|
||||
while assigned(paraloc) do
|
||||
begin
|
||||
if paraloc^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER] then
|
||||
@ -1365,7 +1366,6 @@ implementation
|
||||
{ skip e.g. empty records }
|
||||
if (paraloc^.loc = LOC_VOID) then
|
||||
continue;
|
||||
sizeleft:=currpara.paraloc[calleeside].intsize;
|
||||
if not assigned(paraloc) then
|
||||
internalerror(200408203);
|
||||
case currpara.localloc.loc of
|
||||
@ -1376,80 +1376,59 @@ implementation
|
||||
if not paramanager.param_use_paraloc(currpara.paraloc[calleeside]) then
|
||||
begin
|
||||
href:=currpara.localloc.reference;
|
||||
while assigned(paraloc) do
|
||||
if (currpara.paraloc[calleeside].is_single_reference(paraloc)) then
|
||||
begin
|
||||
unget_para(paraloc^);
|
||||
if (currpara.paraloc[calleeside].is_single_reference(paraloc)) then
|
||||
begin
|
||||
gen_load_ref(paraloc^,href,sizeleft);
|
||||
{ May be needed later, when we add support for }
|
||||
{ passing the same parameter in multiple locations }
|
||||
{ Currently, is_single_reference returns only true }
|
||||
{ if paraloc^.next = nil (JM) }
|
||||
inc(href.offset,sizeleft);
|
||||
sizeleft := 0;
|
||||
end
|
||||
else
|
||||
gen_load_ref(paraloc^,href,currpara.paraloc[calleeside].intsize);
|
||||
end
|
||||
else
|
||||
begin
|
||||
while assigned(paraloc) do
|
||||
begin
|
||||
unget_para(paraloc^);
|
||||
if (paraloc^.size = OS_NO) then
|
||||
internalerror(2005013010);
|
||||
gen_load_ref(paraloc^,href,tcgsize2size[paraloc^.size]);
|
||||
inc(href.offset,TCGSize2Size[paraloc^.size]);
|
||||
dec(sizeleft,TCGSize2Size[paraloc^.size]);
|
||||
paraloc:=paraloc^.next;
|
||||
end;
|
||||
paraloc:=paraloc^.next;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bit}
|
||||
if currpara.localloc.size in [OS_64,OS_S64] then
|
||||
if (currpara.paraloc[calleeside].size in [OS_64,OS_S64]) and
|
||||
is_64bit(currpara.vartype.def) then
|
||||
begin
|
||||
{ Special case for single location 64bit LOC_REFERENCE parameter }
|
||||
if paraloc^.size in [OS_64,OS_S64] then
|
||||
if not assigned(paraloc^.next) then
|
||||
internalerror(200410104);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
if paraloc^.loc<>LOC_REFERENCE then
|
||||
internalerror(200412031);
|
||||
reference_reset_base(href,paraloc^.reference.index,paraloc^.reference.offset);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
cg.a_load_ref_reg(list,OS_32,OS_32,href,currpara.localloc.register64.reghi);
|
||||
inc(href.offset,4);
|
||||
cg.a_load_ref_reg(list,OS_32,OS_32,href,currpara.localloc.register64.reglo);
|
||||
end
|
||||
else
|
||||
begin
|
||||
cg.a_load_ref_reg(list,OS_32,OS_32,href,currpara.localloc.register64.reglo);
|
||||
inc(href.offset,4);
|
||||
cg.a_load_ref_reg(list,OS_32,OS_32,href,currpara.localloc.register64.reghi);
|
||||
end;
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
unget_para(paraloc^);
|
||||
gen_load_reg(paraloc^,currpara.localloc.register64.reghi);
|
||||
unget_para(paraloc^.next^);
|
||||
gen_load_reg(paraloc^.next^,currpara.localloc.register64.reglo);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ First 32bits }
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next -> high }
|
||||
unget_para(paraloc^);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
gen_load_reg(paraloc^,currpara.localloc.register64.reghi)
|
||||
else
|
||||
gen_load_reg(paraloc^,currpara.localloc.register64.reglo);
|
||||
{ Second 32bits }
|
||||
if not assigned(paraloc^.next) then
|
||||
internalerror(200410104);
|
||||
gen_load_reg(paraloc^,currpara.localloc.register64.reglo);
|
||||
unget_para(paraloc^.next^);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
gen_load_reg(paraloc^.next^,currpara.localloc.register64.reglo)
|
||||
else
|
||||
gen_load_reg(paraloc^.next^,currpara.localloc.register64.reghi);
|
||||
gen_load_reg(paraloc^.next^,currpara.localloc.register64.reghi);
|
||||
end;
|
||||
end
|
||||
else
|
||||
{$endif cpu64bit}
|
||||
begin
|
||||
unget_para(paraloc^);
|
||||
gen_load_reg(paraloc^,currpara.localloc.register);
|
||||
if assigned(paraloc^.next) then
|
||||
internalerror(200410105);
|
||||
unget_para(paraloc^);
|
||||
gen_load_reg(paraloc^,currpara.localloc.register);
|
||||
end;
|
||||
end;
|
||||
LOC_CFPUREGISTER :
|
||||
@ -2422,7 +2401,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.260 2005-02-14 17:13:06 peter
|
||||
Revision 1.261 2005-02-15 19:16:04 peter
|
||||
* fix passing of 64bit values when using -Or
|
||||
|
||||
Revision 1.260 2005/02/14 17:13:06 peter
|
||||
* truncate log
|
||||
|
||||
Revision 1.259 2005/01/30 21:51:57 jonas
|
||||
|
Loading…
Reference in New Issue
Block a user