summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
blob: 13f701358ec604745b49478ab02ff81d720aa840 (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
//------------------------------------------------------------------------------ 
//
// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
//
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution.  The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//------------------------------------------------------------------------------


    EXPORT  __aeabi_uidiv
    EXPORT  __aeabi_uidivmod
    EXPORT  __aeabi_idiv
    EXPORT  __aeabi_idivmod
           
    AREA  Math, CODE, READONLY

;
;UINT32
;EFIAPI
;__aeabi_uidivmode (
;  IN UINT32  Dividen
;  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

;
;INT32
;EFIAPI
;__aeabi_idivmode (
;  IN INT32  Dividen
;  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