// Copyright 2018 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include void* memcpy(void* restrict dest, const void* restrict src, size_t len) { void* dest_end; void* src_end; __asm__ volatile("rep movsb" : "=D"(dest_end), "=S"(src_end), "=c"(len) : "0"(dest), "1"(src), "2"(len) : "memory"); return dest; } void* memmove(void* restrict dest, const void* restrict src, size_t len) { if ((uintptr_t)dest < (uintptr_t)src) { void* dest_end; void* src_end; __asm__ volatile("rep movsb" : "=D"(dest_end), "=S"(src_end), "=c"(len) : "0"(dest), "1"(src), "2"(len) : "memory"); } else { __asm__ volatile("std\n\t" "rep movsb\n\t" "cld" : "=D"(dest), "=S"(src), "=c"(len) : "0"((uint8_t*)dest + len - 1), "1"((uint8_t*)src + len - 1), "2"(len) : "memory"); dest = (void*)((uint8_t*)dest + 1); } return dest; } void* memset(void* dest, int val, size_t len) { void* dest_end; __asm__ volatile("rep stosb" : "=D"(dest_end), "=c"(len) : "0"(dest), "1"(len), "a"((unsigned char)val) : "memory"); return dest; } size_t strlen(const char* s) { size_t len = 0; while (*s++ != '\0') { ++len; } return len; }