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/ncgutil.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/ncgutil.pas')
-rw-r--r-- | compiler/ncgutil.pas | 74 |
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 |