Index: boot/arch/arm32/meson.build
===================================================================
--- boot/arch/arm32/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/arm32/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -65,6 +65,6 @@
 	'src/mm.c',
 	'src/putchar.c',
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/division.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/arm32/src/main.c
===================================================================
--- boot/arch/arm32/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/arm32/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -40,5 +40,5 @@
 #include <halt.h>
 #include <printf.h>
-#include <memstr.h>
+#include <mem.h>
 #include <version.h>
 #include <macros.h>
Index: boot/arch/arm64/meson.build
===================================================================
--- boot/arch/arm64/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/arm64/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -48,9 +48,9 @@
 	'src/main.c',
 	'src/relocate.c',
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/efi.c',
 	'../../generic/src/gzip.c',
 	'../../generic/src/inflate.c',
 	'../../generic/src/kernel.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/payload.c',
 	'../../generic/src/printf.c',
Index: boot/arch/arm64/src/main.c
===================================================================
--- boot/arch/arm64/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/arm64/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -46,5 +46,5 @@
 #include <kernel.h>
 #include <macros.h>
-#include <memstr.h>
+#include <mem.h>
 #include <payload.h>
 #include <printf.h>
Index: boot/arch/ia64/meson.build
===================================================================
--- boot/arch/ia64/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/ia64/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -41,8 +41,8 @@
 	'src/pal_asm.S',
 	'src/putchar.c',
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/efi.c',
 	'../../genarch/src/division.c',
 	'../../generic/src/balloc.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/ia64/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,5 +37,5 @@
 #include <halt.h>
 #include <printf.h>
-#include <memstr.h>
+#include <mem.h>
 #include <version.h>
 #include <macros.h>
Index: boot/arch/mips32/meson.build
===================================================================
--- boot/arch/mips32/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/mips32/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -42,7 +42,7 @@
 	'src/main.c',
 	'src/putchar.c',
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/division.c',
 	'../../genarch/src/multiplication.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/mips32/src/main.c
===================================================================
--- boot/arch/mips32/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/mips32/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -33,5 +33,5 @@
 #include <halt.h>
 #include <printf.h>
-#include <memstr.h>
+#include <mem.h>
 #include <version.h>
 #include <macros.h>
Index: boot/arch/ppc32/meson.build
===================================================================
--- boot/arch/ppc32/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/ppc32/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,4 +37,5 @@
 	'src/ofw.c',
 
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/ofw.c',
 	'../../genarch/src/ofw_tree.c',
@@ -42,5 +43,4 @@
 	'../../genarch/src/multiplication.c',
 	'../../generic/src/balloc.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/ppc32/src/main.c
===================================================================
--- boot/arch/ppc32/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/ppc32/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -35,5 +35,5 @@
 #include <halt.h>
 #include <printf.h>
-#include <memstr.h>
+#include <mem.h>
 #include <version.h>
 #include <macros.h>
Index: boot/arch/riscv64/meson.build
===================================================================
--- boot/arch/riscv64/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/riscv64/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,5 +37,6 @@
 	'src/ucb.c',
 	'src/putchar.c',
-	'../../generic/src/memstr.c',
+
+	'../../../common/stdc/mem.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/sparc64/meson.build
===================================================================
--- boot/arch/sparc64/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/sparc64/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,8 +37,8 @@
 	'src/ofw.c',
 
+	'../../../common/stdc/mem.c',
 	'../../genarch/src/ofw.c',
 	'../../genarch/src/ofw_tree.c',
 	'../../generic/src/balloc.c',
-	'../../generic/src/memstr.c',
 	'../../generic/src/printf_core.c',
 	'../../generic/src/vprintf.c',
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/arch/sparc64/src/main.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -36,5 +36,5 @@
 #include <halt.h>
 #include <printf.h>
-#include <memstr.h>
+#include <mem.h>
 #include <version.h>
 #include <macros.h>
Index: boot/genarch/src/ofw_tree.c
===================================================================
--- boot/genarch/src/ofw_tree.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/genarch/src/ofw_tree.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -33,5 +33,5 @@
 #include <str.h>
 #include <balloc.h>
-#include <memstr.h>
+#include <mem.h>
 
 static char path[OFW_TREE_PATH_MAX_LEN + 1];
Index: ot/generic/include/memstr.h
===================================================================
--- boot/generic/include/memstr.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2001-2004 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @file
- */
-
-#ifndef BOOT_MEMSTR_H_
-#define BOOT_MEMSTR_H_
-
-#include <stddef.h>
-
-extern void *memcpy(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)))
-    __attribute__((optimize("-fno-tree-loop-distribute-patterns")));
-extern void *memset(void *, int, size_t)
-    __attribute__((nonnull(1)))
-    __attribute__((optimize("-fno-tree-loop-distribute-patterns")));
-extern void *memmove(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)));
-
-#endif
-
-/** @}
- */
Index: boot/generic/src/gzip.c
===================================================================
--- boot/generic/src/gzip.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/generic/src/gzip.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -32,5 +32,5 @@
 #include <stddef.h>
 #include <errno.h>
-#include <memstr.h>
+#include <mem.h>
 #include <byteorder.h>
 #include <gzip.h>
Index: boot/generic/src/inflate.c
===================================================================
--- boot/generic/src/inflate.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/generic/src/inflate.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -69,5 +69,5 @@
 #include <stdint.h>
 #include <errno.h>
-#include <memstr.h>
+#include <mem.h>
 #include <inflate.h>
 
