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