[arm] Fix the passing of structs with 8 byte alignment with llvm on armeabi, they...
authorZoltan Varga <vargaz@gmail.com>
Wed, 22 Feb 2017 20:06:08 +0000 (15:06 -0500)
committerZoltan Varga <vargaz@gmail.com>
Wed, 22 Feb 2017 20:08:41 +0000 (15:08 -0500)
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/mini-llvm.c
mono/mini/mini.h

index 42715480b0005e5969b924da1773fd3b46488759..f85644d42ca6d5446732a7427bb27e48b48d9177 100644 (file)
@@ -1515,6 +1515,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
                        nwords = (align_size + sizeof (gpointer) -1 ) / sizeof (gpointer);
                        ainfo->storage = RegTypeStructByVal;
                        ainfo->struct_size = size;
+                       ainfo->align = align;
                        /* FIXME: align stack_size if needed */
                        if (eabi_supported) {
                                if (align >= 8 && (gr & 1))
@@ -2166,7 +2167,16 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                        break;
                case RegTypeStructByVal:
                        lainfo->storage = LLVMArgAsIArgs;
-                       lainfo->nslots = ainfo->struct_size / sizeof (gpointer);
+                       if (eabi_supported && ainfo->align == 8) {
+                               /* LLVM models this by passing an int64 array */
+                               lainfo->nslots = ALIGN_TO (ainfo->struct_size, 8) / 8;
+                               lainfo->esize = 8;
+                       } else {
+                               lainfo->nslots = ainfo->struct_size / sizeof (gpointer);
+                               lainfo->esize = 4;
+                       }
+
+                       printf ("D: %d\n", ainfo->align);
                        break;
                case RegTypeStructByAddr:
                case RegTypeStructByAddrOnStack:
index 28678638b6c0e46c3592214e34b8093e399f4d39..31194f2e60d596b17facb97b744e482f3abb3864 100644 (file)
@@ -208,7 +208,7 @@ typedef struct {
        guint8  reg;
        ArgStorage  storage;
        /* RegTypeStructByVal */
-       gint32  struct_size;
+       gint32  struct_size, align;
        guint8  size    : 4; /* 1, 2, 4, 8, or regs used by RegTypeStructByVal */
 } ArgInfo;
 
index 563607f8c0fbeb4b48eba4b4103a1c94729623ff..745c29f13e48c77af959d7d831544421eda14bcf 100644 (file)
@@ -1431,7 +1431,10 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
                        pindex ++;
                        break;
                case LLVMArgAsIArgs:
-                       param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
+                       if (ainfo->esize == 8)
+                               param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
+                       else
+                               param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
                        pindex ++;
                        break;
                case LLVMArgVtypeByRef:
@@ -3490,7 +3493,10 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                }
                case LLVMArgAsIArgs:
                        g_assert (addresses [reg]);
-                       args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
+                       if (ainfo->esize == 8)
+                               args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
+                       else
+                               args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
                        break;
                case LLVMArgVtypeAsScalar:
                        g_assert_not_reached ();
index 25316da324509d1984de2a2657e722de94d32897..d8e9f9ca547311b597c6fa42f6a1e599a26ec0b4 100644 (file)
@@ -826,7 +826,7 @@ typedef struct {
         * in the structure.
         */
        int nslots;
-       /* Only if storage == LLVMArgAsFpArgs/LLVMArgFpStruct (4/8) */
+       /* Only if storage == LLVMArgAsIArgs/LLVMArgAsFpArgs/LLVMArgFpStruct (4/8) */
        int esize;
        /* Parameter index in the LLVM signature */
        int pindex;