]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S
MdePkg/BaseMemoryLibOptDxe: add accelerated ARM routines
[mirror_edk2.git] / MdePkg / Library / BaseMemoryLibOptDxe / Arm / SetMem.S
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S
new file mode 100644 (file)
index 0000000..c175553
--- /dev/null
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+    .text\r
+    .thumb\r
+    .syntax unified\r
+    .align  5\r
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)\r
+ASM_PFX(InternalMemZeroMem):\r
+    movs    r2, #0\r
+\r
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)\r
+ASM_PFX(InternalMemSetMem):\r
+    uxtb    r2, r2\r
+    orr     r2, r2, r2, lsl #8\r
+\r
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)\r
+ASM_PFX(InternalMemSetMem16):\r
+    uxth    r2, r2\r
+    orr     r2, r2, r2, lsl #16\r
+\r
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)\r
+ASM_PFX(InternalMemSetMem32):\r
+    mov     r3, r2\r
+\r
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)\r
+ASM_PFX(InternalMemSetMem64):\r
+    push    {r4, lr}\r
+    cmp     r1, #16                 // fewer than 16 bytes of input?\r
+    add     r1, r1, r0              // r1 := dst + length\r
+    add     lr, r0, #16\r
+    blt     2f\r
+    bic     lr, lr, #15             // align output pointer\r
+\r
+    str     r2, [r0]                // potentially unaligned store of 4 bytes\r
+    str     r3, [r0, #4]            // potentially unaligned store of 4 bytes\r
+    str     r2, [r0, #8]            // potentially unaligned store of 4 bytes\r
+    str     r3, [r0, #12]           // potentially unaligned store of 4 bytes\r
+    beq     1f\r
+\r
+0:  add     lr, lr, #16             // advance the output pointer by 16 bytes\r
+    subs    r4, r1, lr              // past the output?\r
+    blt     3f                      // break out of the loop\r
+    strd    r2, r3, [lr, #-16]      // aligned store of 16 bytes\r
+    strd    r2, r3, [lr, #-8]\r
+    bne     0b                      // goto beginning of loop\r
+1:  pop     {r4, pc}\r
+\r
+2:  subs    r4, r1, lr\r
+3:  adds    r4, r4, #16\r
+    subs    r1, r1, #8\r
+    cmp     r4, #4                  // between 4 and 15 bytes?\r
+    blt     4f\r
+    cmp     r4, #8                  // between 8 and 15 bytes?\r
+    str     r2, [lr, #-16]          // overlapping store of 4 + (4 + 4) + 4 bytes\r
+    itt     gt\r
+    strgt   r3, [lr, #-12]\r
+    strgt   r2, [r1]\r
+    str     r3, [r1, #4]\r
+    pop     {r4, pc}\r
+\r
+4:  cmp     r4, #2                  // 2 or 3 bytes?\r
+    strb    r2, [lr, #-16]          // store 1 byte\r
+    it      ge\r
+    strhge  r2, [r1, #6]            // store 2 bytes\r
+    pop     {r4, pc}\r