github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/ppapi/ppapi_nacl_amd64p32.st (about) 1 // -*- mode: asm -*- 2 // Copyright 2014 The Go Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "../zasm_nacl_amd64p32.h" 7 #include "../../cmd/ld/textflag.h" 8 #include "../irt_nacl.h" 9 #include "../funcdata.h" 10 #include "ppapi_GOOS.h" 11 12 {% if False %} 13 // amd64return(ty) expands to the instruction sequence for saving the return 14 // value into the caller's stack frame. 15 {% endif %} 16 {% macro amd64return(resultType, off, fp) -%} 17 {%- set kind = resultType.kind -%} 18 {%- set size = resultType.size -%} 19 {%- if size == 0 -%} 20 // No return value 21 {%- elif kind == 'float32' -%} 22 MOVSS X0, {{off}}({{fp}}) 23 {%- elif kind == 'float64' -%} 24 MOVSD X0, {{off}}({{fp}}) 25 {%- elif size == 4 -%} 26 MOVL AX, {{off}}({{fp}}) 27 {%- elif size == 8 -%} 28 MOVQ AX, {{off}}({{fp}}) 29 {%- elif size == 12 -%} 30 MOVQ AX, {{off}}({{fp}}) // (sizeof {{size}}) 31 MOVL DX, {{off+8}}({{fp}}) 32 {%- elif size == 16 -%} 33 MOVQ AX, {{off}}({{fp}}) // (sizeof {{size}}) 34 MOVQ DX, {{off+8}}({{fp}}) 35 {%- else -%} 36 Bogus return value of size {{size}} 37 {%- endif %} 38 {%- endmacro -%} 39 40 {% if False %} 41 // amd64args sets up the arguments, converting from the Go calling convention, 42 // where everything is passed on the stack, to the gcc calling convention, where: 43 // - integer args are passed in registers DI, SI, DX, CX, R8, R9. 44 // - float args are passed in registers X0, ..., X5. 45 // - structs smaller than 16 bytes are passed in registers. 46 // - everything else is passed on the stack. 47 // 48 // AX refers to the caller stack frame. 49 // SP refers the the callee stack frame. 50 // Destroys DX. 51 {% endif %} 52 {% macro amd64args(args) -%} 53 {%- set regs = ['DI', 'SI', 'DX', 'CX', 'R8', 'R9'] -%} 54 {%- set fregs = ['X0', 'X1', 'X2', 'X3', 'X4', 'X5'] -%} 55 {%- set ain = 0 -%} 56 {%- set soff = 0 -%} 57 {%- for arg in args -%} 58 {%- set ty = arg.type -%} 59 {%- set kind = ty.kind -%} 60 {%- set size = ty.size -%} 61 {%- if ty.align > 0 %} 62 {%- set ain = align(ain, ty.align) -%} 63 {%- endif -%} 64 {%- if kind == 'float32' and fregs.__len__() >= 1 %} 65 MOVSS {{ain}}(AX), {{fregs[0]}} // {{arg.name}} 66 {%- set fregs = fregs[1:] -%} 67 {%- elif kind == 'float64' and fregs.__len__() >= 1 %} 68 MOVSD {{ain}}(AX), {{fregs[0]}} // {{arg.name}} 69 {%- set fregs = fregs[1:] -%} 70 {%- elif size == 4 and regs.__len__() >= 1 %} 71 MOVL {{ain}}(AX), {{regs[0]}} // {{arg.name}} 72 {%- set regs = regs[1:] -%} 73 {%- elif size == 8 and regs.__len__() >= 1 %} 74 MOVQ {{ain}}(AX), {{regs[0]}} // {{arg.name}} 75 {%- set regs = regs[1:] -%} 76 {%- elif size == 12 and regs.__len__() >= 2 %} 77 MOVQ {{ain}}(AX), {{regs[0]}} // {{arg.name}} (sizeof {{size}}) 78 MOVL {{ain+8}}(AX), {{regs[1]}} 79 {%- set regs = regs[2:] -%} 80 {%- elif size == 16 and regs.__len__() >= 2 %} 81 MOVQ {{ain}}(AX), {{regs[0]}} // {{arg.name}} (sizeof {{size}}) 82 MOVQ {{ain+8}}(AX), {{regs[1]}} 83 {%- set regs = regs[2:] -%} 84 {%- else %} 85 // {{arg.name}} (sizeof {{size}}) 86 {%- for aoff in range(0, size, 4) %} 87 MOVL {{ain+aoff}}(AX), R10 88 MOVL R10, {{soff+aoff}}(SP) 89 {%- endfor -%} 90 {%- set soff = soff + size -%} 91 {%- endif -%} 92 {%- set ain = ain + size -%} 93 {%- endfor -%} 94 {%- endmacro -%} 95 96 {% if False %} 97 // goargs sets up the arguments, converting to the Go calling convention, 98 // where everything is passed on the stack, from the gcc calling convention, where: 99 // - integer args are passed in registers DI, SI, DX, CX, R8, R9. 100 // - float args are passed in registers X0, ..., X5. 101 // - structs smaller than 16 bytes are passed in registers. 102 // - everything else is passed on the stack. 103 // 104 // AX refers to the caller stack frame. 105 // SP refers the the callee stack frame. 106 // Destroys DX. 107 {% endif %} 108 {% macro goargs(args, ain) -%} 109 {%- set regs = ['DI', 'SI', 'DX', 'CX', 'R8', 'R9'] -%} 110 {%- set fregs = ['X0', 'X1', 'X2', 'X3', 'X4', 'X5'] -%} 111 {%- set soff = 0 -%} 112 {%- for arg in args -%} 113 {%- set ty = arg.type -%} 114 {%- set kind = ty.kind -%} 115 {%- set size = ty.size -%} 116 {%- if ty.align > 0 %} 117 {%- set ain = align(ain, ty.align) -%} 118 {%- endif -%} 119 {%- if kind == 'float32' and fregs.__len__() >= 1 %} 120 MOVSS {{fregs[0]}}, {{ain}}(SP) // {{arg.name}} 121 {%- set fregs = fregs[1:] -%} 122 {%- elif kind == 'float64' and fregs.__len__() >= 1 %} 123 MOVSD {{fregs[0]}}, {{ain}}(SP) // {{arg.name}} 124 {%- set fregs = fregs[1:] -%} 125 {%- elif size == 4 and regs.__len__() >= 1 %} 126 MOVL {{regs[0]}}, {{ain}}(SP) // {{arg.name}} 127 {%- set regs = regs[1:] -%} 128 {%- elif size == 8 and regs.__len__() >= 1 %} 129 MOVQ {{regs[0]}}, {{ain}}(SP) // {{arg.name}} 130 {%- set regs = regs[1:] -%} 131 {%- elif size == 12 and regs.__len__() >= 2 %} 132 MOVQ {{regs[0]}}, {{ain}}(SP) // {{arg.name}} (sizeof {{size}}) 133 MOVL {{regs[1]}}, {{ain+8}}(SP) 134 {%- set regs = regs[2:] -%} 135 {%- elif size == 16 and regs.__len__() >= 2 %} 136 MOVQ {{regs[0]}}, {{ain}}(SP) // {{arg.name}} (sizeof {{size}}) 137 MOVQ {{regs[1]}}, {{ain+8}}(SP) 138 {%- set regs = regs[2:] -%} 139 {%- else %} 140 // {{arg.name}} (sizeof {{size}}) 141 {%- for aoff in range(0, size, 4) %} 142 MOVL {{soff+aoff}}(FP), DX 143 MOVL DX, {{ain+aoff}}(SP) 144 {%- endfor -%} 145 {%- set soff = soff + size -%} 146 {%- endif -%} 147 {%- set ain = ain + size -%} 148 {%- endfor -%} 149 {%- endmacro -%} 150 151 // Callbacks are invoked through cgocallback. 152 {% for func in callbacks -%} 153 {% set fsize = align(framesize(func),8) -%} 154 TEXT ppapi·{{func.name}}(SB),NOSPLIT,${{align(fsize+56,16)}} 155 LEAL 0(BP), AX 156 MOVL AX, {{fsize+20}}(SP) 157 MOVQ BX, {{fsize+24}}(SP) 158 MOVQ R12, {{fsize+32}}(SP) 159 MOVQ R13, {{fsize+40}}(SP) 160 MOVQ R14, {{fsize+48}}(SP) 161 {{- goargs(func.args, 16) }} 162 MOVL $0, {{fsize+16}}(SP) 163 LEAL ·{{func.name}}(SB), AX 164 MOVL AX, 0(SP) 165 LEAL 16(SP), AX 166 MOVL AX, 4(SP) 167 MOVL ${{fsize+4}}, 8(SP) 168 CALL runtime·cgocallback(SB) 169 MOVL {{fsize+16}}(SP), AX 170 MOVL {{fsize+20}}(SP), BX 171 LEAL 0(BX), BP 172 MOVQ {{fsize+24}}(SP), BX 173 MOVQ {{fsize+32}}(SP), R12 174 MOVQ {{fsize+40}}(SP), R13 175 MOVQ {{fsize+48}}(SP), R14 176 RET 177 178 {% endfor %} 179 180 // PPAPI calls are invoked using cgocall. 181 {% for func in functions -%} 182 {% set fsize = framesize(func) -%} 183 {% set asize = align(fsize, 16)+8 -%} 184 TEXT ·{{func.name}}(SB),NOSPLIT,$8 185 GO_ARGS 186 NO_LOCAL_POINTERS 187 LEAL ppapi·{{func.name}}(SB), AX 188 MOVL AX, 0(SP) 189 LEAL arg0+0(FP), AX 190 MOVL AX, 4(SP) 191 CALL runtime·cgocall(SB) 192 RET 193 194 // Called on the C stack. 195 {% if func.structReturn and func.result.size <= 16 -%} 196 TEXT ppapi·{{func.name}}(SB),NOSPLIT,${{asize}} 197 MOVL DI, AX 198 MOVL 0(AX), DX // *rval 199 MOVL DX, {{asize-4}}(SP) 200 ADDL $4, AX 201 {{- amd64args(func.args[1:]) }} 202 MOVL ppapi·ppb_interfaces+({{func.interface}}*8+4)(SB), AX 203 MOVL ({{func.index}}*4)(AX), AX 204 CALL AX 205 MOVL {{asize-4}}(SP), DI 206 {{ amd64return(func.result, 0, 'DI') }} 207 RET 208 {% else -%} 209 TEXT ppapi·{{func.name}}(SB),NOSPLIT,${{asize}} 210 MOVL DI, AX 211 MOVL AX, {{asize-4}}(SP) 212 {{- amd64args(func.args) }} 213 MOVL ppapi·ppb_interfaces+({{func.interface}}*8+4)(SB), AX 214 MOVL ({{func.index}}*4)(AX), AX 215 CALL AX 216 {% if func.structReturn -%} 217 // Struct returned as *return_struct (sizeof {{func.result.size}}). 218 {%- else -%} 219 MOVL {{asize-4}}(SP), DI 220 {{ amd64return(func.result, align(fsize, 8), 'DI') }} 221 {%- endif %} 222 RET 223 {% endif %} 224 {% endfor %} 225 226 // ppapi·ppp_initialize_module_handler is called once at initialization 227 // initialization time. Called on the C stack. 228 TEXT ppapi·ppp_initialize_module_handler(SB),NOSPLIT,$24 229 MOVQ R13, 0(SP) 230 MOVQ R14, 8(SP) 231 MOVL DI, ppapi·module_id(SB) // module_id 232 MOVL SI, R14 // get_interface 233 LEAL ppapi·ppb_interfaces(SB), R13 234 initialize_module_loop: 235 MOVL 0(R13), DI // name 236 TESTL DI, DI 237 JZ initialize_module_done 238 CALL R14 239 MOVL AX, 4(R13) // ppb 240 ADDL $8, R13 241 JMP initialize_module_loop 242 initialize_module_done: 243 MOVQ 0(SP), R13 244 MOVQ 8(SP), R14 245 XORL AX, AX 246 RET 247 248 // ppapi·ppp_shutdown_module_handler may or may not be called when the 249 // module is closed. Ignore the callback. Called on the C stack. 250 TEXT ppapi·ppp_shutdown_module_handler(SB),NOSPLIT,$0 251 RET 252 253 // ppapi·ppp_get_interface_handler is called by the browser to get 254 // callback functions. Called on the C stack. 255 TEXT ppapi·ppp_get_interface_handler(SB),NOSPLIT,$48 256 MOVQ BX, 16(SP) 257 MOVQ R12, 24(SP) 258 MOVQ R13, 32(SP) 259 MOVQ R14, 40(SP) 260 MOVL DI, 0(SP) // interface_name 261 CALL ppapi·ppp_get_interface(SB) 262 MOVQ 16(SP), BX 263 MOVQ 24(SP), R12 264 MOVQ 32(SP), R13 265 MOVQ 40(SP), R14 266 RET 267 268 // ppapi·start is called to start PPAPI. Never returns. 269 // Called on the C stack. 270 TEXT ppapi·start(SB),NOSPLIT,$8 271 LEAL 0(SP), BP 272 LEAL ppapi·pp_start_functions(SB), DI 273 MOVL runtime·nacl_irt_ppapihook_v0_1+IRT_PPAPI_START(SB), AX 274 CALL AX 275 RET 276 277 // Called from syscall package to initialize PPAPI. 278 TEXT syscall·runtime_ppapi_InitPPAPI(SB),NOSPLIT,$8-0 279 NO_LOCAL_POINTERS 280 LEAL ppapi·start(SB), AX 281 MOVL AX, 0(SP) 282 MOVL $0, 4(SP) 283 CALL runtime·cgocall(SB) 284 // Not reached 285 INT $3 286 RET 287 288 // Tunnel some functions from runtime. 289 TEXT ·gostring(SB),NOSPLIT,$0 290 JMP runtime·gostring(SB) 291 292 TEXT ·gostringn(SB),NOSPLIT,$0 293 JMP runtime·gostringn(SB) 294 295 TEXT ·free(SB),NOSPLIT,$0 296 JMP runtime·cfree(SB)