From f0a7a8ce23e93eff468dbc1e258104d60e3ba7b1 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Fri, 3 Jun 2011 09:28:40 +0000 Subject: ArmPkg/CompilerIntrinsincsLib: Add div and mullu functions to ARMGCC git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11742 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S | 156 +++++++++++++++++++++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S | 46 +++++++ 2 files changed, 202 insertions(+) create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S (limited to 'ArmPkg/Library/CompilerIntrinsicsLib/Arm') diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S new file mode 100644 index 0000000000..2f133665b5 --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S @@ -0,0 +1,156 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2011, ARM. All rights reserved.
+# +# 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 + +.end + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S new file mode 100644 index 0000000000..e6d85db0a0 --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S @@ -0,0 +1,46 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# +# 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 + +GCC_ASM_EXPORT(__ARM_ll_mullu) +GCC_ASM_EXPORT(__aeabi_lmul) +# +#INT64 +#EFIAPI +#__aeabi_lmul ( +# IN INT64 Multiplicand +# IN INT32 Multiplier +# ); +# +ASM_PFX(__ARM_ll_mullu): + mov r3, #0 +# Make upper part of INT64 Multiplier 0 and use __aeabi_lmul + +# +#INT64 +#EFIAPI +#__aeabi_lmul ( +# IN INT64 Multiplicand +# IN INT64 Multiplier +# ); +# +ASM_PFX(__aeabi_lmul): + stmdb sp!, {lr} + mov lr, r0 + umull r0, ip, r2, lr + mla r1, r2, r1, ip + mla r1, r3, lr, r1 + ldmia sp!, {pc} + +.end -- cgit v1.2.3