/* SPDX-License-Identifier: GPL-2.0 */1#include <linux/linkage.h>23/*4* Unsigned divide operation.5* Input : Divisor in Reg r56* Dividend in Reg r67* Output: Result in Reg r38*/910.text11.globl __udivsi312.type __udivsi3, @function13.ent __udivsi31415__udivsi3:1617.frame r1, 0, r151819addik r1, r1, -1220swi r29, r1, 021swi r30, r1, 422swi r31, r1, 82324beqi r6, div_by_zero /* div_by_zero /* division error */25beqid r5, result_is_zero /* result is zero */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 1 */30rsub r18, r5, r631beqid r18, return_here32addik r3, r0, 13334/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */35xor r18, r5, r636bgeid r18, 1637add r3, r0, r0 /* we would anyways clear r3 */38blti r6, return_here /* r6[bit 31 = 1] hence is greater */39bri checkr640rsub r18, r6, r5 /* microblazecmp */41blti r18, return_here4243/* if r6 [bit 31] is set, then return result as 1 */44checkr6:45bgti r6, div046brid return_here47addik r3, r0, 14849/* first part try to find the first '1' in the r5 */50div0:51blti r5, div252div1:53add r5, r5, r5 /* left shift logical r5 */54bgtid r5, div155addik r29, r29, -156div2:57/* left shift logical r5 get the '1' into the carry */58add r5, r5, r559addc r30, r30, r30 /* move that bit into the mod register */60rsub r31, r6, r30 /* try to subtract (r30 a r6) */61blti r31, mod_too_small62/* move the r31 to mod since the result was positive */63or r30, r0, r3164addik r3, r3, 165mod_too_small:66addik r29, r29, -167beqi r29, loop_end68add r3, r3, r3 /* shift in the '1' into div */69bri div2 /* div2 */70loop_end:71bri return_here72div_by_zero:73result_is_zero:74or r3, r0, r0 /* set result to 0 */75return_here:76/* restore values of csrs and that of r3 and the divisor and the dividend */77lwi r29, r1, 078lwi r30, r1, 479lwi r31, r1, 880rtsd r15, 881addik r1, r1, 128283.size __udivsi3, . - __udivsi384.end __udivsi3858687