linux/arch/h8300/lib/udivsi3.S
<<
>>
Prefs
   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
  25DenHighNonZero:
  26        mov.l   er0,er3
  27        mov.l   er1,er2
  28#ifdef CONFIG_CPU_H8300H
  29divmod_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
  38divmod_L21:
  39        shlr.l  #2,er0
  40divmod_L22:
  41        shlr.l  #2,er2          ; make divisor < 2^16
  42        mov.w   e2,e2
  43        bne     divmod_L21
  44divmod_L22A:
  45        rotxl.w r2
  46        bcs     divmod_L23
  47        shlr.l  er0
  48        bra     divmod_L24
  49divmod_L23:
  50        rotxr.w r2
  51        shlr.l  #2,er0
  52divmod_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
  69divmod_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
  74divmod_L26:
  75        rts
  76
  77        .end
  78