summaryrefslogtreecommitdiffstats
path: root/arch/metag/tbx/tbictxfpu.S
blob: e773bea3e7bd00ed29803e17b27d589963fac55a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * tbictxfpu.S
 *
 * Copyright (C) 2009, 2012 Imagination Technologies.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 *
 * Explicit state save and restore routines forming part of the thread binary
 * interface for META processors
 */

	.file	"tbifpuctx.S"

#include <asm/metag_regs.h>
#include <asm/tbx.h>

#ifdef TBI_1_4
/*
 * void *__TBICtxFPUSave( TBIRES State, void *pExt )
 *
 *                 D0Ar2 contains TBICTX_*_BIT values that control what
 *                    extended data is to be saved.
 *                 These bits must be ored into the SaveMask of this structure.
 *
 *                 Virtually all possible scratch registers are used.
 */
	.text
	.balign	4
	.global	___TBICtxFPUSave
	.type	___TBICtxFPUSave,function
___TBICtxFPUSave:

	/* D1Ar1:D0Ar2 - State
	 * D1Ar3       - pExt
	 * D0Ar4       - Value of METAC_CORE_ID
	 * D1Ar5       - Scratch
	 * D0Ar6       - Scratch
	 */
	
	/* If the FPAC bit isnt set then there is nothing to do */
	TSTT	D0Ar2,#TBICTX_FPAC_BIT
	MOVZ	PC, D1RtP

	/* Obtain the Core config */
	MOVT	D0Ar4,        #HI(METAC_CORE_ID)
	ADD	D0Ar4, D0Ar4, #LO(METAC_CORE_ID)
	GETD	D0Ar4, [D0Ar4]

	/* Detect FX.8 - FX.15 and add to core config */
	MOV	D0Ar6, TXENABLE
	AND	D0Ar6, D0Ar6, #(TXENABLE_CLASSALT_FPUR8 << TXENABLE_CLASS_S)
	AND	D0Ar4, D0Ar4, #LO(0x0000FFFF)
	ORT	D0Ar4, D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT)
	XOR	D0Ar4, D0Ar4, D0Ar6

	/* Save the relevant bits to the buffer */
	SETD	[D1Ar3++], D0Ar4

	/* Save the relevant bits of TXDEFR (Assumes TXDEFR is coherent) ... */
	MOV	D0Ar6, TXDEFR
	LSR	D0Re0, D0Ar6, #8
	AND	D0Re0, D0Re0, #LO(TXDEFR_FPE_FE_BITS>>8)
	AND	D0Ar6, D0Ar6, #LO(TXDEFR_FPE_ICTRL_BITS)
	OR	D0Re0, D0Re0, D0Ar6

	/* ... along with relevant bits of TXMODE to buffer */
	MOV	D0Ar6, TXMODE
	ANDT	D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS)
	ORT	D0Ar6, D0Ar6, #HI(TXMODE_FPURMODEWRITE_BIT)
	OR	D0Ar6, D0Ar6, D0Re0
	SETD	[D1Ar3++], D0Ar6

	GETD	D0Ar6,[D1Ar1+#TBICTX_SaveMask-2] /* Get the current SaveMask */
	/* D0Ar6       - pCtx->SaveMask */

	TSTT	D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
	    	                                    * to avoid stalls
	    	                                    */
	/* Save the standard FPU registers */
F	MSETL	[D1Ar3++], FX.0, FX.2, FX.4, FX.6

	/* Save the extended FPU registers if they are present */
	BZ	$Lskip_save_fx8_fx16
F	MSETL	[D1Ar3++], FX.8, FX.10, FX.12, FX.14
$Lskip_save_fx8_fx16:

	/* Save the FPU Accumulator if it is present */
	TST	D0Ar4, #METAC_COREID_NOFPACC_BIT
	BNZ	$Lskip_save_fpacc
F	SETL	[D1Ar3++], ACF.0
F	SETL	[D1Ar3++], ACF.1
F	SETL	[D1Ar3++], ACF.2
$Lskip_save_fpacc:

	/* Update pCtx->SaveMask */
	ANDT	D0Ar2, D0Ar2, #TBICTX_FPAC_BIT
	OR	D0Ar6, D0Ar6, D0Ar2
	SETD	[D1Ar1+#TBICTX_SaveMask-2],D0Ar6/* Add in XCBF bit to TBICTX */

	MOV	D0Re0, D1Ar3 /* Return end of save area */
	MOV	PC, D1RtP

	.size	___TBICtxFPUSave,.-___TBICtxFPUSave

/*
 * void *__TBICtxFPURestore( TBIRES State, void *pExt )
 *
 *                 D0Ar2 contains TBICTX_*_BIT values that control what
 *                    extended data is to be recovered from D1Ar3 (pExt).
 *
 *                 Virtually all possible scratch registers are used.
 */
/*
 * If TBICTX_XEXT_BIT is specified in State. Then the saved state of
 *       the orginal A0.2 and A1.2 is restored from pExt and the XEXT
 *       related flags are removed from State.pCtx->SaveMask.
 *
 */
	.balign	4
	.global	___TBICtxFPURestore
	.type	___TBICtxFPURestore,function
___TBICtxFPURestore:

	/* D1Ar1:D0Ar2 - State
	 * D1Ar3       - pExt
	 * D0Ar4       - Value of METAC_CORE_ID
	 * D1Ar5       - Scratch
	 * D0Ar6       - Scratch
	 * D1Re0       - Scratch
	 */

	/* If the FPAC bit isnt set then there is nothing to do */
	TSTT	D0Ar2,#TBICTX_FPAC_BIT
	MOVZ	PC, D1RtP

	/* Obtain the relevant bits of the Core config */
	GETD	D0Ar4, [D1Ar3++]

	/* Restore FPU related parts of TXDEFR. Assumes TXDEFR is coherent */
	GETD	D1Ar5, [D1Ar3++]
	MOV	D0Ar6, D1Ar5
	LSL	D1Re0, D1Ar5, #8
	ANDT	D1Re0, D1Re0, #HI(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
	AND	D1Ar5, D1Ar5, #LO(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
	OR	D1Re0, D1Re0, D1Ar5

	MOV	D1Ar5, TXDEFR
	ANDMT	D1Ar5, D1Ar5, #HI(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
	ANDMB	D1Ar5, D1Ar5, #LO(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
	OR	D1Re0, D1Re0, D1Ar5
	MOV	TXDEFR, D1Re0

	/* Restore relevant bits of TXMODE */
	MOV	D1Ar5, TXMODE
	ANDMT	D1Ar5, D1Ar5, #HI(~TXMODE_FPURMODE_BITS)
	ANDT	D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS|TXMODE_FPURMODEWRITE_BIT)
	OR	D0Ar6, D0Ar6, D1Ar5
	MOV	TXMODE, D0Ar6

	TSTT	D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
	    	                                    * to avoid stalls
	    	                                    */
	/* Save the standard FPU registers */
F	MGETL	FX.0, FX.2, FX.4, FX.6, [D1Ar3++]

	/* Save the extended FPU registers if they are present */
	BZ	$Lskip_restore_fx8_fx16
F	MGETL	FX.8, FX.10, FX.12, FX.14, [D1Ar3++]
$Lskip_restore_fx8_fx16:

	/* Save the FPU Accumulator if it is present */
	TST	D0Ar4, #METAC_COREID_NOFPACC_BIT
	BNZ	$Lskip_restore_fpacc
F	GETL	ACF.0, [D1Ar3++]
F	GETL	ACF.1, [D1Ar3++]
F	GETL	ACF.2, [D1Ar3++]
$Lskip_restore_fpacc:

	MOV	D0Re0, D1Ar3 /* Return end of save area */
	MOV	PC, D1RtP

	.size	___TBICtxFPURestore,.-___TBICtxFPURestore

#endif /* TBI_1_4 */

/*
 * End of tbictx.S
 */