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