fastmath_dlib_asm.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. //===----------------------Hexagon builtin routine ------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /* ==================================================================== */
  9. /* FUNCTIONS Optimized double floating point operators */
  10. /* ==================================================================== */
  11. /* c = dadd_asm(a, b) */
  12. /* ====================================================================
  13. QDOUBLE dadd(QDOUBLE a,QDOUBLE b) {
  14. QDOUBLE c;
  15. lint manta = a & MANTMASK;
  16. int expa = HEXAGON_R_sxth_R(a) ;
  17. lint mantb = b & MANTMASK;
  18. int expb = HEXAGON_R_sxth_R(b) ;
  19. int exp, expdiff, j, k, hi, lo, cn;
  20. lint mant;
  21. expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b);
  22. expdiff = HEXAGON_R_sxth_R(expdiff) ;
  23. if (expdiff > 63) { expdiff = 62;}
  24. if (expa > expb) {
  25. exp = expa + 1;
  26. expa = 1;
  27. expb = expdiff + 1;
  28. } else {
  29. exp = expb + 1;
  30. expb = 1;
  31. expa = expdiff + 1;
  32. }
  33. mant = (manta>>expa) + (mantb>>expb);
  34. hi = (int) (mant>>32);
  35. lo = (int) (mant);
  36. k = HEXAGON_R_normamt_R(hi);
  37. if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
  38. mant = (mant << k);
  39. cn = (mant == 0x8000000000000000LL);
  40. exp = exp - k + cn;
  41. if (mant == 0 || mant == -1) exp = 0x8001;
  42. c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
  43. return(c);
  44. }
  45. * ==================================================================== */
  46. .text
  47. .global dadd_asm
  48. .type dadd_asm, @function
  49. dadd_asm:
  50. #define manta R0
  51. #define mantexpa R1:0
  52. #define lmanta R1:0
  53. #define mantb R2
  54. #define mantexpb R3:2
  55. #define lmantb R3:2
  56. #define expa R4
  57. #define expb R5
  58. #define mantexpd R7:6
  59. #define expd R6
  60. #define exp R8
  61. #define c63 R9
  62. #define lmant R1:0
  63. #define manth R1
  64. #define mantl R0
  65. #define zero R7:6
  66. #define zerol R6
  67. #define minus R3:2
  68. #define minusl R2
  69. #define maxneg R9
  70. #define minmin R11:10 // exactly 0x800000000000000000LL
  71. #define minminh R11
  72. #define k R4
  73. #define kl R5
  74. #define ce P0
  75. .falign
  76. {
  77. mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
  78. c63 = #62
  79. expa = SXTH(manta)
  80. expb = SXTH(mantb)
  81. } {
  82. expd = SXTH(expd)
  83. ce = CMP.GT(expa, expb);
  84. if ( ce.new) exp = add(expa, #1)
  85. if (!ce.new) exp = add(expb, #1)
  86. } {
  87. if ( ce) expa = #1
  88. if (!ce) expb = #1
  89. manta.L = #0
  90. expd = MIN(expd, c63)
  91. } {
  92. if (!ce) expa = add(expd, #1)
  93. if ( ce) expb = add(expd, #1)
  94. mantb.L = #0
  95. zero = #0
  96. } {
  97. lmanta = ASR(lmanta, expa)
  98. lmantb = ASR(lmantb, expb)
  99. minmin = #0
  100. } {
  101. lmant = add(lmanta, lmantb)
  102. minus = #-1
  103. minminh.H = #0x8000
  104. } {
  105. k = NORMAMT(manth)
  106. kl = NORMAMT(mantl)
  107. p0 = cmp.eq(manth, zerol)
  108. p1 = cmp.eq(manth, minusl)
  109. } {
  110. p0 = OR(p0, p1)
  111. if(p0.new) k = add(kl, #31)
  112. maxneg.H = #0
  113. } {
  114. mantexpa = ASL(lmant, k)
  115. exp = SUB(exp, k)
  116. maxneg.L = #0x8001
  117. } {
  118. p0 = cmp.eq(mantexpa, zero)
  119. p1 = cmp.eq(mantexpa, minus)
  120. manta.L = #0
  121. exp = ZXTH(exp)
  122. } {
  123. p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0
  124. if(p2.new) exp = add(exp, #1)
  125. }
  126. #if (__HEXAGON_ARCH__ == 60)
  127. {
  128. p0 = OR(p0, p1)
  129. if( p0.new) manta = OR(manta,maxneg)
  130. if(!p0.new) manta = OR(manta,exp)
  131. }
  132. jumpr r31
  133. #else
  134. {
  135. p0 = OR(p0, p1)
  136. if( p0.new) manta = OR(manta,maxneg)
  137. if(!p0.new) manta = OR(manta,exp)
  138. jumpr r31
  139. }
  140. #endif
  141. /* =================================================================== *
  142. QDOUBLE dsub(QDOUBLE a,QDOUBLE b) {
  143. QDOUBLE c;
  144. lint manta = a & MANTMASK;
  145. int expa = HEXAGON_R_sxth_R(a) ;
  146. lint mantb = b & MANTMASK;
  147. int expb = HEXAGON_R_sxth_R(b) ;
  148. int exp, expdiff, j, k, hi, lo, cn;
  149. lint mant;
  150. expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b);
  151. expdiff = HEXAGON_R_sxth_R(expdiff) ;
  152. if (expdiff > 63) { expdiff = 62;}
  153. if (expa > expb) {
  154. exp = expa + 1;
  155. expa = 1;
  156. expb = expdiff + 1;
  157. } else {
  158. exp = expb + 1;
  159. expb = 1;
  160. expa = expdiff + 1;
  161. }
  162. mant = (manta>>expa) - (mantb>>expb);
  163. hi = (int) (mant>>32);
  164. lo = (int) (mant);
  165. k = HEXAGON_R_normamt_R(hi);
  166. if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
  167. mant = (mant << k);
  168. cn = (mant == 0x8000000000000000LL);
  169. exp = exp - k + cn;
  170. if (mant == 0 || mant == -1) exp = 0x8001;
  171. c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
  172. return(c);
  173. }
  174. * ==================================================================== */
  175. .text
  176. .global dsub_asm
  177. .type dsub_asm, @function
  178. dsub_asm:
  179. #define manta R0
  180. #define mantexpa R1:0
  181. #define lmanta R1:0
  182. #define mantb R2
  183. #define mantexpb R3:2
  184. #define lmantb R3:2
  185. #define expa R4
  186. #define expb R5
  187. #define mantexpd R7:6
  188. #define expd R6
  189. #define exp R8
  190. #define c63 R9
  191. #define lmant R1:0
  192. #define manth R1
  193. #define mantl R0
  194. #define zero R7:6
  195. #define zerol R6
  196. #define minus R3:2
  197. #define minusl R2
  198. #define maxneg R9
  199. #define minmin R11:10 // exactly 0x800000000000000000LL
  200. #define minminh R11
  201. #define k R4
  202. #define kl R5
  203. #define ce P0
  204. .falign
  205. {
  206. mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
  207. c63 = #62
  208. expa = SXTH(manta)
  209. expb = SXTH(mantb)
  210. } {
  211. expd = SXTH(expd)
  212. ce = CMP.GT(expa, expb);
  213. if ( ce.new) exp = add(expa, #1)
  214. if (!ce.new) exp = add(expb, #1)
  215. } {
  216. if ( ce) expa = #1
  217. if (!ce) expb = #1
  218. manta.L = #0
  219. expd = MIN(expd, c63)
  220. } {
  221. if (!ce) expa = add(expd, #1)
  222. if ( ce) expb = add(expd, #1)
  223. mantb.L = #0
  224. zero = #0
  225. } {
  226. lmanta = ASR(lmanta, expa)
  227. lmantb = ASR(lmantb, expb)
  228. minmin = #0
  229. } {
  230. lmant = sub(lmanta, lmantb)
  231. minus = #-1
  232. minminh.H = #0x8000
  233. } {
  234. k = NORMAMT(manth)
  235. kl = NORMAMT(mantl)
  236. p0 = cmp.eq(manth, zerol)
  237. p1 = cmp.eq(manth, minusl)
  238. } {
  239. p0 = OR(p0, p1)
  240. if(p0.new) k = add(kl, #31)
  241. maxneg.H = #0
  242. } {
  243. mantexpa = ASL(lmant, k)
  244. exp = SUB(exp, k)
  245. maxneg.L = #0x8001
  246. } {
  247. p0 = cmp.eq(mantexpa, zero)
  248. p1 = cmp.eq(mantexpa, minus)
  249. manta.L = #0
  250. exp = ZXTH(exp)
  251. } {
  252. p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0
  253. if(p2.new) exp = add(exp, #1)
  254. }
  255. #if (__HEXAGON_ARCH__ == 60)
  256. {
  257. p0 = OR(p0, p1)
  258. if( p0.new) manta = OR(manta,maxneg)
  259. if(!p0.new) manta = OR(manta,exp)
  260. }
  261. jumpr r31
  262. #else
  263. {
  264. p0 = OR(p0, p1)
  265. if( p0.new) manta = OR(manta,maxneg)
  266. if(!p0.new) manta = OR(manta,exp)
  267. jumpr r31
  268. }
  269. #endif
  270. /* ==================================================================== *
  271. QDOUBLE dmpy(QDOUBLE a,QDOUBLE b) {
  272. QDOUBLE c;
  273. lint manta = a & MANTMASK;
  274. int expa = HEXAGON_R_sxth_R(a) ;
  275. lint mantb = b & MANTMASK;
  276. int expb = HEXAGON_R_sxth_R(b) ;
  277. int exp, k;
  278. lint mant;
  279. int hia, hib, hi, lo;
  280. unsigned int loa, lob;
  281. hia = (int)(a >> 32);
  282. loa = HEXAGON_R_extractu_RII((int)manta, 31, 1);
  283. hib = (int)(b >> 32);
  284. lob = HEXAGON_R_extractu_RII((int)mantb, 31, 1);
  285. mant = HEXAGON_P_mpy_RR(hia, lob);
  286. mant = HEXAGON_P_mpyacc_RR(mant,hib, loa);
  287. mant = (mant >> 30) + (HEXAGON_P_mpy_RR(hia, hib)<<1);
  288. hi = (int) (mant>>32);
  289. lo = (int) (mant);
  290. k = HEXAGON_R_normamt_R(hi);
  291. if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
  292. mant = mant << k;
  293. exp = expa + expb - k;
  294. if (mant == 0 || mant == -1) exp = 0x8001;
  295. c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
  296. return(c);
  297. }
  298. * ==================================================================== */
  299. .text
  300. .global dmpy_asm
  301. .type dmpy_asm, @function
  302. dmpy_asm:
  303. #define mantal R0
  304. #define mantah R1
  305. #define mantexpa R1:0
  306. #define mantbl R2
  307. #define mantbh R3
  308. #define mantexpb R3:2
  309. #define expa R4
  310. #define expb R5
  311. #define mantexpd R7:6
  312. #define exp R8
  313. #define lmantc R11:10
  314. #define mantch R11
  315. #define mantcl R10
  316. #define zero0 R7:6
  317. #define zero0l R6
  318. #define minus1 R3:2
  319. #define minus1l R2
  320. #define maxneg R9
  321. #define k R4
  322. #define kl R5
  323. .falign
  324. {
  325. mantbl = lsr(mantbl, #16)
  326. mantal = lsr(mantal, #16)
  327. expa = sxth(mantal)
  328. expb = sxth(mantbl)
  329. }
  330. {
  331. lmantc = mpy(mantah, mantbh)
  332. mantexpd = mpy(mantah, mantbl)
  333. }
  334. {
  335. lmantc = add(lmantc, lmantc) //<<1
  336. mantexpd+= mpy(mantbh, mantal)
  337. }
  338. {
  339. lmantc += asr(mantexpd, #15)
  340. exp = add(expa, expb)
  341. zero0 = #0
  342. minus1 = #-1
  343. }
  344. {
  345. k = normamt(mantch)
  346. kl = normamt(mantcl)
  347. p0 = cmp.eq(mantch, zero0l)
  348. p1 = cmp.eq(mantch, minus1l)
  349. }
  350. {
  351. p0 = or(p0, p1)
  352. if(p0.new) k = add(kl, #31)
  353. maxneg.H = #0
  354. }
  355. {
  356. mantexpa = asl(lmantc, k)
  357. exp = sub(exp, k)
  358. maxneg.L = #0x8001
  359. }
  360. {
  361. p0 = cmp.eq(mantexpa, zero0)
  362. p1 = cmp.eq(mantexpa, minus1)
  363. mantal.L = #0
  364. exp = zxth(exp)
  365. }
  366. #if (__HEXAGON_ARCH__ == 60)
  367. {
  368. p0 = or(p0, p1)
  369. if( p0.new) mantal = or(mantal,maxneg)
  370. if(!p0.new) mantal = or(mantal,exp)
  371. }
  372. jumpr r31
  373. #else
  374. {
  375. p0 = or(p0, p1)
  376. if( p0.new) mantal = or(mantal,maxneg)
  377. if(!p0.new) mantal = or(mantal,exp)
  378. jumpr r31
  379. }
  380. #endif