Add memory.op.copy
This commit is contained in:
parent
5d145f524c
commit
40e43c1465
@ -30,9 +30,6 @@ before_script:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- dub test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC
|
- dub test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC
|
||||||
- if [ "$UNITTEST" = "unittest-cov" -a "$ARCH" = "x86_64" -a "$TRAVIS_OS_NAME" = "linux" ]; then
|
|
||||||
dub fetch dscanner && dub run dscanner -- -Isource --styleCheck;
|
|
||||||
fi
|
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- test "$UNITTEST" = "unittest-cov" && bash <(curl -s https://codecov.io/bash)
|
- test "$UNITTEST" = "unittest-cov" && bash <(curl -s https://codecov.io/bash)
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Implementions of functions found in $(D_PSYMBOL tanya.memory.op) for X86-64.
|
||||||
|
*
|
||||||
* Copyright: Eugene Wissner 2017.
|
* Copyright: Eugene Wissner 2017.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
@ -12,17 +14,18 @@ module tanya.memory.arch.x86_64;
|
|||||||
|
|
||||||
version (D_InlineAsm_X86_64):
|
version (D_InlineAsm_X86_64):
|
||||||
|
|
||||||
package void copy(const void[] src, void[] dst)
|
pragma(inline, true)
|
||||||
|
package (tanya.memory) void copy(const void[] source, void[] target)
|
||||||
pure nothrow @system @nogc
|
pure nothrow @system @nogc
|
||||||
{
|
{
|
||||||
asm pure nothrow @nogc
|
asm pure nothrow @nogc
|
||||||
{
|
{
|
||||||
naked;
|
naked;
|
||||||
|
|
||||||
// RDX - src length.
|
// RDX - source length.
|
||||||
// RCX - src data.
|
// RCX - source data.
|
||||||
// RDI - dst length.
|
// RDI - target length.
|
||||||
// RSI - dst data.
|
// RSI - target data.
|
||||||
|
|
||||||
// RDI and RSI should be preserved.
|
// RDI and RSI should be preserved.
|
||||||
mov RAX, RDI;
|
mov RAX, RDI;
|
||||||
|
115
source/tanya/memory/op.d
Normal file
115
source/tanya/memory/op.d
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of operations on memory blocks.
|
||||||
|
*
|
||||||
|
* Copyright: Eugene Wissner 2017.
|
||||||
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
|
* Mozilla Public License, v. 2.0).
|
||||||
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
*/
|
||||||
|
module tanya.memory.op;
|
||||||
|
|
||||||
|
version (D_InlineAsm_X86_64)
|
||||||
|
{
|
||||||
|
static import tanya.memory.arch.x86_64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies $(D_PARAM source) into $(D_PARAM target).
|
||||||
|
*
|
||||||
|
* $(D_PARAM source) and $(D_PARAM target) shall not overlap so that an element
|
||||||
|
* of $(D_PARAM target) points to an element of $(D_PARAM source).
|
||||||
|
*
|
||||||
|
* $(D_PARAM target) shall have enough space $(D_INLINECODE source.length)
|
||||||
|
* elements.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* source = Memory to copy from.
|
||||||
|
* target = Destination memory.
|
||||||
|
*
|
||||||
|
* Precondition: $(D_INLINECODE source.length <= target.length).
|
||||||
|
*/
|
||||||
|
void copy(const void[] source, void[] target) pure nothrow @trusted @nogc
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(source.length <= target.length);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
version (D_InlineAsm_X86_64)
|
||||||
|
{
|
||||||
|
tanya.memory.arch.x86_64.copy(source, target);
|
||||||
|
}
|
||||||
|
else // Naive implementation.
|
||||||
|
{
|
||||||
|
auto source1 = cast(const(ubyte)*) source;
|
||||||
|
auto target1 = cast(ubyte*) target;
|
||||||
|
auto count = source.length;
|
||||||
|
enum alignmentMask = size_t.sizeof - 1;
|
||||||
|
|
||||||
|
// Check if the pointers are aligned or at least can be aligned
|
||||||
|
// properly.
|
||||||
|
ushort naligned = (cast(size_t) source.ptr) & alignmentMask;
|
||||||
|
if (naligned == ((cast(size_t) target.ptr) & alignmentMask))
|
||||||
|
{
|
||||||
|
// Align the pointers if possible.
|
||||||
|
if (naligned != 0)
|
||||||
|
{
|
||||||
|
count -= naligned;
|
||||||
|
while (naligned--)
|
||||||
|
{
|
||||||
|
*target1++ = *source1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Copy size_t.sizeof bytes at once.
|
||||||
|
auto longSource = cast(const(size_t)*) source1;
|
||||||
|
auto longTarget = cast(size_t*) target1;
|
||||||
|
for (; count >= size_t.sizeof; count -= size_t.sizeof)
|
||||||
|
{
|
||||||
|
*longTarget++ = *longSource++;
|
||||||
|
}
|
||||||
|
// Adjust the original pointers.
|
||||||
|
source1 = cast(const(ubyte)*) longSource;
|
||||||
|
target1 = cast(ubyte*) longTarget;
|
||||||
|
}
|
||||||
|
// Copy the remaining bytes by one.
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
*target1++ = *source1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ubyte[9] source = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
ubyte[9] target;
|
||||||
|
source.copy(target);
|
||||||
|
assert(source == target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private pure nothrow @safe @nogc unittest
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ubyte[0] source, target;
|
||||||
|
source.copy(target);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ubyte[1] source = [1];
|
||||||
|
ubyte[1] target;
|
||||||
|
source.copy(target);
|
||||||
|
assert(target[0] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ubyte[8] source = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||||
|
ubyte[8] target;
|
||||||
|
source.copy(target);
|
||||||
|
assert(source == target);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user