2018-12-25 19:09:58 +01:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// GNU GPL OS/K //
|
|
|
|
// //
|
|
|
|
// Authors: spectral` //
|
|
|
|
// NeoX //
|
|
|
|
// //
|
|
|
|
// Desc: mem*() functions //
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-01-01 13:09:57 +01:00
|
|
|
#include <kaleid.h>
|
2019-01-01 20:46:06 +01:00
|
|
|
#include <kallims.h>
|
2018-12-31 10:49:08 +01:00
|
|
|
|
2018-12-31 15:08:56 +01:00
|
|
|
//------------------------------------------//
|
|
|
|
// memset() family //
|
|
|
|
//------------------------------------------//
|
2018-12-31 10:49:08 +01:00
|
|
|
|
2018-12-28 18:52:55 +01:00
|
|
|
//
|
|
|
|
// Set "bytes"-many bytes starting from ptr to val
|
|
|
|
//
|
2019-01-02 14:51:40 +01:00
|
|
|
void *memsetb(void *ptr, int val, size_t bytes)
|
2018-12-28 18:52:55 +01:00
|
|
|
{
|
2018-12-28 20:49:43 +01:00
|
|
|
uchar *uptr = (uchar *)ptr;
|
2018-12-31 10:49:08 +01:00
|
|
|
|
|
|
|
// deal with bytes before start of the first aligned qword
|
2018-12-31 15:08:56 +01:00
|
|
|
while (((ulong)uptr % QWORD_ALIGN) > 0 && bytes--) {
|
2018-12-31 10:49:08 +01:00
|
|
|
*uptr++ = (uchar)val;
|
|
|
|
}
|
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
// we're qword-aligned now
|
|
|
|
if (bytes > QWORD_SIZE) {
|
2018-12-31 15:08:56 +01:00
|
|
|
const ulong uval = ((ulong)val << 56) | ((ulong)val << 48)
|
|
|
|
| ((ulong)val << 40) | ((ulong)val << 32)
|
|
|
|
| ((ulong)val << 24) | ((ulong)val << 16)
|
|
|
|
| ((ulong)val << 8) | ((ulong)val);
|
2018-12-31 10:49:08 +01:00
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
ulong *uqptr = (ulong *)ptr;
|
2018-12-31 10:49:08 +01:00
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
// move qword by qword
|
|
|
|
while (bytes > QWORD_SIZE) {
|
|
|
|
*uqptr++ = uval;
|
|
|
|
bytes -= QWORD_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
uptr = (uchar *)(ulong)uqptr;
|
2018-12-31 10:49:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// deal with what's left
|
|
|
|
while (bytes--) {
|
|
|
|
*uptr++ = (uchar)val;
|
|
|
|
}
|
2018-12-28 18:52:55 +01:00
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2018-12-31 15:08:56 +01:00
|
|
|
//
|
|
|
|
// Set "words"-many words starting from ptr to val
|
|
|
|
//
|
|
|
|
void *memsetw(void *ptr, int val, size_t words)
|
|
|
|
{
|
|
|
|
ushort *uptr = (ushort *)ptr;
|
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
// can't we do this an aligned way?
|
2018-12-31 15:08:56 +01:00
|
|
|
if unlikely (((ulong)uptr % WORD_ALIGN) > 0) {
|
|
|
|
// no, we can't align ourselves
|
|
|
|
while (words--) {
|
|
|
|
// do it the hard way
|
|
|
|
*uptr++ = (ushort)val;
|
|
|
|
}
|
|
|
|
// too bad '-'
|
|
|
|
return uptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// deal with words before start of the first aligned qword
|
|
|
|
while (((ulong)uptr % QWORD_ALIGN) > 0 && words--) {
|
|
|
|
*uptr++ = (ushort)val;
|
|
|
|
}
|
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
// we're aligned for sure
|
|
|
|
if (words > QWORDS_TO_WORDS(1)) {
|
2018-12-31 15:08:56 +01:00
|
|
|
const ulong uval = ((ulong)val << 48) | ((ulong)val << 32)
|
|
|
|
| ((ulong)val << 16) | ((ulong)val);
|
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
ulong *uqptr = (ulong *)uptr;
|
|
|
|
|
|
|
|
// move qword by qword
|
|
|
|
while (words > QWORDS_TO_WORDS(1)) {
|
|
|
|
words -= QWORDS_TO_WORDS(1);
|
|
|
|
*uqptr++ = uval;
|
|
|
|
}
|
2018-12-31 15:08:56 +01:00
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
uptr = (ushort *)(ulong)uqptr;
|
2018-12-31 15:08:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// deal with what's left
|
|
|
|
while (words--) {
|
|
|
|
*uptr++ = (ushort)val;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2019-01-01 17:11:30 +01:00
|
|
|
//
|
|
|
|
// Set "dwords"-many dwords starting from ptr to val
|
|
|
|
// XXX unimplemented
|
|
|
|
//
|
|
|
|
void *memsetd(void *ptr, int val, size_t dwords)
|
|
|
|
{
|
|
|
|
(void)val;
|
|
|
|
(void)dwords;
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2018-12-31 15:08:56 +01:00
|
|
|
//
|
|
|
|
// Set "qwords"-many qwords starting from ptr to val
|
|
|
|
//
|
|
|
|
void *memsetq(void *ptr, long val, size_t qwords)
|
|
|
|
{
|
2019-01-02 14:51:40 +01:00
|
|
|
ulong *uptr = (ulong *)ptr;
|
|
|
|
|
|
|
|
while (qwords--) *uptr++ = (ulong)val;
|
|
|
|
|
|
|
|
return ptr;
|
2018-12-31 15:08:56 +01:00
|
|
|
}
|
|
|
|
|
2018-12-28 18:52:55 +01:00
|
|
|
//
|
|
|
|
// Set "bytes"-many bytes starting from ptr to 0
|
2019-01-02 14:51:40 +01:00
|
|
|
//
|
|
|
|
// WARNING
|
|
|
|
// Assume "bytes" is large, for small sizes
|
|
|
|
// use memset(ptr, 0, bytes) directly
|
2018-12-28 18:52:55 +01:00
|
|
|
//
|
|
|
|
void *memzero(void *ptr, size_t bytes)
|
|
|
|
{
|
2019-01-02 14:51:40 +01:00
|
|
|
return memsetb(ptr, 0, bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Copy "bytes"-many bytes of src to dst
|
|
|
|
// Does not deal with overlapping blocks (memmove's job)
|
|
|
|
//
|
|
|
|
void *memcpy(void *dst, const void *src, size_t bytes)
|
|
|
|
{
|
|
|
|
const ulong *usrc = (const ulong *)src;
|
|
|
|
ulong *udst = (ulong *)dst;
|
2018-12-31 15:08:56 +01:00
|
|
|
|
2019-01-02 14:51:40 +01:00
|
|
|
if unlikely (bytes == 0) return dst;
|
|
|
|
|
|
|
|
// can we align them both at once?
|
|
|
|
if unlikely ((ulong)src % WORD_ALIGN == 1
|
|
|
|
&& (ulong)dst % WORD_ALIGN == 1) {
|
|
|
|
const uchar *ubsrc = (const uchar *)usrc;
|
|
|
|
uchar *ubdst = (uchar *)udst;
|
|
|
|
|
|
|
|
*ubdst++ = *ubsrc++;
|
|
|
|
bytes--;
|
|
|
|
|
|
|
|
udst = (ulong *)ubdst;
|
|
|
|
usrc = (ulong *)ubsrc;
|
2018-12-31 15:08:56 +01:00
|
|
|
}
|
2019-01-02 14:51:40 +01:00
|
|
|
|
|
|
|
const ushort *uwsrc = (const ushort *)usrc;
|
|
|
|
ushort *uwdst = (ushort *)udst;
|
|
|
|
|
|
|
|
// align either dst or src for qword access
|
|
|
|
while ((ulong)dst % QWORD_ALIGN > 0
|
|
|
|
&& (ulong)src % QWORD_ALIGN > 0
|
|
|
|
&& bytes > WORD_SIZE) {
|
|
|
|
|
|
|
|
*uwdst++ = *uwsrc++;
|
|
|
|
bytes -= WORD_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
udst = (ulong *)uwdst;
|
|
|
|
usrc = (ulong *)uwsrc;
|
|
|
|
|
|
|
|
// should be most of the job
|
|
|
|
while (bytes > QWORD_SIZE) {
|
|
|
|
*udst++ = *usrc++;
|
|
|
|
bytes -= QWORD_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uchar *ubsrc = (const uchar *)usrc;
|
|
|
|
ushort *ubdst = (ushort *)udst;
|
|
|
|
|
|
|
|
// deal with what's left
|
|
|
|
while (bytes--) {
|
|
|
|
*ubdst ++ = *ubsrc++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dst;
|
2018-12-28 18:52:55 +01:00
|
|
|
}
|
|
|
|
|