xref: /nrf52832-nimble/rt-thread/libcpu/mips/x1000/mips_fp_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero/*
2*10465441SEvalZero * File      : mips_vfp32_asm.S
3*10465441SEvalZero * This file is part of RT-Thread RTOS
4*10465441SEvalZero * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
5*10465441SEvalZero *
6*10465441SEvalZero *  This program is free software; you can redistribute it and/or modify
7*10465441SEvalZero *  it under the terms of the GNU General Public License as published by
8*10465441SEvalZero *  the Free Software Foundation; either version 2 of the License, or
9*10465441SEvalZero *  (at your option) any later version.
10*10465441SEvalZero *
11*10465441SEvalZero *  This program is distributed in the hope that it will be useful,
12*10465441SEvalZero *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*10465441SEvalZero *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*10465441SEvalZero *  GNU General Public License for more details.
15*10465441SEvalZero *
16*10465441SEvalZero *  You should have received a copy of the GNU General Public License along
17*10465441SEvalZero *  with this program; if not, write to the Free Software Foundation, Inc.,
18*10465441SEvalZero *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*10465441SEvalZero *
20*10465441SEvalZero * Change Logs:
21*10465441SEvalZero * Date           Author       Notes
22*10465441SEvalZero * 2016��9��9��     Urey         the first version
23*10465441SEvalZero */
24*10465441SEvalZero
25*10465441SEvalZero#ifndef __ASSEMBLY__
26*10465441SEvalZero#	define __ASSEMBLY__
27*10465441SEvalZero#endif
28*10465441SEvalZero
29*10465441SEvalZero#ifdef __mips_hard_float
30*10465441SEvalZero
31*10465441SEvalZero.module hardfloat
32*10465441SEvalZero.module doublefloat
33*10465441SEvalZero.set nomips16
34*10465441SEvalZero
35*10465441SEvalZero#include "../common/mips.h"
36*10465441SEvalZero#undef fp
37*10465441SEvalZero
38*10465441SEvalZero	.global mips_vfp32_init
39*10465441SEvalZeroLEAF(mips_vfp32_init)
40*10465441SEvalZero    mfc0 	t0, CP0_STATUS
41*10465441SEvalZero    or      t0 , M_StatusCU1
42*10465441SEvalZero    mtc0 	t0, CP0_STATUS
43*10465441SEvalZero    jr      ra
44*10465441SEvalZero    nop
45*10465441SEvalZeroEND(mips_vfp32_init)
46*10465441SEvalZero
47*10465441SEvalZero#
48*10465441SEvalZero# FUNCTION:	_fpctx_save
49*10465441SEvalZero#
50*10465441SEvalZero# DESCRIPTION:	save floating point registers to memory starting at a0
51*10465441SEvalZero#
52*10465441SEvalZero# RETURNS:	int
53*10465441SEvalZero#			0:	No context saved
54*10465441SEvalZero#			CTX_*:	Type of context stored
55*10465441SEvalZero#
56*10465441SEvalZero	.global _fpctx_save
57*10465441SEvalZeroLEAF(_fpctx_save)
58*10465441SEvalZero	sw 		zero, LINKCTX_NEXT(a0)
59*10465441SEvalZero	mfc0	t0, CP0_STATUS
60*10465441SEvalZero	li		t1, M_StatusCU1
61*10465441SEvalZero	and		t1, t0, t1
62*10465441SEvalZero	bnez	t1, 1f
63*10465441SEvalZero	# FP not enabled, bail out
64*10465441SEvalZero	move	v0, zero
65*10465441SEvalZero	jr		ra
66*10465441SEvalZero
67*10465441SEvalZero1:	# Save FP32 base
68*10465441SEvalZero	li		t1, ST0_FR
69*10465441SEvalZero	and		t0, t0, t1
70*10465441SEvalZero	cfc1	t2, $31
71*10465441SEvalZero	sw		t2, FP32CTX_CSR(a0)
72*10465441SEvalZero	sdc1	$f0, FP32CTX_0(a0)
73*10465441SEvalZero	sdc1	$f2, FP32CTX_2(a0)
74*10465441SEvalZero	sdc1	$f4, FP32CTX_4(a0)
75*10465441SEvalZero	sdc1	$f6, FP32CTX_6(a0)
76*10465441SEvalZero	sdc1	$f8, FP32CTX_8(a0)
77*10465441SEvalZero	sdc1	$f10, FP32CTX_10(a0)
78*10465441SEvalZero	sdc1	$f12, FP32CTX_12(a0)
79*10465441SEvalZero	sdc1	$f14, FP32CTX_14(a0)
80*10465441SEvalZero	sdc1	$f16, FP32CTX_16(a0)
81*10465441SEvalZero	sdc1	$f18, FP32CTX_18(a0)
82*10465441SEvalZero	sdc1	$f20, FP32CTX_20(a0)
83*10465441SEvalZero	sdc1	$f22, FP32CTX_22(a0)
84*10465441SEvalZero	sdc1	$f24, FP32CTX_24(a0)
85*10465441SEvalZero	sdc1	$f26, FP32CTX_26(a0)
86*10465441SEvalZero	sdc1	$f28, FP32CTX_28(a0)
87*10465441SEvalZero	sdc1	$f30, FP32CTX_30(a0)
88*10465441SEvalZero	bnez	t0, 2f
89*10465441SEvalZero	li		v0, LINKCTX_TYPE_FP32
90*10465441SEvalZero	sw		v0, LINKCTX_ID(a0)
91*10465441SEvalZero	jr		ra
92*10465441SEvalZero
93*10465441SEvalZero2:	# Save FP64 extra
94*10465441SEvalZero.set	push
95*10465441SEvalZero.set	fp=64
96*10465441SEvalZero	sdc1	$f1, FP64CTX_1(a0)
97*10465441SEvalZero	sdc1	$f3, FP64CTX_3(a0)
98*10465441SEvalZero	sdc1	$f5, FP64CTX_5(a0)
99*10465441SEvalZero	sdc1	$f7, FP64CTX_7(a0)
100*10465441SEvalZero	sdc1	$f9, FP64CTX_9(a0)
101*10465441SEvalZero	sdc1	$f11, FP64CTX_11(a0)
102*10465441SEvalZero	sdc1	$f13, FP64CTX_13(a0)
103*10465441SEvalZero	sdc1	$f15, FP64CTX_15(a0)
104*10465441SEvalZero	sdc1	$f17, FP64CTX_17(a0)
105*10465441SEvalZero	sdc1	$f19, FP64CTX_19(a0)
106*10465441SEvalZero	sdc1	$f21, FP64CTX_21(a0)
107*10465441SEvalZero	sdc1	$f23, FP64CTX_23(a0)
108*10465441SEvalZero	sdc1	$f25, FP64CTX_25(a0)
109*10465441SEvalZero	sdc1	$f27, FP64CTX_27(a0)
110*10465441SEvalZero	sdc1	$f29, FP64CTX_29(a0)
111*10465441SEvalZero	sdc1	$f31, FP64CTX_31(a0)
112*10465441SEvalZero.set	pop
113*10465441SEvalZero	li	v0, LINKCTX_TYPE_FP64
114*10465441SEvalZero	sw	v0, LINKCTX_ID(a0)
115*10465441SEvalZero	jr	ra
116*10465441SEvalZeroEND(_fpctx_save)
117*10465441SEvalZero
118*10465441SEvalZero#
119*10465441SEvalZero# FUNCTION:	_fpctx_load
120*10465441SEvalZero#
121*10465441SEvalZero# DESCRIPTION:	load floating point registers from context chain starting at a0
122*10465441SEvalZero#
123*10465441SEvalZero# RETURNS:	int
124*10465441SEvalZero#			0:	Unrecognised context
125*10465441SEvalZero#			CTX_*:	Type of context restored
126*10465441SEvalZero#
127*10465441SEvalZero	.global _fpctx_load
128*10465441SEvalZeroLEAF(_fpctx_load)
129*10465441SEvalZero	lw	v0, LINKCTX_ID(a0)
130*10465441SEvalZero	# Detect type
131*10465441SEvalZero	li	t0, LINKCTX_TYPE_FP64
132*10465441SEvalZero	li	t1, LINKCTX_TYPE_FP32
133*10465441SEvalZero	li	t2, M_StatusCU1
134*10465441SEvalZero	beq	v0, t0, 0f
135*10465441SEvalZero	beq	v0, t1, 1f
136*10465441SEvalZero	# Don't recognise this context, fail
137*10465441SEvalZero	move	v0, zero
138*10465441SEvalZero	jr	ra
139*10465441SEvalZero
140*10465441SEvalZero0: 	# FP64 context
141*10465441SEvalZero	# Enable CU1
142*10465441SEvalZero	di	t3
143*10465441SEvalZero	ehb
144*10465441SEvalZero	or	t3, t3, t2
145*10465441SEvalZero	mtc0	t3, CP0_STATUS
146*10465441SEvalZero	ehb
147*10465441SEvalZero	# Load FP64 extra
148*10465441SEvalZero.set	push
149*10465441SEvalZero.set	fp=64
150*10465441SEvalZero	ldc1	$f1, FP64CTX_1(a0)
151*10465441SEvalZero	ldc1	$f3, FP64CTX_3(a0)
152*10465441SEvalZero	ldc1	$f5, FP64CTX_5(a0)
153*10465441SEvalZero	ldc1	$f7, FP64CTX_7(a0)
154*10465441SEvalZero	ldc1	$f9, FP64CTX_9(a0)
155*10465441SEvalZero	ldc1	$f11, FP64CTX_11(a0)
156*10465441SEvalZero	ldc1	$f13, FP64CTX_13(a0)
157*10465441SEvalZero	ldc1	$f15, FP64CTX_15(a0)
158*10465441SEvalZero	ldc1	$f17, FP64CTX_17(a0)
159*10465441SEvalZero	ldc1	$f19, FP64CTX_19(a0)
160*10465441SEvalZero	ldc1	$f21, FP64CTX_21(a0)
161*10465441SEvalZero	ldc1	$f23, FP64CTX_23(a0)
162*10465441SEvalZero	ldc1	$f25, FP64CTX_25(a0)
163*10465441SEvalZero	ldc1	$f27, FP64CTX_27(a0)
164*10465441SEvalZero	ldc1	$f29, FP64CTX_29(a0)
165*10465441SEvalZero	ldc1	$f31, FP64CTX_31(a0)
166*10465441SEvalZero.set	pop
167*10465441SEvalZero1: 	# FP32 context
168*10465441SEvalZero	# Enable CU1
169*10465441SEvalZero	di	t3
170*10465441SEvalZero	ehb
171*10465441SEvalZero	or	t3, t3, t2
172*10465441SEvalZero	mtc0	t3, CP0_STATUS
173*10465441SEvalZero	ehb
174*10465441SEvalZero	# Load FP32 base
175*10465441SEvalZero	lw	t1, FP32CTX_CSR(a0)
176*10465441SEvalZero	ctc1	t1, $31
177*10465441SEvalZero	ldc1	$f0, FP32CTX_0(a0)
178*10465441SEvalZero	ldc1	$f2, FP32CTX_2(a0)
179*10465441SEvalZero	ldc1	$f4, FP32CTX_4(a0)
180*10465441SEvalZero	ldc1	$f6, FP32CTX_6(a0)
181*10465441SEvalZero	ldc1	$f8, FP32CTX_8(a0)
182*10465441SEvalZero	ldc1	$f10, FP32CTX_10(a0)
183*10465441SEvalZero	ldc1	$f12, FP32CTX_12(a0)
184*10465441SEvalZero	ldc1	$f14, FP32CTX_14(a0)
185*10465441SEvalZero	ldc1	$f16, FP32CTX_16(a0)
186*10465441SEvalZero	ldc1	$f18, FP32CTX_18(a0)
187*10465441SEvalZero	ldc1	$f20, FP32CTX_20(a0)
188*10465441SEvalZero	ldc1	$f22, FP32CTX_22(a0)
189*10465441SEvalZero	ldc1	$f24, FP32CTX_24(a0)
190*10465441SEvalZero	ldc1	$f26, FP32CTX_26(a0)
191*10465441SEvalZero	ldc1	$f28, FP32CTX_28(a0)
192*10465441SEvalZero	ldc1	$f30, FP32CTX_30(a0)
193*10465441SEvalZero	# Return CTX_FP32/64
194*10465441SEvalZero	jr	ra
195*10465441SEvalZeroEND(_fpctx_load)
196*10465441SEvalZero
197*10465441SEvalZero#endif
198