diff options
author | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-06 03:37:20 +0000 |
---|---|---|
committer | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-06 03:37:20 +0000 |
commit | c350327d6cc9f124cee3543657f97f74e7cb2500 (patch) | |
tree | 4623ad894f02fcb1b4f53ee584083ade5a6fc60c /libffi | |
parent | e6e4c039ebec5b60512235cd5af25dfbb95660a0 (diff) | |
download | gcc-c350327d6cc9f124cee3543657f97f74e7cb2500.tar.gz |
* src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1
as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte
structures. Kill compilation warnings.
(ffi_closure_inner_LINUX): Print return values as hex in debug
message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
Properly handle 5-7 byte structure returns.
* src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1)
(FFI_TYPE_SMALL_STRUCT2): Remove.
(FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5)
(FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define.
* src/pa/linux.S: Mark source file as using PA1.1 assembly.
(checksmst1, checksmst2): Remove.
(checksmst3): Optimize handling of 3-byte struct returns.
(checksmst567): Properly handle 5-7 byte struct returns.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101650 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi')
-rw-r--r-- | libffi/ChangeLog | 17 | ||||
-rw-r--r-- | libffi/src/pa/ffi.c | 58 | ||||
-rw-r--r-- | libffi/src/pa/ffitarget.h | 6 | ||||
-rw-r--r-- | libffi/src/pa/linux.S | 54 |
4 files changed, 101 insertions, 34 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 3b1afef3ee4..b4a1644ac17 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,20 @@ +2005-07-05 Randolph Chung <tausq@debian.org> + + * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 + as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte + structures. Kill compilation warnings. + (ffi_closure_inner_LINUX): Print return values as hex in debug + message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. + Properly handle 5-7 byte structure returns. + * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) + (FFI_TYPE_SMALL_STRUCT2): Remove. + (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) + (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. + * src/pa/linux.S: Mark source file as using PA1.1 assembly. + (checksmst1, checksmst2): Remove. + (checksmst3): Optimize handling of 3-byte struct returns. + (checksmst567): Properly handle 5-7 byte struct returns. + 2005-06-15 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> PR libgcj/21943 diff --git a/libffi/src/pa/ffi.c b/libffi/src/pa/ffi.c index 57331fe675a..f6264dbc5e9 100644 --- a/libffi/src/pa/ffi.c +++ b/libffi/src/pa/ffi.c @@ -27,6 +27,7 @@ #include <ffi_common.h> #include <stdlib.h> +#include <stdio.h> #define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) #define ROUND_DOWN(v, a) (((size_t)(v) - (a) + 1) & ~((a) - 1)) @@ -53,11 +54,15 @@ static inline int ffi_struct_type(ffi_type *t) else if (sz == 2) return FFI_TYPE_UINT16; else if (sz == 3) - return FFI_TYPE_SMALL_STRUCT1; + return FFI_TYPE_SMALL_STRUCT3; else if (sz == 4) return FFI_TYPE_UINT32; - else if (sz <= 6) - return FFI_TYPE_SMALL_STRUCT2; + else if (sz == 5) + return FFI_TYPE_SMALL_STRUCT5; + else if (sz == 6) + return FFI_TYPE_SMALL_STRUCT6; + else if (sz == 7) + return FFI_TYPE_SMALL_STRUCT7; else if (sz <= 8) return FFI_TYPE_UINT64; else @@ -491,34 +496,32 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) /* Invoke the closure. */ (closure->fun) (cif, rvalue, avalue, closure->user_data); - debug(3, "after calling function, ret[0] = %d, ret[1] = %d\n", ret[0], ret[1]); + debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], ret[1]); /* Store the result */ switch (cif->flags) { case FFI_TYPE_UINT8: - *(stack - FIRST_ARG_SLOT) = *(UINT8 *)&ret[0]; + *(stack - FIRST_ARG_SLOT) = (UINT8)(ret[0] >> 24); break; case FFI_TYPE_SINT8: - *(stack - FIRST_ARG_SLOT) = *(SINT8 *)&ret[0]; + *(stack - FIRST_ARG_SLOT) = (SINT8)(ret[0] >> 24); break; case FFI_TYPE_UINT16: - *(stack - FIRST_ARG_SLOT) = *(UINT16 *)&ret[0]; + *(stack - FIRST_ARG_SLOT) = (UINT16)(ret[0] >> 16); break; case FFI_TYPE_SINT16: - *(stack - FIRST_ARG_SLOT) = *(SINT16 *)&ret[0]; + *(stack - FIRST_ARG_SLOT) = (SINT16)(ret[0] >> 16); break; case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - *(stack - FIRST_ARG_SLOT) = *(UINT32 *)&ret[0]; - break; case FFI_TYPE_SINT32: - *(stack - FIRST_ARG_SLOT) = *(SINT32 *)&ret[0]; + case FFI_TYPE_UINT32: + *(stack - FIRST_ARG_SLOT) = ret[0]; break; case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: - *(stack - FIRST_ARG_SLOT) = *(UINT32 *)&ret[0]; - *(stack - FIRST_ARG_SLOT - 1) = *(UINT32 *)&ret[1]; + *(stack - FIRST_ARG_SLOT) = ret[0]; + *(stack - FIRST_ARG_SLOT - 1) = ret[1]; break; case FFI_TYPE_DOUBLE: @@ -533,15 +536,34 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) /* Don't need a return value, done by caller. */ break; - case FFI_TYPE_SMALL_STRUCT1: + case FFI_TYPE_SMALL_STRUCT3: tmp = (void*)(stack - FIRST_ARG_SLOT); tmp += 4 - cif->rtype->size; memcpy((void*)tmp, &ret[0], cif->rtype->size); break; - case FFI_TYPE_SMALL_STRUCT2: - *(stack - FIRST_ARG_SLOT) = ret[0]; - *(stack - FIRST_ARG_SLOT - 1) = ret[1]; + case FFI_TYPE_SMALL_STRUCT5: + case FFI_TYPE_SMALL_STRUCT6: + case FFI_TYPE_SMALL_STRUCT7: + { + unsigned int ret2[2]; + int off; + + /* Right justify ret[0] and ret[1] */ + switch (cif->flags) + { + case FFI_TYPE_SMALL_STRUCT5: off = 3; break; + case FFI_TYPE_SMALL_STRUCT6: off = 2; break; + case FFI_TYPE_SMALL_STRUCT7: off = 1; break; + default: off = 0; break; + } + + memset (ret2, 0, sizeof (ret2)); + memcpy ((char *)ret2 + off, ret, 8 - off); + + *(stack - FIRST_ARG_SLOT) = ret2[0]; + *(stack - FIRST_ARG_SLOT - 1) = ret2[1]; + } break; case FFI_TYPE_POINTER: diff --git a/libffi/src/pa/ffitarget.h b/libffi/src/pa/ffitarget.h index b8bcad0872f..56206962397 100644 --- a/libffi/src/pa/ffitarget.h +++ b/libffi/src/pa/ffitarget.h @@ -51,7 +51,9 @@ typedef enum ffi_abi { #define FFI_TRAMPOLINE_SIZE 32 -#define FFI_TYPE_SMALL_STRUCT1 -1 -#define FFI_TYPE_SMALL_STRUCT2 -2 +#define FFI_TYPE_SMALL_STRUCT3 -1 +#define FFI_TYPE_SMALL_STRUCT5 -2 +#define FFI_TYPE_SMALL_STRUCT6 -3 +#define FFI_TYPE_SMALL_STRUCT7 -4 #endif diff --git a/libffi/src/pa/linux.S b/libffi/src/pa/linux.S index 1a2ecdbb54c..267cff7b802 100644 --- a/libffi/src/pa/linux.S +++ b/libffi/src/pa/linux.S @@ -28,6 +28,7 @@ #include <ffi.h> .text + .level 1.1 .align 4 /* void ffi_call_LINUX(void (*)(char *, extended_cif *), @@ -105,21 +106,46 @@ ffi_call_LINUX: /* Store the result according to the return type. */ -checksmst1: - comib,<>,n FFI_TYPE_SMALL_STRUCT1, %r21, checksmst2 - /* There is maybe a better way to handle 3 byte structs. */ - sh2add %ret0,0,%ret0 - sh2add %ret0,0,%ret0 - sh2add %ret0,0,%ret0 - sh2add %ret0,0,%ret0 +checksmst3: + comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567 + /* 3-byte structs are returned in ret0 as ??xxyyzz. Shift + left 8 bits to write to the result structure. */ + zdep %ret0, 23, 24, %r22 b done - stw %ret0, 0(%r20) - -checksmst2: - comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, checkint8 - /* Up to now I don't have a way to handle 6/7 byte structs. - The values are left bounded in the registers. In the struct - itself they are left bounded. */ + stw %r22, 0(%r20) + +checksmst567: + /* 5-7 byte values are returned right justified: + ret0 ret1 + 5: ??????aa bbccddee + 6: ????aabb ccddeeff + 7: ??aabbcc ddeeffgg + + To store this in the result, write the first 4 bytes into a temp + register using shrpw (t1 = aabbccdd), followed by a rotation of + ret1: + + ret0 ret1 ret1 + 5: ??????aa bbccddee -> eebbccdd (rotate 8) + 6: ????aabb ccddeeff -> eeffccdd (rotate 16) + 7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24) + + then we write (t1, ret1) into the result. */ + + addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0 + ldi 8, %r22 + addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0 + ldi 16, %r22 + addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0 + ldi 24, %r22 + + /* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */ + cmpib,<=,n 0, %r21, checkint8 + mtsar %r22 + + shrpw %ret0, %ret1, %sar, %ret0 /* ret0 = aabbccdd */ + shrpw %ret1, %ret1, %sar, %ret1 /* rotate ret1 */ + stw %ret0, 0(%r20) b done stw %ret1, 4(%r20) |