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