1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * FPU helper code to use FPU operations from inside the kernel
5 * Copyright (C) 2010 Alexander Graf (agraf@suse.de)
8 #include <linux/pgtable.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>
18 /* Instructions operating on single parameters */
21 * Single operation with one input operand
23 * R3 = (double*)&fpscr
24 * R4 = (short*)&result
25 * R5 = (short*)¶m1
27 #define FPS_ONE_IN(name) \
28 _GLOBAL(fps_ ## name); \
29 lfd 0,0(r3); /* load up fpscr value */ \
37 stfd 0,0(r3); /* save new fpscr value */ \
41 * Single operation with two input operands
43 * R3 = (double*)&fpscr
44 * R4 = (short*)&result
45 * R5 = (short*)¶m1
46 * R6 = (short*)¶m2
48 #define FPS_TWO_IN(name) \
49 _GLOBAL(fps_ ## name); \
50 lfd 0,0(r3); /* load up fpscr value */ \
59 stfd 0,0(r3); /* save new fpscr value */ \
63 * Single operation with three input operands
65 * R3 = (double*)&fpscr
66 * R4 = (short*)&result
67 * R5 = (short*)¶m1
68 * R6 = (short*)¶m2
69 * R7 = (short*)¶m3
71 #define FPS_THREE_IN(name) \
72 _GLOBAL(fps_ ## name); \
73 lfd 0,0(r3); /* load up fpscr value */ \
83 stfd 0,0(r3); /* save new fpscr value */ \
100 /* Instructions operating on double parameters */
103 * Beginning of double instruction processing
105 * R3 = (double*)&fpscr
107 * R5 = (double*)&result
108 * R6 = (double*)¶m1
109 * R7 = (double*)¶m2 [load_two]
110 * R8 = (double*)¶m3 [load_three]
111 * LR = instruction call function
114 lfd 2,0(r8) /* load param3 */
116 lfd 1,0(r7) /* load param2 */
118 lfd 0,0(r6) /* load param1 */
120 lfd 3,0(r3) /* load up fpscr value */
122 lwz r6, 0(r4) /* load cr */
127 * End of double instruction processing
129 * R3 = (double*)&fpscr
131 * R5 = (double*)&result
132 * LR = caller of instruction call function
136 stfd 0,0(r5) /* save result */
138 stfd 0,0(r3) /* save new fpscr value */
139 stw r6,0(r4) /* save new cr value */
143 * Double operation with no input operand
145 * R3 = (double*)&fpscr
147 * R5 = (double*)&result
149 #define FPD_NONE_IN(name) \
150 _GLOBAL(fpd_ ## name); \
155 name. 0; /* call instruction */ \
159 * Double operation with one input operand
161 * R3 = (double*)&fpscr
163 * R5 = (double*)&result
164 * R6 = (double*)¶m1
166 #define FPD_ONE_IN(name) \
167 _GLOBAL(fpd_ ## name); \
172 name. 0,0; /* call instruction */ \
176 * Double operation with two input operands
178 * R3 = (double*)&fpscr
180 * R5 = (double*)&result
181 * R6 = (double*)¶m1
182 * R7 = (double*)¶m2
183 * R8 = (double*)¶m3
185 #define FPD_TWO_IN(name) \
186 _GLOBAL(fpd_ ## name); \
191 name. 0,0,1; /* call instruction */ \
195 * CR Double operation with two input operands
197 * R3 = (double*)&fpscr
199 * R5 = (double*)¶m1
200 * R6 = (double*)¶m2
201 * R7 = (double*)¶m3
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 */ \
209 lwz r6, 0(r4); /* load cr */ \
212 name 0,0,1; /* call instruction */ \
215 stfd 0,0(r3); /* save new fpscr value */ \
216 stw r6,0(r4); /* save new cr value */ \
220 * Double operation with three input operands
222 * R3 = (double*)&fpscr
224 * R5 = (double*)&result
225 * R6 = (double*)¶m1
226 * R7 = (double*)¶m2
227 * R8 = (double*)¶m3
229 #define FPD_THREE_IN(name) \
230 _GLOBAL(fpd_ ## name); \
235 name. 0,0,1,2; /* call instruction */ \
262 FPD_THREE_IN(fnmsubs)
263 FPD_THREE_IN(fnmadds)