Skip to content

Instantly share code, notes, and snippets.

@ljmf00
Created August 4, 2022 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ljmf00/14cd73e84521191f88b2bdc010ee1899 to your computer and use it in GitHub Desktop.
Save ljmf00/14cd73e84521191f88b2bdc010ee1899 to your computer and use it in GitHub Desktop.
module setmem;
export void* _d_memset(size_t tsz)(void* dst, void[tsz] val, size_t sz)
{
static if (tsz == 1) return setmem8 (dst, val, sz);
else static if (tsz == 2) return setmem16 (dst, val, sz);
else static if (tsz == 4) return setmem32 (dst, val, sz);
else static if (tsz == 8) return setmem64 (dst, val, sz);
else static if (tsz == 16) return setmem128(dst, val, sz);
else static if (tsz == 32) return setmem256(dst, val, sz);
else static if (tsz == 64) return setmem512(dst, val, sz);
else return setmemx (dst, val, sz);
}
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));
}
}
private T* setmem8(T)(T* dst, T val, size_t sz)
if (T.sizeof == 1)
{
version (LDC)
{
llvm_memset(cast(void*)dst, *cast(ubyte*)&val, sz);
return dst;
}
else
{
import core.stdc.string : memset;
return cast(T*) memset(dst, val, sz);
}
}
private T* setmem16(T)(T* dst, T 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
{
ushort* buf = *cast(ushort**)&dst;
while(sz--) *buf++ = *cast(ushort*)&val;
return dst;
}
}
private T* setmem32(T)(T* dst, T 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
{
uint* buf = *cast(uint**)&dst;
while(sz--) *buf++ = *cast(uint*)&val;
return dst;
}
}
private T* setmem64(T)(T* dst, T val, size_t sz)
{
ulong* buf = *cast(ulong**)&dst;
while(sz--) *buf++ = *cast(ulong*)&val;
return dst;
}
private T* setmem128(T)(T* dst, T val, size_t sz)
{
version(D_SIMD)
{
import core.simd;
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);
T128* buf = *cast(T128**)&dst;
while(sz--) *buf++ = *cast(T128*)&val;
return dst;
}
}
private T* setmem256(T)(T* dst, T val, size_t sz)
{
version(D_SIMD)
{
import core.simd;
ubyte32* buf = *cast(ubyte32**)&dst;
while(sz--) *buf++ = *cast(ubyte32*)&val;
return dst;
}
else
{
align(1) static struct T256 { align(1): long _1; long _2; }
static assert(T256.sizeof == 32);
T256* buf = *cast(T256**)&dst;
while(sz--) *buf++ = *cast(T256*)&val;
return dst;
}
}
private T* setmem512(T)(T* dst, T val, size_t sz)
{
align(1) static struct T512 { align(1): long _1; long _2; long _3; long _4; }
static assert(T512.sizeof == 64);
T512* buf = *cast(T512**)&dst;
while(sz--) *buf++ = *cast(T512*)&val;
return dst;
}
private T* setmemx(T)(T* dst, T val, size_t sz)
{
void *start = dst;
int i;
for (i = 0; i < count; i++)
{
import core.stdc.string : memcpy;
memcpy(dst, &val, T.sizeof);
dst = cast(T*)(cast(ubyte*)dst + T.sizeof);
}
return start;
}
///
unittest
{
ubyte[10] buf;
setmem(buf.ptr, 123, 10);
assert(buf == [123, 123, 123, 123, 123, 123, 123, 123, 123, 123]);
}
///
unittest
{
ushort[10] buf;
setmem(buf.ptr, 1234, 10);
assert(buf == [1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234]);
}
///
unittest
{
uint[10] buf;
setmem(buf.ptr, 1234, 10);
assert(buf == [1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234]);
}
///
unittest
{
ulong[10] buf;
setmem(buf.ptr, 1234, 10);
assert(buf == [1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234]);
}
///
unittest
{
long[10] buf;
setmem(buf.ptr, 1234, 10);
assert(buf == [1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234]);
}
///
unittest
{
struct S { long l; }
S[10] buf;
setmem(buf.ptr, S(1234), 10);
assert(buf ==
[S(1234),S(1234),S(1234),S(1234),S(1234),S(1234),S(1234),S(1234),S(1234),S(1234)]);
}
///
unittest
{
struct S { long lo; long hi; }
S[10] buf;
setmem(buf.ptr, S(1234, 4321), 10);
assert(buf == [S(1234, 4321),S(1234, 4321),S(1234, 4321),S(1234,
4321),S(1234, 4321),S(1234, 4321),S(1234, 4321),S(1234,
4321),S(1234, 4321),S(1234, 4321)]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment