aboutsummaryrefslogtreecommitdiff
path: root/arch/metag/tbx/tbictxfpu.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/metag/tbx/tbictxfpu.S')
-rw-r--r--arch/metag/tbx/tbictxfpu.S190
1 files changed, 190 insertions, 0 deletions
diff --git a/arch/metag/tbx/tbictxfpu.S b/arch/metag/tbx/tbictxfpu.S
new file mode 100644
index 00000000000..e773bea3e7b
--- /dev/null
+++ b/arch/metag/tbx/tbictxfpu.S
@@ -0,0 +1,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
+ */