[edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds

Pete Batard posted 6 patches 7 years ago
There is a newer version of this series
[edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
Posted by Pete Batard 7 years ago
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
Re: [edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
Posted by Ard Biesheuvel 7 years ago
Hi Pete,

On 8 December 2017 at 14:06, Pete Batard <pete@akeo.ie> wrote:
> 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
> +

Why are these being exported? Are these part of the CRT ABI?

> +  EXPORT __rt_sdiv
> +  EXPORT __rt_udiv
> +  EXPORT __rt_udiv64
> +  EXPORT __rt_sdiv64
> +
> +  AREA  Math, CODE, READONLY
> +
> +_fltused
> +    dcd 0x9875
> +
> +__brkdiv0
> +    udf #249
> +

This will cause a crash when invoked, in a way that gives very little
to go on to figure out what happens. Perhaps branch to a C function
here that calls ASSERT() and CpuDeadLoop ?

> +//
> +// uint64_t __rt_udiv(uint32_t divisor, uint32_t dividend)
> +//

There are many different division implementations already in the same
directory. Do we really need a new one?

> +
> +__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)
> +//
> +

Does signed division return an unsigned result? And do we really need
yet another implementation?

> +__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);
> +//
> +

Same questions here, basically.

> +__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;
> +}

These look fine to me.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
Posted by Pete Batard 7 years ago
Hi Ard. Thanks for reviewing this.

On 2017.12.12 19:59, Ard Biesheuvel wrote:
>> +  EXPORT _fltused
>> +  EXPORT __brkdiv0
>> +
> 
> Why are these being exported? Are these part of the CRT ABI?

Good point. I exported them because I was encountering undefined symbols 
for those when I started working on adding ARM support. But I now 
suspect they may have come from an export statement from VS headers 
(which we no longer include), as re-test shows that the exports seem to 
be superfluous.

I will test further to confirm that this is the case, and remove the 
unneeded exports.

>> +__brkdiv0
>> +    udf #249
>> +
> 
> This will cause a crash when invoked, in a way that gives very little
> to go on to figure out what happens.

Yes. I mostly copied what ReactOS was doing here, since it should be 
similar to what Microsoft does internally.

> Perhaps branch to a C function
> here that calls ASSERT() and CpuDeadLoop ?

I don't mind giving it a try, if we keep the separate .asm files for MSVC.

On the other hand, if I am to try to reuse existing assembly, as you 
suggest below, then I don't think I want to introduce anything that will 
differ from how divisions by zero are currently handled there. As far as 
I can tell (for RVCT, which is the only assembly that might be suitable 
for reuse with MSFT) the current way of handling a zero divisor is to 
set result and remainder to 0 and return (as per uldiv.asm). For gcc, we 
also have the following comment in div.S:

   "@ What to do about division by zero?  For now, just return."

So, while I agree that calling ASSERT and CpuDeadLoop is probably the 
better approach, I'd rather have the introduction of this behaviour be 
the subject of a separate ARM harmonization patch, that applies to all 
the toolchains, rather than something that's specific to Visual Studio 
usage.

> There are many different division implementations already in the same
> directory. Do we really need a new one?

I'll look into that. My goal with this series was to make sure that the 
changes being introduced would not break existing toolchains, which is 
why I saw it preferable to keep the MSVC intrinsics separate.

Now, gcc assembly is not something that can be reused easily with the MS 
toolchain, so the only possibility are the RVCT .asm files.

There's a fair bit of work involved into trying to figure out if and how 
we can reuse that code, but I'll see what I can do. It'll probably be a 
few weeks before I get back to this list on that however.

Regards,

/Pete
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
Posted by Ard Biesheuvel 7 years ago
On 13 December 2017 at 14:56, Pete Batard <pete@akeo.ie> wrote:
> Hi Ard. Thanks for reviewing this.
>
> On 2017.12.12 19:59, Ard Biesheuvel wrote:
>>>
>>> +  EXPORT _fltused
>>> +  EXPORT __brkdiv0
>>> +
>>
>>
>> Why are these being exported? Are these part of the CRT ABI?
>
>
> Good point. I exported them because I was encountering undefined symbols for
> those when I started working on adding ARM support. But I now suspect they
> may have come from an export statement from VS headers (which we no longer
> include), as re-test shows that the exports seem to be superfluous.
>
> I will test further to confirm that this is the case, and remove the
> unneeded exports.
>
>>> +__brkdiv0
>>> +    udf #249
>>> +
>>
>>
>> This will cause a crash when invoked, in a way that gives very little
>> to go on to figure out what happens.
>
>
> Yes. I mostly copied what ReactOS was doing here, since it should be similar
> to what Microsoft does internally.
>
>> Perhaps branch to a C function
>> here that calls ASSERT() and CpuDeadLoop ?
>
>
> I don't mind giving it a try, if we keep the separate .asm files for MSVC.
>
> On the other hand, if I am to try to reuse existing assembly, as you suggest
> below, then I don't think I want to introduce anything that will differ from
> how divisions by zero are currently handled there. As far as I can tell (for
> RVCT, which is the only assembly that might be suitable for reuse with MSFT)
> the current way of handling a zero divisor is to set result and remainder to
> 0 and return (as per uldiv.asm). For gcc, we also have the following comment
> in div.S:
>
>   "@ What to do about division by zero?  For now, just return."
>
> So, while I agree that calling ASSERT and CpuDeadLoop is probably the better
> approach, I'd rather have the introduction of this behaviour be the subject
> of a separate ARM harmonization patch, that applies to all the toolchains,
> rather than something that's specific to Visual Studio usage.
>

I agree. Reusing code is more important than having one flavour of
division that will spot div-by-0. But we really don't want the UDF,
because it will crash unconditionally without a hint of what happened.

>> There are many different division implementations already in the same
>> directory. Do we really need a new one?
>
>
> I'll look into that. My goal with this series was to make sure that the
> changes being introduced would not break existing toolchains, which is why I
> saw it preferable to keep the MSVC intrinsics separate.
>
> Now, gcc assembly is not something that can be reused easily with the MS
> toolchain, so the only possibility are the RVCT .asm files.
>
> There's a fair bit of work involved into trying to figure out if and how we
> can reuse that code, but I'll see what I can do. It'll probably be a few
> weeks before I get back to this list on that however.
>

I'm prepared to be pragmatic here. I would prefer to have all
platforms run the same low level division code, but I understand that
it is tightly coupled to the compiler, given that they are intrinsics.

So yes, please try to reuse the RVCT code if feasible without a ton of
rework, but it seems like we will need to live with some MSFT specific
hooks anyway (if I understand the prototypes correctly)
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
Posted by Gao, Liming 7 years ago
Include ArmPkg maintainers for review. 

> -----Original Message-----
> From: Pete Batard [mailto:pete@akeo.ie]
> Sent: Friday, December 8, 2017 10:06 PM
> To: edk2-devel@lists.01.org
> Cc: Gao, Liming <liming.gao@intel.com>
> Subject: [PATCH v3 4/6] ArmPkg/Library/CompilerIntrinsicsLib: Enable VS2017/ARM builds
> 
> 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