diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2017-07-10 15:51:41 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-10 16:32:34 -0700 |
commit | be5f3c7774a158c5bd08de22d54b0612f954dfa8 (patch) | |
tree | 1db36ebd3507d7e5f294546c9f94db18af140db5 | |
parent | 512750ef8b06290a55d749239f956f9c21d7daca (diff) |
lib/kstrtox.c: use "unsigned int" more
gcc does generates stupid code sign extending data back and forth. Help
by using "unsigned int".
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-61 (-61)
function old new delta
_parse_integer 128 123 -5
It _still_ does generate useless MOVSX but I don't know how to delete it:
0000000000000070 <_parse_integer>:
...
a0: 89 c2 mov edx,eax
a2: 83 e8 30 sub eax,0x30
a5: 83 f8 09 cmp eax,0x9
a8: 76 11 jbe bb <_parse_integer+0x4b>
aa: 83 ca 20 or edx,0x20
ad: 0f be c2 ===> movsx eax,dl <===
useless
b0: 8d 50 9f lea edx,[rax-0x61]
b3: 83 fa 05 cmp edx,0x5
Patch also helps on embedded archs which generally only like "int". On
arm "and 0xff" is generated which is waste because all values used in
comparisons are positive.
Link: http://lkml.kernel.org/r/20170514194720.GB32563@avx2
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | lib/kstrtox.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/lib/kstrtox.c b/lib/kstrtox.c index 90013f4841c7..720144075c1e 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -52,12 +52,14 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long res = 0; rv = 0; while (1) { + unsigned int c = *s; + unsigned int lc = c | 0x20; /* don't tolower() this line */ unsigned int val; - if ('0' <= *s && *s <= '9') - val = *s - '0'; - else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f') - val = _tolower(*s) - 'a' + 10; + if ('0' <= c && c <= '9') + val = c - '0'; + else if ('a' <= lc && lc <= 'f') + val = lc - 'a' + 10; else break; |