1################################### 2# 3# Copyright (C) 2009-2019 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/* An executable stack is *not* required for these functions. */ 36#ifdef __linux__ 37.section .note.GNU-stack,"",%progbits 38.previous 39#endif 40 41 .globl __umodsi3 42 .ent __umodsi3 43 .type __umodsi3,@function 44__umodsi3: 45 .frame r1,0,r15 46 47 addik r1,r1,-12 48 swi r29,r1,0 49 swi r30,r1,4 50 swi r31,r1,8 51 52 BEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error 53 BEQId r5,$LaResult_Is_Zero # Result is Zero 54 ADDIK r3,r0,0 # Clear div 55 ADDIK r30,r0,0 # clear mod 56 ADDIK r29,r0,32 # Initialize the loop count 57 58# Check if r6 and r5 are equal # if yes, return 0 59 rsub r18,r5,r6 60 beqi r18,$LaRETURN_HERE 61 62# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5 63 xor r18,r5,r6 64 bgeid r18,16 65 addik r3,r5,0 66 blti r6,$LaRETURN_HERE 67 bri $LCheckr6 68 rsub r18,r5,r6 # MICROBLAZEcmp 69 bgti r18,$LaRETURN_HERE 70 71# If r6 [bit 31] is set, then return result as r5-r6 72$LCheckr6: 73 bgtid r6,$LaDIV0 74 addik r3,r0,0 75 addik r18,r0,0x7fffffff 76 and r5,r5,r18 77 and r6,r6,r18 78 brid $LaRETURN_HERE 79 rsub r3,r6,r5 80# First part: try to find the first '1' in the r5 81$LaDIV0: 82 BLTI r5,$LaDIV2 83$LaDIV1: 84 ADD r5,r5,r5 # left shift logical r5 85 BGEID r5,$LaDIV1 # 86 ADDIK r29,r29,-1 87$LaDIV2: 88 ADD r5,r5,r5 # left shift logical r5 get the '1' into the Carry 89 ADDC r3,r3,r3 # Move that bit into the Mod register 90 rSUB r31,r6,r3 # Try to subtract (r3 a r6) 91 BLTi r31,$LaMOD_TOO_SMALL 92 OR r3,r0,r31 # Move the r31 to mod since the result was positive 93 ADDIK r30,r30,1 94$LaMOD_TOO_SMALL: 95 ADDIK r29,r29,-1 96 BEQi r29,$LaLOOP_END 97 ADD r30,r30,r30 # Shift in the '1' into div 98 BRI $LaDIV2 # Div2 99$LaLOOP_END: 100 BRI $LaRETURN_HERE 101$LaDiv_By_Zero: 102$LaResult_Is_Zero: 103 or r3,r0,r0 # set result to 0 104$LaRETURN_HERE: 105# Restore values of CSRs and that of r3 and the divisor and the dividend 106 lwi r29,r1,0 107 lwi r30,r1,4 108 lwi r31,r1,8 109 rtsd r15,8 110 addik r1,r1,12 111.end __umodsi3 112 .size __umodsi3, . - __umodsi3 113