#------------------------------------------------------------------------------ | |
# | |
# Copyright (c) 2011, ARM. 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. | |
# | |
#------------------------------------------------------------------------------ | |
.text | |
.align 2 | |
GCC_ASM_EXPORT(__aeabi_uidiv) | |
GCC_ASM_EXPORT(__aeabi_uidivmod) | |
GCC_ASM_EXPORT(__aeabi_idiv) | |
GCC_ASM_EXPORT(__aeabi_idivmod) | |
# AREA Math, CODE, READONLY | |
# | |
#UINT32 | |
#EFIAPI | |
#__aeabi_uidivmode ( | |
# IN UINT32 Dividen | |
# IN UINT32 Divisor | |
# ); | |
# | |
ASM_PFX(__aeabi_uidiv): | |
ASM_PFX(__aeabi_uidivmod): | |
rsbs r12, r1, r0, LSR #4 | |
mov r2, #0 | |
bcc ASM_PFX(__arm_div4) | |
rsbs r12, r1, r0, LSR #8 | |
bcc ASM_PFX(__arm_div8) | |
mov r3, #0 | |
b ASM_PFX(__arm_div_large) | |
# | |
#INT32 | |
#EFIAPI | |
#__aeabi_idivmode ( | |
# IN INT32 Dividen | |
# IN INT32 Divisor | |
# ); | |
# | |
ASM_PFX(__aeabi_idiv): | |
ASM_PFX(__aeabi_idivmod): | |
orrs r12, r0, r1 | |
bmi ASM_PFX(__arm_div_negative) | |
rsbs r12, r1, r0, LSR #1 | |
mov r2, #0 | |
bcc ASM_PFX(__arm_div1) | |
rsbs r12, r1, r0, LSR #4 | |
bcc ASM_PFX(__arm_div4) | |
rsbs r12, r1, r0, LSR #8 | |
bcc ASM_PFX(__arm_div8) | |
mov r3, #0 | |
b ASM_PFX(__arm_div_large) | |
ASM_PFX(__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 | |
ASM_PFX(__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 | |
ASM_PFX(__arm_div1): | |
subs r1, r0, r1 | |
movcc r1, r0 | |
adc r0, r2, r2 | |
bx r14 | |
ASM_PFX(__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 | |
ASM_PFX(__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 ASM_PFX(__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. | |
ASM_PFX(__aeabi_idiv0): | |
bx r14 |