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