diff options
author | Anthony Green <green@gmachine.(none)> | 2009-12-24 00:22:00 -0500 |
---|---|---|
committer | Anthony Green <green@gmachine.(none)> | 2009-12-24 00:22:00 -0500 |
commit | 115ab36fceee69740a01ce49bc27e1908cc237b1 (patch) | |
tree | df2028286cbb876ce100438411cb7cdb4a9527c7 /src/x86 | |
parent | f8c7a245bf5a80bd7e730ec03fcad17c8dcfcb07 (diff) | |
download | libffi-115ab36fceee69740a01ce49bc27e1908cc237b1.tar.gz |
Update missing changes for 3.0.9r4.
Diffstat (limited to 'src/x86')
-rw-r--r-- | src/x86/.svn/entries | 42 | ||||
-rw-r--r-- | src/x86/.svn/text-base/ffi64.c.svn-base | 88 | ||||
-rw-r--r-- | src/x86/ffi64.c | 88 |
3 files changed, 163 insertions, 55 deletions
diff --git a/src/x86/.svn/entries b/src/x86/.svn/entries index d4f129e..8a09cfe 100644 --- a/src/x86/.svn/entries +++ b/src/x86/.svn/entries @@ -1,15 +1,15 @@ 10 dir -152280 -svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/x86 -svn://gcc.gnu.org/svn/gcc +155449 +svn+ssh://green@gcc.gnu.org/svn/gcc/trunk/libffi/src/x86 +svn+ssh://green@gcc.gnu.org/svn/gcc -2009-09-28T22:26:25.100883Z -152256 -ktietz +2009-12-04T18:41:59.918480Z +154988 +uros @@ -32,7 +32,7 @@ file -2009-06-10T05:25:01.000000Z +2009-12-20T06:01:54.810555Z 241e0adeeeba9eb067412930a0229857 2009-06-04T15:43:03.499507Z 148172 @@ -66,11 +66,11 @@ file -2009-06-20T15:53:35.000000Z -4baf2cbce15603b292a1a20b70ae2e74 -2009-06-12T15:57:58.721771Z -148433 -aph +2009-12-20T06:01:54.810555Z +df9e516483d1f4778090c834c5151527 +2009-12-04T18:41:59.918480Z +154988 +uros @@ -92,7 +92,7 @@ aph -16173 +17340 ffitarget.h file @@ -100,7 +100,7 @@ file -2009-06-20T15:53:35.000000Z +2009-12-20T06:01:54.811555Z 5c6748898b1e0857b71f73ba95e2bdab 2009-06-12T15:57:58.721771Z 148433 @@ -134,7 +134,7 @@ file -2009-09-10T17:50:58.000000Z +2009-12-20T06:01:54.812555Z 16c9cbaa5aa2ba0ce316655706880b22 2009-07-24T10:12:16.542948Z 150042 @@ -168,7 +168,7 @@ file -2009-06-10T05:25:01.000000Z +2009-12-20T06:01:54.812555Z e988aa92b714d72199c40b30edcaff89 2009-06-04T15:11:12.475454Z 148171 @@ -202,7 +202,7 @@ file -2009-09-27T03:30:27.000000Z +2009-12-20T06:01:54.813555Z 7a2064a18fae63fbf5b6ca3744372eb5 2009-09-17T20:54:56.860605Z 151819 @@ -236,7 +236,7 @@ file -2009-06-10T05:25:01.000000Z +2009-12-20T06:01:54.813555Z c105ec7c2660ce57770538edd675ff47 2009-06-04T15:43:03.499507Z 148172 @@ -270,7 +270,7 @@ file -2009-09-29T17:13:25.000000Z +2009-12-20T06:01:54.814555Z f8570e3f12f1eef57ed2bb940d829a22 2009-09-28T22:26:25.100883Z 152256 @@ -304,7 +304,7 @@ file -2009-06-10T05:25:01.000000Z +2009-12-20T06:01:54.814555Z ac3a9a04135ada40ad3083503af485e3 2009-06-09T15:23:38.608509Z 148313 @@ -338,7 +338,7 @@ file -2009-06-10T05:25:01.000000Z +2009-12-20T06:01:54.815555Z 8794ca810e989bcfac2b06376c992b96 2009-06-04T15:43:03.499507Z 148172 diff --git a/src/x86/.svn/text-base/ffi64.c.svn-base b/src/x86/.svn/text-base/ffi64.c.svn-base index 116c636..51ada0e 100644 --- a/src/x86/.svn/text-base/ffi64.c.svn-base +++ b/src/x86/.svn/text-base/ffi64.c.svn-base @@ -145,13 +145,35 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: - if (byte_offset + type->size <= 4) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - return 1; + { + int size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } case FFI_TYPE_FLOAT: - if (byte_offset == 0) + if (!(byte_offset % 8)) classes[0] = X86_64_SSESF_CLASS; else classes[0] = X86_64_SSE_CLASS; @@ -171,13 +193,21 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], int i; enum x86_64_reg_class subclasses[MAX_CLASSES]; - /* If the struct is larger than 16 bytes, pass it on the stack. */ - if (type->size > 16) + /* If the struct is larger than 32 bytes, pass it on the stack. */ + if (type->size > 32) return 0; for (i = 0; i < words; i++) classes[i] = X86_64_NO_CLASS; + /* Zero sized arrays or structures are NO_CLASS. We return 0 to + signalize memory class, so handle it as special case. */ + if (!words) + { + classes[0] = X86_64_NO_CLASS; + return 1; + } + /* Merge the fields of structure. */ for (ptr = type->elements; *ptr != NULL; ptr++) { @@ -198,6 +228,20 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], byte_offset += (*ptr)->size; } + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + /* Final merger cleanup. */ for (i = 0; i < words; i++) { @@ -207,15 +251,25 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], return 0; /* The X86_64_SSEUP_CLASS should be always preceded by - X86_64_SSE_CLASS. */ + X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */ if (classes[i] == X86_64_SSEUP_CLASS - && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS)) - classes[i] = X86_64_SSE_CLASS; + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + /* The first one should never be X86_64_SSEUP_CLASS. */ + FFI_ASSERT (i != 0); + classes[i] = X86_64_SSE_CLASS; + } - /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ + /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS, + everything should be passed in memory. */ if (classes[i] == X86_64_X87UP_CLASS - && (i == 0 || classes[i - 1] != X86_64_X87_CLASS)) - classes[i] = X86_64_SSE_CLASS; + && (classes[i - 1] != X86_64_X87_CLASS)) + { + /* The first one should never be X86_64_X87UP_CLASS. */ + FFI_ASSERT (i != 0); + return 0; + } } return words; } @@ -528,10 +582,10 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, argp += arg_types[i]->size; } /* If the argument is in a single register, or two consecutive - registers, then we can use that address directly. */ + integer registers, then we can use that address directly. */ else if (n == 1 - || (n == 2 - && SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1]))) + || (n == 2 && !(SSE_CLASS_P (classes[0]) + || SSE_CLASS_P (classes[1])))) { /* The argument is in a single register. */ if (SSE_CLASS_P (classes[0])) diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c index 116c636..51ada0e 100644 --- a/src/x86/ffi64.c +++ b/src/x86/ffi64.c @@ -145,13 +145,35 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: - if (byte_offset + type->size <= 4) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - return 1; + { + int size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } case FFI_TYPE_FLOAT: - if (byte_offset == 0) + if (!(byte_offset % 8)) classes[0] = X86_64_SSESF_CLASS; else classes[0] = X86_64_SSE_CLASS; @@ -171,13 +193,21 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], int i; enum x86_64_reg_class subclasses[MAX_CLASSES]; - /* If the struct is larger than 16 bytes, pass it on the stack. */ - if (type->size > 16) + /* If the struct is larger than 32 bytes, pass it on the stack. */ + if (type->size > 32) return 0; for (i = 0; i < words; i++) classes[i] = X86_64_NO_CLASS; + /* Zero sized arrays or structures are NO_CLASS. We return 0 to + signalize memory class, so handle it as special case. */ + if (!words) + { + classes[0] = X86_64_NO_CLASS; + return 1; + } + /* Merge the fields of structure. */ for (ptr = type->elements; *ptr != NULL; ptr++) { @@ -198,6 +228,20 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], byte_offset += (*ptr)->size; } + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + /* Final merger cleanup. */ for (i = 0; i < words; i++) { @@ -207,15 +251,25 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], return 0; /* The X86_64_SSEUP_CLASS should be always preceded by - X86_64_SSE_CLASS. */ + X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */ if (classes[i] == X86_64_SSEUP_CLASS - && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS)) - classes[i] = X86_64_SSE_CLASS; + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + /* The first one should never be X86_64_SSEUP_CLASS. */ + FFI_ASSERT (i != 0); + classes[i] = X86_64_SSE_CLASS; + } - /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ + /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS, + everything should be passed in memory. */ if (classes[i] == X86_64_X87UP_CLASS - && (i == 0 || classes[i - 1] != X86_64_X87_CLASS)) - classes[i] = X86_64_SSE_CLASS; + && (classes[i - 1] != X86_64_X87_CLASS)) + { + /* The first one should never be X86_64_X87UP_CLASS. */ + FFI_ASSERT (i != 0); + return 0; + } } return words; } @@ -528,10 +582,10 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, argp += arg_types[i]->size; } /* If the argument is in a single register, or two consecutive - registers, then we can use that address directly. */ + integer registers, then we can use that address directly. */ else if (n == 1 - || (n == 2 - && SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1]))) + || (n == 2 && !(SSE_CLASS_P (classes[0]) + || SSE_CLASS_P (classes[1])))) { /* The argument is in a single register. */ if (SSE_CLASS_P (classes[0])) |