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