1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun#include "libgcc.h" 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun ;; This function also computes the remainder and stores it in er3. 5*4882a593Smuzhiyun .global __udivsi3 6*4882a593Smuzhiyun__udivsi3: 7*4882a593Smuzhiyun mov.w A1E,A1E ; denominator top word 0? 8*4882a593Smuzhiyun bne DenHighNonZero 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun ; do it the easy way, see page 107 in manual 11*4882a593Smuzhiyun mov.w A0E,A2 12*4882a593Smuzhiyun extu.l A2P 13*4882a593Smuzhiyun divxu.w A1,A2P 14*4882a593Smuzhiyun mov.w A2E,A0E 15*4882a593Smuzhiyun divxu.w A1,A0P 16*4882a593Smuzhiyun mov.w A0E,A3 17*4882a593Smuzhiyun mov.w A2,A0E 18*4882a593Smuzhiyun extu.l A3P 19*4882a593Smuzhiyun rts 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun ; er0 = er0 / er1 22*4882a593Smuzhiyun ; er3 = er0 % er1 23*4882a593Smuzhiyun ; trashes er1 er2 24*4882a593Smuzhiyun ; expects er1 >= 2^16 25*4882a593SmuzhiyunDenHighNonZero: 26*4882a593Smuzhiyun mov.l er0,er3 27*4882a593Smuzhiyun mov.l er1,er2 28*4882a593Smuzhiyun#ifdef CONFIG_CPU_H8300H 29*4882a593Smuzhiyundivmod_L21: 30*4882a593Smuzhiyun shlr.l er0 31*4882a593Smuzhiyun shlr.l er2 ; make divisor < 2^16 32*4882a593Smuzhiyun mov.w e2,e2 33*4882a593Smuzhiyun bne divmod_L21 34*4882a593Smuzhiyun#else 35*4882a593Smuzhiyun shlr.l #2,er2 ; make divisor < 2^16 36*4882a593Smuzhiyun mov.w e2,e2 37*4882a593Smuzhiyun beq divmod_L22A 38*4882a593Smuzhiyundivmod_L21: 39*4882a593Smuzhiyun shlr.l #2,er0 40*4882a593Smuzhiyundivmod_L22: 41*4882a593Smuzhiyun shlr.l #2,er2 ; make divisor < 2^16 42*4882a593Smuzhiyun mov.w e2,e2 43*4882a593Smuzhiyun bne divmod_L21 44*4882a593Smuzhiyundivmod_L22A: 45*4882a593Smuzhiyun rotxl.w r2 46*4882a593Smuzhiyun bcs divmod_L23 47*4882a593Smuzhiyun shlr.l er0 48*4882a593Smuzhiyun bra divmod_L24 49*4882a593Smuzhiyundivmod_L23: 50*4882a593Smuzhiyun rotxr.w r2 51*4882a593Smuzhiyun shlr.l #2,er0 52*4882a593Smuzhiyundivmod_L24: 53*4882a593Smuzhiyun#endif 54*4882a593Smuzhiyun ;; At this point, 55*4882a593Smuzhiyun ;; er0 contains shifted dividend 56*4882a593Smuzhiyun ;; er1 contains divisor 57*4882a593Smuzhiyun ;; er2 contains shifted divisor 58*4882a593Smuzhiyun ;; er3 contains dividend, later remainder 59*4882a593Smuzhiyun divxu.w r2,er0 ; r0 now contains the approximate quotient (AQ) 60*4882a593Smuzhiyun extu.l er0 61*4882a593Smuzhiyun beq divmod_L25 62*4882a593Smuzhiyun subs #1,er0 ; er0 = AQ - 1 63*4882a593Smuzhiyun mov.w e1,r2 64*4882a593Smuzhiyun mulxu.w r0,er2 ; er2 = upper (AQ - 1) * divisor 65*4882a593Smuzhiyun sub.w r2,e3 ; dividend - 65536 * er2 66*4882a593Smuzhiyun mov.w r1,r2 67*4882a593Smuzhiyun mulxu.w r0,er2 ; compute er3 = remainder (tentative) 68*4882a593Smuzhiyun sub.l er2,er3 ; er3 = dividend - (AQ - 1) * divisor 69*4882a593Smuzhiyundivmod_L25: 70*4882a593Smuzhiyun cmp.l er1,er3 ; is divisor < remainder? 71*4882a593Smuzhiyun blo divmod_L26 72*4882a593Smuzhiyun adds #1,er0 73*4882a593Smuzhiyun sub.l er1,er3 ; correct the remainder 74*4882a593Smuzhiyundivmod_L26: 75*4882a593Smuzhiyun rts 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun .end 78