Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / metag / tbx / tbictxfpu.S
1 /*
2  * tbictxfpu.S
3  *
4  * Copyright (C) 2009, 2012 Imagination Technologies.
5  *
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation.
9  *
10  * Explicit state save and restore routines forming part of the thread binary
11  * interface for META processors
12  */
13
14         .file   "tbifpuctx.S"
15
16 #include <asm/metag_regs.h>
17 #include <asm/tbx.h>
18
19 #ifdef TBI_1_4
20 /*
21  * void *__TBICtxFPUSave( TBIRES State, void *pExt )
22  *
23  *                 D0Ar2 contains TBICTX_*_BIT values that control what
24  *                    extended data is to be saved.
25  *                 These bits must be ored into the SaveMask of this structure.
26  *
27  *                 Virtually all possible scratch registers are used.
28  */
29         .text
30         .balign 4
31         .global ___TBICtxFPUSave
32         .type   ___TBICtxFPUSave,function
33 ___TBICtxFPUSave:
34
35         /* D1Ar1:D0Ar2 - State
36          * D1Ar3       - pExt
37          * D0Ar4       - Value of METAC_CORE_ID
38          * D1Ar5       - Scratch
39          * D0Ar6       - Scratch
40          */
41         
42         /* If the FPAC bit isnt set then there is nothing to do */
43         TSTT    D0Ar2,#TBICTX_FPAC_BIT
44         MOVZ    PC, D1RtP
45
46         /* Obtain the Core config */
47         MOVT    D0Ar4,        #HI(METAC_CORE_ID)
48         ADD     D0Ar4, D0Ar4, #LO(METAC_CORE_ID)
49         GETD    D0Ar4, [D0Ar4]
50
51         /* Detect FX.8 - FX.15 and add to core config */
52         MOV     D0Ar6, TXENABLE
53         AND     D0Ar6, D0Ar6, #(TXENABLE_CLASSALT_FPUR8 << TXENABLE_CLASS_S)
54         AND     D0Ar4, D0Ar4, #LO(0x0000FFFF)
55         ORT     D0Ar4, D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT)
56         XOR     D0Ar4, D0Ar4, D0Ar6
57
58         /* Save the relevant bits to the buffer */
59         SETD    [D1Ar3++], D0Ar4
60
61         /* Save the relevant bits of TXDEFR (Assumes TXDEFR is coherent) ... */
62         MOV     D0Ar6, TXDEFR
63         LSR     D0Re0, D0Ar6, #8
64         AND     D0Re0, D0Re0, #LO(TXDEFR_FPE_FE_BITS>>8)
65         AND     D0Ar6, D0Ar6, #LO(TXDEFR_FPE_ICTRL_BITS)
66         OR      D0Re0, D0Re0, D0Ar6
67
68         /* ... along with relevant bits of TXMODE to buffer */
69         MOV     D0Ar6, TXMODE
70         ANDT    D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS)
71         ORT     D0Ar6, D0Ar6, #HI(TXMODE_FPURMODEWRITE_BIT)
72         OR      D0Ar6, D0Ar6, D0Re0
73         SETD    [D1Ar3++], D0Ar6
74
75         GETD    D0Ar6,[D1Ar1+#TBICTX_SaveMask-2] /* Get the current SaveMask */
76         /* D0Ar6       - pCtx->SaveMask */
77
78         TSTT    D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
79                                                     * to avoid stalls
80                                                     */
81         /* Save the standard FPU registers */
82 F       MSETL   [D1Ar3++], FX.0, FX.2, FX.4, FX.6
83
84         /* Save the extended FPU registers if they are present */
85         BZ      $Lskip_save_fx8_fx16
86 F       MSETL   [D1Ar3++], FX.8, FX.10, FX.12, FX.14
87 $Lskip_save_fx8_fx16:
88
89         /* Save the FPU Accumulator if it is present */
90         TST     D0Ar4, #METAC_COREID_NOFPACC_BIT
91         BNZ     $Lskip_save_fpacc
92 F       SETL    [D1Ar3++], ACF.0
93 F       SETL    [D1Ar3++], ACF.1
94 F       SETL    [D1Ar3++], ACF.2
95 $Lskip_save_fpacc:
96
97         /* Update pCtx->SaveMask */
98         ANDT    D0Ar2, D0Ar2, #TBICTX_FPAC_BIT
99         OR      D0Ar6, D0Ar6, D0Ar2
100         SETD    [D1Ar1+#TBICTX_SaveMask-2],D0Ar6/* Add in XCBF bit to TBICTX */
101
102         MOV     D0Re0, D1Ar3 /* Return end of save area */
103         MOV     PC, D1RtP
104
105         .size   ___TBICtxFPUSave,.-___TBICtxFPUSave
106
107 /*
108  * void *__TBICtxFPURestore( TBIRES State, void *pExt )
109  *
110  *                 D0Ar2 contains TBICTX_*_BIT values that control what
111  *                    extended data is to be recovered from D1Ar3 (pExt).
112  *
113  *                 Virtually all possible scratch registers are used.
114  */
115 /*
116  * If TBICTX_XEXT_BIT is specified in State. Then the saved state of
117  *       the orginal A0.2 and A1.2 is restored from pExt and the XEXT
118  *       related flags are removed from State.pCtx->SaveMask.
119  *
120  */
121         .balign 4
122         .global ___TBICtxFPURestore
123         .type   ___TBICtxFPURestore,function
124 ___TBICtxFPURestore:
125
126         /* D1Ar1:D0Ar2 - State
127          * D1Ar3       - pExt
128          * D0Ar4       - Value of METAC_CORE_ID
129          * D1Ar5       - Scratch
130          * D0Ar6       - Scratch
131          * D1Re0       - Scratch
132          */
133
134         /* If the FPAC bit isnt set then there is nothing to do */
135         TSTT    D0Ar2,#TBICTX_FPAC_BIT
136         MOVZ    PC, D1RtP
137
138         /* Obtain the relevant bits of the Core config */
139         GETD    D0Ar4, [D1Ar3++]
140
141         /* Restore FPU related parts of TXDEFR. Assumes TXDEFR is coherent */
142         GETD    D1Ar5, [D1Ar3++]
143         MOV     D0Ar6, D1Ar5
144         LSL     D1Re0, D1Ar5, #8
145         ANDT    D1Re0, D1Re0, #HI(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
146         AND     D1Ar5, D1Ar5, #LO(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS)
147         OR      D1Re0, D1Re0, D1Ar5
148
149         MOV     D1Ar5, TXDEFR
150         ANDMT   D1Ar5, D1Ar5, #HI(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
151         ANDMB   D1Ar5, D1Ar5, #LO(~(TXDEFR_FPE_FE_BITS|TXDEFR_FPE_ICTRL_BITS))
152         OR      D1Re0, D1Re0, D1Ar5
153         MOV     TXDEFR, D1Re0
154
155         /* Restore relevant bits of TXMODE */
156         MOV     D1Ar5, TXMODE
157         ANDMT   D1Ar5, D1Ar5, #HI(~TXMODE_FPURMODE_BITS)
158         ANDT    D0Ar6, D0Ar6, #HI(TXMODE_FPURMODE_BITS|TXMODE_FPURMODEWRITE_BIT)
159         OR      D0Ar6, D0Ar6, D1Ar5
160         MOV     TXMODE, D0Ar6
161
162         TSTT    D0Ar4, #HI(TBICTX_CFGFPU_FX16_BIT) /* Perform test here for extended FPU registers
163                                                     * to avoid stalls
164                                                     */
165         /* Save the standard FPU registers */
166 F       MGETL   FX.0, FX.2, FX.4, FX.6, [D1Ar3++]
167
168         /* Save the extended FPU registers if they are present */
169         BZ      $Lskip_restore_fx8_fx16
170 F       MGETL   FX.8, FX.10, FX.12, FX.14, [D1Ar3++]
171 $Lskip_restore_fx8_fx16:
172
173         /* Save the FPU Accumulator if it is present */
174         TST     D0Ar4, #METAC_COREID_NOFPACC_BIT
175         BNZ     $Lskip_restore_fpacc
176 F       GETL    ACF.0, [D1Ar3++]
177 F       GETL    ACF.1, [D1Ar3++]
178 F       GETL    ACF.2, [D1Ar3++]
179 $Lskip_restore_fpacc:
180
181         MOV     D0Re0, D1Ar3 /* Return end of save area */
182         MOV     PC, D1RtP
183
184         .size   ___TBICtxFPURestore,.-___TBICtxFPURestore
185
186 #endif /* TBI_1_4 */
187
188 /*
189  * End of tbictx.S
190  */