#include <linux/linkage.h>12/*3* Unsigned divide operation.4* Input : Divisor in Reg r55* Dividend in Reg r66* Output: Result in Reg r37*/89.text10.globl __udivsi311.type __udivsi3, @function12.ent __udivsi31314__udivsi3:1516.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 r30, r0, 0 /* clear mod */26addik r29, r0, 32 /* initialize the loop count */2728/* check if r6 and r5 are equal - if yes, return 1 */29rsub r18, r5, r630beqid r18, return_here31addik r3, r0, 13233/* check if (uns)r6 is greater than (uns)r5. in that case, just return 0 */34xor r18, r5, r635bgeid r18, 1636add r3, r0, r0 /* we would anyways clear r3 */37blti r6, return_here /* r6[bit 31 = 1] hence is greater */38bri checkr639rsub r18, r6, r5 /* microblazecmp */40blti r18, return_here4142/* if r6 [bit 31] is set, then return result as 1 */43checkr6:44bgti r6, div045brid return_here46addik r3, r0, 14748/* first part try to find the first '1' in the r5 */49div0:50blti r5, div251div1:52add r5, r5, r5 /* left shift logical r5 */53bgtid r5, div154addik r29, r29, -155div2:56/* left shift logical r5 get the '1' into the carry */57add r5, r5, r558addc r30, r30, r30 /* move that bit into the mod register */59rsub r31, r6, r30 /* try to subtract (r30 a r6) */60blti r31, mod_too_small61/* move the r31 to mod since the result was positive */62or r30, r0, r3163addik r3, r3, 164mod_too_small:65addik r29, r29, -166beqi r29, loop_end67add r3, r3, r3 /* shift in the '1' into div */68bri div2 /* div2 */69loop_end:70bri return_here71div_by_zero:72result_is_zero:73or r3, r0, r0 /* set result to 0 */74return_here:75/* restore values of csrs and that of r3 and the divisor and the dividend */76lwi r29, r1, 077lwi r30, r1, 478lwi r31, r1, 879rtsd r15, 880addik r1, r1, 128182.size __udivsi3, . - __udivsi383.end __udivsi3848586