blob: d72bf568df45906bbdb64043d1de6be1884c1441 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/macros.h"
// The symbols below are all provided by the host libc. To avoid linker clashes,
// they are all marked as `OT_WEAK`.
OT_WEAK
void *memcpy(void *restrict dest, const void *restrict src, size_t len) {
uint8_t *dest8 = (uint8_t *)dest;
uint8_t *src8 = (uint8_t *)src;
for (size_t i = 0; i < len; ++i) {
dest8[i] = src8[i];
}
return dest;
}
OT_WEAK
void *memset(void *dest, int value, size_t len) {
uint8_t *dest8 = (uint8_t *)dest;
uint8_t value8 = (uint8_t)value;
for (size_t i = 0; i < len; ++i) {
dest8[i] = value8;
}
return dest;
}
enum {
kMemCmpEq = 0,
kMemCmpLt = -42,
kMemCmpGt = 42,
};
OT_WEAK
int memcmp(const void *lhs, const void *rhs, size_t len) {
const uint8_t *lhs8 = (uint8_t *)lhs;
const uint8_t *rhs8 = (uint8_t *)rhs;
for (size_t i = 0; i < len; ++i) {
if (lhs8[i] < rhs8[i]) {
return kMemCmpLt;
} else if (lhs8[i] > rhs8[i]) {
return kMemCmpGt;
}
}
return kMemCmpEq;
}
OT_WEAK
int memrcmp(const void *lhs, const void *rhs, size_t len) {
const uint8_t *lhs8 = (uint8_t *)lhs;
const uint8_t *rhs8 = (uint8_t *)rhs;
size_t j;
for (size_t i = 0; i < len; ++i) {
j = len - 1 - i;
if (lhs8[j] < rhs8[j]) {
return kMemCmpLt;
} else if (lhs8[j] > rhs8[j]) {
return kMemCmpGt;
}
}
return kMemCmpEq;
}
OT_WEAK
void *memchr(const void *ptr, int value, size_t len) {
uint8_t *ptr8 = (uint8_t *)ptr;
uint8_t value8 = (uint8_t)value;
for (size_t i = 0; i < len; ++i) {
if (ptr8[i] == value8) {
return ptr8 + i;
}
}
return NULL;
}
OT_WEAK
void *memrchr(const void *ptr, int value, size_t len) {
uint8_t *ptr8 = (uint8_t *)ptr;
uint8_t value8 = (uint8_t)value;
for (size_t i = 0; i < len; ++i) {
size_t idx = len - i - 1;
if (ptr8[idx] == value8) {
return ptr8 + idx;
}
}
return NULL;
}
// `extern` declarations to give the inline functions in the corresponding
// header a link location.
extern ptrdiff_t misalignment32_of(uintptr_t);
extern uint32_t read_32(const void *);
extern void write_32(uint32_t, void *);
extern uint64_t read_64(const void *);
extern void write_64(uint64_t, void *);