Text file src/runtime/race_ppc64le.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  //go:build race
     6  
     7  #include "go_asm.h"
     8  #include "go_tls.h"
     9  #include "funcdata.h"
    10  #include "textflag.h"
    11  #include "asm_ppc64x.h"
    12  
    13  // The following functions allow calling the clang-compiled race runtime directly
    14  // from Go code without going all the way through cgo.
    15  // First, it's much faster (up to 50% speedup for real Go programs).
    16  // Second, it eliminates race-related special cases from cgocall and scheduler.
    17  // Third, in long-term it will allow to remove cyclic runtime/race dependency on cmd/go.
    18  
    19  // A brief recap of the ppc64le calling convention.
    20  // Arguments are passed in R3, R4, R5 ...
    21  // SP must be 16-byte aligned.
    22  
    23  // Note that for ppc64x, LLVM follows the standard ABI and
    24  // expects arguments in registers, so these functions move
    25  // the arguments from storage to the registers expected
    26  // by the ABI.
    27  
    28  // When calling from Go to Clang tsan code:
    29  // R3 is the 1st argument and is usually the ThreadState*
    30  // R4-? are the 2nd, 3rd, 4th, etc. arguments
    31  
    32  // When calling racecalladdr:
    33  // R8 is the call target address
    34  
    35  // The race ctx is passed in R3 and loaded in
    36  // racecalladdr.
    37  //
    38  // The sequence used to get the race ctx:
    39  //    MOVD    runtime·tls_g(SB), R10 // Address of TLS variable
    40  //    MOVD    0(R10), g              // g = R30
    41  //    MOVD    g_racectx(g), R3       // racectx == ThreadState
    42  
    43  // func runtime·RaceRead(addr uintptr)
    44  // Called from instrumented Go code
    45  TEXT	runtime·raceread<ABIInternal>(SB), NOSPLIT, $0-8
    46  	MOVD	R3, R4 // addr
    47  	MOVD	LR, R5 // caller of this?
    48  	// void __tsan_read(ThreadState *thr, void *addr, void *pc);
    49  	MOVD	$__tsan_read(SB), R8
    50  	BR	racecalladdr<>(SB)
    51  
    52  TEXT    runtime·RaceRead(SB), NOSPLIT, $0-8
    53  	BR	runtime·raceread(SB)
    54  
    55  // void runtime·racereadpc(void *addr, void *callpc, void *pc)
    56  TEXT	runtime·racereadpc(SB), NOSPLIT, $0-24
    57  	MOVD	addr+0(FP), R4
    58  	MOVD	callpc+8(FP), R5
    59  	MOVD	pc+16(FP), R6
    60  	// void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
    61  	MOVD	$__tsan_read_pc(SB), R8
    62  	BR	racecalladdr<>(SB)
    63  
    64  // func runtime·RaceWrite(addr uintptr)
    65  // Called from instrumented Go code
    66  TEXT	runtime·racewrite<ABIInternal>(SB), NOSPLIT, $0-8
    67  	MOVD	R3, R4 // addr
    68  	MOVD	LR, R5 // caller has set LR via BL inst
    69  	// void __tsan_write(ThreadState *thr, void *addr, void *pc);
    70  	MOVD	$__tsan_write(SB), R8
    71  	BR	racecalladdr<>(SB)
    72  
    73  TEXT    runtime·RaceWrite(SB), NOSPLIT, $0-8
    74  	JMP	runtime·racewrite(SB)
    75  
    76  // void runtime·racewritepc(void *addr, void *callpc, void *pc)
    77  TEXT	runtime·racewritepc(SB), NOSPLIT, $0-24
    78  	MOVD	addr+0(FP), R4
    79  	MOVD	callpc+8(FP), R5
    80  	MOVD	pc+16(FP), R6
    81  	// void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
    82  	MOVD	$__tsan_write_pc(SB), R8
    83  	BR	racecalladdr<>(SB)
    84  
    85  // func runtime·RaceReadRange(addr, size uintptr)
    86  // Called from instrumented Go code.
    87  TEXT	runtime·racereadrange<ABIInternal>(SB), NOSPLIT, $0-16
    88  	MOVD	R4, R5 // size
    89  	MOVD	R3, R4 // addr
    90  	MOVD	LR, R6
    91  	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
    92  	MOVD	$__tsan_read_range(SB), R8
    93  	BR	racecalladdr<>(SB)
    94  
    95  // void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc)
    96  TEXT	runtime·racereadrangepc1(SB), NOSPLIT, $0-24
    97  	MOVD    addr+0(FP), R4
    98  	MOVD    size+8(FP), R5
    99  	MOVD    pc+16(FP), R6
   100  	ADD	$4, R6		// tsan wants return addr
   101  	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
   102  	MOVD    $__tsan_read_range(SB), R8
   103  	BR	racecalladdr<>(SB)
   104  
   105  TEXT    runtime·RaceReadRange(SB), NOSPLIT, $0-16
   106  	BR	runtime·racereadrange(SB)
   107  
   108  // func runtime·RaceWriteRange(addr, size uintptr)
   109  // Called from instrumented Go code.
   110  TEXT	runtime·racewriterange<ABIInternal>(SB), NOSPLIT, $0-16
   111  	MOVD	R4, R5 // size
   112  	MOVD	R3, R4 // addr
   113  	MOVD	LR, R6
   114  	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
   115  	MOVD	$__tsan_write_range(SB), R8
   116  	BR	racecalladdr<>(SB)
   117  
   118  TEXT    runtime·RaceWriteRange(SB), NOSPLIT, $0-16
   119  	BR	runtime·racewriterange(SB)
   120  
   121  // void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc)
   122  // Called from instrumented Go code
   123  TEXT	runtime·racewriterangepc1(SB), NOSPLIT, $0-24
   124  	MOVD	addr+0(FP), R4
   125  	MOVD	size+8(FP), R5
   126  	MOVD	pc+16(FP), R6
   127  	ADD	$4, R6			// add 4 to inst offset?
   128  	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
   129  	MOVD	$__tsan_write_range(SB), R8
   130  	BR	racecalladdr<>(SB)
   131  
   132  // Call a __tsan function from Go code.
   133  // R8 = tsan function address
   134  // R3 = *ThreadState a.k.a. g_racectx from g
   135  // R4 = addr passed to __tsan function
   136  //
   137  // Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
   138  TEXT	racecalladdr<>(SB), NOSPLIT, $0-0
   139  	MOVD    runtime·tls_g(SB), R10
   140  	MOVD	0(R10), g
   141  	MOVD	g_racectx(g), R3	// goroutine context
   142  	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
   143  	MOVD	runtime·racearenastart(SB), R9
   144  	CMP	R4, R9
   145  	BLT	data
   146  	MOVD	runtime·racearenaend(SB), R9
   147  	CMP	R4, R9
   148  	BLT	call
   149  data:
   150  	MOVD	runtime·racedatastart(SB), R9
   151  	CMP	R4, R9
   152  	BLT	ret
   153  	MOVD	runtime·racedataend(SB), R9
   154  	CMP	R4, R9
   155  	BGT	ret
   156  call:
   157  	// Careful!! racecall will save LR on its
   158  	// stack, which is OK as long as racecalladdr
   159  	// doesn't change in a way that generates a stack.
   160  	// racecall should return to the caller of
   161  	// recalladdr.
   162  	BR	racecall<>(SB)
   163  ret:
   164  	RET
   165  
   166  // func runtime·racefuncenter(pc uintptr)
   167  // Called from instrumented Go code.
   168  TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
   169  	MOVD	callpc+0(FP), R8
   170  	BR	racefuncenter<>(SB)
   171  
   172  // Common code for racefuncenter
   173  // R11 = caller's return address
   174  TEXT	racefuncenter<>(SB), NOSPLIT, $0-0
   175  	MOVD    runtime·tls_g(SB), R10
   176  	MOVD    0(R10), g
   177  	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
   178  	MOVD	R8, R4			// caller pc set by caller in R8
   179  	// void __tsan_func_enter(ThreadState *thr, void *pc);
   180  	MOVD	$__tsan_func_enter(SB), R8
   181  	BR	racecall<>(SB)
   182  	RET
   183  
   184  // func runtime·racefuncexit()
   185  // Called from Go instrumented code.
   186  TEXT	runtime·racefuncexit(SB), NOSPLIT, $0-0
   187  	MOVD    runtime·tls_g(SB), R10
   188  	MOVD    0(R10), g
   189  	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
   190  	// void __tsan_func_exit(ThreadState *thr);
   191  	MOVD	$__tsan_func_exit(SB), R8
   192  	BR	racecall<>(SB)
   193  
   194  // Atomic operations for sync/atomic package.
   195  // Some use the __tsan versions instead
   196  // R6 = addr of arguments passed to this function
   197  // R3, R4, R5 set in racecallatomic
   198  
   199  // Load atomic in tsan
   200  TEXT	sync∕atomic·LoadInt32(SB), NOSPLIT, $0-12
   201  	GO_ARGS
   202  	// void __tsan_go_atomic32_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   203  	MOVD	$__tsan_go_atomic32_load(SB), R8
   204  	ADD	$32, R1, R6	// addr of caller's 1st arg
   205  	BR	racecallatomic<>(SB)
   206  	RET
   207  
   208  TEXT	sync∕atomic·LoadInt64(SB), NOSPLIT, $0-16
   209  	GO_ARGS
   210  	// void __tsan_go_atomic64_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   211  	MOVD	$__tsan_go_atomic64_load(SB), R8
   212  	ADD	$32, R1, R6	// addr of caller's 1st arg
   213  	BR	racecallatomic<>(SB)
   214  	RET
   215  
   216  TEXT	sync∕atomic·LoadUint32(SB), NOSPLIT, $0-12
   217  	GO_ARGS
   218  	BR	sync∕atomic·LoadInt32(SB)
   219  
   220  TEXT	sync∕atomic·LoadUint64(SB), NOSPLIT, $0-16
   221  	GO_ARGS
   222  	BR	sync∕atomic·LoadInt64(SB)
   223  
   224  TEXT	sync∕atomic·LoadUintptr(SB), NOSPLIT, $0-16
   225  	GO_ARGS
   226  	BR	sync∕atomic·LoadInt64(SB)
   227  
   228  TEXT	sync∕atomic·LoadPointer(SB), NOSPLIT, $0-16
   229  	GO_ARGS
   230  	BR	sync∕atomic·LoadInt64(SB)
   231  
   232  // Store atomic in tsan
   233  TEXT	sync∕atomic·StoreInt32(SB), NOSPLIT, $0-12
   234  	GO_ARGS
   235  	// void __tsan_go_atomic32_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   236  	MOVD	$__tsan_go_atomic32_store(SB), R8
   237  	ADD	$32, R1, R6	// addr of caller's 1st arg
   238  	BR	racecallatomic<>(SB)
   239  
   240  TEXT	sync∕atomic·StoreInt64(SB), NOSPLIT, $0-16
   241  	GO_ARGS
   242  	// void __tsan_go_atomic64_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   243  	MOVD	$__tsan_go_atomic64_store(SB), R8
   244  	ADD	$32, R1, R6	// addr of caller's 1st arg
   245  	BR	racecallatomic<>(SB)
   246  
   247  TEXT	sync∕atomic·StoreUint32(SB), NOSPLIT, $0-12
   248  	GO_ARGS
   249  	BR	sync∕atomic·StoreInt32(SB)
   250  
   251  TEXT	sync∕atomic·StoreUint64(SB), NOSPLIT, $0-16
   252  	GO_ARGS
   253  	BR	sync∕atomic·StoreInt64(SB)
   254  
   255  TEXT	sync∕atomic·StoreUintptr(SB), NOSPLIT, $0-16
   256  	GO_ARGS
   257  	BR	sync∕atomic·StoreInt64(SB)
   258  
   259  // Swap in tsan
   260  TEXT	sync∕atomic·SwapInt32(SB), NOSPLIT, $0-20
   261  	GO_ARGS
   262  	// void __tsan_go_atomic32_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   263  	MOVD	$__tsan_go_atomic32_exchange(SB), R8
   264  	ADD	$32, R1, R6	// addr of caller's 1st arg
   265  	BR	racecallatomic<>(SB)
   266  
   267  TEXT	sync∕atomic·SwapInt64(SB), NOSPLIT, $0-24
   268  	GO_ARGS
   269  	// void __tsan_go_atomic64_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a)
   270  	MOVD	$__tsan_go_atomic64_exchange(SB), R8
   271  	ADD	$32, R1, R6	// addr of caller's 1st arg
   272  	BR	racecallatomic<>(SB)
   273  
   274  TEXT	sync∕atomic·SwapUint32(SB), NOSPLIT, $0-20
   275  	GO_ARGS
   276  	BR	sync∕atomic·SwapInt32(SB)
   277  
   278  TEXT	sync∕atomic·SwapUint64(SB), NOSPLIT, $0-24
   279  	GO_ARGS
   280  	BR	sync∕atomic·SwapInt64(SB)
   281  
   282  TEXT	sync∕atomic·SwapUintptr(SB), NOSPLIT, $0-24
   283  	GO_ARGS
   284  	BR	sync∕atomic·SwapInt64(SB)
   285  
   286  // Add atomic in tsan
   287  TEXT	sync∕atomic·AddInt32(SB), NOSPLIT, $0-20
   288  	GO_ARGS
   289  	// void __tsan_go_atomic32_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   290  	MOVD	$__tsan_go_atomic32_fetch_add(SB), R8
   291  	ADD	$64, R1, R6	// addr of caller's 1st arg
   292  	BL	racecallatomic<>(SB)
   293  	// The tsan fetch_add result is not as expected by Go,
   294  	// so the 'add' must be added to the result.
   295  	MOVW	add+8(FP), R3	// The tsa fetch_add does not return the
   296  	MOVW	ret+16(FP), R4	// result as expected by go, so fix it.
   297  	ADD	R3, R4, R3
   298  	MOVW	R3, ret+16(FP)
   299  	RET
   300  
   301  TEXT	sync∕atomic·AddInt64(SB), NOSPLIT, $0-24
   302  	GO_ARGS
   303  	// void __tsan_go_atomic64_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
   304  	MOVD	$__tsan_go_atomic64_fetch_add(SB), R8
   305  	ADD	$64, R1, R6	// addr of caller's 1st arg
   306  	BL	racecallatomic<>(SB)
   307  	// The tsan fetch_add result is not as expected by Go,
   308  	// so the 'add' must be added to the result.
   309  	MOVD	add+8(FP), R3
   310  	MOVD	ret+16(FP), R4
   311  	ADD	R3, R4, R3
   312  	MOVD	R3, ret+16(FP)
   313  	RET
   314  
   315  TEXT	sync∕atomic·AddUint32(SB), NOSPLIT, $0-20
   316  	GO_ARGS
   317  	BR	sync∕atomic·AddInt32(SB)
   318  
   319  TEXT	sync∕atomic·AddUint64(SB), NOSPLIT, $0-24
   320  	GO_ARGS
   321  	BR	sync∕atomic·AddInt64(SB)
   322  
   323  TEXT	sync∕atomic·AddUintptr(SB), NOSPLIT, $0-24
   324  	GO_ARGS
   325  	BR	sync∕atomic·AddInt64(SB)
   326  
   327  // CompareAndSwap in tsan
   328  TEXT	sync∕atomic·CompareAndSwapInt32(SB), NOSPLIT, $0-17
   329  	GO_ARGS
   330  	// void __tsan_go_atomic32_compare_exchange(
   331  	//   ThreadState *thr, uptr cpc, uptr pc, u8 *a)
   332  	MOVD	$__tsan_go_atomic32_compare_exchange(SB), R8
   333  	ADD	$32, R1, R6	// addr of caller's 1st arg
   334  	BR	racecallatomic<>(SB)
   335  
   336  TEXT	sync∕atomic·CompareAndSwapInt64(SB), NOSPLIT, $0-25
   337  	GO_ARGS
   338  	// void __tsan_go_atomic32_compare_exchange(
   339  	//   ThreadState *thr, uptr cpc, uptr pc, u8 *a)
   340  	MOVD	$__tsan_go_atomic64_compare_exchange(SB), R8
   341  	ADD	$32, R1, R6	// addr of caller's 1st arg
   342  	BR	racecallatomic<>(SB)
   343  
   344  TEXT	sync∕atomic·CompareAndSwapUint32(SB), NOSPLIT, $0-17
   345  	GO_ARGS
   346  	BR	sync∕atomic·CompareAndSwapInt32(SB)
   347  
   348  TEXT	sync∕atomic·CompareAndSwapUint64(SB), NOSPLIT, $0-25
   349  	GO_ARGS
   350  	BR	sync∕atomic·CompareAndSwapInt64(SB)
   351  
   352  TEXT	sync∕atomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-25
   353  	GO_ARGS
   354  	BR	sync∕atomic·CompareAndSwapInt64(SB)
   355  
   356  // Common function used to call tsan's atomic functions
   357  // R3 = *ThreadState
   358  // R4 = TODO: What's this supposed to be?
   359  // R5 = caller pc
   360  // R6 = addr of incoming arg list
   361  // R8 contains addr of target function.
   362  TEXT	racecallatomic<>(SB), NOSPLIT, $0-0
   363  	// Trigger SIGSEGV early if address passed to atomic function is bad.
   364  	MOVD	(R6), R7	// 1st arg is addr
   365  	MOVD	(R7), R9	// segv here if addr is bad
   366  	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
   367  	MOVD	runtime·racearenastart(SB), R9
   368  	CMP	R7, R9
   369  	BLT	racecallatomic_data
   370  	MOVD	runtime·racearenaend(SB), R9
   371  	CMP	R7, R9
   372  	BLT	racecallatomic_ok
   373  racecallatomic_data:
   374  	MOVD	runtime·racedatastart(SB), R9
   375  	CMP	R7, R9
   376  	BLT	racecallatomic_ignore
   377  	MOVD	runtime·racedataend(SB), R9
   378  	CMP	R7, R9
   379  	BGE	racecallatomic_ignore
   380  racecallatomic_ok:
   381  	// Addr is within the good range, call the atomic function.
   382  	MOVD    runtime·tls_g(SB), R10
   383  	MOVD    0(R10), g
   384  	MOVD    g_racectx(g), R3        // goroutine racectx aka *ThreadState
   385  	MOVD	R8, R5			// pc is the function called
   386  	MOVD	(R1), R4		// caller pc from stack
   387  	BL	racecall<>(SB)		// BL needed to maintain stack consistency
   388  	RET				//
   389  racecallatomic_ignore:
   390  	// Addr is outside the good range.
   391  	// Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op.
   392  	// An attempt to synchronize on the address would cause crash.
   393  	MOVD	R8, R15	// save the original function
   394  	MOVD	R6, R17 // save the original arg list addr
   395  	MOVD	$__tsan_go_ignore_sync_begin(SB), R8 // func addr to call
   396  	MOVD    runtime·tls_g(SB), R10
   397  	MOVD    0(R10), g
   398  	MOVD    g_racectx(g), R3        // goroutine context
   399  	BL	racecall<>(SB)
   400  	MOVD	R15, R8	// restore the original function
   401  	MOVD	R17, R6 // restore arg list addr
   402  	// Call the atomic function.
   403  	// racecall will call LLVM race code which might clobber r30 (g)
   404  	MOVD	runtime·tls_g(SB), R10
   405  	MOVD	0(R10), g
   406  
   407  	MOVD	g_racectx(g), R3
   408  	MOVD	R8, R4		// pc being called same TODO as above
   409  	MOVD	(R1), R5	// caller pc from latest LR
   410  	BL	racecall<>(SB)
   411  	// Call __tsan_go_ignore_sync_end.
   412  	MOVD	$__tsan_go_ignore_sync_end(SB), R8
   413  	MOVD	g_racectx(g), R3	// goroutine context g should still be good?
   414  	BL	racecall<>(SB)
   415  	RET
   416  
   417  // void runtime·racecall(void(*f)(...), ...)
   418  // Calls C function f from race runtime and passes up to 4 arguments to it.
   419  // The arguments are never heap-object-preserving pointers, so we pretend there are no arguments.
   420  TEXT	runtime·racecall(SB), NOSPLIT, $0-0
   421  	MOVD	fn+0(FP), R8
   422  	MOVD	arg0+8(FP), R3
   423  	MOVD	arg1+16(FP), R4
   424  	MOVD	arg2+24(FP), R5
   425  	MOVD	arg3+32(FP), R6
   426  	JMP	racecall<>(SB)
   427  
   428  // Finds g0 and sets its stack
   429  // Arguments were loaded for call from Go to C
   430  TEXT	racecall<>(SB), NOSPLIT, $0-0
   431  	// Set the LR slot for the ppc64 ABI
   432  	MOVD	LR, R10
   433  	MOVD	R10, 0(R1)	// Go expectation
   434  	MOVD	R10, 16(R1)	// C ABI
   435  	// Get info from the current goroutine
   436  	MOVD    runtime·tls_g(SB), R10	// g offset in TLS
   437  	MOVD    0(R10), g
   438  	MOVD	g_m(g), R7		// m for g
   439  	MOVD	R1, R16			// callee-saved, preserved across C call
   440  	MOVD	m_g0(R7), R10		// g0 for m
   441  	CMP	R10, g			// same g0?
   442  	BEQ	call			// already on g0
   443  	MOVD	(g_sched+gobuf_sp)(R10), R1 // switch R1
   444  call:
   445  	// prepare frame for C ABI
   446  	SUB	$32, R1			// create frame for callee saving LR, CR, R2 etc.
   447  	RLDCR   $0, R1, $~15, R1	// align SP to 16 bytes
   448  	MOVD	R8, CTR			// R8 = caller addr
   449  	MOVD	R8, R12			// expected by PPC64 ABI
   450  	BL	(CTR)
   451  	XOR     R0, R0			// clear R0 on return from Clang
   452  	MOVD	R16, R1			// restore R1; R16 nonvol in Clang
   453  	MOVD    runtime·tls_g(SB), R10	// find correct g
   454  	MOVD    0(R10), g
   455  	MOVD	16(R1), R10		// LR was saved away, restore for return
   456  	MOVD	R10, LR
   457  	RET
   458  
   459  // C->Go callback thunk that allows to call runtime·racesymbolize from C code.
   460  // Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g.
   461  // The overall effect of Go->C->Go call chain is similar to that of mcall.
   462  // RARG0 contains command code. RARG1 contains command-specific context.
   463  // See racecallback for command codes.
   464  TEXT	runtime·racecallbackthunk(SB), NOSPLIT, $-8
   465  	// Handle command raceGetProcCmd (0) here.
   466  	// First, code below assumes that we are on curg, while raceGetProcCmd
   467  	// can be executed on g0. Second, it is called frequently, so will
   468  	// benefit from this fast path.
   469  	XOR	R0, R0		// clear R0 since we came from C code
   470  	CMP	R3, $0
   471  	BNE	rest
   472  	// g0 TODO: Don't modify g here since R30 is nonvolatile
   473  	MOVD	g, R9
   474  	MOVD    runtime·tls_g(SB), R10
   475  	MOVD    0(R10), g
   476  	MOVD	g_m(g), R3
   477  	MOVD	m_p(R3), R3
   478  	MOVD	p_raceprocctx(R3), R3
   479  	MOVD	R3, (R4)
   480  	MOVD	R9, g		// restore R30 ??
   481  	RET
   482  
   483  	// This is all similar to what cgo does
   484  	// Save registers according to the ppc64 ABI
   485  rest:
   486  	MOVD	LR, R10	// save link register
   487  	MOVD	R10, 16(R1)
   488  	MOVW	CR, R10
   489  	MOVW	R10, 8(R1)
   490  	MOVDU   R1, -336(R1) // Allocate frame needed for outargs and register save area
   491  
   492  	MOVD    R14, 328(R1)
   493  	MOVD    R15, 48(R1)
   494  	MOVD    R16, 56(R1)
   495  	MOVD    R17, 64(R1)
   496  	MOVD    R18, 72(R1)
   497  	MOVD    R19, 80(R1)
   498  	MOVD    R20, 88(R1)
   499  	MOVD    R21, 96(R1)
   500  	MOVD    R22, 104(R1)
   501  	MOVD    R23, 112(R1)
   502  	MOVD    R24, 120(R1)
   503  	MOVD    R25, 128(R1)
   504  	MOVD    R26, 136(R1)
   505  	MOVD    R27, 144(R1)
   506  	MOVD    R28, 152(R1)
   507  	MOVD    R29, 160(R1)
   508  	MOVD    g, 168(R1) // R30
   509  	MOVD    R31, 176(R1)
   510  	FMOVD   F14, 184(R1)
   511  	FMOVD   F15, 192(R1)
   512  	FMOVD   F16, 200(R1)
   513  	FMOVD   F17, 208(R1)
   514  	FMOVD   F18, 216(R1)
   515  	FMOVD   F19, 224(R1)
   516  	FMOVD   F20, 232(R1)
   517  	FMOVD   F21, 240(R1)
   518  	FMOVD   F22, 248(R1)
   519  	FMOVD   F23, 256(R1)
   520  	FMOVD   F24, 264(R1)
   521  	FMOVD   F25, 272(R1)
   522  	FMOVD   F26, 280(R1)
   523  	FMOVD   F27, 288(R1)
   524  	FMOVD   F28, 296(R1)
   525  	FMOVD   F29, 304(R1)
   526  	FMOVD   F30, 312(R1)
   527  	FMOVD   F31, 320(R1)
   528  
   529  	MOVD	R3, FIXED_FRAME+0(R1)
   530  	MOVD	R4, FIXED_FRAME+8(R1)
   531  
   532  	MOVD    runtime·tls_g(SB), R10
   533  	MOVD    0(R10), g
   534  
   535  	MOVD	g_m(g), R7
   536  	MOVD	m_g0(R7), R8
   537  	CMP	g, R8
   538  	BEQ	noswitch
   539  
   540  	MOVD	R8, g // set g = m-> g0
   541  
   542  	BL	runtime·racecallback(SB)
   543  
   544  	// All registers are clobbered after Go code, reload.
   545  	MOVD    runtime·tls_g(SB), R10
   546  	MOVD    0(R10), g
   547  
   548  	MOVD	g_m(g), R7
   549  	MOVD	m_curg(R7), g // restore g = m->curg
   550  
   551  ret:
   552  	MOVD    328(R1), R14
   553  	MOVD    48(R1), R15
   554  	MOVD    56(R1), R16
   555  	MOVD    64(R1), R17
   556  	MOVD    72(R1), R18
   557  	MOVD    80(R1), R19
   558  	MOVD    88(R1), R20
   559  	MOVD    96(R1), R21
   560  	MOVD    104(R1), R22
   561  	MOVD    112(R1), R23
   562  	MOVD    120(R1), R24
   563  	MOVD    128(R1), R25
   564  	MOVD    136(R1), R26
   565  	MOVD    144(R1), R27
   566  	MOVD    152(R1), R28
   567  	MOVD    160(R1), R29
   568  	MOVD    168(R1), g // R30
   569  	MOVD    176(R1), R31
   570  	FMOVD   184(R1), F14
   571  	FMOVD   192(R1), F15
   572  	FMOVD   200(R1), F16
   573  	FMOVD   208(R1), F17
   574  	FMOVD   216(R1), F18
   575  	FMOVD   224(R1), F19
   576  	FMOVD   232(R1), F20
   577  	FMOVD   240(R1), F21
   578  	FMOVD   248(R1), F22
   579  	FMOVD   256(R1), F23
   580  	FMOVD   264(R1), F24
   581  	FMOVD   272(R1), F25
   582  	FMOVD   280(R1), F26
   583  	FMOVD   288(R1), F27
   584  	FMOVD   296(R1), F28
   585  	FMOVD   304(R1), F29
   586  	FMOVD   312(R1), F30
   587  	FMOVD   320(R1), F31
   588  
   589  	ADD     $336, R1
   590  	MOVD    8(R1), R10
   591  	MOVFL   R10, $0xff // Restore of CR
   592  	MOVD    16(R1), R10	// needed?
   593  	MOVD    R10, LR
   594  	RET
   595  
   596  noswitch:
   597  	BL      runtime·racecallback(SB)
   598  	JMP     ret
   599  
   600  // tls_g, g value for each thread in TLS
   601  GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
   602  

View as plain text