From e58427e3964e50caf274d4ba84a984f0cdfcd90d Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 12 Jan 2018 21:33:29 +0800 Subject: [PATCH] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds Introduce CRT assembly replacements for __rt_sdiv, __rt_udiv, __rt_udiv64, __rt_sdiv64, __rt_srsh (by reusing the RVCT code) as well as memcpy and memset. For MSFT compatibility, some of the code needs to be explicitly forced to ARM, and the /oldit assembly flag needs to be added. Also, while RVCT_ASM_EXPORT macro invocations have been removed, the replacement code is designed to be as close as possible to the one that would have been generated if using the macros. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Pete Batard Reviewed-by: Ard Biesheuvel --- .../Library/CompilerIntrinsicsLib/Arm/div.asm | 43 ++++++++++++++++--- .../CompilerIntrinsicsLib/Arm/ldivmod.asm | 40 ++++++++++++----- .../CompilerIntrinsicsLib/Arm/llsr.asm | 22 +++++----- .../CompilerIntrinsicsLib/Arm/uldiv.asm | 29 +++++++++++-- .../CompilerIntrinsicsLib.inf | 16 ++++++- .../Library/CompilerIntrinsicsLib/memcpy_ms.c | 34 +++++++++++++++ .../Library/CompilerIntrinsicsLib/memset_ms.c | 33 ++++++++++++++ 7 files changed, 185 insertions(+), 32 deletions(-) create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm index b539e51689..f9e0107395 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+// Copyright (c) 2018, Pete Batard. All rights reserved.
// // This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License @@ -17,18 +18,19 @@ EXPORT __aeabi_uidivmod EXPORT __aeabi_idiv EXPORT __aeabi_idivmod + EXPORT __rt_udiv + EXPORT __rt_sdiv AREA Math, CODE, READONLY ; ;UINT32 ;EFIAPI -;__aeabi_uidivmode ( -; IN UINT32 Dividen +;__aeabi_uidivmod ( +; IN UINT32 Dividend ; IN UINT32 Divisor ; ); ; - __aeabi_uidiv __aeabi_uidivmod RSBS r12, r1, r0, LSR #4 @@ -39,11 +41,41 @@ __aeabi_uidivmod MOV r3, #0 B __arm_div_large +; +;UINT64 +;EFIAPI +;__rt_udiv ( +; IN UINT32 Divisor, +; IN UINT32 Dividend +; ); +; +__rt_udiv + ; Swap R0 and R1 + MOV r12, r0 + MOV r0, r1 + MOV r1, r12 + B __aeabi_uidivmod + +; +;UINT64 +;EFIAPI +;__rt_sdiv ( +; IN INT32 Divisor, +; IN INT32 Dividend +; ); +; +__rt_sdiv + ; Swap R0 and R1 + MOV r12, r0 + MOV r0, r1 + MOV r1, r12 + B __aeabi_idivmod + ; ;INT32 ;EFIAPI -;__aeabi_idivmode ( -; IN INT32 Dividen +;__aeabi_idivmod ( +; IN INT32 Dividend ; IN INT32 Divisor ; ); ; @@ -152,4 +184,3 @@ __aeabi_idiv0 BX r14 END - diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm index c71bd59e45..115a2b9c0e 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+// Copyright (c) 2018, Pete Batard. All rights reserved.
// // This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License @@ -13,20 +14,41 @@ //------------------------------------------------------------------------------ - EXTERN __aeabi_uldivmod + IMPORT __aeabi_uldivmod + EXPORT __aeabi_ldivmod + EXPORT __rt_sdiv64 - INCLUDE AsmMacroExport.inc + AREA s___aeabi_ldivmod, CODE, READONLY, ARM + + ARM ; -;UINT32 +;INT64 ;EFIAPI -;__aeabi_uidivmode ( -; IN UINT32 Dividen -; IN UINT32 Divisor +;__rt_sdiv64 ( +; IN INT64 Divisor +; IN INT64 Dividend ; ); ; +__rt_sdiv64 + ; Swap r0-r1 and r2-r3 + MOV r12, r0 + MOV r0, r2 + MOV r2, r12 + MOV r12, r1 + MOV r1, r3 + MOV r3, r12 + B __aeabi_ldivmod - RVCT_ASM_EXPORT __aeabi_ldivmod +; +;INT64 +;EFIAPI +;__aeabi_ldivmod ( +; IN INT64 Dividend +; IN INT64 Divisor +; ); +; +__aeabi_ldivmod PUSH {r4,lr} ASRS r4,r1,#1 EOR r4,r4,r3,LSR #1 @@ -39,7 +61,7 @@ L_Test1 RSBS r2,r2,#0 RSC r3,r3,#0 L_Test2 - BL __aeabi_uldivmod ; + BL __aeabi_uldivmod TST r4,#0x40000000 BEQ L_Test3 RSBS r0,r0,#0 @@ -53,5 +75,3 @@ L_Exit POP {r4,pc} END - - diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm index 881db106d9..abfd7ab64a 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+// Copyright (c) 2018, Pete Batard. All rights reserved.
// // This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License @@ -12,32 +13,33 @@ // //------------------------------------------------------------------------------ + EXPORT __aeabi_llsr + EXPORT __rt_srsh + AREA s___aeabi_llsr, CODE, READONLY, ARM - INCLUDE AsmMacroExport.inc + ARM ; ;VOID ;EFIAPI ;__aeabi_llsr ( -; IN VOID *Destination, -; IN VOID *Source, -; IN UINT32 Size -; ); +; IN UINT64 Value, +; IN UINT32 Shift +;) ; - RVCT_ASM_EXPORT __aeabi_llsr +__aeabi_llsr +__rt_srsh SUBS r3,r2,#0x20 - BPL {pc} + 0x18 ; 0x1c + BPL __aeabi_llsr_label1 RSB r3,r2,#0x20 LSR r0,r0,r2 ORR r0,r0,r1,LSL r3 LSR r1,r1,r2 BX lr +__aeabi_llsr_label1 LSR r0,r1,r3 MOV r1,#0 BX lr END - - - diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm index 6b6184ebd3..aedaac8c6c 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+// Copyright (c) 2018, Pete Batard. All rights reserved.
// // This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License @@ -13,9 +14,30 @@ //------------------------------------------------------------------------------ + EXPORT __aeabi_uldivmod + EXPORT __rt_udiv64 + AREA s___aeabi_uldivmod, CODE, READONLY, ARM - INCLUDE AsmMacroExport.inc + ARM + +; +;UINT64 +;EFIAPI +;__rt_udiv64 ( +; IN UINT64 Divisor +; IN UINT64 Dividend +; ) +; +__rt_udiv64 + ; Swap r0-r1 and r2-r3 + mov r12, r0 + mov r0, r2 + mov r2, r12 + mov r12, r1 + mov r1, r3 + mov r3, r12 + b __aeabi_uldivmod ; ;UINT64 @@ -25,7 +47,7 @@ ; IN UINT64 Divisor ; ) ; - RVCT_ASM_EXPORT __aeabi_uldivmod +__aeabi_uldivmod stmdb sp!, {r4, r5, r6, lr} mov r4, r1 mov r5, r0 @@ -261,7 +283,6 @@ _ll_div0 b __aeabi_ldiv0 __aeabi_ldiv0 - BX r14 + bx r14 END - diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf index 44333141a7..14e88da7ce 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf +++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf @@ -23,8 +23,12 @@ 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,10 @@ Arm/llsr.S | GCC Arm/llsl.S | GCC + Arm/div.asm | MSFT + Arm/uldiv.asm | MSFT + Arm/ldivmod.asm | MSFT + Arm/llsr.asm | MSFT [Packages] MdePkg/MdePkg.dec @@ -101,3 +109,7 @@ [LibraryClasses] +[BuildOptions] + MSFT:*_*_ARM_CC_FLAGS = /GL- + MSFT:*_*_ARM_ASM_FLAGS = /oldit + 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 0000000000..90bbbb930d --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017, Pete Batard. 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. +// +//------------------------------------------------------------------------------ + +#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 0000000000..64205e5d10 --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017, Pete Batard. 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. +// +//------------------------------------------------------------------------------ + +#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.39.2