root/arch/h8300/lib/udivsi3.S

/* [<][>][^][v][top][bottom][index][help] */
   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

/* [<][>][^][v][top][bottom][index][help] */