summaryrefslogtreecommitdiff
path: root/compiler/ncgutil.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/ncgutil.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/ncgutil.pas')
-rw-r--r--compiler/ncgutil.pas74
1 files changed, 54 insertions, 20 deletions
diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas
index 52c6849df7..80582f29ea 100644
--- a/compiler/ncgutil.pas
+++ b/compiler/ncgutil.pas
@@ -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