* function.c (dump_stack_clash_frame_info): New function.
[official-gcc.git] / libgcc / config / cr16 / lib1funcs.S
blob478b687a4b420b89ce57ae950b9bdd308165625c
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
10    version.
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
15    for more details.
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/>.  */
26 #ifdef  L_mulsi3
27         .text
28         .align  4
29         .globl  ___mulsi3
30 ___mulsi3:
31         movw    r4,r0
32         movw    r2,r1
33         /* Extended multiplication between the 2 lower words */
34         muluw   r1,(r1,r0)
36         /* Multiply the lower word of each parameter  */  
37         mulw    r2,r5   
38     
39         /* With the higher word of the other  */
40         mulw    r3,r4     
41   
42         /* Add products to the higher part of the final result  */
43         addw    r4,r1       
44         addw    r5,r1
45         jump    (ra)
46 #endif
48 #ifdef L_divdi3
49         .text
50         .align 4
51         .globl ___divdi3
53 ___divdi3:
54         push    $4, r7, ra
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)
63         
64         /* Set neg to 0 */
65         movw $0, r10
66         
67         subd $16, (sp)
69         /* Compare if param1 is greater than 0 */       
70         cmpw $0, r3
71         ble L4
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)
83         stord (r3, r2), 4(sp)
84         
85         /* Compare if param2 is greater than 0 */       
86         cmpw $0, r7
87         ble L5
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)
100         movw $0, r2
102         /* Call udivmoddi3 */
103 #ifdef __PIC__
104         loadd   ___udivmoddi3@cGOT(r12), (r1,r0)
105         jal     (r1,r0)
106 #else
107         bal (ra), ___udivmoddi3
108 #endif
110         /* If (neg) */
111         addd    $16, (sp)
112         cmpw $0, r10            /* Compare 0 with neg */
113         beq Lexit__
114         
115         /* Neg = -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 */
119         bcc Lexit__
120         addd $1, (r3, r2)       /* Add 1 to high bit of ures */
122 Lexit__:
123 #  ifdef __ID_SHARED_LIB__
124         pop     $2, r12
125 #  endif
126         popret $4, r7, ra
127 #endif
129 #ifdef L_lshrdi3
130         .text
131         .align 4
132         .globl ___lshrdi3
134 ___lshrdi3:
135         push    $3, r7
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  */
154         lshd r7, (r9, r8)       
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  */
172         lshd r7, (r9, r8)       
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 */
181         
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 */
185 #endif
187 #ifdef L_moddi3
188         .text
189         .align 4
190         .globl ___moddi3
192 ___moddi3:
193         push    $4, r7, ra
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)
202         
203         subd    $18, (sp)
205         /* Set neg to 0 */
206         storw $0, 16(sp)
207         
208         movd    $-1, (r9, r8)   /* Temp set to FFFFFFFF */
210         /* Compare if param1 is greater than 0 */       
211         cmpw $0, r3
212         ble L4
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 */
218         storw $1, 16(sp)
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)
224         
225         /* Compare if param2 is greater than 0 */       
226         cmpw $0, r7
227         ble L5
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)
238         movw $1, r2
240         /* Call udivmoddi3 */
241 #ifdef __PIC__
242         loadd   ___udivmoddi3@cGOT(r12), (r1,r0)
243         jal     (r1,r0)
244 #else
245         bal (ra), ___udivmoddi3
246 #endif
248         /* If (neg) */
249         loadw 16(sp), r10       /* Load neg from stack */
250         addd    $18, (sp)
251         cmpw $0, r10            /* Compare 0 with neg */
252         beq     Lexit__
253         
254         /* Neg = -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 */
258         bcc     Lexit__
259         addd $1, (r3, r2)       /* Add 1 to high bit of ures */
260 Lexit__:
261 #  ifdef __ID_SHARED_LIB__
262         pop     $2, r12
263 #  endif
264         popret  $4, r7, ra
265 #endif
267 #ifdef L_muldi3
268         .text
269         .align 4
270         .globl ___muldi3
272 ___muldi3:
273         push    $2, r13
274         push    $7, r7
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)
284         /* Clear r13, r12 */    
285         movd $0, (r12)  
286         movd $0, (r13)
288         /* Set neg */
289         movw $0, r10
291         /* Compare if param1 is greater than 0 */       
292         cmpw $0, r3
293         ble L1
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 */       
305         cmpw $0, r7
306         ble L2  
307         
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 */
316         
317 L2:     storw r10, 18(sp)       /* Store neg to stack so we can use r10 */
319         /* B*D */
320         /* Bl*Dl */
321         macuw r0, r4, (r12)     /* Multiply r0 and r4 and add to r12 */
322                 
323         /* Bh*Dl */
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 */
334                 
335         /* Bl*Dh */
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 */
346         /* Bh*Dh */
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 */
351         /* A*D */
352         /* Al*Dl */
353         movd $0, (r11, r10)     /* Clear (r11, r10) */
354         macuw r2, r4, (r11, r10)/* Multiply r2 and r4 and add to (r11, r10) */
355         
356         addd (r13), (r11, r10)  /* Copy r13 to (r11, r10) */
358         /* Al*Dh */
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 */
362         
363         /* Ah*Dl */
364         muluw r3, (r5, r4)      /* Multiply r3 and r4 and stor in (r5, r4) */
365         addw r4, r11            /* Add r4 to r11 */
367         /* B*C */
368         /* Bl*Cl */
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 */
373         /* Bl*Ch */
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 */
380         /* Bh*Cl */
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)
385         movd (r12), (r1, r0)    
387         /* If (neg) */
388         cmpw $0, r8             /* Compare 0 with neg */
389         beq     Lexit__
390         
391         /* Neg = -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 */
396         bcc     Lexit__
397         addd $1, (r3, r2)       /* Add 1 to high bit of result */
398 Lexit__:
399         pop     $7, r7
400         popret  $2, r13
401 #endif
403 #ifdef L_negdi2
404         .text
405         .align 4
406         .globl ___negdi2
408 ___negdi2:
409         /* Load parameter from the registers in this order */
410         loadd 0(sp), (r1, r0)
411         loadd 4(sp), (r3, r2)
412         
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 */
417         jcc (ra)
418         addd $1, (r3, r2)       /* Add the carry to the high bits */
419         jump (ra)
420 #endif
422 #ifdef L_udivdi3
423         .text
424         .align 4
425         .globl ___udivdi3
427 ___udivdi3:
428         movw $0, r2
429         br ___udivmoddi3
430 #endif
432 #ifdef L_udivmoddi3
433         .text
434         .align 4
435         .globl ___udivmoddi3
437 ___udivmoddi3:
438         push    $2, r13
439         push    $7, r7
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)
450         /* Set ures to 0 */
451         movd $0, (r13)
452         movd $0, (r12)
453         
454         cmpd (r12), (r5, r4)
455         beq LE
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 */
459         
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 */
467         bhs L10                  
469 L8:     /* Check if most significant bit of param 2 is set */
470         tbit $15, r7            
471         bfs L10                 /* If PSR is set go to L10 */
473         /* Shift bit */
474         lshd $1, (r11, r10)     /* Shift left: high bits of bit */ 
475         /* Check if most significant bit of bit is set */
476         tbit $15, r9            
477         lshd $1, (r9, r8)       /* Shift left: low bits of bit */
478         bfs L28                 /* If PSR is set go to L28 */
480 L9:     /* Shift b */
481         lshd $1, (r7, r6)       /* Shift left: high bits of param 2 */
482         /* Check if most significant bit of param 2 is set */
483         tbit $15, r5            
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 */
487         br L6                   /* Go to L6 */
488         
489 L10:    /* While (bit) */
490         cmpd $0, (r11, r10)     
491         bne L11
492         cmpd $0, (r9, r8)
493         beq E1
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)
504         ord (r9, r8), (r12)     
506         /* Num -= den */
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 */
511         
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 */
515         tbit $0, r10            
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 */
522         tbit $0, r6             
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 */
526         orw $32768, r5          
527         br L10                  /* Go to L10 */
529 L18:    /* Or with 0x8000 to set most significant bit */
530         orw $32768, r9          
531         br L17
533 L28:    /* Left shift bit */
534         addw $1, r10            /* Add 1 to highest bits of bit */
535         br L9                   /* Go to L9 */
537 LE:     cmpd (r12), (r7, r6)
538         bne L5
539         excp dvz
540         br      Lexit__
542 E1:     loadw   18(sp), r4
543         cmpw $0, r4
544         bne     Lexit__
546         /* Return result */
547         movd (r12), (r1, r0)
548         movd (r13), (r3, r2)
549 Lexit__:
550         pop     $7, r7
551         popret  $2, r13
552 #endif
554 #ifdef L_umoddi3
555         .text
556         .align 4
557         .globl ___umoddi3
559 ___umoddi3:
560         movw $1, r2
561         br ___udivmoddi3
562 #endif