1################################### 2# 3# Copyright (C) 2009-2015 Free Software Foundation, Inc. 4# 5# Contributed by Michael Eager <eager@eagercon.com>. 6# 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. 11# 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. 16# 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. 20# 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 64 bit integers. 29# 30####################################### 31 32 33 .globl __moddi3 34 .ent __moddi3 35__moddi3: 36 .frame r1,0,r15 37 38#Change the stack pointer value and Save callee saved regs 39 addik r1,r1,-24 40 swi r25,r1,0 41 swi r26,r1,4 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 46 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 52 BGEId r5,$La1_Pos 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 56$La1_Pos: 57 BGEI r7,$La2_Pos 58 RSUBI r8,r8,0 # Make Divisor Positive 59 RSUBIC r9,r9,0 # Make Divisor Positive 60$La2_Pos: 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 67$LaDIV1: 68 ADD r6,r6,r6 69 ADDC r5,r5,r5 # left shift logical r5 70 BGEID r5,$LaDIV1 71 ADDIK r28,r28,-1 72$LaDIV2: 73 ADD r6,r6,r6 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 78 bnei r18,$L_High_EQ 79 rsub r18,r6,r4 # Compare Low Parts only if Mod[h] == Divisor[h] 80$L_High_EQ: 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] 86 ADDI r30,r30,1 87 ADDC r29,r29,r0 88$LaMOD_TOO_SMALL: 89 ADDIK r28,r28,-1 90 BEQi r28,$LaLOOP_END 91 ADD r30,r30,r30 # Shift in the '1' into div [low] 92 ADDC r29,r29,r29 # Move the carry generated into high 93 BRI $LaDIV2 # Div2 94$LaLOOP_END: 95 BGEI r27,$LaRETURN_HERE 96 rsubi r30,r30,0 97 rsubc r29,r29,r0 98 BRI $LaRETURN_HERE 99$LaDiv_By_Zero: 100$LaResult_Is_Zero: 101 or r29,r0,r0 # set result to 0 [High] 102 or r30,r0,r0 # set result to 0 [Low] 103$LaRETURN_HERE: 104# Restore values of CSRs and that of r29 and the divisor and the dividend 105 106 lwi r25,r1,0 107 lwi r26,r1,4 108 lwi r27,r1,8 109 lwi r28,r1,12 110 lwi r29,r1,16 111 lwi r30,r1,20 112 rtsd r15,8 113 addik r1,r1,24 114 .end __moddi3 115 116