source: trunk/libs/newlib/src/newlib/libc/machine/riscv/strlen.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 1.7 KB
Line 
1/* Copyright (c) 2017  SiFive Inc. All rights reserved.
2
3   This copyrighted material is made available to anyone wishing to use,
4   modify, copy, or redistribute it subject to the terms and conditions
5   of the FreeBSD License.   This program is distributed in the hope that
6   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
7   including the implied warranties of MERCHANTABILITY or FITNESS FOR
8   A PARTICULAR PURPOSE.  A copy of this license is available at
9   http://www.opensource.org/licenses.
10*/
11
12#include <string.h>
13#include <stdint.h>
14
15size_t strlen(const char *str)
16{
17  const char *start = str;
18
19#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
20  while (*str++)
21    ;
22  return str - start - 1;
23#else
24  if (__builtin_expect ((uintptr_t)str & (sizeof (long) - 1), 0)) do
25    {
26      char ch = *str;
27      str++;
28      if (!ch)
29        return str - start - 1;
30    } while ((uintptr_t)str & (sizeof (long) - 1));
31
32  unsigned long *ls = (unsigned long *)str;
33  while (!__libc_detect_null (*ls++))
34    ;
35  asm volatile ("" : "+r"(ls)); /* prevent "optimization" */
36
37  str = (const char *)ls;
38  size_t ret = str - start, sl = sizeof (long);
39
40  char c0 = str[0 - sl], c1 = str[1 - sl], c2 = str[2 - sl], c3 = str[3 - sl];
41  if (c0 == 0)            return ret + 0 - sl;
42  if (c1 == 0)            return ret + 1 - sl;
43  if (c2 == 0)            return ret + 2 - sl;
44  if (sl == 4 || c3 == 0) return ret + 3 - sl;
45
46  c0 = str[4 - sl], c1 = str[5 - sl], c2 = str[6 - sl], c3 = str[7 - sl];
47  if (c0 == 0)            return ret + 4 - sl;
48  if (c1 == 0)            return ret + 5 - sl;
49  if (c2 == 0)            return ret + 6 - sl;
50
51  return ret + 7 - sl;
52#endif /* not PREFER_SIZE_OVER_SPEED */
53}
Note: See TracBrowser for help on using the repository browser.