...
Run Format

Text file src/runtime/sys_linux_arm.s

Documentation: runtime

     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 "go_asm.h"
    10	#include "go_tls.h"
    11	#include "textflag.h"
    12	
    13	// for EABI, as we don't support OABI
    14	#define SYS_BASE 0x0
    15	
    16	#define SYS_exit (SYS_BASE + 1)
    17	#define SYS_read (SYS_BASE + 3)
    18	#define SYS_write (SYS_BASE + 4)
    19	#define SYS_open (SYS_BASE + 5)
    20	#define SYS_close (SYS_BASE + 6)
    21	#define SYS_getpid (SYS_BASE + 20)
    22	#define SYS_kill (SYS_BASE + 37)
    23	#define SYS_gettimeofday (SYS_BASE + 78)
    24	#define SYS_clone (SYS_BASE + 120)
    25	#define SYS_rt_sigreturn (SYS_BASE + 173)
    26	#define SYS_rt_sigaction (SYS_BASE + 174)
    27	#define SYS_rt_sigprocmask (SYS_BASE + 175)
    28	#define SYS_sigaltstack (SYS_BASE + 186)
    29	#define SYS_mmap2 (SYS_BASE + 192)
    30	#define SYS_futex (SYS_BASE + 240)
    31	#define SYS_exit_group (SYS_BASE + 248)
    32	#define SYS_munmap (SYS_BASE + 91)
    33	#define SYS_madvise (SYS_BASE + 220)
    34	#define SYS_setitimer (SYS_BASE + 104)
    35	#define SYS_mincore (SYS_BASE + 219)
    36	#define SYS_gettid (SYS_BASE + 224)
    37	#define SYS_tkill (SYS_BASE + 238)
    38	#define SYS_sched_yield (SYS_BASE + 158)
    39	#define SYS_pselect6 (SYS_BASE + 335)
    40	#define SYS_ugetrlimit (SYS_BASE + 191)
    41	#define SYS_sched_getaffinity (SYS_BASE + 242)
    42	#define SYS_clock_gettime (SYS_BASE + 263)
    43	#define SYS_epoll_create (SYS_BASE + 250)
    44	#define SYS_epoll_ctl (SYS_BASE + 251)
    45	#define SYS_epoll_wait (SYS_BASE + 252)
    46	#define SYS_epoll_create1 (SYS_BASE + 357)
    47	#define SYS_fcntl (SYS_BASE + 55)
    48	#define SYS_access (SYS_BASE + 33)
    49	#define SYS_connect (SYS_BASE + 283)
    50	#define SYS_socket (SYS_BASE + 281)
    51	#define SYS_brk (SYS_BASE + 45)
    52	
    53	#define ARM_BASE (SYS_BASE + 0x0f0000)
    54	
    55	TEXT runtime·open(SB),NOSPLIT,$0
    56		MOVW	name+0(FP), R0
    57		MOVW	mode+4(FP), R1
    58		MOVW	perm+8(FP), R2
    59		MOVW	$SYS_open, R7
    60		SWI	$0
    61		MOVW	$0xfffff001, R1
    62		CMP	R1, R0
    63		MOVW.HI	$-1, R0
    64		MOVW	R0, ret+12(FP)
    65		RET
    66	
    67	TEXT runtime·closefd(SB),NOSPLIT,$0
    68		MOVW	fd+0(FP), R0
    69		MOVW	$SYS_close, R7
    70		SWI	$0
    71		MOVW	$0xfffff001, R1
    72		CMP	R1, R0
    73		MOVW.HI	$-1, R0
    74		MOVW	R0, ret+4(FP)
    75		RET
    76	
    77	TEXT runtime·write(SB),NOSPLIT,$0
    78		MOVW	fd+0(FP), R0
    79		MOVW	p+4(FP), R1
    80		MOVW	n+8(FP), R2
    81		MOVW	$SYS_write, R7
    82		SWI	$0
    83		MOVW	$0xfffff001, R1
    84		CMP	R1, R0
    85		MOVW.HI	$-1, R0
    86		MOVW	R0, ret+12(FP)
    87		RET
    88	
    89	TEXT runtime·read(SB),NOSPLIT,$0
    90		MOVW	fd+0(FP), R0
    91		MOVW	p+4(FP), R1
    92		MOVW	n+8(FP), R2
    93		MOVW	$SYS_read, R7
    94		SWI	$0
    95		MOVW	$0xfffff001, R1
    96		CMP	R1, R0
    97		MOVW.HI	$-1, R0
    98		MOVW	R0, ret+12(FP)
    99		RET
   100	
   101	TEXT runtime·getrlimit(SB),NOSPLIT,$0
   102		MOVW	kind+0(FP), R0
   103		MOVW	limit+4(FP), R1
   104		MOVW	$SYS_ugetrlimit, R7
   105		SWI	$0
   106		MOVW	R0, ret+8(FP)
   107		RET
   108	
   109	TEXT runtime·exit(SB),NOSPLIT,$-4
   110		MOVW	code+0(FP), R0
   111		MOVW	$SYS_exit_group, R7
   112		SWI	$0
   113		MOVW	$1234, R0
   114		MOVW	$1002, R1
   115		MOVW	R0, (R1)	// fail hard
   116	
   117	TEXT runtime·exit1(SB),NOSPLIT,$-4
   118		MOVW	code+0(FP), R0
   119		MOVW	$SYS_exit, R7
   120		SWI	$0
   121		MOVW	$1234, R0
   122		MOVW	$1003, R1
   123		MOVW	R0, (R1)	// fail hard
   124	
   125	TEXT runtime·gettid(SB),NOSPLIT,$0-4
   126		MOVW	$SYS_gettid, R7
   127		SWI	$0
   128		MOVW	R0, ret+0(FP)
   129		RET
   130	
   131	TEXT	runtime·raise(SB),NOSPLIT,$-4
   132		MOVW	$SYS_gettid, R7
   133		SWI	$0
   134		// arg 1 tid already in R0 from gettid
   135		MOVW	sig+0(FP), R1	// arg 2 - signal
   136		MOVW	$SYS_tkill, R7
   137		SWI	$0
   138		RET
   139	
   140	TEXT	runtime·raiseproc(SB),NOSPLIT,$-4
   141		MOVW	$SYS_getpid, R7
   142		SWI	$0
   143		// arg 1 tid already in R0 from getpid
   144		MOVW	sig+0(FP), R1	// arg 2 - signal
   145		MOVW	$SYS_kill, R7
   146		SWI	$0
   147		RET
   148	
   149	TEXT runtime·mmap(SB),NOSPLIT,$0
   150		MOVW	addr+0(FP), R0
   151		MOVW	n+4(FP), R1
   152		MOVW	prot+8(FP), R2
   153		MOVW	flags+12(FP), R3
   154		MOVW	fd+16(FP), R4
   155		MOVW	off+20(FP), R5
   156		MOVW	$SYS_mmap2, R7
   157		SWI	$0
   158		MOVW	$0xfffff001, R6
   159		CMP		R6, R0
   160		RSB.HI	$0, R0
   161		MOVW	R0, ret+24(FP)
   162		RET
   163	
   164	TEXT runtime·munmap(SB),NOSPLIT,$0
   165		MOVW	addr+0(FP), R0
   166		MOVW	n+4(FP), R1
   167		MOVW	$SYS_munmap, R7
   168		SWI	$0
   169		MOVW	$0xfffff001, R6
   170		CMP 	R6, R0
   171		MOVW.HI	$0, R8  // crash on syscall failure
   172		MOVW.HI	R8, (R8)
   173		RET
   174	
   175	TEXT runtime·madvise(SB),NOSPLIT,$0
   176		MOVW	addr+0(FP), R0
   177		MOVW	n+4(FP), R1
   178		MOVW	flags+8(FP), R2
   179		MOVW	$SYS_madvise, R7
   180		SWI	$0
   181		// ignore failure - maybe pages are locked
   182		RET
   183	
   184	TEXT runtime·setitimer(SB),NOSPLIT,$0
   185		MOVW	mode+0(FP), R0
   186		MOVW	new+4(FP), R1
   187		MOVW	old+8(FP), R2
   188		MOVW	$SYS_setitimer, R7
   189		SWI	$0
   190		RET
   191	
   192	TEXT runtime·mincore(SB),NOSPLIT,$0
   193		MOVW	addr+0(FP), R0
   194		MOVW	n+4(FP), R1
   195		MOVW	dst+8(FP), R2
   196		MOVW	$SYS_mincore, R7
   197		SWI	$0
   198		MOVW	R0, ret+12(FP)
   199		RET
   200	
   201	TEXT runtime·walltime(SB), NOSPLIT, $32
   202		MOVW	$0, R0  // CLOCK_REALTIME
   203		MOVW	$8(R13), R1  // timespec
   204		MOVW	$SYS_clock_gettime, R7
   205		SWI	$0
   206		
   207		MOVW	8(R13), R0  // sec
   208		MOVW	12(R13), R2  // nsec
   209		
   210		MOVW	R0, sec_lo+0(FP)
   211		MOVW	$0, R1
   212		MOVW	R1, sec_hi+4(FP)
   213		MOVW	R2, nsec+8(FP)
   214		RET	
   215	
   216	// int64 nanotime(void)
   217	TEXT runtime·nanotime(SB),NOSPLIT,$32
   218		MOVW	$1, R0  // CLOCK_MONOTONIC
   219		MOVW	$8(R13), R1  // timespec
   220		MOVW	$SYS_clock_gettime, R7
   221		SWI	$0
   222		
   223		MOVW	8(R13), R0  // sec
   224		MOVW	12(R13), R2  // nsec
   225		
   226		MOVW	$1000000000, R3
   227		MULLU	R0, R3, (R1, R0)
   228		MOVW	$0, R4
   229		ADD.S	R2, R0
   230		ADC	R4, R1
   231	
   232		MOVW	R0, ret_lo+0(FP)
   233		MOVW	R1, ret_hi+4(FP)
   234		RET
   235	
   236	// int32 futex(int32 *uaddr, int32 op, int32 val,
   237	//	struct timespec *timeout, int32 *uaddr2, int32 val2);
   238	TEXT runtime·futex(SB),NOSPLIT,$0
   239		MOVW    addr+0(FP), R0
   240		MOVW    op+4(FP), R1
   241		MOVW    val+8(FP), R2
   242		MOVW    ts+12(FP), R3
   243		MOVW    addr2+16(FP), R4
   244		MOVW    val3+20(FP), R5
   245		MOVW	$SYS_futex, R7
   246		SWI	$0
   247		MOVW	R0, ret+24(FP)
   248		RET
   249	
   250	// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
   251	TEXT runtime·clone(SB),NOSPLIT,$0
   252		MOVW	flags+0(FP), R0
   253		MOVW	stk+4(FP), R1
   254		MOVW	$0, R2	// parent tid ptr
   255		MOVW	$0, R3	// tls_val
   256		MOVW	$0, R4	// child tid ptr
   257		MOVW	$0, R5
   258	
   259		// Copy mp, gp, fn off parent stack for use by child.
   260		// TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying
   261		MOVW	$-16(R1), R1
   262		MOVW	mp+8(FP), R6
   263		MOVW	R6, 0(R1)
   264		MOVW	gp+12(FP), R6
   265		MOVW	R6, 4(R1)
   266		MOVW	fn+16(FP), R6
   267		MOVW	R6, 8(R1)
   268		MOVW	$1234, R6
   269		MOVW	R6, 12(R1)
   270	
   271		MOVW	$SYS_clone, R7
   272		SWI	$0
   273	
   274		// In parent, return.
   275		CMP	$0, R0
   276		BEQ	3(PC)
   277		MOVW	R0, ret+20(FP)
   278		RET
   279	
   280		// Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
   281		MOVW	12(R13), R0
   282		MOVW	$1234, R1
   283		CMP	R0, R1
   284		BEQ	2(PC)
   285		BL	runtime·abort(SB)
   286	
   287		MOVW	0(R13), R8    // m
   288		MOVW	4(R13), R0    // g
   289	
   290		CMP	$0, R8
   291		BEQ	nog
   292		CMP	$0, R0
   293		BEQ	nog
   294	
   295		MOVW	R0, g
   296		MOVW	R8, g_m(g)
   297	
   298		// paranoia; check they are not nil
   299		MOVW	0(R8), R0
   300		MOVW	0(g), R0
   301	
   302		BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   303	
   304		// Initialize m->procid to Linux tid
   305		MOVW	$SYS_gettid, R7
   306		SWI	$0
   307		MOVW	g_m(g), R8
   308		MOVW	R0, m_procid(R8)
   309	
   310	nog:
   311		// Call fn
   312		MOVW	8(R13), R0
   313		MOVW	$16(R13), R13
   314		BL	(R0)
   315	
   316		// It shouldn't return. If it does, exit that thread.
   317		SUB	$16, R13 // restore the stack pointer to avoid memory corruption
   318		MOVW	$0, R0
   319		MOVW	R0, 4(R13)
   320		BL	runtime·exit1(SB)
   321	
   322		MOVW	$1234, R0
   323		MOVW	$1005, R1
   324		MOVW	R0, (R1)
   325	
   326	TEXT runtime·sigaltstack(SB),NOSPLIT,$0
   327		MOVW	new+0(FP), R0
   328		MOVW	old+4(FP), R1
   329		MOVW	$SYS_sigaltstack, R7
   330		SWI	$0
   331		MOVW	$0xfffff001, R6
   332		CMP 	R6, R0
   333		MOVW.HI	$0, R8  // crash on syscall failure
   334		MOVW.HI	R8, (R8)
   335		RET
   336	
   337	TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
   338		MOVW	sig+4(FP), R0
   339		MOVW	info+8(FP), R1
   340		MOVW	ctx+12(FP), R2
   341		MOVW	fn+0(FP), R11
   342		MOVW	R13, R4
   343		SUB	$24, R13
   344		BIC	$0x7, R13 // alignment for ELF ABI
   345		BL	(R11)
   346		MOVW	R4, R13
   347		RET
   348	
   349	TEXT runtime·sigtramp(SB),NOSPLIT,$12
   350		// this might be called in external code context,
   351		// where g is not set.
   352		// first save R0, because runtime·load_g will clobber it
   353		MOVW	R0, 4(R13)
   354		MOVB	runtime·iscgo(SB), R0
   355		CMP 	$0, R0
   356		BL.NE	runtime·load_g(SB)
   357	
   358		MOVW	R1, 8(R13)
   359		MOVW	R2, 12(R13)
   360		MOVW  	$runtime·sigtrampgo(SB), R11
   361		BL	(R11)
   362		RET
   363	
   364	TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   365		MOVW  	$runtime·sigtramp(SB), R11
   366		B	(R11)
   367	
   368	TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
   369		MOVW	how+0(FP), R0
   370		MOVW	new+4(FP), R1
   371		MOVW	old+8(FP), R2
   372		MOVW	size+12(FP), R3
   373		MOVW	$SYS_rt_sigprocmask, R7
   374		SWI	$0
   375		RET
   376	
   377	TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
   378		MOVW	sig+0(FP), R0
   379		MOVW	new+4(FP), R1
   380		MOVW	old+8(FP), R2
   381		MOVW	size+12(FP), R3
   382		MOVW	$SYS_rt_sigaction, R7
   383		SWI	$0
   384		MOVW	R0, ret+16(FP)
   385		RET
   386	
   387	TEXT runtime·usleep(SB),NOSPLIT,$12
   388		MOVW	usec+0(FP), R0
   389		CALL	runtime·usplitR0(SB)
   390		MOVW	R0, 4(R13)
   391		MOVW	$1000, R0	// usec to nsec
   392		MUL	R0, R1
   393		MOVW	R1, 8(R13)
   394		MOVW	$0, R0
   395		MOVW	$0, R1
   396		MOVW	$0, R2
   397		MOVW	$0, R3
   398		MOVW	$4(R13), R4
   399		MOVW	$0, R5
   400		MOVW	$SYS_pselect6, R7
   401		SWI	$0
   402		RET
   403	
   404	// As for cas, memory barriers are complicated on ARM, but the kernel
   405	// provides a user helper. ARMv5 does not support SMP and has no
   406	// memory barrier instruction at all. ARMv6 added SMP support and has
   407	// a memory barrier, but it requires writing to a coprocessor
   408	// register. ARMv7 introduced the DMB instruction, but it's expensive
   409	// even on single-core devices. The kernel helper takes care of all of
   410	// this for us.
   411	
   412	TEXT publicationBarrier<>(SB),NOSPLIT,$0
   413		// void __kuser_memory_barrier(void);
   414		MOVW	$0xffff0fa0, R15 // R15 is hardware PC.
   415	
   416	TEXT ·publicationBarrier(SB),NOSPLIT,$0
   417		BL	publicationBarrier<>(SB)
   418		RET
   419	
   420	TEXT runtime·osyield(SB),NOSPLIT,$0
   421		MOVW	$SYS_sched_yield, R7
   422		SWI	$0
   423		RET
   424	
   425	TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
   426		MOVW	pid+0(FP), R0
   427		MOVW	len+4(FP), R1
   428		MOVW	buf+8(FP), R2
   429		MOVW	$SYS_sched_getaffinity, R7
   430		SWI	$0
   431		MOVW	R0, ret+12(FP)
   432		RET
   433	
   434	// int32 runtime·epollcreate(int32 size)
   435	TEXT runtime·epollcreate(SB),NOSPLIT,$0
   436		MOVW	size+0(FP), R0
   437		MOVW	$SYS_epoll_create, R7
   438		SWI	$0
   439		MOVW	R0, ret+4(FP)
   440		RET
   441	
   442	// int32 runtime·epollcreate1(int32 flags)
   443	TEXT runtime·epollcreate1(SB),NOSPLIT,$0
   444		MOVW	flags+0(FP), R0
   445		MOVW	$SYS_epoll_create1, R7
   446		SWI	$0
   447		MOVW	R0, ret+4(FP)
   448		RET
   449	
   450	// func epollctl(epfd, op, fd int32, ev *epollEvent) int
   451	TEXT runtime·epollctl(SB),NOSPLIT,$0
   452		MOVW	epfd+0(FP), R0
   453		MOVW	op+4(FP), R1
   454		MOVW	fd+8(FP), R2
   455		MOVW	ev+12(FP), R3
   456		MOVW	$SYS_epoll_ctl, R7
   457		SWI	$0
   458		MOVW	R0, ret+16(FP)
   459		RET
   460	
   461	// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
   462	TEXT runtime·epollwait(SB),NOSPLIT,$0
   463		MOVW	epfd+0(FP), R0
   464		MOVW	ev+4(FP), R1
   465		MOVW	nev+8(FP), R2
   466		MOVW	timeout+12(FP), R3
   467		MOVW	$SYS_epoll_wait, R7
   468		SWI	$0
   469		MOVW	R0, ret+16(FP)
   470		RET
   471	
   472	// void runtime·closeonexec(int32 fd)
   473	TEXT runtime·closeonexec(SB),NOSPLIT,$0
   474		MOVW	fd+0(FP), R0	// fd
   475		MOVW	$2, R1	// F_SETFD
   476		MOVW	$1, R2	// FD_CLOEXEC
   477		MOVW	$SYS_fcntl, R7
   478		SWI	$0
   479		RET
   480	
   481	// b __kuser_get_tls @ 0xffff0fe0
   482	TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
   483		MOVW	$0xffff0fe0, R0
   484		B	(R0)
   485	
   486	TEXT runtime·access(SB),NOSPLIT,$0
   487		MOVW	name+0(FP), R0
   488		MOVW	mode+4(FP), R1
   489		MOVW	$SYS_access, R7
   490		SWI	$0
   491		MOVW	R0, ret+8(FP)
   492		RET
   493	
   494	TEXT runtime·connect(SB),NOSPLIT,$0
   495		MOVW	fd+0(FP), R0
   496		MOVW	addr+4(FP), R1
   497		MOVW	len+8(FP), R2
   498		MOVW	$SYS_connect, R7
   499		SWI	$0
   500		MOVW	R0, ret+12(FP)
   501		RET
   502	
   503	TEXT runtime·socket(SB),NOSPLIT,$0
   504		MOVW	domain+0(FP), R0
   505		MOVW	typ+4(FP), R1
   506		MOVW	prot+8(FP), R2
   507		MOVW	$SYS_socket, R7
   508		SWI	$0
   509		MOVW	R0, ret+12(FP)
   510		RET
   511	
   512	// func sbrk0() uintptr
   513	TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
   514		// Implemented as brk(NULL).
   515		MOVW	$0, R0
   516		MOVW	$SYS_brk, R7
   517		SWI	$0
   518		MOVW	R0, ret+0(FP)
   519		RET

View as plain text