xref: /DragonStub/lib/arm/div.S (revision 9485c65f6d28b71ff697849c1c8d47fd077ccd07)
1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2011, ARM. All rights reserved.<BR>
4#
5# This program and the accompanying materials
6# are licensed and made available under the terms and conditions of the BSD License
7# which accompanies this distribution.  The full text of the license may be found at
8# http://opensource.org/licenses/bsd-license.php
9#
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12#
13#------------------------------------------------------------------------------
14
15#include "edk2asm.h"
16
17.text
18.align 2
19GCC_ASM_EXPORT(__aeabi_uidiv)
20GCC_ASM_EXPORT(__aeabi_uidivmod)
21GCC_ASM_EXPORT(__aeabi_idiv)
22GCC_ASM_EXPORT(__aeabi_idivmod)
23
24#    AREA  Math, CODE, READONLY
25
26#
27#UINT32
28#EFIAPI
29#__aeabi_uidivmode (
30#  IN UINT32  Dividen
31#  IN UINT32  Divisor
32#  );
33#
34
35ASM_PFX(__aeabi_uidiv):
36ASM_PFX(__aeabi_uidivmod):
37  rsbs    r12, r1, r0, LSR #4
38  mov     r2, #0
39  bcc     ASM_PFX(__arm_div4)
40  rsbs    r12, r1, r0, LSR #8
41  bcc     ASM_PFX(__arm_div8)
42  mov     r3, #0
43  b       ASM_PFX(__arm_div_large)
44
45#
46#INT32
47#EFIAPI
48#__aeabi_idivmode (
49#  IN INT32  Dividen
50#  IN INT32  Divisor
51#  );
52#
53ASM_PFX(__aeabi_idiv):
54ASM_PFX(__aeabi_idivmod):
55  orrs    r12, r0, r1
56  bmi     ASM_PFX(__arm_div_negative)
57  rsbs    r12, r1, r0, LSR #1
58  mov     r2, #0
59  bcc     ASM_PFX(__arm_div1)
60  rsbs    r12, r1, r0, LSR #4
61  bcc     ASM_PFX(__arm_div4)
62  rsbs    r12, r1, r0, LSR #8
63  bcc     ASM_PFX(__arm_div8)
64  mov     r3, #0
65  b       ASM_PFX(__arm_div_large)
66ASM_PFX(__arm_div8):
67  rsbs    r12, r1, r0, LSR #7
68  subcs   r0, r0, r1, LSL #7
69  adc     r2, r2, r2
70  rsbs    r12, r1, r0,LSR #6
71  subcs   r0, r0, r1, LSL #6
72  adc     r2, r2, r2
73  rsbs    r12, r1, r0, LSR #5
74  subcs   r0, r0, r1, LSL #5
75  adc     r2, r2, r2
76  rsbs    r12, r1, r0, LSR #4
77  subcs   r0, r0, r1, LSL #4
78  adc     r2, r2, r2
79ASM_PFX(__arm_div4):
80  rsbs    r12, r1, r0, LSR #3
81  subcs   r0, r0, r1, LSL #3
82  adc     r2, r2, r2
83  rsbs    r12, r1, r0, LSR #2
84  subcs   r0, r0, r1, LSL #2
85  adcs    r2, r2, r2
86  rsbs    r12, r1, r0, LSR #1
87  subcs   r0, r0, r1, LSL #1
88  adc     r2, r2, r2
89ASM_PFX(__arm_div1):
90  subs    r1, r0, r1
91  movcc   r1, r0
92  adc     r0, r2, r2
93  bx      r14
94ASM_PFX(__arm_div_negative):
95  ands    r2, r1, #0x80000000
96  rsbmi   r1, r1, #0
97  eors    r3, r2, r0, ASR #32
98  rsbcs   r0, r0, #0
99  rsbs    r12, r1, r0, LSR #4
100  bcc     label1
101  rsbs    r12, r1, r0, LSR #8
102  bcc     label2
103ASM_PFX(__arm_div_large):
104  lsl     r1, r1, #6
105  rsbs    r12, r1, r0, LSR #8
106  orr     r2, r2, #0xfc000000
107  bcc     label2
108  lsl     r1, r1, #6
109  rsbs    r12, r1, r0, LSR #8
110  orr     r2, r2, #0x3f00000
111  bcc     label2
112  lsl     r1, r1, #6
113  rsbs    r12, r1, r0, LSR #8
114  orr     r2, r2, #0xfc000
115  orrcs   r2, r2, #0x3f00
116  lslcs   r1, r1, #6
117  rsbs    r12, r1, #0
118  bcs     ASM_PFX(__aeabi_idiv0)
119label3:
120  lsrcs   r1, r1, #6
121label2:
122  rsbs    r12, r1, r0, LSR #7
123  subcs   r0, r0, r1, LSL #7
124  adc     r2, r2, r2
125  rsbs    r12, r1, r0, LSR #6
126  subcs   r0, r0, r1, LSL #6
127  adc     r2, r2, r2
128  rsbs    r12, r1, r0, LSR #5
129  subcs   r0, r0, r1, LSL #5
130  adc     r2, r2, r2
131  rsbs    r12, r1, r0, LSR #4
132  subcs   r0, r0, r1, LSL #4
133  adc     r2, r2, r2
134label1:
135  rsbs    r12, r1, r0, LSR #3
136  subcs   r0, r0, r1, LSL #3
137  adc     r2, r2, r2
138  rsbs    r12, r1, r0, LSR #2
139  subcs   r0, r0, r1, LSL #2
140  adcs    r2, r2, r2
141  bcs     label3
142  rsbs    r12, r1, r0, LSR #1
143  subcs   r0, r0, r1, LSL #1
144  adc     r2, r2, r2
145  subs    r1, r0, r1
146  movcc   r1, r0
147  adc     r0, r2, r2
148  asrs    r3, r3, #31
149  rsbmi   r0, r0, #0
150  rsbcs   r1, r1, #0
151  bx      r14
152
153  @ What to do about division by zero?  For now, just return.
154ASM_PFX(__aeabi_idiv0):
155  bx      r14
156