summaryrefslogtreecommitdiff
path: root/MdePkg/Library/BaseMemoryLibOptDxe
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2017-03-07 20:53:26 +0000
committerWarner Losh <imp@FreeBSD.org>2017-03-07 20:53:26 +0000
commit0499b37cea9ca98acfe36368e521ad36b7783f2d (patch)
tree7968fdc8d6edf3e051bbd434a466eca88aacf938 /MdePkg/Library/BaseMemoryLibOptDxe
Notes
Diffstat (limited to 'MdePkg/Library/BaseMemoryLibOptDxe')
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareGuid.S40
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S142
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S284
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S161
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S247
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.S65
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.asm70
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.S138
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.asm140
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.S175
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.asm147
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/MemLibGuid.c165
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.S148
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.asm147
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMemGeneric.c142
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S89
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.asm96
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf174
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni22
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c66
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c63
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm56
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.nasm57
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S85
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm84
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.nasm84
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/IsZeroBuffer.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S52
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.nasm54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S52
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.nasm54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S61
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm64
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.nasm63
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S52
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.nasm54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S50
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm53
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.nasm52
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S43
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm45
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.nasm44
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S43
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm45
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.nasm44
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S46
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm49
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.nasm48
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S49
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm50
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.nasm49
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/IsZeroBufferWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c171
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h251
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c67
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c66
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c67
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c100
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c64
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c64
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c64
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c91
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S59
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.nasm58
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S82
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm79
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.nasm83
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/IsZeroBuffer.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S56
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm53
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S56
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm53
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm53
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S56
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm53
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.nasm55
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S57
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm58
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.nasm62
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S47
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm45
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.nasm47
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S47
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm45
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.nasm47
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S46
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm44
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.nasm46
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S51
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm48
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.nasm50
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c56
101 files changed, 7558 insertions, 0 deletions
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareGuid.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareGuid.S
new file mode 100644
index 000000000000..8544c018c4f5
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareGuid.S
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+ .text
+ .align 5
+ASM_GLOBAL ASM_PFX(InternalMemCompareGuid)
+ASM_PFX(InternalMemCompareGuid):
+ mov x2, xzr
+ ldp x3, x4, [x0]
+ cbz x1, 0f
+ ldp x1, x2, [x1]
+0: cmp x1, x3
+ ccmp x2, x4, #0, eq
+ cset w0, eq
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S
new file mode 100644
index 000000000000..7e5bf8a6c334
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S
@@ -0,0 +1,142 @@
+//
+// Copyright (c) 2013, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64
+//
+
+
+// Parameters and result.
+#define src1 x0
+#define src2 x1
+#define limit x2
+#define result x0
+
+// Internal variables.
+#define data1 x3
+#define data1w w3
+#define data2 x4
+#define data2w w4
+#define diff x6
+#define endloop x7
+#define tmp1 x8
+#define tmp2 x9
+#define pos x11
+#define limit_wd x12
+#define mask x13
+
+ .p2align 6
+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ eor tmp1, src1, src2
+ tst tmp1, #7
+ b.ne .Lmisaligned8
+ ands tmp1, src1, #7
+ b.ne .Lmutual_align
+ add limit_wd, limit, #7
+ lsr limit_wd, limit_wd, #3
+
+ // Start of performance-critical section -- one 64B cache line.
+.Lloop_aligned:
+ ldr data1, [src1], #8
+ ldr data2, [src2], #8
+.Lstart_realigned:
+ subs limit_wd, limit_wd, #1
+ eor diff, data1, data2 // Non-zero if differences found.
+ csinv endloop, diff, xzr, ne // Last Dword or differences.
+ cbz endloop, .Lloop_aligned
+ // End of performance-critical section -- one 64B cache line.
+
+ // Not reached the limit, must have found a diff.
+ cbnz limit_wd, .Lnot_limit
+
+ // Limit % 8 == 0 => all bytes significant.
+ ands limit, limit, #7
+ b.eq .Lnot_limit
+
+ lsl limit, limit, #3 // Bits -> bytes.
+ mov mask, #~0
+ lsl mask, mask, limit
+ bic data1, data1, mask
+ bic data2, data2, mask
+
+ orr diff, diff, mask
+
+.Lnot_limit:
+ rev diff, diff
+ rev data1, data1
+ rev data2, data2
+
+ // The MS-non-zero bit of DIFF marks either the first bit
+ // that is different, or the end of the significant data.
+ // Shifting left now will bring the critical information into the
+ // top bits.
+ clz pos, diff
+ lsl data1, data1, pos
+ lsl data2, data2, pos
+
+ // But we need to zero-extend (char is unsigned) the value and then
+ // perform a signed 32-bit subtraction.
+ lsr data1, data1, #56
+ sub result, data1, data2, lsr #56
+ ret
+
+.Lmutual_align:
+ // Sources are mutually aligned, but are not currently at an
+ // alignment boundary. Round down the addresses and then mask off
+ // the bytes that precede the start point.
+ bic src1, src1, #7
+ bic src2, src2, #7
+ add limit, limit, tmp1 // Adjust the limit for the extra.
+ lsl tmp1, tmp1, #3 // Bytes beyond alignment -> bits.
+ ldr data1, [src1], #8
+ neg tmp1, tmp1 // Bits to alignment -64.
+ ldr data2, [src2], #8
+ mov tmp2, #~0
+
+ // Little-endian. Early bytes are at LSB.
+ lsr tmp2, tmp2, tmp1 // Shift (tmp1 & 63).
+ add limit_wd, limit, #7
+ orr data1, data1, tmp2
+ orr data2, data2, tmp2
+ lsr limit_wd, limit_wd, #3
+ b .Lstart_realigned
+
+ .p2align 6
+.Lmisaligned8:
+ sub limit, limit, #1
+1:
+ // Perhaps we can do better than this.
+ ldrb data1w, [src1], #1
+ ldrb data2w, [src2], #1
+ subs limit, limit, #1
+ ccmp data1w, data2w, #0, cs // NZCV = 0b0000.
+ b.eq 1b
+ sub result, data1, data2
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S
new file mode 100644
index 000000000000..fdba763f8b47
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S
@@ -0,0 +1,284 @@
+//
+// Copyright (c) 2012 - 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// Copyright (c) 2015 ARM Ltd
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the company may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64, unaligned accesses.
+//
+//
+
+#define dstin x0
+#define src x1
+#define count x2
+#define dst x3
+#define srcend x4
+#define dstend x5
+#define A_l x6
+#define A_lw w6
+#define A_h x7
+#define A_hw w7
+#define B_l x8
+#define B_lw w8
+#define B_h x9
+#define C_l x10
+#define C_h x11
+#define D_l x12
+#define D_h x13
+#define E_l x14
+#define E_h x15
+#define F_l srcend
+#define F_h dst
+#define tmp1 x9
+#define tmp2 x3
+
+#define L(l) .L ## l
+
+// Copies are split into 3 main cases: small copies of up to 16 bytes,
+// medium copies of 17..96 bytes which are fully unrolled. Large copies
+// of more than 96 bytes align the destination and use an unrolled loop
+// processing 64 bytes per iteration.
+// Small and medium copies read all data before writing, allowing any
+// kind of overlap, and memmove tailcalls memcpy for these cases as
+// well as non-overlapping copies.
+
+__memcpy:
+ prfm PLDL1KEEP, [src]
+ add srcend, src, count
+ add dstend, dstin, count
+ cmp count, 16
+ b.ls L(copy16)
+ cmp count, 96
+ b.hi L(copy_long)
+
+ // Medium copies: 17..96 bytes.
+ sub tmp1, count, 1
+ ldp A_l, A_h, [src]
+ tbnz tmp1, 6, L(copy96)
+ ldp D_l, D_h, [srcend, -16]
+ tbz tmp1, 5, 1f
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [srcend, -32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstend, -32]
+1:
+ stp A_l, A_h, [dstin]
+ stp D_l, D_h, [dstend, -16]
+ ret
+
+ .p2align 4
+ // Small copies: 0..16 bytes.
+L(copy16):
+ cmp count, 8
+ b.lo 1f
+ ldr A_l, [src]
+ ldr A_h, [srcend, -8]
+ str A_l, [dstin]
+ str A_h, [dstend, -8]
+ ret
+ .p2align 4
+1:
+ tbz count, 2, 1f
+ ldr A_lw, [src]
+ ldr A_hw, [srcend, -4]
+ str A_lw, [dstin]
+ str A_hw, [dstend, -4]
+ ret
+
+ // Copy 0..3 bytes. Use a branchless sequence that copies the same
+ // byte 3 times if count==1, or the 2nd byte twice if count==2.
+1:
+ cbz count, 2f
+ lsr tmp1, count, 1
+ ldrb A_lw, [src]
+ ldrb A_hw, [srcend, -1]
+ ldrb B_lw, [src, tmp1]
+ strb A_lw, [dstin]
+ strb B_lw, [dstin, tmp1]
+ strb A_hw, [dstend, -1]
+2: ret
+
+ .p2align 4
+ // Copy 64..96 bytes. Copy 64 bytes from the start and
+ // 32 bytes from the end.
+L(copy96):
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [src, 32]
+ ldp D_l, D_h, [src, 48]
+ ldp E_l, E_h, [srcend, -32]
+ ldp F_l, F_h, [srcend, -16]
+ stp A_l, A_h, [dstin]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin, 32]
+ stp D_l, D_h, [dstin, 48]
+ stp E_l, E_h, [dstend, -32]
+ stp F_l, F_h, [dstend, -16]
+ ret
+
+ // Align DST to 16 byte alignment so that we don't cross cache line
+ // boundaries on both loads and stores. There are at least 96 bytes
+ // to copy, so copy 16 bytes unaligned and then align. The loop
+ // copies 64 bytes per iteration and prefetches one iteration ahead.
+
+ .p2align 4
+L(copy_long):
+ and tmp1, dstin, 15
+ bic dst, dstin, 15
+ ldp D_l, D_h, [src]
+ sub src, src, tmp1
+ add count, count, tmp1 // Count is now 16 too large.
+ ldp A_l, A_h, [src, 16]
+ stp D_l, D_h, [dstin]
+ ldp B_l, B_h, [src, 32]
+ ldp C_l, C_h, [src, 48]
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 128 + 16 // Test and readjust count.
+ b.ls 2f
+1:
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [src, 16]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [src, 32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [src, 48]
+ stp D_l, D_h, [dst, 64]!
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 64
+ b.hi 1b
+
+ // Write the last full set of 64 bytes. The remainder is at most 64
+ // bytes, so it is safe to always copy 64 bytes from the end even if
+ // there is just 1 byte left.
+2:
+ ldp E_l, E_h, [srcend, -64]
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [srcend, -48]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [srcend, -16]
+ stp D_l, D_h, [dst, 64]
+ stp E_l, E_h, [dstend, -64]
+ stp A_l, A_h, [dstend, -48]
+ stp B_l, B_h, [dstend, -32]
+ stp C_l, C_h, [dstend, -16]
+ ret
+
+
+//
+// All memmoves up to 96 bytes are done by memcpy as it supports overlaps.
+// Larger backwards copies are also handled by memcpy. The only remaining
+// case is forward large copies. The destination is aligned, and an
+// unrolled loop processes 64 bytes per iteration.
+//
+
+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ sub tmp2, dstin, src
+ cmp count, 96
+ ccmp tmp2, count, 2, hi
+ b.hs __memcpy
+
+ cbz tmp2, 3f
+ add dstend, dstin, count
+ add srcend, src, count
+
+ // Align dstend to 16 byte alignment so that we don't cross cache line
+ // boundaries on both loads and stores. There are at least 96 bytes
+ // to copy, so copy 16 bytes unaligned and then align. The loop
+ // copies 64 bytes per iteration and prefetches one iteration ahead.
+
+ and tmp2, dstend, 15
+ ldp D_l, D_h, [srcend, -16]
+ sub srcend, srcend, tmp2
+ sub count, count, tmp2
+ ldp A_l, A_h, [srcend, -16]
+ stp D_l, D_h, [dstend, -16]
+ ldp B_l, B_h, [srcend, -32]
+ ldp C_l, C_h, [srcend, -48]
+ ldp D_l, D_h, [srcend, -64]!
+ sub dstend, dstend, tmp2
+ subs count, count, 128
+ b.ls 2f
+ nop
+1:
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [srcend, -16]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [srcend, -48]
+ stp D_l, D_h, [dstend, -64]!
+ ldp D_l, D_h, [srcend, -64]!
+ subs count, count, 64
+ b.hi 1b
+
+ // Write the last full set of 64 bytes. The remainder is at most 64
+ // bytes, so it is safe to always copy 64 bytes from the start even if
+ // there is just 1 byte left.
+2:
+ ldp E_l, E_h, [src, 48]
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [src, 32]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [src, 16]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [src]
+ stp D_l, D_h, [dstend, -64]
+ stp E_l, E_h, [dstin, 48]
+ stp A_l, A_h, [dstin, 32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin]
+3: ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S
new file mode 100644
index 000000000000..708ebb59c423
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2014, ARM Limited
+// All rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the company nor the names of its contributors
+// may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64
+// Neon Available.
+//
+
+// Arguments and results.
+#define srcin x0
+#define cntin x1
+#define chrin w2
+
+#define result x0
+
+#define src x3
+#define tmp x4
+#define wtmp2 w5
+#define synd x6
+#define soff x9
+#define cntrem x10
+
+#define vrepchr v0
+#define vdata1 v1
+#define vdata2 v2
+#define vhas_chr1 v3
+#define vhas_chr2 v4
+#define vrepmask v5
+#define vend v6
+
+//
+// Core algorithm:
+//
+// For each 32-byte chunk we calculate a 64-bit syndrome value, with two bits
+// per byte. For each tuple, bit 0 is set if the relevant byte matched the
+// requested character and bit 1 is not used (faster than using a 32bit
+// syndrome). Since the bits in the syndrome reflect exactly the order in which
+// things occur in the original string, counting trailing zeros allows to
+// identify exactly which byte has matched.
+//
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ // Do not dereference srcin if no bytes to compare.
+ cbz cntin, .Lzero_length
+ //
+ // Magic constant 0x40100401 allows us to identify which lane matches
+ // the requested byte.
+ //
+ mov wtmp2, #0x0401
+ movk wtmp2, #0x4010, lsl #16
+ dup vrepchr.16b, chrin
+ // Work with aligned 32-byte chunks
+ bic src, srcin, #31
+ dup vrepmask.4s, wtmp2
+ ands soff, srcin, #31
+ and cntrem, cntin, #31
+ b.eq .Lloop
+
+ //
+ // Input string is not 32-byte aligned. We calculate the syndrome
+ // value for the aligned 32 bytes block containing the first bytes
+ // and mask the irrelevant part.
+ //
+
+ ld1 {vdata1.16b, vdata2.16b}, [src], #32
+ sub tmp, soff, #32
+ adds cntin, cntin, tmp
+ cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
+ cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
+ and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
+ and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
+ addp vend.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
+ addp vend.16b, vend.16b, vend.16b // 128->64
+ mov synd, vend.d[0]
+ // Clear the soff*2 lower bits
+ lsl tmp, soff, #1
+ lsr synd, synd, tmp
+ lsl synd, synd, tmp
+ // The first block can also be the last
+ b.ls .Lmasklast
+ // Have we found something already?
+ cbnz synd, .Ltail
+
+.Lloop:
+ ld1 {vdata1.16b, vdata2.16b}, [src], #32
+ subs cntin, cntin, #32
+ cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
+ cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
+ // If we're out of data we finish regardless of the result
+ b.ls .Lend
+ // Use a fast check for the termination condition
+ orr vend.16b, vhas_chr1.16b, vhas_chr2.16b
+ addp vend.2d, vend.2d, vend.2d
+ mov synd, vend.d[0]
+ // We're not out of data, loop if we haven't found the character
+ cbz synd, .Lloop
+
+.Lend:
+ // Termination condition found, let's calculate the syndrome value
+ and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
+ and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
+ addp vend.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
+ addp vend.16b, vend.16b, vend.16b // 128->64
+ mov synd, vend.d[0]
+ // Only do the clear for the last possible block
+ b.hi .Ltail
+
+.Lmasklast:
+ // Clear the (32 - ((cntrem + soff) % 32)) * 2 upper bits
+ add tmp, cntrem, soff
+ and tmp, tmp, #31
+ sub tmp, tmp, #32
+ neg tmp, tmp, lsl #1
+ lsl synd, synd, tmp
+ lsr synd, synd, tmp
+
+.Ltail:
+ // Count the trailing zeros using bit reversing
+ rbit synd, synd
+ // Compensate the last post-increment
+ sub src, src, #32
+ // Check that we have found a character
+ cmp synd, #0
+ // And count the leading zeros
+ clz synd, synd
+ // Compute the potential result
+ add result, src, synd, lsr #1
+ // Select result or NULL
+ csel result, xzr, result, eq
+ ret
+
+.Lzero_length:
+ mov result, #0
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S
new file mode 100644
index 000000000000..384fbdc6c04e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S
@@ -0,0 +1,247 @@
+//
+// Copyright (c) 2012 - 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// Copyright (c) 2015 ARM Ltd
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the company may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64, unaligned accesses
+//
+//
+
+#define dstin x0
+#define count x1
+#define val x2
+#define valw w2
+#define dst x3
+#define dstend x4
+#define tmp1 x5
+#define tmp1w w5
+#define tmp2 x6
+#define tmp2w w6
+#define zva_len x7
+#define zva_lenw w7
+
+#define L(l) .L ## l
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ dup v0.8H, valw
+ lsl count, count, #1
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ dup v0.4S, valw
+ lsl count, count, #2
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ dup v0.2D, val
+ lsl count, count, #3
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ movi v0.16B, #0
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ dup v0.16B, valw
+0: add dstend, dstin, count
+ mov val, v0.D[0]
+
+ cmp count, 96
+ b.hi L(set_long)
+ cmp count, 16
+ b.hs L(set_medium)
+
+ // Set 0..15 bytes.
+ tbz count, 3, 1f
+ str val, [dstin]
+ str val, [dstend, -8]
+ ret
+ nop
+1: tbz count, 2, 2f
+ str valw, [dstin]
+ str valw, [dstend, -4]
+ ret
+2: cbz count, 3f
+ strb valw, [dstin]
+ tbz count, 1, 3f
+ strh valw, [dstend, -2]
+3: ret
+
+ // Set 17..96 bytes.
+L(set_medium):
+ str q0, [dstin]
+ tbnz count, 6, L(set96)
+ str q0, [dstend, -16]
+ tbz count, 5, 1f
+ str q0, [dstin, 16]
+ str q0, [dstend, -32]
+1: ret
+
+ .p2align 4
+ // Set 64..96 bytes. Write 64 bytes from the start and
+ // 32 bytes from the end.
+L(set96):
+ str q0, [dstin, 16]
+ stp q0, q0, [dstin, 32]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+ nop
+L(set_long):
+ bic dst, dstin, 15
+ str q0, [dstin]
+ cmp count, 256
+ ccmp val, 0, 0, cs
+ b.eq L(try_zva)
+L(no_zva):
+ sub count, dstend, dst // Count is 16 too large.
+ add dst, dst, 16
+ sub count, count, 64 + 16 // Adjust count and bias for loop.
+1: stp q0, q0, [dst], 64
+ stp q0, q0, [dst, -32]
+L(tail64):
+ subs count, count, 64
+ b.hi 1b
+2: stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+L(try_zva):
+ mrs tmp1, dczid_el0
+ tbnz tmp1w, 4, L(no_zva)
+ and tmp1w, tmp1w, 15
+ cmp tmp1w, 4 // ZVA size is 64 bytes.
+ b.ne L(zva_128)
+
+ // Write the first and last 64 byte aligned block using stp rather
+ // than using DC ZVA. This is faster on some cores.
+L(zva_64):
+ str q0, [dst, 16]
+ stp q0, q0, [dst, 32]
+ bic dst, dst, 63
+ stp q0, q0, [dst, 64]
+ stp q0, q0, [dst, 96]
+ sub count, dstend, dst // Count is now 128 too large.
+ sub count, count, 128+64+64 // Adjust count and bias for loop.
+ add dst, dst, 128
+ nop
+1: dc zva, dst
+ add dst, dst, 64
+ subs count, count, 64
+ b.hi 1b
+ stp q0, q0, [dst, 0]
+ stp q0, q0, [dst, 32]
+ stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+L(zva_128):
+ cmp tmp1w, 5 // ZVA size is 128 bytes.
+ b.ne L(zva_other)
+
+ str q0, [dst, 16]
+ stp q0, q0, [dst, 32]
+ stp q0, q0, [dst, 64]
+ stp q0, q0, [dst, 96]
+ bic dst, dst, 127
+ sub count, dstend, dst // Count is now 128 too large.
+ sub count, count, 128+128 // Adjust count and bias for loop.
+ add dst, dst, 128
+1: dc zva, dst
+ add dst, dst, 128
+ subs count, count, 128
+ b.hi 1b
+ stp q0, q0, [dstend, -128]
+ stp q0, q0, [dstend, -96]
+ stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+L(zva_other):
+ mov tmp2w, 4
+ lsl zva_lenw, tmp2w, tmp1w
+ add tmp1, zva_len, 64 // Max alignment bytes written.
+ cmp count, tmp1
+ blo L(no_zva)
+
+ sub tmp2, zva_len, 1
+ add tmp1, dst, zva_len
+ add dst, dst, 16
+ subs count, tmp1, dst // Actual alignment bytes to write.
+ bic tmp1, tmp1, tmp2 // Aligned dc zva start address.
+ beq 2f
+1: stp q0, q0, [dst], 64
+ stp q0, q0, [dst, -32]
+ subs count, count, 64
+ b.hi 1b
+2: mov dst, tmp1
+ sub count, dstend, tmp1 // Remaining bytes to write.
+ subs count, count, zva_len
+ b.lo 4f
+3: dc zva, dst
+ add dst, dst, zva_len
+ subs count, count, zva_len
+ b.hs 3b
+4: add count, count, zva_len
+ b L(tail64)
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.S
new file mode 100644
index 000000000000..abda83a1f18c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.S
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+ .text
+ .thumb
+ .syntax unified
+ .align 5
+ASM_GLOBAL ASM_PFX(InternalMemCompareGuid)
+ASM_PFX(InternalMemCompareGuid):
+ push {r4, lr}
+ ldr r2, [r0]
+ ldr r3, [r0, #4]
+ ldr r4, [r0, #8]
+ ldr r0, [r0, #12]
+ cbz r1, 1f
+ ldr ip, [r1]
+ ldr lr, [r1, #4]
+ cmp r2, ip
+ it eq
+ cmpeq.n r3, lr
+ beq 0f
+ movs r0, #0
+ pop {r4, pc}
+
+0: ldr r2, [r1, #8]
+ ldr r3, [r1, #12]
+ cmp r4, r2
+ it eq
+ cmpeq.n r0, r3
+ bne 2f
+ movs r0, #1
+ pop {r4, pc}
+
+1: orrs r2, r2, r3
+ orrs r4, r4, r0
+ movs r0, #1
+ orrs r2, r2, r4
+2: it ne
+ movne.n r0, #0
+ pop {r4, pc}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.asm
new file mode 100644
index 000000000000..0373404ea9d5
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareGuid.asm
@@ -0,0 +1,70 @@
+;
+; Copyright (c) 2016, Linaro Limited
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; * Neither the name of the Linaro nor the
+; names of its contributors may be used to endorse or promote products
+; derived from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+; HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+ EXPORT InternalMemCompareGuid
+ THUMB
+ AREA CompareGuid, CODE, READONLY, CODEALIGN, ALIGN=5
+
+InternalMemCompareGuid
+ push {r4, lr}
+ ldr r2, [r0]
+ ldr r3, [r0, #4]
+ ldr r4, [r0, #8]
+ ldr r0, [r0, #12]
+ cbz r1, L1
+ ldr ip, [r1]
+ ldr lr, [r1, #4]
+ cmp r2, ip
+ it eq
+ cmpeq r3, lr
+ beq L0
+ movs r0, #0
+ pop {r4, pc}
+
+L0
+ ldr r2, [r1, #8]
+ ldr r3, [r1, #12]
+ cmp r4, r2
+ it eq
+ cmpeq r0, r3
+ bne L2
+ movs r0, #1
+ pop {r4, pc}
+
+L1
+ orrs r2, r2, r3
+ orrs r4, r4, r0
+ movs r0, #1
+ orrs r2, r2, r4
+
+L2
+ it ne
+ movne r0, #0
+ pop {r4, pc}
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.S
new file mode 100644
index 000000000000..763f54a8b802
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.S
@@ -0,0 +1,138 @@
+//
+// Copyright (c) 2013 - 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Parameters and result.
+#define src1 r0
+#define src2 r1
+#define limit r2
+#define result r0
+
+// Internal variables.
+#define data1 r3
+#define data2 r4
+#define limit_wd r5
+#define diff r6
+#define tmp1 r7
+#define tmp2 r12
+#define pos r8
+#define mask r14
+
+ .text
+ .thumb
+ .syntax unified
+ .align 5
+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ push {r4-r8, lr}
+ eor tmp1, src1, src2
+ tst tmp1, #3
+ bne .Lmisaligned4
+ ands tmp1, src1, #3
+ bne .Lmutual_align
+ add limit_wd, limit, #3
+ nop.w
+ lsr limit_wd, limit_wd, #2
+
+ // Start of performance-critical section -- one 32B cache line.
+.Lloop_aligned:
+ ldr data1, [src1], #4
+ ldr data2, [src2], #4
+.Lstart_realigned:
+ subs limit_wd, limit_wd, #1
+ eor diff, data1, data2 // Non-zero if differences found.
+ cbnz diff, 0f
+ bne .Lloop_aligned
+ // End of performance-critical section -- one 32B cache line.
+
+ // Not reached the limit, must have found a diff.
+0: cbnz limit_wd, .Lnot_limit
+
+ // Limit % 4 == 0 => all bytes significant.
+ ands limit, limit, #3
+ beq .Lnot_limit
+
+ lsl limit, limit, #3 // Bits -> bytes.
+ mov mask, #~0
+ lsl mask, mask, limit
+ bic data1, data1, mask
+ bic data2, data2, mask
+
+ orr diff, diff, mask
+
+.Lnot_limit:
+ rev diff, diff
+ rev data1, data1
+ rev data2, data2
+
+ // The MS-non-zero bit of DIFF marks either the first bit
+ // that is different, or the end of the significant data.
+ // Shifting left now will bring the critical information into the
+ // top bits.
+ clz pos, diff
+ lsl data1, data1, pos
+ lsl data2, data2, pos
+
+ // But we need to zero-extend (char is unsigned) the value and then
+ // perform a signed 32-bit subtraction.
+ lsr data1, data1, #28
+ sub result, data1, data2, lsr #28
+ pop {r4-r8, pc}
+
+.Lmutual_align:
+ // Sources are mutually aligned, but are not currently at an
+ // alignment boundary. Round down the addresses and then mask off
+ // the bytes that precede the start point.
+ bic src1, src1, #3
+ bic src2, src2, #3
+ add limit, limit, tmp1 // Adjust the limit for the extra.
+ lsl tmp1, tmp1, #3 // Bytes beyond alignment -> bits.
+ ldr data1, [src1], #4
+ rsb tmp1, tmp1, #32 // Bits to alignment -32.
+ ldr data2, [src2], #4
+ mov tmp2, #~0
+
+ // Little-endian. Early bytes are at LSB.
+ lsr tmp2, tmp2, tmp1 // Shift (tmp1 & 31).
+ add limit_wd, limit, #3
+ orr data1, data1, tmp2
+ orr data2, data2, tmp2
+ lsr limit_wd, limit_wd, #2
+ b .Lstart_realigned
+
+.Lmisaligned4:
+ sub limit, limit, #1
+1:
+ // Perhaps we can do better than this.
+ ldrb data1, [src1], #1
+ ldrb data2, [src2], #1
+ subs limit, limit, #1
+ it cs
+ cmpcs.n data1, data2
+ beq 1b
+ sub result, data1, data2
+ pop {r4-r8, pc}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.asm
new file mode 100644
index 000000000000..4c72dcf38597
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CompareMem.asm
@@ -0,0 +1,140 @@
+;
+; Copyright (c) 2013 - 2016, Linaro Limited
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; * Neither the name of the Linaro nor the
+; names of its contributors may be used to endorse or promote products
+; derived from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+; HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+; Parameters and result.
+#define src1 r0
+#define src2 r1
+#define limit r2
+#define result r0
+
+; Internal variables.
+#define data1 r3
+#define data2 r4
+#define limit_wd r5
+#define diff r6
+#define tmp1 r7
+#define tmp2 r12
+#define pos r8
+#define mask r14
+
+ EXPORT InternalMemCompareMem
+ THUMB
+ AREA CompareMem, CODE, READONLY
+
+InternalMemCompareMem
+ push {r4-r8, lr}
+ eor tmp1, src1, src2
+ tst tmp1, #3
+ bne Lmisaligned4
+ ands tmp1, src1, #3
+ bne Lmutual_align
+ add limit_wd, limit, #3
+ nop.w
+ lsr limit_wd, limit_wd, #2
+
+ ; Start of performance-critical section -- one 32B cache line.
+Lloop_aligned
+ ldr data1, [src1], #4
+ ldr data2, [src2], #4
+Lstart_realigned
+ subs limit_wd, limit_wd, #1
+ eor diff, data1, data2 ; Non-zero if differences found.
+ cbnz diff, L0
+ bne Lloop_aligned
+ ; End of performance-critical section -- one 32B cache line.
+
+ ; Not reached the limit, must have found a diff.
+L0
+ cbnz limit_wd, Lnot_limit
+
+ // Limit % 4 == 0 => all bytes significant.
+ ands limit, limit, #3
+ beq Lnot_limit
+
+ lsl limit, limit, #3 // Bits -> bytes.
+ mov mask, #~0
+ lsl mask, mask, limit
+ bic data1, data1, mask
+ bic data2, data2, mask
+
+ orr diff, diff, mask
+
+Lnot_limit
+ rev diff, diff
+ rev data1, data1
+ rev data2, data2
+
+ ; The MS-non-zero bit of DIFF marks either the first bit
+ ; that is different, or the end of the significant data.
+ ; Shifting left now will bring the critical information into the
+ ; top bits.
+ clz pos, diff
+ lsl data1, data1, pos
+ lsl data2, data2, pos
+
+ ; But we need to zero-extend (char is unsigned) the value and then
+ ; perform a signed 32-bit subtraction.
+ lsr data1, data1, #28
+ sub result, data1, data2, lsr #28
+ pop {r4-r8, pc}
+
+Lmutual_align
+ ; Sources are mutually aligned, but are not currently at an
+ ; alignment boundary. Round down the addresses and then mask off
+ ; the bytes that precede the start point.
+ bic src1, src1, #3
+ bic src2, src2, #3
+ add limit, limit, tmp1 ; Adjust the limit for the extra.
+ lsl tmp1, tmp1, #2 ; Bytes beyond alignment -> bits.
+ ldr data1, [src1], #4
+ neg tmp1, tmp1 ; Bits to alignment -32.
+ ldr data2, [src2], #4
+ mov tmp2, #~0
+
+ ; Little-endian. Early bytes are at LSB.
+ lsr tmp2, tmp2, tmp1 ; Shift (tmp1 & 31).
+ add limit_wd, limit, #3
+ orr data1, data1, tmp2
+ orr data2, data2, tmp2
+ lsr limit_wd, limit_wd, #2
+ b Lstart_realigned
+
+Lmisaligned4
+ sub limit, limit, #1
+L1
+ // Perhaps we can do better than this.
+ ldrb data1, [src1], #1
+ ldrb data2, [src2], #1
+ subs limit, limit, #1
+ it cs
+ cmpcs data1, data2
+ beq L1
+ sub result, data1, data2
+ pop {r4-r8, pc}
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.S
new file mode 100644
index 000000000000..32c104999d22
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.S
@@ -0,0 +1,175 @@
+#------------------------------------------------------------------------------
+#
+# CopyMem() worker for ARM
+#
+# This file started out as C code that did 64 bit moves if the buffer was
+# 32-bit aligned, else it does a byte copy. It also does a byte copy for
+# any trailing bytes. It was updated to do 32-byte copies using stm/ldm.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .thumb
+ .syntax unified
+
+/**
+ Copy Length bytes from Source to Destination. Overlap is OK.
+
+ This implementation
+
+ @param Destination Target of copy
+ @param Source Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+**/
+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ push {r4-r11, lr}
+ // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
+ mov r11, r0
+ mov r10, r0
+ mov r12, r2
+ mov r14, r1
+
+ cmp r11, r1
+ // If (dest < source)
+ bcc memcopy_check_optim_default
+
+ // If (source + length < dest)
+ rsb r3, r1, r11
+ cmp r12, r3
+ bcc memcopy_check_optim_default
+ b memcopy_check_optim_overlap
+
+memcopy_check_optim_default:
+ // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
+ tst r0, #0xF
+ it ne
+ movne.n r0, #0
+ bne memcopy_default
+ tst r1, #0xF
+ it ne
+ movne.n r3, #0
+ it eq
+ moveq.n r3, #1
+ cmp r2, #31
+ it ls
+ movls.n r0, #0
+ bls memcopy_default
+ and r0, r3, #1
+ b memcopy_default
+
+memcopy_check_optim_overlap:
+ // r10 = dest_end, r14 = source_end
+ add r10, r11, r12
+ add r14, r12, r1
+
+ // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
+ cmp r2, #31
+ it ls
+ movls.n r0, #0
+ it hi
+ movhi.n r0, #1
+ tst r10, #0xF
+ it ne
+ movne.n r0, #0
+ tst r14, #0xF
+ it ne
+ movne.n r0, #0
+ b memcopy_overlapped
+
+memcopy_overlapped_non_optim:
+ // We read 1 byte from the end of the source buffer
+ sub r3, r14, #1
+ sub r12, r12, #1
+ ldrb r3, [r3, #0]
+ sub r2, r10, #1
+ cmp r12, #0
+ // We write 1 byte at the end of the dest buffer
+ sub r10, r10, #1
+ sub r14, r14, #1
+ strb r3, [r2, #0]
+ bne memcopy_overlapped_non_optim
+ b memcopy_end
+
+// r10 = dest_end, r14 = source_end
+memcopy_overlapped:
+ // Are we in the optimized case ?
+ cmp r0, #0
+ beq memcopy_overlapped_non_optim
+
+ // Optimized Overlapped - Read 32 bytes
+ sub r14, r14, #32
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ it ls
+ movls.n r0, #0
+
+ cmp r12, #0
+
+ // Optimized Overlapped - Write 32 bytes
+ sub r10, r10, #32
+ stmia r10, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_overlapped
+ b memcopy_end
+
+memcopy_default_non_optim:
+ // Byte copy
+ ldrb r3, [r14], #1
+ sub r12, r12, #1
+ strb r3, [r10], #1
+
+memcopy_default:
+ cmp r12, #0
+ beq memcopy_end
+
+// r10 = dest, r14 = source
+memcopy_default_loop:
+ cmp r0, #0
+ beq memcopy_default_non_optim
+
+ // Optimized memcopy - Read 32 Bytes
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14!, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ it ls
+ movls.n r0, #0
+
+ cmp r12, #0
+
+ // Optimized memcopy - Write 32 Bytes
+ stmia r10!, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_default_loop
+
+memcopy_end:
+ mov r0, r11
+ pop {r4-r11, pc}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.asm
new file mode 100644
index 000000000000..f5447405fbf1
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.asm
@@ -0,0 +1,147 @@
+;------------------------------------------------------------------------------
+;
+; CopyMem() worker for ARM
+;
+; This file started out as C code that did 64 bit moves if the buffer was
+; 32-bit aligned, else it does a byte copy. It also does a byte copy for
+; any trailing bytes. It was updated to do 32-byte copies using stm/ldm.
+;
+; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+; Copyright (c) 2016, Linaro Ltd. 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 InternalMemCopyMem
+ AREA SetMem, CODE, READONLY
+ THUMB
+
+InternalMemCopyMem
+ stmfd sp!, {r4-r11, lr}
+ // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
+ mov r11, r0
+ mov r10, r0
+ mov r12, r2
+ mov r14, r1
+
+memcopy_check_overlapped
+ cmp r11, r1
+ // If (dest < source)
+ bcc memcopy_check_optim_default
+
+ // If (source + length < dest)
+ rsb r3, r1, r11
+ cmp r12, r3
+ bcc memcopy_check_optim_default
+ b memcopy_check_optim_overlap
+
+memcopy_check_optim_default
+ // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
+ tst r0, #0xF
+ movne r0, #0
+ bne memcopy_default
+ tst r1, #0xF
+ movne r3, #0
+ moveq r3, #1
+ cmp r2, #31
+ movls r0, #0
+ andhi r0, r3, #1
+ b memcopy_default
+
+memcopy_check_optim_overlap
+ // r10 = dest_end, r14 = source_end
+ add r10, r11, r12
+ add r14, r12, r1
+
+ // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
+ cmp r2, #31
+ movls r0, #0
+ movhi r0, #1
+ tst r10, #0xF
+ movne r0, #0
+ tst r14, #0xF
+ movne r0, #0
+ b memcopy_overlapped
+
+memcopy_overlapped_non_optim
+ // We read 1 byte from the end of the source buffer
+ sub r3, r14, #1
+ sub r12, r12, #1
+ ldrb r3, [r3, #0]
+ sub r2, r10, #1
+ cmp r12, #0
+ // We write 1 byte at the end of the dest buffer
+ sub r10, r10, #1
+ sub r14, r14, #1
+ strb r3, [r2, #0]
+ bne memcopy_overlapped_non_optim
+ b memcopy_end
+
+// r10 = dest_end, r14 = source_end
+memcopy_overlapped
+ // Are we in the optimized case ?
+ cmp r0, #0
+ beq memcopy_overlapped_non_optim
+
+ // Optimized Overlapped - Read 32 bytes
+ sub r14, r14, #32
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized Overlapped - Write 32 bytes
+ sub r10, r10, #32
+ stmia r10, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_overlapped
+ b memcopy_end
+
+memcopy_default_non_optim
+ // Byte copy
+ ldrb r3, [r14], #1
+ sub r12, r12, #1
+ strb r3, [r10], #1
+
+memcopy_default
+ cmp r12, #0
+ beq memcopy_end
+
+// r10 = dest, r14 = source
+memcopy_default_loop
+ cmp r0, #0
+ beq memcopy_default_non_optim
+
+ // Optimized memcopy - Read 32 Bytes
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14!, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized memcopy - Write 32 Bytes
+ stmia r10!, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_default_loop
+
+memcopy_end
+ mov r0, r11
+ ldmfd sp!, {r4-r11, pc}
+
+ END
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/MemLibGuid.c b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/MemLibGuid.c
new file mode 100644
index 000000000000..b2942f31c3f5
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/MemLibGuid.c
@@ -0,0 +1,165 @@
+/** @file
+ Implementation of GUID functions for ARM and AARCH64
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. 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 "MemLibInternals.h"
+
+/**
+ Internal function to compare two GUIDs.
+
+ This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
+ If there are any bit differences in the two GUIDs, then FALSE is returned.
+
+ @param Guid1 A pointer to a 128 bit GUID.
+ @param Guid2 A pointer to a 128 bit GUID.
+
+ @retval TRUE Guid1 and Guid2 are identical.
+ @retval FALSE Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+InternalMemCompareGuid (
+ IN CONST GUID *Guid1,
+ IN CONST GUID *Guid2
+ );
+
+/**
+ Copies a source GUID to a destination GUID.
+
+ This function copies the contents of the 128-bit GUID specified by SourceGuid to
+ DestinationGuid, and returns DestinationGuid.
+
+ If DestinationGuid is NULL, then ASSERT().
+ If SourceGuid is NULL, then ASSERT().
+
+ @param DestinationGuid The pointer to the destination GUID.
+ @param SourceGuid The pointer to the source GUID.
+
+ @return DestinationGuid.
+
+**/
+GUID *
+EFIAPI
+CopyGuid (
+ OUT GUID *DestinationGuid,
+ IN CONST GUID *SourceGuid
+ )
+{
+ ASSERT (DestinationGuid != NULL);
+ ASSERT (SourceGuid != NULL);
+
+ return InternalMemCopyMem (DestinationGuid, SourceGuid, sizeof (GUID));
+}
+
+/**
+ Compares two GUIDs.
+
+ This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
+ If there are any bit differences in the two GUIDs, then FALSE is returned.
+
+ If Guid1 is NULL, then ASSERT().
+ If Guid2 is NULL, then ASSERT().
+
+ @param Guid1 A pointer to a 128 bit GUID.
+ @param Guid2 A pointer to a 128 bit GUID.
+
+ @retval TRUE Guid1 and Guid2 are identical.
+ @retval FALSE Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+CompareGuid (
+ IN CONST GUID *Guid1,
+ IN CONST GUID *Guid2
+ )
+{
+ ASSERT (Guid1 != NULL);
+ ASSERT (Guid2 != NULL);
+
+ return InternalMemCompareGuid (Guid1, Guid2);
+}
+
+/**
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Guid The value to search for in the target buffer.
+
+ @return A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanGuid (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN CONST GUID *Guid
+ )
+{
+ CONST GUID *GuidPtr;
+
+ ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);
+
+ GuidPtr = (GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (CONST GUID*)Buffer) {
+ if (InternalMemCompareGuid (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
+
+/**
+ Checks if the given GUID is a zero GUID.
+
+ This function checks whether the given GUID is a zero GUID. If the GUID is
+ identical to a zero GUID then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The pointer to a 128 bit GUID.
+
+ @retval TRUE Guid is a zero GUID.
+ @retval FALSE Guid is not a zero GUID.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroGuid (
+ IN CONST GUID *Guid
+ )
+{
+ ASSERT (Guid != NULL);
+
+ return InternalMemCompareGuid (Guid, NULL);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.S
new file mode 100644
index 000000000000..5502f286537e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.S
@@ -0,0 +1,148 @@
+// Copyright (c) 2010-2011, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of Linaro Limited nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// Written by Dave Gilbert <david.gilbert@linaro.org>
+//
+// This memchr routine is optimised on a Cortex-A9 and should work on
+// all ARMv7 processors. It has a fast past for short sizes, and has
+// an optimised path for large data sets; the worst case is finding the
+// match early in a large data set.
+//
+
+
+// 2011-02-07 david.gilbert@linaro.org
+// Extracted from local git a5b438d861
+// 2011-07-14 david.gilbert@linaro.org
+// Import endianness fix from local git ea786f1b
+// 2011-12-07 david.gilbert@linaro.org
+// Removed unneeded cbz from align loop
+
+// this lets us check a flag in a 00/ff byte easily in either endianness
+#define CHARTSTMASK(c) 1<<(c*8)
+
+ .text
+ .thumb
+ .syntax unified
+
+ .type ASM_PFX(InternalMemScanMem8), %function
+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ // r0 = start of memory to scan
+ // r1 = length
+ // r2 = character to look for
+ // returns r0 = pointer to character or NULL if not found
+ uxtb r2, r2 // Don't think we can trust the caller to actually pass a char
+
+ cmp r1, #16 // If it's short don't bother with anything clever
+ blt 20f
+
+ tst r0, #7 // If it's already aligned skip the next bit
+ beq 10f
+
+ // Work up to an aligned point
+5:
+ ldrb r3, [r0],#1
+ subs r1, r1, #1
+ cmp r3, r2
+ beq 50f // If it matches exit found
+ tst r0, #7
+ bne 5b // If not aligned yet then do next byte
+
+10:
+ // At this point, we are aligned, we know we have at least 8 bytes to work with
+ push {r4-r7}
+ orr r2, r2, r2, lsl #8 // expand the match word across to all bytes
+ orr r2, r2, r2, lsl #16
+ bic r4, r1, #7 // Number of double words to work with
+ mvns r7, #0 // all F's
+ movs r3, #0
+
+15:
+ ldmia r0!, {r5,r6}
+ subs r4, r4, #8
+ eor r5, r5, r2 // Get it so that r5,r6 have 00's where the bytes match the target
+ eor r6, r6, r2
+ uadd8 r5, r5, r7 // Parallel add 0xff - sets the GE bits for anything that wasn't 0
+ sel r5, r3, r7 // bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+ uadd8 r6, r6, r7 // Parallel add 0xff - sets the GE bits for anything that wasn't 0
+ sel r6, r5, r7 // chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+ cbnz r6, 60f
+ bne 15b // (Flags from the subs above) If not run out of bytes then go around again
+
+ pop {r4-r7}
+ and r2, r2, #0xff // Get r2 back to a single character from the expansion above
+ and r1, r1, #7 // Leave the count remaining as the number after the double words have been done
+
+20:
+ cbz r1, 40f // 0 length or hit the end already then not found
+
+21: // Post aligned section, or just a short call
+ ldrb r3, [r0], #1
+ subs r1, r1, #1
+ eor r3, r3, r2 // r3 = 0 if match - doesn't break flags from sub
+ cbz r3, 50f
+ bne 21b // on r1 flags
+
+40:
+ movs r0, #0 // not found
+ bx lr
+
+50:
+ subs r0, r0, #1 // found
+ bx lr
+
+60: // We're here because the fast path found a hit - now we have to track down exactly which word it was
+ // r0 points to the start of the double word after the one that was tested
+ // r5 has the 00/ff pattern for the first word, r6 has the chained value
+ subs r0, r0, #3
+ cmp r5, #0
+ it eq
+ moveq.n r5, r6 // the end is in the 2nd word
+ it ne
+ subne.n r0, r0, #4 // or 2nd byte of 1st word
+
+ // r0 currently points to the 3rd byte of the word containing the hit
+ tst r5, #CHARTSTMASK(0) // 1st character
+ bne 61f
+ adds r0, r0, #1
+ tst r5, #CHARTSTMASK(1) // 2nd character
+ bne 61f
+ adds r0, r0 ,#1
+ tst r5, #(3 << 15) // 2nd & 3rd character
+ // If not the 3rd must be the last one
+ it eq
+ addeq.n r0, r0, #1
+
+61:
+ pop {r4-r7}
+ subs r0, r0, #1
+ bx lr
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.asm
new file mode 100644
index 000000000000..bb489f14cf7e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMem.asm
@@ -0,0 +1,147 @@
+; Copyright (c) 2010-2011, Linaro Limited
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+;
+; * Neither the name of Linaro Limited nor the names of its
+; contributors may be used to endorse or promote products derived
+; from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+; HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+;
+; Written by Dave Gilbert <david.gilbert@linaro.org>
+;
+; This memchr routine is optimised on a Cortex-A9 and should work on
+; all ARMv7 processors. It has a fast past for short sizes, and has
+; an optimised path for large data sets; the worst case is finding the
+; match early in a large data set.
+;
+
+
+; 2011-02-07 david.gilbert@linaro.org
+; Extracted from local git a5b438d861
+; 2011-07-14 david.gilbert@linaro.org
+; Import endianness fix from local git ea786f1b
+; 2011-12-07 david.gilbert@linaro.org
+; Removed unneeded cbz from align loop
+
+; this lets us check a flag in a 00/ff byte easily in either endianness
+#define CHARTSTMASK(c) 1<<(c*8)
+
+ EXPORT InternalMemScanMem8
+ AREA ScanMem, CODE, READONLY
+ THUMB
+
+InternalMemScanMem8
+ ; r0 = start of memory to scan
+ ; r1 = length
+ ; r2 = character to look for
+ ; returns r0 = pointer to character or NULL if not found
+ uxtb r2, r2 ; Don't think we can trust the caller to actually pass a char
+
+ cmp r1, #16 ; If it's short don't bother with anything clever
+ blt L20
+
+ tst r0, #7 ; If it's already aligned skip the next bit
+ beq L10
+
+ ; Work up to an aligned point
+L5
+ ldrb r3, [r0],#1
+ subs r1, r1, #1
+ cmp r3, r2
+ beq L50 ; If it matches exit found
+ tst r0, #7
+ bne L5 ; If not aligned yet then do next byte
+
+L10
+ ; At this point, we are aligned, we know we have at least 8 bytes to work with
+ push {r4-r7}
+ orr r2, r2, r2, lsl #8 ; expand the match word across to all bytes
+ orr r2, r2, r2, lsl #16
+ bic r4, r1, #7 ; Number of double words to work with
+ mvns r7, #0 ; all F's
+ movs r3, #0
+
+L15
+ ldmia r0!, {r5,r6}
+ subs r4, r4, #8
+ eor r5, r5, r2 ; Get it so that r5,r6 have 00's where the bytes match the target
+ eor r6, r6, r2
+ uadd8 r5, r5, r7 ; Parallel add 0xff - sets the GE bits for anything that wasn't 0
+ sel r5, r3, r7 ; bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+ uadd8 r6, r6, r7 ; Parallel add 0xff - sets the GE bits for anything that wasn't 0
+ sel r6, r5, r7 ; chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+ cbnz r6, L60
+ bne L15 ; (Flags from the subs above) If not run out of bytes then go around again
+
+ pop {r4-r7}
+ and r2, r2, #0xff ; Get r2 back to a single character from the expansion above
+ and r1, r1, #7 ; Leave the count remaining as the number after the double words have been done
+
+L20
+ cbz r1, L40 ; 0 length or hit the end already then not found
+
+L21 ; Post aligned section, or just a short call
+ ldrb r3, [r0], #1
+ subs r1, r1, #1
+ eor r3, r3, r2 ; r3 = 0 if match - doesn't break flags from sub
+ cbz r3, L50
+ bne L21 ; on r1 flags
+
+L40
+ movs r0, #0 ; not found
+ bx lr
+
+L50
+ subs r0, r0, #1 ; found
+ bx lr
+
+L60 ; We're here because the fast path found a hit - now we have to track down exactly which word it was
+ ; r0 points to the start of the double word after the one that was tested
+ ; r5 has the 00/ff pattern for the first word, r6 has the chained value
+ cmp r5, #0
+ itte eq
+ moveq r5, r6 ; the end is in the 2nd word
+ subeq r0, r0, #3 ; Points to 2nd byte of 2nd word
+ subne r0, r0, #7 ; or 2nd byte of 1st word
+
+ ; r0 currently points to the 3rd byte of the word containing the hit
+ tst r5, #CHARTSTMASK(0) ; 1st character
+ bne L61
+ adds r0, r0, #1
+ tst r5, #CHARTSTMASK(1) ; 2nd character
+ ittt eq
+ addeq r0, r0 ,#1
+ tsteq r5, #(3 << 15) ; 2nd & 3rd character
+ ; If not the 3rd must be the last one
+ addeq r0, r0, #1
+
+L61
+ pop {r4-r7}
+ subs r0, r0, #1
+ bx lr
+
+ END
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMemGeneric.c b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMemGeneric.c
new file mode 100644
index 000000000000..e48db7278aa0
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/ScanMemGeneric.c
@@ -0,0 +1,142 @@
+/** @file
+ Architecture Independent Base Memory Library Implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2016, Intel Corporation. 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 "../MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 16-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence, or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ CONST UINT16 *Pointer;
+
+ Pointer = (CONST UINT16*)Buffer;
+ do {
+ if (*Pointer == Value) {
+ return Pointer;
+ }
+ ++Pointer;
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 32-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence, or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ CONST UINT32 *Pointer;
+
+ Pointer = (CONST UINT32*)Buffer;
+ do {
+ if (*Pointer == Value) {
+ return Pointer;
+ }
+ ++Pointer;
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 64-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence, or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ CONST UINT64 *Pointer;
+
+ Pointer = (CONST UINT64*)Buffer;
+ do {
+ if (*Pointer == Value) {
+ return Pointer;
+ }
+ ++Pointer;
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Checks whether the contents of a buffer are all zeros.
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+InternalMemIsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ CONST UINT8 *BufferData;
+ UINTN Index;
+
+ BufferData = Buffer;
+ for (Index = 0; Index < Length; Index++) {
+ if (BufferData[Index] != 0) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S
new file mode 100644
index 000000000000..41cf81a8e20f
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.S
@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2016, Linaro Ltd. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .thumb
+ .syntax unified
+ .align 5
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ uxth r2, r2
+ lsl r1, r1, #1
+ orr r2, r2, r2, lsl #16
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ lsl r1, r1, #2
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ lsl r1, r1, #3
+ b 1f
+
+ .align 5
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ uxtb r2, r2
+ orr r2, r2, r2, lsl #8
+ orr r2, r2, r2, lsl #16
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ movs r2, #0
+0: mov r3, r2
+
+1: push {r4, lr}
+ cmp r1, #16 // fewer than 16 bytes of input?
+ add r1, r1, r0 // r1 := dst + length
+ add lr, r0, #16
+ blt 2f
+ bic lr, lr, #15 // align output pointer
+
+ str r2, [r0] // potentially unaligned store of 4 bytes
+ str r3, [r0, #4] // potentially unaligned store of 4 bytes
+ str r2, [r0, #8] // potentially unaligned store of 4 bytes
+ str r3, [r0, #12] // potentially unaligned store of 4 bytes
+ beq 1f
+
+0: add lr, lr, #16 // advance the output pointer by 16 bytes
+ subs r4, r1, lr // past the output?
+ blt 3f // break out of the loop
+ strd r2, r3, [lr, #-16] // aligned store of 16 bytes
+ strd r2, r3, [lr, #-8]
+ bne 0b // goto beginning of loop
+1: pop {r4, pc}
+
+2: subs r4, r1, lr
+3: adds r4, r4, #16
+ subs r1, r1, #8
+ cmp r4, #4 // between 4 and 15 bytes?
+ blt 4f
+ cmp r4, #8 // between 8 and 15 bytes?
+ sub r4, lr, #16
+ str r2, [r4] // overlapping store of 4 + (4 + 4) + 4 bytes
+ it gt
+ strgt.n r3, [r4, #4]
+ it gt
+ strgt.n r2, [r1]
+ str r3, [r1, #4]
+ pop {r4, pc}
+
+4: cmp r4, #2 // 2 or 3 bytes?
+ strb r2, [lr, #-16] // store 1 byte
+ it ge
+ strhge.n r2, [r1, #6] // store 2 bytes
+ pop {r4, pc}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.asm
new file mode 100644
index 000000000000..000c2a22fad6
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Arm/SetMem.asm
@@ -0,0 +1,96 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Linaro Ltd. 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 InternalMemZeroMem
+ EXPORT InternalMemSetMem
+ EXPORT InternalMemSetMem16
+ EXPORT InternalMemSetMem32
+ EXPORT InternalMemSetMem64
+
+ AREA SetMem, CODE, READONLY, CODEALIGN, ALIGN=5
+ THUMB
+
+InternalMemSetMem16
+ uxth r2, r2
+ lsl r1, r1, #1
+ orr r2, r2, r2, lsl #16
+ b B0
+
+InternalMemSetMem32
+ lsl r1, r1, #2
+ b B0
+
+InternalMemSetMem64
+ lsl r1, r1, #3
+ b B1
+
+ ALIGN 32
+InternalMemSetMem
+ uxtb r2, r2
+ orr r2, r2, r2, lsl #8
+ orr r2, r2, r2, lsl #16
+ b B0
+
+InternalMemZeroMem
+ movs r2, #0
+B0
+ mov r3, r2
+
+B1
+ push {r4, lr}
+ cmp r1, #16 ; fewer than 16 bytes of input?
+ add r1, r1, r0 ; r1 := dst + length
+ add lr, r0, #16
+ blt L2
+ bic lr, lr, #15 ; align output pointer
+
+ str r2, [r0] ; potentially unaligned store of 4 bytes
+ str r3, [r0, #4] ; potentially unaligned store of 4 bytes
+ str r2, [r0, #8] ; potentially unaligned store of 4 bytes
+ str r3, [r0, #12] ; potentially unaligned store of 4 bytes
+ beq L1
+
+L0
+ add lr, lr, #16 ; advance the output pointer by 16 bytes
+ subs r4, r1, lr ; past the output?
+ blt L3 ; break out of the loop
+ strd r2, r3, [lr, #-16] ; aligned store of 16 bytes
+ strd r2, r3, [lr, #-8]
+ bne L0 ; goto beginning of loop
+L1
+ pop {r4, pc}
+
+L2
+ subs r4, r1, lr
+L3
+ adds r4, r4, #16
+ subs r1, r1, #8
+ cmp r4, #4 ; between 4 and 15 bytes?
+ blt L4
+ cmp r4, #8 ; between 8 and 15 bytes?
+ str r2, [lr, #-16] ; overlapping store of 4 + (4 + 4) + 4 bytes
+ itt gt
+ strgt r3, [lr, #-12]
+ strgt r2, [r1]
+ str r3, [r1, #4]
+ pop {r4, pc}
+
+L4
+ cmp r4, #2 ; 2 or 3 bytes?
+ strb r2, [lr, #-16] ; store 1 byte
+ it ge
+ strhge r2, [r1, #6] ; store 2 bytes
+ pop {r4, pc}
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
new file mode 100644
index 000000000000..d28aa84a33b9
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
@@ -0,0 +1,174 @@
+## @file
+# Instance of Base Memory Library optimized for use in DXE phase.
+#
+# Base Memory Library that is optimized for use in DXE phase.
+# Uses REP, MMX, XMM registers as required for best performance.
+#
+# Copyright (c) 2007 - 2016, Intel Corporation. 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.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseMemoryLibOptDxe
+ MODULE_UNI_FILE = BaseMemoryLibOptDxe.uni
+ FILE_GUID = 02BD55C2-AB1D-4b75-B0FD-9A63AE09B31D
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BaseMemoryLib
+
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ MemLibInternals.h
+
+[Sources.Ia32]
+ Ia32/ScanMem64.nasm
+ Ia32/ScanMem64.S
+ Ia32/ScanMem32.nasm
+ Ia32/ScanMem32.S
+ Ia32/ScanMem16.nasm
+ Ia32/ScanMem16.S
+ Ia32/ScanMem8.nasm
+ Ia32/ScanMem8.S
+ Ia32/CompareMem.nasm
+ Ia32/CompareMem.S
+ Ia32/ZeroMem.nasm
+ Ia32/ZeroMem.S
+ Ia32/SetMem64.nasm
+ Ia32/SetMem64.S
+ Ia32/SetMem32.nasm
+ Ia32/SetMem32.S
+ Ia32/SetMem16.nasm
+ Ia32/SetMem16.S
+ Ia32/SetMem.nasm
+ Ia32/SetMem.S
+ Ia32/CopyMem.nasm
+ Ia32/CopyMem.S
+ Ia32/ScanMem64.nasm
+ Ia32/ScanMem64.asm
+ Ia32/ScanMem32.nasm
+ Ia32/ScanMem32.asm
+ Ia32/ScanMem16.nasm
+ Ia32/ScanMem16.asm
+ Ia32/ScanMem8.nasm
+ Ia32/ScanMem8.asm
+ Ia32/CompareMem.nasm
+ Ia32/CompareMem.asm
+ Ia32/ZeroMem.nasm
+ Ia32/ZeroMem.asm
+ Ia32/SetMem64.nasm
+ Ia32/SetMem64.asm
+ Ia32/SetMem32.nasm
+ Ia32/SetMem32.asm
+ Ia32/SetMem16.nasm
+ Ia32/SetMem16.asm
+ Ia32/SetMem.nasm
+ Ia32/SetMem.asm
+ Ia32/CopyMem.nasm
+ Ia32/CopyMem.asm
+ Ia32/IsZeroBuffer.nasm
+ MemLibGuid.c
+
+[Sources.X64]
+ X64/ScanMem64.nasm
+ X64/ScanMem64.asm
+ X64/ScanMem64.S
+ X64/ScanMem32.nasm
+ X64/ScanMem32.asm
+ X64/ScanMem32.S
+ X64/ScanMem16.nasm
+ X64/ScanMem16.asm
+ X64/ScanMem16.S
+ X64/ScanMem8.nasm
+ X64/ScanMem8.asm
+ X64/ScanMem8.S
+ X64/CompareMem.nasm
+ X64/CompareMem.asm
+ X64/CompareMem.S
+ X64/ZeroMem.nasm
+ X64/ZeroMem.asm
+ X64/ZeroMem.S
+ X64/SetMem64.nasm
+ X64/SetMem64.asm
+ X64/SetMem64.S
+ X64/SetMem32.nasm
+ X64/SetMem32.asm
+ X64/SetMem32.S
+ X64/SetMem16.nasm
+ X64/SetMem16.asm
+ X64/SetMem16.S
+ X64/SetMem.nasm
+ X64/SetMem.asm
+ X64/SetMem.S
+ X64/CopyMem.nasm
+ X64/CopyMem.asm
+ X64/CopyMem.S
+ X64/IsZeroBuffer.nasm
+ MemLibGuid.c
+
+[Defines.ARM, Defines.AARCH64]
+ #
+ # The ARM implementations of this library may perform unaligned accesses, and
+ # may use DC ZVA instructions that are only allowed when the MMU and D-cache
+ # are on. Since SEC, PEI_CORE and PEIM modules may execute with the MMU off,
+ # omit them from the supported module types list for this library.
+ #
+ LIBRARY_CLASS = BaseMemoryLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources.ARM]
+ Arm/ScanMem.S |GCC
+ Arm/SetMem.S |GCC
+ Arm/CopyMem.S |GCC
+ Arm/CompareMem.S |GCC
+ Arm/CompareGuid.S |GCC
+
+ Arm/ScanMem.asm |RVCT
+ Arm/SetMem.asm |RVCT
+ Arm/CopyMem.asm |RVCT
+ Arm/CompareMem.asm |RVCT
+ Arm/CompareGuid.asm |RVCT
+
+[Sources.AARCH64]
+ AArch64/ScanMem.S
+ AArch64/SetMem.S
+ AArch64/CopyMem.S
+ AArch64/CompareMem.S
+ AArch64/CompareGuid.S
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/ScanMemGeneric.c
+ Arm/MemLibGuid.c
+
+[Sources]
+ ScanMem64Wrapper.c
+ ScanMem32Wrapper.c
+ ScanMem16Wrapper.c
+ ScanMem8Wrapper.c
+ ZeroMemWrapper.c
+ CompareMemWrapper.c
+ SetMem64Wrapper.c
+ SetMem32Wrapper.c
+ SetMem16Wrapper.c
+ SetMemWrapper.c
+ CopyMemWrapper.c
+ IsZeroBufferWrapper.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni
new file mode 100644
index 000000000000..bb0cd565a25c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni
@@ -0,0 +1,22 @@
+// /** @file
+// Instance of Base Memory Library optimized for use in DXE phase.
+//
+// Base Memory Library that is optimized for use in DXE phase.
+// Uses REP, MMX, XMM registers as required for best performance.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Base Memory Library for DXE"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Base Memory Library that is optimized for use in DXE phase. Uses REP, MMX, XMM registers as required for best performance."
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c
new file mode 100644
index 000000000000..aa7c2aab812c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ CompareMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Compares the contents of two buffers.
+
+ This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.
+ If all Length bytes of the two buffers are identical, then 0 is returned. Otherwise, the
+ value returned is the first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+ If Length > 0 and DestinationBuffer is NULL, then ASSERT().
+ If Length > 0 and SourceBuffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer The pointer to the destination buffer to compare.
+ @param SourceBuffer The pointer to the source buffer to compare.
+ @param Length The number of bytes to compare.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+CompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0 || DestinationBuffer == SourceBuffer) {
+ return 0;
+ }
+ ASSERT (DestinationBuffer != NULL);
+ ASSERT (SourceBuffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c
new file mode 100644
index 000000000000..f1a97699445d
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ CopyMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source buffer to a destination buffer, and returns the destination buffer.
+
+ This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns
+ DestinationBuffer. The implementation must be reentrant, and it must handle the case
+ where SourceBuffer overlaps DestinationBuffer.
+
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer The pointer to the destination buffer of the memory copy.
+ @param SourceBuffer The pointer to the source buffer of the memory copy.
+ @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @return DestinationBuffer.
+
+**/
+VOID *
+EFIAPI
+CopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0) {
+ return DestinationBuffer;
+ }
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ if (DestinationBuffer == SourceBuffer) {
+ return DestinationBuffer;
+ }
+ return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S
new file mode 100644
index 000000000000..a430453938e7
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# CompareMem.S
+#
+# Abstract:
+#
+# CompareMem function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)
+
+#------------------------------------------------------------------------------
+# INTN
+# EFIAPI
+# InternalMemCompareMem (
+# IN CONST VOID *DestinationBuffer,
+# IN CONST VOID *SourceBuffer,
+# IN UINTN Length
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemCompareMem):
+ push %esi
+ push %edi
+ movl 12(%esp), %esi
+ movl 16(%esp), %edi
+ movl 20(%esp), %ecx
+ repe cmpsb
+ movzbl -1(%esi), %eax
+ movzbl -1(%edi), %edx
+ subl %edx, %eax
+ pop %edi
+ pop %esi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm
new file mode 100644
index 000000000000..ba31a1875712
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CompareMem.Asm
+;
+; Abstract:
+;
+; CompareMem function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; INTN
+; EFIAPI
+; InternalMemCompareMem (
+; IN CONST VOID *DestinationBuffer,
+; IN CONST VOID *SourceBuffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+InternalMemCompareMem PROC USES esi edi
+ mov esi, [esp + 12]
+ mov edi, [esp + 16]
+ mov ecx, [esp + 20]
+ repe cmpsb
+ movzx eax, byte ptr [esi - 1]
+ movzx edx, byte ptr [edi - 1]
+ sub eax, edx
+ ret
+InternalMemCompareMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.nasm
new file mode 100644
index 000000000000..e8d1abdc17fc
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.nasm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CompareMem.Asm
+;
+; Abstract:
+;
+; CompareMem function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; INTN
+; EFIAPI
+; InternalMemCompareMem (
+; IN CONST VOID *DestinationBuffer,
+; IN CONST VOID *SourceBuffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ push esi
+ push edi
+ mov esi, [esp + 12]
+ mov edi, [esp + 16]
+ mov ecx, [esp + 20]
+ repe cmpsb
+ movzx eax, byte [esi - 1]
+ movzx edx, byte [edi - 1]
+ sub eax, edx
+ pop edi
+ pop esi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S
new file mode 100644
index 000000000000..dbd052ba71c0
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S
@@ -0,0 +1,85 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# CopyMem.S
+#
+# Abstract:
+#
+# CopyMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
+
+#------------------------------------------------------------------------------
+# VOID *
+# EFIAPI
+# InternalMemCopyMem (
+# IN VOID *Destination,
+# IN VOID *Source,
+# IN UINTN Count
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemCopyMem):
+ push %esi
+ push %edi
+ movl 16(%esp), %esi # esi <- Source
+ movl 12(%esp), %edi # edi <- Destination
+ movl 20(%esp), %edx # edx <- Count
+ leal -1(%esi,%edx,), %eax # eax <- End of Source
+ cmpl %edi, %esi
+ jae L0
+ cmpl %edi, %eax # Overlapped?
+ jae L_CopyBackward # Copy backward if overlapped
+L0:
+ xorl %ecx, %ecx
+ subl %edi, %ecx
+ andl $15, %ecx # ecx + edi aligns on 16-byte boundary
+ jz L1
+ cmpl %edx, %ecx
+ cmova %edx, %ecx
+ subl %ecx, %edx # edx <- remaining bytes to copy
+ rep
+ movsb
+L1:
+ movl %edx, %ecx
+ andl $15, %edx
+ shrl $4, %ecx # ecx <- # of DQwords to copy
+ jz L_CopyBytes
+ addl $-16, %esp
+ movdqu %xmm0, (%esp)
+L2:
+ movdqu (%esi), %xmm0
+ movntdq %xmm0, (%edi)
+ addl $16, %esi
+ addl $16, %edi
+ loop L2
+ mfence
+ movdqu (%esp),%xmm0
+ addl $16, %esp # stack cleanup
+ jmp L_CopyBytes
+L_CopyBackward:
+ movl %eax, %esi # esi <- Last byte in Source
+ leal -1(%edi,%edx,), %edi # edi <- Last byte in Destination
+ std
+L_CopyBytes:
+ movl %edx, %ecx
+ rep
+ movsb
+ cld
+ movl 12(%esp), %eax # eax <- Destination as return value
+ pop %edi
+ pop %esi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm
new file mode 100644
index 000000000000..84fad9190d2f
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CopyMem.asm
+;
+; Abstract:
+;
+; CopyMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .xmm
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemCopyMem (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+InternalMemCopyMem PROC USES esi edi
+ mov esi, [esp + 16] ; esi <- Source
+ mov edi, [esp + 12] ; edi <- Destination
+ mov edx, [esp + 20] ; edx <- Count
+ lea eax, [esi + edx - 1] ; eax <- End of Source
+ cmp esi, edi
+ jae @F
+ cmp eax, edi ; Overlapped?
+ jae @CopyBackward ; Copy backward if overlapped
+@@:
+ xor ecx, ecx
+ sub ecx, edi
+ and ecx, 15 ; ecx + edi aligns on 16-byte boundary
+ jz @F
+ cmp ecx, edx
+ cmova ecx, edx
+ sub edx, ecx ; edx <- remaining bytes to copy
+ rep movsb
+@@:
+ mov ecx, edx
+ and edx, 15
+ shr ecx, 4 ; ecx <- # of DQwords to copy
+ jz @CopyBytes
+ add esp, -16
+ movdqu [esp], xmm0 ; save xmm0
+@@:
+ movdqu xmm0, [esi] ; esi may not be 16-bytes aligned
+ movntdq [edi], xmm0 ; edi should be 16-bytes aligned
+ add esi, 16
+ add edi, 16
+ loop @B
+ mfence
+ movdqu xmm0, [esp] ; restore xmm0
+ add esp, 16 ; stack cleanup
+ jmp @CopyBytes
+@CopyBackward:
+ mov esi, eax ; esi <- Last byte in Source
+ lea edi, [edi + edx - 1] ; edi <- Last byte in Destination
+ std
+@CopyBytes:
+ mov ecx, edx
+ rep movsb
+ cld
+ mov eax, [esp + 12] ; eax <- Destination as return value
+ ret
+InternalMemCopyMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.nasm
new file mode 100644
index 000000000000..6913874d3055
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.nasm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CopyMem.nasm
+;
+; Abstract:
+;
+; CopyMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemCopyMem (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ push esi
+ push edi
+ mov esi, [esp + 16] ; esi <- Source
+ mov edi, [esp + 12] ; edi <- Destination
+ mov edx, [esp + 20] ; edx <- Count
+ lea eax, [esi + edx - 1] ; eax <- End of Source
+ cmp esi, edi
+ jae .0
+ cmp eax, edi ; Overlapped?
+ jae @CopyBackward ; Copy backward if overlapped
+.0:
+ xor ecx, ecx
+ sub ecx, edi
+ and ecx, 15 ; ecx + edi aligns on 16-byte boundary
+ jz .1
+ cmp ecx, edx
+ cmova ecx, edx
+ sub edx, ecx ; edx <- remaining bytes to copy
+ rep movsb
+.1:
+ mov ecx, edx
+ and edx, 15
+ shr ecx, 4 ; ecx <- # of DQwords to copy
+ jz @CopyBytes
+ add esp, -16
+ movdqu [esp], xmm0 ; save xmm0
+.2:
+ movdqu xmm0, [esi] ; esi may not be 16-bytes aligned
+ movntdq [edi], xmm0 ; edi should be 16-bytes aligned
+ add esi, 16
+ add edi, 16
+ loop .2
+ mfence
+ movdqu xmm0, [esp] ; restore xmm0
+ add esp, 16 ; stack cleanup
+ jmp @CopyBytes
+@CopyBackward:
+ mov esi, eax ; esi <- Last byte in Source
+ lea edi, [edi + edx - 1] ; edi <- Last byte in Destination
+ std
+@CopyBytes:
+ mov ecx, edx
+ rep movsb
+ cld
+ mov eax, [esp + 12] ; eax <- Destination as return value
+ pop edi
+ pop esi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/IsZeroBuffer.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/IsZeroBuffer.nasm
new file mode 100644
index 000000000000..cfd41a62500b
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/IsZeroBuffer.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. 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.
+;
+; Module Name:
+;
+; IsZeroBuffer.nasm
+;
+; Abstract:
+;
+; IsZeroBuffer function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; BOOLEAN
+; EFIAPI
+; InternalMemIsZeroBuffer (
+; IN CONST VOID *Buffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemIsZeroBuffer)
+ASM_PFX(InternalMemIsZeroBuffer):
+ push edi
+ mov edi, [esp + 8] ; edi <- Buffer
+ mov ecx, [esp + 12] ; ecx <- Length
+ mov edx, ecx ; edx <- ecx
+ shr ecx, 2 ; ecx <- number of dwords
+ and edx, 3 ; edx <- number of trailing bytes
+ xor eax, eax ; eax <- 0, also set ZF
+ repe scasd
+ jnz @ReturnFalse ; ZF=0 means non-zero element found
+ mov ecx, edx
+ repe scasb
+ jnz @ReturnFalse
+ pop edi
+ mov eax, 1 ; return TRUE
+ ret
+@ReturnFalse:
+ pop edi
+ xor eax, eax
+ ret ; return FALSE
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S
new file mode 100644
index 000000000000..c485543e873e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem16.Asm
+#
+# Abstract:
+#
+# ScanMem16 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem16 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT16 Value
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemScanMem16):
+ push %edi
+ movl 12(%esp), %ecx
+ movl 8(%esp), %edi
+ movl 16(%esp), %eax
+ repne scasw
+ leal -2(%edi), %eax
+ cmovnz %ecx, %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm
new file mode 100644
index 000000000000..bca66e02c896
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem16.Asm
+;
+; Abstract:
+;
+; ScanMem16 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem16 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT16 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem16 PROC USES edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov eax, [esp + 16]
+ repne scasw
+ lea eax, [edi - 2]
+ cmovnz eax, ecx
+ ret
+InternalMemScanMem16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.nasm
new file mode 100644
index 000000000000..78d9f3071e8c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.nasm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem16.Asm
+;
+; Abstract:
+;
+; ScanMem16 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem16 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT16 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem16)
+ASM_PFX(InternalMemScanMem16):
+ push edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov eax, [esp + 16]
+ repne scasw
+ lea eax, [edi - 2]
+ cmovnz eax, ecx
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S
new file mode 100644
index 000000000000..016ebd252265
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem32.S
+#
+# Abstract:
+#
+# ScanMem32 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem32 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT32 Value
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemScanMem32):
+ push %edi
+ movl 12(%esp), %ecx
+ movl 8(%esp), %edi
+ movl 16(%esp), %eax
+ repne scasl
+ leal -4(%edi), %eax
+ cmovnz %ecx, %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm
new file mode 100644
index 000000000000..8c24bd010953
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem32.Asm
+;
+; Abstract:
+;
+; ScanMem32 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem32 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem32 PROC USES edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov eax, [esp + 16]
+ repne scasd
+ lea eax, [edi - 4]
+ cmovnz eax, ecx
+ ret
+InternalMemScanMem32 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.nasm
new file mode 100644
index 000000000000..bbacf38a7245
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.nasm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem32.Asm
+;
+; Abstract:
+;
+; ScanMem32 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem32 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem32)
+ASM_PFX(InternalMemScanMem32):
+ push edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov eax, [esp + 16]
+ repne scasd
+ lea eax, [edi - 4]
+ cmovnz eax, ecx
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S
new file mode 100644
index 000000000000..6e4285645711
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem64.S
+#
+# Abstract:
+#
+# ScanMem64 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem64 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT64 Value
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemScanMem64):
+ push %edi
+ movl 12(%esp), %ecx
+ movl 16(%esp), %eax
+ movl 20(%esp), %edx
+ movl 8(%esp), %edi
+L0:
+ cmpl (%edi), %eax
+ leal 8(%edi), %edi
+ loopne L0
+ jne L1
+ cmpl -4(%edi), %edx
+ jecxz L1
+ jne L0
+L1:
+ leal -8(%edi), %eax
+ cmovne %ecx, %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm
new file mode 100644
index 000000000000..c835effc0cea
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem64.Asm
+;
+; Abstract:
+;
+; ScanMem64 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem64 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem64 PROC USES edi
+ mov ecx, [esp + 12]
+ mov eax, [esp + 16]
+ mov edx, [esp + 20]
+ mov edi, [esp + 8]
+@@:
+ cmp eax, [edi]
+ lea edi, [edi + 8]
+ loopne @B
+ jne @F
+ cmp edx, [edi - 4]
+ jecxz @F
+ jne @B
+@@:
+ lea eax, [edi - 8]
+ cmovne eax, ecx
+ ret
+InternalMemScanMem64 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.nasm
new file mode 100644
index 000000000000..e994d4ac437a
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem64.Asm
+;
+; Abstract:
+;
+; ScanMem64 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem64 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem64)
+ASM_PFX(InternalMemScanMem64):
+ push edi
+ mov ecx, [esp + 12]
+ mov eax, [esp + 16]
+ mov edx, [esp + 20]
+ mov edi, [esp + 8]
+.0:
+ cmp eax, [edi]
+ lea edi, [edi + 8]
+ loopne .0
+ jne .1
+ cmp edx, [edi - 4]
+ jecxz .1
+ jne .0
+.1:
+ lea eax, [edi - 8]
+ cmovne eax, ecx
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S
new file mode 100644
index 000000000000..02bb27f36ac6
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem8.S
+#
+# Abstract:
+#
+# ScanMem8 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem8 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT8 Value
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemScanMem8):
+ push %edi
+ movl 12(%esp), %ecx
+ movl 8(%esp), %edi
+ movb 16(%esp), %al
+ repne scasb
+ leal -1(%edi), %eax
+ cmovnz %ecx, %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm
new file mode 100644
index 000000000000..f199bb957a6c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem8.Asm
+;
+; Abstract:
+;
+; ScanMem8 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem8 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT8 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem8 PROC USES edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov al, [esp + 16]
+ repne scasb
+ lea eax, [edi - 1]
+ cmovnz eax, ecx
+ ret
+InternalMemScanMem8 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.nasm
new file mode 100644
index 000000000000..d13c9c7bf400
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.nasm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem8.Asm
+;
+; Abstract:
+;
+; ScanMem8 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem8 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT8 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ push edi
+ mov ecx, [esp + 12]
+ mov edi, [esp + 8]
+ mov al, [esp + 16]
+ repne scasb
+ lea eax, [edi - 1]
+ cmovnz eax, ecx
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S
new file mode 100644
index 000000000000..ee0b659afd97
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S
@@ -0,0 +1,50 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem.S
+#
+# Abstract:
+#
+# SetMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemSetMem (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT8 Value
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemSetMem):
+ push %edi
+ movl 12(%esp),%ecx
+ movb 16(%esp),%al
+ movb %al, %ah
+ shrd $16, %eax, %edx
+ shld $16, %edx, %eax
+ movl %ecx, %edx
+ movl 8(%esp),%edi
+ shr $2, %ecx
+ rep stosl
+ movl %edx, %ecx
+ andl $3, %ecx
+ rep stosb
+ movl 8(%esp),%eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm
new file mode 100644
index 000000000000..6de9c2ff8077
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem.Asm
+;
+; Abstract:
+;
+; SetMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT8 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem PROC USES edi
+ mov ecx, [esp + 12]
+ mov al, [esp + 16]
+ mov ah, al
+ shrd edx, eax, 16
+ shld eax, edx, 16
+ mov edx, ecx
+ mov edi, [esp + 8]
+ shr ecx, 2
+ rep stosd
+ mov ecx, edx
+ and ecx, 3
+ rep stosb
+ mov eax, [esp + 8]
+ ret
+InternalMemSetMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.nasm
new file mode 100644
index 000000000000..3a75363e3ad3
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.nasm
@@ -0,0 +1,52 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem.Asm
+;
+; Abstract:
+;
+; SetMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT8 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ push edi
+ mov ecx, [esp + 12]
+ mov al, [esp + 16]
+ mov ah, al
+ shrd edx, eax, 16
+ shld eax, edx, 16
+ mov edx, ecx
+ mov edi, [esp + 8]
+ shr ecx, 2
+ rep stosd
+ mov ecx, edx
+ and ecx, 3
+ rep stosb
+ mov eax, [esp + 8]
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S
new file mode 100644
index 000000000000..8989bdd02f40
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem16.S
+#
+# Abstract:
+#
+# SetMem16 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemSetMem16 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT16 Value
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemSetMem16):
+ push %edi
+ movl 16(%esp), %eax
+ movl 8(%esp), %edi
+ movl 12(%esp), %ecx
+ rep
+ stosw
+ movl 8(%esp), %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm
new file mode 100644
index 000000000000..3d8c9a6299fc
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem16.Asm
+;
+; Abstract:
+;
+; SetMem16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem16 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT16 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem16 PROC USES edi
+ mov eax, [esp + 16]
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ rep stosw
+ mov eax, [esp + 8]
+ ret
+InternalMemSetMem16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.nasm
new file mode 100644
index 000000000000..cfa4906e729c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.nasm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem16.Asm
+;
+; Abstract:
+;
+; SetMem16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem16 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT16 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ push edi
+ mov eax, [esp + 16]
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ rep stosw
+ mov eax, [esp + 8]
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S
new file mode 100644
index 000000000000..b2c9a854a988
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem32.S
+#
+# Abstract:
+#
+# SetMem32 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemSetMem32 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT32 Value
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemSetMem32):
+ push %edi
+ movl 16(%esp),%eax
+ movl 8(%esp),%edi
+ movl 12(%esp),%ecx
+ rep
+ stosl
+ movl 8(%esp),%eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm
new file mode 100644
index 000000000000..f1e1991b8d67
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem32.Asm
+;
+; Abstract:
+;
+; SetMem32 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem32 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT32 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem32 PROC USES edi
+ mov eax, [esp + 16]
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ rep stosd
+ mov eax, [esp + 8]
+ ret
+InternalMemSetMem32 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.nasm
new file mode 100644
index 000000000000..78e09b39e2a2
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.nasm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem32.Asm
+;
+; Abstract:
+;
+; SetMem32 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem32 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT32 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ push edi
+ mov eax, [esp + 16]
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ rep stosd
+ mov eax, [esp + 8]
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S
new file mode 100644
index 000000000000..f25dfe180432
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem64.S
+#
+# Abstract:
+#
+# SetMem64 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemSetMem64 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT64 Value
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemSetMem64):
+ push %edi
+ movl 12(%esp), %ecx
+ movl 16(%esp), %eax
+ movl 20(%esp), %edx
+ movl 8(%esp), %edi
+L0:
+ mov %eax, -8(%edi, %ecx, 8)
+ mov %edx, -4(%edi, %ecx, 8)
+ loop L0
+ movl %edi, %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm
new file mode 100644
index 000000000000..31d718adae72
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem64.Asm
+;
+; Abstract:
+;
+; SetMem64 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem64 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT64 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem64 PROC USES edi
+ mov ecx, [esp + 12]
+ mov eax, [esp + 16]
+ mov edx, [esp + 20]
+ mov edi, [esp + 8]
+@@:
+ mov [edi + ecx*8 - 8], eax
+ mov [edi + ecx*8 - 4], edx
+ loop @B
+ mov eax, edi
+ ret
+InternalMemSetMem64 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.nasm
new file mode 100644
index 000000000000..d0afacb52493
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.nasm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem64.Asm
+;
+; Abstract:
+;
+; SetMem64 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem64 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT64 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ push edi
+ mov ecx, [esp + 12]
+ mov eax, [esp + 16]
+ mov edx, [esp + 20]
+ mov edi, [esp + 8]
+.0:
+ mov [edi + ecx*8 - 8], eax
+ mov [edi + ecx*8 - 4], edx
+ loop .0
+ mov eax, edi
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S
new file mode 100644
index 000000000000..70cede6cce93
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ZeroMem.S
+#
+# Abstract:
+#
+# ZeroMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemZeroMem (
+# IN VOID *Buffer,
+# IN UINTN Count
+# );
+#------------------------------------------------------------------------------
+ASM_PFX(InternalMemZeroMem):
+ push %edi
+ xorl %eax,%eax
+ movl 8(%esp),%edi
+ movl 12(%esp),%ecx
+ movl %ecx,%edx
+ shrl $2,%ecx
+ andl $3,%edx
+ pushl %edi
+ rep
+ stosl
+ movl %edx,%ecx
+ rep
+ stosb
+ popl %eax
+ pop %edi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm
new file mode 100644
index 000000000000..01ea1af932ee
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ZeroMem.Asm
+;
+; Abstract:
+;
+; ZeroMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemZeroMem (
+; IN VOID *Buffer,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+InternalMemZeroMem PROC USES edi
+ xor eax, eax
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ mov edx, ecx
+ shr ecx, 2
+ and edx, 3
+ push edi
+ rep stosd
+ mov ecx, edx
+ rep stosb
+ pop eax
+ ret
+InternalMemZeroMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.nasm
new file mode 100644
index 000000000000..31efb6ad8668
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.nasm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ZeroMem.Asm
+;
+; Abstract:
+;
+; ZeroMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemZeroMem (
+; IN VOID *Buffer,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ push edi
+ xor eax, eax
+ mov edi, [esp + 8]
+ mov ecx, [esp + 12]
+ mov edx, ecx
+ shr ecx, 2
+ and edx, 3
+ push edi
+ rep stosd
+ mov ecx, edx
+ rep stosb
+ pop eax
+ pop edi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/IsZeroBufferWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/IsZeroBufferWrapper.c
new file mode 100644
index 000000000000..078c924da153
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/IsZeroBufferWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ Implementation of IsZeroBuffer function.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2016, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Checks if the contents of a buffer are all zeros.
+
+ This function checks whether the contents of a buffer are all zeros. If the
+ contents are all zeros, return TRUE. Otherwise, return FALSE.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ ASSERT (!(Buffer == NULL && Length > 0));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ return InternalMemIsZeroBuffer (Buffer, Length);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c b/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c
new file mode 100644
index 000000000000..4aab05d53b67
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c
@@ -0,0 +1,171 @@
+/** @file
+ Implementation of GUID functions.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2016, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source GUID to a destination GUID.
+
+ This function copies the contents of the 128-bit GUID specified by SourceGuid to
+ DestinationGuid, and returns DestinationGuid.
+
+ If DestinationGuid is NULL, then ASSERT().
+ If SourceGuid is NULL, then ASSERT().
+
+ @param DestinationGuid The pointer to the destination GUID.
+ @param SourceGuid The pointer to the source GUID.
+
+ @return DestinationGuid.
+
+**/
+GUID *
+EFIAPI
+CopyGuid (
+ OUT GUID *DestinationGuid,
+ IN CONST GUID *SourceGuid
+ )
+{
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+ );
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid + 1,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+ );
+ return DestinationGuid;
+}
+
+/**
+ Compares two GUIDs.
+
+ This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
+ If there are any bit differences in the two GUIDs, then FALSE is returned.
+
+ If Guid1 is NULL, then ASSERT().
+ If Guid2 is NULL, then ASSERT().
+
+ @param Guid1 A pointer to a 128 bit GUID.
+ @param Guid2 A pointer to a 128 bit GUID.
+
+ @retval TRUE Guid1 and Guid2 are identical.
+ @retval FALSE Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+CompareGuid (
+ IN CONST GUID *Guid1,
+ IN CONST GUID *Guid2
+ )
+{
+ UINT64 LowPartOfGuid1;
+ UINT64 LowPartOfGuid2;
+ UINT64 HighPartOfGuid1;
+ UINT64 HighPartOfGuid2;
+
+ LowPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1);
+ LowPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2);
+ HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);
+ HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);
+
+ return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);
+}
+
+/**
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Guid The value to search for in the target buffer.
+
+ @return A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanGuid (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN CONST GUID *Guid
+ )
+{
+ CONST GUID *GuidPtr;
+
+ ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);
+
+ GuidPtr = (GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (CONST GUID*)Buffer) {
+ if (CompareGuid (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
+
+/**
+ Checks if the given GUID is a zero GUID.
+
+ This function checks whether the given GUID is a zero GUID. If the GUID is
+ identical to a zero GUID then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The pointer to a 128 bit GUID.
+
+ @retval TRUE Guid is a zero GUID.
+ @retval FALSE Guid is not a zero GUID.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroGuid (
+ IN CONST GUID *Guid
+ )
+{
+ UINT64 LowPartOfGuid;
+ UINT64 HighPartOfGuid;
+
+ LowPartOfGuid = ReadUnaligned64 ((CONST UINT64*) Guid);
+ HighPartOfGuid = ReadUnaligned64 ((CONST UINT64*) Guid + 1);
+
+ return (BOOLEAN) (LowPartOfGuid == 0 && HighPartOfGuid == 0);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h b/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h
new file mode 100644
index 000000000000..be7952e75c86
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h
@@ -0,0 +1,251 @@
+/** @file
+ Declaration of internal functions for Base Memory Library.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+
+ Copyright (c) 2006 - 2016, Intel Corporation. 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.
+
+**/
+
+#ifndef __MEM_LIB_INTERNALS__
+#define __MEM_LIB_INTERNALS__
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer The target of the copy request.
+ @param SourceBuffer The place to copy from.
+ @param Length The number of bytes to copy.
+
+ @return Destination.
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer The memory to set.
+ @param Length The number of bytes to set.
+ @param Value The value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The count of 16-bit value to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The count of 32-bit value to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The count of 64-bit value to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+/**
+ Set Buffer to 0 for Size bytes.
+
+ @param Buffer The memory to set.
+ @param Length The number of bytes to set
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+InternalMemZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ Compares two memory buffers of a given length.
+
+ @param DestinationBuffer The first memory buffer.
+ @param SourceBuffer The second memory buffer.
+ @param Length The length of DestinationBuffer and SourceBuffer memory
+ regions to compare. Must be non-zero.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+InternalMemCompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the
+ matching 8-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 8-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 16-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 32-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The count of 64-bit value to scan. Must be non-zero.
+ @param Value The value to search for in the target buffer.
+
+ @return The pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+/**
+ Checks whether the contents of a buffer are all zeros.
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+InternalMemIsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ );
+
+#endif
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c
new file mode 100644
index 000000000000..c407469843c4
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 16-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Value The value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c
new file mode 100644
index 000000000000..a3243a67089c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ ScanMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 32-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Value The value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c
new file mode 100644
index 000000000000..10ed74d50256
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 64-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Value The value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c
new file mode 100644
index 000000000000..229703ebcccf
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c
@@ -0,0 +1,100 @@
+/** @file
+ ScanMem8() and ScanMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for an 8-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Value The value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);
+}
+
+/**
+ Scans a target buffer for a UINTN sized value, and returns a pointer to the matching
+ UINTN sized value in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a UINTN sized value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to scan.
+ @param Length The number of bytes in Buffer to scan.
+ @param Value
+The value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMemN (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return ScanMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return ScanMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c
new file mode 100644
index 000000000000..8e6daa3928cc
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 16-bit value specified by
+ Value, and returns Buffer. Value is repeated every 16-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c
new file mode 100644
index 000000000000..7758e1f438db
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 32-bit value specified by
+ Value, and returns Buffer. Value is repeated every 32-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c
new file mode 100644
index 000000000000..5273a864f187
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 64-bit value specified by
+ Value, and returns Buffer. Value is repeated every 64-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
new file mode 100644
index 000000000000..6e3c3f80f3b2
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file
+ SetMem() and SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a byte value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with Value, and returns Buffer.
+
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The memory to set.
+ @param Length The number of bytes to set.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return InternalMemSetMem (Buffer, Length, Value);
+}
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S
new file mode 100644
index 000000000000..90a04bb709ba
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#
+# ConvertAsm.py: Automatically generated from CompareMem.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# CompareMem.S
+#
+# Abstract:
+#
+# CompareMem function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# INTN
+# EFIAPI
+# InternalMemCompareMem (
+# IN CONST VOID *DestinationBuffer,
+# IN CONST VOID *SourceBuffer,
+# IN UINTN Length
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ pushq %rsi
+ pushq %rdi
+ movq %rcx, %rsi
+ movq %rdx, %rdi
+ movq %r8, %rcx
+ repe cmpsb
+ movzbq -1(%rsi) , %rax
+ movzbq -1(%rdi) , %rdx
+ sub %dl, %al
+ popq %rdi
+ popq %rsi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm
new file mode 100644
index 000000000000..09f077b85df8
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CompareMem.Asm
+;
+; Abstract:
+;
+; CompareMem function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; INTN
+; EFIAPI
+; InternalMemCompareMem (
+; IN CONST VOID *DestinationBuffer,
+; IN CONST VOID *SourceBuffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+InternalMemCompareMem PROC USES rsi rdi
+ mov rsi, rcx
+ mov rdi, rdx
+ mov rcx, r8
+ repe cmpsb
+ movzx rax, byte ptr [rsi - 1]
+ movzx rdx, byte ptr [rdi - 1]
+ sub rax, rdx
+ ret
+InternalMemCompareMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.nasm
new file mode 100644
index 000000000000..cb0d88658387
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.nasm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CompareMem.Asm
+;
+; Abstract:
+;
+; CompareMem function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; INTN
+; EFIAPI
+; InternalMemCompareMem (
+; IN CONST VOID *DestinationBuffer,
+; IN CONST VOID *SourceBuffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ push rsi
+ push rdi
+ mov rsi, rcx
+ mov rdi, rdx
+ mov rcx, r8
+ repe cmpsb
+ movzx rax, byte [rsi - 1]
+ movzx rdx, byte [rdi - 1]
+ sub rax, rdx
+ pop rdi
+ pop rsi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S
new file mode 100644
index 000000000000..39e36bd7f147
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S
@@ -0,0 +1,82 @@
+#
+# ConvertAsm.py: Automatically generated from CopyMem.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# CopyMem.S
+#
+# Abstract:
+#
+# CopyMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# VOID *
+# EFIAPI
+# InternalMemCopyMem (
+# IN VOID *Destination,
+# IN VOID *Source,
+# IN UINTN Count
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ pushq %rsi
+ pushq %rdi
+ movq %rdx, %rsi # rsi <- Source
+ movq %rcx, %rdi # rdi <- Destination
+ leaq -1(%rsi,%r8,), %r9 # r9 <- Last byte of Source
+ cmpq %rdi, %rsi
+ movq %rdi, %rax # rax <- Destination as return value
+ jae L0 # Copy forward if Source > Destination
+ cmpq %rdi, %r9 # Overlapped?
+ jae L_CopyBackward # Copy backward if overlapped
+L0:
+ xorq %rcx, %rcx
+ subq %rdi, %rcx # rcx <- -rdi
+ andq $15, %rcx # rcx + rsi should be 16 bytes aligned
+ jz L1 # skip if rcx == 0
+ cmpq %r8, %rcx
+ cmova %r8, %rcx
+ subq %rcx, %r8
+ rep movsb
+L1:
+ movq %r8, %rcx
+ andq $15, %r8
+ shrq $4, %rcx # rcx <- # of DQwords to copy
+ jz L_CopyBytes
+ movdqu %xmm0, 0x18(%rsp) # save xmm0 on stack
+L2:
+ movdqu (%rsi), %xmm0 # rsi may not be 16-byte aligned
+ movntdq %xmm0, (%rdi) # rdi should be 16-byte aligned
+ addq $16, %rsi
+ addq $16, %rdi
+ loop L2
+ mfence
+ movdqa 0x18(%rsp), %xmm0 # restore xmm0
+ jmp L_CopyBytes # copy remaining bytes
+L_CopyBackward:
+ movq %r9, %rsi # rsi <- Last byte of Source
+ leaq -1(%rdi, %r8,), %rdi # rdi <- Last byte of Destination
+ std
+L_CopyBytes:
+ movq %r8, %rcx
+ rep movsb
+ cld
+ popq %rdi
+ popq %rsi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm
new file mode 100644
index 000000000000..9218003428f6
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CopyMem.asm
+;
+; Abstract:
+;
+; CopyMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemCopyMem (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+InternalMemCopyMem PROC USES rsi rdi
+ mov rsi, rdx ; rsi <- Source
+ mov rdi, rcx ; rdi <- Destination
+ lea r9, [rsi + r8 - 1] ; r9 <- Last byte of Source
+ cmp rsi, rdi
+ mov rax, rdi ; rax <- Destination as return value
+ jae @F ; Copy forward if Source > Destination
+ cmp r9, rdi ; Overlapped?
+ jae @CopyBackward ; Copy backward if overlapped
+@@:
+ xor rcx, rcx
+ sub rcx, rdi ; rcx <- -rdi
+ and rcx, 15 ; rcx + rsi should be 16 bytes aligned
+ jz @F ; skip if rcx == 0
+ cmp rcx, r8
+ cmova rcx, r8
+ sub r8, rcx
+ rep movsb
+@@:
+ mov rcx, r8
+ and r8, 15
+ shr rcx, 4 ; rcx <- # of DQwords to copy
+ jz @CopyBytes
+ movdqa [rsp + 18h], xmm0 ; save xmm0 on stack
+@@:
+ movdqu xmm0, [rsi] ; rsi may not be 16-byte aligned
+ movntdq [rdi], xmm0 ; rdi should be 16-byte aligned
+ add rsi, 16
+ add rdi, 16
+ loop @B
+ mfence
+ movdqa xmm0, [rsp + 18h] ; restore xmm0
+ jmp @CopyBytes ; copy remaining bytes
+@CopyBackward:
+ mov rsi, r9 ; rsi <- Last byte of Source
+ lea rdi, [rdi + r8 - 1] ; rdi <- Last byte of Destination
+ std
+@CopyBytes:
+ mov rcx, r8
+ rep movsb
+ cld
+ ret
+InternalMemCopyMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.nasm
new file mode 100644
index 000000000000..9fe45d4e8c2f
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.nasm
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; CopyMem.nasm
+;
+; Abstract:
+;
+; CopyMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemCopyMem (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ push rsi
+ push rdi
+ mov rsi, rdx ; rsi <- Source
+ mov rdi, rcx ; rdi <- Destination
+ lea r9, [rsi + r8 - 1] ; r9 <- Last byte of Source
+ cmp rsi, rdi
+ mov rax, rdi ; rax <- Destination as return value
+ jae .0 ; Copy forward if Source > Destination
+ cmp r9, rdi ; Overlapped?
+ jae @CopyBackward ; Copy backward if overlapped
+.0:
+ xor rcx, rcx
+ sub rcx, rdi ; rcx <- -rdi
+ and rcx, 15 ; rcx + rsi should be 16 bytes aligned
+ jz .1 ; skip if rcx == 0
+ cmp rcx, r8
+ cmova rcx, r8
+ sub r8, rcx
+ rep movsb
+.1:
+ mov rcx, r8
+ and r8, 15
+ shr rcx, 4 ; rcx <- # of DQwords to copy
+ jz @CopyBytes
+ movdqa [rsp + 0x18], xmm0 ; save xmm0 on stack
+.2:
+ movdqu xmm0, [rsi] ; rsi may not be 16-byte aligned
+ movntdq [rdi], xmm0 ; rdi should be 16-byte aligned
+ add rsi, 16
+ add rdi, 16
+ loop .2
+ mfence
+ movdqa xmm0, [rsp + 0x18] ; restore xmm0
+ jmp @CopyBytes ; copy remaining bytes
+@CopyBackward:
+ mov rsi, r9 ; rsi <- Last byte of Source
+ lea rdi, [rdi + r8 - 1] ; rdi <- Last byte of Destination
+ std
+@CopyBytes:
+ mov rcx, r8
+ rep movsb
+ cld
+ pop rdi
+ pop rsi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/IsZeroBuffer.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/IsZeroBuffer.nasm
new file mode 100644
index 000000000000..3b855a7bf4a6
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/IsZeroBuffer.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. 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.
+;
+; Module Name:
+;
+; IsZeroBuffer.nasm
+;
+; Abstract:
+;
+; IsZeroBuffer function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; BOOLEAN
+; EFIAPI
+; InternalMemIsZeroBuffer (
+; IN CONST VOID *Buffer,
+; IN UINTN Length
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemIsZeroBuffer)
+ASM_PFX(InternalMemIsZeroBuffer):
+ push rdi
+ mov rdi, rcx ; rdi <- Buffer
+ mov rcx, rdx ; rcx <- Length
+ shr rcx, 3 ; rcx <- number of qwords
+ and rdx, 7 ; rdx <- number of trailing bytes
+ xor rax, rax ; rax <- 0, also set ZF
+ repe scasq
+ jnz @ReturnFalse ; ZF=0 means non-zero element found
+ mov rcx, rdx
+ repe scasb
+ jnz @ReturnFalse
+ pop rdi
+ mov rax, 1 ; return TRUE
+ ret
+@ReturnFalse:
+ pop rdi
+ xor rax, rax
+ ret ; return FALSE
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S
new file mode 100644
index 000000000000..ea82f5558829
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#
+# ConvertAsm.py: Automatically generated from ScanMem16.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem16.S
+#
+# Abstract:
+#
+# ScanMem16 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem16 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT16 Value
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)
+ASM_PFX(InternalMemScanMem16):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ movq %rdx, %rcx
+ repne scasw
+ leaq -2(%rdi), %rax
+ cmovnz %rcx, %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm
new file mode 100644
index 000000000000..75200414d1c1
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem16.Asm
+;
+; Abstract:
+;
+; ScanMem16 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem16 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT16 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem16 PROC USES rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasw
+ lea rax, [rdi - 2]
+ cmovnz rax, rcx
+ ret
+InternalMemScanMem16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.nasm
new file mode 100644
index 000000000000..9f0de63ea655
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem16.Asm
+;
+; Abstract:
+;
+; ScanMem16 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem16 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT16 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem16)
+ASM_PFX(InternalMemScanMem16):
+ push rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasw
+ lea rax, [rdi - 2]
+ cmovnz rax, rcx
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S
new file mode 100644
index 000000000000..7ff1c08e111c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#
+# ConvertAsm.py: Automatically generated from ScanMem32.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem32.S
+#
+# Abstract:
+#
+# ScanMem32 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem32 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT32 Value
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)
+ASM_PFX(InternalMemScanMem32):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ movq %rdx, %rcx
+ repne scasl
+ leaq -4(%rdi), %rax
+ cmovnz %rcx, %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm
new file mode 100644
index 000000000000..ad47e5a53a13
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem32.Asm
+;
+; Abstract:
+;
+; ScanMem32 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem32 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem32 PROC USES rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasd
+ lea rax, [rdi - 4]
+ cmovnz rax, rcx
+ ret
+InternalMemScanMem32 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.nasm
new file mode 100644
index 000000000000..5c9ae5d08389
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem32.Asm
+;
+; Abstract:
+;
+; ScanMem32 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem32 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem32)
+ASM_PFX(InternalMemScanMem32):
+ push rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasd
+ lea rax, [rdi - 4]
+ cmovnz rax, rcx
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S
new file mode 100644
index 000000000000..1948c16e302c
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S
@@ -0,0 +1,55 @@
+#
+# ConvertAsm.py: Automatically generated from ScanMem64.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem64.S
+#
+# Abstract:
+#
+# ScanMem64 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem64 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT64 Value
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)
+ASM_PFX(InternalMemScanMem64):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ movq %rdx, %rcx
+ repne scasq
+ leaq -8(%rdi), %rax
+ cmovnz %rcx, %rax
+ popq %rdi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm
new file mode 100644
index 000000000000..3eb5b719fa07
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem64.Asm
+;
+; Abstract:
+;
+; ScanMem64 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem64 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem64 PROC USES rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasq
+ lea rax, [rdi - 8]
+ cmovnz rax, rcx
+ ret
+InternalMemScanMem64 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.nasm
new file mode 100644
index 000000000000..b98c6dece330
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem64.Asm
+;
+; Abstract:
+;
+; ScanMem64 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem64 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem64)
+ASM_PFX(InternalMemScanMem64):
+ push rdi
+ mov rdi, rcx
+ mov rax, r8
+ mov rcx, rdx
+ repne scasq
+ lea rax, [rdi - 8]
+ cmovnz rax, rcx
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S
new file mode 100644
index 000000000000..688884f448a4
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#
+# ConvertAsm.py: Automatically generated from ScanMem8.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ScanMem8.S
+#
+# Abstract:
+#
+# ScanMem8 function
+#
+# Notes:
+#
+# The following BaseMemoryLib instances contain the same copy of this file:
+#
+# BaseMemoryLibRepStr
+# BaseMemoryLibMmx
+# BaseMemoryLibSse2
+# BaseMemoryLibOptDxe
+# BaseMemoryLibOptPei
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# CONST VOID *
+# EFIAPI
+# InternalMemScanMem8 (
+# IN CONST VOID *Buffer,
+# IN UINTN Length,
+# IN UINT8 Value
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %rdx, %rcx
+ movq %r8, %rax
+ repne scasb
+ leaq -1(%rdi), %rax
+ cmovnz %rcx, %rax # set rax to 0 if not found
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm
new file mode 100644
index 000000000000..8ece85e5b4a2
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem8.Asm
+;
+; Abstract:
+;
+; ScanMem8 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem8 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT8 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemScanMem8 PROC USES rdi
+ mov rdi, rcx
+ mov rcx, rdx
+ mov rax, r8
+ repne scasb
+ lea rax, [rdi - 1]
+ cmovnz rax, rcx ; set rax to 0 if not found
+ ret
+InternalMemScanMem8 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.nasm
new file mode 100644
index 000000000000..8499795a1d7e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.nasm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ScanMem8.Asm
+;
+; Abstract:
+;
+; ScanMem8 function
+;
+; Notes:
+;
+; The following BaseMemoryLib instances contain the same copy of this file:
+;
+; BaseMemoryLibRepStr
+; BaseMemoryLibMmx
+; BaseMemoryLibSse2
+; BaseMemoryLibOptDxe
+; BaseMemoryLibOptPei
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; CONST VOID *
+; EFIAPI
+; InternalMemScanMem8 (
+; IN CONST VOID *Buffer,
+; IN UINTN Length,
+; IN UINT8 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ push rdi
+ mov rdi, rcx
+ mov rcx, rdx
+ mov rax, r8
+ repne scasb
+ lea rax, [rdi - 1]
+ cmovnz rax, rcx ; set rax to 0 if not found
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S
new file mode 100644
index 000000000000..41558f610563
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem.S
+#
+# Abstract:
+#
+# SetMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+#------------------------------------------------------------------------------
+# VOID *
+# EFIAPI
+# InternalMemSetMem (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT8 Value
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ pushq %rdi
+ pushq %rbx
+ pushq %rcx # push Buffer
+ movq %r8, %rax # rax = Value
+ andq $0xff, %rax # rax = lower 8 bits of r8, upper 56 bits are 0
+ movb %al, %ah # ah = al
+ movw %ax, %bx # bx = ax
+ shlq $0x10, %rax # rax = ax << 16
+ movw %bx, %ax # ax = bx
+ movq %rax, %rbx # ebx = eax
+ shlq $0x20, %rax # rax = rax << 32
+ orq %rbx, %rax # eax = ebx
+ movq %rcx, %rdi # rdi = Buffer
+ movq %rdx, %rcx # rcx = Count
+ shrq $3, %rcx # rcx = rcx / 8
+ cld
+ rep stosq
+ movq %rdx, %rcx # rcx = rdx
+ andq $7, %rcx # rcx = rcx & 7
+ rep stosb
+ popq %rax # rax = Buffer
+ popq %rbx
+ popq %rdi
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm
new file mode 100644
index 000000000000..ffe242da6657
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem.Asm
+;
+; Abstract:
+;
+; SetMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT8 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem PROC USES rdi rbx
+ push rcx ; push Buffer
+ mov rax, r8 ; rax = Value
+ and rax, 0ffh ; rax = lower 8 bits of r8, upper 56 bits are 0
+ mov ah, al ; ah = al
+ mov bx, ax ; bx = ax
+ shl rax, 10h ; rax = ax << 16
+ mov ax, bx ; ax = bx
+ mov rbx, rax ; ebx = eax
+ shl rax, 20h ; rax = rax << 32
+ or rax, rbx ; eax = ebx
+ mov rdi, rcx ; rdi = Buffer
+ mov rcx, rdx ; rcx = Count
+ shr rcx, 3 ; rcx = rcx / 8
+ cld
+ rep stosq
+ mov rcx, rdx ; rcx = rdx
+ and rcx, 7 ; rcx = rcx & 7
+ rep stosb
+ pop rax ; rax = Buffer
+ ret
+InternalMemSetMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.nasm
new file mode 100644
index 000000000000..48d69ab9ab52
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.nasm
@@ -0,0 +1,62 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2008, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem.Asm
+;
+; Abstract:
+;
+; SetMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT8 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ push rdi
+ push rbx
+ push rcx ; push Buffer
+ mov rax, r8 ; rax = Value
+ and rax, 0xff ; rax = lower 8 bits of r8, upper 56 bits are 0
+ mov ah, al ; ah = al
+ mov bx, ax ; bx = ax
+ shl rax, 0x10 ; rax = ax << 16
+ mov ax, bx ; ax = bx
+ mov rbx, rax ; ebx = eax
+ shl rax, 0x20 ; rax = rax << 32
+ or rax, rbx ; eax = ebx
+ mov rdi, rcx ; rdi = Buffer
+ mov rcx, rdx ; rcx = Count
+ shr rcx, 3 ; rcx = rcx / 8
+ cld
+ rep stosq
+ mov rcx, rdx ; rcx = rdx
+ and rcx, 7 ; rcx = rcx & 7
+ rep stosb
+ pop rax ; rax = Buffer
+ pop rbx
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S
new file mode 100644
index 000000000000..d6f570f29207
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S
@@ -0,0 +1,47 @@
+#
+# ConvertAsm.py: Automatically generated from SetMem16.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem16.S
+#
+# Abstract:
+#
+# SetMem16 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID *
+# EFIAPI
+# InternalMemSetMem16 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT16 Value
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ xchg %rdx, %rcx
+ rep stosw
+ movq %rdx, %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm
new file mode 100644
index 000000000000..c09619f6da3d
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem16.Asm
+;
+; Abstract:
+;
+; SetMem16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem16 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT16 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem16 PROC USES rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosw
+ pop rax
+ ret
+InternalMemSetMem16 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.nasm
new file mode 100644
index 000000000000..d9a3d358cd0d
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.nasm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem16.Asm
+;
+; Abstract:
+;
+; SetMem16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem16 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT16 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ push rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosw
+ pop rax
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S
new file mode 100644
index 000000000000..7dba067a5065
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S
@@ -0,0 +1,47 @@
+#
+# ConvertAsm.py: Automatically generated from SetMem32.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem32.S
+#
+# Abstract:
+#
+# SetMem32 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID *
+# EFIAPI
+# InternalMemSetMem32 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT32 Value
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ xchgq %rdx, %rcx
+ rep stosl
+ movq %rdx, %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm
new file mode 100644
index 000000000000..99b6087b0ed1
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem32.Asm
+;
+; Abstract:
+;
+; SetMem32 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem32 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+InternalMemSetMem32 PROC USES rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosd
+ pop rax
+ ret
+InternalMemSetMem32 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.nasm
new file mode 100644
index 000000000000..6f9770438b35
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.nasm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem32.Asm
+;
+; Abstract:
+;
+; SetMem32 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; EFIAPI
+; InternalMemSetMem32 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT32 Value
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ push rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosd
+ pop rax
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S
new file mode 100644
index 000000000000..a94f0388d00f
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S
@@ -0,0 +1,46 @@
+#
+# ConvertAsm.py: Automatically generated from SetMem64.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# SetMem64.S
+#
+# Abstract:
+#
+# SetMem64 function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemSetMem64 (
+# IN VOID *Buffer,
+# IN UINTN Count,
+# IN UINT64 Value
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ pushq %rdi
+ movq %rcx, %rdi
+ movq %r8, %rax
+ xchg %rdx, %rcx
+ rep stosq
+ movq %rdx, %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm
new file mode 100644
index 000000000000..1e33f053305b
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem64.Asm
+;
+; Abstract:
+;
+; SetMem64 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem64 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT64 Value
+; )
+;------------------------------------------------------------------------------
+InternalMemSetMem64 PROC USES rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosq
+ pop rax
+ ret
+InternalMemSetMem64 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.nasm
new file mode 100644
index 000000000000..9b0b8acaef45
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.nasm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; SetMem64.Asm
+;
+; Abstract:
+;
+; SetMem64 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemSetMem64 (
+; IN VOID *Buffer,
+; IN UINTN Count,
+; IN UINT64 Value
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ push rdi
+ push rcx
+ mov rdi, rcx
+ mov rax, r8
+ xchg rcx, rdx
+ rep stosq
+ pop rax
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S
new file mode 100644
index 000000000000..38b867897507
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S
@@ -0,0 +1,51 @@
+#
+# ConvertAsm.py: Automatically generated from ZeroMem.asm
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation. 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.
+#
+# Module Name:
+#
+# ZeroMem.S
+#
+# Abstract:
+#
+# ZeroMem function
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID *
+# InternalMemZeroMem (
+# IN VOID *Buffer,
+# IN UINTN Count
+# );
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ pushq %rdi
+ pushq %rcx
+ xorq %rax, %rax
+ movq %rcx, %rdi
+ movq %rdx, %rcx
+ shrq $3, %rcx
+ andq $7, %rdx
+ cld
+ rep stosq
+ movq %rdx, %rcx
+ rep stosb
+ popq %rax
+ popq %rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm
new file mode 100644
index 000000000000..80ddd1d53e28
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ZeroMem.Asm
+;
+; Abstract:
+;
+; ZeroMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemZeroMem (
+; IN VOID *Buffer,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+InternalMemZeroMem PROC USES rdi
+ push rcx ; push Buffer
+ xor rax, rax ; rax = 0
+ mov rdi, rcx ; rdi = Buffer
+ mov rcx, rdx ; rcx = Count
+ shr rcx, 3 ; rcx = rcx / 8
+ and rdx, 7 ; rdx = rdx & 7
+ cld
+ rep stosq
+ mov rcx, rdx ; rcx = rdx
+ rep stosb
+ pop rax ; rax = Buffer
+ ret
+InternalMemZeroMem ENDP
+
+ END
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.nasm b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.nasm
new file mode 100644
index 000000000000..12c1da99868e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.nasm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. 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.
+;
+; Module Name:
+;
+; ZeroMem.Asm
+;
+; Abstract:
+;
+; ZeroMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID *
+; InternalMemZeroMem (
+; IN VOID *Buffer,
+; IN UINTN Count
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ push rdi
+ push rcx ; push Buffer
+ xor rax, rax ; rax = 0
+ mov rdi, rcx ; rdi = Buffer
+ mov rcx, rdx ; rcx = Count
+ shr rcx, 3 ; rcx = rcx / 8
+ and rdx, 7 ; rdx = rdx & 7
+ cld
+ rep stosq
+ mov rcx, rdx ; rcx = rdx
+ rep stosb
+ pop rax ; rax = Buffer
+ pop rdi
+ ret
+
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c
new file mode 100644
index 000000000000..067c7af84819
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c
@@ -0,0 +1,56 @@
+/** @file
+ ZeroMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with zeros, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with zeros, and returns Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill with zeros.
+ @param Length The number of bytes in Buffer to fill with zeros.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ return InternalMemZeroMem (Buffer, Length);
+}