3.16. TOUPPER() FUNCTION
strb w0, [sp,15]
ldrb w0, [sp,15]
cmp w0, 96
bls .L2
ldrb w0, [sp,15]
cmp w0, 122
bhi .L2
ldrb w0, [sp,15]
sub w0, w0, #32
uxtb w0, w0
b .L3
.L2:
ldrb w0, [sp,15]
.L3:
add sp, sp, 16
ret
Listing 3.77: Optimizing GCC 4.9 (ARM64)
toupper:
uxtb w0, w0
sub w1, w0, #97
uxtb w1, w1
cmp w1, 25
bhi .L2
sub w0, w0, #32
uxtb w0, w0
.L2:
ret
3.16.3 Using bit operations.
Given the fact that 5th bit (counting from 0th) is always present after the check, subtracting is merely
clearing this sole bit, but the very same effect can be achieved with ANDing (2.5 on page 458).
Even simpler, with XOR-ing:
char toupper (char c)
{
if(c>='a' && c<='z')
return c^0x20;
else
return c;
}
ThecodeisclosetowhattheoptimizedGCChasproducedforthepreviousexample(3.73onthepreceding
page):
Listing 3.78: Optimizing GCC 5.4 (x86)
toupper:
mov edx, DWORD PTR [esp+4]
lea ecx, [edx-97]
mov eax, edx
xor eax, 32
cmp cl, 25
cmova eax, edx
ret
...butXORis used instead ofSUB.
Flipping 5th bit is just moving acursorinASCIItable up and down by two rows.
Some people say that lowercase/uppercase letters has been placed in theASCIItable in such a way
deliberately, because: