198 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			198 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
|  | /* | |||
|  |  * File      : mips_vfp32_asm.S | |||
|  |  * This file is part of RT-Thread RTOS | |||
|  |  * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team | |||
|  |  * | |||
|  |  *  This program is free software; you can redistribute it and/or modify
 | |||
|  |  *  it under the terms of the GNU General Public License as published by | |||
|  |  *  the Free Software Foundation; either version 2 of the License, or
 | |||
|  |  *  (at your option) any later version. | |||
|  |  * | |||
|  |  *  This program is distributed in the hope that it will be useful, | |||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |||
|  |  *  GNU General Public License for more details. | |||
|  |  * | |||
|  |  *  You should have received a copy of the GNU General Public License along | |||
|  |  *  with this program; if not, write to the Free Software Foundation, Inc.,
 | |||
|  |  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||
|  |  * | |||
|  |  * Change Logs: | |||
|  |  * Date           Author       Notes | |||
|  |  * 2016<EFBFBD><EFBFBD>9<EFBFBD><EFBFBD>9<EFBFBD><EFBFBD>     Urey         the first version | |||
|  |  */ | |||
|  | 
 | |||
|  | #ifndef __ASSEMBLY__ | |||
|  | #	define __ASSEMBLY__ | |||
|  | #endif | |||
|  | 
 | |||
|  | #ifdef __mips_hard_float | |||
|  | 
 | |||
|  | .module hardfloat
 | |||
|  | .module doublefloat
 | |||
|  | .set nomips16
 | |||
|  | 
 | |||
|  | #include "../common/mips.h" | |||
|  | #undef fp | |||
|  | 
 | |||
|  | 	.global mips_vfp32_init
 | |||
|  | LEAF(mips_vfp32_init) | |||
|  |     mfc0 	t0, CP0_STATUS | |||
|  |     or      t0 , M_StatusCU1 | |||
|  |     mtc0 	t0, CP0_STATUS | |||
|  |     jr      ra | |||
|  |     nop | |||
|  | END(mips_vfp32_init) | |||
|  | 
 | |||
|  | # | |||
|  | # FUNCTION:	_fpctx_save | |||
|  | # | |||
|  | # DESCRIPTION:	save floating point registers to memory starting at a0 | |||
|  | # | |||
|  | # RETURNS:	int | |||
|  | #			0:	No context saved | |||
|  | #			CTX_*:	Type of context stored | |||
|  | # | |||
|  | 	.global _fpctx_save
 | |||
|  | LEAF(_fpctx_save) | |||
|  | 	sw 		zero, LINKCTX_NEXT(a0) | |||
|  | 	mfc0	t0, CP0_STATUS | |||
|  | 	li		t1, M_StatusCU1 | |||
|  | 	and		t1, t0, t1 | |||
|  | 	bnez	t1, 1f | |||
|  | 	# FP not enabled, bail out | |||
|  | 	move	v0, zero | |||
|  | 	jr		ra | |||
|  | 
 | |||
|  | 1:	# Save FP32 base | |||
|  | 	li		t1, ST0_FR | |||
|  | 	and		t0, t0, t1 | |||
|  | 	cfc1	t2, $31 | |||
|  | 	sw		t2, FP32CTX_CSR(a0) | |||
|  | 	sdc1	$f0, FP32CTX_0(a0) | |||
|  | 	sdc1	$f2, FP32CTX_2(a0) | |||
|  | 	sdc1	$f4, FP32CTX_4(a0) | |||
|  | 	sdc1	$f6, FP32CTX_6(a0) | |||
|  | 	sdc1	$f8, FP32CTX_8(a0) | |||
|  | 	sdc1	$f10, FP32CTX_10(a0) | |||
|  | 	sdc1	$f12, FP32CTX_12(a0) | |||
|  | 	sdc1	$f14, FP32CTX_14(a0) | |||
|  | 	sdc1	$f16, FP32CTX_16(a0) | |||
|  | 	sdc1	$f18, FP32CTX_18(a0) | |||
|  | 	sdc1	$f20, FP32CTX_20(a0) | |||
|  | 	sdc1	$f22, FP32CTX_22(a0) | |||
|  | 	sdc1	$f24, FP32CTX_24(a0) | |||
|  | 	sdc1	$f26, FP32CTX_26(a0) | |||
|  | 	sdc1	$f28, FP32CTX_28(a0) | |||
|  | 	sdc1	$f30, FP32CTX_30(a0) | |||
|  | 	bnez	t0, 2f | |||
|  | 	li		v0, LINKCTX_TYPE_FP32 | |||
|  | 	sw		v0, LINKCTX_ID(a0) | |||
|  | 	jr		ra | |||
|  | 
 | |||
|  | 2:	# Save FP64 extra | |||
|  | .set	push
 | |||
|  | .set	fp=64 | |||
|  | 	sdc1	$f1, FP64CTX_1(a0) | |||
|  | 	sdc1	$f3, FP64CTX_3(a0) | |||
|  | 	sdc1	$f5, FP64CTX_5(a0) | |||
|  | 	sdc1	$f7, FP64CTX_7(a0) | |||
|  | 	sdc1	$f9, FP64CTX_9(a0) | |||
|  | 	sdc1	$f11, FP64CTX_11(a0) | |||
|  | 	sdc1	$f13, FP64CTX_13(a0) | |||
|  | 	sdc1	$f15, FP64CTX_15(a0) | |||
|  | 	sdc1	$f17, FP64CTX_17(a0) | |||
|  | 	sdc1	$f19, FP64CTX_19(a0) | |||
|  | 	sdc1	$f21, FP64CTX_21(a0) | |||
|  | 	sdc1	$f23, FP64CTX_23(a0) | |||
|  | 	sdc1	$f25, FP64CTX_25(a0) | |||
|  | 	sdc1	$f27, FP64CTX_27(a0) | |||
|  | 	sdc1	$f29, FP64CTX_29(a0) | |||
|  | 	sdc1	$f31, FP64CTX_31(a0) | |||
|  | .set	pop
 | |||
