github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/runtime/race_ppc64le.s (about)

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