github.com/notti/nocgo@v0.0.0-20190619201224-fc443047424c/internal/ffi/call_amd64.s (about) 1 #include "textflag.h" 2 #include "go_asm.h" 3 4 // runtime has #include "go_asm.h" 5 // we need to fake the defines here: 6 #define slice_array 0 7 #define slice_len 8 8 #define slice_cap 16 9 10 11 #define LOADREG(off, target) \ 12 MOVLQSX spec_intargs+argument__size*off(R12), AX \ 13 TESTQ AX, AX \ 14 JS xmm \ 15 MOVWQZX AX, R11 \ 16 SHRL $16, AX \ 17 ADDQ R13, R11 \ 18 CMPB AX, $const_type64 \ 19 JNE 3(PC) \ 20 MOVQ 0(R11), target \ // 64bit 21 JMP 20(PC) \ 22 CMPB AX, $const_typeS32 \ 23 JNE 3(PC) \ 24 MOVLQSX 0(R11), target \ // signed 32 bit 25 JMP 18(PC) \ 26 CMPB AX, $const_typeU32 \ 27 JNE 3(PC) \ 28 MOVLQZX 0(R11), target \ // unsigned 32 bit 29 JMP 14(PC) \ 30 CMPB AX, $const_typeS16 \ 31 JNE 3(PC) \ 32 MOVWQSX 0(R11), target \ // signed 16 bit 33 JMP 10(PC) \ 34 CMPB AX, $const_typeU16 \ 35 JNE 3(PC) \ 36 MOVWQZX 0(R11), target \ // unsigned 16 bit 37 JMP 6(PC) \ 38 CMPB AX, $const_typeS8 \ 39 JNE 3(PC) \ 40 MOVBQSX 0(R11), target \ // signed 8 bit 41 JMP 2(PC) \ 42 MOVBQZX 0(R11), target // unsigned 8 bit 43 44 #define LOADXMMREG(off, target) \ 45 MOVLQSX spec_xmmargs+argument__size*off(R12), AX \ 46 TESTQ AX, AX \ 47 JS prepared \ 48 MOVWQZX AX, R11 \ 49 SHRL $16, AX \ 50 ADDQ R13, R11 \ 51 CMPB AX, $const_typeDouble \ 52 JNE 3(PC) \ 53 MOVSD 0(R11), target \ // float 64bit 54 JMP 2(PC) \ 55 MOVSS 0(R11), target \ // float 32bit 56 57 TEXT ·cgocall(SB),NOSPLIT,$0 58 JMP runtime·cgocall(SB) 59 60 // pass struct { &args, &spec } to cgocall 61 TEXT ·callWrapper(SB),NOSPLIT|WRAPPER,$32 62 MOVQ DX, 24(SP) 63 LEAQ argframe+0(FP), AX 64 MOVQ AX, 16(SP) 65 LEAQ 16(SP), AX 66 MOVQ AX, 8(SP) 67 LEAQ asmcall(SB), AX 68 MOVQ AX, 0(SP) 69 CALL ·cgocall(SB) 70 RET 71 72 TEXT asmcall(SB),NOSPLIT,$0 73 MOVQ 8(DI), R12 // spec (preserved) 74 MOVQ 0(DI), R13 // base of args (preserved) 75 MOVQ SP, R14 // stack for restoring later on (preserved) 76 77 ANDQ $~0x1F, SP // 32 byte alignment for cdecl (in case someone wants to pass __m256 on the stack) 78 // for no __m256 16 byte would be ok 79 // this is actually already done by cgocall - but asmcall was called from there and destroys that :( 80 81 MOVQ spec_stack+slice_len(R12), AX // length of stack registers 82 TESTQ AX, AX 83 JZ reg 84 85 // ok we have stack arguments so let's do that first 86 87 // Fix alignment depending on number of arguments 88 MOVQ AX, BX 89 ANDQ $3, BX 90 SHLQ $3, BX 91 SUBQ BX, SP 92 93 MOVQ spec_stack+slice_array(R12), BX 94 95 next: 96 DECQ AX 97 MOVQ (BX)(AX*argument__size), CX 98 //check type and push to stack 99 MOVWQZX CX, R11 100 SHRL $16, CX 101 ADDQ R13, R11 102 103 #define LOADSTACK(type, instr) \ 104 CMPB CX, type \ 105 JNE 7(PC) \ 106 SUBQ $8, SP \ 107 instr 0(R11), CX \ 108 instr CX, 0(SP) \ 109 TESTQ AX, AX \ 110 JZ reg \ 111 JMP next 112 113 LOADSTACK($const_type64, MOVQ) 114 LOADSTACK($const_typeU32, MOVL) 115 LOADSTACK($const_typeU16, MOVW) 116 LOADSTACK($const_typeU8, MOVB) 117 118 INT $3 119 120 reg: 121 // load register arguments 122 LOADREG(0, DI) 123 LOADREG(1, SI) 124 LOADREG(2, DX) 125 LOADREG(3, CX) 126 LOADREG(4, R8) 127 LOADREG(5, R9) 128 129 xmm: 130 // load xmm arguments 131 LOADXMMREG(0, X0) 132 LOADXMMREG(1, X1) 133 LOADXMMREG(2, X2) 134 LOADXMMREG(3, X3) 135 LOADXMMREG(4, X4) 136 LOADXMMREG(5, X5) 137 LOADXMMREG(6, X6) 138 LOADXMMREG(7, X7) 139 140 prepared: 141 // load number of vector registers 142 MOVBQSX spec_rax(R12), AX 143 144 // do the actuall call 145 CALL spec_fn(R12) 146 147 MOVQ R14, SP 148 149 // TODO: check R13, if it still points to the correct stack! (could happen if we have a callback into go that splits the stack) 150 151 // store ret 152 MOVLQSX spec_ret(R12), BX 153 TESTQ BX, BX 154 JS DONE 155 MOVWQZX BX, R11 156 SHRL $16, BX 157 ADDQ R13, R11 158 159 CMPB BX, $const_type64 160 JNE 3(PC) 161 MOVQ AX, (R11) 162 JMP DONE 163 164 CMPB BX, $const_typeU32 165 JNE 3(PC) 166 MOVL AX, (R11) 167 JMP DONE 168 169 CMPB BX, $const_typeU16 170 JNE 3(PC) 171 MOVW AX, (R11) 172 JMP DONE 173 174 CMPB BX, $const_typeU8 175 JNE 3(PC) 176 MOVB AX, (R11) 177 JMP DONE 178 179 CMPB BX, $const_typeDouble 180 JNE 3(PC) 181 MOVSD X0, (R11) 182 JMP DONE 183 184 CMPB BX, $const_typeFloat 185 JNE 3(PC) 186 MOVSS X0, (R11) 187 JMP DONE 188 189 INT $3 190 191 DONE: 192 RET