Merge tag 'locking-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux/fpc-iii.git] / arch / h8300 / lib / udivsi3.S
blobb810aba8e1009603c5cf07b88ad3c5ebd3333f4b
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include "libgcc.h"
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
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
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
77         .end