2 * FPU helper code to use FPU operations from inside the kernel
4 * Copyright (C) 2010 Alexander Graf (agraf@suse.de)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
16 #include <asm/pgtable.h>
17 #include <asm/cputable.h>
18 #include <asm/cache.h>
19 #include <asm/thread_info.h>
20 #include <asm/ppc_asm.h>
21 #include <asm/asm-offsets.h>
23 /* Instructions operating on single parameters */
26 * Single operation with one input operand
28 * R3 = (double*)&fpscr
29 * R4 = (short*)&result
30 * R5 = (short*)¶m1
32 #define FPS_ONE_IN(name) \
33 _GLOBAL(fps_ ## name); \
34 lfd 0,0(r3); /* load up fpscr value */ \
42 stfd 0,0(r3); /* save new fpscr value */ \
46 * Single operation with two input operands
48 * R3 = (double*)&fpscr
49 * R4 = (short*)&result
50 * R5 = (short*)¶m1
51 * R6 = (short*)¶m2
53 #define FPS_TWO_IN(name) \
54 _GLOBAL(fps_ ## name); \
55 lfd 0,0(r3); /* load up fpscr value */ \
64 stfd 0,0(r3); /* save new fpscr value */ \
68 * Single operation with three input operands
70 * R3 = (double*)&fpscr
71 * R4 = (short*)&result
72 * R5 = (short*)¶m1
73 * R6 = (short*)¶m2
74 * R7 = (short*)¶m3
76 #define FPS_THREE_IN(name) \
77 _GLOBAL(fps_ ## name); \
78 lfd 0,0(r3); /* load up fpscr value */ \
88 stfd 0,0(r3); /* save new fpscr value */ \
100 FPS_THREE_IN(fnmadds)
101 FPS_THREE_IN(fnmsubs)
105 /* Instructions operating on double parameters */
108 * Beginning of double instruction processing
110 * R3 = (double*)&fpscr
112 * R5 = (double*)&result
113 * R6 = (double*)¶m1
114 * R7 = (double*)¶m2 [load_two]
115 * R8 = (double*)¶m3 [load_three]
116 * LR = instruction call function
119 lfd 2,0(r8) /* load param3 */
121 lfd 1,0(r7) /* load param2 */
123 lfd 0,0(r6) /* load param1 */
125 lfd 3,0(r3) /* load up fpscr value */
127 lwz r6, 0(r4) /* load cr */
132 * End of double instruction processing
134 * R3 = (double*)&fpscr
136 * R5 = (double*)&result
137 * LR = caller of instruction call function
141 stfd 0,0(r5) /* save result */
143 stfd 0,0(r3) /* save new fpscr value */
144 stw r6,0(r4) /* save new cr value */
148 * Double operation with no input operand
150 * R3 = (double*)&fpscr
152 * R5 = (double*)&result
154 #define FPD_NONE_IN(name) \
155 _GLOBAL(fpd_ ## name); \
160 name. 0; /* call instruction */ \
164 * Double operation with one input operand
166 * R3 = (double*)&fpscr
168 * R5 = (double*)&result
169 * R6 = (double*)¶m1
171 #define FPD_ONE_IN(name) \
172 _GLOBAL(fpd_ ## name); \
177 name. 0,0; /* call instruction */ \
181 * Double operation with two input operands
183 * R3 = (double*)&fpscr
185 * R5 = (double*)&result
186 * R6 = (double*)¶m1
187 * R7 = (double*)¶m2
188 * R8 = (double*)¶m3
190 #define FPD_TWO_IN(name) \
191 _GLOBAL(fpd_ ## name); \
196 name. 0,0,1; /* call instruction */ \
200 * CR Double operation with two input operands
202 * R3 = (double*)&fpscr
204 * R5 = (double*)¶m1
205 * R6 = (double*)¶m2
206 * R7 = (double*)¶m3
208 #define FPD_TWO_IN_CR(name) \
209 _GLOBAL(fpd_ ## name); \
210 lfd 1,0(r6); /* load param2 */ \
211 lfd 0,0(r5); /* load param1 */ \
212 lfd 3,0(r3); /* load up fpscr value */ \
214 lwz r6, 0(r4); /* load cr */ \
217 name 0,0,1; /* call instruction */ \
220 stfd 0,0(r3); /* save new fpscr value */ \
221 stw r6,0(r4); /* save new cr value */ \
225 * Double operation with three input operands
227 * R3 = (double*)&fpscr
229 * R5 = (double*)&result
230 * R6 = (double*)¶m1
231 * R7 = (double*)¶m2
232 * R8 = (double*)¶m3
234 #define FPD_THREE_IN(name) \
235 _GLOBAL(fpd_ ## name); \
240 name. 0,0,1,2; /* call instruction */ \
267 FPD_THREE_IN(fnmsubs)
268 FPD_THREE_IN(fnmadds)