| // Copyright 2016 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | // +build mips mipsle | 
 |  | 
 | /* | 
 |  * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g) | 
 |  * | 
 |  * Calling into the gc tool chain, where all registers are caller save. | 
 |  * Called from standard MIPS O32 ABI, where $16-$23, $30, and $f20-$f31 | 
 |  * are callee-save, so they must be saved explicitly, along with $31 (LR). | 
 |  */ | 
 | .globl crosscall1 | 
 | .set noat | 
 | crosscall1: | 
 | #ifndef __mips_soft_float | 
 | 	addiu	$29, $29, -88 | 
 | #else | 
 | 	addiu	$29, $29, -40 // For soft-float, no need to make room for FP registers | 
 | #endif | 
 | 	sw	$31, 0($29) | 
 | 	sw	$16, 4($29) | 
 | 	sw	$17, 8($29) | 
 | 	sw	$18, 12($29) | 
 | 	sw	$19, 16($29) | 
 | 	sw	$20, 20($29) | 
 | 	sw	$21, 24($29) | 
 | 	sw	$22, 28($29) | 
 | 	sw	$23, 32($29) | 
 | 	sw	$30, 36($29) | 
 |  | 
 | #ifndef __mips_soft_float | 
 | 	sdc1	$f20, 40($29) | 
 | 	sdc1	$f22, 48($29) | 
 | 	sdc1	$f24, 56($29) | 
 | 	sdc1	$f26, 64($29) | 
 | 	sdc1	$f28, 72($29) | 
 | 	sdc1	$f30, 80($29) | 
 | #endif | 
 | 	move	$20, $4 // save R4 | 
 | 	move	$4, $6 | 
 | 	jalr	$5	// call setg_gcc | 
 | 	jalr	$20	// call fn | 
 |  | 
 | 	lw	$16, 4($29) | 
 | 	lw	$17, 8($29) | 
 | 	lw	$18, 12($29) | 
 | 	lw	$19, 16($29) | 
 | 	lw	$20, 20($29) | 
 | 	lw	$21, 24($29) | 
 | 	lw	$22, 28($29) | 
 | 	lw	$23, 32($29) | 
 | 	lw	$30, 36($29) | 
 | #ifndef __mips_soft_float | 
 | 	ldc1	$f20, 40($29) | 
 | 	ldc1	$f22, 48($29) | 
 | 	ldc1	$f24, 56($29) | 
 | 	ldc1	$f26, 64($29) | 
 | 	ldc1	$f28, 72($29) | 
 | 	ldc1	$f30, 80($29) | 
 | #endif | 
 | 	lw	$31, 0($29) | 
 | #ifndef __mips_soft_float | 
 | 	addiu	$29, $29, 88 | 
 | #else | 
 | 	addiu	$29, $29, 40 | 
 | #endif | 
 | 	jr	$31 | 
 |  | 
 | .set at | 
 |  | 
 | #ifdef __ELF__ | 
 | .section .note.GNU-stack,"",%progbits | 
 | #endif |