![Thomas Gleixner](/assets/img/avatar_default.png)
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 3029 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
279 lines
5.5 KiB
ArmAsm
279 lines
5.5 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* FPU helper code to use FPU operations from inside the kernel
|
|
*
|
|
* Copyright (C) 2010 Alexander Graf (agraf@suse.de)
|
|
*/
|
|
|
|
#include <asm/reg.h>
|
|
#include <asm/page.h>
|
|
#include <asm/mmu.h>
|
|
#include <asm/pgtable.h>
|
|
#include <asm/cputable.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/thread_info.h>
|
|
#include <asm/ppc_asm.h>
|
|
#include <asm/asm-offsets.h>
|
|
|
|
/* Instructions operating on single parameters */
|
|
|
|
/*
|
|
* Single operation with one input operand
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (short*)&result
|
|
* R5 = (short*)¶m1
|
|
*/
|
|
#define FPS_ONE_IN(name) \
|
|
_GLOBAL(fps_ ## name); \
|
|
lfd 0,0(r3); /* load up fpscr value */ \
|
|
MTFSF_L(0); \
|
|
lfs 0,0(r5); \
|
|
\
|
|
name 0,0; \
|
|
\
|
|
stfs 0,0(r4); \
|
|
mffs 0; \
|
|
stfd 0,0(r3); /* save new fpscr value */ \
|
|
blr
|
|
|
|
/*
|
|
* Single operation with two input operands
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (short*)&result
|
|
* R5 = (short*)¶m1
|
|
* R6 = (short*)¶m2
|
|
*/
|
|
#define FPS_TWO_IN(name) \
|
|
_GLOBAL(fps_ ## name); \
|
|
lfd 0,0(r3); /* load up fpscr value */ \
|
|
MTFSF_L(0); \
|
|
lfs 0,0(r5); \
|
|
lfs 1,0(r6); \
|
|
\
|
|
name 0,0,1; \
|
|
\
|
|
stfs 0,0(r4); \
|
|
mffs 0; \
|
|
stfd 0,0(r3); /* save new fpscr value */ \
|
|
blr
|
|
|
|
/*
|
|
* Single operation with three input operands
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (short*)&result
|
|
* R5 = (short*)¶m1
|
|
* R6 = (short*)¶m2
|
|
* R7 = (short*)¶m3
|
|
*/
|
|
#define FPS_THREE_IN(name) \
|
|
_GLOBAL(fps_ ## name); \
|
|
lfd 0,0(r3); /* load up fpscr value */ \
|
|
MTFSF_L(0); \
|
|
lfs 0,0(r5); \
|
|
lfs 1,0(r6); \
|
|
lfs 2,0(r7); \
|
|
\
|
|
name 0,0,1,2; \
|
|
\
|
|
stfs 0,0(r4); \
|
|
mffs 0; \
|
|
stfd 0,0(r3); /* save new fpscr value */ \
|
|
blr
|
|
|
|
FPS_ONE_IN(fres)
|
|
FPS_ONE_IN(frsqrte)
|
|
FPS_ONE_IN(fsqrts)
|
|
FPS_TWO_IN(fadds)
|
|
FPS_TWO_IN(fdivs)
|
|
FPS_TWO_IN(fmuls)
|
|
FPS_TWO_IN(fsubs)
|
|
FPS_THREE_IN(fmadds)
|
|
FPS_THREE_IN(fmsubs)
|
|
FPS_THREE_IN(fnmadds)
|
|
FPS_THREE_IN(fnmsubs)
|
|
FPS_THREE_IN(fsel)
|
|
|
|
|
|
/* Instructions operating on double parameters */
|
|
|
|
/*
|
|
* Beginning of double instruction processing
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
* R6 = (double*)¶m1
|
|
* R7 = (double*)¶m2 [load_two]
|
|
* R8 = (double*)¶m3 [load_three]
|
|
* LR = instruction call function
|
|
*/
|
|
fpd_load_three:
|
|
lfd 2,0(r8) /* load param3 */
|
|
fpd_load_two:
|
|
lfd 1,0(r7) /* load param2 */
|
|
fpd_load_one:
|
|
lfd 0,0(r6) /* load param1 */
|
|
fpd_load_none:
|
|
lfd 3,0(r3) /* load up fpscr value */
|
|
MTFSF_L(3)
|
|
lwz r6, 0(r4) /* load cr */
|
|
mtcr r6
|
|
blr
|
|
|
|
/*
|
|
* End of double instruction processing
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
* LR = caller of instruction call function
|
|
*/
|
|
fpd_return:
|
|
mfcr r6
|
|
stfd 0,0(r5) /* save result */
|
|
mffs 0
|
|
stfd 0,0(r3) /* save new fpscr value */
|
|
stw r6,0(r4) /* save new cr value */
|
|
blr
|
|
|
|
/*
|
|
* Double operation with no input operand
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
*/
|
|
#define FPD_NONE_IN(name) \
|
|
_GLOBAL(fpd_ ## name); \
|
|
mflr r12; \
|
|
bl fpd_load_none; \
|
|
mtlr r12; \
|
|
\
|
|
name. 0; /* call instruction */ \
|
|
b fpd_return
|
|
|
|
/*
|
|
* Double operation with one input operand
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
* R6 = (double*)¶m1
|
|
*/
|
|
#define FPD_ONE_IN(name) \
|
|
_GLOBAL(fpd_ ## name); \
|
|
mflr r12; \
|
|
bl fpd_load_one; \
|
|
mtlr r12; \
|
|
\
|
|
name. 0,0; /* call instruction */ \
|
|
b fpd_return
|
|
|
|
/*
|
|
* Double operation with two input operands
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
* R6 = (double*)¶m1
|
|
* R7 = (double*)¶m2
|
|
* R8 = (double*)¶m3
|
|
*/
|
|
#define FPD_TWO_IN(name) \
|
|
_GLOBAL(fpd_ ## name); \
|
|
mflr r12; \
|
|
bl fpd_load_two; \
|
|
mtlr r12; \
|
|
\
|
|
name. 0,0,1; /* call instruction */ \
|
|
b fpd_return
|
|
|
|
/*
|
|
* CR Double operation with two input operands
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)¶m1
|
|
* R6 = (double*)¶m2
|
|
* R7 = (double*)¶m3
|
|
*/
|
|
#define FPD_TWO_IN_CR(name) \
|
|
_GLOBAL(fpd_ ## name); \
|
|
lfd 1,0(r6); /* load param2 */ \
|
|
lfd 0,0(r5); /* load param1 */ \
|
|
lfd 3,0(r3); /* load up fpscr value */ \
|
|
MTFSF_L(3); \
|
|
lwz r6, 0(r4); /* load cr */ \
|
|
mtcr r6; \
|
|
\
|
|
name 0,0,1; /* call instruction */ \
|
|
mfcr r6; \
|
|
mffs 0; \
|
|
stfd 0,0(r3); /* save new fpscr value */ \
|
|
stw r6,0(r4); /* save new cr value */ \
|
|
blr
|
|
|
|
/*
|
|
* Double operation with three input operands
|
|
*
|
|
* R3 = (double*)&fpscr
|
|
* R4 = (u32*)&cr
|
|
* R5 = (double*)&result
|
|
* R6 = (double*)¶m1
|
|
* R7 = (double*)¶m2
|
|
* R8 = (double*)¶m3
|
|
*/
|
|
#define FPD_THREE_IN(name) \
|
|
_GLOBAL(fpd_ ## name); \
|
|
mflr r12; \
|
|
bl fpd_load_three; \
|
|
mtlr r12; \
|
|
\
|
|
name. 0,0,1,2; /* call instruction */ \
|
|
b fpd_return
|
|
|
|
FPD_ONE_IN(fsqrts)
|
|
FPD_ONE_IN(frsqrtes)
|
|
FPD_ONE_IN(fres)
|
|
FPD_ONE_IN(frsp)
|
|
FPD_ONE_IN(fctiw)
|
|
FPD_ONE_IN(fctiwz)
|
|
FPD_ONE_IN(fsqrt)
|
|
FPD_ONE_IN(fre)
|
|
FPD_ONE_IN(frsqrte)
|
|
FPD_ONE_IN(fneg)
|
|
FPD_ONE_IN(fabs)
|
|
FPD_TWO_IN(fadds)
|
|
FPD_TWO_IN(fsubs)
|
|
FPD_TWO_IN(fdivs)
|
|
FPD_TWO_IN(fmuls)
|
|
FPD_TWO_IN_CR(fcmpu)
|
|
FPD_TWO_IN(fcpsgn)
|
|
FPD_TWO_IN(fdiv)
|
|
FPD_TWO_IN(fadd)
|
|
FPD_TWO_IN(fmul)
|
|
FPD_TWO_IN_CR(fcmpo)
|
|
FPD_TWO_IN(fsub)
|
|
FPD_THREE_IN(fmsubs)
|
|
FPD_THREE_IN(fmadds)
|
|
FPD_THREE_IN(fnmsubs)
|
|
FPD_THREE_IN(fnmadds)
|
|
FPD_THREE_IN(fsel)
|
|
FPD_THREE_IN(fmsub)
|
|
FPD_THREE_IN(fmadd)
|
|
FPD_THREE_IN(fnmsub)
|
|
FPD_THREE_IN(fnmadd)
|
|
|
|
_GLOBAL(kvm_cvt_fd)
|
|
lfs 0,0(r3)
|
|
stfd 0,0(r4)
|
|
blr
|
|
|
|
_GLOBAL(kvm_cvt_df)
|
|
lfd 0,0(r3)
|
|
stfs 0,0(r4)
|
|
blr
|