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
10fast2_QLDOUBLE fast2_ldadd(fast2_QLDOUBLE a,fast2_QLDOUBLE b) {
11 fast2_QLDOUBLE c;
12 lint manta = a & MANTMASK;
13 int expa = Q6_R_sxth_R(a) ;
14 lint mantb = b & MANTMASK;
15 int expb = Q6_R_sxth_R(b) ;
16 int exp, expdiff, j, k, hi, lo, cn;
17 lint mant;
18
19 expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
20 expdiff = Q6_R_sxth_R(expdiff) ;
21 if (expdiff > 63) { expdiff = 62;}
22 if (expa > expb) {
23 exp = expa + 1;
24 expa = 1;
25 expb = expdiff + 1;
26 } else {
27 exp = expb + 1;
28 expb = 1;
29 expa = expdiff + 1;
30 }
31 mant = (manta>>expa) + (mantb>>expb);
32
33 hi = (int) (mant>>32);
34 lo = (int) (mant);
35
36 k = Q6_R_normamt_R(hi);
37 if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo);
38
39 mant = (mant << k);
40 cn = (mant == 0x8000000000000000LL);
41 exp = exp - k + cn;
42
43 if (mant == 0 || mant == -1) exp = 0x8001;
44 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
45 return(c);
46 }
47 * ==================================================================== */
48 .text
49 .global fast2_ldadd_asm
50 .type fast2_ldadd_asm, @function
51fast2_ldadd_asm:
52#define manta R1:0
53#define lmanta R1:0
54#define mantb R3:2
55#define lmantb R3:2
56#define expa R4
57#define expb R5
58#define expd R6
59#define exp R8
60#define c63 R9
61#define lmant R1:0
62#define k R4
63#define ce P0
64#define zero R3:2
65 .falign
66 {
67 expa = memw(r29+#8)
68 expb = memw(r29+#24)
69 r7 = r0
70 }
71 {
72 expd = sub(expa, expb):sat
73 ce = CMP.GT(expa, expb);
74 if ( ce.new) exp = add(expa, #1)
75 if (!ce.new) exp = add(expb, #1)
76 } {
77 expd = abs(expd):sat
78 if ( ce) expa = #1
79 if (!ce) expb = #1
80 c63 = #62
81 } {
82 expd = MIN(expd, c63)
83 manta = memd(r29+#0)
84 mantb = memd(r29+#16)
85 } {
86 if (!ce) expa = add(expd, #1)
87 if ( ce) expb = add(expd, #1)
88 } {
89 lmanta = ASR(lmanta, expa)
90 lmantb = ASR(lmantb, expb)
91 } {
92 lmant = add(lmanta, lmantb)
93 zero = #0
94 } {
95 k = clb(lmant)
96 c63.L =#0x0001
97 } {
98 exp -= add(k, #-1) //exp = exp - (k-1)
99 k = add(k, #-1)
100 p0 = cmp.gt(k, #58)
101 c63.H =#0x8000
102 } {
103 if(!p0)memw(r7+#8) = exp
104 lmant = ASL(lmant, k)
105 if(p0) jump .Ldenorma
106 } {
107 memd(r7+#0) = lmant
108 jumpr r31
109 }
110.Ldenorma:
111 memd(r7+#0) = zero
112 {
113 memw(r7+#8) = c63
114 jumpr r31
115 }
116/* =================================================================== *
117 fast2_QLDOUBLE fast2_ldsub(fast2_QLDOUBLE a,fast2_QLDOUBLE b) {
118 fast2_QLDOUBLE c;
119 lint manta = a & MANTMASK;
120 int expa = Q6_R_sxth_R(a) ;
121 lint mantb = b & MANTMASK;
122 int expb = Q6_R_sxth_R(b) ;
123 int exp, expdiff, j, k;
124 lint mant;
125
126 expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
127 expdiff = Q6_R_sxth_R(expdiff) ;
128 if (expdiff > 63) { expdiff = 62;}
129 if (expa > expb) {
130 exp = expa + 1;
131 expa = 1;
132 expb = expdiff + 1;
133 } else {
134 exp = expb + 1;
135 expb = 1;
136 expa = expdiff + 1;
137 }
138 mant = (manta>>expa) - (mantb>>expb);
139 k = Q6_R_clb_P(mant)-1;
140 mant = (mant << k);
141 exp = exp - k;
142 if (mant == 0 || mant == -1) exp = 0x8001;
143 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
144 return(c);
145 }
146 * ==================================================================== */
147 .text
148 .global fast2_ldsub_asm
149 .type fast2_ldsub_asm, @function
150fast2_ldsub_asm:
151#define manta R1:0
152#define lmanta R1:0
153#define mantb R3:2
154#define lmantb R3:2
155#define expa R4
156#define expb R5
157#define expd R6
158#define exp R8
159#define c63 R9
160#define lmant R1:0
161#define k R4
162#define ce P0
163#define zero R3:2
164 .falign
165 {
166 expa = memw(r29+#8)
167 expb = memw(r29+#24)
168 r7 = r0
169 }
170 {
171 expd = sub(expa, expb):sat
172 ce = CMP.GT(expa, expb);
173 if ( ce.new) exp = add(expa, #1)
174 if (!ce.new) exp = add(expb, #1)
175 } {
176 expd = abs(expd):sat
177 if ( ce) expa = #1
178 if (!ce) expb = #1
179 c63 = #62
180 } {
181 expd = min(expd, c63)
182 manta = memd(r29+#0)
183 mantb = memd(r29+#16)
184 } {
185 if (!ce) expa = add(expd, #1)
186 if ( ce) expb = add(expd, #1)
187 } {
188 lmanta = ASR(lmanta, expa)
189 lmantb = ASR(lmantb, expb)
190 } {
191 lmant = sub(lmanta, lmantb)
192 zero = #0
193 } {
194 k = clb(lmant)
195 c63.L =#0x0001
196 } {
197 exp -= add(k, #-1) //exp = exp - (k+1)
198 k = add(k, #-1)
199 p0 = cmp.gt(k, #58)
200 c63.H =#0x8000
201 } {
202 if(!p0)memw(r7+#8) = exp
203 lmant = asl(lmant, k)
204 if(p0) jump .Ldenorma_s
205 } {
206 memd(r7+#0) = lmant
207 jumpr r31
208 }
209.Ldenorma_s:
210 memd(r7+#0) = zero
211 {
212 memw(r7+#8) = c63
213 jumpr r31
214 }
215
216/* ==================================================================== *
217 fast2_QLDOUBLE fast2_ldmpy(fast2_QLDOUBLE a,fast2_QLDOUBLE b) {
218 fast2_QLDOUBLE c;
219 lint manta = a & MANTMASK;
220 int expa = Q6_R_sxth_R(a) ;
221 lint mantb = b & MANTMASK;
222 int expb = Q6_R_sxth_R(b) ;
223 int exp, k;
224 lint mant;
225 int hia, hib, hi, lo;
226 unsigned int loa, lob;
227
228 hia = (int)(a >> 32);
229 loa = Q6_R_extractu_RII((int)manta, 31, 1);
230 hib = (int)(b >> 32);
231 lob = Q6_R_extractu_RII((int)mantb, 31, 1);
232
233 mant = Q6_P_mpy_RR(hia, lob);
234 mant = Q6_P_mpyacc_RR(mant,hib, loa);
235 mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1);
236
237 hi = (int) (mant>>32);
238
239 k = Q6_R_normamt_R(hi);
240 mant = mant << k;
241 exp = expa + expb - k;
242 if (mant == 0 || mant == -1) exp = 0x8001;
243 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
244 return(c);
245 }
246 * ==================================================================== */
247 .text
248 .global fast2_ldmpy_asm
249 .type fast2_ldmpy_asm, @function
250fast2_ldmpy_asm:
251
252#define mantxl_ R9
253#define mantxl R14
254#define mantxh R15
255#define mantx R15:14
256#define mantbl R2
257#define mantbl_ R8
258#define mantbh R3
259#define mantb R3:2
260#define expa R4
261#define expb R5
262#define c8001 R8
263#define mantd R7:6
264#define lmantc R11:10
265#define kp R9
266#define min R13:12
267#define minh R13
268#define max R13:12
269#define maxh R13
270#define ret R0
271
272 .falign
273 {
274 mantx = memd(r29+#0)
275 mantb = memd(r29+#16)
276 min = #0
277 }
278 {
279 mantbl_= extractu(mantbl, #31, #1)
280 mantxl_= extractu(mantxl, #31, #1)
281 minh.H = #0x8000
282 }
283 {
284 lmantc = mpy(mantxh, mantbh)
285 mantd = mpy(mantxh, mantbl_)
286 expa = memw(r29+#8)
287 expb = memw(r29+#24)
288 }
289 {
290 lmantc = add(lmantc, lmantc)
291 mantd += mpy(mantbh, mantxl_)
292 }
293 {
294 mantd = asr(mantd, #30)
295 c8001.L = #0x0001
296 p1 = cmp.eq(mantx, mantb)
297 }
298 {
299 mantd = add(mantd, lmantc)
300 expa= add(expa, expb)
301 p2 = cmp.eq(mantb, min)
302 }
303 {
304 kp = clb(mantd)
305 c8001.H = #0x8000
306 p1 = and(p1, p2)
307 }
308 {
309 expa-= add(kp, #-1)
310 kp = add(kp, #-1)
311 if(p1) jump .Lsat
312 }
313 {
314 mantd = asl(mantd, kp)
315 memw(ret+#8) = expa
316 p0 = cmp.gt(kp, #58)
317 if(p0.new) jump:NT .Ldenorm //rarely happens
318 }
319 {
320 memd(ret+#0) = mantd
321 jumpr r31
322 }
323.Lsat:
324 {
325 max = #0
326 expa+= add(kp, #1)
327 }
328 {
329 maxh.H = #0x4000
330 memw(ret+#8) = expa
331 }
332 {
333 memd(ret+#0) = max
334 jumpr r31
335 }
336.Ldenorm:
337 {
338 memw(ret+#8) = c8001
339 mantx = #0
340 }
341 {
342 memd(ret+#0) = mantx
343 jumpr r31
344 }
345

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