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