summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
blob: 3cbeaa4c1b50f465ca6c2b8414a45b590a943ab7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//------------------------------------------------------------------------------
//
// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
// Copyright (c) 2018, Pete Batard. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------


    EXPORT  __aeabi_uidiv
    EXPORT  __aeabi_uidivmod
    EXPORT  __aeabi_idiv
    EXPORT  __aeabi_idivmod
    EXPORT  __rt_udiv
    EXPORT  __rt_sdiv

    AREA  Math, CODE, READONLY

;
;UINT32
;EFIAPI
;__aeabi_uidivmod (
;  IN UINT32  Dividend
;  IN UINT32  Divisor
;  );
;
__aeabi_uidiv
__aeabi_uidivmod
    RSBS    r12, r1, r0, LSR #4
    MOV     r2, #0
    BCC     __arm_div4
    RSBS    r12, r1, r0, LSR #8
    BCC     __arm_div8
    MOV     r3, #0
    B       __arm_div_large

;
;UINT64
;EFIAPI
;__rt_udiv (
;  IN UINT32  Divisor,
;  IN UINT32  Dividend
;  );
;
__rt_udiv
    ; Swap R0 and R1
    MOV     r12, r0
    MOV     r0, r1
    MOV     r1, r12
    B       __aeabi_uidivmod

;
;UINT64
;EFIAPI
;__rt_sdiv (
;  IN INT32  Divisor,
;  IN INT32  Dividend
;  );
;
__rt_sdiv
    ; Swap R0 and R1
    MOV     r12, r0
    MOV     r0, r1
    MOV     r1, r12
    B       __aeabi_idivmod

;
;INT32
;EFIAPI
;__aeabi_idivmod (
;  IN INT32  Dividend
;  IN INT32  Divisor
;  );
;
__aeabi_idiv
__aeabi_idivmod
    ORRS    r12, r0, r1
    BMI     __arm_div_negative
    RSBS    r12, r1, r0, LSR #1
    MOV     r2, #0
    BCC     __arm_div1
    RSBS    r12, r1, r0, LSR #4
    BCC     __arm_div4
    RSBS    r12, r1, r0, LSR #8
    BCC     __arm_div8
    MOV     r3, #0
    B       __arm_div_large
__arm_div8
    RSBS    r12, r1, r0, LSR #7
    SUBCS   r0, r0, r1, LSL #7
    ADC     r2, r2, r2
    RSBS    r12, r1, r0,LSR #6
    SUBCS   r0, r0, r1, LSL #6
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #5
    SUBCS   r0, r0, r1, LSL #5
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #4
    SUBCS   r0, r0, r1, LSL #4
    ADC     r2, r2, r2
__arm_div4
    RSBS    r12, r1, r0, LSR #3
    SUBCS   r0, r0, r1, LSL #3
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #2
    SUBCS   r0, r0, r1, LSL #2
    ADCS    r2, r2, r2
    RSBS    r12, r1, r0, LSR #1
    SUBCS   r0, r0, r1, LSL #1
    ADC     r2, r2, r2
__arm_div1
    SUBS    r1, r0, r1
    MOVCC   r1, r0
    ADC     r0, r2, r2
    BX      r14
__arm_div_negative
    ANDS    r2, r1, #0x80000000
    RSBMI   r1, r1, #0
    EORS    r3, r2, r0, ASR #32
    RSBCS   r0, r0, #0
    RSBS    r12, r1, r0, LSR #4
    BCC     label1
    RSBS    r12, r1, r0, LSR #8
    BCC     label2
__arm_div_large
    LSL     r1, r1, #6
    RSBS    r12, r1, r0, LSR #8
    ORR     r2, r2, #0xfc000000
    BCC     label2
    LSL     r1, r1, #6
    RSBS    r12, r1, r0, LSR #8
    ORR     r2, r2, #0x3f00000
    BCC     label2
    LSL     r1, r1, #6
    RSBS    r12, r1, r0, LSR #8
    ORR     r2, r2, #0xfc000
    ORRCS   r2, r2, #0x3f00
    LSLCS   r1, r1, #6
    RSBS    r12, r1, #0
    BCS     __aeabi_idiv0
label3
    LSRCS   r1, r1, #6
label2
    RSBS    r12, r1, r0, LSR #7
    SUBCS   r0, r0, r1, LSL #7
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #6
    SUBCS   r0, r0, r1, LSL #6
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #5
    SUBCS   r0, r0, r1, LSL #5
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #4
    SUBCS   r0, r0, r1, LSL #4
    ADC     r2, r2, r2
label1
    RSBS    r12, r1, r0, LSR #3
    SUBCS   r0, r0, r1, LSL #3
    ADC     r2, r2, r2
    RSBS    r12, r1, r0, LSR #2
    SUBCS   r0, r0, r1, LSL #2
    ADCS    r2, r2, r2
    BCS     label3
    RSBS    r12, r1, r0, LSR #1
    SUBCS   r0, r0, r1, LSL #1
    ADC     r2, r2, r2
    SUBS    r1, r0, r1
    MOVCC   r1, r0
    ADC     r0, r2, r2
    ASRS    r3, r3, #31
    RSBMI   r0, r0, #0
    RSBCS   r1, r1, #0
    BX      r14

    ; What to do about division by zero?  For now, just return.
__aeabi_idiv0
    BX      r14

    END