Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame^] | 1 | PUBLIC ffi_call_AMD64 |
| 2 | |
| 3 | EXTRN __chkstk:NEAR |
| 4 | EXTRN ffi_closure_SYSV:NEAR |
| 5 | |
| 6 | _TEXT SEGMENT |
| 7 | |
| 8 | ;;; ffi_closure_OUTER will be called with these registers set: |
| 9 | ;;; rax points to 'closure' |
| 10 | ;;; r11 contains a bit mask that specifies which of the |
| 11 | ;;; first four parameters are float or double |
| 12 | ;;; |
| 13 | ;;; It must move the parameters passed in registers to their stack location, |
| 14 | ;;; call ffi_closure_SYSV for the actual work, then return the result. |
| 15 | ;;; |
| 16 | ffi_closure_OUTER PROC FRAME |
| 17 | ;; save actual arguments to their stack space. |
| 18 | test r11, 1 |
| 19 | jne first_is_float |
| 20 | mov QWORD PTR [rsp+8], rcx |
| 21 | jmp second |
| 22 | first_is_float: |
| 23 | movlpd QWORD PTR [rsp+8], xmm0 |
| 24 | |
| 25 | second: |
| 26 | test r11, 2 |
| 27 | jne second_is_float |
| 28 | mov QWORD PTR [rsp+16], rdx |
| 29 | jmp third |
| 30 | second_is_float: |
| 31 | movlpd QWORD PTR [rsp+16], xmm1 |
| 32 | |
| 33 | third: |
| 34 | test r11, 4 |
| 35 | jne third_is_float |
| 36 | mov QWORD PTR [rsp+24], r8 |
| 37 | jmp forth |
| 38 | third_is_float: |
| 39 | movlpd QWORD PTR [rsp+24], xmm2 |
| 40 | |
| 41 | forth: |
| 42 | test r11, 8 |
| 43 | jne forth_is_float |
| 44 | mov QWORD PTR [rsp+32], r9 |
| 45 | jmp done |
| 46 | forth_is_float: |
| 47 | movlpd QWORD PTR [rsp+32], xmm3 |
| 48 | |
| 49 | done: |
| 50 | .ALLOCSTACK 40 |
| 51 | sub rsp, 40 |
| 52 | .ENDPROLOG |
| 53 | mov rcx, rax ; context is first parameter |
| 54 | mov rdx, rsp ; stack is second parameter |
| 55 | add rdx, 40 ; correct our own area |
| 56 | mov rax, ffi_closure_SYSV |
| 57 | call rax ; call the real closure function |
| 58 | ;; Here, code is missing that handles float return values |
| 59 | add rsp, 40 |
| 60 | movd xmm0, rax ; In case the closure returned a float. |
| 61 | ret 0 |
| 62 | ffi_closure_OUTER ENDP |
| 63 | |
| 64 | |
| 65 | ;;; ffi_call_AMD64 |
| 66 | |
| 67 | stack$ = 0 |
| 68 | prepfunc$ = 32 |
| 69 | ecif$ = 40 |
| 70 | bytes$ = 48 |
| 71 | flags$ = 56 |
| 72 | rvalue$ = 64 |
| 73 | fn$ = 72 |
| 74 | |
| 75 | ffi_call_AMD64 PROC FRAME |
| 76 | |
| 77 | mov QWORD PTR [rsp+32], r9 |
| 78 | mov QWORD PTR [rsp+24], r8 |
| 79 | mov QWORD PTR [rsp+16], rdx |
| 80 | mov QWORD PTR [rsp+8], rcx |
| 81 | .PUSHREG rbp |
| 82 | push rbp |
| 83 | .ALLOCSTACK 48 |
| 84 | sub rsp, 48 ; 00000030H |
| 85 | .SETFRAME rbp, 32 |
| 86 | lea rbp, QWORD PTR [rsp+32] |
| 87 | .ENDPROLOG |
| 88 | |
| 89 | mov eax, DWORD PTR bytes$[rbp] |
| 90 | add rax, 15 |
| 91 | and rax, -16 |
| 92 | call __chkstk |
| 93 | sub rsp, rax |
| 94 | lea rax, QWORD PTR [rsp+32] |
| 95 | mov QWORD PTR stack$[rbp], rax |
| 96 | |
| 97 | mov rdx, QWORD PTR ecif$[rbp] |
| 98 | mov rcx, QWORD PTR stack$[rbp] |
| 99 | call QWORD PTR prepfunc$[rbp] |
| 100 | |
| 101 | mov rsp, QWORD PTR stack$[rbp] |
| 102 | |
| 103 | movlpd xmm3, QWORD PTR [rsp+24] |
| 104 | movd r9, xmm3 |
| 105 | |
| 106 | movlpd xmm2, QWORD PTR [rsp+16] |
| 107 | movd r8, xmm2 |
| 108 | |
| 109 | movlpd xmm1, QWORD PTR [rsp+8] |
| 110 | movd rdx, xmm1 |
| 111 | |
| 112 | movlpd xmm0, QWORD PTR [rsp] |
| 113 | movd rcx, xmm0 |
| 114 | |
| 115 | call QWORD PTR fn$[rbp] |
| 116 | ret_int$: |
| 117 | cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT |
| 118 | jne ret_float$ |
| 119 | |
| 120 | mov rcx, QWORD PTR rvalue$[rbp] |
| 121 | mov DWORD PTR [rcx], eax |
| 122 | jmp SHORT ret_nothing$ |
| 123 | |
| 124 | ret_float$: |
| 125 | cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT |
| 126 | jne SHORT ret_double$ |
| 127 | |
| 128 | mov rax, QWORD PTR rvalue$[rbp] |
| 129 | movlpd QWORD PTR [rax], xmm0 |
| 130 | jmp SHORT ret_nothing$ |
| 131 | |
| 132 | ret_double$: |
| 133 | cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE |
| 134 | jne SHORT ret_int64$ |
| 135 | |
| 136 | mov rax, QWORD PTR rvalue$[rbp] |
| 137 | movlpd QWORD PTR [rax], xmm0 |
| 138 | jmp SHORT ret_nothing$ |
| 139 | |
| 140 | ret_int64$: |
| 141 | cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64 |
| 142 | jne ret_nothing$ |
| 143 | |
| 144 | mov rcx, QWORD PTR rvalue$[rbp] |
| 145 | mov QWORD PTR [rcx], rax |
| 146 | jmp SHORT ret_nothing$ |
| 147 | |
| 148 | ret_nothing$: |
| 149 | xor eax, eax |
| 150 | |
| 151 | lea rsp, QWORD PTR [rbp+16] |
| 152 | pop rbp |
| 153 | ret 0 |
| 154 | ffi_call_AMD64 ENDP |
| 155 | _TEXT ENDS |
| 156 | END |