diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-05-19 12:50:15 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-05-19 12:50:15 +0000 |
commit | c108d6b953e0a4f00a86207307f1ccd4ce3517e0 (patch) | |
tree | e3a9a92a00feb97b6f1605e55d2c0453f3078614 /compiler/cg64f32.pas | |
parent | c0fd601108d4a15fe86d9653d87ca646ce207e75 (diff) | |
download | fpc-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.pas | 70 |
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; |