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# umodsi3.S 27# 28# Unsigned modulo operation for 32 bit integers. 29# Input : op1 in Reg r5 30# op2 in Reg r6 31# Output: op1 mod op2 in Reg r3 32# 33####################################### 34 35 .globl __umodsi3 36 .ent __umodsi3 37 .type __umodsi3,@function 38__umodsi3: 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 r3,r0,0 # Clear div 49 ADDIK r30,r0,0 # clear mod 50 ADDIK r29,r0,32 # Initialize the loop count 51 52# Check if r6 and r5 are equal # if yes, return 0 53 rsub r18,r5,r6 54 beqi r18,$LaRETURN_HERE 55 56# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5 57 xor r18,r5,r6 58 bgeid r18,16 59 addik r3,r5,0 60 blti r6,$LaRETURN_HERE 61 bri $LCheckr6 62 rsub r18,r5,r6 # MICROBLAZEcmp 63 bgti r18,$LaRETURN_HERE 64 65# If r6 [bit 31] is set, then return result as r5-r6 66$LCheckr6: 67 bgtid r6,$LaDIV0 68 addik r3,r0,0 69 addik r18,r0,0x7fffffff 70 and r5,r5,r18 71 and r6,r6,r18 72 brid $LaRETURN_HERE 73 rsub r3,r6,r5 74# First part: try to find the first '1' in the r5 75$LaDIV0: 76 BLTI r5,$LaDIV2 77$LaDIV1: 78 ADD r5,r5,r5 # left shift logical r5 79 BGEID r5,$LaDIV1 # 80 ADDIK r29,r29,-1 81$LaDIV2: 82 ADD r5,r5,r5 # left shift logical r5 get the '1' into the Carry 83 ADDC r3,r3,r3 # Move that bit into the Mod register 84 rSUB r31,r6,r3 # Try to subtract (r3 a r6) 85 BLTi r31,$LaMOD_TOO_SMALL 86 OR r3,r0,r31 # Move the r31 to mod since the result was positive 87 ADDIK r30,r30,1 88$LaMOD_TOO_SMALL: 89 ADDIK r29,r29,-1 90 BEQi r29,$LaLOOP_END 91 ADD r30,r30,r30 # Shift in the '1' into div 92 BRI $LaDIV2 # Div2 93$LaLOOP_END: 94 BRI $LaRETURN_HERE 95$LaDiv_By_Zero: 96$LaResult_Is_Zero: 97 or r3,r0,r0 # set result to 0 98$LaRETURN_HERE: 99# Restore values of CSRs and that of r3 and the divisor and the dividend 100 lwi r29,r1,0 101 lwi r30,r1,4 102 lwi r31,r1,8 103 rtsd r15,8 104 addik r1,r1,12 105.end __umodsi3 106 .size __umodsi3, . - __umodsi3 107