1 /* Libgcc Target specific implementation.
2 Copyright (C) 2012-2017 Free Software Foundation, Inc.
3 Contributed by KPIT Cummins Infosystems Limited.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
33 /* Extended multiplication between the 2 lower words */
36 /* Multiply the lower word of each parameter */
39 /* With the higher word of the other */
42 /* Add products to the higher part of the final result */
56 /* Param #1 Long Long low bit first */
57 loadd 12(sp), (r1, r0)
58 loadd 16(sp), (r3, r2)
60 /* Param #2 Long Long low bit first */
61 loadd 20(sp), (r5, r4)
62 loadd 24(sp), (r7, r6)
69 /* Compare if param1 is greater than 0 */
73 /* Invert param1 and neg */
74 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
75 xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
76 xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
77 addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
78 xorw $1, r10 /* Invert neg */
79 bcc L4 /* If no carry occurred go to L4 */
80 addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
82 L4: stord (r1, r0), 0(sp)
85 /* Compare if param2 is greater than 0 */
89 /* Invert param2 and neg */
90 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
91 xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
92 xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
93 addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
94 xorw $1, r10 /* Invert neg */
95 bcc L5 /* If no carry occurred go to L5 */
96 addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
98 L5: stord (r5, r4), 8(sp)
99 stord (r7, r6), 12(sp)
102 /* Call udivmoddi3 */
104 loadd ___udivmoddi3@cGOT(r12), (r1,r0)
107 bal (ra), ___udivmoddi3
112 cmpw $0, r10 /* Compare 0 with neg */
116 xord (r9, r8), (r1, r0) /* Xor low bits of ures with temp */
117 xord (r9, r8), (r3, r2) /* Xor high bits of ures with temp */
118 addd $1, (r1, r0) /* Add 1 to low bits of ures */
120 addd $1, (r3, r2) /* Add 1 to high bit of ures */
123 # ifdef __ID_SHARED_LIB__
137 /* Load parameters from stack in this order */
138 movw r2, r6 /* Number of shifts */
139 loadd 6(sp), (r1, r0) /* Low bits */
140 loadd 10(sp), (r3, r2)/* High bits */
142 xorw $-1, r6 /* Invert number of shifts */
143 addw $1, r6 /* Add 1 by number of shifts */
145 movw r6, r7 /* Copy number of shifts */
147 tbit $15, r6 /* Test if number is negative */
148 bfs L2 /* If negative jump to L2 */
150 movd (r1, r0), (r9, r8) /* Copy low bits */
152 subw $32, r7 /* Calc how many bits will overflow */
153 /* Shift the temp low bit to the right to see the overflowing bits */
156 cmpw $32, r6 /* If number of shifts is higher than 31 */
157 blt L1 /* Shift by moving */
159 lshd r6, (r3, r2) /* Shift high bits */
160 lshd r6, (r1, r0) /* Shift low bits */
161 addd (r9, r8), (r3, r2) /* Add overflow to the high bits */
162 popret $3, r7 /* Return */
164 L1: movd $0, (r1, r0) /* Reset low bit */
165 movd (r9, r8), (r3, r2) /* Add the overflow from the low bit */
166 popret $3, r7 /* Return */
168 L2: movd (r3, r2), (r9, r8) /* Copy high bits */
170 addw $32, r7 /* Calc how many bits will overflow */
171 /* Shift the temp low bit to the left to see the overflowing bits */
174 cmpw $-32, r6 /* If number of shifts is lower than -31 */
175 bgt L3 /* Shift by moving */
177 lshd r6, (r1, r0) /* Shift low bits */
178 lshd r6, (r3, r2) /* Shift high bits */
179 addd (r9, r8), (r1, r0) /* Add overflow to the low bits */
180 popret $3, r7 /* Return */
182 L3: movd $0, (r3, r2) /* Reset the high bit */
183 movd (r9, r8), (r1, r0) /* Add the overflow from the high bit */
184 popret $3, r7 /* Return */
195 /* Param #1 Long Long low bit first */
196 loadd 12(sp), (r1, r0)
197 loadd 16(sp), (r3, r2)
199 /* Param #2 Long Long low bit first */
200 loadd 20(sp), (r5, r4)
201 loadd 24(sp), (r7, r6)
208 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
210 /* Compare if param1 is greater than 0 */
214 /* Invert param1 and neg */
215 xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
216 xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
217 addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
219 bcc L4 /* If no carry occurred go to L4 */
220 addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
222 L4: stord (r1, r0), 0(sp)
223 stord (r3, r2), 4(sp)
225 /* Compare if param2 is greater than 0 */
229 /* Invert param2 and neg */
230 xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
231 xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
232 addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
233 bcc L5 /* If no carry occurred go to L5 */
234 addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
236 L5: stord (r5, r4), 8(sp)
237 stord (r7, r6), 12(sp)
240 /* Call udivmoddi3 */
242 loadd ___udivmoddi3@cGOT(r12), (r1,r0)
245 bal (ra), ___udivmoddi3
249 loadw 16(sp), r10 /* Load neg from stack */
251 cmpw $0, r10 /* Compare 0 with neg */
255 xord (r9, r8), (r1, r0) /* Xor low bits of ures with temp */
256 xord (r9, r8), (r3, r2) /* Xor high bits of ures with temp */
257 addd $1, (r1, r0) /* Add 1 to low bits of ures */
259 addd $1, (r3, r2) /* Add 1 to high bit of ures */
261 # ifdef __ID_SHARED_LIB__
276 /* Param #1 Long Long low bit first */
277 loadd 18(sp), (r1, r0)
278 loadd 22(sp), (r3, r2)
280 /* Param #2 Long Long low bit first */
281 loadd 26(sp), (r5, r4)
282 loadd 30(sp), (r7, r6)
291 /* Compare if param1 is greater than 0 */
295 /* Invert param1 and neg */
296 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
297 xord (r9, r8), (r1, r0) /* Xor low bits of param 1 with temp */
298 xord (r9, r8), (r3, r2) /* Xor high bits of param 1 with temp */
299 addd $1, (r1, r0) /* Add 1 to low bits of param 1 */
300 xorw $1, r10 /* Invert neg */
301 bcc L1 /* If no carry occurred go to L1 */
302 addd $1, (r3, r2) /* Add 1 to high bits of param 1 */
304 L1: /* Compare if param2 is greater than 0 */
308 /* Invert param2 and neg */
309 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
310 xord (r9, r8), (r5, r4) /* Xor low bits of param 2 with temp */
311 xord (r9, r8), (r7, r6) /* Xor high bits of param 2 with temp */
312 addd $1, (r5, r4) /* Add 1 to low bits of param 2 */
313 xorw $1, r10 /* Invert neg */
314 bcc L2 /* If no carry occurred go to L2 */
315 addd $1, (r7, r6) /* Add 1 to high bits of param 2 */
317 L2: storw r10, 18(sp) /* Store neg to stack so we can use r10 */
321 macuw r0, r4, (r12) /* Multiply r0 and r4 and add to r12 */
324 movd $0, (r9, r8) /* Clear r9, r8 */
325 macuw r1, r4, (r9, r8) /* Multiply Bh*Dl and add result to (r9, r8) */
326 movw r9, r10 /* Shift left: r9 to r10 */
327 lshd $16, (r9, r8) /* Shift left: r8 to r9 */
328 movw $0, r11 /* Clear r11 */
329 addd (r9, r8), (r12) /* Add (r9, r8) to r12 */
330 bcc L3 /* If no carry occurred go to L3 */
331 addd $1, (r13) /* If carry occurred add 1 to r13 */
333 L3: addd (r11, r10), (r13) /* Add (r11, r10) to r13 */
336 movd $0, (r9, r8) /* Clear (r9, r8) */
337 macuw r0, r5, (r9, r8) /* Multiply r0 and r5 and stor in (r9, r8) */
338 movw r9, r10 /* Shift left: r9 to r10 */
339 lshd $16, (r9, r8) /* Shift left: r8 to r9 */
340 addd (r9, r8), (r12) /* Add (r9, r8) to r12 */
341 bcc L4 /* If no carry occurred go to L4 */
342 addd $1, (r13) /* If carry occurred add 1 to r13 */
344 L4: addd (r11, r10), (r13) /* Add (r11, r10) to r13 */
347 movd $0, (r9, r8) /* Clear (r9, r8) */
348 macuw r1, r5, (r9, r8) /* Multiply r1 and r5 and add to r13 */
349 addd (r9, r8), (r13) /* Add (r9, r8) to result */
353 movd $0, (r11, r10) /* Clear (r11, r10) */
354 macuw r2, r4, (r11, r10)/* Multiply r2 and r4 and add to (r11, r10) */
356 addd (r13), (r11, r10) /* Copy r13 to (r11, r10) */
359 movd $0, (r9, r8) /* Clear (r9, r8) */
360 macuw r2, r5, (r9, r8) /* Multiply r2 and r5 and add to (r9, r8) */
361 addw r8, r11 /* Add r8 to r11 */
364 muluw r3, (r5, r4) /* Multiply r3 and r4 and stor in (r5, r4) */
365 addw r4, r11 /* Add r4 to r11 */
369 movd $0, (r9, r8) /* Clear (r9, r8) */
370 macuw r0, r6, (r9, r8) /* Multiply r0 and r6 and add to (r9, r8) */
371 addd (r9, r8), (r11, r10)/* Add (r9, r8) to result */
374 movd $0, (r9, r8) /* Clear (r9, r8) */
375 macuw r0, r7, (r9, r8) /* Multiply r0 and r7 and add to (r9, r8) */
376 addw r8, r11 /* Add r8 to r11 */
378 loadw 18(sp), r8 /* Load neg from stack */
381 muluw r1, (r7, r6) /* Multiply r1 and r6 and stor in (r7, r6) */
382 addw r6, r11 /* Add r6 to r11 */
384 E1: movd (r11, r10), (r3, r2)
388 cmpw $0, r8 /* Compare 0 with neg */
392 movd $-1, (r9, r8) /* Temp set to FFFFFFFF */
393 xord (r9, r8), (r1, r0) /* Xor low bits of result with temp */
394 xord (r9, r8), (r3, r2) /* Xor high bits of result with temp */
395 addd $1, (r1, r0) /* Add 1 to low bits of result */
397 addd $1, (r3, r2) /* Add 1 to high bit of result */
409 /* Load parameter from the registers in this order */
410 loadd 0(sp), (r1, r0)
411 loadd 4(sp), (r3, r2)
413 movd $-1, (r6, r5) /* Set temp to FFFFFFFF */
414 xord (r6, r5), (r1, r0) /* Xor low bits with temp */
415 xord (r6, r5), (r3, r2) /* Xor high bits with temp */
416 addd $1, (r1, r0) /* Add one */
418 addd $1, (r3, r2) /* Add the carry to the high bits */
441 /* Param #1 Long Long low bit first */
442 loadd 18(sp), (r1, r0)
443 storw r2, 18(sp) /* Store modulo on stack */
444 loadd 22(sp), (r3, r2)
446 /* Param #2 Long Long low bit first */
447 loadd 26(sp), (r5, r4)
448 loadd 30(sp), (r7, r6)
457 L5: movd $1, (r9, r8) /* Store 1 in low bits from bit */
458 movd $0, (r11, r10) /* Store 0 in high bits from bit */
460 L6: /* While (den < num && (!den & (1LL<<63))) */
461 /* Compare high bits from param 1 and param 2 */
462 cmpd (r7, r6), (r3, r2)
463 bhi L10 /* If param 2 is greater go to L10 */
464 bne L8 /* If param 1 is greater go to L8 */
465 cmpd (r5, r4), (r1, r0) /* Compare low bits from param 1 and param 2 */
466 /* If param 2 is greater or the same go to L1 */
469 L8: /* Check if most significant bit of param 2 is set */
471 bfs L10 /* If PSR is set go to L10 */
474 lshd $1, (r11, r10) /* Shift left: high bits of bit */
475 /* Check if most significant bit of bit is set */
477 lshd $1, (r9, r8) /* Shift left: low bits of bit */
478 bfs L28 /* If PSR is set go to L28 */
481 lshd $1, (r7, r6) /* Shift left: high bits of param 2 */
482 /* Check if most significant bit of param 2 is set */
484 lshd $1, (r5, r4) /* Shift left: low bits of param 2 */
485 bfc L6 /* If PSR is set go to L6 */
486 addw $1, r6 /* Add 1 to the highest bits of b */
489 L10: /* While (bit) */
495 L11: /* If (num >= den) */
496 cmpd (r3, r2), (r7, r6) /* Compare high bits of param 1 and param 2 */
497 blo L15 /* If param 1 lower than param 2 go to L15 */
498 bne L12 /* If not equal go to L12 */
499 cmpd (r1, r0), (r5, r4) /* Compare low bits of param 1 and param 2 */
500 blo L15 /* If param 1 lower than param 2 go to L15 */
502 L12: /* Ures |= bit */
503 ord (r11, r10), (r13)
507 subd (r7, r6), (r3, r2) /* Subtract highest 32 bits from each other */
508 subd (r5, r4), (r1, r0) /* Subtract lowest 32 bits from each other */
509 bcc L15 /* If no carry occurred go to L15 */
510 subd $1, (r3, r2) /* Subtract the carry */
512 L15: /* Shift bit to the right */
513 lshd $-1, (r9, r8) /* Shift right: low bits of bit */
514 /* Check if least significant bit of high bits is set */
516 lshd $-1, (r11, r10) /* Shift right: high bits of bit */
517 bfs L18 /* If PSR is set go to L18 */
519 L17: /* Shift param#2 to the right */
520 lshd $-1, (r5, r4) /* Shift right: low bits of param 2 */
521 /* Check if least significant bit of high bits is set */
523 lshd $-1, (r7, r6) /* Shift right: high bits of param 2 */
524 bfc L10 /* If PSR is not set go to L10 */
525 /* Or with 0x8000 to set most significant bit */
527 br L10 /* Go to L10 */
529 L18: /* Or with 0x8000 to set most significant bit */
533 L28: /* Left shift bit */
534 addw $1, r10 /* Add 1 to highest bits of bit */
537 LE: cmpd (r12), (r7, r6)