Home | History | Annotate | Download | only in powerpc
      1 /* -----------------------------------------------------------------------
      2    aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
      3    based on darwin.S by John Hornkvist
      4 
      5    PowerPC Assembly glue.
      6 
      7    Permission is hereby granted, free of charge, to any person obtaining
      8    a copy of this software and associated documentation files (the
      9    ``Software''), to deal in the Software without restriction, including
     10    without limitation the rights to use, copy, modify, merge, publish,
     11    distribute, sublicense, and/or sell copies of the Software, and to
     12    permit persons to whom the Software is furnished to do so, subject to
     13    the following conditions:
     14 
     15    The above copyright notice and this permission notice shall be included
     16    in all copies or substantial portions of the Software.
     17 
     18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
     22    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     23    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     24    OTHER DEALINGS IN THE SOFTWARE.
     25    ----------------------------------------------------------------------- */
     26 
     27 	.set r0,0
     28 	.set r1,1
     29 	.set r2,2
     30 	.set r3,3
     31 	.set r4,4
     32 	.set r5,5
     33 	.set r6,6
     34 	.set r7,7
     35 	.set r8,8
     36 	.set r9,9
     37 	.set r10,10
     38 	.set r11,11
     39 	.set r12,12
     40 	.set r13,13
     41 	.set r14,14
     42 	.set r15,15
     43 	.set r16,16
     44 	.set r17,17
     45 	.set r18,18
     46 	.set r19,19
     47 	.set r20,20
     48 	.set r21,21
     49 	.set r22,22
     50 	.set r23,23
     51 	.set r24,24
     52 	.set r25,25
     53 	.set r26,26
     54 	.set r27,27
     55 	.set r28,28
     56 	.set r29,29
     57 	.set r30,30
     58 	.set r31,31
     59 	.set f0,0
     60 	.set f1,1
     61 	.set f2,2
     62 	.set f3,3
     63 	.set f4,4
     64 	.set f5,5
     65 	.set f6,6
     66 	.set f7,7
     67 	.set f8,8
     68 	.set f9,9
     69 	.set f10,10
     70 	.set f11,11
     71 	.set f12,12
     72 	.set f13,13
     73 	.set f14,14
     74 	.set f15,15
     75 	.set f16,16
     76 	.set f17,17
     77 	.set f18,18
     78 	.set f19,19
     79 	.set f20,20
     80 	.set f21,21
     81 
     82 #define LIBFFI_ASM
     83 #include <fficonfig.h>
     84 #include <ffi.h>
     85 #define JUMPTARGET(name) name
     86 #define L(x) x
     87 	.file "aix.S"
     88 	.toc
     89 	.csect .text[PR]
     90 	.align 2
     91 .globl ffi_prep_args
     92 
     93 .csect .text[PR]
     94 	.align 2
     95 	.globl ffi_call_AIX
     96 	.globl .ffi_call_AIX
     97 .csect ffi_call_AIX[DS]
     98 ffi_call_AIX:
     99 	.long .ffi_call_AIX, TOC[tc0], 0
    100 	.csect .text[PR]
    101 .ffi_call_AIX:
    102 	mr      r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
    103 	/* Save the old stack pointer as AP.  */
    104 	mr	r8,r1
    105 
    106 	/* Allocate the stack space we need.  */
    107 	stwux	r1,r1,r4
    108 
    109 	/* Save registers we use.  */
    110 	mflr	r9
    111 
    112 	stw	r28,-16(r8)
    113 	stw	r29,-12(r8)
    114 	stw	r30, -8(r8)
    115 	stw	r31, -4(r8)
    116 
    117 	stw	r9,  8(r8)
    118 	stw	r2, 20(r1)
    119 
    120 	/* Save arguments over call...  */
    121 	mr	r31,r5	/* flags, */
    122 	mr	r30,r6	/* rvalue, */
    123 	mr	r29,r7	/* function address, */
    124 	mr	r28,r8	/* our AP. */
    125 
    126 	/* Call ffi_prep_args.  */
    127 	mr	r4,r1
    128 	li	r9,0
    129 
    130 	lwz	r2,4(r12)
    131 	lwz	r12,0(r12)
    132 	mtctr	r12 // r12 holds address of _ffi_prep_args
    133 	bctrl
    134 	lwz     r2,20(r1)
    135 
    136 	/* Now do the call.  */
    137 	lwz	r12,0(r29)
    138 	/* Set up cr1 with bits 4-7 of the flags.  */
    139 	mtcrf	0x40,r31
    140 	stw	r2,20(r1)
    141 	mtctr	r12
    142 	lwz	r2,4(r29)
    143 	/* Load all those argument registers.  */
    144 	// We have set up a nice stack frame, just load it into registers.
    145 	lwz     r3, 20+(1*4)(r1)
    146 	lwz     r4, 20+(2*4)(r1)
    147 	lwz     r5, 20+(3*4)(r1)
    148 	lwz     r6, 20+(4*4)(r1)
    149 	nop
    150 	lwz     r7, 20+(5*4)(r1)
    151 	lwz     r8, 20+(6*4)(r1)
    152 	lwz     r9, 20+(7*4)(r1)
    153 	lwz     r10,20+(8*4)(r1)
    154 
    155 L1:
    156 	/* Load all the FP registers.  */
    157 	bf	6,L2 // 2f + 0x18
    158 	lfd	f1,-16-(13*8)(r28)
    159 	lfd	f2,-16-(12*8)(r28)
    160 	lfd	f3,-16-(11*8)(r28)
    161 	lfd	f4,-16-(10*8)(r28)
    162 	nop
    163 	lfd	f5,-16-(9*8)(r28)
    164 	lfd	f6,-16-(8*8)(r28)
    165 	lfd	f7,-16-(7*8)(r28)
    166 	lfd	f8,-16-(6*8)(r28)
    167 	nop
    168 	lfd     f9,-16-(5*8)(r28)
    169 	lfd     f10,-16-(4*8)(r28)
    170 	lfd     f11,-16-(3*8)(r28)
    171 	lfd     f12,-16-(2*8)(r28)
    172 	nop
    173 	lfd     f13,-16-(1*8)(r28)
    174 
    175 L2:
    176 	/* Make the call.  */
    177 	bctrl
    178 	lwz r2,20(r1)
    179 
    180 	/* Now, deal with the return value.  */
    181 	mtcrf	0x01,r31
    182 
    183 	bt	30,L(done_return_value)
    184 	bt	29,L(fp_return_value)
    185 	stw	r3,0(r30)
    186 	bf	28,L(done_return_value)
    187 	stw	r4,4(r30)
    188 
    189 	/* Fall through...  */
    190 
    191 L(done_return_value):
    192 	/* Restore the registers we used and return.  */
    193 	lwz	r9,   8(r28)
    194 	lwz	r31,  -4(r28)
    195 	mtlr	r9
    196 	lwz	r30, -8(r28)
    197 	lwz	r29,-12(r28)
    198 	lwz	r28,-16(r28)
    199 	lwz	r1,0(r1)
    200 	blr
    201 
    202 L(fp_return_value):
    203 	bf	28,L(float_return_value)
    204 	stfd	f1,0(r30)
    205 	b	L(done_return_value)
    206 L(float_return_value):
    207 	stfs	f1,0(r30)
    208 	b	L(done_return_value)
    209 	.long 0
    210 	.byte 0,0,0,1,128,4,0,0
    211 //END(ffi_call_AIX)
    212 
    213 .csect .text[PR]
    214 	.align 2
    215 	.globl ffi_call_DARWIN
    216 	.globl .ffi_call_DARWIN
    217 .csect ffi_call_DARWIN[DS]
    218 ffi_call_DARWIN:
    219 	.long .ffi_call_DARWIN, TOC[tc0], 0
    220 	.csect .text[PR]
    221 .ffi_call_DARWIN:
    222 	blr
    223 	.long 0
    224 	.byte 0,0,0,0,0,0,0,0
    225 //END(ffi_call_DARWIN)
    226