diff --git a/src/SConscript b/src/SConscript index c6701cc..cdf8a01 100644 --- a/src/SConscript +++ b/src/SConscript @@ -20,7 +20,8 @@ files = [ 'cxa.cc', 'isr.S', - 'kstd/CString.cc' + 'kstd/CString.cc', + 'kstd/Memory.cc', ] toolchain_bin = Dir(os.environ['POLKA_TOOLCHAIN']).Dir('bin') diff --git a/src/kstd/Memory.cc b/src/kstd/Memory.cc index 65806b0..3503875 100644 --- a/src/kstd/Memory.cc +++ b/src/kstd/Memory.cc @@ -6,34 +6,101 @@ * Basic, low-level memory utilities. */ +#include "Memory.hh" + namespace kstd { namespace Memory { -void * -copy(void *to, +void* +copy(void* to, + const void* from, + usize length) +{ + if (to == from) { + return to; + } + + auto toBytes = reinterpret_cast(to); + auto fromBytes = reinterpret_cast(from); + auto toBytesEnd = toBytes + length; + auto fromBytesEnd = fromBytes + length; + + if ((toBytes <= fromBytes && toBytesEnd > fromBytes) || (fromBytes <= toBytes && fromBytesEnd > toBytes)) { + // Memory regions cannot overlap. Do nothing...silently. >_< + return to; + } + + // TODO: Copy. + + return to; +} + + +void* +move(void* to, const void *from, - size_t length) -{ } + usize length) +{ + if (to == from) { + return to; + } + + auto toBytes = reinterpret_cast(to); + auto fromBytes = reinterpret_cast(from); + auto toBytesEnd = toBytes + length; + auto fromBytesEnd = fromBytes + length; + + if ((toBytes <= fromBytes && toBytesEnd > fromBytes) || (fromBytes <= toBytes && fromBytesEnd > toBytes)) { + // We have to work backwards here to avoid copying over stuff that we still need to copy. + } else { + // Straight forward move. + } + + return to; +} -void * -move(void *to, - const void *from, - size_t length) -{ } +void* +zero(void* ptr, + usize length) +{ + auto p = reinterpret_cast(ptr); + + while (length > 8) { + *reinterpret_cast(p) = u64(0); + p += 8; + length -= 8; + } + while (length > 4) { + *reinterpret_cast(p) = u32(0); + p += 4; + length -= 4; + } + while (length > 2) { + *reinterpret_cast(p) = u16(0); + p += 2; + length -= 2; + } + while (length > 0) { + *p++ = u8(0); + length--; + } + + return ptr; +} -void * -zero(void *s, - size_t length) -{ } +void* +set(void* ptr, + u8 value, + usize length) +{ + auto bytes = reinterpret_cast(ptr); + for (usize i = 0; i < length; i++) { + bytes[i] = value; + } + return ptr; +} - -void * -set(void *s, - uint8_t value, - size_t length) -{ } - } /* namespace Memory */ } /* namespace kstd */ diff --git a/src/kstd/Memory.hh b/src/kstd/Memory.hh index 4aa4878..0399354 100644 --- a/src/kstd/Memory.hh +++ b/src/kstd/Memory.hh @@ -9,21 +9,23 @@ #ifndef __MEMORY_HH__ #define __MEMORY_HH__ +#include "Types.hh" + namespace kstd { namespace Memory { /** Copy `length` bytes from `from` to `to`. */ -void *copy(void *to, const void *from, size_t length); +void* copy(void* to, const void* from, usize length); /** Move `length` bytes from `from` to `to`. */ -void *move(void *to, const void *from, size_t length); +void* move(void* to, const void* from, usize length); /** Set `length` bytes starting at `s` to zero. */ -void *zero(void *s, size_t length); +void* zero(void* s, usize length); /** Set `length` bytes starting at `s` to `value`. */ -void *set(void *s, uint8_t value, size_t length); - +void* set(void* s, u8 value, usize length); + } /* namespace Memory */ } /* namespace kstd */