Enable no-exec stacks for more targets using the Linux kernel.
[official-gcc.git] / libgcc / config / microblaze / moddi3.S
blob7d2a31d124e1938821788bfb4e430bc3ee87e231
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/>. 
26 #  modsi3.S
27
28 #  modulo operation for 64 bit integers.
29
30 #######################################
33 /* An executable stack is *not* required for these functions.  */
34 #ifdef __linux__
35 .section .note.GNU-stack,"",%progbits
36 .previous
37 #endif
39         .globl  __moddi3
40         .ent    __moddi3
41 __moddi3:
42         .frame  r1,0,r15        
44 #Change the stack pointer value and Save callee saved regs
45         addik   r1,r1,-24
46         swi     r25,r1,0
47         swi     r26,r1,4
48         swi     r27,r1,8        # used for sign
49         swi     r28,r1,12       # used for loop count
50         swi     r29,r1,16       # Used for div value High
51         swi     r30,r1,20       # Used for div value Low
53 #Check for Zero Value in the divisor/dividend
54         OR      r9,r5,r6                        # Check for the op1 being zero
55         BEQID   r9,$LaResult_Is_Zero            # Result is zero
56         OR      r9,r7,r8                        # Check for the dividend being zero
57         BEQI    r9,$LaDiv_By_Zero               # Div_by_Zero   # Division Error
58         BGEId   r5,$La1_Pos 
59         XOR     r27,r5,r7                       # Get the sign of the result
60         RSUBI   r6,r6,0                         # Make dividend positive
61         RSUBIC  r5,r5,0                         # Make dividend positive
62 $La1_Pos:
63         BGEI    r7,$La2_Pos
64         RSUBI   r8,r8,0                         # Make Divisor Positive
65         RSUBIC  r9,r9,0                         # Make Divisor Positive
66 $La2_Pos:
67         ADDIK   r4,r0,0                         # Clear mod low
68         ADDIK   r3,r0,0                         # Clear mod high
69         ADDIK   r29,r0,0                        # clear div high
70         ADDIK   r30,r0,0                        # clear div low
71         ADDIK   r28,r0,64                       # Initialize the loop count
72    # First part try to find the first '1' in the r5/r6
73 $LaDIV1:
74         ADD     r6,r6,r6
75         ADDC    r5,r5,r5                        # left shift logical r5
76         BGEID   r5,$LaDIV1                      
77         ADDIK   r28,r28,-1
78 $LaDIV2:
79         ADD     r6,r6,r6
80         ADDC    r5,r5,r5        # left shift logical r5/r6 get the '1' into the Carry
81         ADDC    r4,r4,r4        # Move that bit into the Mod register
82         ADDC    r3,r3,r3        # Move carry into high mod register
83         rsub    r18,r7,r3       # Compare the High Parts of Mod and Divisor
84         bnei    r18,$L_High_EQ
85         rsub    r18,r6,r4       # Compare Low Parts only if Mod[h] == Divisor[h]
86 $L_High_EQ:     
87         rSUB    r26,r8,r4       # Subtract divisor[L] from Mod[L]
88         rsubc   r25,r7,r3       # Subtract divisor[H] from Mod[H]
89         BLTi    r25,$LaMOD_TOO_SMALL
90         OR      r3,r0,r25       # move r25 to mod [h]
91         OR      r4,r0,r26       # move r26 to mod [l]
92         ADDI    r30,r30,1
93         ADDC    r29,r29,r0
94 $LaMOD_TOO_SMALL:
95         ADDIK   r28,r28,-1
96         BEQi    r28,$LaLOOP_END
97         ADD     r30,r30,r30             # Shift in the '1' into div [low]
98         ADDC    r29,r29,r29             # Move the carry generated into high
99         BRI     $LaDIV2   # Div2
100 $LaLOOP_END:
101         BGEI    r27,$LaRETURN_HERE
102         rsubi   r30,r30,0
103         rsubc   r29,r29,r0
104         BRI     $LaRETURN_HERE
105 $LaDiv_By_Zero:
106 $LaResult_Is_Zero:
107         or      r29,r0,r0       # set result to 0 [High]
108         or      r30,r0,r0       # set result to 0 [Low]
109 $LaRETURN_HERE:
110 # Restore values of CSRs and that of r29 and the divisor and the dividend
111         
112         lwi     r25,r1,0
113         lwi     r26,r1,4
114         lwi     r27,r1,8
115         lwi     r28,r1,12
116         lwi     r29,r1,16
117         lwi     r30,r1,20
118         rtsd    r15,8
119         addik r1,r1,24
120         .end __moddi3
121