1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2564ee7a5SStephen Rothwell /*
3564ee7a5SStephen Rothwell * Routines to emulate some Altivec/VMX instructions, specifically
4564ee7a5SStephen Rothwell * those that can trap when given denormalized operands in Java mode.
5564ee7a5SStephen Rothwell */
6564ee7a5SStephen Rothwell #include <linux/kernel.h>
7564ee7a5SStephen Rothwell #include <linux/errno.h>
8564ee7a5SStephen Rothwell #include <linux/sched.h>
9564ee7a5SStephen Rothwell #include <asm/ptrace.h>
10564ee7a5SStephen Rothwell #include <asm/processor.h>
11d647b210SMathieu Malaterre #include <asm/switch_to.h>
127c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
138094892dSJordan Niethe #include <asm/inst.h>
14564ee7a5SStephen Rothwell
15564ee7a5SStephen Rothwell /* Functions in vector.S */
16564ee7a5SStephen Rothwell extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
17564ee7a5SStephen Rothwell extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
18564ee7a5SStephen Rothwell extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
19564ee7a5SStephen Rothwell extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
20564ee7a5SStephen Rothwell extern void vrefp(vector128 *dst, vector128 *src);
21564ee7a5SStephen Rothwell extern void vrsqrtefp(vector128 *dst, vector128 *src);
22564ee7a5SStephen Rothwell extern void vexptep(vector128 *dst, vector128 *src);
23564ee7a5SStephen Rothwell
24564ee7a5SStephen Rothwell static unsigned int exp2s[8] = {
25564ee7a5SStephen Rothwell 0x800000,
26564ee7a5SStephen Rothwell 0x8b95c2,
27564ee7a5SStephen Rothwell 0x9837f0,
28564ee7a5SStephen Rothwell 0xa5fed7,
29564ee7a5SStephen Rothwell 0xb504f3,
30564ee7a5SStephen Rothwell 0xc5672a,
31564ee7a5SStephen Rothwell 0xd744fd,
32564ee7a5SStephen Rothwell 0xeac0c7
33564ee7a5SStephen Rothwell };
34564ee7a5SStephen Rothwell
35564ee7a5SStephen Rothwell /*
36564ee7a5SStephen Rothwell * Computes an estimate of 2^x. The `s' argument is the 32-bit
37564ee7a5SStephen Rothwell * single-precision floating-point representation of x.
38564ee7a5SStephen Rothwell */
eexp2(unsigned int s)39564ee7a5SStephen Rothwell static unsigned int eexp2(unsigned int s)
40564ee7a5SStephen Rothwell {
41564ee7a5SStephen Rothwell int exp, pwr;
42564ee7a5SStephen Rothwell unsigned int mant, frac;
43564ee7a5SStephen Rothwell
44564ee7a5SStephen Rothwell /* extract exponent field from input */
45564ee7a5SStephen Rothwell exp = ((s >> 23) & 0xff) - 127;
46564ee7a5SStephen Rothwell if (exp > 7) {
47564ee7a5SStephen Rothwell /* check for NaN input */
48564ee7a5SStephen Rothwell if (exp == 128 && (s & 0x7fffff) != 0)
49564ee7a5SStephen Rothwell return s | 0x400000; /* return QNaN */
50564ee7a5SStephen Rothwell /* 2^-big = 0, 2^+big = +Inf */
51564ee7a5SStephen Rothwell return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */
52564ee7a5SStephen Rothwell }
53564ee7a5SStephen Rothwell if (exp < -23)
54564ee7a5SStephen Rothwell return 0x3f800000; /* 1.0 */
55564ee7a5SStephen Rothwell
56564ee7a5SStephen Rothwell /* convert to fixed point integer in 9.23 representation */
57564ee7a5SStephen Rothwell pwr = (s & 0x7fffff) | 0x800000;
58564ee7a5SStephen Rothwell if (exp > 0)
59564ee7a5SStephen Rothwell pwr <<= exp;
60564ee7a5SStephen Rothwell else
61564ee7a5SStephen Rothwell pwr >>= -exp;
62564ee7a5SStephen Rothwell if (s & 0x80000000)
63564ee7a5SStephen Rothwell pwr = -pwr;
64564ee7a5SStephen Rothwell
65564ee7a5SStephen Rothwell /* extract integer part, which becomes exponent part of result */
66564ee7a5SStephen Rothwell exp = (pwr >> 23) + 126;
67564ee7a5SStephen Rothwell if (exp >= 254)
68564ee7a5SStephen Rothwell return 0x7f800000;
69564ee7a5SStephen Rothwell if (exp < -23)
70564ee7a5SStephen Rothwell return 0;
71564ee7a5SStephen Rothwell
72564ee7a5SStephen Rothwell /* table lookup on top 3 bits of fraction to get mantissa */
73564ee7a5SStephen Rothwell mant = exp2s[(pwr >> 20) & 7];
74564ee7a5SStephen Rothwell
75564ee7a5SStephen Rothwell /* linear interpolation using remaining 20 bits of fraction */
76564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (frac)
77564ee7a5SStephen Rothwell : "r" (pwr << 12), "r" (0x172b83ff));
78564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
79564ee7a5SStephen Rothwell mant += frac;
80564ee7a5SStephen Rothwell
81564ee7a5SStephen Rothwell if (exp >= 0)
82564ee7a5SStephen Rothwell return mant + (exp << 23);
83564ee7a5SStephen Rothwell
84564ee7a5SStephen Rothwell /* denormalized result */
85564ee7a5SStephen Rothwell exp = -exp;
86564ee7a5SStephen Rothwell mant += 1 << (exp - 1);
87564ee7a5SStephen Rothwell return mant >> exp;
88564ee7a5SStephen Rothwell }
89564ee7a5SStephen Rothwell
90564ee7a5SStephen Rothwell /*
91564ee7a5SStephen Rothwell * Computes an estimate of log_2(x). The `s' argument is the 32-bit
92564ee7a5SStephen Rothwell * single-precision floating-point representation of x.
93564ee7a5SStephen Rothwell */
elog2(unsigned int s)94564ee7a5SStephen Rothwell static unsigned int elog2(unsigned int s)
95564ee7a5SStephen Rothwell {
96564ee7a5SStephen Rothwell int exp, mant, lz, frac;
97564ee7a5SStephen Rothwell
98564ee7a5SStephen Rothwell exp = s & 0x7f800000;
99564ee7a5SStephen Rothwell mant = s & 0x7fffff;
100564ee7a5SStephen Rothwell if (exp == 0x7f800000) { /* Inf or NaN */
101564ee7a5SStephen Rothwell if (mant != 0)
102564ee7a5SStephen Rothwell s |= 0x400000; /* turn NaN into QNaN */
103564ee7a5SStephen Rothwell return s;
104564ee7a5SStephen Rothwell }
105564ee7a5SStephen Rothwell if ((exp | mant) == 0) /* +0 or -0 */
106564ee7a5SStephen Rothwell return 0xff800000; /* return -Inf */
107564ee7a5SStephen Rothwell
108564ee7a5SStephen Rothwell if (exp == 0) {
109564ee7a5SStephen Rothwell /* denormalized */
110564ee7a5SStephen Rothwell asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
111564ee7a5SStephen Rothwell mant <<= lz - 8;
112564ee7a5SStephen Rothwell exp = (-118 - lz) << 23;
113564ee7a5SStephen Rothwell } else {
114564ee7a5SStephen Rothwell mant |= 0x800000;
115564ee7a5SStephen Rothwell exp -= 127 << 23;
116564ee7a5SStephen Rothwell }
117564ee7a5SStephen Rothwell
118564ee7a5SStephen Rothwell if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */
119564ee7a5SStephen Rothwell exp |= 0x400000; /* 0.5 * 2^23 */
120564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (mant)
121564ee7a5SStephen Rothwell : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */
122564ee7a5SStephen Rothwell }
123564ee7a5SStephen Rothwell if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */
124564ee7a5SStephen Rothwell exp |= 0x200000; /* 0.25 * 2^23 */
125564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (mant)
126564ee7a5SStephen Rothwell : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */
127564ee7a5SStephen Rothwell }
128564ee7a5SStephen Rothwell if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */
129564ee7a5SStephen Rothwell exp |= 0x100000; /* 0.125 * 2^23 */
130564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (mant)
131564ee7a5SStephen Rothwell : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */
132564ee7a5SStephen Rothwell }
133564ee7a5SStephen Rothwell if (mant > 0x800000) { /* 1.0 * 2^23 */
134564ee7a5SStephen Rothwell /* calculate (mant - 1) * 1.381097463 */
135564ee7a5SStephen Rothwell /* 1.381097463 == 0.125 / (2^0.125 - 1) */
136564ee7a5SStephen Rothwell asm("mulhwu %0,%1,%2" : "=r" (frac)
137564ee7a5SStephen Rothwell : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
138564ee7a5SStephen Rothwell exp += frac;
139564ee7a5SStephen Rothwell }
140564ee7a5SStephen Rothwell s = exp & 0x80000000;
141564ee7a5SStephen Rothwell if (exp != 0) {
142564ee7a5SStephen Rothwell if (s)
143564ee7a5SStephen Rothwell exp = -exp;
144564ee7a5SStephen Rothwell asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
145564ee7a5SStephen Rothwell lz = 8 - lz;
146564ee7a5SStephen Rothwell if (lz > 0)
147564ee7a5SStephen Rothwell exp >>= lz;
148564ee7a5SStephen Rothwell else if (lz < 0)
149564ee7a5SStephen Rothwell exp <<= -lz;
150564ee7a5SStephen Rothwell s += ((lz + 126) << 23) + exp;
151564ee7a5SStephen Rothwell }
152564ee7a5SStephen Rothwell return s;
153564ee7a5SStephen Rothwell }
154564ee7a5SStephen Rothwell
155564ee7a5SStephen Rothwell #define VSCR_SAT 1
156564ee7a5SStephen Rothwell
ctsxs(unsigned int x,int scale,unsigned int * vscrp)157564ee7a5SStephen Rothwell static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
158564ee7a5SStephen Rothwell {
159564ee7a5SStephen Rothwell int exp, mant;
160564ee7a5SStephen Rothwell
161564ee7a5SStephen Rothwell exp = (x >> 23) & 0xff;
162564ee7a5SStephen Rothwell mant = x & 0x7fffff;
163564ee7a5SStephen Rothwell if (exp == 255 && mant != 0)
164564ee7a5SStephen Rothwell return 0; /* NaN -> 0 */
165564ee7a5SStephen Rothwell exp = exp - 127 + scale;
166564ee7a5SStephen Rothwell if (exp < 0)
167564ee7a5SStephen Rothwell return 0; /* round towards zero */
168564ee7a5SStephen Rothwell if (exp >= 31) {
169564ee7a5SStephen Rothwell /* saturate, unless the result would be -2^31 */
170564ee7a5SStephen Rothwell if (x + (scale << 23) != 0xcf000000)
171564ee7a5SStephen Rothwell *vscrp |= VSCR_SAT;
172564ee7a5SStephen Rothwell return (x & 0x80000000)? 0x80000000: 0x7fffffff;
173564ee7a5SStephen Rothwell }
174564ee7a5SStephen Rothwell mant |= 0x800000;
175564ee7a5SStephen Rothwell mant = (mant << 7) >> (30 - exp);
176564ee7a5SStephen Rothwell return (x & 0x80000000)? -mant: mant;
177564ee7a5SStephen Rothwell }
178564ee7a5SStephen Rothwell
ctuxs(unsigned int x,int scale,unsigned int * vscrp)179564ee7a5SStephen Rothwell static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
180564ee7a5SStephen Rothwell {
181564ee7a5SStephen Rothwell int exp;
182564ee7a5SStephen Rothwell unsigned int mant;
183564ee7a5SStephen Rothwell
184564ee7a5SStephen Rothwell exp = (x >> 23) & 0xff;
185564ee7a5SStephen Rothwell mant = x & 0x7fffff;
186564ee7a5SStephen Rothwell if (exp == 255 && mant != 0)
187564ee7a5SStephen Rothwell return 0; /* NaN -> 0 */
188564ee7a5SStephen Rothwell exp = exp - 127 + scale;
189564ee7a5SStephen Rothwell if (exp < 0)
190564ee7a5SStephen Rothwell return 0; /* round towards zero */
191564ee7a5SStephen Rothwell if (x & 0x80000000) {
192564ee7a5SStephen Rothwell /* negative => saturate to 0 */
193564ee7a5SStephen Rothwell *vscrp |= VSCR_SAT;
194564ee7a5SStephen Rothwell return 0;
195564ee7a5SStephen Rothwell }
196564ee7a5SStephen Rothwell if (exp >= 32) {
197564ee7a5SStephen Rothwell /* saturate */
198564ee7a5SStephen Rothwell *vscrp |= VSCR_SAT;
199564ee7a5SStephen Rothwell return 0xffffffff;
200564ee7a5SStephen Rothwell }
201564ee7a5SStephen Rothwell mant |= 0x800000;
202564ee7a5SStephen Rothwell mant = (mant << 8) >> (31 - exp);
203564ee7a5SStephen Rothwell return mant;
204564ee7a5SStephen Rothwell }
205564ee7a5SStephen Rothwell
206564ee7a5SStephen Rothwell /* Round to floating integer, towards 0 */
rfiz(unsigned int x)207564ee7a5SStephen Rothwell static unsigned int rfiz(unsigned int x)
208564ee7a5SStephen Rothwell {
209564ee7a5SStephen Rothwell int exp;
210564ee7a5SStephen Rothwell
211564ee7a5SStephen Rothwell exp = ((x >> 23) & 0xff) - 127;
212564ee7a5SStephen Rothwell if (exp == 128 && (x & 0x7fffff) != 0)
213564ee7a5SStephen Rothwell return x | 0x400000; /* NaN -> make it a QNaN */
214564ee7a5SStephen Rothwell if (exp >= 23)
215564ee7a5SStephen Rothwell return x; /* it's an integer already (or Inf) */
216564ee7a5SStephen Rothwell if (exp < 0)
217564ee7a5SStephen Rothwell return x & 0x80000000; /* |x| < 1.0 rounds to 0 */
218564ee7a5SStephen Rothwell return x & ~(0x7fffff >> exp);
219564ee7a5SStephen Rothwell }
220564ee7a5SStephen Rothwell
221564ee7a5SStephen Rothwell /* Round to floating integer, towards +/- Inf */
rfii(unsigned int x)222564ee7a5SStephen Rothwell static unsigned int rfii(unsigned int x)
223564ee7a5SStephen Rothwell {
224564ee7a5SStephen Rothwell int exp, mask;
225564ee7a5SStephen Rothwell
226564ee7a5SStephen Rothwell exp = ((x >> 23) & 0xff) - 127;
227564ee7a5SStephen Rothwell if (exp == 128 && (x & 0x7fffff) != 0)
228564ee7a5SStephen Rothwell return x | 0x400000; /* NaN -> make it a QNaN */
229564ee7a5SStephen Rothwell if (exp >= 23)
230564ee7a5SStephen Rothwell return x; /* it's an integer already (or Inf) */
231564ee7a5SStephen Rothwell if ((x & 0x7fffffff) == 0)
232564ee7a5SStephen Rothwell return x; /* +/-0 -> +/-0 */
233564ee7a5SStephen Rothwell if (exp < 0)
234564ee7a5SStephen Rothwell /* 0 < |x| < 1.0 rounds to +/- 1.0 */
235564ee7a5SStephen Rothwell return (x & 0x80000000) | 0x3f800000;
236564ee7a5SStephen Rothwell mask = 0x7fffff >> exp;
237564ee7a5SStephen Rothwell /* mantissa overflows into exponent - that's OK,
238564ee7a5SStephen Rothwell it can't overflow into the sign bit */
239564ee7a5SStephen Rothwell return (x + mask) & ~mask;
240564ee7a5SStephen Rothwell }
241564ee7a5SStephen Rothwell
242564ee7a5SStephen Rothwell /* Round to floating integer, to nearest */
rfin(unsigned int x)243564ee7a5SStephen Rothwell static unsigned int rfin(unsigned int x)
244564ee7a5SStephen Rothwell {
245564ee7a5SStephen Rothwell int exp, half;
246564ee7a5SStephen Rothwell
247564ee7a5SStephen Rothwell exp = ((x >> 23) & 0xff) - 127;
248564ee7a5SStephen Rothwell if (exp == 128 && (x & 0x7fffff) != 0)
249564ee7a5SStephen Rothwell return x | 0x400000; /* NaN -> make it a QNaN */
250564ee7a5SStephen Rothwell if (exp >= 23)
251564ee7a5SStephen Rothwell return x; /* it's an integer already (or Inf) */
252564ee7a5SStephen Rothwell if (exp < -1)
253564ee7a5SStephen Rothwell return x & 0x80000000; /* |x| < 0.5 -> +/-0 */
254564ee7a5SStephen Rothwell if (exp == -1)
255564ee7a5SStephen Rothwell /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
256564ee7a5SStephen Rothwell return (x & 0x80000000) | 0x3f800000;
257564ee7a5SStephen Rothwell half = 0x400000 >> exp;
258564ee7a5SStephen Rothwell /* add 0.5 to the magnitude and chop off the fraction bits */
259564ee7a5SStephen Rothwell return (x + half) & ~(0x7fffff >> exp);
260564ee7a5SStephen Rothwell }
261564ee7a5SStephen Rothwell
emulate_altivec(struct pt_regs * regs)262564ee7a5SStephen Rothwell int emulate_altivec(struct pt_regs *regs)
263564ee7a5SStephen Rothwell {
264*c545b9f0SChristophe Leroy ppc_inst_t instr;
26594afd069SJordan Niethe unsigned int i, word;
266564ee7a5SStephen Rothwell unsigned int va, vb, vc, vd;
267564ee7a5SStephen Rothwell vector128 *vrs;
268564ee7a5SStephen Rothwell
2695249385aSJordan Niethe if (get_user_instr(instr, (void __user *)regs->nip))
270564ee7a5SStephen Rothwell return -EFAULT;
271777e26f0SJordan Niethe
272777e26f0SJordan Niethe word = ppc_inst_val(instr);
2738094892dSJordan Niethe if (ppc_inst_primary_opcode(instr) != 4)
274564ee7a5SStephen Rothwell return -EINVAL; /* not an altivec instruction */
275777e26f0SJordan Niethe vd = (word >> 21) & 0x1f;
276777e26f0SJordan Niethe va = (word >> 16) & 0x1f;
277777e26f0SJordan Niethe vb = (word >> 11) & 0x1f;
278777e26f0SJordan Niethe vc = (word >> 6) & 0x1f;
279564ee7a5SStephen Rothwell
280de79f7b9SPaul Mackerras vrs = current->thread.vr_state.vr;
281777e26f0SJordan Niethe switch (word & 0x3f) {
282564ee7a5SStephen Rothwell case 10:
283564ee7a5SStephen Rothwell switch (vc) {
284564ee7a5SStephen Rothwell case 0: /* vaddfp */
285564ee7a5SStephen Rothwell vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
286564ee7a5SStephen Rothwell break;
287564ee7a5SStephen Rothwell case 1: /* vsubfp */
288564ee7a5SStephen Rothwell vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
289564ee7a5SStephen Rothwell break;
290564ee7a5SStephen Rothwell case 4: /* vrefp */
291564ee7a5SStephen Rothwell vrefp(&vrs[vd], &vrs[vb]);
292564ee7a5SStephen Rothwell break;
293564ee7a5SStephen Rothwell case 5: /* vrsqrtefp */
294564ee7a5SStephen Rothwell vrsqrtefp(&vrs[vd], &vrs[vb]);
295564ee7a5SStephen Rothwell break;
296564ee7a5SStephen Rothwell case 6: /* vexptefp */
297564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
298564ee7a5SStephen Rothwell vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
299564ee7a5SStephen Rothwell break;
300564ee7a5SStephen Rothwell case 7: /* vlogefp */
301564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
302564ee7a5SStephen Rothwell vrs[vd].u[i] = elog2(vrs[vb].u[i]);
303564ee7a5SStephen Rothwell break;
304564ee7a5SStephen Rothwell case 8: /* vrfin */
305564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
306564ee7a5SStephen Rothwell vrs[vd].u[i] = rfin(vrs[vb].u[i]);
307564ee7a5SStephen Rothwell break;
308564ee7a5SStephen Rothwell case 9: /* vrfiz */
309564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
310564ee7a5SStephen Rothwell vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
311564ee7a5SStephen Rothwell break;
312564ee7a5SStephen Rothwell case 10: /* vrfip */
313564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i) {
314564ee7a5SStephen Rothwell u32 x = vrs[vb].u[i];
315564ee7a5SStephen Rothwell x = (x & 0x80000000)? rfiz(x): rfii(x);
316564ee7a5SStephen Rothwell vrs[vd].u[i] = x;
317564ee7a5SStephen Rothwell }
318564ee7a5SStephen Rothwell break;
319564ee7a5SStephen Rothwell case 11: /* vrfim */
320564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i) {
321564ee7a5SStephen Rothwell u32 x = vrs[vb].u[i];
322564ee7a5SStephen Rothwell x = (x & 0x80000000)? rfii(x): rfiz(x);
323564ee7a5SStephen Rothwell vrs[vd].u[i] = x;
324564ee7a5SStephen Rothwell }
325564ee7a5SStephen Rothwell break;
326564ee7a5SStephen Rothwell case 14: /* vctuxs */
327564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
328564ee7a5SStephen Rothwell vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
329de79f7b9SPaul Mackerras ¤t->thread.vr_state.vscr.u[3]);
330564ee7a5SStephen Rothwell break;
331564ee7a5SStephen Rothwell case 15: /* vctsxs */
332564ee7a5SStephen Rothwell for (i = 0; i < 4; ++i)
333564ee7a5SStephen Rothwell vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
334de79f7b9SPaul Mackerras ¤t->thread.vr_state.vscr.u[3]);
335564ee7a5SStephen Rothwell break;
336564ee7a5SStephen Rothwell default:
337564ee7a5SStephen Rothwell return -EINVAL;
338564ee7a5SStephen Rothwell }
339564ee7a5SStephen Rothwell break;
340564ee7a5SStephen Rothwell case 46: /* vmaddfp */
341564ee7a5SStephen Rothwell vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
342564ee7a5SStephen Rothwell break;
343564ee7a5SStephen Rothwell case 47: /* vnmsubfp */
344564ee7a5SStephen Rothwell vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
345564ee7a5SStephen Rothwell break;
346564ee7a5SStephen Rothwell default:
347564ee7a5SStephen Rothwell return -EINVAL;
348564ee7a5SStephen Rothwell }
349564ee7a5SStephen Rothwell
350564ee7a5SStephen Rothwell return 0;
351564ee7a5SStephen Rothwell }
352