Index: ot/generic/src/memstr.c
===================================================================
--- boot/generic/src/memstr.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,123 +1,0 @@
-/*
- * Copyright (c) 2010 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <memstr.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/** Move memory block without overlapping.
- *
- * Copy cnt bytes from src address to dst address. The source
- * and destination memory areas cannot overlap.
- *
- * @param dst Destination address to copy to.
- * @param src Source address to copy from.
- * @param cnt Number of bytes to copy.
- *
- * @return Destination address.
- *
- */
-void *memcpy(void *dst, const void *src, size_t cnt)
-{
-	uint8_t *dp = (uint8_t *) dst;
-	const uint8_t *sp = (uint8_t *) src;
-
-	while (cnt-- != 0)
-		*dp++ = *sp++;
-
-	return dst;
-}
-
-/** Fill block of memory.
- *
- * Fill cnt bytes at dst address with the value val.
- *
- * @param dst Destination address to fill.
- * @param val Value to fill.
- * @param cnt Number of bytes to fill.
- *
- * @return Destination address.
- *
- */
-void *memset(void *dst, int val, size_t cnt)
-{
-	uint8_t *dp = (uint8_t *) dst;
-
-	while (cnt-- != 0)
-		*dp++ = val;
-
-	return dst;
-}
-
-/** Move memory block with possible overlapping.
- *
- * Copy cnt bytes from src address to dst address. The source
- * and destination memory areas may overlap.
- *
- * @param dst Destination address to copy to.
- * @param src Source address to copy from.
- * @param cnt Number of bytes to copy.
- *
- * @return Destination address.
- *
- */
-void *memmove(void *dst, const void *src, size_t cnt)
-{
-	/* Nothing to do? */
-	if (src == dst)
-		return dst;
-
-	/* Non-overlapping? */
-	if ((dst >= src + cnt) || (src >= dst + cnt))
-		return memcpy(dst, src, cnt);
-
-	uint8_t *dp;
-	const uint8_t *sp;
-
-	/* Which direction? */
-	if (src > dst) {
-		/* Forwards. */
-		dp = dst;
-		sp = src;
-
-		while (cnt-- != 0)
-			*dp++ = *sp++;
-	} else {
-		/* Backwards. */
-		dp = dst + (cnt - 1);
-		sp = src + (cnt - 1);
-
-		while (cnt-- != 0)
-			*dp-- = *sp--;
-	}
-
-	return dst;
-}
-
-/** @}
- */
Index: boot/generic/src/payload.c
===================================================================
--- boot/generic/src/payload.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/generic/src/payload.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -36,5 +36,5 @@
 #include <gzip.h>
 #include <stdbool.h>
-#include <memstr.h>
+#include <mem.h>
 #include <errno.h>
 #include <str.h>
Index: boot/meson.build
===================================================================
--- boot/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ boot/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -78,4 +78,5 @@
 		'../abi/arch'/BARCH/'include',
 		'../abi/include',
+		'../common/include',
 	)
 
