Skip to content

Instantly share code, notes, and snippets.

@iK4tsu
Last active August 6, 2022 09:58
Show Gist options
  • Save iK4tsu/a2e4f20ba2259deb09a9e18b186783c9 to your computer and use it in GitHub Desktop.
Save iK4tsu/a2e4f20ba2259deb09a9e18b186783c9 to your computer and use it in GitHub Desktop.
module setmem;
version(unittest)
{
import std.range : repeat;
import std.algorithm : equal;
}
version (LDC)
{
nothrow @nogc
{
pragma(LDC_intrinsic, "llvm.memset.p0i8.i#")
private void llvm_memset(T)(void* dst, ubyte val, T len, bool volatile_ = false)
if (__traits(isIntegral, T));
}
}
export void* _d_memset(size_t tsz: 1)(return scope void* dst, scope void* val, size_t sz)
{
version (LDC)
{
llvm_memset(dst, *cast(ubyte*) val, sz);
return dst;
}
else
{
import core.stdc.string : memset;
return memset(dst, *(cast(int*) val), sz);
}
}
///
unittest
{
ubyte[10] buf;
ubyte val = 123;
_d_memset!1(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 2)(return scope void* dst, scope void* val, size_t sz)
{
version (D_InlineAsm_X86)
{
asm @safe pure nothrow @nogc
{
mov EDI,dst ;
mov EAX,val ;
mov ECX,sz ;
mov EDX,EDI ;
rep ;
stosw ;
mov EAX,EDX ;
}
}
else
{
scope ushort* buf = cast(ushort*) dst;
while(sz--) *buf++ = *cast(ushort*) val;
return dst;
}
}
///
unittest
{
ushort[10] buf;
ushort val = 1234;
_d_memset!2(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 4)(return scope void* dst, scope void* val, size_t sz)
{
version (D_InlineAsm_X86)
{
asm @safe pure nothrow @nogc
{
mov EDI,dst ;
mov EAX,val ;
mov ECX,sz ;
mov EDX,EDI ;
rep ;
stosd ;
mov EAX,EDX ;
}
}
else
{
scope uint* buf = cast(uint*) dst;
while(sz--) *buf++ = *cast(uint*) val;
return dst;
}
}
///
unittest
{
uint[10] buf;
uint val = 1234;
_d_memset!4(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 8)(return scope void* dst, scope void* val, size_t sz)
{
scope ulong* buf = cast(ulong*) dst;
while(sz--) *buf++ = *cast(ulong*) val;
return dst;
}
///
unittest
{
ulong[10] buf;
ulong val = 1234;
_d_memset!8(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
///
unittest
{
long[10] buf;
long val = 1234;
_d_memset!8(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
///
unittest
{
struct S { long l; }
S[10] buf;
S val = { l: 1234 };
_d_memset!8(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 16)(return scope void* dst, scope void* val, size_t sz)
{
version(D_SIMD)
{
import core.simd;
scope ubyte16* buf = cast(ubyte16*) dst;
while(sz--) *buf++ = *cast(ubyte16*) val;
return dst;
}
else
{
align(1) static struct T128 { align(1): long _1; long _2; }
static assert(T128.sizeof == 16);
scope T128* buf = cast(T128*) dst;
while(sz--) *buf++ = *cast(T128*) val;
return dst;
}
}
///
unittest
{
struct S { long lo; long hi; }
S[10] buf;
S val = { lo: 1234, hi: 4321 };
_d_memset!16(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 32)(return scope void* dst, scope void* val, size_t sz)
{
version(D_SIMD)
{
import core.simd;
static if (is(ubyte32))
{
scope ubyte32* buf = cast(ubyte32*) dst;
while(sz--) *buf++ = *cast(ubyte32*) val;
return dst;
}
}
align(1) static struct T256 { align(1): long _1; long _2; long _3; long _4; }
static assert(T256.sizeof == 32);
scope T256* buf = cast(T256*) dst;
while(sz--) *buf++ = *cast(T256*) val;
return dst;
}
///
unittest
{
struct S { long l1; long l2; long l3; long l4; }
S[10] buf;
S val = { l1: 1, l2: 2, l3: 3, l4: 4 };
_d_memset!32(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz: 64)(return scope void* dst, scope void* val, size_t sz)
{
align(1) static struct T512 { align(1): long _1; long _2; long _3; long _4; long _5; long _6; long _7; long _8; }
static assert(T512.sizeof == 64);
scope T512* buf = cast(T512*) dst;
while(sz--) *buf++ = *cast(T512*) val;
return dst;
}
///
unittest
{
struct S { long l1; long l2; long l3; long l4; long l5; long l6; long l7; long l8; }
S[10] buf;
S val = { l1: 1, l2: 2, l3: 3, l4: 4, l5: 5, l6: 6, l7: 7, l8: 8 };
_d_memset!64(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
export void* _d_memset(size_t tsz)(return scope void* dst, scope void* val, size_t sz)
{
void* start = dst;
for (int i; i < sz; i++)
{
import core.stdc.string : memcpy;
memcpy(dst, val, tsz);
dst = cast(void *)(cast(char *) dst + tsz);
}
return start;
}
///
unittest
{
struct S { long l1; long l2; long l3; long l4; long l5; long l6; long l7; long l8; long l9; }
S[10] buf;
S val = { l1: 1, l2: 2, l3: 3, l4: 4, l5: 5, l6: 6, l7: 7, l8: 8, l9: 9 };
_d_memset!72(buf.ptr, &val, 10);
assert(buf[].equal(val.repeat(10)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment