cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fpu.S (5664B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 *  FPU helper code to use FPU operations from inside the kernel
      4 *
      5 *    Copyright (C) 2010 Alexander Graf (agraf@suse.de)
      6 */
      7
      8#include <linux/pgtable.h>
      9#include <asm/reg.h>
     10#include <asm/page.h>
     11#include <asm/mmu.h>
     12#include <asm/cputable.h>
     13#include <asm/cache.h>
     14#include <asm/thread_info.h>
     15#include <asm/ppc_asm.h>
     16#include <asm/asm-offsets.h>
     17
     18/* Instructions operating on single parameters */
     19
     20/*
     21 * Single operation with one input operand
     22 *
     23 * R3 = (double*)&fpscr
     24 * R4 = (short*)&result
     25 * R5 = (short*)&param1
     26 */
     27#define FPS_ONE_IN(name) 					\
     28_GLOBAL(fps_ ## name);							\
     29	lfd	0,0(r3);		/* load up fpscr value */	\
     30	MTFSF_L(0);							\
     31	lfs	0,0(r5);						\
     32									\
     33	name	0,0;							\
     34									\
     35	stfs	0,0(r4);						\
     36	mffs	0;							\
     37	stfd	0,0(r3);	/* save new fpscr value */	\
     38	blr
     39
     40/*
     41 * Single operation with two input operands
     42 *
     43 * R3 = (double*)&fpscr
     44 * R4 = (short*)&result
     45 * R5 = (short*)&param1
     46 * R6 = (short*)&param2
     47 */
     48#define FPS_TWO_IN(name) 					\
     49_GLOBAL(fps_ ## name);							\
     50	lfd	0,0(r3);		/* load up fpscr value */	\
     51	MTFSF_L(0);							\
     52	lfs	0,0(r5);						\
     53	lfs	1,0(r6);						\
     54									\
     55	name	0,0,1;							\
     56									\
     57	stfs	0,0(r4);						\
     58	mffs	0;							\
     59	stfd	0,0(r3);		/* save new fpscr value */	\
     60	blr
     61
     62/*
     63 * Single operation with three input operands
     64 *
     65 * R3 = (double*)&fpscr
     66 * R4 = (short*)&result
     67 * R5 = (short*)&param1
     68 * R6 = (short*)&param2
     69 * R7 = (short*)&param3
     70 */
     71#define FPS_THREE_IN(name) 					\
     72_GLOBAL(fps_ ## name);							\
     73	lfd	0,0(r3);		/* load up fpscr value */	\
     74	MTFSF_L(0);							\
     75	lfs	0,0(r5);						\
     76	lfs	1,0(r6);						\
     77	lfs	2,0(r7);						\
     78									\
     79	name	0,0,1,2;						\
     80									\
     81	stfs	0,0(r4);						\
     82	mffs	0;							\
     83	stfd	0,0(r3);		/* save new fpscr value */	\
     84	blr
     85
     86FPS_ONE_IN(fres)
     87FPS_ONE_IN(frsqrte)
     88FPS_ONE_IN(fsqrts)
     89FPS_TWO_IN(fadds)
     90FPS_TWO_IN(fdivs)
     91FPS_TWO_IN(fmuls)
     92FPS_TWO_IN(fsubs)
     93FPS_THREE_IN(fmadds)
     94FPS_THREE_IN(fmsubs)
     95FPS_THREE_IN(fnmadds)
     96FPS_THREE_IN(fnmsubs)
     97FPS_THREE_IN(fsel)
     98
     99
    100/* Instructions operating on double parameters */
    101
    102/*
    103 * Beginning of double instruction processing
    104 *
    105 * R3 = (double*)&fpscr
    106 * R4 = (u32*)&cr
    107 * R5 = (double*)&result
    108 * R6 = (double*)&param1
    109 * R7 = (double*)&param2 [load_two]
    110 * R8 = (double*)&param3 [load_three]
    111 * LR = instruction call function
    112 */
    113fpd_load_three:
    114	lfd	2,0(r8)			/* load param3 */
    115fpd_load_two:
    116	lfd	1,0(r7)			/* load param2 */
    117fpd_load_one:
    118	lfd	0,0(r6)			/* load param1 */
    119fpd_load_none:
    120	lfd	3,0(r3)			/* load up fpscr value */
    121	MTFSF_L(3)
    122	lwz	r6, 0(r4)		/* load cr */
    123	mtcr	r6
    124	blr
    125
    126/*
    127 * End of double instruction processing
    128 *
    129 * R3 = (double*)&fpscr
    130 * R4 = (u32*)&cr
    131 * R5 = (double*)&result
    132 * LR = caller of instruction call function
    133 */
    134fpd_return:
    135	mfcr	r6
    136	stfd	0,0(r5)			/* save result */
    137	mffs	0
    138	stfd	0,0(r3)			/* save new fpscr value */
    139	stw	r6,0(r4)		/* save new cr value */
    140	blr
    141
    142/*
    143 * Double operation with no input operand
    144 *
    145 * R3 = (double*)&fpscr
    146 * R4 = (u32*)&cr
    147 * R5 = (double*)&result
    148 */
    149#define FPD_NONE_IN(name) 						\
    150_GLOBAL(fpd_ ## name);							\
    151	mflr	r12;							\
    152	bl	fpd_load_none;						\
    153	mtlr	r12;							\
    154									\
    155	name.	0;			/* call instruction */		\
    156	b	fpd_return
    157
    158/*
    159 * Double operation with one input operand
    160 *
    161 * R3 = (double*)&fpscr
    162 * R4 = (u32*)&cr
    163 * R5 = (double*)&result
    164 * R6 = (double*)&param1
    165 */
    166#define FPD_ONE_IN(name) 						\
    167_GLOBAL(fpd_ ## name);							\
    168	mflr	r12;							\
    169	bl	fpd_load_one;						\
    170	mtlr	r12;							\
    171									\
    172	name.	0,0;			/* call instruction */		\
    173	b	fpd_return
    174
    175/*
    176 * Double operation with two input operands
    177 *
    178 * R3 = (double*)&fpscr
    179 * R4 = (u32*)&cr
    180 * R5 = (double*)&result
    181 * R6 = (double*)&param1
    182 * R7 = (double*)&param2
    183 * R8 = (double*)&param3
    184 */
    185#define FPD_TWO_IN(name) 						\
    186_GLOBAL(fpd_ ## name);							\
    187	mflr	r12;							\
    188	bl	fpd_load_two;						\
    189	mtlr	r12;							\
    190									\
    191	name.	0,0,1;			/* call instruction */		\
    192	b	fpd_return
    193
    194/*
    195 * CR Double operation with two input operands
    196 *
    197 * R3 = (double*)&fpscr
    198 * R4 = (u32*)&cr
    199 * R5 = (double*)&param1
    200 * R6 = (double*)&param2
    201 * R7 = (double*)&param3
    202 */
    203#define FPD_TWO_IN_CR(name)						\
    204_GLOBAL(fpd_ ## name);							\
    205	lfd	1,0(r6);		/* load param2 */		\
    206	lfd	0,0(r5);		/* load param1 */		\
    207	lfd	3,0(r3);		/* load up fpscr value */	\
    208	MTFSF_L(3);							\
    209	lwz	r6, 0(r4);		/* load cr */			\
    210	mtcr	r6;							\
    211									\
    212	name	0,0,1;			/* call instruction */		\
    213	mfcr	r6;							\
    214	mffs	0;							\
    215	stfd	0,0(r3);		/* save new fpscr value */	\
    216	stw	r6,0(r4);		/* save new cr value */		\
    217	blr
    218
    219/*
    220 * Double operation with three input operands
    221 *
    222 * R3 = (double*)&fpscr
    223 * R4 = (u32*)&cr
    224 * R5 = (double*)&result
    225 * R6 = (double*)&param1
    226 * R7 = (double*)&param2
    227 * R8 = (double*)&param3
    228 */
    229#define FPD_THREE_IN(name) 						\
    230_GLOBAL(fpd_ ## name);							\
    231	mflr	r12;							\
    232	bl	fpd_load_three;						\
    233	mtlr	r12;							\
    234									\
    235	name.	0,0,1,2;		/* call instruction */		\
    236	b	fpd_return
    237
    238FPD_ONE_IN(fsqrts)
    239FPD_ONE_IN(frsqrtes)
    240FPD_ONE_IN(fres)
    241FPD_ONE_IN(frsp)
    242FPD_ONE_IN(fctiw)
    243FPD_ONE_IN(fctiwz)
    244FPD_ONE_IN(fsqrt)
    245FPD_ONE_IN(fre)
    246FPD_ONE_IN(frsqrte)
    247FPD_ONE_IN(fneg)
    248FPD_ONE_IN(fabs)
    249FPD_TWO_IN(fadds)
    250FPD_TWO_IN(fsubs)
    251FPD_TWO_IN(fdivs)
    252FPD_TWO_IN(fmuls)
    253FPD_TWO_IN_CR(fcmpu)
    254FPD_TWO_IN(fcpsgn)
    255FPD_TWO_IN(fdiv)
    256FPD_TWO_IN(fadd)
    257FPD_TWO_IN(fmul)
    258FPD_TWO_IN_CR(fcmpo)
    259FPD_TWO_IN(fsub)
    260FPD_THREE_IN(fmsubs)
    261FPD_THREE_IN(fmadds)
    262FPD_THREE_IN(fnmsubs)
    263FPD_THREE_IN(fnmadds)
    264FPD_THREE_IN(fsel)
    265FPD_THREE_IN(fmsub)
    266FPD_THREE_IN(fmadd)
    267FPD_THREE_IN(fnmsub)
    268FPD_THREE_IN(fnmadd)
    269
    270_GLOBAL(kvm_cvt_fd)
    271	lfs	0,0(r3)
    272	stfd	0,0(r4)
    273	blr
    274
    275_GLOBAL(kvm_cvt_df)
    276	lfd	0,0(r3)
    277	stfs	0,0(r4)
    278	blr