Index: common/include/mem.h
===================================================================
--- common/include/mem.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ common/include/mem.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_MEM_H_
+#define _LIBC_MEM_H_
+
+#include <stddef.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
+
+extern void *memset(void *, int, size_t)
+    __attribute__((nonnull(1)));
+extern void *memcpy(void *, const void *, size_t)
+    __attribute__((nonnull(1, 2)));
+extern void *memmove(void *, const void *, size_t)
+    __attribute__((nonnull(1, 2)));
+extern int memcmp(const void *, const void *, size_t)
+    __attribute__((nonnull(1, 2)));
+extern void *memchr(const void *, int, size_t)
+    __attribute__((nonnull(1)));
+
+__C_DECLS_END;
+
+#if !__STDC_HOSTED__
+#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
+#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+#define memcmp(s1, s2, cnt)    __builtin_memcmp((s1), (s2), (cnt))
+#define memmove(dst, src, cnt)  __builtin_memmove((dst), (src), (cnt))
+#define memchr(s, c, cnt)  __builtin_memchr((s), (c), (cnt))
+#endif
+
+#endif
+
+/** @}
+ */
Index: common/stdc/cc.h
===================================================================
--- common/stdc/cc.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ common/stdc/cc.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * Macros related to used compiler (such as GCC-specific attributes).
+ */
+
+#ifndef _LIBC_CC_H_
+#define _LIBC_CC_H_
+
+#ifndef __clang__
+#define ATTRIBUTE_OPTIMIZE(opt) \
+    __attribute__ ((optimize(opt)))
+#else
+#define ATTRIBUTE_OPTIMIZE(opt)
+#endif
+
+#define ATTRIBUTE_OPTIMIZE_NO_TLDP \
+    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns")
+
+#ifdef CONFIG_LTO
+#define DO_NOT_DISCARD __attribute__ ((used))
+#else
+#define DO_NOT_DISCARD
+#endif
+
+#endif
+
+/** @}
+ */
Index: common/stdc/mem.c
===================================================================
--- common/stdc/mem.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ common/stdc/mem.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2018 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include "../include/mem.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include "cc.h"
+
+#undef memset
+#undef memcpy
+#undef memcmp
+#undef memmove
+#undef memchr
+
+/** Fill memory block with a constant value. */
+DO_NOT_DISCARD
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memset(void *dest, int b, size_t n)
+{
+	char *pb;
+	unsigned long *pw;
+	size_t word_size;
+	size_t n_words;
+
+	unsigned long pattern;
+	size_t i;
+	size_t fill;
+
+	/* Fill initial segment. */
+	word_size = sizeof(unsigned long);
+	fill = word_size - ((uintptr_t) dest & (word_size - 1));
+	if (fill > n)
+		fill = n;
+
+	pb = dest;
+
+	i = fill;
+	while (i-- != 0)
+		*pb++ = b;
+
+	/* Compute remaining size. */
+	n -= fill;
+	if (n == 0)
+		return dest;
+
+	n_words = n / word_size;
+	n = n % word_size;
+	pw = (unsigned long *) pb;
+
+	/* Create word-sized pattern for aligned segment. */
+	pattern = 0;
+	i = word_size;
+	while (i-- != 0)
+		pattern = (pattern << 8) | (uint8_t) b;
+
+	/* Fill aligned segment. */
+	i = n_words;
+	while (i-- != 0)
+		*pw++ = pattern;
+
+	pb = (char *) pw;
+
+	/* Fill final segment. */
+	i = n;
+	while (i-- != 0)
+		*pb++ = b;
+
+	return dest;
+}
+
+struct along {
+	unsigned long n;
+} __attribute__((packed));
+
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    static void *unaligned_memcpy(void *dst, const void *src, size_t n)
+{
+	size_t i, j;
+	struct along *adst = dst;
+	const struct along *asrc = src;
+
+	for (i = 0; i < n / sizeof(unsigned long); i++)
+		adst[i].n = asrc[i].n;
+
+	for (j = 0; j < n % sizeof(unsigned long); j++)
+		((unsigned char *) (((unsigned long *) dst) + i))[j] =
+		    ((unsigned char *) (((unsigned long *) src) + i))[j];
+
+	return (char *) dst;
+}
+
+/** Copy memory block. */
+DO_NOT_DISCARD
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memcpy(void *dst, const void *src, size_t n)
+{
+	size_t i;
+	size_t mod, fill;
+	size_t word_size;
+	size_t n_words;
+
+	const unsigned long *srcw;
+	unsigned long *dstw;
+	const uint8_t *srcb;
+	uint8_t *dstb;
+
+	word_size = sizeof(unsigned long);
+
+	/*
+	 * Are source and destination addresses congruent modulo word_size?
+	 * If not, use unaligned_memcpy().
+	 */
+
+	if (((uintptr_t) dst & (word_size - 1)) !=
+	    ((uintptr_t) src & (word_size - 1)))
+		return unaligned_memcpy(dst, src, n);
+
+	/*
+	 * mod is the address modulo word size. fill is the length of the
+	 * initial buffer segment before the first word boundary.
+	 * If the buffer is very short, use unaligned_memcpy(), too.
+	 */
+
+	mod = (uintptr_t) dst & (word_size - 1);
+	fill = word_size - mod;
+	if (fill > n)
+		fill = n;
+
+	/* Copy the initial segment. */
+
+	srcb = src;
+	dstb = dst;
+
+	i = fill;
+	while (i-- != 0)
+		*dstb++ = *srcb++;
+
+	/* Compute remaining length. */
+
+	n -= fill;
+	if (n == 0)
+		return dst;
+
+	/* Pointers to aligned segment. */
+
+	dstw = (unsigned long *) dstb;
+	srcw = (const unsigned long *) srcb;
+
+	n_words = n / word_size;	/* Number of whole words to copy. */
+	n -= n_words * word_size;	/* Remaining bytes at the end. */
+
+	/* "Fast" copy. */
+	i = n_words;
+	while (i-- != 0)
+		*dstw++ = *srcw++;
+
+	/*
+	 * Copy the rest.
+	 */
+
+	srcb = (const uint8_t *) srcw;
+	dstb = (uint8_t *) dstw;
+
+	i = n;
+	while (i-- != 0)
+		*dstb++ = *srcb++;
+
+	return dst;
+}
+
+/** Move memory block with possible overlapping. */
+DO_NOT_DISCARD
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+void *memmove(void *dst, const void *src, size_t n)
+{
+	const uint8_t *sp;
+	uint8_t *dp;
+
+	/* Nothing to do? */
+	if (src == dst)
+		return dst;
+
+	/* Non-overlapping? */
+	if (dst >= src + n || src >= dst + n) {
+		return memcpy(dst, src, n);
+	}
+
+	/* Which direction? */
+	if (src > dst) {
+		/* Forwards. */
+		sp = src;
+		dp = dst;
+
+		while (n-- != 0)
+			*dp++ = *sp++;
+	} else {
+		/* Backwards. */
+		sp = src + (n - 1);
+		dp = dst + (n - 1);
+
+		while (n-- != 0)
+			*dp-- = *sp--;
+	}
+
+	return dst;
+}
+
+/** Compare two memory areas.
+ *
+ * @param s1  Pointer to the first area to compare.
+ * @param s2  Pointer to the second area to compare.
+ * @param len Size of the areas in bytes.
+ *
+ * @return Zero if areas have the same contents. If they differ,
+ *	   the sign of the result is the same as the sign of the
+ *	   difference of the first pair of different bytes.
+ *
+ */
+DO_NOT_DISCARD
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    int memcmp(const void *s1, const void *s2, size_t len)
+{
+	uint8_t *u1 = (uint8_t *) s1;
+	uint8_t *u2 = (uint8_t *) s2;
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (*u1 != *u2)
+			return (int)(*u1) - (int)(*u2);
+		++u1;
+		++u2;
+	}
+
+	return 0;
+}
+
+/** Search memory area.
+ *
+ * @param s Memory area
+ * @param c Character (byte) to search for
+ * @param n Size of memory area in bytes
+ *
+ * @return Pointer to the first occurrence of @a c in the first @a n
+ *         bytes of @a s or @c NULL if not found.
+ */
+DO_NOT_DISCARD
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+void *memchr(const void *s, int c, size_t n)
+{
+	uint8_t *u = (uint8_t *) s;
+	unsigned char uc = (unsigned char) c;
+	size_t i;
+
+	for (i = 0; i < n; i++) {
+		if (u[i] == uc)
+			return (void *) &u[i];
+	}
+
+	return NULL;
+}
+
+/** @}
+ */
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/amd64/src/amd64.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,5 +37,5 @@
 #include <stdint.h>
 #include <errno.h>