|  | 	li	v0, LINKCTX_TYPE_FP64 | |||
|  | 	sw	v0, LINKCTX_ID(a0) | |||
|  | 	jr	ra | |||
|  | END(_fpctx_save) | |||
|  | 
 | |||
|  | # | |||
|  | # FUNCTION:	_fpctx_load | |||
|  | # | |||
|  | # DESCRIPTION:	load floating point registers from context chain starting at a0 | |||
|  | # | |||
|  | # RETURNS:	int | |||
|  | #			0:	Unrecognised context | |||
|  | #			CTX_*:	Type of context restored | |||
|  | # | |||
|  | 	.global _fpctx_load
 | |||
|  | LEAF(_fpctx_load) | |||
|  | 	lw	v0, LINKCTX_ID(a0) | |||
|  | 	# Detect type | |||
|  | 	li	t0, LINKCTX_TYPE_FP64 | |||
|  | 	li	t1, LINKCTX_TYPE_FP32 | |||
|  | 	li	t2, M_StatusCU1 | |||
|  | 	beq	v0, t0, 0f | |||
|  | 	beq	v0, t1, 1f | |||
|  | 	# Don't recognise this context, fail | |||
|  | 	move	v0, zero | |||
|  | 	jr	ra | |||
|  | 
 | |||
|  | 0: 	# FP64 context | |||
|  | 	# Enable CU1 | |||
|  | 	di	t3 | |||
|  | 	ehb | |||
|  | 	or	t3, t3, t2 | |||
|  | 	mtc0	t3, CP0_STATUS | |||
|  | 	ehb | |||
|  | 	# Load FP64 extra | |||
|  | .set	push
 | |||
|  | .set	fp=64 | |||
|  | 	ldc1	$f1, FP64CTX_1(a0) | |||
|  | 	ldc1	$f3, FP64CTX_3(a0) | |||
|  | 	ldc1	$f5, FP64CTX_5(a0) | |||
|  | 	ldc1	$f7, FP64CTX_7(a0) | |||
|  | 	ldc1	$f9, FP64CTX_9(a0) | |||
|  | 	ldc1	$f11, FP64CTX_11(a0) | |||
|  | 	ldc1	$f13, FP64CTX_13(a0) | |||
|  | 	ldc1	$f15, FP64CTX_15(a0) | |||
|  | 	ldc1	$f17, FP64CTX_17(a0) | |||
|  | 	ldc1	$f19, FP64CTX_19(a0) | |||
|  | 	ldc1	$f21, FP64CTX_21(a0) | |||
|  | 	ldc1	$f23, FP64CTX_23(a0) | |||
|  | 	ldc1	$f25, FP64CTX_25(a0) | |||
|  | 	ldc1	$f27, FP64CTX_27(a0) | |||
|  | 	ldc1	$f29, FP64CTX_29(a0) | |||
|  | 	ldc1	$f31, FP64CTX_31(a0) | |||
|  | .set	pop
 | |||
|  | 1: 	# FP32 context | |||
|  | 	# Enable CU1 | |||
|  | 	di	t3 | |||
|  | 	ehb | |||
|  | 	or	t3, t3, t2 | |||
|  | 	mtc0	t3, CP0_STATUS | |||
|  | 	ehb | |||
|  | 	# Load FP32 base | |||
|  | 	lw	t1, FP32CTX_CSR(a0) | |||
|  | 	ctc1	t1, $31 | |||
|  | 	ldc1	$f0, FP32CTX_0(a0) | |||
|  | 	ldc1	$f2, FP32CTX_2(a0) | |||
|  | 	ldc1	$f4, FP32CTX_4(a0) | |||
|  | 	ldc1	$f6, FP32CTX_6(a0) | |||
|  | 	ldc1	$f8, FP32CTX_8(a0) | |||
|  | 	ldc1	$f10, FP32CTX_10(a0) | |||
|  | 	ldc1	$f12, FP32CTX_12(a0) | |||
|  | 	ldc1	$f14, FP32CTX_14(a0) | |||
|  | 	ldc1	$f16, FP32CTX_16(a0) | |||
|  | 	ldc1	$f18, FP32CTX_18(a0) | |||
|  | 	ldc1	$f20, FP32CTX_20(a0) | |||
|  | 	ldc1	$f22, FP32CTX_22(a0) | |||
|  | 	ldc1	$f24, FP32CTX_24(a0) | |||
|  | 	ldc1	$f26, FP32CTX_26(a0) | |||
|  | 	ldc1	$f28, FP32CTX_28(a0) | |||
|  | 	ldc1	$f30, FP32CTX_30(a0) | |||
|  | 	# Return CTX_FP32/64 | |||
|  | 	jr	ra | |||
|  | END(_fpctx_load) | |||
|  | 
 | |||
|  | #endif |