* fix passing of 64bit values when using -Or

This commit is contained in:
peter 2005-02-15 19:16:04 +00:00
parent 2ec108a9c7
commit dd0664156d
3 changed files with 68 additions and 109 deletions

View File

@ -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

View File

@ -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

View File

@ -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