// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_MEMORY_H_
#define OPENTITAN_SW_DEVICE_LIB_BASE_MEMORY_H_

#include <stdalign.h>
#include <stddef.h>
#include <stdint.h>

/**
 * Load a word from memory directly, bypassing aliasing rules.
 *
 * ISO C forbids, in general, casting a pointer to non-character types and
 * reading them, though it is frequently necessary to read exactly one word out
 * of a `void *`. This function performs that action in a manner which is
 * well-defined.
 *
 * Of course, `ptr` must point to word-aligned memory that is at least one word
 * wide. To do otherwise is Undefined Behavior. It goes eithout saying that the
 * memory this function intents to read must be initialized.
 *
 * This function has reordering properties as weak as a normal, non-atomic,
 * non-volatile load.
 *
 * @param ptr a word-aligned pointer pointed to at least four bytes of memory.
 * @return the word `ptr` points to.
 */
inline uint32_t read_32(const void *ptr) {
  // Both GCC and Clang optimize the code below into a single word-load on most
  // platforms. It is necessary and sufficient to indicate to the compiler that
  // the pointer points to four bytes of four-byte-aligned memory.
  //
  // Failing to get that particular codegen in either GCC or Clang with -O2 or
  // -Os set shall be considred a bug in this function. The same applies to
  // `write32()`.
  ptr = __builtin_assume_aligned(ptr, alignof(uint32_t));
  uint32_t val;
  __builtin_memcpy(&val, ptr, sizeof(uint32_t));
  return val;
}

/**
 * Store a word to memory directly, bypassing aliasing rules.
 *
 * ISO C forbids, in general, casting a pointer to non-character types and
 * reading them, though it is frequently necessary to write exactly one word to
 * a `void *`. This function performs that action in a manner which is
 * well-defined.
 *
 * Of course, `ptr` must point to word-aligned memory that is at least one word
 * wide. To do otherwise is Undefined Behavior.
 *
 * This function has reordering properties as weak as a normal, non-atomic,
 * non-volatile load.
 *
 * @param value the value to store.
 * @param ptr a word-aligned pointer pointed to at least four bytes of memory.
 */
inline void write_32(uint32_t value, void *ptr) {
  // Both GCC and Clang optimize the code below into a single word-store on most
  // platforms. See the comment in `read_32()` for more implementation-private
  // information.
  ptr = __builtin_assume_aligned(ptr, alignof(uint32_t));
  __builtin_memcpy(ptr, &value, sizeof(uint32_t));
}

/**
 * Copy memory between non-overlapping regions.
 *
 * This function conforms to the semantics defined in ISO C11 S7.23.2.1.
 *
 * @param dest the region to copy to.
 * @param src the region to copy from.
 * @param len the number of bytes to copy.
 * @return the value of `dest`.
 */
void *memcpy(void *restrict dest, const void *restrict src, size_t len);

/**
 * Set a region of memory to a particular byte value.
 *
 * This function conforms to the semantics defined in ISO C11 S7.23.6.1.
 *
 * @param dest the region to write to.
 * @param value the value, converted to a byte, to write to each byte cell.
 * @param len the number of bytes to write.
 * @return the value of `dest`.
 */
void *memset(void *dest, int value, size_t len);

/**
 * Compare two (potentially overlapping) regions of memory for byte-wise
 * lexicographic order.
 *
 * This function conforms to the semantics defined in ISO C11 S7.24.4.1.
 *
 * @param lhs the left-hand-side of the comparison.
 * @param rhs the right-hand-side of the comparison.
 * @param len the length of both regions, in bytes.
 * @return a zero, positive, or negative integer, corresponding to the
 * contingencies of `lhs == rhs`, `lhs > rhs`, and `lhs < rhs` (as buffers, not
 * pointers), respectively.
 */
int memcmp(const void *lhs, const void *rhs, size_t len);

/**
 * Search a region of memory for the first occurence of a particular byte value.
 *
 * This function conforms to the semantics defined in ISO C11 S7.24.5.1.
 *
 * Since libbase does not provide a `strlen()` function, this function can be
 * used as an approximation: `memchr(my_str, 0, SIZE_MAX) - my_str`.
 *
 * @param ptr the region to search.
 * @param value the value, converted to a byte, to search for.
 * @param len the length of the region, in bytes.
 * @return a pointer to the found value, or NULL.
 */
void *memchr(const void *ptr, int value, size_t len);

/**
 * Search a region of memory for the last occurence of a particular byte value.
 *
 * This function is not specified by C11, but is named for a well-known glibc
 * extension.
 *
 * @param ptr the region to search.
 * @param value the value, converted to a byte, to search for.
 * @param len the length of the region, in bytes.
 * @return a pointer to the found value, or NULL.
 */
void *memrchr(const void *ptr, int value, size_t len);

#endif  // OPENTITAN_SW_DEVICE_LIB_BASE_MEMORY_H_
