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