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
*/
|