asm_ppc64le.s raw

   1  // Copyright 2014 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 "textflag.h"
   6  #include "abi_ppc64x.h"
   7  
   8  // Called by C code generated by cmd/cgo.
   9  // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
  10  // Saves C callee-saved registers and calls cgocallback with three arguments.
  11  // fn is the PC of a func(a unsafe.Pointer) function.
  12  //
  13  // This is a simplified version that only saves GPR and FPR registers,
  14  // not vector registers. This keeps the stack frame smaller to avoid
  15  // exceeding the nosplit stack limit.
  16  //
  17  // On PPC64LE ELFv2, callee-save registers are:
  18  //   R14-R31 (18 GPRs = 144 bytes)
  19  //   F14-F31 (18 FPRs = 144 bytes)
  20  //   CR2-CR4 (saved in CR field)
  21  //
  22  // Stack layout (must be 16-byte aligned):
  23  //   32 (FIXED_FRAME) + 24 (args) + 144 (GPR) + 144 (FPR) = 344
  24  //   Rounded to 352 for 16-byte alignment.
  25  
  26  #define FIXED_FRAME 32
  27  #define SAVE_SIZE    352
  28  #define GPR_OFFSET   (FIXED_FRAME+24)
  29  #define FPR_OFFSET   (GPR_OFFSET+SAVE_GPR_SIZE)
  30  
  31  TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
  32  	// Save LR and CR in caller's frame per ELFv2 ABI
  33  	MOVD LR, R0
  34  	MOVD R0, 16(R1)
  35  	MOVW CR, R0
  36  	MOVD R0, 8(R1)
  37  
  38  	// Allocate our stack frame
  39  	MOVDU R1, -SAVE_SIZE(R1)
  40  
  41  	// Save TOC (R2) in case needed
  42  	MOVD R2, 24(R1)
  43  
  44  	// Save callee-save GPRs
  45  	SAVE_GPR(GPR_OFFSET)
  46  
  47  	// Save callee-save FPRs
  48  	SAVE_FPR(FPR_OFFSET)
  49  
  50  	// Initialize R0 to 0 as expected by Go
  51  	MOVD $0, R0
  52  
  53  	// Load the current g.
  54  	BL runtimeĀ·load_g(SB)
  55  
  56  	// Set up arguments for cgocallback
  57  	MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
  58  	MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
  59  
  60  	// Skip R5 = n uint32
  61  	MOVD R6, FIXED_FRAME+16(R1)  // ctxt uintptr
  62  	BL   runtimeĀ·cgocallback(SB)
  63  
  64  	// Restore callee-save FPRs
  65  	RESTORE_FPR(FPR_OFFSET)
  66  
  67  	// Restore callee-save GPRs
  68  	RESTORE_GPR(GPR_OFFSET)
  69  
  70  	// Restore TOC
  71  	MOVD 24(R1), R2
  72  
  73  	// Deallocate stack frame
  74  	ADD $SAVE_SIZE, R1
  75  
  76  	// Restore LR and CR from caller's frame
  77  	MOVD 16(R1), R0
  78  	MOVD R0, LR
  79  	MOVD 8(R1), R0
  80  	MOVW R0, CR
  81  
  82  	RET
  83