mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-25 23:09:26 +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);
|
procedure splitparaloc64(const cgpara:tcgpara;var cgparalo,cgparahi:tcgpara);
|
||||||
var
|
var
|
||||||
paraloclo,
|
paraloclo,paraloclo2,
|
||||||
paralochi : pcgparalocation;
|
paralochi,paralochi2 : pcgparalocation;
|
||||||
begin
|
begin
|
||||||
if not(cgpara.size in [OS_64,OS_S64]) then
|
if not(cgpara.size in [OS_64,OS_S64]) then
|
||||||
internalerror(200408231);
|
internalerror(200408231);
|
||||||
@ -143,6 +143,55 @@ unit cg64f32;
|
|||||||
cgparalo.intsize:=4;
|
cgparalo.intsize:=4;
|
||||||
cgparalo.alignment:=cgpara.alignment;
|
cgparalo.alignment:=cgpara.alignment;
|
||||||
paraloclo:=cgparalo.add_location;
|
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? }
|
{ 2 parameter fields? }
|
||||||
if assigned(cgpara.location^.next) then
|
if assigned(cgpara.location^.next) then
|
||||||
begin
|
begin
|
||||||
@ -163,6 +212,12 @@ unit cg64f32;
|
|||||||
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;
|
||||||
|
|
||||||
|
{ fix size }
|
||||||
|
paraloclo^.size:=cgparalo.size;
|
||||||
|
paraloclo^.next:=nil;
|
||||||
|
paralochi^.size:=cgparahi.size;
|
||||||
|
paralochi^.next:=nil;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -182,12 +237,13 @@ unit cg64f32;
|
|||||||
inc(cgparahi.location^.reference.offset,4);
|
inc(cgparahi.location^.reference.offset,4);
|
||||||
cgparahi.alignment:=newalignment(cgparahi.alignment,4);
|
cgparahi.alignment:=newalignment(cgparahi.alignment,4);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ fix size }
|
||||||
|
paraloclo^.size:=cgparalo.size;
|
||||||
|
paraloclo^.next:=nil;
|
||||||
|
paralochi^.size:=cgparahi.size;
|
||||||
|
paralochi^.next:=nil;
|
||||||
end;
|
end;
|
||||||
{ fix size }
|
|
||||||
paraloclo^.size:=cgparalo.size;
|
|
||||||
paraloclo^.next:=nil;
|
|
||||||
paralochi^.size:=cgparahi.size;
|
|
||||||
paralochi^.next:=nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,21 +329,39 @@ unit cpupara;
|
|||||||
paraloc^.loc:=LOC_REGISTER;
|
paraloc^.loc:=LOC_REGISTER;
|
||||||
if retcgsize in [OS_64,OS_S64] then
|
if retcgsize in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
{ low 32bits }
|
{ bits 0..15 }
|
||||||
if side=callerside then
|
if side=callerside then
|
||||||
paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
|
paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
|
||||||
else
|
else
|
||||||
paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
|
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:=result.add_location;
|
||||||
paraloc^.loc:=LOC_REGISTER;
|
paraloc^.loc:=LOC_REGISTER;
|
||||||
if side=callerside then
|
if side=callerside then
|
||||||
paraloc^.register:=NR_FUNCTION_RESULT64_HIGHER_REG
|
paraloc^.register:=NR_FUNCTION_RESULT64_HIGHER_REG
|
||||||
else
|
else
|
||||||
paraloc^.register:=NR_FUNCTION_RETURN64_HIGHER_REG;
|
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
|
end
|
||||||
else if retcgsize in [OS_32,OS_S32] then
|
else if retcgsize in [OS_32,OS_S32] then
|
||||||
begin
|
begin
|
||||||
|
@ -1002,27 +1002,61 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if not assigned(paraloc^.next) then
|
if not assigned(paraloc^.next) then
|
||||||
internalerror(200410104);
|
internalerror(200410104);
|
||||||
if (target_info.endian=ENDIAN_BIG) then
|
{$ifdef cpu16bitalu}
|
||||||
begin
|
{ 4 paralocs? }
|
||||||
{ paraloc^ -> high
|
if assigned(paraloc^.next) and assigned(paraloc^.next^.next) and assigned(paraloc^.next^.next^.next) then
|
||||||
paraloc^.next -> low }
|
if (target_info.endian=ENDIAN_BIG) then
|
||||||
unget_para(paraloc^);
|
begin
|
||||||
gen_alloc_regloc(list,destloc);
|
{ paraloc^ -> high
|
||||||
{ reg->reg, alignment is irrelevant }
|
paraloc^.next^.next -> low }
|
||||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reghi,4);
|
unget_para(paraloc^);
|
||||||
unget_para(paraloc^.next^);
|
gen_alloc_regloc(list,destloc);
|
||||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reglo,4);
|
{ reg->reg, alignment is irrelevant }
|
||||||
end
|
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
|
else
|
||||||
begin
|
{$endif cpu16bitalu}
|
||||||
{ paraloc^ -> low
|
if (target_info.endian=ENDIAN_BIG) then
|
||||||
paraloc^.next -> high }
|
begin
|
||||||
unget_para(paraloc^);
|
{ paraloc^ -> high
|
||||||
gen_alloc_regloc(list,destloc);
|
paraloc^.next -> low }
|
||||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^,destloc.register64.reglo,4);
|
unget_para(paraloc^);
|
||||||
unget_para(paraloc^.next^);
|
gen_alloc_regloc(list,destloc);
|
||||||
cg.a_load_cgparaloc_anyreg(list,OS_32,paraloc^.next^,destloc.register64.reghi,4);
|
{ reg->reg, alignment is irrelevant }
|
||||||
end;
|
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;
|
end;
|
||||||
LOC_REFERENCE:
|
LOC_REFERENCE:
|
||||||
begin
|
begin
|
||||||
|
@ -556,16 +556,6 @@ implementation
|
|||||||
{$ifdef i8086}
|
{$ifdef i8086}
|
||||||
function GetNextReg(const r: TRegister): TRegister;
|
function GetNextReg(const r: TRegister): TRegister;
|
||||||
begin
|
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
|
if getsupreg(r)<first_int_imreg then
|
||||||
internalerror(2013051401);
|
internalerror(2013051401);
|
||||||
result:=TRegister(longint(r)+1);
|
result:=TRegister(longint(r)+1);
|
||||||
|
Loading…
Reference in New Issue
Block a user