summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-02-16 16:58:25 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-02-16 16:58:25 +0000
commitb2c53da09aa0df2004c4f448bf5a59b6db5f1fee (patch)
tree84c4a773a3d25e1fbbc13b0a41b9eed815f19b26
parent3c30d45b9556df762f179e71e0b8fcb57ae4c8ab (diff)
downloadfpc-b2c53da09aa0df2004c4f448bf5a59b6db5f1fee.tar.gz
* fixed tdel1/2 tests again for AArch64/LLVM
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@44195 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/llvm/llvmdef.pas9
-rw-r--r--compiler/llvm/llvmpara.pas7
-rw-r--r--compiler/pparautl.pas3
-rw-r--r--compiler/symconst.pas21
4 files changed, 30 insertions, 10 deletions
diff --git a/compiler/llvm/llvmdef.pas b/compiler/llvm/llvmdef.pas
index 34d3d99af2..f5e995f6c6 100644
--- a/compiler/llvm/llvmdef.pas
+++ b/compiler/llvm/llvmdef.pas
@@ -742,11 +742,16 @@ implementation
register (-> paranr_result is smaller than paranr_self for that
platform in symconst) }
{$ifdef aarch64}
- if not first then
+ if not first and
+ not is_managed_type(hp.vardef) then
internalerror(2015101404);
{$endif aarch64}
if withattributes then
- if first then
+ if first
+{$ifdef aarch64}
+ and not is_managed_type(hp.vardef)
+{$endif aarch64}
+ then
encodedstr:=encodedstr+' sret noalias nocapture'
else
encodedstr:=encodedstr+' noalias nocapture';
diff --git a/compiler/llvm/llvmpara.pas b/compiler/llvm/llvmpara.pas
index 64fe80d464..44cba6426a 100644
--- a/compiler/llvm/llvmpara.pas
+++ b/compiler/llvm/llvmpara.pas
@@ -148,7 +148,12 @@ unit llvmpara;
paralocs }
while assigned(paraloc) do
begin
- if vo_is_funcret in parasym.varoptions then
+ if (vo_is_funcret in parasym.varoptions)
+ {$ifdef aarch64}
+ { see AArch64's tcpuparamanager.create_paraloc_info_intern() }
+ and not is_managed_type(parasym.vardef)
+ {$endif aarch64}
+ then
paraloc^.retvalloc:=true;
{ ordinal parameters must be passed as a single paraloc }
if (cgpara.def.typ in [orddef,enumdef,floatdef]) and
diff --git a/compiler/pparautl.pas b/compiler/pparautl.pas
index 73f4ef3e4b..b61173d50c 100644
--- a/compiler/pparautl.pas
+++ b/compiler/pparautl.pas
@@ -105,6 +105,9 @@ implementation
paranr:=paranr_result_leftright
else
{$endif}
+ if is_managed_type(pd.returndef) then
+ paranr:=paranr_result_managed
+ else
paranr:=paranr_result;
{ Generate result variable accessing function result }
vs:=cparavarsym.create('$result',paranr,vs_var,pd.returndef,[vo_is_funcret,vo_is_hidden_para]);
diff --git a/compiler/symconst.pas b/compiler/symconst.pas
index 9c91944020..08951b97ca 100644
--- a/compiler/symconst.pas
+++ b/compiler/symconst.pas
@@ -124,10 +124,10 @@ const
paranr_blockselfpara = 1;
paranr_parentfp_delphi_cc_leftright = 2;
{$if defined(aarch64) and defined(llvm)}
- { for AArch64 on LLVM, the "sret" parameter
- must always be the first -> give it a higher number; can't do it for other
- platforms, because that would change the register assignment/parameter order
- and the current one is presumably Delphi-compatible }
+ { for AArch64 on LLVM, the "sret" parameter must always be the first
+ (it gets passed in a dedicated register, so it won't shift the register
+ assignments) -> give it a lower number; can't do it for other platforms,
+ because that would change the register assignment/parameter order }
paranr_result = 2;
paranr_parentfp = 3;
paranr_self = 4;
@@ -136,12 +136,19 @@ const
paranr_self = 3;
paranr_result = 4;
{$endif}
- paranr_vmt = 5;
+ { pointers to managed result parameters must always be passed in the same way as the first regular
+ parameter, regardless of ABI conventions, because the RTL expects the two following declarations
+ to be handled in the same way:
+ function f: com_interface;
+ procedure p(out o: obj);
+ }
+ paranr_result_managed = 5;
+ paranr_vmt = 6;
{ the implicit parameters for Objective-C methods need to come
after the hidden result parameter }
- paranr_objc_self = 5;
- paranr_objc_cmd = 6;
+ paranr_objc_self = 7;
+ paranr_objc_cmd = 8;
{ Required to support variations of syscalls on Amiga-likes }
paranr_syscall_lib_first = 9; { for basefirst on MorphOS/ppc and AmigaOS4/ppc }