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 */
82F	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
86F	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
92F	SETL	[D1Ar3++], ACF.0
93F	SETL	[D1Ar3++], ACF.1
94F	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 */
166F	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
170F	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
176F	GETL	ACF.0, [D1Ar3++]
177F	GETL	ACF.1, [D1Ar3++]
178F	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 */
191