1 ###################################
3 # Copyright
2009, 2010 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
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
/>.
28 # modulo operation for
64 bit integers.
30 #######################################
38 #Change the stack pointer value
and Save callee saved regs
42 swi r27
,r1
,8 # used for sign
43 swi r28
,r1
,12 # used for
loop count
44 swi r29
,r1
,16 # Used for
div value
High
45 swi r30
,r1
,20 # Used for
div value
Low
47 #Check for Zero Value
in the divisor
/dividend
48 OR r9
,r5
,r6 # Check for the op1 being zero
49 BEQID r9
,$LaResult_Is_Zero # Result is zero
50 OR r9
,r7
,r8 # Check for the dividend being zero
51 BEQI r9
,$LaDiv_By_Zero # Div_by_Zero # Division Error
53 XOR r27
,r5
,r7 # Get the sign of the result
54 RSUBI r6
,r6
,0 # Make dividend positive
55 RSUBIC r5
,r5
,0 # Make dividend positive
58 RSUBI r8
,r8
,0 # Make Divisor Positive
59 RSUBIC r9
,r9
,0 # Make Divisor Positive
61 ADDIK r4
,r0
,0 # Clear
mod low
62 ADDIK r3
,r0
,0 # Clear
mod high
63 ADDIK r29
,r0
,0 # clear
div high
64 ADDIK r30
,r0
,0 # clear
div low
65 ADDIK r28
,r0
,64 # Initialize the
loop count
66 # First part try to find the first
'1' in the r5
/r6
69 ADDC r5
,r5
,r5 # left shift logical r5
74 ADDC r5
,r5
,r5 # left shift logical r5
/r6 get the
'1' into the Carry
75 ADDC r4
,r4
,r4 # Move that bit
into the
Mod register
76 ADDC r3
,r3
,r3 # Move carry
into high mod register
77 rsub r18
,r7
,r3 # Compare the
High Parts of
Mod and Divisor
79 rsub r18
,r6
,r4 # Compare
Low Parts only if
Mod[h
] == Divisor
[h
]
81 rSUB r26
,r8
,r4 # Subtract divisor
[L
] from
Mod[L
]
82 rsubc r25
,r7
,r3 # Subtract divisor
[H
] from
Mod[H
]
83 BLTi r25
,$LaMOD_TOO_SMALL
84 OR r3
,r0
,r25 # move r25 to
mod [h
]
85 OR r4
,r0
,r26 # move r26 to
mod [l
]
91 ADD r30
,r30
,r30 # Shift
in the
'1' into div [low]
92 ADDC r29
,r29
,r29 # Move the carry generated
into high
95 BGEI r27
,$LaRETURN_HERE
101 or r29
,r0
,r0 # set result to
0 [High]
102 or r30
,r0
,r0 # set result to
0 [Low]
104 # Restore values of CSRs
and that of r29
and the divisor
and the dividend