1b3f3620ea
and aarch64 builds. Signed-off-by: Peter Jones <pjones@redhat.com>
1216 lines
30 KiB
Diff
1216 lines
30 KiB
Diff
From a86ab98d50e3aa15fbdc65cb3bd220fc86f18cad Mon Sep 17 00:00:00 2001
|
|
From: Nigel Croxon <nigel.croxon@hpe.com>
|
|
Date: Wed, 23 Dec 2015 08:33:02 -0500
|
|
Subject: [PATCH 06/10] From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
|
Subject: [PATCH 2/2] Replace ARM arithmetic support routines with EDK2
|
|
versions.
|
|
|
|
Replace the incomplete GPL licensed ARM arithmetic support routines
|
|
with the ones from the EDK2 project. These cover long long multiplication
|
|
and long long logical shift as well.
|
|
|
|
Also remove the special case for small dividends in DivU64x32: we can
|
|
simply let the compiler handle this, and emit calls to the support
|
|
routines where appropriate.
|
|
|
|
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
|
Signed-off-by: Nigel Croxon <nigel.croxon@hpe.com>
|
|
---
|
|
inc/arm/efibind.h | 9 +-
|
|
lib/Makefile | 3 +-
|
|
lib/arm/div.S | 155 +++++++++++++++++++++++++++++
|
|
lib/arm/div64.S | 193 ------------------------------------
|
|
lib/arm/edk2asm.h | 6 ++
|
|
lib/arm/ldivmod.S | 61 ++++++++++++
|
|
lib/arm/lib1funcs.S | 279 ----------------------------------------------------
|
|
lib/arm/llsl.S | 41 ++++++++
|
|
lib/arm/llsr.S | 41 ++++++++
|
|
lib/arm/mullu.S | 33 +++++++
|
|
lib/arm/uldiv.S | 267 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
11 files changed, 608 insertions(+), 480 deletions(-)
|
|
create mode 100644 lib/arm/div.S
|
|
delete mode 100644 lib/arm/div64.S
|
|
create mode 100644 lib/arm/edk2asm.h
|
|
create mode 100644 lib/arm/ldivmod.S
|
|
delete mode 100644 lib/arm/lib1funcs.S
|
|
create mode 100644 lib/arm/llsl.S
|
|
create mode 100644 lib/arm/llsr.S
|
|
create mode 100644 lib/arm/mullu.S
|
|
create mode 100644 lib/arm/uldiv.S
|
|
|
|
diff --git a/inc/arm/efibind.h b/inc/arm/efibind.h
|
|
index 798212c..cc4b5c5 100644
|
|
--- a/inc/arm/efibind.h
|
|
+++ b/inc/arm/efibind.h
|
|
@@ -125,13 +125,8 @@ typedef uint32_t UINTN;
|
|
#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__)
|
|
#define EFI_FUNCTION
|
|
|
|
-extern UINT64 __DivU64x32(UINT64 Dividend, UINTN Divisor, UINTN *Remainder);
|
|
-
|
|
static inline UINT64 DivU64x32(UINT64 Dividend, UINTN Divisor, UINTN *Remainder)
|
|
{
|
|
- if (Dividend >> 32)
|
|
- return __DivU64x32(Dividend, Divisor, Remainder);
|
|
-
|
|
/*
|
|
* GCC turns a division into a multiplication and shift with precalculated
|
|
* constants if the divisor is constant and the dividend fits into a 32 bit
|
|
@@ -139,7 +134,7 @@ static inline UINT64 DivU64x32(UINT64 Dividend, UINTN Divisor, UINTN *Remainder)
|
|
* library functions.
|
|
*/
|
|
if (Remainder)
|
|
- *Remainder = (UINTN)Dividend % Divisor;
|
|
- Dividend = (UINTN)Dividend / Divisor;
|
|
+ *Remainder = Dividend % Divisor;
|
|
+ Dividend = Dividend / Divisor;
|
|
return Dividend;
|
|
}
|
|
diff --git a/lib/Makefile b/lib/Makefile
|
|
index 622730f..a9ba4e2 100644
|
|
--- a/lib/Makefile
|
|
+++ b/lib/Makefile
|
|
@@ -58,7 +58,8 @@ FILES += $(ARCH)/callwrap $(ARCH)/efi_stub
|
|
endif
|
|
|
|
ifeq ($(ARCH),arm)
|
|
-FILES += $(ARCH)/lib1funcs $(ARCH)/div64
|
|
+FILES += $(ARCH)/uldiv $(ARCH)/ldivmod $(ARCH)/div $(ARCH)/llsl $(ARCH)/llsr \
|
|
+ $(ARCH)/mullu
|
|
endif
|
|
|
|
OBJS = $(FILES:%=%.o)
|
|
diff --git a/lib/arm/div.S b/lib/arm/div.S
|
|
new file mode 100644
|
|
index 0000000..71158b6
|
|
--- /dev/null
|
|
+++ b/lib/arm/div.S
|
|
@@ -0,0 +1,155 @@
|
|
+#------------------------------------------------------------------------------
|
|
+#
|
|
+# 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.
|
|
+#
|
|
+#------------------------------------------------------------------------------
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+.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
|
|
diff --git a/lib/arm/div64.S b/lib/arm/div64.S
|
|
deleted file mode 100644
|
|
index f67ba77..0000000
|
|
--- a/lib/arm/div64.S
|
|
+++ /dev/null
|
|
@@ -1,193 +0,0 @@
|
|
-/*
|
|
- * linux/arch/arm/lib/div64.S
|
|
- *
|
|
- * Optimized computation of 64-bit dividend / 32-bit divisor
|
|
- *
|
|
- * Author: Nicolas Pitre
|
|
- * Created: Oct 5, 2003
|
|
- * Copyright: Monta Vista Software, Inc.
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU General Public License version 2 as
|
|
- * published by the Free Software Foundation.
|
|
- */
|
|
-
|
|
-#define xl r0
|
|
-#define xh r1
|
|
-#define yl r2
|
|
-#define yh r3
|
|
-
|
|
-#define UNWIND(x...)
|
|
-#define ARM(x...) x
|
|
-#define THUMB(x...)
|
|
-
|
|
-#define ENTRY(__f) \
|
|
- .align 3 ;\
|
|
- .globl __f ;\
|
|
- .type __f,%function ;\
|
|
-__f:
|
|
-#define ENDPROC(__f) ;\
|
|
- .size __f, . - __f
|
|
-
|
|
-
|
|
-/*
|
|
-UINT64
|
|
-DivU64x32 (
|
|
- IN UINT64 Dividend,
|
|
- IN UINTN Divisor,
|
|
- OUT UINTN *Remainder OPTIONAL
|
|
- )
|
|
-// divide 64bit by 32bit and get a 64bit result
|
|
-// N.B. only works for 31bit divisors!!
|
|
-{
|
|
-}
|
|
-*/
|
|
-
|
|
-ENTRY(__DivU64x32)
|
|
- stmfd sp!, {r4-r6, lr}
|
|
-
|
|
- mov r5, r4 @ preserve Remainder
|
|
- mov r4, r2 @ divisor in r4
|
|
- bl __do_div64
|
|
-
|
|
- teq r5, #0
|
|
- strne xh, [r5]
|
|
- mov r0, yl
|
|
- mov r1, yh
|
|
- ldmfd sp!, {r4-r6, pc}
|
|
-ENDPROC(__DivU64x32)
|
|
-
|
|
-/*
|
|
- * __do_div64: perform a division with 64-bit dividend and 32-bit divisor.
|
|
- *
|
|
- * Note: Calling convention is totally non standard for optimal code.
|
|
- * This is meant to be used by do_div() from include/asm/div64.h only.
|
|
- *
|
|
- * Input parameters:
|
|
- * xh-xl = dividend (clobbered)
|
|
- * r4 = divisor (preserved)
|
|
- *
|
|
- * Output values:
|
|
- * yh-yl = result
|
|
- * xh = remainder
|
|
- *
|
|
- * Clobbered regs: xl, ip
|
|
- */
|
|
-
|
|
-ENTRY(__do_div64)
|
|
-UNWIND(.fnstart)
|
|
-
|
|
- @ Test for easy paths first.
|
|
- subs ip, r4, #1
|
|
- bls 9f @ divisor is 0 or 1
|
|
- tst ip, r4
|
|
- beq 8f @ divisor is power of 2
|
|
-
|
|
- @ See if we need to handle upper 32-bit result.
|
|
- cmp xh, r4
|
|
- mov yh, #0
|
|
- blo 3f
|
|
-
|
|
- @ Align divisor with upper part of dividend.
|
|
- @ The aligned divisor is stored in yl preserving the original.
|
|
- @ The bit position is stored in ip.
|
|
-
|
|
- clz yl, r4
|
|
- clz ip, xh
|
|
- sub yl, yl, ip
|
|
- mov ip, #1
|
|
- mov ip, ip, lsl yl
|
|
- mov yl, r4, lsl yl
|
|
-
|
|
- @ The division loop for needed upper bit positions.
|
|
- @ Break out early if dividend reaches 0.
|
|
-2: cmp xh, yl
|
|
- orrcs yh, yh, ip
|
|
- subcss xh, xh, yl
|
|
- movnes ip, ip, lsr #1
|
|
- mov yl, yl, lsr #1
|
|
- bne 2b
|
|
-
|
|
- @ See if we need to handle lower 32-bit result.
|
|
-3: cmp xh, #0
|
|
- mov yl, #0
|
|
- cmpeq xl, r4
|
|
- movlo xh, xl
|
|
- movlo pc, lr
|
|
-
|
|
- @ The division loop for lower bit positions.
|
|
- @ Here we shift remainer bits leftwards rather than moving the
|
|
- @ divisor for comparisons, considering the carry-out bit as well.
|
|
- mov ip, #0x80000000
|
|
-4: movs xl, xl, lsl #1
|
|
- adcs xh, xh, xh
|
|
- beq 6f
|
|
- cmpcc xh, r4
|
|
-5: orrcs yl, yl, ip
|
|
- subcs xh, xh, r4
|
|
- movs ip, ip, lsr #1
|
|
- bne 4b
|
|
- mov pc, lr
|
|
-
|
|
- @ The top part of remainder became zero. If carry is set
|
|
- @ (the 33th bit) this is a false positive so resume the loop.
|
|
- @ Otherwise, if lower part is also null then we are done.
|
|
-6: bcs 5b
|
|
- cmp xl, #0
|
|
- moveq pc, lr
|
|
-
|
|
- @ We still have remainer bits in the low part. Bring them up.
|
|
-
|
|
- clz xh, xl @ we know xh is zero here so...
|
|
- add xh, xh, #1
|
|
- mov xl, xl, lsl xh
|
|
- mov ip, ip, lsr xh
|
|
-
|
|
- @ Current remainder is now 1. It is worthless to compare with
|
|
- @ divisor at this point since divisor can not be smaller than 3 here.
|
|
- @ If possible, branch for another shift in the division loop.
|
|
- @ If no bit position left then we are done.
|
|
- movs ip, ip, lsr #1
|
|
- mov xh, #1
|
|
- bne 4b
|
|
- mov pc, lr
|
|
-
|
|
-8: @ Division by a power of 2: determine what that divisor order is
|
|
- @ then simply shift values around
|
|
-
|
|
- clz ip, r4
|
|
- rsb ip, ip, #31
|
|
-
|
|
- mov yh, xh, lsr ip
|
|
- mov yl, xl, lsr ip
|
|
- rsb ip, ip, #32
|
|
- ARM( orr yl, yl, xh, lsl ip )
|
|
- THUMB( lsl xh, xh, ip )
|
|
- THUMB( orr yl, yl, xh )
|
|
- mov xh, xl, lsl ip
|
|
- mov xh, xh, lsr ip
|
|
- mov pc, lr
|
|
-
|
|
- @ eq -> division by 1: obvious enough...
|
|
-9: moveq yl, xl
|
|
- moveq yh, xh
|
|
- moveq xh, #0
|
|
- moveq pc, lr
|
|
-UNWIND(.fnend)
|
|
-
|
|
-UNWIND(.fnstart)
|
|
-UNWIND(.pad #4)
|
|
-UNWIND(.save {lr})
|
|
-Ldiv0_64:
|
|
- @ Division by 0:
|
|
- str lr, [sp, #-8]!
|
|
- bl __div0
|
|
-
|
|
- @ as wrong as it could be...
|
|
- mov yl, #0
|
|
- mov yh, #0
|
|
- mov xh, #0
|
|
- ldr pc, [sp], #8
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__do_div64)
|
|
diff --git a/lib/arm/edk2asm.h b/lib/arm/edk2asm.h
|
|
new file mode 100644
|
|
index 0000000..9515eaf
|
|
--- /dev/null
|
|
+++ b/lib/arm/edk2asm.h
|
|
@@ -0,0 +1,6 @@
|
|
+
|
|
+#define ASM_PFX(x) x
|
|
+#define GCC_ASM_EXPORT(x) \
|
|
+ .globl x ; \
|
|
+ .type x, %function
|
|
+
|
|
diff --git a/lib/arm/ldivmod.S b/lib/arm/ldivmod.S
|
|
new file mode 100644
|
|
index 0000000..edbf89e
|
|
--- /dev/null
|
|
+++ b/lib/arm/ldivmod.S
|
|
@@ -0,0 +1,61 @@
|
|
+//------------------------------------------------------------------------------
|
|
+//
|
|
+// 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.
|
|
+//
|
|
+//------------------------------------------------------------------------------
|
|
+
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+ .text
|
|
+ .align 2
|
|
+ GCC_ASM_EXPORT(__aeabi_ldivmod)
|
|
+
|
|
+//
|
|
+// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},
|
|
+// the quotient in {r0, r1}, and the remainder in {r2, r3}.
|
|
+//
|
|
+//__value_in_regs lldiv_t
|
|
+//EFIAPI
|
|
+//__aeabi_ldivmod (
|
|
+// IN UINT64 Dividen
|
|
+// IN UINT64 Divisor
|
|
+// )//
|
|
+//
|
|
+
|
|
+ASM_PFX(__aeabi_ldivmod):
|
|
+ push {r4,lr}
|
|
+ asrs r4,r1,#1
|
|
+ eor r4,r4,r3,LSR #1
|
|
+ bpl L_Test1
|
|
+ rsbs r0,r0,#0
|
|
+ rsc r1,r1,#0
|
|
+L_Test1:
|
|
+ tst r3,r3
|
|
+ bpl L_Test2
|
|
+ rsbs r2,r2,#0
|
|
+ rsc r3,r3,#0
|
|
+L_Test2:
|
|
+ bl ASM_PFX(__aeabi_uldivmod)
|
|
+ tst r4,#0x40000000
|
|
+ beq L_Test3
|
|
+ rsbs r0,r0,#0
|
|
+ rsc r1,r1,#0
|
|
+L_Test3:
|
|
+ tst r4,#0x80000000
|
|
+ beq L_Exit
|
|
+ rsbs r2,r2,#0
|
|
+ rsc r3,r3,#0
|
|
+L_Exit:
|
|
+ pop {r4,pc}
|
|
+
|
|
+
|
|
+
|
|
diff --git a/lib/arm/lib1funcs.S b/lib/arm/lib1funcs.S
|
|
deleted file mode 100644
|
|
index 6b4d4bf..0000000
|
|
--- a/lib/arm/lib1funcs.S
|
|
+++ /dev/null
|
|
@@ -1,279 +0,0 @@
|
|
-/*
|
|
- * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
|
|
- *
|
|
- * Author: Nicolas Pitre <nico@fluxnic.net>
|
|
- * - contributed to gcc-3.4 on Sep 30, 2003
|
|
- * - adapted for the Linux kernel on Oct 2, 2003
|
|
- */
|
|
-
|
|
-/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
|
|
-
|
|
-This file is free software; you can redistribute it and/or modify it
|
|
-under the terms of the GNU General Public License as published by the
|
|
-Free Software Foundation; either version 2, or (at your option) any
|
|
-later version.
|
|
-
|
|
-In addition to the permissions in the GNU General Public License, the
|
|
-Free Software Foundation gives you unlimited permission to link the
|
|
-compiled version of this file into combinations with other programs,
|
|
-and to distribute those combinations without any restriction coming
|
|
-from the use of this file. (The General Public License restrictions
|
|
-do apply in other respects; for example, they cover modification of
|
|
-the file, and distribution when not linked into a combine
|
|
-executable.)
|
|
-
|
|
-This file is distributed in the hope that it will be useful, but
|
|
-WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
-General Public License for more details.
|
|
-
|
|
-You should have received a copy of the GNU General Public License
|
|
-along with this program; see the file COPYING. If not, write to
|
|
-the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
-Boston, MA 02111-1307, USA. */
|
|
-
|
|
-#define UNWIND(x...)
|
|
-
|
|
-#define ENTRY(__f) \
|
|
- .align 3 ;\
|
|
- .globl __f ;\
|
|
- .type __f,%function ;\
|
|
-__f:
|
|
-#define ENDPROC(__f) ;\
|
|
- .size __f, . - __f
|
|
-
|
|
-.macro ARM_DIV_BODY dividend, divisor, result, curbit
|
|
-
|
|
- clz \curbit, \divisor
|
|
- clz \result, \dividend
|
|
- sub \result, \curbit, \result
|
|
- mov \curbit, #1
|
|
- mov \divisor, \divisor, lsl \result
|
|
- mov \curbit, \curbit, lsl \result
|
|
- mov \result, #0
|
|
-
|
|
- @ Division loop
|
|
-1: cmp \dividend, \divisor
|
|
- subhs \dividend, \dividend, \divisor
|
|
- orrhs \result, \result, \curbit
|
|
- cmp \dividend, \divisor, lsr #1
|
|
- subhs \dividend, \dividend, \divisor, lsr #1
|
|
- orrhs \result, \result, \curbit, lsr #1
|
|
- cmp \dividend, \divisor, lsr #2
|
|
- subhs \dividend, \dividend, \divisor, lsr #2
|
|
- orrhs \result, \result, \curbit, lsr #2
|
|
- cmp \dividend, \divisor, lsr #3
|
|
- subhs \dividend, \dividend, \divisor, lsr #3
|
|
- orrhs \result, \result, \curbit, lsr #3
|
|
- cmp \dividend, #0 @ Early termination?
|
|
- movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
|
|
- movne \divisor, \divisor, lsr #4
|
|
- bne 1b
|
|
-
|
|
-.endm
|
|
-
|
|
-
|
|
-.macro ARM_DIV2_ORDER divisor, order
|
|
-
|
|
- clz \order, \divisor
|
|
- rsb \order, \order, #31
|
|
-
|
|
-.endm
|
|
-
|
|
-
|
|
-.macro ARM_MOD_BODY dividend, divisor, order, spare
|
|
-
|
|
- clz \order, \divisor
|
|
- clz \spare, \dividend
|
|
- sub \order, \order, \spare
|
|
- mov \divisor, \divisor, lsl \order
|
|
-
|
|
- @ Perform all needed substractions to keep only the reminder.
|
|
- @ Do comparisons in batch of 4 first.
|
|
- subs \order, \order, #3 @ yes, 3 is intended here
|
|
- blt 2f
|
|
-
|
|
-1: cmp \dividend, \divisor
|
|
- subhs \dividend, \dividend, \divisor
|
|
- cmp \dividend, \divisor, lsr #1
|
|
- subhs \dividend, \dividend, \divisor, lsr #1
|
|
- cmp \dividend, \divisor, lsr #2
|
|
- subhs \dividend, \dividend, \divisor, lsr #2
|
|
- cmp \dividend, \divisor, lsr #3
|
|
- subhs \dividend, \dividend, \divisor, lsr #3
|
|
- cmp \dividend, #1
|
|
- mov \divisor, \divisor, lsr #4
|
|
- subges \order, \order, #4
|
|
- bge 1b
|
|
-
|
|
- tst \order, #3
|
|
- teqne \dividend, #0
|
|
- beq 5f
|
|
-
|
|
- @ Either 1, 2 or 3 comparison/substractions are left.
|
|
-2: cmn \order, #2
|
|
- blt 4f
|
|
- beq 3f
|
|
- cmp \dividend, \divisor
|
|
- subhs \dividend, \dividend, \divisor
|
|
- mov \divisor, \divisor, lsr #1
|
|
-3: cmp \dividend, \divisor
|
|
- subhs \dividend, \dividend, \divisor
|
|
- mov \divisor, \divisor, lsr #1
|
|
-4: cmp \dividend, \divisor
|
|
- subhs \dividend, \dividend, \divisor
|
|
-5:
|
|
-.endm
|
|
-
|
|
-
|
|
-ENTRY(__aeabi_uidiv)
|
|
-ENTRY(__udivsi3)
|
|
-
|
|
- subs r2, r1, #1
|
|
- moveq pc, lr
|
|
- bcc Ldiv0
|
|
- cmp r0, r1
|
|
- bls 11f
|
|
- tst r1, r2
|
|
- beq 12f
|
|
-
|
|
- ARM_DIV_BODY r0, r1, r2, r3
|
|
-
|
|
- mov r0, r2
|
|
- mov pc, lr
|
|
-
|
|
-11: moveq r0, #1
|
|
- movne r0, #0
|
|
- mov pc, lr
|
|
-
|
|
-12: ARM_DIV2_ORDER r1, r2
|
|
-
|
|
- mov r0, r0, lsr r2
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__udivsi3)
|
|
-ENDPROC(__aeabi_uidiv)
|
|
-
|
|
-ENTRY(__umodsi3)
|
|
-UNWIND(.fnstart)
|
|
-
|
|
- subs r2, r1, #1 @ compare divisor with 1
|
|
- bcc Ldiv0
|
|
- cmpne r0, r1 @ compare dividend with divisor
|
|
- moveq r0, #0
|
|
- tsthi r1, r2 @ see if divisor is power of 2
|
|
- andeq r0, r0, r2
|
|
- movls pc, lr
|
|
-
|
|
- ARM_MOD_BODY r0, r1, r2, r3
|
|
-
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__umodsi3)
|
|
-
|
|
-ENTRY(__divsi3)
|
|
-ENTRY(__aeabi_idiv)
|
|
-UNWIND(.fnstart)
|
|
-
|
|
- cmp r1, #0
|
|
- eor ip, r0, r1 @ save the sign of the result.
|
|
- beq Ldiv0
|
|
- rsbmi r1, r1, #0 @ loops below use unsigned.
|
|
- subs r2, r1, #1 @ division by 1 or -1 ?
|
|
- beq 10f
|
|
- movs r3, r0
|
|
- rsbmi r3, r0, #0 @ positive dividend value
|
|
- cmp r3, r1
|
|
- bls 11f
|
|
- tst r1, r2 @ divisor is power of 2 ?
|
|
- beq 12f
|
|
-
|
|
- ARM_DIV_BODY r3, r1, r0, r2
|
|
-
|
|
- cmp ip, #0
|
|
- rsbmi r0, r0, #0
|
|
- mov pc, lr
|
|
-
|
|
-10: teq ip, r0 @ same sign ?
|
|
- rsbmi r0, r0, #0
|
|
- mov pc, lr
|
|
-
|
|
-11: movlo r0, #0
|
|
- moveq r0, ip, asr #31
|
|
- orreq r0, r0, #1
|
|
- mov pc, lr
|
|
-
|
|
-12: ARM_DIV2_ORDER r1, r2
|
|
-
|
|
- cmp ip, #0
|
|
- mov r0, r3, lsr r2
|
|
- rsbmi r0, r0, #0
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__divsi3)
|
|
-ENDPROC(__aeabi_idiv)
|
|
-
|
|
-ENTRY(__modsi3)
|
|
-UNWIND(.fnstart)
|
|
-
|
|
- cmp r1, #0
|
|
- beq Ldiv0
|
|
- rsbmi r1, r1, #0 @ loops below use unsigned.
|
|
- movs ip, r0 @ preserve sign of dividend
|
|
- rsbmi r0, r0, #0 @ if negative make positive
|
|
- subs r2, r1, #1 @ compare divisor with 1
|
|
- cmpne r0, r1 @ compare dividend with divisor
|
|
- moveq r0, #0
|
|
- tsthi r1, r2 @ see if divisor is power of 2
|
|
- andeq r0, r0, r2
|
|
- bls 10f
|
|
-
|
|
- ARM_MOD_BODY r0, r1, r2, r3
|
|
-
|
|
-10: cmp ip, #0
|
|
- rsbmi r0, r0, #0
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__modsi3)
|
|
-
|
|
-ENTRY(__aeabi_uidivmod)
|
|
-UNWIND(.fnstart)
|
|
-UNWIND(.save {r0, r1, ip, lr} )
|
|
-
|
|
- stmfd sp!, {r0, r1, ip, lr}
|
|
- bl __aeabi_uidiv
|
|
- ldmfd sp!, {r1, r2, ip, lr}
|
|
- mul r3, r0, r2
|
|
- sub r1, r1, r3
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__aeabi_uidivmod)
|
|
-
|
|
-ENTRY(__aeabi_idivmod)
|
|
-UNWIND(.fnstart)
|
|
-UNWIND(.save {r0, r1, ip, lr} )
|
|
- stmfd sp!, {r0, r1, ip, lr}
|
|
- bl __aeabi_idiv
|
|
- ldmfd sp!, {r1, r2, ip, lr}
|
|
- mul r3, r0, r2
|
|
- sub r1, r1, r3
|
|
- mov pc, lr
|
|
-
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(__aeabi_idivmod)
|
|
-
|
|
-Ldiv0:
|
|
-UNWIND(.fnstart)
|
|
-UNWIND(.pad #4)
|
|
-UNWIND(.save {lr})
|
|
- str lr, [sp, #-8]!
|
|
- bl __div0
|
|
- mov r0, #0 @ About as wrong as it could be.
|
|
- ldr pc, [sp], #8
|
|
-UNWIND(.fnend)
|
|
-ENDPROC(Ldiv0)
|
|
diff --git a/lib/arm/llsl.S b/lib/arm/llsl.S
|
|
new file mode 100644
|
|
index 0000000..0f5c407
|
|
--- /dev/null
|
|
+++ b/lib/arm/llsl.S
|
|
@@ -0,0 +1,41 @@
|
|
+#------------------------------------------------------------------------------
|
|
+#
|
|
+# Copyright (c) 2013, 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.
|
|
+#
|
|
+#------------------------------------------------------------------------------
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+.text
|
|
+.align 2
|
|
+GCC_ASM_EXPORT(__aeabi_llsl)
|
|
+
|
|
+#
|
|
+#VOID
|
|
+#EFIAPI
|
|
+#__aeabi_llsl (
|
|
+# IN VOID *Destination,
|
|
+# IN VOID *Source,
|
|
+# IN UINT32 Size
|
|
+# );
|
|
+#
|
|
+ASM_PFX(__aeabi_llsl):
|
|
+ subs r3,r2,#0x20
|
|
+ bpl 1f
|
|
+ rsb r3,r2,#0x20
|
|
+ lsl r1,r1,r2
|
|
+ orr r1,r1,r0,lsr r3
|
|
+ lsl r0,r0,r2
|
|
+ bx lr
|
|
+1:
|
|
+ lsl r1,r0,r3
|
|
+ mov r0,#0
|
|
+ bx lr
|
|
diff --git a/lib/arm/llsr.S b/lib/arm/llsr.S
|
|
new file mode 100644
|
|
index 0000000..432b27d
|
|
--- /dev/null
|
|
+++ b/lib/arm/llsr.S
|
|
@@ -0,0 +1,41 @@
|
|
+#------------------------------------------------------------------------------
|
|
+#
|
|
+# Copyright (c) 2013, 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.
|
|
+#
|
|
+#------------------------------------------------------------------------------
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+.text
|
|
+.align 2
|
|
+GCC_ASM_EXPORT(__aeabi_llsr)
|
|
+
|
|
+#
|
|
+#VOID
|
|
+#EFIAPI
|
|
+#__aeabi_llsr (
|
|
+# IN VOID *Destination,
|
|
+# IN VOID *Source,
|
|
+# IN UINT32 Size
|
|
+# );
|
|
+#
|
|
+ASM_PFX(__aeabi_llsr):
|
|
+ subs r3,r2,#0x20
|
|
+ bpl 1f
|
|
+ rsb r3,r2,#0x20
|
|
+ lsr r0,r0,r2
|
|
+ orr r0,r0,r1,lsl r3
|
|
+ lsr r1,r1,r2
|
|
+ bx lr
|
|
+1:
|
|
+ lsr r0,r1,r3
|
|
+ mov r1,#0
|
|
+ bx lr
|
|
diff --git a/lib/arm/mullu.S b/lib/arm/mullu.S
|
|
new file mode 100644
|
|
index 0000000..39b9a80
|
|
--- /dev/null
|
|
+++ b/lib/arm/mullu.S
|
|
@@ -0,0 +1,33 @@
|
|
+#------------------------------------------------------------------------------
|
|
+#
|
|
+# 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.
|
|
+#
|
|
+#------------------------------------------------------------------------------
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+.text
|
|
+GCC_ASM_EXPORT(__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}
|
|
diff --git a/lib/arm/uldiv.S b/lib/arm/uldiv.S
|
|
new file mode 100644
|
|
index 0000000..f478898
|
|
--- /dev/null
|
|
+++ b/lib/arm/uldiv.S
|
|
@@ -0,0 +1,267 @@
|
|
+//------------------------------------------------------------------------------
|
|
+//
|
|
+// 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.
|
|
+//
|
|
+//------------------------------------------------------------------------------
|
|
+
|
|
+#include "edk2asm.h"
|
|
+
|
|
+ .text
|
|
+ .align 2
|
|
+ GCC_ASM_EXPORT(__aeabi_uldivmod)
|
|
+
|
|
+//
|
|
+//UINT64
|
|
+//EFIAPI
|
|
+//__aeabi_uldivmod (
|
|
+// IN UINT64 Dividend
|
|
+// IN UINT64 Divisor
|
|
+// )
|
|
+//
|
|
+ASM_PFX(__aeabi_uldivmod):
|
|
+ stmdb sp!, {r4, r5, r6, lr}
|
|
+ mov r4, r1
|
|
+ mov r5, r0
|
|
+ mov r6, #0 // 0x0
|
|
+ orrs ip, r3, r2, lsr #31
|
|
+ bne ASM_PFX(__aeabi_uldivmod_label1)
|
|
+ tst r2, r2
|
|
+ beq ASM_PFX(_ll_div0)
|
|
+ movs ip, r2, lsr #15
|
|
+ addeq r6, r6, #16 // 0x10
|
|
+ mov ip, r2, lsl r6
|
|
+ movs lr, ip, lsr #23
|
|
+ moveq ip, ip, lsl #8
|
|
+ addeq r6, r6, #8 // 0x8
|
|
+ movs lr, ip, lsr #27
|
|
+ moveq ip, ip, lsl #4
|
|
+ addeq r6, r6, #4 // 0x4
|
|
+ movs lr, ip, lsr #29
|
|
+ moveq ip, ip, lsl #2
|
|
+ addeq r6, r6, #2 // 0x2
|
|
+ movs lr, ip, lsr #30
|
|
+ moveq ip, ip, lsl #1
|
|
+ addeq r6, r6, #1 // 0x1
|
|
+ b ASM_PFX(_ll_udiv_small)
|
|
+ASM_PFX(__aeabi_uldivmod_label1):
|
|
+ tst r3, #-2147483648 // 0x80000000
|
|
+ bne ASM_PFX(__aeabi_uldivmod_label2)
|
|
+ movs ip, r3, lsr #15
|
|
+ addeq r6, r6, #16 // 0x10
|
|
+ mov ip, r3, lsl r6
|
|
+ movs lr, ip, lsr #23
|
|
+ moveq ip, ip, lsl #8
|
|
+ addeq r6, r6, #8 // 0x8
|
|
+ movs lr, ip, lsr #27
|
|
+ moveq ip, ip, lsl #4
|
|
+ addeq r6, r6, #4 // 0x4
|
|
+ movs lr, ip, lsr #29
|
|
+ moveq ip, ip, lsl #2
|
|
+ addeq r6, r6, #2 // 0x2
|
|
+ movs lr, ip, lsr #30
|
|
+ addeq r6, r6, #1 // 0x1
|
|
+ rsb r3, r6, #32 // 0x20
|
|
+ moveq ip, ip, lsl #1
|
|
+ orr ip, ip, r2, lsr r3
|
|
+ mov lr, r2, lsl r6
|
|
+ b ASM_PFX(_ll_udiv_big)
|
|
+ASM_PFX(__aeabi_uldivmod_label2):
|
|
+ mov ip, r3
|
|
+ mov lr, r2
|
|
+ b ASM_PFX(_ll_udiv_ginormous)
|
|
+
|
|
+ASM_PFX(_ll_udiv_small):
|
|
+ cmp r4, ip, lsl #1
|
|
+ mov r3, #0 // 0x0
|
|
+ subcs r4, r4, ip, lsl #1
|
|
+ addcs r3, r3, #2 // 0x2
|
|
+ cmp r4, ip
|
|
+ subcs r4, r4, ip
|
|
+ adcs r3, r3, #0 // 0x0
|
|
+ add r2, r6, #32 // 0x20
|
|
+ cmp r2, #32 // 0x20
|
|
+ rsb ip, ip, #0 // 0x0
|
|
+ bcc ASM_PFX(_ll_udiv_small_label1)
|
|
+ orrs r0, r4, r5, lsr #30
|
|
+ moveq r4, r5
|
|
+ moveq r5, #0 // 0x0
|
|
+ subeq r2, r2, #32 // 0x20
|
|
+ASM_PFX(_ll_udiv_small_label1):
|
|
+ mov r1, #0 // 0x0
|
|
+ cmp r2, #16 // 0x10
|
|
+ bcc ASM_PFX(_ll_udiv_small_label2)
|
|
+ movs r0, r4, lsr #14
|
|
+ moveq r4, r4, lsl #16
|
|
+ addeq r1, r1, #16 // 0x10
|
|
+ASM_PFX(_ll_udiv_small_label2):
|
|
+ sub lr, r2, r1
|
|
+ cmp lr, #8 // 0x8
|
|
+ bcc ASM_PFX(_ll_udiv_small_label3)
|
|
+ movs r0, r4, lsr #22
|
|
+ moveq r4, r4, lsl #8
|
|
+ addeq r1, r1, #8 // 0x8
|
|
+ASM_PFX(_ll_udiv_small_label3):
|
|
+ rsb r0, r1, #32 // 0x20
|
|
+ sub r2, r2, r1
|
|
+ orr r4, r4, r5, lsr r0
|
|
+ mov r5, r5, lsl r1
|
|
+ cmp r2, #1 // 0x1
|
|
+ bcc ASM_PFX(_ll_udiv_small_label5)
|
|
+ sub r2, r2, #1 // 0x1
|
|
+ and r0, r2, #7 // 0x7
|
|
+ eor r0, r0, #7 // 0x7
|
|
+ adds r0, r0, r0, lsl #1
|
|
+ add pc, pc, r0, lsl #2
|
|
+ nop // (mov r0,r0)
|
|
+ASM_PFX(_ll_udiv_small_label4):
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ rsbcc r4, ip, r4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, ip, r4, lsl #1
|
|
+ sub r2, r2, #8 // 0x8
|
|
+ tst r2, r2
|
|
+ rsbcc r4, ip, r4
|
|
+ bpl ASM_PFX(_ll_udiv_small_label4)
|
|
+ASM_PFX(_ll_udiv_small_label5):
|
|
+ mov r2, r4, lsr r6
|
|
+ bic r4, r4, r2, lsl r6
|
|
+ adcs r0, r5, r5
|
|
+ adc r1, r4, r4
|
|
+ add r1, r1, r3, lsl r6
|
|
+ mov r3, #0 // 0x0
|
|
+ ldmia sp!, {r4, r5, r6, pc}
|
|
+
|
|
+ASM_PFX(_ll_udiv_big):
|
|
+ subs r0, r5, lr
|
|
+ mov r3, #0 // 0x0
|
|
+ sbcs r1, r4, ip
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ adcs r3, r3, #0 // 0x0
|
|
+ subs r0, r5, lr
|
|
+ sbcs r1, r4, ip
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ adcs r3, r3, #0 // 0x0
|
|
+ subs r0, r5, lr
|
|
+ sbcs r1, r4, ip
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ adcs r3, r3, #0 // 0x0
|
|
+ mov r1, #0 // 0x0
|
|
+ rsbs lr, lr, #0 // 0x0
|
|
+ rsc ip, ip, #0 // 0x0
|
|
+ cmp r6, #16 // 0x10
|
|
+ bcc ASM_PFX(_ll_udiv_big_label1)
|
|
+ movs r0, r4, lsr #14
|
|
+ moveq r4, r4, lsl #16
|
|
+ addeq r1, r1, #16 // 0x10
|
|
+ASM_PFX(_ll_udiv_big_label1):
|
|
+ sub r2, r6, r1
|
|
+ cmp r2, #8 // 0x8
|
|
+ bcc ASM_PFX(_ll_udiv_big_label2)
|
|
+ movs r0, r4, lsr #22
|
|
+ moveq r4, r4, lsl #8
|
|
+ addeq r1, r1, #8 // 0x8
|
|
+ASM_PFX(_ll_udiv_big_label2):
|
|
+ rsb r0, r1, #32 // 0x20
|
|
+ sub r2, r6, r1
|
|
+ orr r4, r4, r5, lsr r0
|
|
+ mov r5, r5, lsl r1
|
|
+ cmp r2, #1 // 0x1
|
|
+ bcc ASM_PFX(_ll_udiv_big_label4)
|
|
+ sub r2, r2, #1 // 0x1
|
|
+ and r0, r2, #3 // 0x3
|
|
+ rsb r0, r0, #3 // 0x3
|
|
+ adds r0, r0, r0, lsl #1
|
|
+ add pc, pc, r0, lsl #3
|
|
+ nop // (mov r0,r0)
|
|
+ASM_PFX(_ll_udiv_big_label3):
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, r4, r4
|
|
+ adcs r0, lr, r5
|
|
+ adcs r1, ip, r4
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, r4, r4
|
|
+ adcs r0, lr, r5
|
|
+ adcs r1, ip, r4
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, r4, r4
|
|
+ adcs r0, lr, r5
|
|
+ adcs r1, ip, r4
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ sub r2, r2, #4 // 0x4
|
|
+ adcs r5, r5, r5
|
|
+ adcs r4, r4, r4
|
|
+ adcs r0, lr, r5
|
|
+ adcs r1, ip, r4
|
|
+ tst r2, r2
|
|
+ movcs r5, r0
|
|
+ movcs r4, r1
|
|
+ bpl ASM_PFX(_ll_udiv_big_label3)
|
|
+ASM_PFX(_ll_udiv_big_label4):
|
|
+ mov r1, #0 // 0x0
|
|
+ mov r2, r5, lsr r6
|
|
+ bic r5, r5, r2, lsl r6
|
|
+ adcs r0, r5, r5
|
|
+ adc r1, r1, #0 // 0x0
|
|
+ movs lr, r3, lsl r6
|
|
+ mov r3, r4, lsr r6
|
|
+ bic r4, r4, r3, lsl r6
|
|
+ adc r1, r1, #0 // 0x0
|
|
+ adds r0, r0, lr
|
|
+ orr r2, r2, r4, ror r6
|
|
+ adc r1, r1, #0 // 0x0
|
|
+ ldmia sp!, {r4, r5, r6, pc}
|
|
+
|
|
+ASM_PFX(_ll_udiv_ginormous):
|
|
+ subs r2, r5, lr
|
|
+ mov r1, #0 // 0x0
|
|
+ sbcs r3, r4, ip
|
|
+ adc r0, r1, r1
|
|
+ movcc r2, r5
|
|
+ movcc r3, r4
|
|
+ ldmia sp!, {r4, r5, r6, pc}
|
|
+
|
|
+ASM_PFX(_ll_div0):
|
|
+ ldmia sp!, {r4, r5, r6, lr}
|
|
+ mov r0, #0 // 0x0
|
|
+ mov r1, #0 // 0x0
|
|
+ b ASM_PFX(__aeabi_ldiv0)
|
|
+
|
|
+ASM_PFX(__aeabi_ldiv0):
|
|
+ bx r14
|
|
+
|
|
+
|
|
--
|
|
2.5.0
|
|
|