Working on individual bits
Flags, permissions, colours, network headers — lots of data is packed into bits. A bitmask picks bits out: andi t1, a0, 1 keeps only the lowest bit; shifts move bits left (×2) or right (÷2).
Two classic tricks
# popcount(a0) -> how many bits are 1 popcount: li t0, 0 pc_loop: beqz a0, pc_done andi t1, a0, 1 # the lowest bit add t0, t0, t1 srli a0, a0, 1 # logical shift: zeros come in from the left j pc_loop pc_done: mv a0, t0 ret # is_pow2(a0) -> 1 if a0 is a power of two, else 0 is_pow2: beqz a0, no addi t0, a0, -1 # 1000 - 1 = 0111 and t0, t0, a0 # a power of two shares no bits with itself - 1 seqz a0, t0 ret no: li a0, 0 ret