Fix broken MinGW build of gcc.c
[official-gcc.git] / libgcc / config / microblaze / modsi3.S
blobeb671a145af3cda5449666d47d924e17b5025adb
1 ###################################
2
3 #  Copyright (C) 2009-2017 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 #  modsi3.S
27
28 #  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 #######################################
35         .globl  __modsi3
36         .ent    __modsi3
37         .type   __modsi3,@function
38 __modsi3:
39         .frame  r1,0,r15        
41         addik   r1,r1,-16
42         swi     r28,r1,0
43         swi     r29,r1,4
44         swi     r30,r1,8
45         swi     r31,r1,12
47         BEQI    r6,$LaDiv_By_Zero       # Div_by_Zero   # Division Error
48         BEQI    r5,$LaResult_Is_Zero    # Result is Zero 
49         BGEId   r5,$LaR5_Pos 
50         ADD     r28,r5,r0               # Get the sign of the result [ Depends only on the first arg]
51         RSUBI   r5,r5,0                 # Make r5 positive
52 $LaR5_Pos:
53         BGEI    r6,$LaR6_Pos
54         RSUBI   r6,r6,0     # Make r6 positive
55 $LaR6_Pos:
56         ADDIK   r3,r0,0      # Clear mod
57         ADDIK   r30,r0,0     # clear div
58         BLTId   r5,$LaDIV2   # If r5 is still negative (0x80000000), skip
59                              # the first bit search.
60         ADDIK   r29,r0,32    # Initialize the loop count
61    # First part try to find the first '1' in the r5
62 $LaDIV1:
63         ADD     r5,r5,r5         # left shift logical r5
64         BGEID   r5,$LaDIV1       #
65         ADDIK   r29,r29,-1
66 $LaDIV2:
67         ADD     r5,r5,r5         # left shift logical  r5 get the '1' into the Carry
68         ADDC    r3,r3,r3         # Move that bit into the Mod register
69         rSUB    r31,r6,r3        # Try to subtract (r30 a r6)
70         BLTi    r31,$LaMOD_TOO_SMALL
71         OR      r3,r0,r31       # Move the r31 to mod since the result was positive
72         ADDIK   r30,r30,1
73 $LaMOD_TOO_SMALL:
74         ADDIK   r29,r29,-1
75         BEQi    r29,$LaLOOP_END
76         ADD     r30,r30,r30         # Shift in the '1' into div
77         BRI     $LaDIV2          # Div2
78 $LaLOOP_END:
79         BGEI    r28,$LaRETURN_HERE
80         BRId    $LaRETURN_HERE
81         rsubi   r3,r3,0 # Negate the result
82 $LaDiv_By_Zero:
83 $LaResult_Is_Zero:
84         or      r3,r0,r0        # set result to 0 [Both mod as well as div are 0]
85 $LaRETURN_HERE:
86 # Restore values of CSRs and that of r3 and the divisor and the dividend
87         lwi     r28,r1,0
88         lwi     r29,r1,4
89         lwi     r30,r1,8
90         lwi     r31,r1,12
91         rtsd    r15,8
92         addik   r1,r1,16
93         .end __modsi3
94         .size   __modsi3, . - __modsi3