Using shifts to clear bits has it's advantages. Mainly because to and something you need to load a value into a register and then and between two registers. Using bitshifts to cut off bits you don't care about is often simpler because it requires only one register.
Basically, as a consequence of the processor design there's no function for AND rX, Value, just AND rX, rY
Here's a summary of all the ALU operations from gbatek:
Code:
THUMB.4: ALU operations
Opcode Format
Bit Expl.
15-10 Must be 010000b for this type of instructions
9-6 Opcode (0-Fh)
0: AND Rd,Rs ;AND logical Rd = Rd AND Rs
1: EOR Rd,Rs ;XOR logical Rd = Rd XOR Rs
2: LSL Rd,Rs ;log. shift left Rd = Rd << (Rs AND 0FFh)
3: LSR Rd,Rs ;log. shift right Rd = Rd >> (Rs AND 0FFh)
4: ASR Rd,Rs ;arit shift right Rd = Rd SAR (Rs AND 0FFh)
5: ADC Rd,Rs ;add with carry Rd = Rd + Rs + Cy
6: SBC Rd,Rs ;sub with carry Rd = Rd - Rs - NOT Cy
7: ROR Rd,Rs ;rotate right Rd = Rd ROR (Rs AND 0FFh)
8: TST Rd,Rs ;test Void = Rd AND Rs
9: NEG Rd,Rs ;negate Rd = 0 - Rs
A: CMP Rd,Rs ;compare Void = Rd - Rs
B: CMN Rd,Rs ;neg.compare Void = Rd + Rs
C: ORR Rd,Rs ;OR logical Rd = Rd OR Rs
D: MUL Rd,Rs ;multiply Rd = Rd * Rs
E: BIC Rd,Rs ;bit clear Rd = Rd AND NOT Rs
F: MVN Rd,Rs ;not Rd = NOT Rs
5-3 Rs - Source Register (R0..R7)
2-0 Rd - Destination Register (R0..R7)
As you can see, they only work between two registers (with the exception of the NOT/NEG operations).