1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdint.h>
6#include <string.h>
7
8void* memcpy(void* restrict dest, const void* restrict src, size_t len) {
9    void* dest_end;
10    void* src_end;
11    __asm__ volatile("rep movsb" :
12                     "=D"(dest_end), "=S"(src_end), "=c"(len) :
13                     "0"(dest), "1"(src), "2"(len) :
14                     "memory");
15    return dest;
16}
17
18void* memmove(void* restrict dest, const void* restrict src, size_t len) {
19    if ((uintptr_t)dest < (uintptr_t)src) {
20        void* dest_end;
21        void* src_end;
22        __asm__ volatile("rep movsb" :
23                         "=D"(dest_end), "=S"(src_end), "=c"(len) :
24                         "0"(dest), "1"(src), "2"(len) :
25                         "memory");
26    } else {
27        __asm__ volatile("std\n\t"
28                         "rep movsb\n\t"
29                         "cld" :
30                         "=D"(dest), "=S"(src), "=c"(len) :
31                         "0"((uint8_t*)dest + len - 1),
32                         "1"((uint8_t*)src + len - 1),
33                         "2"(len) :
34                         "memory");
35        dest = (void*)((uint8_t*)dest + 1);
36    }
37    return dest;
38}
39
40void* memset(void* dest, int val, size_t len) {
41    void* dest_end;
42    __asm__ volatile("rep stosb" :
43                     "=D"(dest_end), "=c"(len) :
44                     "0"(dest), "1"(len), "a"((unsigned char)val) :
45                     "memory");
46    return dest;
47}
48
49size_t strlen(const char* s) {
50    size_t len = 0;
51    while (*s++ != '\0') {
52        ++len;
53    }
54    return len;
55}
56