github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/sys_linux_arm.s (about)

     1  // Copyright 2009 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  //
     6  // System calls and other sys.stuff for arm, Linux
     7  //
     8  
     9  #include "zasm_GOOS_GOARCH.h"
    10  #include "../../cmd/ld/textflag.h"
    11  
    12  // for EABI, as we don't support OABI
    13  #define SYS_BASE 0x0
    14  
    15  #define SYS_exit (SYS_BASE + 1)
    16  #define SYS_read (SYS_BASE + 3)
    17  #define SYS_write (SYS_BASE + 4)
    18  #define SYS_open (SYS_BASE + 5)
    19  #define SYS_close (SYS_BASE + 6)
    20  #define SYS_gettimeofday (SYS_BASE + 78)
    21  #define SYS_clone (SYS_BASE + 120)
    22  #define SYS_rt_sigreturn (SYS_BASE + 173)
    23  #define SYS_rt_sigaction (SYS_BASE + 174)
    24  #define SYS_rt_sigprocmask (SYS_BASE + 175)
    25  #define SYS_sigaltstack (SYS_BASE + 186)
    26  #define SYS_mmap2 (SYS_BASE + 192)
    27  #define SYS_futex (SYS_BASE + 240)
    28  #define SYS_exit_group (SYS_BASE + 248)
    29  #define SYS_munmap (SYS_BASE + 91)
    30  #define SYS_madvise (SYS_BASE + 220)
    31  #define SYS_setitimer (SYS_BASE + 104)
    32  #define SYS_mincore (SYS_BASE + 219)
    33  #define SYS_gettid (SYS_BASE + 224)
    34  #define SYS_tkill (SYS_BASE + 238)
    35  #define SYS_sched_yield (SYS_BASE + 158)
    36  #define SYS_select (SYS_BASE + 142) // newselect
    37  #define SYS_ugetrlimit (SYS_BASE + 191)
    38  #define SYS_sched_getaffinity (SYS_BASE + 242)
    39  #define SYS_clock_gettime (SYS_BASE + 263)
    40  #define SYS_epoll_create (SYS_BASE + 250)
    41  #define SYS_epoll_ctl (SYS_BASE + 251)
    42  #define SYS_epoll_wait (SYS_BASE + 252)
    43  #define SYS_epoll_create1 (SYS_BASE + 357)
    44  #define SYS_fcntl (SYS_BASE + 55)
    45  
    46  #define ARM_BASE (SYS_BASE + 0x0f0000)
    47  
    48  TEXT runtime·open(SB),NOSPLIT,$0
    49  	MOVW	0(FP), R0
    50  	MOVW	4(FP), R1
    51  	MOVW	8(FP), R2
    52  	MOVW	$SYS_open, R7
    53  	SWI	$0
    54  	RET
    55  
    56  TEXT runtime·close(SB),NOSPLIT,$0
    57  	MOVW	0(FP), R0
    58  	MOVW	$SYS_close, R7
    59  	SWI	$0
    60  	RET
    61  
    62  TEXT runtime·write(SB),NOSPLIT,$0
    63  	MOVW	0(FP), R0
    64  	MOVW	4(FP), R1
    65  	MOVW	8(FP), R2
    66  	MOVW	$SYS_write, R7
    67  	SWI	$0
    68  	RET
    69  
    70  TEXT runtime·read(SB),NOSPLIT,$0
    71  	MOVW	0(FP), R0
    72  	MOVW	4(FP), R1
    73  	MOVW	8(FP), R2
    74  	MOVW	$SYS_read, R7
    75  	SWI	$0
    76  	RET
    77  
    78  TEXT runtime·getrlimit(SB),NOSPLIT,$0
    79  	MOVW	0(FP), R0
    80  	MOVW	4(FP), R1
    81  	MOVW	$SYS_ugetrlimit, R7
    82  	SWI	$0
    83  	RET
    84  
    85  TEXT runtime·exit(SB),NOSPLIT,$-4
    86  	MOVW	0(FP), R0
    87  	MOVW	$SYS_exit_group, R7
    88  	SWI	$0
    89  	MOVW	$1234, R0
    90  	MOVW	$1002, R1
    91  	MOVW	R0, (R1)	// fail hard
    92  
    93  TEXT runtime·exit1(SB),NOSPLIT,$-4
    94  	MOVW	0(FP), R0
    95  	MOVW	$SYS_exit, R7
    96  	SWI	$0
    97  	MOVW	$1234, R0
    98  	MOVW	$1003, R1
    99  	MOVW	R0, (R1)	// fail hard
   100  
   101  TEXT	runtime·raise(SB),NOSPLIT,$-4
   102  	MOVW	$SYS_gettid, R7
   103  	SWI	$0
   104  	// arg 1 tid already in R0 from gettid
   105  	MOVW	sig+0(FP), R1	// arg 2 - signal
   106  	MOVW	$SYS_tkill, R7
   107  	SWI	$0
   108  	RET
   109  
   110  TEXT runtime·mmap(SB),NOSPLIT,$0
   111  	MOVW	0(FP), R0
   112  	MOVW	4(FP), R1
   113  	MOVW	8(FP), R2
   114  	MOVW	12(FP), R3
   115  	MOVW	16(FP), R4
   116  	MOVW	20(FP), R5
   117  	MOVW	$SYS_mmap2, R7
   118  	SWI	$0
   119  	MOVW	$0xfffff001, R6
   120  	CMP		R6, R0
   121  	RSB.HI	$0, R0
   122  	RET
   123  
   124  TEXT runtime·munmap(SB),NOSPLIT,$0
   125  	MOVW	0(FP), R0
   126  	MOVW	4(FP), R1
   127  	MOVW	$SYS_munmap, R7
   128  	SWI	$0
   129  	MOVW	$0xfffff001, R6
   130  	CMP 	R6, R0
   131  	MOVW.HI	$0, R8  // crash on syscall failure
   132  	MOVW.HI	R8, (R8)
   133  	RET
   134  
   135  TEXT runtime·madvise(SB),NOSPLIT,$0
   136  	MOVW	0(FP), R0
   137  	MOVW	4(FP), R1
   138  	MOVW	8(FP), R2
   139  	MOVW	$SYS_madvise, R7
   140  	SWI	$0
   141  	// ignore failure - maybe pages are locked
   142  	RET
   143  
   144  TEXT runtime·setitimer(SB),NOSPLIT,$0
   145  	MOVW	0(FP), R0
   146  	MOVW	4(FP), R1
   147  	MOVW	8(FP), R2
   148  	MOVW	$SYS_setitimer, R7
   149  	SWI	$0
   150  	RET
   151  
   152  TEXT runtime·mincore(SB),NOSPLIT,$0
   153  	MOVW	0(FP), R0
   154  	MOVW	4(FP), R1
   155  	MOVW	8(FP), R2
   156  	MOVW	$SYS_mincore, R7
   157  	SWI	$0
   158  	RET
   159  
   160  TEXT time·now(SB), NOSPLIT, $32
   161  	MOVW	$0, R0  // CLOCK_REALTIME
   162  	MOVW	$8(R13), R1  // timespec
   163  	MOVW	$SYS_clock_gettime, R7
   164  	SWI	$0
   165  	
   166  	MOVW	8(R13), R0  // sec
   167  	MOVW	12(R13), R2  // nsec
   168  	
   169  	MOVW	R0, 0(FP)
   170  	MOVW	$0, R1
   171  	MOVW	R1, 4(FP)
   172  	MOVW	R2, 8(FP)
   173  	RET	
   174  
   175  // int64 nanotime(void) so really
   176  // void nanotime(int64 *nsec)
   177  TEXT runtime·nanotime(SB),NOSPLIT,$32
   178  	MOVW	$0, R0  // CLOCK_REALTIME
   179  	MOVW	$8(R13), R1  // timespec
   180  	MOVW	$SYS_clock_gettime, R7
   181  	SWI	$0
   182  	
   183  	MOVW	8(R13), R0  // sec
   184  	MOVW	12(R13), R2  // nsec
   185  	
   186  	MOVW	$1000000000, R3
   187  	MULLU	R0, R3, (R1, R0)
   188  	MOVW	$0, R4
   189  	ADD.S	R2, R0
   190  	ADC	R4, R1
   191  
   192  	MOVW	0(FP), R3
   193  	MOVW	R0, 0(R3)
   194  	MOVW	R1, 4(R3)
   195  	RET
   196  
   197  // int32 futex(int32 *uaddr, int32 op, int32 val,
   198  //	struct timespec *timeout, int32 *uaddr2, int32 val2);
   199  TEXT runtime·futex(SB),NOSPLIT,$0
   200  	MOVW	4(SP), R0
   201  	MOVW	8(SP), R1
   202  	MOVW	12(SP), R2
   203  	MOVW	16(SP), R3
   204  	MOVW	20(SP), R4
   205  	MOVW	24(SP), R5
   206  	MOVW	$SYS_futex, R7
   207  	SWI	$0
   208  	RET
   209  
   210  
   211  // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
   212  TEXT runtime·clone(SB),NOSPLIT,$0
   213  	MOVW	flags+0(FP), R0
   214  	MOVW	stack+4(FP), R1
   215  	MOVW	$0, R2	// parent tid ptr
   216  	MOVW	$0, R3	// tls_val
   217  	MOVW	$0, R4	// child tid ptr
   218  	MOVW	$0, R5
   219  
   220  	// Copy mp, gp, fn off parent stack for use by child.
   221  	// TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying
   222  	MOVW	$-16(R1), R1
   223  	MOVW	mm+8(FP), R6
   224  	MOVW	R6, 0(R1)
   225  	MOVW	gg+12(FP), R6
   226  	MOVW	R6, 4(R1)
   227  	MOVW	fn+16(FP), R6
   228  	MOVW	R6, 8(R1)
   229  	MOVW	$1234, R6
   230  	MOVW	R6, 12(R1)
   231  
   232  	MOVW	$SYS_clone, R7
   233  	SWI	$0
   234  
   235  	// In parent, return.
   236  	CMP	$0, R0
   237  	BEQ	2(PC)
   238  	RET
   239  
   240  	// Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
   241  	MOVW	12(R13), R0
   242  	MOVW	$1234, R1
   243  	CMP	R0, R1
   244  	BEQ	2(PC)
   245  	BL	runtime·abort(SB)
   246  
   247  	MOVW	0(R13), m
   248  	MOVW	4(R13), g
   249  
   250  	// paranoia; check they are not nil
   251  	MOVW	0(m), R0
   252  	MOVW	0(g), R0
   253  
   254  	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   255  
   256  	// Initialize m->procid to Linux tid
   257  	MOVW	$SYS_gettid, R7
   258  	SWI	$0
   259  	MOVW	R0, m_procid(m)
   260  
   261  	// Call fn
   262  	MOVW	8(R13), R0
   263  	MOVW	$16(R13), R13
   264  	BL	(R0)
   265  
   266  	MOVW	$0, R0
   267  	MOVW	R0, 4(R13)
   268  	BL	runtime·exit1(SB)
   269  
   270  	// It shouldn't return
   271  	MOVW	$1234, R0
   272  	MOVW	$1005, R1
   273  	MOVW	R0, (R1)
   274  
   275  TEXT runtime·sigaltstack(SB),NOSPLIT,$0
   276  	MOVW	0(FP), R0
   277  	MOVW	4(FP), R1
   278  	MOVW	$SYS_sigaltstack, R7
   279  	SWI	$0
   280  	MOVW	$0xfffff001, R6
   281  	CMP 	R6, R0
   282  	MOVW.HI	$0, R8  // crash on syscall failure
   283  	MOVW.HI	R8, (R8)
   284  	RET
   285  
   286  TEXT runtime·sigtramp(SB),NOSPLIT,$24
   287  	// this might be called in external code context,
   288  	// where g and m are not set.
   289  	// first save R0, because runtime·load_gm will clobber it
   290  	MOVW	R0, 4(R13)
   291  	MOVB	runtime·iscgo(SB), R0
   292  	CMP 	$0, R0
   293  	BL.NE	runtime·load_gm(SB)
   294  
   295  	CMP 	$0, m
   296  	BNE 	4(PC)
   297  	// signal number is already prepared in 4(R13)
   298  	MOVW  	$runtime·badsignal(SB), R11
   299  	BL	(R11)
   300  	RET
   301  
   302  	// save g
   303  	MOVW	g, R3
   304  	MOVW	g, 20(R13)
   305  
   306  	// g = m->gsignal
   307  	MOVW	m_gsignal(m), g
   308  
   309  	// copy arguments for call to sighandler
   310  	// R0 is already saved above
   311  	MOVW	R1, 8(R13)
   312  	MOVW	R2, 12(R13)
   313  	MOVW	R3, 16(R13)
   314  
   315  	BL	runtime·sighandler(SB)
   316  
   317  	// restore g
   318  	MOVW	20(R13), g
   319  
   320  	RET
   321  
   322  TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
   323  	MOVW	0(FP), R0
   324  	MOVW	4(FP), R1
   325  	MOVW	8(FP), R2
   326  	MOVW	12(FP), R3
   327  	MOVW	$SYS_rt_sigprocmask, R7
   328  	SWI	$0
   329  	RET
   330  
   331  TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
   332  	MOVW	0(FP), R0
   333  	MOVW	4(FP), R1
   334  	MOVW	8(FP), R2
   335  	MOVW	12(FP), R3
   336  	MOVW	$SYS_rt_sigaction, R7
   337  	SWI	$0
   338  	RET
   339  
   340  TEXT runtime·sigreturn(SB),NOSPLIT,$0
   341  	MOVW	$SYS_rt_sigreturn, R7
   342  	SWI	$0
   343  	RET
   344  
   345  TEXT runtime·usleep(SB),NOSPLIT,$12
   346  	MOVW	usec+0(FP), R0
   347  	MOVW	R0, R1
   348  	MOVW	$1000000, R2
   349  	DIV	R2, R0
   350  	MOD	R2, R1
   351  	MOVW	R0, 4(SP)
   352  	MOVW	R1, 8(SP)
   353  	MOVW	$0, R0
   354  	MOVW	$0, R1
   355  	MOVW	$0, R2
   356  	MOVW	$0, R3
   357  	MOVW	$4(SP), R4
   358  	MOVW	$SYS_select, R7
   359  	SWI	$0
   360  	RET
   361  
   362  // Use kernel version instead of native armcas in asm_arm.s.
   363  // See ../sync/atomic/asm_linux_arm.s for details.
   364  TEXT cas<>(SB),NOSPLIT,$0
   365  	MOVW	$0xffff0fc0, PC
   366  
   367  TEXT runtime·cas(SB),NOSPLIT,$0
   368  	MOVW	valptr+0(FP), R2
   369  	MOVW	old+4(FP), R0
   370  casagain:
   371  	MOVW	new+8(FP), R1
   372  	BL	cas<>(SB)
   373  	BCC	cascheck
   374  	MOVW	$1, R0
   375  	RET
   376  cascheck:
   377  	// Kernel lies; double-check.
   378  	MOVW	valptr+0(FP), R2
   379  	MOVW	old+4(FP), R0
   380  	MOVW	0(R2), R3
   381  	CMP	R0, R3
   382  	BEQ	casagain
   383  	MOVW	$0, R0
   384  	RET
   385  
   386  TEXT runtime·casp(SB),NOSPLIT,$0
   387  	B	runtime·cas(SB)
   388  
   389  TEXT runtime·osyield(SB),NOSPLIT,$0
   390  	MOVW	$SYS_sched_yield, R7
   391  	SWI	$0
   392  	RET
   393  
   394  TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
   395  	MOVW	0(FP), R0
   396  	MOVW	4(FP), R1
   397  	MOVW	8(FP), R2
   398  	MOVW	$SYS_sched_getaffinity, R7
   399  	SWI	$0
   400  	RET
   401  
   402  // int32 runtime·epollcreate(int32 size)
   403  TEXT runtime·epollcreate(SB),NOSPLIT,$0
   404  	MOVW	0(FP), R0
   405  	MOVW	$SYS_epoll_create, R7
   406  	SWI	$0
   407  	RET
   408  
   409  // int32 runtime·epollcreate1(int32 flags)
   410  TEXT runtime·epollcreate1(SB),NOSPLIT,$0
   411  	MOVW	0(FP), R0
   412  	MOVW	$SYS_epoll_create1, R7
   413  	SWI	$0
   414  	RET
   415  
   416  // int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev)
   417  TEXT runtime·epollctl(SB),NOSPLIT,$0
   418  	MOVW	0(FP), R0
   419  	MOVW	4(FP), R1
   420  	MOVW	8(FP), R2
   421  	MOVW	12(FP), R3
   422  	MOVW	$SYS_epoll_ctl, R7
   423  	SWI	$0
   424  	RET
   425  
   426  // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
   427  TEXT runtime·epollwait(SB),NOSPLIT,$0
   428  	MOVW	0(FP), R0
   429  	MOVW	4(FP), R1
   430  	MOVW	8(FP), R2
   431  	MOVW	12(FP), R3
   432  	MOVW	$SYS_epoll_wait, R7
   433  	SWI	$0
   434  	RET
   435  
   436  // void runtime·closeonexec(int32 fd)
   437  TEXT runtime·closeonexec(SB),NOSPLIT,$0
   438  	MOVW	0(FP), R0	// fd
   439  	MOVW	$2, R1	// F_SETFD
   440  	MOVW	$1, R2	// FD_CLOEXEC
   441  	MOVW	$SYS_fcntl, R7
   442  	SWI	$0
   443  	RET
   444  
   445  // b __kuser_get_tls @ 0xffff0fe0
   446  TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
   447  	MOVW	$0xffff0fe0, R0
   448  	B	(R0)