forked from Minki/linux
29507663df
Our internal process shares memcpy, memset, etc., with libc, and we did some minor tweaking as part of moving from uclibc to glibc, which is now reflected in the kernel versions of these files. There are no semantic changes in this commit, just whitespace (memcpy_32.S now properly uses tabs), naming (memmove.c instead of memmove_32.c, since TILE-Gx shares the file with TILEPro), and a couple of other minor tweaks. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
39 lines
1.1 KiB
C
39 lines
1.1 KiB
C
/*
|
|
* Copyright 2010 Tilera Corporation. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, version 2.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
|
* NON INFRINGEMENT. See the GNU General Public License for
|
|
* more details.
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/string.h>
|
|
#include <linux/module.h>
|
|
|
|
#undef strlen
|
|
|
|
size_t strlen(const char *s)
|
|
{
|
|
/* Get an aligned pointer. */
|
|
const uintptr_t s_int = (uintptr_t) s;
|
|
const uint32_t *p = (const uint32_t *)(s_int & -4);
|
|
|
|
/* Read the first word, but force bytes before the string to be nonzero.
|
|
* This expression works because we know shift counts are taken mod 32.
|
|
*/
|
|
uint32_t v = *p | ((1 << (s_int << 3)) - 1);
|
|
|
|
uint32_t bits;
|
|
while ((bits = __insn_seqb(v, 0)) == 0)
|
|
v = *++p;
|
|
|
|
return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
|
|
}
|
|
EXPORT_SYMBOL(strlen);
|