-#include <mem.h>
+#include <memw.h>
 #include <interrupt.h>
 #include <console/console.h>
Index: kernel/arch/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/amd64/src/pm.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -39,5 +39,5 @@
 #include <mm/as.h>
 #include <mm/frame.h>
-#include <mem.h>
+#include <memw.h>
 #include <stdlib.h>
 
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/arm32/src/ras.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -44,5 +44,5 @@
 #include <arch/exception.h>
 #include <arch.h>
-#include <mem.h>
+#include <memw.h>
 #include <typedefs.h>
 
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/ia32/src/ia32.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -39,5 +39,5 @@
 #include <stdint.h>
 #include <errno.h>
-#include <mem.h>
+#include <memw.h>
 #include <interrupt.h>
 #include <console/console.h>
Index: kernel/arch/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/ia32/src/pm.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -44,5 +44,5 @@
 #include <mm/frame.h>
 #include <stdlib.h>
-#include <mem.h>
+#include <memw.h>
 #include <arch/boot/boot.h>
 #include <interrupt.h>
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/ia32/src/smp/smp.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -54,5 +54,5 @@
 #include <mm/as.h>
 #include <log.h>
-#include <mem.h>
+#include <memw.h>
 #include <genarch/drivers/i8259/i8259.h>
 #include <cpu.h>
Index: kernel/arch/ia64/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia64/src/cpu/cpu.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,5 +37,5 @@
 #include <arch/register.h>
 #include <stdio.h>
-#include <mem.h>
+#include <memw.h>
 
 void cpu_arch_init(void)
Index: kernel/arch/ia64/src/mm/vhpt.c
===================================================================
--- kernel/arch/ia64/src/mm/vhpt.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/ia64/src/mm/vhpt.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -33,5 +33,5 @@
  */
 
-#include <mem.h>
+#include <memw.h>
 #include <arch/barrier.h>
 #include <arch/mm/vhpt.h>
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/mips32/src/mips32.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -40,5 +40,5 @@
 #include <macros.h>
 #include <str.h>
-#include <mem.h>
+#include <memw.h>
 #include <preemption.h>
 #include <userspace.h>
Index: kernel/arch/riscv64/src/riscv64.c
===================================================================
--- kernel/arch/riscv64/src/riscv64.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/riscv64/src/riscv64.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -50,5 +50,5 @@
 #include <proc/thread.h>
 #include <console/console.h>
-#include <mem.h>
+#include <memw.h>
 #include <str.h>
 
Index: kernel/arch/sparc64/src/mm/sun4u/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/as.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/sparc64/src/mm/sun4u/as.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -47,5 +47,5 @@
 #include <bitops.h>
 #include <macros.h>
-#include <mem.h>
+#include <memw.h>
 
 #endif /* CONFIG_TSB */
Index: kernel/arch/sparc64/src/mm/sun4v/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/as.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/arch/sparc64/src/mm/sun4v/as.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -50,5 +50,5 @@
 #include <bitops.h>
 #include <macros.h>
-#include <mem.h>
+#include <memw.h>
 
 #endif /* CONFIG_TSB */
Index: kernel/genarch/src/acpi/acpi.c
===================================================================
--- kernel/genarch/src/acpi/acpi.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/acpi/acpi.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -43,5 +43,5 @@
 #include <mm/km.h>
 #include <log.h>
-#include <mem.h>
+#include <memw.h>
 
 #define RSDP_SIGNATURE      "RSD PTR "
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -42,5 +42,5 @@
 #include <typedefs.h>
 #include <arch/asm.h>
-#include <mem.h>
+#include <memw.h>
 #include <str.h>
 #include <console/chardev.h>
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -41,5 +41,5 @@
 #include <stdlib.h>
 #include <synch/spinlock.h>
-#include <mem.h>
+#include <memw.h>
 
 static irq_ownership_t cuda_claim(irq_t *irq);
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/fb/fb.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -45,5 +45,5 @@
 #include <align.h>
 #include <panic.h>
-#include <mem.h>
+#include <memw.h>
 #include <config.h>
 #include <bitops.h>
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/mm/as_pt.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -44,5 +44,5 @@
 #include <arch/mm/as.h>
 #include <typedefs.h>
-#include <mem.h>
+#include <memw.h>
 #include <arch.h>
 
Index: kernel/genarch/src/mm/page_pt.c
===================================================================
--- kernel/genarch/src/mm/page_pt.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/mm/page_pt.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -47,5 +47,5 @@
 #include <typedefs.h>
 #include <arch/asm.h>
