Chapter 7 Manipulating Bits Part 1 Specifying Bit

Chapter 7 Manipulating Bits Part 1: Specifying Bit Patterns

Bit Patterns • A bit pattern (aka, “mask”) is a string of 1’s and 0’s designed to select a subset of bits from another operand. • Bit patterns are used to: – Test the value of one bit while ignoring others – Set, clear, or invert the value of one bit without affecting others – Extract or Insert a value stored in a subset of the bits of a word

Useful Bit Patterns: (1 << k) = 2 k (A single 1 shifted left k bits) LDR R 0, =(1<<4)

Useful Bit Patterns: ~(1 << k) = ~2 k (A single 0 shifted left k bits) LDR R 0, =~(1<<4)

Useful Bit Patterns: (1 << k)-1 = 2 k-1 (A string of k 1’s, preceded by all 0's) LDR R 0, =(1<<6)-1 Six 1’s

Useful Bit Patterns: -(1 << k) = -2 k (A string of 1’s, followed by k 0's) LDR R 0, =-(1<<6) Six 0's

Chapter 7 Manipulating Bits Part 2: Shift Instructions

APPLICATIONS OF SHIFTING Multiplication by 2 k: 2 k×A = A << k Division by 2 k: A÷ 2 k = A >> k (sort of) Subscript Scaling: &a 32[k] = &a 32[0] + 4×k Creating Multiples: 7×A = 8×A - 1×A

SHIFT INSTRUCTIONS Instruction Syntax Operation Flags Notes Logical Shift Left LSL{S} Rd, Rn, bits Rd Rn << bits N, Z, C Zero fills Logical Shift Right LSR{S} Rd, Rn, bits Rd Rn >> bits N, Z, C Zero fills Arithmetic Shift ASR{S} Right Rd, Rn, bits Rd Rn >> bits N, Z, C Sign extends Rotate Right ROR{S} Rd, Rn, bits Rd Rn >> bits N, Z, C right rotate Right w/Extend RRX{S} Rd, Rn N, Z, C Rd Rn >> 1 source The only difference is what is used to fill the left-most bit position. Append "S" to capture the last bit shifted out in the carry (C) flag. right shift, fill w/C C C 0 0 destination

3 PLACES WHERE SHIFT CAN BE USED ROR R 0, R 1, R 2 // R 0 R 1 rotated right R 2 times 1. As a regular shift instruction. ADD R 0, R 1, R 2, LSR 3 The only context in which the shift count may be a variable (e. g. , R 2 here). // R 0 R 1 + (R 2 >> 3) 2. To provide a pre-shifted copy of the value in a register as the last operand of an instruction. STR R 0, [R 1, R 2, LSL 2] // R 0 mem 32[R 1+4×R 2] 3. To multiply a subscript (R 2) by the # of bytes per element in a subscripted array reference. Only a Logical Shift Left (LSL) by 1, 2 or 3 bits may be used in this context.

Constants Dependent on Sign of R 0 Instruction Sequence Result left in R 1: When R 0 < 0 When R 0 ≥ 0 LSR R 1, R 0, 31 +1 0 ASR R 1, R 0, 31 -1 0 MVN R 1, R 0, ASR 31 0 -1 MVN R 1, R 0, LSR 31 -2 -1 LSR LSL R 1, R 0, 31 R 1, k +2 k 0 ASR LSL R 1, R 0, 31 R 1, k -2 k 0 ASR LSR R 1, R 0, k-1 R 1, 32 -k +2 k-1 0

DIVIDING BY ARITHMETIC RIGHT SHIFT Positive & Even: +2410 Positive & Odd: +2510 Negative & Even: -2410 Negative & Odd: -2510 = 000110002 ? ASR (+24)÷ 2 = 00011000 >> 1 = 00001100 = +1210 = 000110012 ? ASR (+25)÷ 2 = 00011001 >> 1 = 00001100 = +1210 = 111010002 ? ASR (-24)÷ 2 = 11101000 >> 1 = 11110100 = -1210 = 111001112 ? ASR (-25)÷ 2 = 11100111 >> 1 = 11110011 = -1310

PRE-SHIFT ADJUSTMENT Operand Original operation Adjusted Dividend Binary Operand ASR Result (Binary) ASR Result (Decimal) Positive & even +10 ÷ 2 +10 00001010 00000101 +5 Positive & odd +11 ÷ 2 +11 00001011 00000101 +5 Negative & even – 10 ÷ 2 – 9 11110111 11111011 – 5 Negative & odd – 11 ÷ 2 – 10 11110110 11111011 – 5 Divide by 2: Add 1 to negative dividends before the 1 -bit arithmetic shift right.

Chapter 7 Manipulating Bits Part 3: 64 -bit Shifts

64 -BIT LOGICAL SHIFT LEFT (By 1 bit) // uint 64_t LSL 64 x 1(uint 64_t dword 64) LSL 64 x 1: LSLS ADC BX R 0, 1 R 1, R 1 LR // Shift LS 32 bits left by 1, capture C // Shift MS 32 bits left by 1, add C // Return R 1 R 0 C b 63 • • • b 32 b 31 • • • b 0 ? LSLS R 0, 1 b 63 • • • b 32 b 30 • • • b 00 b 31 ADC R 1, R 1 b 62 • • • b 31 b 30 • • • b 00 b 31

64 -BIT LOGICAL SHIFT LEFT (by k bits, where k is a constant) R 1 R 0 b 63 • • • b 32 b 31 • • • b 0 LSL R 1, 2 b 61 • • • b 3200 b 31 • • • b 0 ADD R 1, R 0, LSR 30 b 61 • • • b 31 b 30 b 31 • • • b 0 LSL R 0, 2 b 61 • • • b 30 b 29 • • • b 100 To shift by k bits (k = constant), change the constants to k, 32 -k, and k respectively.

64 -BIT ROTATE LEFT (By 1 bit) // uint 64_t ROL 64 x 1(uint 64_t dword 64) ROL 64 x 1: ADDS ADC BX R 0, R 0 R 1, R 1 R 0, 0 LR // // Shift LS 32 bits left by 1, capture C Shift MS 32 bits left by 1, add C Add carry into bit position 0 Return R 1 R 0 C b 63 • • • b 32 b 31 • • • b 0 ? ADDS R 0, R 0 b 63 • • • b 32 b 30 • • • b 00 b 31 ADCS R 1, R 1 b 62 • • • b 31 b 30 • • • b 00 b 63 ADC R 0, 0 b 62 • • • b 31 b 30 • • • b 0 b 63

Chapter 7 Manipulating Bits Part 4: Bitwise Operations

Review: Bitwise Operators a= a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0 b= b 7 b 6 b 5 b 4 b 3 b 2 b 1 b 0 result = c 7 c 6 c 5 c 4 c 3 c 2 c 1 c 0 Each bit position of the result depends only on bits in the same position within the operands.

Bitwise AND a=0 a=1 a 0 0 1 1 b 0 1 a AND b 0 0 0 1 Use bitwise AND to clear a single bit to 0 b 3 b 2 b 1 b 0 & 1 0 1 1 b 3 0 b 1 b 0 bits & ~(1 << 2) 0 b a b If a=0, output = 0 If a=1, output = b b 3 b 2 0 b 1 b 0 1 0 1 1 a 3 a 2 a 1 a 0

Bitwise AND a=0 a=1 a 0 0 1 1 b 0 1 a AND b 0 0 0 1 0 bits & (1 << 2) a b Use bitwise AND to isolate/test a single bit b 3 b 2 b 1 b 0 & 0 1 0 0 0 b 2 0 0 b If a=0, output = 0 If a=1, output = b b 3 0 b 2 b 1 0 b 0 0 0 1 0 0 a 3 a 2 a 1 a 0

Bitwise OR a=0 a=1 a 0 0 1 1 b 0 1 a OR b 0 1 1 1 Use bitwise OR to set a single bit to 1 b 3 b 2 b 1 b 0 | 0 1 0 0 b 3 1 b 0 bits | (1 << 2) b b a 1 If a=0, output = b If a=1, output = 1 b 3 b 2 1 b 1 b 0 0 1 0 0 a 3 a 2 a 1 a 0

Bitwise Exclusive-OR a=0 a=1 a 0 0 1 1 b 0 1 a XOR b 0 1 1 0 b b a b Use bitwise XOR to change a single bit b 3 b 2 b 1 b 0 ^ 0 1 0 0 b 3 b 2 b 1 b 0 b 1 bits ^ (1 << 2) If a=0, output = b If a=1, output = b b 3 b 2 b 1 b 0 0 1 0 0 a 3 a 2 a 1 a 0

BITWISE INSTRUCTIONS Instruction Syntax Operation Flags Bitwise AND{S} Rd, Rn, Op 2 Rd Rn & Op 2 N, Z, C Bit Clear BIC{S} Rd Rn & ~Op 2 N, Z, C Bitwise OR ORR{S} Rd, Rn, Op 2 Rd Rn | Op 2 N, Z, C Exclusive OR EOR{S} Rd, Rn, Op 2 Rd Rn ^ Op 2 N, Z, C Bitwise OR NOT ORN{S} Rd, Rn, Op 2 Rd Rn | ~Op 2 N, Z, C Move NOT MVN{S} Rd, Rn Rd ~Rn N, Z, C AND BIC ORR EOR R 0, 1 << 5 R 0, ~(1 << 5) R 0, 1 << 5 R 0, 1 << 5 Rd, Rn, Op 2 // Isolate bit #5 // Clear bit #5 to 0 // Set bit #5 to a 1 // Change the value of bit #5 bb 77 bb 66 bb 55 bb 44 bb 33 bb 22 bb 11 bb 00 00 1 11 0 00 1 00 1 bb 077 bb 066 b 1 b 044 bb 033 bb 022 bb 011 bb 000 055 bb

USING BITWISE INSTRUCTIONS • Set a bit to 1 without affecting other bits: X |= (1 << 5) ; • Clear a bit to 0 without affecting other bits: X &= ~(1 << 5) ; • Change a bit without affecting other bits. X ^= (1 << 5) ; LDR ORR STR R 1, =x R 0, [R 1] R 0, 1<<5 R 0, [R 1] LDR BIC STR R 1, =x R 0, [R 1] R 0, 1<<5 R 0, [R 1] LDR EOR STR R 1, =x R 0, [R 1] R 0, 1<<5 R 0, [R 1]

USING C BITWISE OPERATIONS • Test the value of a single bit in a word if ((word & (1 << 5)) != 0) … • Calculate remainder n%d when n≥ 0 and d= 2 k rem = n % 16 rem = n & 0 x. F • Determine if an integer is an odd number (a % 2) == 1 (a & 1) != 0 • Determine if an integer is divisible by 2 k (a % 8) == 0 (a & 0 x 7) == 0 Calculating % takes more ARM CPU instructions than calculating &.

Other Values Dependent on Sign of R 0 Instruction Sequence Result left in R 2: When R 0 < 0 When R 0 ≥ 0 ADD R 2, R 1, R 0, LSR 31 R 1 + 1 R 1 SUB R 2, R 1, R 0, LSR 31 R 1 – 1 RSB R 2, R 1, R 0, LSR 31 1 – R 1 AND R 2, R 1, R 0, ASR 31 R 1 0 BIC R 2, R 1, R 0, ASR 31 0 R 1 ORR R 2, R 1, R 0, ASR 31 ORN R 2, R 1, R 0, ASR 31 R 1 EOR R 2, R 1, R 0, ASR 31 ~R 1 R 1

Chapter 7 Manipulating Bits Part 5: Bitfields

Trading Execution Time for Memory • 31 20 19 0

Structure Bitfields 3 1 2 5 age struct { unsigned unsigned } packed ; 2 4 2 2 2 1 unused gender siblings hair eyes weight ethnicity age : 1; : 4; : 2; : 9; : 4; : 3; : 7; packed. eyes = color_code ; 1 8 ethnicity 1 7 9 weight 8 7 eyes // 0 = male, 1 = female // 0 -15 // 0=black, 1=brown, etc. // 0=brown, 1=blue, 2=green // 0 -511 // 0=Caucasian, 1=Asian, etc… // unused LDR // 0 -127 LDR AND ORR STR 6 5 hair 4 1 siblings R 2, =packed R 0, [R 2] R 0, ~(0 b 11 << 7) R 1, =color_code R 1, [R 1] R 1, 0 b 11 R 0, R 1, LSL 7 R 0, [R 2] 0

Extracting Unsigned Bitfields (Using LSL and LSR) R 0 LSL 2 2 4 3 R 1, R 0, 8 3 1 width = 9 1 1 5 4 0 lsb = 15 32 – (lsb + width) = 8 R 1 LSR 3 1 2 2 3 2 8 7 0 0 0 0 0 32 – len = 23 R 1, 23 R 1 3 1 9 8 0 0 0 0 0 0 unsigned zero-extension (all 0’s) Extracted bit-field

Extracting Signed Bitfields (Using LSL and ASR) 3 1 R 0 LSL R 1, R 0, 8 1 1 5 4 0 s 32 – (lsb + width) = 8 3 1 R 1 ASR width = 9 2 2 4 3 lsb = 15 sign bit 2 2 3 2 8 7 s 0 0 0 0 0 32 – len = 23 R 1, 23 3 1 R 1 s 9 8 s s s s s 2’s complement sign-extension s s 0 s Extracted bit-field

Extracting Unsigned Bitfields (Using the UBFX instruction) 3 1 2 2 4 3 width = 9 1 1 5 4 0 R 0 lsb = 15 UBFX R 1, R 0, 15, 9 3 1 R 1 9 8 0 0 0 0 0 0 unsigned zero-extension (all 0’s) Extracted bit-field

Extracting Signed Bitfields (Using the SBFX instruction) 3 1 width = 9 2 2 4 3 R 0 1 1 5 4 0 s lsb = 15 sign bit SBFX R 1, R 0, 15, 9 3 1 R 1 s 9 8 s s s s s 2’s complement sign-extension s s 0 s Extracted bit-field

Inserting Bitfield from R 0 into R 1 (Using AND, LSL, LSR and ORR) 3 1 R 0 9 8 23 bits source 3 1 R 1 0 2 2 4 3 1 1 5 4 do not change destination 0 do not change 8 bits // Clear the destination field of R 0 to all 0’s: 3 2 2 LDR R 2, =0 x. FF 007 FFF 1 4 3 AND R 1, R 2 0 unchanged R 1 1 1 5 4 0 0 0 0 // Align a copy of source in R 2; fill the rest with 0’s: 3 2 2 LSL R 2, R 0, 23 1 4 3 LSR R 2, 8 0000 source R 2 // Insert source from R 2 into destination (R 1): 3 2 2 ORR R 1, R 2 1 4 3 R 1 unchanged 0 unchanged 1 1 5 4 0 00000000 1 1 5 4 source 0 unchanged

Inserting Bitfield from R 0 into R 1 (Using the BFI instruction) width = 9 3 1 9 8 0 R 0 BFI R 1, R 0, 15, 9 lsb = 15 3 1 2 2 4 3 1 1 5 4 R 1 width = 9 0

BITFIELD INSTRUCTIONS & APPLICATIONS Instruction Syntax Operation Notes Bit Field Clear BFC Rd, lsb, width Bit Field Insert BFI Rd, Rn, lsb, width Rd<bits> Rn<lsb’s> Signed Bit Field Extract SBFX Rd, Rn, lsb, width Rd Rn<bits> Sign extends Unsigned Bit Field Extract UBFX Rd, Rn, lsb, width Rd Rn<bits> Zero extends Rd<bits> 0 Extract an unsigned bitfield member a structure Clear Extract Insert aabitfield signed structure member bitfield member into member a structure from to allfrom a 0’s structure uint 32_t count = =s. number s. age = =210 ; ; int 32_t s. total balance s. total ; ; The lsb and width parameters must be constants.

Chapter 7 Manipulating Bits Part 6: Programming Tricks

Register Swap Using Exclusive-OR (Uses 1 less register and no additional instructions) // Standard method // (requires 3 rd register) // Exclusive-OR method // No extra registers needed MOV MOV EOR EOR R 2, R 0, R 1, R 2 R 0, R 1, R 0, R 1 Exclusive-OR is 1 wherever the bits are different R 0 1011 R 1 0011 1000 1011 0011

Selection Without a Branch Consider Bitwise OR when at least one input is 0: When a=0, output = b a 0 0 1 1 b 0 1 a OR b 0 1 1 1 When b=0, output = a // Selection: R 5 = (R 0 < 0) ? R 1 : R 2 AND BIC ORR R 3, R 1, R 0, ASR 31 // R 3 = (R 0 < 0) ? R 1 : 0 R 4, R 2, R 0, ASR 31 // R 4 = (R 0 < 0) ? 0 : R 2 R 5, R 3, R 4 // One of R 3 or R 4 will be all 0’s

A Fast Absolute Value Function a=0 a=1 a 0 0 1 1 b 0 1 a XOR b 0 1 1 0 b b Recall that exclusive OR can be used to pass an operand through unmodified or inverted // uint 32_t Abs. Value(int 32_t s 32) Abs. Value: EOR R 1, R 0, ASR 31 ADD R 0, R 1, R 0, LSR 31 BX LR 1 if s 32 < 0 0 if s 32 ≥ 0 All 1’s if s 32 < 0 All 0’s if s 32 ≥ 0 // s 32 < 0: else: // R 1 = ~s 32 R 1 = s 32 // R 0 = ~s 32 + 1 R 0 = s 32 + 0 // Return Fast! Avoids using making a compare and branch so that the instruction pipeline never stalls.

An Integer Power Function uint 32_t ipow(uint 32_t x, uint 32_t n) { uint 32_t result ; result = 1 ; while (n != 0) { if (n & 1) result *= x ; n >>= 1 ; x *= x ; // x 1, x 2, x 4, x 8, x 16, etc. } return result ; } // R 0=x, R 1=n, R 2=result ipow: LDR loop: CBZ LSRS IT MULCS MUL B done: MOV BX R 2, =1 R 1, done R 1, 1 CS R 2, R 0, R 0 loop R 0, R 2 LR

More Bit-Manipulation Tricks: http: //graphics. stanford. edu/~seander/bithacks. html

Chapter 7 Manipulating Bits Part 7: Bit-Banding

APPLICATIONS OF BIT-BANDING Fast access to individual bits in memory or I/O • Only 1 instruction required to access a single bit • No bitwise-AND, bitwise-OR, or shifting required "Atomic" access to manage a "mutex". • Atomic: An atomic operation completes without preemption / interruption. • Mutex: Used in operating systems, networking and multi-threaded software to arbitrate access to a shared resource.

64 MB of R/W Address Space 1 word 1 bit 32 MB Bit-Band Alias 22000000 -23 FFFFFF 16 64 MB of I/O Address Space BIT-BAND REGIONS & ALIASES 32 MB Bit-Band Alias 42000000 -43 FFFFFF 16 1 word Each individual bit in a bit-band 31 MB of RAM region corresponds to an entire 31 MB of I/O 20100000 -21 FFFFFF 16 word in its bit-band alias. 40100000 -41 FFFFFF 16 1 MB Bit-Band Region 20000000 -200 FFFFF 16 1 MB Bit-Band Region 40000000 -400 FFFFF 16 1 bit

BIT-BAND MAPPING 7 6 5 4 3 2 1 0 A byte in the "bit-band region" 200016 1 0 1 1 0 0 1 0 … 2202001 C 16 00000000 00000001 2202001816 00000000 2202001416 00000000 00000001 2202001016 00000000 00000001 2202000 C 16 00000000 2202000816 00000000 2202000416 00000000 00000001 2202000016 00000000 Corresponding 32 -bit word(s) in the "bit-band alias region”

FINDING THE ALIAS ADDRESS Bit-Band Alias address = 2200000016 + 32 × Bit-Band Region offset + 4 × bit number 3 1 2 5 2 4 5 4 2 1 0 0 0 10 0 0 0 1 0 0 0 0 1 10 0 7 6 5 4 3 2 1 0 Example: Access bit 3 in 200016 Bit-Band Region offset = 200016 – 2000000016 = 0100016 Bit-Band Alias address = 2200000016 + 3210 × 0100016 + 4 × 3 Starting address of = 2200000016 + (0100016 << 5) + (3 << 2) Bit-Band Region = 2202000 C 16 Read or write to this address accesses bit 3 at address 200016

BIT-BAND FUNCTION // uint 32_t *Bit. Band. Alias. Address(void *Bit. Band. Adrs, int Bit. Num) ; // Bit. Band. Adrs: The address of data in the bit band region // Bit. Num: The number (0 -31) of the bit within the data. global Bit. Band. Alias. Address. align. thumb_func Bit. Band. Alias. Address: SUB R 0, 0 x 20000000 LSL R 0, 5 ADD R 0, R 1, LSL 2 ADD R 0, 0 x 22000000 BX LR. end // // compute bit band offset insert offset into alias address add 4 times the bit number (0 -31) add base adrs of alias region
- Slides: 49