aboutsummaryrefslogtreecommitdiff
path: root/libffi/src/powerpc/linux64.S
diff options
context:
space:
mode:
Diffstat (limited to 'libffi/src/powerpc/linux64.S')
-rw-r--r--libffi/src/powerpc/linux64.S111
1 files changed, 83 insertions, 28 deletions
diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S
index f0006fe..e92d64a 100644
--- a/libffi/src/powerpc/linux64.S
+++ b/libffi/src/powerpc/linux64.S
@@ -109,40 +109,70 @@ ffi_call_LINUX64:
ld %r2, 8(%r29)
# endif
/* Now do the call. */
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40, %r31
+ /* Set up cr1 with bits 3-7 of the flags. */
+ mtcrf 0xc0, %r31
/* Get the address to call into CTR. */
mtctr %r12
/* Load all those argument registers. */
- ld %r3, -32-(8*8)(%r28)
- ld %r4, -32-(7*8)(%r28)
- ld %r5, -32-(6*8)(%r28)
- ld %r6, -32-(5*8)(%r28)
+ addi %r29, %r28, -32-(8*8)
+ ld %r3, (0*8)(%r29)
+ ld %r4, (1*8)(%r29)
+ ld %r5, (2*8)(%r29)
+ ld %r6, (3*8)(%r29)
bf- 5, 1f
- ld %r7, -32-(4*8)(%r28)
- ld %r8, -32-(3*8)(%r28)
- ld %r9, -32-(2*8)(%r28)
- ld %r10, -32-(1*8)(%r28)
+ ld %r7, (4*8)(%r29)
+ ld %r8, (5*8)(%r29)
+ ld %r9, (6*8)(%r29)
+ ld %r10, (7*8)(%r29)
1:
/* Load all the FP registers. */
bf- 6, 2f
- lfd %f1, -32-(21*8)(%r28)
- lfd %f2, -32-(20*8)(%r28)
- lfd %f3, -32-(19*8)(%r28)
- lfd %f4, -32-(18*8)(%r28)
- lfd %f5, -32-(17*8)(%r28)
- lfd %f6, -32-(16*8)(%r28)
- lfd %f7, -32-(15*8)(%r28)
- lfd %f8, -32-(14*8)(%r28)
- lfd %f9, -32-(13*8)(%r28)
- lfd %f10, -32-(12*8)(%r28)
- lfd %f11, -32-(11*8)(%r28)
- lfd %f12, -32-(10*8)(%r28)
- lfd %f13, -32-(9*8)(%r28)
+ addi %r29, %r29, -(14*8)
+ lfd %f1, ( 1*8)(%r29)
+ lfd %f2, ( 2*8)(%r29)
+ lfd %f3, ( 3*8)(%r29)
+ lfd %f4, ( 4*8)(%r29)
+ lfd %f5, ( 5*8)(%r29)
+ lfd %f6, ( 6*8)(%r29)
+ lfd %f7, ( 7*8)(%r29)
+ lfd %f8, ( 8*8)(%r29)
+ lfd %f9, ( 9*8)(%r29)
+ lfd %f10, (10*8)(%r29)
+ lfd %f11, (11*8)(%r29)
+ lfd %f12, (12*8)(%r29)
+ lfd %f13, (13*8)(%r29)
2:
+ /* Load all the vector registers. */
+ bf- 3, 3f
+ addi %r29, %r29, -16
+ lvx %v13, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v12, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v11, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v10, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v9, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v8, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v7, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v6, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v5, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v4, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v3, 0, %r29
+ addi %r29, %r29, -16
+ lvx %v2, 0, %r29
+3:
+
/* Make the call. */
ld %r11, 8(%r28)
bctrl
@@ -160,6 +190,7 @@ ffi_call_LINUX64:
bt 31, .Lstruct_return_value
bt 30, .Ldone_return_value
bt 29, .Lfp_return_value
+ bt 28, .Lvec_return_value
std %r3, 0(%r30)
/* Fall through... */
@@ -175,12 +206,16 @@ ffi_call_LINUX64:
ld %r31, -8(%r1)
blr
+.Lvec_return_value:
+ stvx %v2, 0, %r30
+ b .Ldone_return_value
+
.Lfp_return_value:
.cfi_def_cfa_register 28
- bf 28, .Lfloat_return_value
- stfd %f1, 0(%r30)
mtcrf 0x02, %r31 /* cr6 */
- bf 27, .Ldone_return_value
+ bf 27, .Lfloat_return_value
+ stfd %f1, 0(%r30)
+ bf 26, .Ldone_return_value
stfd %f2, 8(%r30)
b .Ldone_return_value
.Lfloat_return_value:
@@ -188,8 +223,9 @@ ffi_call_LINUX64:
b .Ldone_return_value
.Lstruct_return_value:
- bf 29, .Lsmall_struct
- bf 28, .Lfloat_homog_return_value
+ bf 29, .Lvec_homog_or_small_struct
+ mtcrf 0x02, %r31 /* cr6 */
+ bf 27, .Lfloat_homog_return_value
stfd %f1, 0(%r30)
stfd %f2, 8(%r30)
stfd %f3, 16(%r30)
@@ -211,6 +247,25 @@ ffi_call_LINUX64:
stfs %f8, 28(%r30)
b .Ldone_return_value
+.Lvec_homog_or_small_struct:
+ bf 28, .Lsmall_struct
+ stvx %v2, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v3, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v4, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v5, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v6, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v7, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v8, 0, %r30
+ addi %r30, %r30, 16
+ stvx %v9, 0, %r30
+ b .Ldone_return_value
+
.Lsmall_struct:
std %r3, 0(%r30)
std %r4, 8(%r30)