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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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 262564ee7a5SStephen Rothwell int emulate_altivec(struct pt_regs *regs) 263564ee7a5SStephen Rothwell { 264*94afd069SJordan Niethe struct ppc_inst instr; 265*94afd069SJordan Niethe unsigned int i, word; 266564ee7a5SStephen Rothwell unsigned int va, vb, vc, vd; 267564ee7a5SStephen Rothwell vector128 *vrs; 268564ee7a5SStephen Rothwell 269*94afd069SJordan Niethe if (get_user(instr.val, (unsigned int __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