Text file src/runtime/sys_windows_arm.s

     1  // Copyright 2018 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  #include "go_asm.h"
     6  #include "go_tls.h"
     7  #include "textflag.h"
     8  #include "time_windows.h"
     9  
    10  // Note: For system ABI, R0-R3 are args, R4-R11 are callee-save.
    11  
    12  TEXT runtime·getlasterror(SB),NOSPLIT,$0
    13  	MRC	15, 0, R0, C13, C0, 2
    14  	MOVW	0x34(R0), R0
    15  	MOVW	R0, ret+0(FP)
    16  	RET
    17  
    18  // Called by Windows as a Vectored Exception Handler (VEH).
    19  // R0 is pointer to struct containing
    20  // exception record and context pointers.
    21  // R1 is the kind of sigtramp function.
    22  // Return value of sigtrampgo is stored in R0.
    23  TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
    24  	MOVM.DB.W [R4-R11, R14], (R13)	// push {r4-r11, lr} (SP-=40)
    25  	SUB	$(16), R13		// reserve space for parameters/retval to go call
    26  
    27  	MOVW	R0, R6			// Save param0
    28  	MOVW	R1, R7			// Save param1
    29  	BL	runtime·load_g(SB)	// Clobbers R0
    30  
    31  	MOVW	$0, R4
    32  	MOVW	R4, 0(R13)	// No saved link register.
    33  	MOVW	R6, 4(R13)	// Move arg0 into position
    34  	MOVW	R7, 8(R13)	// Move arg1 into position
    35  	BL	runtime·sigtrampgo(SB)
    36  	MOVW	12(R13), R0	// Fetch return value from stack
    37  
    38  	ADD	$(16), R13			// free locals
    39  	MOVM.IA.W (R13), [R4-R11, R14]	// pop {r4-r11, lr}
    40  
    41  	B	(R14)				// return
    42  
    43  // Trampoline to resume execution from exception handler.
    44  // This is part of the control flow guard workaround.
    45  // It switches stacks and jumps to the continuation address.
    46  // R0 and R1 are set above at the end of sigtrampgo
    47  // in the context that starts executing at sigresume.
    48  TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0
    49  	// Important: do not smash LR,
    50  	// which is set to a live value when handling
    51  	// a signal by pushing a call to sigpanic onto the stack.
    52  	MOVW	R0, R13
    53  	B	(R1)
    54  
    55  TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
    56  	MOVW	$const_callbackVEH, R1
    57  	B	sigtramp<>(SB)
    58  
    59  TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0
    60  	MOVW	$const_callbackFirstVCH, R1
    61  	B	sigtramp<>(SB)
    62  
    63  TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0
    64  	MOVW	$const_callbackLastVCH, R1
    65  	B	sigtramp<>(SB)
    66  
    67  TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
    68  	// On entry, the trampoline in zcallback_windows_arm.s left
    69  	// the callback index in R12 (which is volatile in the C ABI).
    70  
    71  	// Push callback register arguments r0-r3. We do this first so
    72  	// they're contiguous with stack arguments.
    73  	MOVM.DB.W [R0-R3], (R13)
    74  	// Push C callee-save registers r4-r11 and lr.
    75  	MOVM.DB.W [R4-R11, R14], (R13)
    76  	SUB	$(16 + callbackArgs__size), R13	// space for locals
    77  
    78  	// Create a struct callbackArgs on our stack.
    79  	MOVW	R12, (16+callbackArgs_index)(R13)	// callback index
    80  	MOVW	$(16+callbackArgs__size+4*9)(R13), R0
    81  	MOVW	R0, (16+callbackArgs_args)(R13)		// address of args vector
    82  	MOVW	$0, R0
    83  	MOVW	R0, (16+callbackArgs_result)(R13)	// result
    84  
    85  	// Prepare for entry to Go.
    86  	BL	runtime·load_g(SB)
    87  
    88  	// Call cgocallback, which will call callbackWrap(frame).
    89  	MOVW	$0, R0
    90  	MOVW	R0, 12(R13)	// context
    91  	MOVW	$16(R13), R1	// R1 = &callbackArgs{...}
    92  	MOVW	R1, 8(R13)	// frame (address of callbackArgs)
    93  	MOVW	$·callbackWrap(SB), R1
    94  	MOVW	R1, 4(R13)	// PC of function to call
    95  	BL	runtime·cgocallback(SB)
    96  
    97  	// Get callback result.
    98  	MOVW	(16+callbackArgs_result)(R13), R0
    99  
   100  	ADD	$(16 + callbackArgs__size), R13	// free locals
   101  	MOVM.IA.W (R13), [R4-R11, R12]	// pop {r4-r11, lr=>r12}
   102  	ADD	$(4*4), R13	// skip r0-r3
   103  	B	(R12)	// return
   104  
   105  // uint32 tstart_stdcall(M *newm);
   106  TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0
   107  	MOVM.DB.W [R4-R11, R14], (R13)		// push {r4-r11, lr}
   108  
   109  	MOVW	m_g0(R0), g
   110  	MOVW	R0, g_m(g)
   111  	BL	runtime·save_g(SB)
   112  
   113  	// Layout new m scheduler stack on os stack.
   114  	MOVW	R13, R0
   115  	MOVW	R0, g_stack+stack_hi(g)
   116  	SUB	$(64*1024), R0
   117  	MOVW	R0, (g_stack+stack_lo)(g)
   118  	MOVW	R0, g_stackguard0(g)
   119  	MOVW	R0, g_stackguard1(g)
   120  
   121  	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   122  	BL	runtime·mstart(SB)
   123  
   124  	// Exit the thread.
   125  	MOVW	$0, R0
   126  	MOVM.IA.W (R13), [R4-R11, R15]		// pop {r4-r11, pc}
   127  
   128  TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
   129  	B	runtime·armPublicationBarrier(SB)
   130  
   131  // never called (this is a GOARM=7 platform)
   132  TEXT runtime·read_tls_fallback(SB),NOSPLIT,$0
   133  	MOVW	$0xabcd, R0
   134  	MOVW	R0, (R0)
   135  	RET
   136  
   137  TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
   138  	MOVW	$_INTERRUPT_TIME, R3
   139  loop:
   140  	MOVW	time_hi1(R3), R1
   141  	DMB	MB_ISH
   142  	MOVW	time_lo(R3), R0
   143  	DMB	MB_ISH
   144  	MOVW	time_hi2(R3), R2
   145  	CMP	R1, R2
   146  	BNE	loop
   147  
   148  	// wintime = R1:R0, multiply by 100
   149  	MOVW	$100, R2
   150  	MULLU	R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
   151  	MULA	R1, R2, R4, R4
   152  
   153  	// wintime*100 = R4:R3
   154  	MOVW	R3, ret_lo+0(FP)
   155  	MOVW	R4, ret_hi+4(FP)
   156  	RET
   157  
   158  // save_g saves the g register (R10) into thread local memory
   159  // so that we can call externally compiled
   160  // ARM code that will overwrite those registers.
   161  // NOTE: runtime.gogo assumes that R1 is preserved by this function.
   162  //       runtime.mcall assumes this function only clobbers R0 and R11.
   163  // Returns with g in R0.
   164  // Save the value in the _TEB->TlsSlots array.
   165  // Effectively implements TlsSetValue().
   166  // tls_g stores the TLS slot allocated TlsAlloc().
   167  TEXT runtime·save_g(SB),NOSPLIT,$0
   168  	MRC	15, 0, R0, C13, C0, 2
   169  	ADD	$0xe10, R0
   170  	MOVW 	$runtime·tls_g(SB), R11
   171  	MOVW	(R11), R11
   172  	MOVW	g, R11<<2(R0)
   173  	MOVW	g, R0	// preserve R0 across call to setg<>
   174  	RET
   175  
   176  // load_g loads the g register from thread-local memory,
   177  // for use after calling externally compiled
   178  // ARM code that overwrote those registers.
   179  // Get the value from the _TEB->TlsSlots array.
   180  // Effectively implements TlsGetValue().
   181  TEXT runtime·load_g(SB),NOSPLIT,$0
   182  	MRC	15, 0, R0, C13, C0, 2
   183  	ADD	$0xe10, R0
   184  	MOVW 	$runtime·tls_g(SB), g
   185  	MOVW	(g), g
   186  	MOVW	g<<2(R0), g
   187  	RET
   188  
   189  // This is called from rt0_go, which runs on the system stack
   190  // using the initial stack allocated by the OS.
   191  // It calls back into standard C using the BL below.
   192  // To do that, the stack pointer must be 8-byte-aligned.
   193  TEXT runtime·_initcgo(SB),NOSPLIT|NOFRAME,$0
   194  	MOVM.DB.W [R4, R14], (R13)	// push {r4, lr}
   195  
   196  	// Ensure stack is 8-byte aligned before calling C code
   197  	MOVW	R13, R4
   198  	BIC	$0x7, R13
   199  
   200  	// Allocate a TLS slot to hold g across calls to external code
   201  	MOVW 	$runtime·_TlsAlloc(SB), R0
   202  	MOVW	(R0), R0
   203  	BL	(R0)
   204  
   205  	// Assert that slot is less than 64 so we can use _TEB->TlsSlots
   206  	CMP	$64, R0
   207  	MOVW	$runtime·abort(SB), R1
   208  	BL.GE	(R1)
   209  
   210  	// Save Slot into tls_g
   211  	MOVW 	$runtime·tls_g(SB), R1
   212  	MOVW	R0, (R1)
   213  
   214  	MOVW	R4, R13
   215  	MOVM.IA.W (R13), [R4, R15]	// pop {r4, pc}
   216  
   217  // Holds the TLS Slot, which was allocated by TlsAlloc()
   218  GLOBL runtime·tls_g+0(SB), NOPTR, $4
   219  

View as plain text