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