-#include <mem.h>
+#include <memw.h>
 #include <align.h>
 #include <macros.h>
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -39,5 +39,5 @@
 #include <stdlib.h>
 #include <sysinfo/sysinfo.h>
-#include <mem.h>
+#include <memw.h>
 #include <str.h>
 #include <panic.h>
Index: kernel/generic/common
===================================================================
--- kernel/generic/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ kernel/generic/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,1 @@
+../../common
Index: kernel/generic/include/cc.h
===================================================================
--- kernel/generic/include/cc.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/include/cc.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -38,10 +38,7 @@
 
 #ifndef __clang__
-#define ATTRIBUTE_OPTIMIZE(opt) \
-	__attribute__ ((optimize(opt)))
 #define ATTRIBUTE_USED \
 	__attribute__ ((used))
 #else
-#define ATTRIBUTE_OPTIMIZE(opt)
 #define ATTRIBUTE_USED
 #endif
Index: kernel/generic/include/cpu/cpu_mask.h
===================================================================
--- kernel/generic/include/cpu/cpu_mask.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/include/cpu/cpu_mask.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -37,5 +37,5 @@
 #include <cpu.h>
 #include <config.h>
-#include <lib/memfnc.h>
+#include <memw.h>
 
 /** Iterates over all cpu id's whose bit is included in the cpu mask.
Index: rnel/generic/include/lib/memfnc.h
===================================================================
--- kernel/generic/include/lib/memfnc.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kernel_generic
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_LIB_MEMFNC_H_
-#define KERN_LIB_MEMFNC_H_
-
-#include <stddef.h>
-#include <cc.h>
-
-#ifdef CONFIG_LTO
-#define DO_NOT_DISCARD ATTRIBUTE_USED
-#else
-#define DO_NOT_DISCARD
-#endif
-
-extern void *memset(void *, int, size_t)
-    __attribute__((nonnull(1)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns") DO_NOT_DISCARD;
-extern void *memcpy(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns") DO_NOT_DISCARD;
-extern int memcmp(const void *, const void *, size_t len)
-    __attribute__((nonnull(1, 2)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns") DO_NOT_DISCARD;
-
-#define alloca(size) __builtin_alloca((size))
-
-#endif
-
-/** @}
- */
Index: rnel/generic/include/mem.h
===================================================================
--- kernel/generic/include/mem.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2001-2004 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kernel_generic
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_MEM_H_
-#define KERN_MEM_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <cc.h>
-
-#ifdef CONFIG_LTO
-#define DO_NOT_DISCARD ATTRIBUTE_USED
-#else
-#define DO_NOT_DISCARD
-#endif
-
-#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
-#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
-#define memcmp(s1, s2, cnt)    __builtin_memcmp((s1), (s2), (cnt))
-
-extern void memsetb(void *, size_t, uint8_t)
-    __attribute__((nonnull(1)));
-extern void memsetw(void *, size_t, uint16_t)
-    __attribute__((nonnull(1)));
-extern void *memmove(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2))) DO_NOT_DISCARD;
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/memw.h
===================================================================
--- kernel/generic/include/memw.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ kernel/generic/include/memw.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kernel_generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_MEM_H_
+#define KERN_MEM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <mem.h>
+
+extern void memsetb(void *, size_t, uint8_t)
+    __attribute__((nonnull(1)));
+extern void memsetw(void *, size_t, uint16_t)
+    __attribute__((nonnull(1)));
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/meson.build
===================================================================
--- kernel/generic/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -36,4 +36,6 @@
 
 generic_src += files(
+	'common/stdc/mem.c',
+
 	'src/adt/bitmap.c',
 	'src/adt/hash_table.c',
@@ -73,5 +75,4 @@
 	'src/lib/halt.c',
 	'src/lib/mem.c',
-	'src/lib/memfnc.c',
 	'src/lib/ra.c',
 	'src/lib/rd.c',
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/cpu/cpu.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -45,5 +45,5 @@
 #include <config.h>
 #include <panic.h>
-#include <mem.h>
+#include <memw.h>
 #include <adt/list.h>
 #include <stdio.h>
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/ddi/ddi.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -54,5 +54,5 @@
 #include <align.h>
 #include <errno.h>
-#include <mem.h>
+#include <memw.h>
 #include <trace.h>
 #include <bitops.h>
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/ddi/irq.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -47,5 +47,5 @@
 #include <console/console.h>
 #include <interrupt.h>
-#include <mem.h>
+#include <memw.h>
 #include <arch.h>
 
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/ipc/ipc.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -54,5 +54,5 @@
 #include <arch.h>
 #include <proc/task.h>
-#include <mem.h>
+#include <memw.h>
 #include <stdio.h>
 #include <console/console.h>
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/ipc/sysipc.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -36,5 +36,5 @@
 #include <assert.h>
 #include <errno.h>
-#include <mem.h>
+#include <memw.h>
 #include <ipc/ipc.h>
 #include <abi/ipc/methods.h>
Index: kernel/generic/src/lib/gsort.c
===================================================================
--- kernel/generic/src/lib/gsort.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/lib/gsort.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -41,5 +41,5 @@
 
 #include <gsort.h>
-#include <mem.h>
+#include <memw.h>
 #include <stdlib.h>
 
Index: kernel/generic/src/lib/mem.c
===================================================================
--- kernel/generic/src/lib/mem.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/lib/mem.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -41,5 +41,5 @@
  */
 
-#include <mem.h>
+#include <memw.h>
 #include <typedefs.h>
 
@@ -77,49 +77,4 @@
 }
 
