1.22. MANIPULATING SPECIFIC BIT(S)
ARM + Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
Listing 1.294: Optimizing Xcode 4.6.3 (LLVM) (ARM mode)
MOV R1, R0
MOV R0, #0
MOV R2, #1
MOV R3, R0
loc_2E54
TST R1, R2,LSL R3 ; set flags according to R1 & (R2<<R3)
ADD R3, R3, #1 ; R3++
ADDNE R0, R0, #1 ; if ZF flag is cleared by TST, then R0++
CMP R3, #32
BNE loc_2E54
BX LR
TSTis the same things asTESTin x86.
As was noted before (3.9.3 on page 499), there are no separate shifting instructions in ARM mode. How-
ever, there are modifiers LSL (Logical Shift Left), LSR (Logical Shift Right), ASR (Arithmetic Shift Right),
ROR (Rotate Right) and RRX (Rotate Right with Extend), which may be added to such instructions asMOV,
TST,CMP,ADD,SUB,RSB^155.
These modificators define how to shift the second operand and by how many bits.
Thus the“TST R1, R2,LSL R3”instruction works here asR 1 ∧(R 2 ≪R3).
ARM + Optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
Almost the same, but here are twoLSL.W/TSTinstructions are used instead of a singleTST, because in
Thumb mode it is not possible to defineLSLmodifier directly inTST.
MOV R1, R0
MOVS R0, #0
MOV.W R9, #1
MOVS R3, #0
loc_2F7A
LSL.W R2, R9, R3
TST R2, R1
ADD.W R3, R3, #1
IT NE
ADDNE R0, #1
CMP R3, #32
BNE loc_2F7A
BX LR
ARM64 + Optimizing GCC 4.9
Let’s take the 64-bit example which has been already used:1.22.5 on page 330.
Listing 1.295: Optimizing GCC (Linaro) 4.8
f:
mov w2, 0 ; rt=0
mov x5, 1
mov w1, w2
.L2:
lsl x4, x5, x1 ; w4 = w5<<w1 = 1<<i
add w3, w2, 1 ; new_rt=rt+1
tst x4, x0 ; (1<<i) & a
add w1, w1, 1 ; i++
; result of TST was non-zero?
; then w2=w3 or rt=new_rt.
; otherwise: w2=w2 or rt=rt (idle operation)
csel w2, w3, w2, ne
cmp w1, 64 ; i<64?
(^155) These instructions are also called “data processing instructions”