1################################### 2# 3# Copyright (C) 2009-2022 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 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 __modsi3 42 .ent __modsi3 43 .type __modsi3,@function 44__modsi3: 45 .frame r1,0,r15 46 47 addik r1,r1,-16 48 swi r28,r1,0 49 swi r29,r1,4 50 swi r30,r1,8 51 swi r31,r1,12 52 53 BEQI r6,$LaDiv_By_Zero # Div_by_Zero # Division Error 54 BEQI r5,$LaResult_Is_Zero # Result is Zero 55 BGEId r5,$LaR5_Pos 56 ADD r28,r5,r0 # Get the sign of the result [ Depends only on the first arg] 57 RSUBI r5,r5,0 # Make r5 positive 58$LaR5_Pos: 59 BGEI r6,$LaR6_Pos 60 RSUBI r6,r6,0 # Make r6 positive 61$LaR6_Pos: 62 ADDIK r3,r0,0 # Clear mod 63 ADDIK r30,r0,0 # clear div 64 BLTId r5,$LaDIV2 # If r5 is still negative (0x80000000), skip 65 # the first bit search. 66 ADDIK r29,r0,32 # Initialize the loop count 67 # First part try to find the first '1' in the r5 68$LaDIV1: 69 ADD r5,r5,r5 # left shift logical r5 70 BGEID r5,$LaDIV1 # 71 ADDIK r29,r29,-1 72$LaDIV2: 73 ADD r5,r5,r5 # left shift logical r5 get the '1' into the Carry 74 ADDC r3,r3,r3 # Move that bit into the Mod register 75 rSUB r31,r6,r3 # Try to subtract (r30 a r6) 76 BLTi r31,$LaMOD_TOO_SMALL 77 OR r3,r0,r31 # Move the r31 to mod since the result was positive 78 ADDIK r30,r30,1 79$LaMOD_TOO_SMALL: 80 ADDIK r29,r29,-1 81 BEQi r29,$LaLOOP_END 82 ADD r30,r30,r30 # Shift in the '1' into div 83 BRI $LaDIV2 # Div2 84$LaLOOP_END: 85 BGEI r28,$LaRETURN_HERE 86 BRId $LaRETURN_HERE 87 rsubi r3,r3,0 # Negate the result 88$LaDiv_By_Zero: 89$LaResult_Is_Zero: 90 or r3,r0,r0 # set result to 0 [Both mod as well as div are 0] 91$LaRETURN_HERE: 92# Restore values of CSRs and that of r3 and the divisor and the dividend 93 lwi r28,r1,0 94 lwi r29,r1,4 95 lwi r30,r1,8 96 lwi r31,r1,12 97 rtsd r15,8 98 addik r1,r1,16 99 .end __modsi3 100 .size __modsi3, . - __modsi3 101 102