2
0
Эх сурвалжийг харах

* fixed tdel1/2 tests again for AArch64/LLVM

git-svn-id: trunk@44195 -
Jonas Maebe 5 жил өмнө
parent
commit
3188dc18d4

+ 7 - 2
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';

+ 6 - 1
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

+ 3 - 0
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]);

+ 14 - 7
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 }