[NDS32] Support Linux target for nds32.
[official-gcc.git] / libgcc / config / microblaze / umodsi3.S
bloba2582d037736f515c328bc9a366557edd23ec160
1 ###################################
2
3 #  Copyright (C) 2009-2018 Free Software Foundation, Inc.
5 #  Contributed by Michael Eager <eager@eagercon.com>.
7 #  This file is free software; you can redistribute it and/or modify it
8 #  under the terms of the GNU General Public License as published by the
9 #  Free Software Foundation; either version 3, or (at your option) any
10 #  later version.
12 #  GCC is distributed in the hope that it will be useful, but WITHOUT
13 #  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 #  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 #  License 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/>. 
25
26 #  umodsi3.S
28 #  Unsigned modulo operation for 32 bit integers.
29 #       Input : op1 in Reg r5
30 #               op2 in Reg r6
31 #       Output: op1 mod op2 in Reg r3
32
33 #######################################
34         
35 /* An executable stack is *not* required for these functions.  */
36 #ifdef __linux__
37 .section .note.GNU-stack,"",%progbits
38 .previous
39 #endif
41         .globl  __umodsi3
42         .ent    __umodsi3
43         .type   __umodsi3,@function
44 __umodsi3:
45         .frame  r1,0,r15        
47         addik   r1,r1,-12
48         swi     r29,r1,0
49         swi     r30,r1,4
50         swi     r31,r1,8
52         BEQI    r6,$LaDiv_By_Zero         # Div_by_Zero   # Division Error
53         BEQId   r5,$LaResult_Is_Zero     # Result is Zero 
54         ADDIK   r3,r0,0                  # Clear div
55         ADDIK   r30,r0,0        # clear mod
56         ADDIK   r29,r0,32       # Initialize the loop count
58 # Check if r6 and r5 are equal # if yes, return 0
59         rsub    r18,r5,r6
60         beqi    r18,$LaRETURN_HERE
62 # Check if (uns)r6 is greater than (uns)r5. In that case, just return r5
63         xor     r18,r5,r6
64         bgeid   r18,16
65         addik   r3,r5,0
66         blti    r6,$LaRETURN_HERE
67         bri     $LCheckr6
68         rsub    r18,r5,r6 # MICROBLAZEcmp
69         bgti    r18,$LaRETURN_HERE
71 # If r6 [bit 31] is set, then return result as r5-r6
72 $LCheckr6:
73         bgtid   r6,$LaDIV0
74         addik   r3,r0,0
75         addik   r18,r0,0x7fffffff
76         and     r5,r5,r18
77         and     r6,r6,r18
78         brid    $LaRETURN_HERE
79         rsub    r3,r6,r5
80 # First part: try to find the first '1' in the r5
81 $LaDIV0:
82         BLTI    r5,$LaDIV2
83 $LaDIV1:
84         ADD     r5,r5,r5     # left shift logical r5
85         BGEID   r5,$LaDIV1   #
86         ADDIK   r29,r29,-1
87 $LaDIV2:
88         ADD     r5,r5,r5     # left shift logical  r5 get the '1' into the Carry
89         ADDC    r3,r3,r3     # Move that bit into the Mod register
90         rSUB    r31,r6,r3    # Try to subtract (r3 a r6)
91         BLTi    r31,$LaMOD_TOO_SMALL
92         OR      r3,r0,r31    # Move the r31 to mod since the result was positive
93         ADDIK   r30,r30,1
94 $LaMOD_TOO_SMALL:
95         ADDIK   r29,r29,-1
96         BEQi    r29,$LaLOOP_END
97         ADD     r30,r30,r30 # Shift in the '1' into div
98         BRI     $LaDIV2     # Div2
99 $LaLOOP_END:
100         BRI     $LaRETURN_HERE
101 $LaDiv_By_Zero:
102 $LaResult_Is_Zero:
103         or      r3,r0,r0   # set result to 0
104 $LaRETURN_HERE:
105 # Restore values of CSRs and that of r3 and the divisor and the dividend
106         lwi     r29,r1,0
107         lwi     r30,r1,4
108         lwi     r31,r1,8
109         rtsd    r15,8
110         addik   r1,r1,12
111 .end __umodsi3
112         .size   __umodsi3, . - __umodsi3