summaryrefslogtreecommitdiff
path: root/compiler/cg64f32.pas
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-05-19 12:50:15 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-05-19 12:50:15 +0000
commitc108d6b953e0a4f00a86207307f1ccd4ce3517e0 (patch)
treee3a9a92a00feb97b6f1605e55d2c0453f3078614 /compiler/cg64f32.pas
parentc0fd601108d4a15fe86d9653d87ca646ce207e75 (diff)
downloadfpc-c108d6b953e0a4f00a86207307f1ccd4ce3517e0.tar.gz
* refactored the int64 result passing in ax:bx:cx:dx to use 4 paralocs, instead of the GetNextReg hack
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@24527 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/cg64f32.pas')
-rw-r--r--compiler/cg64f32.pas70
1 files changed, 63 insertions, 7 deletions
diff --git a/compiler/cg64f32.pas b/compiler/cg64f32.pas
index e5624c6ca5..028cf8d2c6 100644
--- a/compiler/cg64f32.pas
+++ b/compiler/cg64f32.pas
@@ -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;