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)