-/** Move memory block with possible overlapping.
- *
- * Copy cnt bytes from src address to dst address. The source
- * and destination memory areas may overlap.
- *
- * @param dst Destination address to copy to.
- * @param src Source address to copy from.
- * @param cnt Number of bytes to copy.
- *
- * @return Destination address.
- *
- */
-void *memmove(void *dst, const void *src, size_t cnt)
-{
-	/* Nothing to do? */
-	if (src == dst)
-		return dst;
-
-	/* Non-overlapping? */
-	if ((dst >= src + cnt) || (src >= dst + cnt))
-		return memcpy(dst, src, cnt);
-
-	uint8_t *dp;
-	const uint8_t *sp;
-
-	/* Which direction? */
-	if (src > dst) {
-		/* Forwards. */
-		dp = dst;
-		sp = src;
-
-		while (cnt-- != 0)
-			*dp++ = *sp++;
-	} else {
-		/* Backwards. */
-		dp = dst + (cnt - 1);
-		sp = src + (cnt - 1);
-
-		while (cnt-- != 0)
-			*dp-- = *sp--;
-	}
-
-	return dst;
-}
-
 /** @}
  */
Index: rnel/generic/src/lib/memfnc.c
===================================================================
--- kernel/generic/src/lib/memfnc.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kernel_generic
- * @{
- */
-
-/**
- * @file
- * @brief Memory string functions.
- *
- * This file provides architecture independent functions to manipulate blocks
- * of memory. These functions are optimized as much as generic functions of
- * this type can be.
- */
-
-#include <lib/memfnc.h>
-#include <typedefs.h>
-
-/** Fill block of memory.
- *
- * Fill cnt bytes at dst address with the value val.
- *
- * @param dst Destination address to fill.
- * @param val Value to fill.
- * @param cnt Number of bytes to fill.
- *
- * @return Destination address.
- *
- */
-void *memset(void *dst, int val, size_t cnt)
-{
-	uint8_t *dp = (uint8_t *) dst;
-
-	while (cnt-- != 0)
-		*dp++ = val;
-
-	return dst;
-}
-
-/** Move memory block without overlapping.
- *
- * Copy cnt bytes from src address to dst address. The source
- * and destination memory areas cannot overlap.
- *
- * @param dst Destination address to copy to.
- * @param src Source address to copy from.
- * @param cnt Number of bytes to copy.
- *
- * @return Destination address.
- *
- */
-void *memcpy(void *dst, const void *src, size_t cnt)
-{
-	uint8_t *dp = (uint8_t *) dst;
-	const uint8_t *sp = (uint8_t *) src;
-
-	while (cnt-- != 0)
-		*dp++ = *sp++;
-
-	return dst;
-}
-
-/** Compare two memory areas.
- *
- * @param s1  Pointer to the first area to compare.
- * @param s2  Pointer to the second area to compare.
- * @param len Size of the areas in bytes.
- *
- * @return Zero if areas have the same contents. If they differ,
- *	   the sign of the result is the same as the sign of the
- *	   difference of the first pair of different bytes.
- *
- */
-int memcmp(const void *s1, const void *s2, size_t len)
-{
-	uint8_t *u1 = (uint8_t *) s1;
-	uint8_t *u2 = (uint8_t *) s2;
-	size_t i;
-
-	for (i = 0; i < len; i++) {
-		if (*u1 != *u2)
-			return (int)(*u1) - (int)(*u2);
-		++u1;
-		++u2;
-	}
-
-	return 0;
-}
-
-/** @}
- */
Index: kernel/generic/src/lib/ubsan.c
===================================================================
--- kernel/generic/src/lib/ubsan.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/lib/ubsan.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -10,5 +10,5 @@
 #include <stddef.h>
 #include <panic.h>
-#include <mem.h>
+#include <memw.h>
 
 #define PRINTF(...) printf(__VA_ARGS__)
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/main/kinit.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -61,5 +61,5 @@
 #include <stdio.h>
 #include <log.h>
-#include <mem.h>
+#include <memw.h>
 #include <console/console.h>
 #include <interrupt.h>
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/mm/as.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -69,5 +69,5 @@
 #include <assert.h>
 #include <stdio.h>
-#include <mem.h>
+#include <memw.h>
 #include <macros.h>
 #include <bitops.h>
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/mm/backend_anon.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -51,5 +51,5 @@
 #include <typedefs.h>
 #include <align.h>
-#include <mem.h>
+#include <memw.h>
 #include <arch.h>
 
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/mm/backend_elf.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -48,5 +48,5 @@
 #include <genarch/mm/page_ht.h>
 #include <align.h>
-#include <mem.h>
+#include <memw.h>
 #include <macros.h>
 #include <arch.h>
Index: kernel/generic/src/mm/malloc.c
===================================================================
--- kernel/generic/src/mm/malloc.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/mm/malloc.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -34,5 +34,5 @@
 #include <bitops.h>
 #include <mm/slab.h>
-#include <mem.h>
+#include <memw.h>
 #include <main/main.h> // malloc_init()
 #include <macros.h>
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/mm/slab.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -106,5 +106,5 @@
 #include <mm/slab.h>
 #include <adt/list.h>
-#include <mem.h>
+#include <memw.h>
 #include <align.h>
 #include <mm/frame.h>
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/printf/vsnprintf.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -36,5 +36,5 @@
 #include <printf/printf_core.h>
 #include <str.h>
-#include <mem.h>
+#include <memw.h>
 #include <errno.h>
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/proc/thread.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -62,5 +62,5 @@
 #include <arch/faddr.h>
 #include <atomic.h>
-#include <mem.h>
+#include <memw.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/synch/waitq.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -59,5 +59,5 @@
 #include <adt/list.h>
 #include <arch/cycle.h>
-#include <mem.h>
+#include <memw.h>
 
 /** Initialize wait queue
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -51,5 +51,5 @@
 #include <udebug/udebug.h>
 #include <udebug/udebug_ops.h>
-#include <mem.h>
+#include <memw.h>
 #include <stdlib.h>
 
Index: kernel/meson.build
===================================================================
--- kernel/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -48,4 +48,5 @@
 	'..' / 'abi' / 'arch' / KARCH / 'include',
 	'..' / 'abi' / 'include',
+	'..' / 'common' / 'include',
 	'test',
 )
Index: kernel/test/mm/falloc2.c
===================================================================
--- kernel/test/mm/falloc2.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/test/mm/falloc2.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -35,5 +35,5 @@
 #include <atomic.h>
 #include <proc/thread.h>
-#include <mem.h>
+#include <memw.h>
 #include <arch.h>
 
Index: kernel/test/mm/slab1.c
===================================================================
--- kernel/test/mm/slab1.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/test/mm/slab1.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -31,5 +31,5 @@
 #include <proc/thread.h>
 #include <arch.h>
-#include <mem.h>
+#include <memw.h>
 
 #define VAL_COUNT  1024
Index: kernel/test/mm/slab2.c
===================================================================
--- kernel/test/mm/slab2.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ kernel/test/mm/slab2.c	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -32,5 +32,5 @@
 #include <arch.h>
 #include <mm/frame.h>
-#include <mem.h>
+#include <memw.h>
 #include <synch/condvar.h>
 #include <synch/mutex.h>
Index: uspace/lib/c/common
===================================================================
--- uspace/lib/c/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ uspace/lib/c/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,1 @@
+../../../common
Index: pace/lib/c/generic/mem.c
===================================================================
--- uspace/lib/c/generic/mem.c	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,281 +1,0 @@
-/*
- * Copyright (c) 2005 Martin Decky
- * Copyright (c) 2018 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <mem.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-#include "private/cc.h"
-
-/** Fill memory block with a constant value. */
-ATTRIBUTE_OPTIMIZE_NO_TLDP
-    void *memset(void *dest, int b, size_t n)
-{
-	char *pb;
-	unsigned long *pw;
-	size_t word_size;
-	size_t n_words;
-
-	unsigned long pattern;
-	size_t i;
-	size_t fill;
-
-	/* Fill initial segment. */
-	word_size = sizeof(unsigned long);
-	fill = word_size - ((uintptr_t) dest & (word_size - 1));
-	if (fill > n)
-		fill = n;
-
-	pb = dest;
-
-	i = fill;
-	while (i-- != 0)
-		*pb++ = b;
-
-	/* Compute remaining size. */
-	n -= fill;
-	if (n == 0)
-		return dest;
-
-	n_words = n / word_size;
-	n = n % word_size;
-	pw = (unsigned long *) pb;
-
-	/* Create word-sized pattern for aligned segment. */
-	pattern = 0;
-	i = word_size;
-	while (i-- != 0)
-		pattern = (pattern << 8) | (uint8_t) b;
-
-	/* Fill aligned segment. */
-	i = n_words;
-	while (i-- != 0)
-		*pw++ = pattern;
-
-	pb = (char *) pw;
-
-	/* Fill final segment. */
-	i = n;
-	while (i-- != 0)
-		*pb++ = b;
-
-	return dest;
-}
-
-struct along {
-	unsigned long n;
-} __attribute__((packed));
-
-static void *unaligned_memcpy(void *dst, const void *src, size_t n)
-{
-	size_t i, j;
-	struct along *adst = dst;
-	const struct along *asrc = src;
-
-	for (i = 0; i < n / sizeof(unsigned long); i++)
-		adst[i].n = asrc[i].n;
-
-	for (j = 0; j < n % sizeof(unsigned long); j++)
-		((unsigned char *) (((unsigned long *) dst) + i))[j] =
-		    ((unsigned char *) (((unsigned long *) src) + i))[j];
-
-	return (char *) dst;
-}
-
-/** Copy memory block. */
-ATTRIBUTE_OPTIMIZE_NO_TLDP
-    void *memcpy(void *dst, const void *src, size_t n)
-{
-	size_t i;
-	size_t mod, fill;
-	size_t word_size;
-	size_t n_words;
-
-	const unsigned long *srcw;
-	unsigned long *dstw;
-	const uint8_t *srcb;
-	uint8_t *dstb;
-
-	word_size = sizeof(unsigned long);
-
-	/*
-	 * Are source and destination addresses congruent modulo word_size?
-	 * If not, use unaligned_memcpy().
-	 */
-
-	if (((uintptr_t) dst & (word_size - 1)) !=
-	    ((uintptr_t) src & (word_size - 1)))
-		return unaligned_memcpy(dst, src, n);
-
-	/*
-	 * mod is the address modulo word size. fill is the length of the
-	 * initial buffer segment before the first word boundary.
-	 * If the buffer is very short, use unaligned_memcpy(), too.
-	 */
-
-	mod = (uintptr_t) dst & (word_size - 1);
-	fill = word_size - mod;
-	if (fill > n)
-		fill = n;
-
-	/* Copy the initial segment. */
-
-	srcb = src;
-	dstb = dst;
-
-	i = fill;
-	while (i-- != 0)
-		*dstb++ = *srcb++;
-
-	/* Compute remaining length. */
-
-	n -= fill;
-	if (n == 0)
-		return dst;
-
-	/* Pointers to aligned segment. */
-
-	dstw = (unsigned long *) dstb;
-	srcw = (const unsigned long *) srcb;
-
-	n_words = n / word_size;	/* Number of whole words to copy. */
-	n -= n_words * word_size;	/* Remaining bytes at the end. */
-
-	/* "Fast" copy. */
-	i = n_words;
-	while (i-- != 0)
-		*dstw++ = *srcw++;
-
-	/*
-	 * Copy the rest.
-	 */
-
-	srcb = (const uint8_t *) srcw;
-	dstb = (uint8_t *) dstw;
-
-	i = n;
-	while (i-- != 0)
-		*dstb++ = *srcb++;
-
-	return dst;
-}
-
-/** Move memory block with possible overlapping. */
-void *memmove(void *dst, const void *src, size_t n)
-{
-	const uint8_t *sp;
-	uint8_t *dp;
-
-	/* Nothing to do? */
-	if (src == dst)
-		return dst;
-
-	/* Non-overlapping? */
-	if (dst >= src + n || src >= dst + n) {
-		return memcpy(dst, src, n);
-	}
-
-	/* Which direction? */
-	if (src > dst) {
-		/* Forwards. */
-		sp = src;
-		dp = dst;
-
-		while (n-- != 0)
-			*dp++ = *sp++;
-	} else {
-		/* Backwards. */
-		sp = src + (n - 1);
-		dp = dst + (n - 1);
-
-		while (n-- != 0)
-			*dp-- = *sp--;
-	}
-
-	return dst;
-}
-
-/** Compare two memory areas.
- *
- * @param s1  Pointer to the first area to compare.
- * @param s2  Pointer to the second area to compare.
- * @param len Size of the areas in bytes.
- *
- * @return Zero if areas have the same contents. If they differ,
- *	   the sign of the result is the same as the sign of the
- *	   difference of the first pair of different bytes.
- *
- */
-int memcmp(const void *s1, const void *s2, size_t len)
-{
-	uint8_t *u1 = (uint8_t *) s1;
-	uint8_t *u2 = (uint8_t *) s2;
-	size_t i;
-
-	for (i = 0; i < len; i++) {
-		if (*u1 != *u2)
-			return (int)(*u1) - (int)(*u2);
-		++u1;
-		++u2;
-	}
-
-	return 0;
-}
-
-/** Search memory area.
- *
- * @param s Memory area
- * @param c Character (byte) to search for
- * @param n Size of memory area in bytes
- *
- * @return Pointer to the first occurrence of @a c in the first @a n
- *         bytes of @a s or @c NULL if not found.
- */
-void *memchr(const void *s, int c, size_t n)
-{
-	uint8_t *u = (uint8_t *) s;
-	unsigned char uc = (unsigned char) c;
-	size_t i;
-
-	for (i = 0; i < n; i++) {
-		if (u[i] == uc)
-			return (void *) &u[i];
-	}
-
-	return NULL;
-}
-
-/** @}
- */
Index: pace/lib/c/include/mem.h
===================================================================
--- uspace/lib/c/include/mem.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2005 Martin Decky
- * Copyright (c) 2018 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_MEM_H_
-#define _LIBC_MEM_H_
-
-#include <stddef.h>
-#include <_bits/decls.h>
-
-__C_DECLS_BEGIN;
-
-extern void *memset(void *, int, size_t)
-    __attribute__((nonnull(1)));
-extern void *memcpy(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)));
-extern void *memmove(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)));
-extern int memcmp(const void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)));
-extern void *memchr(const void *, int, size_t)
-    __attribute__((nonnull(1)));
-
-__C_DECLS_END;
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/meson.build
===================================================================
--- uspace/lib/c/meson.build	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ uspace/lib/c/meson.build	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -42,4 +42,5 @@
 	root_path / 'abi' / 'arch' / UARCH / 'include',
 	root_path / 'abi' / 'include',
+	root_path / 'common' / 'include',
 ]
 
@@ -60,4 +61,5 @@
 
 src += files(
+	'common/stdc/mem.c',
 	'generic/libc.c',
 	'generic/as.c',
@@ -85,5 +87,4 @@
 	'generic/ipc_test.c',
 	'generic/loc.c',
-	'generic/mem.c',
 	'generic/str.c',
 	'generic/string.c',
Index: uspace/lib/posix/include/common
===================================================================
--- uspace/lib/posix/include/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
+++ uspace/lib/posix/include/common	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -0,0 +1,1 @@
+../../../../common/include
Index: uspace/lib/posix/include/posix/string.h
===================================================================
--- uspace/lib/posix/include/posix/string.h	(revision c89ae2562f477e91a8041f1bdff7ef9c6bec68b8)
+++ uspace/lib/posix/include/posix/string.h	(revision b1696194837e19c7e4d446880d20ede25043bad4)
@@ -46,5 +46,5 @@
 #include <stddef.h>
 
-#include <libc/mem.h>
+#include <common/mem.h>
 
 #define _REALLY_WANT_STRING_H
