diff options
| author | Warner Losh <imp@FreeBSD.org> | 2017-03-07 20:53:26 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2017-03-07 20:53:26 +0000 |
| commit | 0499b37cea9ca98acfe36368e521ad36b7783f2d (patch) | |
| tree | 7968fdc8d6edf3e051bbd434a466eca88aacf938 /MdePkg/Library/BaseMemoryLibOptDxe | |
Notes
Diffstat (limited to 'MdePkg/Library/BaseMemoryLibOptDxe')
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); +} |
