1###################################- 2# 3# Copyright (C) 2009-2014 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# udivsi3.S 27# 28# Unsigned divide operation. 29# Input : Divisor in Reg r5 30# Dividend in Reg r6 31# Output: Result in Reg r3 32# 33####################################### 34 35 .globl __udivsi3 36 .ent __udivsi3 37 .type __udivsi3,@function 38__udivsi3: 39 .frame r1,0,r15 40 41 ADDIK r1,r1,-12 42 SWI r29,r1,0 43 SWI r30,r1,4 44 SWI r31,r1,8 45 46 BEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error 47 BEQID r5,$LaResult_Is_Zero # Result is Zero 48 ADDIK r30,r0,0 # Clear mod 49 ADDIK r29,r0,32 # Initialize the loop count 50 51 # Check if r6 and r5 are equal # if yes, return 1 52 RSUB r18,r5,r6 53 BEQID r18,$LaRETURN_HERE 54 ADDIK r3,r0,1 55 56 # Check if (uns)r6 is greater than (uns)r5. In that case, just return 0 57 XOR r18,r5,r6 58 BGEID r18,16 59 ADD r3,r0,r0 # We would anyways clear r3 60 BLTI r6,$LaRETURN_HERE # r6[bit 31 = 1] hence is greater 61 BRI $LCheckr6 62 RSUB r18,r6,r5 # MICROBLAZEcmp 63 BLTI r18,$LaRETURN_HERE 64 65 # If r6 [bit 31] is set, then return result as 1 66$LCheckr6: 67 BGTI r6,$LaDIV0 68 BRID $LaRETURN_HERE 69 ADDIK r3,r0,1 70 71 # First part try to find the first '1' in the r5 72$LaDIV0: 73 BLTI r5,$LaDIV2 74$LaDIV1: 75 ADD r5,r5,r5 # left shift logical r5 76 BGTID r5,$LaDIV1 77 ADDIK r29,r29,-1 78$LaDIV2: 79 ADD r5,r5,r5 # left shift logical r5 get the '1' into the Carry 80 ADDC r30,r30,r30 # Move that bit into the Mod register 81 RSUB r31,r6,r30 # Try to subtract (r30 a r6) 82 BLTI r31,$LaMOD_TOO_SMALL 83 OR r30,r0,r31 # Move the r31 to mod since the result was positive 84 ADDIK r3,r3,1 85$LaMOD_TOO_SMALL: 86 ADDIK r29,r29,-1 87 BEQi r29,$LaLOOP_END 88 ADD r3,r3,r3 # Shift in the '1' into div 89 BRI $LaDIV2 # Div2 90$LaLOOP_END: 91 BRI $LaRETURN_HERE 92$LaDiv_By_Zero: 93$LaResult_Is_Zero: 94 OR r3,r0,r0 # set result to 0 95$LaRETURN_HERE: 96 # Restore values of CSRs and that of r3 and the divisor and the dividend 97 LWI r29,r1,0 98 LWI r30,r1,4 99 LWI r31,r1,8 100 RTSD r15,8 101 ADDIK r1,r1,12 102 .end __udivsi3 103 .size __udivsi3, . - __udivsi3 104