/* SPDX-License-Identifier: GPL-2.0 */1#include <linux/linkage.h>23/*4* Unsigned modulo operation for 32 bit integers.5* Input : op1 in Reg r56* op2 in Reg r67* Output: op1 mod op2 in Reg r38*/910.text11.globl __umodsi312.type __umodsi3, @function13.ent __umodsi31415__umodsi3:16.frame r1, 0, r151718addik r1, r1, -1219swi r29, r1, 020swi r30, r1, 421swi r31, r1, 82223beqi r6, div_by_zero /* div_by_zero - division error */24beqid r5, result_is_zero /* result is zero */25addik r3, r0, 0 /* clear div */26addik r30, r0, 0 /* clear mod */27addik r29, r0, 32 /* initialize the loop count */2829/* check if r6 and r5 are equal /* if yes, return 0 */30rsub r18, r5, r631beqi r18, return_here3233/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */34xor r18, r5, r635bgeid r18, 1636addik r3, r5, 037blti r6, return_here38bri $lcheckr639rsub r18, r5, r6 /* microblazecmp */40bgti r18, return_here4142/* if r6 [bit 31] is set, then return result as r5-r6 */43$lcheckr6:44bgtid r6, div045addik r3, r0, 046addik r18, r0, 0x7fffffff47and r5, r5, r1848and r6, r6, r1849brid return_here50rsub r3, r6, r551/* first part: try to find the first '1' in the r5 */52div0:53blti r5, div254div1:55add r5, r5, r5 /* left shift logical r5 */56bgeid r5, div157addik r29, r29, -158div2:59/* left shift logical r5 get the '1' into the carry */60add r5, r5, r561addc r3, r3, r3 /* move that bit into the mod register */62rsub r31, r6, r3 /* try to subtract (r3 a r6) */63blti r31, mod_too_small64/* move the r31 to mod since the result was positive */65or r3, r0, r3166addik r30, r30, 167mod_too_small:68addik r29, r29, -169beqi r29, loop_end70add r30, r30, r30 /* shift in the '1' into div */71bri div2 /* div2 */72loop_end:73bri return_here74div_by_zero:75result_is_zero:76or r3, r0, r0 /* set result to 0 */77return_here:78/* restore values of csrs and that of r3 and the divisor and the dividend */79lwi r29, r1, 080lwi r30, r1, 481lwi r31, r1, 882rtsd r15, 883addik r1, r1, 128485.size __umodsi3, . - __umodsi386.end __umodsi3878889