summaryrefslogtreecommitdiff
path: root/src/x86
diff options
context:
space:
mode:
authorAnthony Green <green@gmachine.(none)>2009-12-24 00:22:00 -0500
committerAnthony Green <green@gmachine.(none)>2009-12-24 00:22:00 -0500
commit115ab36fceee69740a01ce49bc27e1908cc237b1 (patch)
treedf2028286cbb876ce100438411cb7cdb4a9527c7 /src/x86
parentf8c7a245bf5a80bd7e730ec03fcad17c8dcfcb07 (diff)
downloadlibffi-115ab36fceee69740a01ce49bc27e1908cc237b1.tar.gz
Update missing changes for 3.0.9r4.
Diffstat (limited to 'src/x86')
-rw-r--r--src/x86/.svn/entries42
-rw-r--r--src/x86/.svn/text-base/ffi64.c.svn-base88
-rw-r--r--src/x86/ffi64.c88
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]))