moddi3.S revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls ###################################
2 1.1.1.1.8.2 tls #
3 1.1.1.1.8.2 tls # Copyright (C) 2009-2013 Free Software Foundation, Inc.
4 1.1.1.1.8.2 tls #
5 1.1.1.1.8.2 tls # Contributed by Michael Eager <eager@eagercon.com>.
6 1.1.1.1.8.2 tls #
7 1.1.1.1.8.2 tls # This file is free software; you can redistribute it and/or modify it
8 1.1.1.1.8.2 tls # under the terms of the GNU General Public License as published by the
9 1.1.1.1.8.2 tls # Free Software Foundation; either version 3, or (at your option) any
10 1.1.1.1.8.2 tls # later version.
11 1.1.1.1.8.2 tls #
12 1.1.1.1.8.2 tls # GCC is distributed in the hope that it will be useful, but WITHOUT
13 1.1.1.1.8.2 tls # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1.1.1.8.2 tls # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 1.1.1.1.8.2 tls # License for more details.
16 1.1.1.1.8.2 tls #
17 1.1.1.1.8.2 tls # Under Section 7 of GPL version 3, you are granted additional
18 1.1.1.1.8.2 tls # permissions described in the GCC Runtime Library Exception, version
19 1.1.1.1.8.2 tls # 3.1, as published by the Free Software Foundation.
20 1.1.1.1.8.2 tls #
21 1.1.1.1.8.2 tls # You should have received a copy of the GNU General Public License and
22 1.1.1.1.8.2 tls # a copy of the GCC Runtime Library Exception along with this program;
23 1.1.1.1.8.2 tls # see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1.1.1.8.2 tls # <http://www.gnu.org/licenses/>.
25 1.1.1.1.8.2 tls #
26 1.1.1.1.8.2 tls # modsi3.S
27 1.1.1.1.8.2 tls #
28 1.1.1.1.8.2 tls # modulo operation for 64 bit integers.
29 1.1.1.1.8.2 tls #
30 1.1.1.1.8.2 tls #######################################
31 1.1.1.1.8.2 tls
32 1.1.1.1.8.2 tls
33 1.1.1.1.8.2 tls .globl __moddi3
34 1.1.1.1.8.2 tls .ent __moddi3
35 1.1.1.1.8.2 tls __moddi3:
36 1.1.1.1.8.2 tls .frame r1,0,r15
37 1.1.1.1.8.2 tls
38 1.1.1.1.8.2 tls #Change the stack pointer value and Save callee saved regs
39 1.1.1.1.8.2 tls addik r1,r1,-24
40 1.1.1.1.8.2 tls swi r25,r1,0
41 1.1.1.1.8.2 tls swi r26,r1,4
42 1.1.1.1.8.2 tls swi r27,r1,8 # used for sign
43 1.1.1.1.8.2 tls swi r28,r1,12 # used for loop count
44 1.1.1.1.8.2 tls swi r29,r1,16 # Used for div value High
45 1.1.1.1.8.2 tls swi r30,r1,20 # Used for div value Low
46 1.1.1.1.8.2 tls
47 1.1.1.1.8.2 tls #Check for Zero Value in the divisor/dividend
48 1.1.1.1.8.2 tls OR r9,r5,r6 # Check for the op1 being zero
49 1.1.1.1.8.2 tls BEQID r9,$LaResult_Is_Zero # Result is zero
50 1.1.1.1.8.2 tls OR r9,r7,r8 # Check for the dividend being zero
51 1.1.1.1.8.2 tls BEQI r9,$LaDiv_By_Zero # Div_by_Zero # Division Error
52 1.1.1.1.8.2 tls BGEId r5,$La1_Pos
53 1.1.1.1.8.2 tls XOR r27,r5,r7 # Get the sign of the result
54 1.1.1.1.8.2 tls RSUBI r6,r6,0 # Make dividend positive
55 1.1.1.1.8.2 tls RSUBIC r5,r5,0 # Make dividend positive
56 1.1.1.1.8.2 tls $La1_Pos:
57 1.1.1.1.8.2 tls BGEI r7,$La2_Pos
58 1.1.1.1.8.2 tls RSUBI r8,r8,0 # Make Divisor Positive
59 1.1.1.1.8.2 tls RSUBIC r9,r9,0 # Make Divisor Positive
60 1.1.1.1.8.2 tls $La2_Pos:
61 1.1.1.1.8.2 tls ADDIK r4,r0,0 # Clear mod low
62 1.1.1.1.8.2 tls ADDIK r3,r0,0 # Clear mod high
63 1.1.1.1.8.2 tls ADDIK r29,r0,0 # clear div high
64 1.1.1.1.8.2 tls ADDIK r30,r0,0 # clear div low
65 1.1.1.1.8.2 tls ADDIK r28,r0,64 # Initialize the loop count
66 1.1.1.1.8.2 tls # First part try to find the first '1' in the r5/r6
67 1.1.1.1.8.2 tls $LaDIV1:
68 1.1.1.1.8.2 tls ADD r6,r6,r6
69 1.1.1.1.8.2 tls ADDC r5,r5,r5 # left shift logical r5
70 1.1.1.1.8.2 tls BGEID r5,$LaDIV1
71 1.1.1.1.8.2 tls ADDIK r28,r28,-1
72 1.1.1.1.8.2 tls $LaDIV2:
73 1.1.1.1.8.2 tls ADD r6,r6,r6
74 1.1.1.1.8.2 tls ADDC r5,r5,r5 # left shift logical r5/r6 get the '1' into the Carry
75 1.1.1.1.8.2 tls ADDC r4,r4,r4 # Move that bit into the Mod register
76 1.1.1.1.8.2 tls ADDC r3,r3,r3 # Move carry into high mod register
77 1.1.1.1.8.2 tls rsub r18,r7,r3 # Compare the High Parts of Mod and Divisor
78 1.1.1.1.8.2 tls bnei r18,$L_High_EQ
79 1.1.1.1.8.2 tls rsub r18,r6,r4 # Compare Low Parts only if Mod[h] == Divisor[h]
80 1.1.1.1.8.2 tls $L_High_EQ:
81 1.1.1.1.8.2 tls rSUB r26,r8,r4 # Subtract divisor[L] from Mod[L]
82 1.1.1.1.8.2 tls rsubc r25,r7,r3 # Subtract divisor[H] from Mod[H]
83 1.1.1.1.8.2 tls BLTi r25,$LaMOD_TOO_SMALL
84 1.1.1.1.8.2 tls OR r3,r0,r25 # move r25 to mod [h]
85 1.1.1.1.8.2 tls OR r4,r0,r26 # move r26 to mod [l]
86 1.1.1.1.8.2 tls ADDI r30,r30,1
87 1.1.1.1.8.2 tls ADDC r29,r29,r0
88 1.1.1.1.8.2 tls $LaMOD_TOO_SMALL:
89 1.1.1.1.8.2 tls ADDIK r28,r28,-1
90 1.1.1.1.8.2 tls BEQi r28,$LaLOOP_END
91 1.1.1.1.8.2 tls ADD r30,r30,r30 # Shift in the '1' into div [low]
92 1.1.1.1.8.2 tls ADDC r29,r29,r29 # Move the carry generated into high
93 1.1.1.1.8.2 tls BRI $LaDIV2 # Div2
94 1.1.1.1.8.2 tls $LaLOOP_END:
95 1.1.1.1.8.2 tls BGEI r27,$LaRETURN_HERE
96 1.1.1.1.8.2 tls rsubi r30,r30,0
97 1.1.1.1.8.2 tls rsubc r29,r29,r0
98 1.1.1.1.8.2 tls BRI $LaRETURN_HERE
99 1.1.1.1.8.2 tls $LaDiv_By_Zero:
100 1.1.1.1.8.2 tls $LaResult_Is_Zero:
101 1.1.1.1.8.2 tls or r29,r0,r0 # set result to 0 [High]
102 1.1.1.1.8.2 tls or r30,r0,r0 # set result to 0 [Low]
103 1.1.1.1.8.2 tls $LaRETURN_HERE:
104 1.1.1.1.8.2 tls # Restore values of CSRs and that of r29 and the divisor and the dividend
105 1.1.1.1.8.2 tls
106 1.1.1.1.8.2 tls lwi r25,r1,0
107 1.1.1.1.8.2 tls lwi r26,r1,4
108 1.1.1.1.8.2 tls lwi r27,r1,8
109 1.1.1.1.8.2 tls lwi r28,r1,12
110 1.1.1.1.8.2 tls lwi r29,r1,16
111 1.1.1.1.8.2 tls lwi r30,r1,20
112 1.1.1.1.8.2 tls rtsd r15,8
113 1.1.1.1.8.2 tls addik r1,r1,24
114 1.1.1.1.8.2 tls .end __moddi3
115 1.1.1.1.8.2 tls
116