diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-06 22:47:23 -0500 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-06 22:47:23 -0500 |
commit | c95b10cff38fabf23a763d1889d024f6dabd4955 (patch) | |
tree | dc014fab60c42ef06c08956773e66f6fa0f83de1 | |
parent | 11a84a636ce9722053cc3100d5c04e30e9f93df2 (diff) | |
parent | 831bb584a91f5409af5df3c44f1bc8dc354ff0d8 (diff) |
Merge pull request #2103 from juj/opt_cmp1.10.2
Add optimized versions of musl libc string and memory comparison functions.
-rwxr-xr-x | emcc | 8 | ||||
-rw-r--r-- | src/library.js | 73 | ||||
-rw-r--r-- | system/lib/libc.symbols | 9 | ||||
-rw-r--r-- | system/lib/libc/musl/src/locale/strcoll.c | 15 | ||||
-rw-r--r-- | system/lib/libc/musl/src/string/memcmp.c | 8 | ||||
-rw-r--r-- | system/lib/libc/musl/src/string/strcasecmp.c | 9 | ||||
-rw-r--r-- | system/lib/libc/musl/src/string/strcmp.c | 7 | ||||
-rw-r--r-- | system/lib/libc/musl/src/string/strncasecmp.c | 10 | ||||
-rw-r--r-- | system/lib/libc/musl/src/string/strncmp.c | 9 | ||||
-rw-r--r-- | tests/core/test_strcmp_uni.out | 6 | ||||
-rw-r--r-- | tests/test_core.py | 7 | ||||
-rw-r--r-- | tools/shared.py | 2 |
12 files changed, 85 insertions, 78 deletions
@@ -1476,6 +1476,13 @@ try: ['stdlib', [ 'atof.c', 'strtod.c', + ]], + ['string', [ + 'memcmp.c', + 'strcasecmp.c', + 'strcmp.c', + 'strncasecmp.c', + 'strncmp.c', ]] ] for directory, sources in musl_files: @@ -1538,6 +1545,7 @@ try: 'iswspace_l.c', 'iswupper_l.c', 'iswxdigit_l.c', + 'strcoll.c', 'strcasecmp_l.c', 'strfmon.c', 'strncasecmp_l.c', diff --git a/src/library.js b/src/library.js index 3a5f6480..4f57c324 100644 --- a/src/library.js +++ b/src/library.js @@ -3761,79 +3761,6 @@ LibraryManager.library = { return pdest; }, - strcmp__deps: ['strncmp'], - strcmp: function(px, py) { - return _strncmp(px, py, TOTAL_MEMORY); - }, - // We always assume ASCII locale. - strcoll: 'strcmp', - strcoll_l__deps: ['strcoll'], - strcoll_l: function(px, py) { - return _strcoll(px, py); // no locale support yet - }, - - strcasecmp__asm: true, - strcasecmp__sig: 'iii', - strcasecmp__deps: ['strncasecmp'], - strcasecmp: function(px, py) { - px = px|0; py = py|0; - return _strncasecmp(px, py, -1)|0; - }, - - strncmp: function(px, py, n) { - var i = 0; - while (i < n) { - var x = {{{ makeGetValue('px', 'i', 'i8', 0, 1) }}}; - var y = {{{ makeGetValue('py', 'i', 'i8', 0, 1) }}}; - if (x == y && x == 0) return 0; - if (x == 0) return -1; - if (y == 0) return 1; - if (x == y) { - i ++; - continue; - } else { - return x > y ? 1 : -1; - } - } - return 0; - }, - - strncasecmp__asm: true, - strncasecmp__sig: 'iiii', - strncasecmp__deps: ['tolower'], - strncasecmp: function(px, py, n) { - px = px|0; py = py|0; n = n|0; - var i = 0, x = 0, y = 0; - while ((i>>>0) < (n>>>0)) { - x = _tolower({{{ makeGetValueAsm('px', 'i', 'i8', 0, 1) }}})|0; - y = _tolower({{{ makeGetValueAsm('py', 'i', 'i8', 0, 1) }}})|0; - if (((x|0) == (y|0)) & ((x|0) == 0)) return 0; - if ((x|0) == 0) return -1; - if ((y|0) == 0) return 1; - if ((x|0) == (y|0)) { - i = (i + 1)|0; - continue; - } else { - return ((x>>>0) > (y>>>0) ? 1 : -1)|0; - } - } - return 0; - }, - - memcmp__asm: true, - memcmp__sig: 'iiii', - memcmp: function(p1, p2, num) { - p1 = p1|0; p2 = p2|0; num = num|0; - var i = 0, v1 = 0, v2 = 0; - while ((i|0) < (num|0)) { - v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}}; - v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}}; - if ((v1|0) != (v2|0)) return ((v1|0) > (v2|0) ? 1 : -1)|0; - i = (i+1)|0; - } - return 0; - }, - memchr: function(ptr, chr, num) { chr = unSign(chr); for (var i = 0; i < num; i++) { diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols index 6f80ef90..53a27082 100644 --- a/system/lib/libc.symbols +++ b/system/lib/libc.symbols @@ -72,7 +72,16 @@ W realloc_in_place T scalbn T scalbnl + T memcmp + T memcpy T strtod + T strcoll + T __strcoll_l + W strcoll_l + T strcmp + T strncmp + T strcasecmp + T strncasecmp T strtod_l T strtof T strtof_l diff --git a/system/lib/libc/musl/src/locale/strcoll.c b/system/lib/libc/musl/src/locale/strcoll.c new file mode 100644 index 00000000..39ea1123 --- /dev/null +++ b/system/lib/libc/musl/src/locale/strcoll.c @@ -0,0 +1,15 @@ +#include <string.h> +#include <locale.h> +#include "libc.h" + +int __strcoll_l(const char *l, const char *r, locale_t loc) +{ + return strcmp(l, r); +} + +int strcoll(const char *l, const char *r) +{ + return __strcoll_l(l, r, 0); +} + +weak_alias(__strcoll_l, strcoll_l); diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c new file mode 100644 index 00000000..bdbce9f0 --- /dev/null +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -0,0 +1,8 @@ +#include <string.h> + +int memcmp(const void *vl, const void *vr, size_t n) +{ + const unsigned char *l=vl, *r=vr; + for (; n && *l == *r; n--, l++, r++); + return n ? *l-*r : 0; +} diff --git a/system/lib/libc/musl/src/string/strcasecmp.c b/system/lib/libc/musl/src/string/strcasecmp.c new file mode 100644 index 00000000..02fd5f8c --- /dev/null +++ b/system/lib/libc/musl/src/string/strcasecmp.c @@ -0,0 +1,9 @@ +#include <strings.h> +#include <ctype.h> + +int strcasecmp(const char *_l, const char *_r) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); + return tolower(*l) - tolower(*r); +} diff --git a/system/lib/libc/musl/src/string/strcmp.c b/system/lib/libc/musl/src/string/strcmp.c new file mode 100644 index 00000000..91eb7404 --- /dev/null +++ b/system/lib/libc/musl/src/string/strcmp.c @@ -0,0 +1,7 @@ +#include <string.h> + +int strcmp(const char *l, const char *r) +{ + for (; *l==*r && *l && *r; l++, r++); + return *(unsigned char *)l - *(unsigned char *)r; +} diff --git a/system/lib/libc/musl/src/string/strncasecmp.c b/system/lib/libc/musl/src/string/strncasecmp.c new file mode 100644 index 00000000..24659721 --- /dev/null +++ b/system/lib/libc/musl/src/string/strncasecmp.c @@ -0,0 +1,10 @@ +#include <strings.h> +#include <ctype.h> + +int strncasecmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--); + return tolower(*l) - tolower(*r); +} diff --git a/system/lib/libc/musl/src/string/strncmp.c b/system/lib/libc/musl/src/string/strncmp.c new file mode 100644 index 00000000..e228843f --- /dev/null +++ b/system/lib/libc/musl/src/string/strncmp.c @@ -0,0 +1,9 @@ +#include <string.h> + +int strncmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && *l == *r ; l++, r++, n--); + return *l - *r; +} diff --git a/tests/core/test_strcmp_uni.out b/tests/core/test_strcmp_uni.out index 58e237d7..ebfe2c8e 100644 --- a/tests/core/test_strcmp_uni.out +++ b/tests/core/test_strcmp_uni.out @@ -1,3 +1,3 @@ -Compare value strncmp is -1 -Compare value strncasecmp is -1 -Compare value memcmp is -1 +Compare value strncmp is -108 +Compare value strncasecmp is -76 +Compare value memcmp is -108 diff --git a/tests/test_core.py b/tests/test_core.py index 47360fd6..a77d2465 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3264,6 +3264,7 @@ def process(filename): #include <assert.h> #include <stdio.h> #include <dlfcn.h> + #include <string.h> typedef int (*FUNCTYPE)(const char *); @@ -3274,6 +3275,10 @@ def process(filename): snprintf(str, sizeof(str), "foobar"); + // HACK: Use strcmp in the main executable so that it doesn't get optimized out and the dynamic library + // is able to use it. + assert(!strcmp(str, "foobar")); + lib_handle = dlopen("liblib.so", RTLD_NOW); assert(lib_handle != NULL); @@ -3286,7 +3291,7 @@ def process(filename): return 0; } ''' - Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc'] + Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_strcmp'] self.do_run(src, 'success', force_c=True, post_build=self.dlfcn_post_build) def test_dlfcn_funcs(self): diff --git a/tools/shared.py b/tools/shared.py index 3b0b92a3..dbf1e3ef 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -345,7 +345,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.10.1' +EMSCRIPTEN_VERSION = '1.10.2' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT + '|' + get_clang_version() |