ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
* 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. From-SVN: r101650
This commit is contained in:
parent
00518cb117
commit
b65da30441
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
stw %r22, 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. */
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user