]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/hexagon/fastmath2_dlib_asm.S
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / builtins / hexagon / fastmath2_dlib_asm.S
1 //===----------------------Hexagon builtin routine ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /* ==================================================================== */
10 /*   FUNCTIONS Optimized double floating point operators                */
11 /* ==================================================================== */
12 /*      c = dadd_asm(a, b)                                              */
13 /* ==================================================================== *
14 fast2_QDOUBLE fast2_dadd(fast2_QDOUBLE a,fast2_QDOUBLE b) {
15       fast2_QDOUBLE c;
16       lint manta = a & MANTMASK;
17       int  expa  = Q6_R_sxth_R(a) ;
18       lint mantb = b & MANTMASK;
19       int  expb  = Q6_R_sxth_R(b) ;
20       int  exp, expdiff, j, k, hi, lo, cn;
21       lint mant;
22
23         expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
24         expdiff = Q6_R_sxth_R(expdiff) ;
25         if (expdiff > 63) { expdiff = 62;}
26         if (expa > expb) {
27           exp = expa + 1;
28           expa = 1;
29           expb = expdiff + 1;
30         } else {
31           exp = expb + 1;
32           expb = 1;
33           expa = expdiff + 1;
34         }
35         mant = (manta>>expa) + (mantb>>expb);
36
37         hi = (int) (mant>>32);
38         lo = (int) (mant);
39
40         k =  Q6_R_normamt_R(hi);
41         if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo);
42
43         mant = (mant << k);
44         cn  = (mant == 0x8000000000000000LL);
45         exp = exp - k + cn;
46
47         if (mant ==  0 || mant == -1)  exp = 0x8001;
48         c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
49       return(c);
50  }
51  * ==================================================================== */
52         .text
53         .global fast2_dadd_asm
54         .type fast2_dadd_asm, @function
55 fast2_dadd_asm:
56 #define manta      R0
57 #define mantexpa   R1:0
58 #define lmanta     R1:0
59 #define mantb      R2
60 #define mantexpb   R3:2
61 #define lmantb     R3:2
62 #define expa       R4
63 #define expb       R5
64 #define mantexpd   R7:6
65 #define expd       R6
66 #define exp        R8
67 #define c63        R9
68 #define lmant      R1:0
69 #define manth      R1
70 #define mantl      R0
71 #define minmin     R11:10  // exactly 0x000000000000008001LL
72 #define minminl    R10
73 #define k          R4
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         minmin = #0
96       } {
97         lmanta = ASR(lmanta, expa)
98         lmantb = ASR(lmantb, expb)
99       } {
100         lmant = add(lmanta, lmantb)
101         minminl.L = #0x8001
102       } {
103         k  = clb(lmant)
104         c63 = #58
105       } {
106         k = add(k, #-1)
107         p0 = cmp.gt(k, c63)
108       } {
109         mantexpa = ASL(lmant, k)
110         exp = SUB(exp, k)
111         if(p0) jump .Ldenorma
112       } {
113         manta = insert(exp, #16, #0)
114         jumpr  r31
115       }
116 .Ldenorma:
117       {
118         mantexpa = minmin
119         jumpr  r31
120       }
121 /* =================================================================== *
122  fast2_QDOUBLE fast2_dsub(fast2_QDOUBLE a,fast2_QDOUBLE b) {
123       fast2_QDOUBLE c;
124       lint manta = a & MANTMASK;
125       int  expa  = Q6_R_sxth_R(a) ;
126       lint mantb = b & MANTMASK;
127       int  expb  = Q6_R_sxth_R(b) ;
128       int  exp, expdiff, j, k;
129       lint mant;
130
131         expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
132         expdiff = Q6_R_sxth_R(expdiff) ;
133         if (expdiff > 63) { expdiff = 62;}
134         if (expa > expb) {
135           exp = expa + 1;
136           expa = 1;
137           expb = expdiff + 1;
138         } else {
139           exp = expb + 1;
140           expb = 1;
141           expa = expdiff + 1;
142         }
143         mant = (manta>>expa) - (mantb>>expb);
144         k =  Q6_R_clb_P(mant)-1;
145         mant = (mant << k);
146         exp = exp - k;
147         if (mant ==  0 || mant == -1)  exp = 0x8001;
148         c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
149       return(c);
150  }
151  * ==================================================================== */
152         .text
153         .global fast2_dsub_asm
154         .type fast2_dsub_asm, @function
155 fast2_dsub_asm:
156
157 #define manta      R0
158 #define mantexpa   R1:0
159 #define lmanta     R1:0
160 #define mantb      R2
161 #define mantexpb   R3:2
162 #define lmantb     R3:2
163 #define expa       R4
164 #define expb       R5
165 #define mantexpd   R7:6
166 #define expd       R6
167 #define exp        R8
168 #define c63        R9
169 #define lmant      R1:0
170 #define manth      R1
171 #define mantl      R0
172 #define minmin     R11:10  // exactly 0x000000000000008001LL
173 #define minminl    R10
174 #define k          R4
175 #define ce         P0
176         .falign
177       {
178         mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
179         c63 = #62
180         expa = SXTH(manta)
181         expb = SXTH(mantb)
182       } {
183         expd = SXTH(expd)
184         ce = CMP.GT(expa, expb);
185         if ( ce.new) exp = add(expa, #1)
186         if (!ce.new) exp = add(expb, #1)
187       } {
188         if ( ce) expa = #1
189         if (!ce) expb = #1
190         manta.L = #0
191         expd = MIN(expd, c63)
192       } {
193         if (!ce) expa = add(expd, #1)
194         if ( ce) expb = add(expd, #1)
195         mantb.L = #0
196         minmin = #0
197       } {
198         lmanta = ASR(lmanta, expa)
199         lmantb = ASR(lmantb, expb)
200       } {
201         lmant = sub(lmanta, lmantb)
202         minminl.L = #0x8001
203       } {
204         k  = clb(lmant)
205         c63 = #58
206       } {
207         k = add(k, #-1)
208         p0 = cmp.gt(k, c63)
209       } {
210         mantexpa = ASL(lmant, k)
211         exp = SUB(exp, k)
212         if(p0) jump .Ldenorm
213       } {
214         manta = insert(exp, #16, #0)
215         jumpr  r31
216       }
217 .Ldenorm:
218       {
219         mantexpa = minmin
220         jumpr  r31
221       }
222 /* ==================================================================== *
223  fast2_QDOUBLE fast2_dmpy(fast2_QDOUBLE a,fast2_QDOUBLE b) {
224         fast2_QDOUBLE c;
225         lint manta = a & MANTMASK;
226         int  expa  = Q6_R_sxth_R(a) ;
227         lint mantb = b & MANTMASK;
228         int  expb  = Q6_R_sxth_R(b) ;
229         int exp, k;
230         lint mant;
231         int          hia, hib, hi, lo;
232         unsigned int loa, lob;
233
234         hia = (int)(a >> 32);
235         loa = Q6_R_extractu_RII((int)manta, 31, 1);
236         hib = (int)(b >> 32);
237         lob = Q6_R_extractu_RII((int)mantb, 31, 1);
238
239         mant = Q6_P_mpy_RR(hia, lob);
240         mant = Q6_P_mpyacc_RR(mant,hib, loa);
241         mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1);
242
243         hi = (int) (mant>>32);
244
245         k =  Q6_R_normamt_R(hi);
246         mant = mant << k;
247         exp = expa + expb - k;
248         if (mant ==  0 || mant == -1)  exp = 0x8001;
249         c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
250         return(c);
251  }
252  * ==================================================================== */
253         .text
254         .global fast2_dmpy_asm
255         .type fast2_dmpy_asm, @function
256 fast2_dmpy_asm:
257
258 #define mantal     R0
259 #define mantah     R1
260 #define mantexpa   R1:0
261 #define mantbl     R2
262 #define mantbh     R3
263 #define mantexpb   R3:2
264 #define expa       R4
265 #define expb       R5
266 #define c8001      R12
267 #define mantexpd   R7:6
268 #define mantdh     R7
269 #define exp        R8
270 #define lmantc     R11:10
271 #define kb         R9
272 #define guard      R11
273 #define mantal_    R12
274 #define mantbl_    R13
275 #define min        R15:14
276 #define minh       R15
277
278         .falign
279       {
280         mantbl_= lsr(mantbl, #16)
281         expb = sxth(mantbl)
282         expa = sxth(mantal)
283         mantal_= lsr(mantal, #16)
284       }
285       {
286         lmantc = mpy(mantah, mantbh)
287         mantexpd = mpy(mantah, mantbl_)
288         mantal.L = #0x0
289         min = #0
290       }
291       {
292         lmantc = add(lmantc, lmantc)
293         mantexpd+= mpy(mantbh, mantal_)
294         mantbl.L = #0x0
295         minh.H = #0x8000
296       }
297       {
298         mantexpd = asr(mantexpd, #15)
299         c8001.L =  #0x8001
300         p1 = cmp.eq(mantexpa, mantexpb)
301       }
302       {
303         mantexpd = add(mantexpd, lmantc)
304         exp = add(expa, expb)
305         p2 = cmp.eq(mantexpa, min)
306       }
307       {
308         kb  = clb(mantexpd)
309         mantexpb = abs(mantexpd)
310         guard = #58
311       }
312       {
313         p1 = and(p1, p2)
314         exp = sub(exp, kb)
315         kb = add(kb, #-1)
316         p0 = cmp.gt(kb, guard)
317       }
318       {
319         exp = add(exp, #1)
320         mantexpa = asl(mantexpd, kb)
321         if(p1) jump .Lsat   //rarely happens
322       }
323       {
324         mantal = insert(exp,#16, #0)
325         if(!p0) jumpr  r31
326       }
327       {
328         mantal = insert(c8001,#16, #0)
329         jumpr  r31
330       }
331 .Lsat:
332       {
333         mantexpa = #-1
334       }
335       {
336         mantexpa = lsr(mantexpa, #1)
337       }
338       {
339         mantal = insert(exp,#16, #0)
340         jumpr  r31
341       }
342
343 /* ==================================================================== *
344  int fast2_qd2f(fast2_QDOUBLE a) {
345         int exp;
346         long long int manta;
347         int ic, rnd, mantb;
348
349         manta = a>>32;
350         exp = Q6_R_sxth_R(a) ;
351         ic = 0x80000000 & manta;
352         manta = Q6_R_abs_R_sat(manta);
353         mantb = (manta + rnd)>>7;
354         rnd = 0x40
355         exp = (exp + 126);
356         if((manta & 0xff) == rnd) rnd = 0x00;
357         if((manta & 0x7fffffc0) == 0x7fffffc0) {
358            manta = 0x0; exp++;
359         } else {
360            manta= mantb & 0x007fffff;
361         }
362         exp = (exp << 23) & 0x7fffffc0;
363         ic = Q6_R_addacc_RR(ic, exp, manta);
364         return (ic);
365  }
366  * ==================================================================== */
367
368         .text
369         .global fast2_qd2f_asm
370         .type fast2_qd2f_asm, @function
371 fast2_qd2f_asm:
372 #define mantah   R1
373 #define mantal   R0
374 #define cff      R0
375 #define mant     R3
376 #define expo     R4
377 #define rnd      R5
378 #define mask     R6
379 #define c07f     R7
380 #define c80      R0
381 #define mantb    R2
382 #define ic       R0
383
384       .falign
385      {
386        mant = abs(mantah):sat
387        expo = sxth(mantal)
388        rnd = #0x40
389        mask.L = #0xffc0
390      }
391      {
392        cff = extractu(mant, #8, #0)
393        p2 = cmp.gt(expo, #126)
394        p3 = cmp.ge(expo, #-126)
395        mask.H = #0x7fff
396      }
397      {
398        p1 = cmp.eq(cff,#0x40)
399        if(p1.new) rnd = #0
400        expo = add(expo, #126)
401        if(!p3) jump .Lmin
402      }
403      {
404        p0 = bitsset(mant, mask)
405        c80.L = #0x0000
406        mantb = add(mant, rnd)
407        c07f = lsr(mask, #8)
408      }
409      {
410        if(p0) expo = add(expo, #1)
411        if(p0) mant = #0
412        mantb = lsr(mantb, #7)
413        c80.H = #0x8000
414      }
415      {
416        ic = and(c80, mantah)
417        mask &= asl(expo, #23)
418        if(!p0) mant = and(mantb, c07f)
419        if(p2) jump .Lmax
420      }
421      {
422        ic += add(mask, mant)
423        jumpr r31
424      }
425 .Lmax:
426      {
427        ic.L = #0xffff;
428      }
429      {
430        ic.H = #0x7f7f;
431        jumpr r31
432      }
433 .Lmin:
434      {
435        ic = #0x0
436        jumpr r31
437      }
438
439 /* ==================================================================== *
440 fast2_QDOUBLE fast2_f2qd(int ia) {
441         lint exp;
442         lint mant;
443         fast2_QDOUBLE c;
444
445         mant = ((ia << 7) | 0x40000000)&0x7fffff80 ;
446         if (ia & 0x80000000) mant = -mant;
447         exp =  ((ia >> 23) & 0xFFLL) - 126;
448         c = (mant<<32) | Q6_R_zxth_R(exp);;
449         return(c);
450 }
451  * ==================================================================== */
452         .text
453         .global fast2_f2qd_asm
454         .type fast2_f2qd_asm, @function
455 fast2_f2qd_asm:
456 #define ia    R0
457 #define mag   R3
458 #define mantr R1
459 #define expr  R0
460 #define zero  R2
461 #define maxneg R5:4
462 #define maxnegl R4
463         .falign
464   {
465        mantr = asl(ia, #7)
466        p0 = tstbit(ia, #31)
467        maxneg = #0
468        mag = add(ia,ia)
469   }
470   {
471        mantr = setbit(mantr, #30)
472        expr= extractu(ia,#8,#23)
473        maxnegl.L = #0x8001
474        p1 = cmp.eq(mag, #0)
475   }
476   {
477        mantr= extractu(mantr, #31, #0)
478        expr= add(expr, #-126)
479        zero = #0
480        if(p1) jump .Lminqd
481   }
482   {
483        expr = zxth(expr)
484        if(p0) mantr= sub(zero, mantr)
485        jumpr r31
486   }
487 .Lminqd:
488   {
489        R1:0 = maxneg
490        jumpr r31
491   }