mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 12:29:14 +02:00
* refactored the int64 result passing in ax:bx:cx:dx to use 4 paralocs, instead of the GetNextReg hack
git-svn-id: trunk@24527 -
This commit is contained in:
parent
d98fb1f004
commit
ecb5a4866d
@ -122,8 +122,8 @@ unit cg64f32;
|
||||
|
||||
procedure splitparaloc64(const cgpara:tcgpara;var cgparalo,cgparahi:tcgpara);
|
||||
var
|
||||
paraloclo,
|
||||
paralochi : pcgparalocation;
|
||||
paraloclo,paraloclo2,
|
||||
paralochi,paralochi2 : pcgparalocation;
|
||||
begin
|
||||
if not(cgpara.size in [OS_64,OS_S64]) then
|
||||
internalerror(200408231);
|
||||
@ -143,6 +143,55 @@ unit cg64f32;
|
||||
cgparalo.intsize:=4;
|
||||
cgparalo.alignment:=cgpara.alignment;
|
||||
paraloclo:=cgparalo.add_location;
|
||||
{ 4 parameter fields? }
|
||||
if assigned(cgpara.location^.next) and assigned(cgpara.location^.next^.next) and assigned(cgpara.location^.next^.next^.next) then
|
||||
begin
|
||||
{ Order for multiple locations is always
|
||||
paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ paraloc^ -> high }
|
||||
move(cgpara.location^,paralochi^,sizeof(paralochi^));
|
||||
paralochi^.next:=nil;
|
||||
paralochi2:=cgparahi.add_location;
|
||||
move(cgpara.location^.next,paralochi2^,sizeof(paralochi2^));
|
||||
|
||||
{ paraloc^.next^.next^ -> low }
|
||||
move(cgpara.location^.next^.next^,paraloclo^,sizeof(paraloclo^));
|
||||
paraloclo^.next:=nil;
|
||||
paraloclo2:=cgparalo.add_location;
|
||||
move(cgpara.location^.next^.next^.next^,paraloclo2^,sizeof(paraloclo2^));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ paraloc^ -> low }
|
||||
move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
|
||||
paraloclo^.next:=nil;
|
||||
paraloclo2:=cgparalo.add_location;
|
||||
move(cgpara.location^.next^,paraloclo2^,sizeof(paraloclo2^));
|
||||
|
||||
{ paraloc^.next^.next -> high }
|
||||
move(cgpara.location^.next^.next^,paralochi^,sizeof(paralochi^));
|
||||
paralochi^.next:=nil;
|
||||
paralochi2:=cgparahi.add_location;
|
||||
move(cgpara.location^.next^.next^.next^,paralochi2^,sizeof(paralochi2^));
|
||||
end;
|
||||
|
||||
{ fix size }
|
||||
paraloclo^.size:=OS_16;
|
||||
paraloclo2^.size:=OS_16;
|
||||
paraloclo2^.next:=nil;
|
||||
paralochi^.size:=OS_16;
|
||||
paralochi2^.size:=OS_16;
|
||||
paralochi2^.next:=nil;
|
||||
if cgpara.size=OS_S64 then
|
||||
if target_info.endian=ENDIAN_BIG then
|
||||
paralochi^.size:=OS_S16
|
||||
else
|
||||
paraloclo2^.size:=OS_S16;
|
||||
end
|
||||
else
|
||||
{ 2 parameter fields? }
|
||||
if assigned(cgpara.location^.next) then
|
||||
begin
|
||||
@ -163,6 +212,12 @@ unit cg64f32;
|
||||
move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
|
||||
move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
|
||||
end;
|
||||
|
||||
{ fix size }
|
||||
paraloclo^.size:=cgparalo.size;
|
||||
paraloclo^.next:=nil;
|
||||
paralochi^.size:=cgparahi.size;
|
||||
paralochi^.next:=nil;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -182,12 +237,13 @@ unit cg64f32;
|
||||
inc(cgparahi.location^.reference.offset,4);
|
||||
cgparahi.alignment:=newalignment(cgparahi.alignment,4);
|
||||
end;
|
||||
|
||||
{ fix size }
|
||||
paraloclo^.size:=cgparalo.size;
|
||||
paraloclo^.next:=nil;
|
||||
paralochi^.size:=cgparahi.size;
|
||||
paralochi^.next:=nil;
|
||||
end;
|
||||
{ fix size }
|
||||
paraloclo^.size:=cgparalo.size;
|
||||
paraloclo^.next:=nil;
|
||||
paralochi^.size:=cgparahi.size;
|
||||
paralochi^.next:=nil;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -329,21 +329,39 @@ unit cpupara;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
if retcgsize in [OS_64,OS_S64] then
|
||||
begin
|
||||
{ low 32bits }
|
||||
{ bits 0..15 }
|
||||
if side=callerside then
|
||||
paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
|
||||
else
|
||||
paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
|
||||
paraloc^.size:=OS_32;
|
||||
paraloc^.size:=OS_16;
|
||||
|
||||
{ high 32bits }
|
||||
{ bits 16..31 }
|
||||
paraloc:=result.add_location;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
if side=callerside then
|
||||
paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
|
||||
else
|
||||
paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
|
||||
paraloc^.size:=OS_16;
|
||||
|
||||
{ bits 32..47 }
|
||||
paraloc:=result.add_location;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
if side=callerside then
|
||||
paraloc^.register:=NR_FUNCTION_RESULT64_HIGHER_REG
|
||||
else
|
||||
paraloc^.register:=NR_FUNCTION_RETURN64_HIGHER_REG;
|
||||
paraloc^.size:=OS_32;
|
||||
paraloc^.size:=OS_16;
|
||||
|
||||
{ bits 48..63 }
|
||||
paraloc:=result.add_location;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
if side=callerside then
|
||||
paraloc^.register:=NR_FUNCTION_RESULT64_HIGHEST_REG
|
||||
else
|
||||
paraloc^.register:=NR_FUNCTION_RETURN64_HIGHEST_REG;
|
||||
paraloc^.size:=OS_16;
|
||||
end
|
||||
else if retcgsize in [OS_32,OS_S32] then
|
||||
begin
|
||||
|
@ -1002,27 +1002,61 @@ implementation
|
||||
begin
|
||||
if not assigned(paraloc^.next) then
|
||||
internalerror(200410104);
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
{ reg->reg, alignment is irrelevant }
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reghi,4);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reglo,4);
|
||||
end
|
||||
{$ifdef cpu16bitalu}
|
||||
{ 4 paralocs? }
|
||||
if assigned(paraloc^.next) and assigned(paraloc^.next^.next) and assigned(paraloc^.next^.next^.next) then
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next^.next -> low }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
{ reg->reg, alignment is irrelevant }
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^,GetNextReg(destloc.register64.reghi),2);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^,destloc.register64.reghi,2);
|
||||
unget_para(paraloc^.next^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^.next^,GetNextReg(destloc.register64.reglo),2);
|
||||
unget_para(paraloc^.next^.next^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^.next^.next^,destloc.register64.reglo,2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next^.next -> high }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^,destloc.register64.reglo,2);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^,GetNextReg(destloc.register64.reglo),2);
|
||||
unget_para(paraloc^.next^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^.next^,destloc.register64.reghi,2);
|
||||
unget_para(paraloc^.next^.next^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_16,paraloc^.next^.next^.next^,GetNextReg(destloc.register64.reghi),2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next -> high }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reglo,4);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reghi,4);
|
||||
end;
|
||||
{$endif cpu16bitalu}
|
||||
if (target_info.endian=ENDIAN_BIG) then
|
||||
begin
|
||||
{ paraloc^ -> high
|
||||
paraloc^.next -> low }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
{ reg->reg, alignment is irrelevant }
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reghi,4);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reglo,4);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ paraloc^ -> low
|
||||
paraloc^.next -> high }
|
||||
unget_para(paraloc^);
|
||||
gen_alloc_regloc(list,destloc);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reglo,4);
|
||||
unget_para(paraloc^.next^);
|
||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reghi,4);
|
||||
end;
|
||||
end;
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
|
@ -556,16 +556,6 @@ implementation
|
||||
{$ifdef i8086}
|
||||
function GetNextReg(const r: TRegister): TRegister;
|
||||
begin
|
||||
{ HACK for returning 64-bit values in registers ax:bx:cx:dx }
|
||||
case r of
|
||||
NR_FUNCTION_RESULT64_LOW_REG: exit(NR_FUNCTION_RESULT64_HIGH_REG);
|
||||
NR_FUNCTION_RESULT64_HIGHER_REG: exit(NR_FUNCTION_RESULT64_HIGHEST_REG);
|
||||
end;
|
||||
case r of
|
||||
NR_FUNCTION_RETURN64_LOW_REG: exit(NR_FUNCTION_RETURN64_HIGH_REG);
|
||||
NR_FUNCTION_RETURN64_HIGHER_REG: exit(NR_FUNCTION_RETURN64_HIGHEST_REG);
|
||||
end;
|
||||
|
||||
if getsupreg(r)<first_int_imreg then
|
||||
internalerror(2013051401);
|
||||
result:=TRegister(longint(r)+1);
|
||||
|
Loading…
Reference in New Issue
Block a user