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
14QDOUBLE 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;
22
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);
36
37 hi = (int) (mant>>32);
38 lo = (int) (mant);
39
40 k = HEXAGON_R_normamt_R(hi);
41 if(hi == 0 || hi == -1) k = 31+HEXAGON_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 dadd_asm
54 .type dadd_asm, @function
55dadd_asm:
56
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;
157
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);
171
172 hi = (int) (mant>>32);
173 lo = (int) (mant);
174
175 k = HEXAGON_R_normamt_R(hi);
176 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
177
178 mant = (mant << k);
179 cn = (mant == 0x8000000000000000LL);
180 exp = exp - k + cn;
181
182 if (mant == 0 || mant == -1) exp = 0x8001;
183 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
184 return(c);
185 }
186 * ==================================================================== */
187 .text
188 .global dsub_asm
189 .type dsub_asm, @function
190dsub_asm:
191
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;
294
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);
299
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);
303
304 hi = (int) (mant>>32);
305 lo = (int) (mant);
306
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);
314 }
315 * ==================================================================== */
316 .text
317 .global dmpy_asm
318 .type dmpy_asm, @function
319dmpy_asm:
320
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
341
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
400

source code of compiler-rt/lib/builtins/hexagon/fastmath_dlib_asm.S