vecemu.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Routines to emulate some Altivec/VMX instructions, specifically
  4. * those that can trap when given denormalized operands in Java mode.
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/errno.h>
  8. #include <linux/sched.h>
  9. #include <asm/ptrace.h>
  10. #include <asm/processor.h>
  11. #include <asm/switch_to.h>
  12. #include <linux/uaccess.h>
  13. #include <asm/inst.h>
  14. /* Functions in vector.S */
  15. extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
  16. extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
  17. extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
  18. extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
  19. extern void vrefp(vector128 *dst, vector128 *src);
  20. extern void vrsqrtefp(vector128 *dst, vector128 *src);
  21. extern void vexptep(vector128 *dst, vector128 *src);
  22. static unsigned int exp2s[8] = {
  23. 0x800000,
  24. 0x8b95c2,
  25. 0x9837f0,
  26. 0xa5fed7,
  27. 0xb504f3,
  28. 0xc5672a,
  29. 0xd744fd,
  30. 0xeac0c7
  31. };
  32. /*
  33. * Computes an estimate of 2^x. The `s' argument is the 32-bit
  34. * single-precision floating-point representation of x.
  35. */
  36. static unsigned int eexp2(unsigned int s)
  37. {
  38. int exp, pwr;
  39. unsigned int mant, frac;
  40. /* extract exponent field from input */
  41. exp = ((s >> 23) & 0xff) - 127;
  42. if (exp > 7) {
  43. /* check for NaN input */
  44. if (exp == 128 && (s & 0x7fffff) != 0)
  45. return s | 0x400000; /* return QNaN */
  46. /* 2^-big = 0, 2^+big = +Inf */
  47. return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */
  48. }
  49. if (exp < -23)
  50. return 0x3f800000; /* 1.0 */
  51. /* convert to fixed point integer in 9.23 representation */
  52. pwr = (s & 0x7fffff) | 0x800000;
  53. if (exp > 0)
  54. pwr <<= exp;
  55. else
  56. pwr >>= -exp;
  57. if (s & 0x80000000)
  58. pwr = -pwr;
  59. /* extract integer part, which becomes exponent part of result */
  60. exp = (pwr >> 23) + 126;
  61. if (exp >= 254)
  62. return 0x7f800000;
  63. if (exp < -23)
  64. return 0;
  65. /* table lookup on top 3 bits of fraction to get mantissa */
  66. mant = exp2s[(pwr >> 20) & 7];
  67. /* linear interpolation using remaining 20 bits of fraction */
  68. asm("mulhwu %0,%1,%2" : "=r" (frac)
  69. : "r" (pwr << 12), "r" (0x172b83ff));
  70. asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
  71. mant += frac;
  72. if (exp >= 0)
  73. return mant + (exp << 23);
  74. /* denormalized result */
  75. exp = -exp;
  76. mant += 1 << (exp - 1);
  77. return mant >> exp;
  78. }
  79. /*
  80. * Computes an estimate of log_2(x). The `s' argument is the 32-bit
  81. * single-precision floating-point representation of x.
  82. */
  83. static unsigned int elog2(unsigned int s)
  84. {
  85. int exp, mant, lz, frac;
  86. exp = s & 0x7f800000;
  87. mant = s & 0x7fffff;
  88. if (exp == 0x7f800000) { /* Inf or NaN */
  89. if (mant != 0)
  90. s |= 0x400000; /* turn NaN into QNaN */
  91. return s;
  92. }
  93. if ((exp | mant) == 0) /* +0 or -0 */
  94. return 0xff800000; /* return -Inf */
  95. if (exp == 0) {
  96. /* denormalized */
  97. asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
  98. mant <<= lz - 8;
  99. exp = (-118 - lz) << 23;
  100. } else {
  101. mant |= 0x800000;
  102. exp -= 127 << 23;
  103. }
  104. if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */
  105. exp |= 0x400000; /* 0.5 * 2^23 */
  106. asm("mulhwu %0,%1,%2" : "=r" (mant)
  107. : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */
  108. }
  109. if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */
  110. exp |= 0x200000; /* 0.25 * 2^23 */
  111. asm("mulhwu %0,%1,%2" : "=r" (mant)
  112. : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */
  113. }
  114. if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */
  115. exp |= 0x100000; /* 0.125 * 2^23 */
  116. asm("mulhwu %0,%1,%2" : "=r" (mant)
  117. : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */
  118. }
  119. if (mant > 0x800000) { /* 1.0 * 2^23 */
  120. /* calculate (mant - 1) * 1.381097463 */
  121. /* 1.381097463 == 0.125 / (2^0.125 - 1) */
  122. asm("mulhwu %0,%1,%2" : "=r" (frac)
  123. : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
  124. exp += frac;
  125. }
  126. s = exp & 0x80000000;
  127. if (exp != 0) {
  128. if (s)
  129. exp = -exp;
  130. asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
  131. lz = 8 - lz;
  132. if (lz > 0)
  133. exp >>= lz;
  134. else if (lz < 0)
  135. exp <<= -lz;
  136. s += ((lz + 126) << 23) + exp;
  137. }
  138. return s;
  139. }
  140. #define VSCR_SAT 1
  141. static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
  142. {
  143. int exp, mant;
  144. exp = (x >> 23) & 0xff;
  145. mant = x & 0x7fffff;
  146. if (exp == 255 && mant != 0)
  147. return 0; /* NaN -> 0 */
  148. exp = exp - 127 + scale;
  149. if (exp < 0)
  150. return 0; /* round towards zero */
  151. if (exp >= 31) {
  152. /* saturate, unless the result would be -2^31 */
  153. if (x + (scale << 23) != 0xcf000000)
  154. *vscrp |= VSCR_SAT;
  155. return (x & 0x80000000)? 0x80000000: 0x7fffffff;
  156. }
  157. mant |= 0x800000;
  158. mant = (mant << 7) >> (30 - exp);
  159. return (x & 0x80000000)? -mant: mant;
  160. }
  161. static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
  162. {
  163. int exp;
  164. unsigned int mant;
  165. exp = (x >> 23) & 0xff;
  166. mant = x & 0x7fffff;
  167. if (exp == 255 && mant != 0)
  168. return 0; /* NaN -> 0 */
  169. exp = exp - 127 + scale;
  170. if (exp < 0)
  171. return 0; /* round towards zero */
  172. if (x & 0x80000000) {
  173. /* negative => saturate to 0 */
  174. *vscrp |= VSCR_SAT;
  175. return 0;
  176. }
  177. if (exp >= 32) {
  178. /* saturate */
  179. *vscrp |= VSCR_SAT;
  180. return 0xffffffff;
  181. }
  182. mant |= 0x800000;
  183. mant = (mant << 8) >> (31 - exp);
  184. return mant;
  185. }
  186. /* Round to floating integer, towards 0 */
  187. static unsigned int rfiz(unsigned int x)
  188. {
  189. int exp;
  190. exp = ((x >> 23) & 0xff) - 127;
  191. if (exp == 128 && (x & 0x7fffff) != 0)
  192. return x | 0x400000; /* NaN -> make it a QNaN */
  193. if (exp >= 23)
  194. return x; /* it's an integer already (or Inf) */
  195. if (exp < 0)
  196. return x & 0x80000000; /* |x| < 1.0 rounds to 0 */
  197. return x & ~(0x7fffff >> exp);
  198. }
  199. /* Round to floating integer, towards +/- Inf */
  200. static unsigned int rfii(unsigned int x)
  201. {
  202. int exp, mask;
  203. exp = ((x >> 23) & 0xff) - 127;
  204. if (exp == 128 && (x & 0x7fffff) != 0)
  205. return x | 0x400000; /* NaN -> make it a QNaN */
  206. if (exp >= 23)
  207. return x; /* it's an integer already (or Inf) */
  208. if ((x & 0x7fffffff) == 0)
  209. return x; /* +/-0 -> +/-0 */
  210. if (exp < 0)
  211. /* 0 < |x| < 1.0 rounds to +/- 1.0 */
  212. return (x & 0x80000000) | 0x3f800000;
  213. mask = 0x7fffff >> exp;
  214. /* mantissa overflows into exponent - that's OK,
  215. it can't overflow into the sign bit */
  216. return (x + mask) & ~mask;
  217. }
  218. /* Round to floating integer, to nearest */
  219. static unsigned int rfin(unsigned int x)
  220. {
  221. int exp, half;
  222. exp = ((x >> 23) & 0xff) - 127;
  223. if (exp == 128 && (x & 0x7fffff) != 0)
  224. return x | 0x400000; /* NaN -> make it a QNaN */
  225. if (exp >= 23)
  226. return x; /* it's an integer already (or Inf) */
  227. if (exp < -1)
  228. return x & 0x80000000; /* |x| < 0.5 -> +/-0 */
  229. if (exp == -1)
  230. /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
  231. return (x & 0x80000000) | 0x3f800000;
  232. half = 0x400000 >> exp;
  233. /* add 0.5 to the magnitude and chop off the fraction bits */
  234. return (x + half) & ~(0x7fffff >> exp);
  235. }
  236. int emulate_altivec(struct pt_regs *regs)
  237. {
  238. struct ppc_inst instr;
  239. unsigned int i, word;
  240. unsigned int va, vb, vc, vd;
  241. vector128 *vrs;
  242. if (get_user_instr(instr, (void __user *)regs->nip))
  243. return -EFAULT;
  244. word = ppc_inst_val(instr);
  245. if (ppc_inst_primary_opcode(instr) != 4)
  246. return -EINVAL; /* not an altivec instruction */
  247. vd = (word >> 21) & 0x1f;
  248. va = (word >> 16) & 0x1f;
  249. vb = (word >> 11) & 0x1f;
  250. vc = (word >> 6) & 0x1f;
  251. vrs = current->thread.vr_state.vr;
  252. switch (word & 0x3f) {
  253. case 10:
  254. switch (vc) {
  255. case 0: /* vaddfp */
  256. vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
  257. break;
  258. case 1: /* vsubfp */
  259. vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
  260. break;
  261. case 4: /* vrefp */
  262. vrefp(&vrs[vd], &vrs[vb]);
  263. break;
  264. case 5: /* vrsqrtefp */
  265. vrsqrtefp(&vrs[vd], &vrs[vb]);
  266. break;
  267. case 6: /* vexptefp */
  268. for (i = 0; i < 4; ++i)
  269. vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
  270. break;
  271. case 7: /* vlogefp */
  272. for (i = 0; i < 4; ++i)
  273. vrs[vd].u[i] = elog2(vrs[vb].u[i]);
  274. break;
  275. case 8: /* vrfin */
  276. for (i = 0; i < 4; ++i)
  277. vrs[vd].u[i] = rfin(vrs[vb].u[i]);
  278. break;
  279. case 9: /* vrfiz */
  280. for (i = 0; i < 4; ++i)
  281. vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
  282. break;
  283. case 10: /* vrfip */
  284. for (i = 0; i < 4; ++i) {
  285. u32 x = vrs[vb].u[i];
  286. x = (x & 0x80000000)? rfiz(x): rfii(x);
  287. vrs[vd].u[i] = x;
  288. }
  289. break;
  290. case 11: /* vrfim */
  291. for (i = 0; i < 4; ++i) {
  292. u32 x = vrs[vb].u[i];
  293. x = (x & 0x80000000)? rfii(x): rfiz(x);
  294. vrs[vd].u[i] = x;
  295. }
  296. break;
  297. case 14: /* vctuxs */
  298. for (i = 0; i < 4; ++i)
  299. vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
  300. &current->thread.vr_state.vscr.u[3]);
  301. break;
  302. case 15: /* vctsxs */
  303. for (i = 0; i < 4; ++i)
  304. vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
  305. &current->thread.vr_state.vscr.u[3]);
  306. break;
  307. default:
  308. return -EINVAL;
  309. }
  310. break;
  311. case 46: /* vmaddfp */
  312. vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
  313. break;
  314. case 47: /* vnmsubfp */
  315. vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
  316. break;
  317. default:
  318. return -EINVAL;
  319. }
  320. return 0;
  321. }