Introduce CRT assembly replacements for __rt_sdiv, __rt_udiv,
__rt_udiv64, __rt_sdiv64, __rt_srsh, memcpy and memset.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Pete Batard <pete@akeo.ie>
---
ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtdiv.asm | 255 ++++++++++++++++++++
ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtsrsh.asm | 45 ++++
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf | 13 +-
ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c | 34 +++
ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c | 33 +++
5 files changed, 378 insertions(+), 2 deletions(-)
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtdiv.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtdiv.asm
new file mode 100644
index 000000000000..096dc6317318
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtdiv.asm
@@ -0,0 +1,255 @@
+///** @file
+//
+// This code provides replacement for MSVC CRT division functions
+//
+// Copyright (c) 2017, Pete Batard. All rights reserved.<BR>
+// Based on generated assembly of ReactOS' sdk/lib/crt/math/arm/__rt_###div.c,
+// Copyright (c) Timo Kreuzer. 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.
+//
+//**/
+
+ EXPORT _fltused
+ EXPORT __brkdiv0
+
+ EXPORT __rt_sdiv
+ EXPORT __rt_udiv
+ EXPORT __rt_udiv64
+ EXPORT __rt_sdiv64
+
+ AREA Math, CODE, READONLY
+
+_fltused
+ dcd 0x9875
+
+__brkdiv0
+ udf #249
+
+//
+// uint64_t __rt_udiv(uint32_t divisor, uint32_t dividend)
+//
+
+__rt_udiv
+ cmp r0, #0
+ beq __brkdiv0
+ push {r3-r5,lr}
+ mov r5,r0
+ mov r4,r1
+ cmp r5,r4
+ it hi
+ movhi r0,#0
+ bhi __rt_udiv_label3
+ clz r2,r5
+ clz r3,r4
+ subs r3,r2,r3
+ movs r1,#1
+ lsl r2,r5,r3
+ lsl r3,r1,r3
+ movs r0,#0
+__rt_udiv_label1
+ cmp r4,r2
+ bcc __rt_udiv_label2
+ orrs r0,r0,r3
+ subs r4,r4,r2
+__rt_udiv_label2
+ lsrs r2,r2,#1
+ lsrs r3,r3,#1
+ bne __rt_udiv_label1
+__rt_udiv_label3
+ mov r1,r4
+ pop {r3-r5,pc}
+
+//
+// uint64_t __rt_sdiv(int32_t divisor, int32_t dividend)
+//
+
+__rt_sdiv
+ cmp r0, #0
+ beq __brkdiv0
+ push {r4-r6,lr}
+ mov r4,r1
+ ands r6,r0,#0x80000000
+ it ne
+ rsbne r4,r4,#0
+ mov r5,r0
+ rsbs r5,r5,#0
+ cmp r5,r4
+ it hi
+ movhi r0,#0
+ bhi __rt_sdiv_label3
+ clz r2,r5
+ clz r3,r4
+ subs r3,r2,r3
+ movs r1,#1
+ lsl r2,r5,r3
+ lsl r3,r1,r3
+ movs r0,#0
+__rt_sdiv_label1
+ cmp r4,r2
+ bcc __rt_sdiv_label2
+ orrs r0,r0,r3
+ subs r4,r4,r2
+__rt_sdiv_label2
+ lsrs r2,r2,#1
+ lsrs r3,r3,#1
+ bne __rt_sdiv_label1
+__rt_sdiv_label3
+ cbz r6,__rt_sdiv_label4
+ rsbs r4,r4,#0
+__rt_sdiv_label4
+ mov r1,r4
+ pop {r4-r6,pc}
+
+//
+// typedef struct {
+// uint64_t quotient;
+// uint64_t modulus;
+// } udiv64_result_t;
+//
+// void __rt_udiv64_internal(udiv64_result_t *result, uint64_t divisor, uint64_t dividend)
+//
+
+__rt_udiv64_internal
+ orrs r1,r2,r3
+ beq __brkdiv0
+ push {r4-r8,lr}
+ mov r7,r3
+ mov r6,r2
+ mov r4,r0
+ ldrd r0,r5,[sp,#0x18]
+ cmp r7,r5
+ bcc __rt_udiv64_internal_label2
+ bhi __rt_udiv64_internal_label1
+ cmp r6,r0
+ bls __rt_udiv64_internal_label2
+__rt_udiv64_internal_label1
+ movs r3,#0
+ strd r3,r3,[r4]
+ b __rt_udiv64_internal_label8
+__rt_udiv64_internal_label2
+ clz r2,r7
+ cmp r2,#0x20
+ bne __rt_udiv64_internal_label3
+ clz r3,r6
+ add r2,r2,r3
+__rt_udiv64_internal_label3
+ clz r1,r5 ;
+ cmp r1,#0x20
+ bne __rt_udiv64_internal_label4
+ clz r3,r0
+ add r1,r1,r3
+__rt_udiv64_internal_label4
+ subs r1,r2,r1
+ rsb r3,r1,#0x20
+ lsr r3,r6,r3
+ lsl r2,r7,r1
+ orrs r2,r2,r3
+ sub r3,r1,#0x20
+ lsl r3,r6,r3
+ orrs r2,r2,r3
+ lsl r7,r6,r1
+ sub r3,r1,#0x20
+ movs r6,#1
+ lsls r6,r6,r3
+ movs r3,#1
+ mov lr,#0
+ lsl r1,r3,r1
+ mov r8,lr
+__rt_udiv64_internal_label5
+ cmp r5,r2
+ bcc __rt_udiv64_internal_label7
+ bhi __rt_udiv64_internal_label6
+ cmp r0,r7
+ bcc __rt_udiv64_internal_label7
+__rt_udiv64_internal_label6
+ subs r0,r0,r7
+ sbcs r5,r5,r2
+ orr lr,lr,r1
+ orr r8,r8,r6
+__rt_udiv64_internal_label7
+ lsls r3,r2,#0x1F
+ orr r7,r3,r7,lsr #1
+ lsls r3,r6,#0x1F
+ orr r1,r3,r1,lsr #1
+ lsrs r6,r6,#1
+ lsrs r2,r2,#1
+ orrs r3,r1,r6
+ bne __rt_udiv64_internal_label5
+ strd lr,r8,[r4]
+__rt_udiv64_internal_label8
+ str r5,[r4,#0xC]
+ str r0,[r4,#8]
+ pop {r4-r8,pc}
+
+//
+// {int64_t, int64_t} __rt_sdiv64(int64_t divisor, int64_t dividend)
+//
+
+__rt_sdiv64
+ push {r4-r6,lr}
+ sub sp,sp,#0x18
+ and r6,r1,#0x80000000
+ movs r4,r6
+ mov r5,r0
+ beq __rt_sdiv64_label1
+ movs r0,#0
+ rsbs r2,r2,#0
+ sbc r3,r0,r3
+__rt_sdiv64_label1
+ movs r4,r6
+ beq __rt_sdiv64_label2
+ movs r0,#0
+ rsbs r5,r5,#0
+ sbc r1,r0,r1
+__rt_sdiv64_label2
+ str r2,[sp]
+ str r3,[sp,#4]
+ mov r3,r1
+ mov r2,r5
+ add r0,sp,#8
+ bl __rt_udiv64_internal
+ movs r3,r6
+ beq __rt_sdiv64_label3
+ ldrd r3,r2,[sp,#0x10]
+ movs r1,#0
+ rsbs r3,r3,#0
+ sbcs r1,r1,r2
+ b __rt_sdiv64_label4
+__rt_sdiv64_label3
+ ldrd r3,r1,[sp,#0x10]
+__rt_sdiv64_label4
+ mov r2,r3
+ ldr r0,[sp,#8]
+ mov r3,r1
+ ldr r1,[sp,#0xC]
+ add sp,sp,#0x18
+ pop {r4-r6,pc}
+
+//
+// {uint64_t, uint64_t} __rt_udiv64(uint64_t divisor, uint64_t dividend)
+//
+
+__rt_udiv64
+ push {r4,r5,lr}
+ sub sp,sp,#0x1C
+ mov r4,r2
+ mov r2,r0
+ mov r5,r3
+ add r0,sp,#8
+ mov r3,r1
+ str r4,[sp]
+ str r5,[sp,#4]
+ bl __rt_udiv64_internal
+ ldrd r2,r3,[sp,#0x10]
+ ldrd r0,r1,[sp,#8]
+ add sp,sp,#0x1C
+ pop {r4,r5,pc}
+
+ END
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtsrsh.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtsrsh.asm
new file mode 100644
index 000000000000..2332dda823f2
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/rtsrsh.asm
@@ -0,0 +1,45 @@
+///** @file
+//
+// This code provides replacement for MSVC CRT __rt_srsh
+//
+// Copyright (c) Timo Kreuzer. 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.
+//
+//**/
+
+ EXPORT __rt_srsh
+
+ AREA Math, CODE, READONLY
+
+//
+// int64_t __rt_srsh(int64_t value, uint32_t shift);
+//
+
+__rt_srsh
+ rsbs r3, r2, #32
+ bmi __rt_srsh_label1
+ lsr r0, r0, r2
+ lsl r3, r1, r3
+ orr r0, r0, r3
+ asr r1, r1, r2
+ bx lr
+__rt_srsh_label1
+ cmp r2, 64
+ bhs __rt_srsh_label2
+ sub r3, r2, #32
+ asr r0, r1, r3
+ asr r1, r1, #32
+ bx lr
+__rt_srsh_label2
+ asr r1, r1, #32
+ mov r0, r1
+ bx lr
+
+ END
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
index 44333141a70a..0dacc5e5117d 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -23,8 +23,12 @@ [Defines]
LIBRARY_CLASS = CompilerIntrinsicsLib
[Sources]
- memcpy.c
- memset.c
+ memcpy.c | RVCT
+ memcpy.c | GCC
+ memcpy_ms.c | MSFT
+ memset.c | RVCT
+ memset.c | GCC
+ memset_ms.c | MSFT
[Sources.ARM]
Arm/mullu.asm | RVCT
@@ -94,6 +98,8 @@ [Sources.ARM]
Arm/llsr.S | GCC
Arm/llsl.S | GCC
+ Arm/rtdiv.asm | MSFT
+ Arm/rtsrsh.asm | MSFT
[Packages]
MdePkg/MdePkg.dec
@@ -101,3 +107,6 @@ [Packages]
[LibraryClasses]
+[BuildOptions]
+ MSFT:*_*_ARM_CC_FLAGS = /GL-
+ MSFT:*_*_AARCH64_CC_FLAGS = /GL-
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c b/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c
new file mode 100644
index 000000000000..90bbbb930d31
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c
@@ -0,0 +1,34 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2017, Pete Batard. 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.
+//
+//------------------------------------------------------------------------------
+
+#if defined(_M_ARM64)
+typedef unsigned __int64 size_t;
+#else
+typedef unsigned __int32 size_t;
+#endif
+
+void* memcpy(void *, const void *, size_t);
+#pragma intrinsic(memcpy)
+#pragma function(memcpy)
+void* memcpy(void *dest, const void *src, size_t n)
+{
+ unsigned char *d = dest;
+ unsigned char const *s = src;
+
+ while (n--)
+ *d++ = *s++;
+
+ return dest;
+}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c b/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c
new file mode 100644
index 000000000000..64205e5d1012
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2017, Pete Batard. 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.
+//
+//------------------------------------------------------------------------------
+
+#if defined(_M_ARM64)
+typedef unsigned __int64 size_t;
+#else
+typedef unsigned __int32 size_t;
+#endif
+
+void* memset(void *, int, size_t);
+#pragma intrinsic(memset)
+#pragma function(memset)
+void *memset(void *s, int c, size_t n)
+{
+ unsigned char *d = s;
+
+ while (n--)
+ *d++ = (unsigned char)c;
+
+ return s;
+}
--
2.9.3.windows.2
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.