github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/sys_solaris_sparc64.s (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  //
     5  // System calls and other sys.stuff for SPARC64, Solaris.
     6  //
     7  
     8  #include "go_asm.h"
     9  #include "go_tls.h"
    10  #include "textflag.h"
    11  #include "asm_sparc64.h"
    12  
    13  // void libc_miniterrno(void *(*___errno)(void));
    14  //
    15  // Set the TLS errno pointer in M.
    16  //
    17  // Called using runtime·asmcgocall from os_solaris.c:/minit.
    18  // NOT USING GO CALLING CONVENTION.
    19  TEXT runtime·miniterrno(SB),NOSPLIT|REGWIN,$0
    20  	// asmcgocall will put first argument into I0.
    21  	CALL	I0	// SysV ABI so returns in O0
    22  	CALL	runtime·load_g(SB)
    23  	MOVD	g_m(g), I3
    24  	MOVD	O0,	(m_mOS+mOS_perrno)(I3)
    25  	RET
    26  
    27  // int64 runtime·nanotime1(void);
    28  //
    29  // clock_gettime(3c) wrapper because Timespec is too large for
    30  // runtime·nanotime stack.
    31  //
    32  // Called using runtime·sysvicall6 from os_solaris.c:/nanotime.
    33  // NOT USING GO CALLING CONVENTION.
    34  TEXT runtime·nanotime1(SB),NOSPLIT|REGWIN,$64
    35  	MOVW	$3, O0	// CLOCK_REALTIME from <sys/time_impl.h>
    36  	MOVD	$tv-16(SP), O1
    37  	MOVD	$libc_clock_gettime(SB), I3
    38  	CALL	I3
    39  	MOVD	tv_sec-16(SP), I3	// tv_sec from struct timespec
    40  	MOVD	$1000000000, I1
    41  	MULD	I1, I3	// multiply into nanoseconds
    42  	MOVD	tv_nsec-8(SP), I5	// tv_nsec, offset should be stable.
    43  	ADD	I5, I3, I0
    44  	RET
    45  
    46  // pipe(3c) wrapper that returns fds in AX, DX.
    47  // NOT USING GO CALLING CONVENTION.
    48  TEXT runtime·pipe1(SB),NOSPLIT|REGWIN,$16
    49  	MOVD	$FIXED_FRAME(BSP), O0
    50  	MOVD	$libc_pipe(SB), I3
    51  	CALL	I3
    52  	MOVW	(FIXED_FRAME+0)(BSP), I0
    53  	MOVW	(FIXED_FRAME+4)(BSP), I1
    54  	RET
    55  
    56  // Call a library function with SysV calling conventions.
    57  // The called function can take a maximum of 6 INTEGER class arguments,
    58  // see 
    59  // 	SYSTEM V APPLICATION BINARY INTERFACE
    60  // 	SPARC Version 9 Processor Supplement
    61  // section 3.2.2.
    62  //
    63  // Called by runtime·asmcgocall or runtime·cgocall.
    64  // NOT USING GO CALLING CONVENTION.
    65  TEXT runtime·asmsysvicall6(SB),NOSPLIT|REGWIN,$0
    66  	// asmcgocall will put first argument into I0.
    67  	MOVD	I0, L6
    68  	MOVD	libcall_fn(I0), I3
    69  	MOVD	libcall_args(I0), L1
    70  	MOVD	libcall_n(I0), L2
    71  
    72  	CMP	ZR, g
    73  	BED	skiperrno1
    74  	MOVD	g_m(g), I5
    75  	MOVD	(m_mOS+mOS_perrno)(I5), I1
    76  	CMP	I1, ZR
    77  	BED	skiperrno1
    78  	MOVW	ZR, (I1)
    79  
    80  skiperrno1:
    81  	CMP	L1, ZR
    82  	BED	skipargs
    83  	// Load 6 args into correspondent registers.
    84  	MOVD	0(L1), O0
    85  	MOVD	8(L1), O1
    86  	MOVD	16(L1), O2
    87  	MOVD	24(L1), O3
    88  	MOVD	32(L1), O4
    89  	MOVD	40(L1), O5
    90  skipargs:
    91  
    92  	MOVD	g, L1
    93  	// Call SysV function
    94  	CALL	I3
    95  	MOVD	L1, g
    96  
    97  	// Return result
    98  	MOVD	O0, libcall_r1(L6)
    99  	MOVD	O1, libcall_r2(L6)
   100  	MOVD	O0, I0
   101  	MOVD	O1, I1
   102  
   103  	CMP	g, ZR
   104  	BED	skiperrno2
   105  	MOVD	g_m(g), I5
   106  	MOVD	(m_mOS+mOS_perrno)(I5), I4
   107  	CMP	I4, ZR
   108  	BED	skiperrno2
   109  	MOVW	(I4), I4
   110  	MOVD	I4, libcall_err(L6)
   111  
   112  skiperrno2:	
   113  	RET
   114  
   115  // uint32 tstart_sysvicall(M *newm);
   116  TEXT runtime·tstart_sysvicall(SB),NOSPLIT|REGWIN,$0
   117  	// I0 contains first arg newm
   118  	MOVD	m_g0(I0), g		// g
   119  	MOVD	I0, g_m(g)
   120  
   121  	CALL	runtime·save_g(SB)
   122  
   123  	// Layout new m scheduler stack on os stack.
   124  	MOVD	BSP, I3
   125  	MOVD	I3, (g_stack+stack_hi)(g)
   126  	SUB	$(0x100000), I3		// stack size
   127  	MOVD	I3, (g_stack+stack_lo)(g)
   128  	ADD	$const__StackGuard, I3
   129  	MOVD	I3, g_stackguard0(g)
   130  	MOVD	I3, g_stackguard1(g)
   131  
   132  	// initialize essential registers
   133  	CALL	runtime·reginit(SB)
   134  
   135  	CALL	runtime·stackcheck(SB)
   136  	CALL	runtime·mstart(SB)
   137  
   138  	MOVW	ZR, ret+8(FP)
   139  	RET
   140  
   141  #define SIGTRAMP_FRAME 144
   142  
   143  // Careful, this is called by __sighndlr, a libc function.
   144  // We must preserve registers as per SPARC64 ABI.
   145  TEXT runtime·sigtramp(SB),NOSPLIT|REGWIN,$SIGTRAMP_FRAME
   146  	MOVD	g, L1
   147  	CALL	runtime·load_g(SB)
   148  	CMP	g, ZR
   149  	BNED	allgood
   150  	MOVD	L1, g
   151  	MOVD	I0, (8*0+FIXED_FRAME)(BSP)
   152  	MOVD	ZR, (8*1+FIXED_FRAME)(BSP)
   153  	MOVD	$runtime·badsignal(SB), L1
   154  	CALL	(L1)
   155  	JMP	exit
   156  
   157  allgood:
   158  	// initialize essential registers (just in case)
   159  	CALL	runtime·reginit(SB)
   160  
   161  	// save g
   162  	MOVD	g, (-8-0*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   163  
   164  	// Save m->libcall and m->scratch. We need to do this because we
   165  	// might get interrupted by a signal in runtime·asmcgocall.
   166  
   167  	// save m->libcall 
   168  	MOVD	g_m(g), L1
   169  	MOVD	$m_libcall(L1), L2
   170  	MOVD	libcall_fn(L2), L3
   171  	MOVD	L3, (-8-1*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   172  	MOVD	libcall_args(L2), L3
   173  	MOVD	L3, (-8-2*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   174  	MOVD	libcall_n(L2), L3
   175  	MOVD	L3, (-8-3*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   176  	MOVD	libcall_r1(L2), L3
   177  	MOVD	L3, (-8-4*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   178  	MOVD	libcall_r2(L2), L3
   179  	MOVD	L3, (-8-5*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   180  
   181  	// save m->scratch
   182  	MOVD	$(m_mOS+mOS_scratch)(L1), L2
   183  	MOVD	0(L2), L3
   184  	MOVD	L3, (-8-6*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   185  	MOVD	8(L2), L3
   186  	MOVD	L3, (-8-7*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   187  	MOVD	16(L2), L3
   188  	MOVD	L3, (-8-8*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   189  	MOVD	24(L2), L3
   190  	MOVD	L3, (-8-9*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   191  	MOVD	32(L2), L3
   192  	MOVD	L3, (-8-10*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   193  	MOVD	40(L2), L3
   194  	MOVD	L3, (-8-11*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   195  
   196  	// save errno, it might be EINTR; stuff we do here might reset it.
   197  	MOVD	(m_mOS+mOS_perrno)(L1), L2
   198  	MOVW	0(L2), L2
   199  	MOVD	L2, (-8-12*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP)
   200  
   201  	// prepare call
   202  	MOVW	I0, (8*0+FIXED_FRAME)(BSP)
   203  	MOVD	I1, (8*1+FIXED_FRAME)(BSP)
   204  	MOVD	I2, (8*2+FIXED_FRAME)(BSP)
   205  	MOVD	g, (8*3+FIXED_FRAME)(BSP)
   206  
   207  	// g = m->gsignal
   208  	MOVD	m_gsignal(L1), g
   209  	CALL	runtime·save_g(SB)
   210  
   211  	// TODO(shawn): If current SP is not in gsignal.stack, then assume
   212  	// non-Go code caused a signal and adjust gsignal.stack?
   213  	MOVD	(g_stack+stack_lo)(g), L2
   214  	MOVD	BSP, TMP
   215  	CMP	L2, TMP
   216  	BGED	checkhi
   217  	CALL	runtime·abort(SB)
   218  
   219  checkhi:
   220  	MOVD	(g_stack+stack_hi)(g), L2
   221  	MOVD	BSP, TMP
   222  	CMP	L2, TMP
   223  	BLD	handler
   224  	CALL	runtime·abort(SB)
   225  
   226  handler:
   227  	CALL	runtime·sighandler(SB)
   228  
   229  	MOVD	g_m(g), L1
   230  	// restore libcall
   231  	MOVD	$m_libcall(L1), L2
   232  	MOVD	(-8-1*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   233  	MOVD	L3, libcall_fn(L2)
   234  	MOVD	(-8-2*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   235  	MOVD	L3, libcall_args(L2)
   236  	MOVD	(-8-3*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3	
   237  	MOVD	L3, libcall_n(L2)
   238  	MOVD	(-8-4*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   239  	MOVD	L3, libcall_r1(L2)
   240  	MOVD	(-8-5*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   241  	MOVD	L3, libcall_r2(L2)
   242  
   243  	// restore scratch
   244  	MOVD	$(m_mOS+mOS_scratch)(L1), L2
   245  	MOVD	(-8-6*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   246  	MOVD	L3, 0(L2)
   247  	MOVD	(-8-7*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   248  	MOVD	L3, 8(L2)
   249  	MOVD	(-8-8*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   250  	MOVD	L3, 16(L2)
   251  	MOVD	(-8-9*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   252  	MOVD	L3, 24(L2)
   253  	MOVD	(-8-10*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   254  	MOVD	L3, 32(L2)
   255  	MOVD	(-8-11*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   256  	MOVD	L3, 40(L2)
   257  
   258  	// restore errno
   259  	MOVD	(m_mOS+mOS_perrno)(L1), L2
   260  	MOVD	(-8-12*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3
   261  	MOVW	L3, 0(L2)
   262  
   263  	// restore g
   264  	MOVD	(-8-0*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), g
   265  	CALL	runtime·save_g(SB)
   266  
   267  exit:
   268  	// kernel will restore registers
   269  	RET
   270  
   271  
   272  // Runs on OS stack, called from runtime·usleep1_go.
   273  TEXT runtime·usleep2(SB),NOSPLIT|REGWIN,$0
   274  	MOVW	us+0(FP), O0
   275  	MOVD	$libc_usleep(SB), I3
   276  	CALL	I3
   277  	RET
   278  
   279  // Runs on OS stack, called from runtime·osyield.
   280  TEXT runtime·osyield1(SB),NOSPLIT|REGWIN,$0
   281  	MOVD	$libc_sched_yield(SB), I3
   282  	CALL	I3
   283  	RET