Let your assembler encode the shift / rotate for you, by giving it the 0x00110000
value.
Most assemblers (including all ARM assemblers?) support assemble-time constant expressions so you can write
mov r1, #0x11 << 16
This will assemble in ARM mode to 11 18 a0 e3
. But in Thumb mode it requires ARMv6 Thumb2. See http://www.keil.com/support/man/docs/armasm/armasm_dom1361289878994.htm for the available forms of MOV.
Probably a better choice is and LDR pseudo-instruction that lets the assembler pick between a PC-relative load (from a literal pool) or a mov-immediate with some encoding. http://www.keil.com/support/man/docs/armasm/armasm_dom1359731145835.htm (That's keil's doc for their assembler, but GAS and clang also support the same syntax.)
ldr r1, =0x11 << 16
I'm working with several devices
Consider rebuilding for each device so you can make code optimized for each one. Especially if you use ldr reg, =value
- it can use mov.w reg, #imm16
when available.
and some of them allow immediate values up to 32 bits
If you're talking about ARMv6T2 movt
/ movw
, that's two 32-bit instructions each providing a 16-bit half.
No ARM is capable of encoding any arbitrary 32-bit constant with a single instruction; that would leave no bits for an opcode in a 32-bit instruction.
mov r1, #0x11 << 16
assembles fine; use that. I think Thumb2 mode allows a rotated 8-bit immediate, and your assembler knows how to encode any encodeable immediate. – Peter Cordesldr r1, =0x00110000
and let the assembler sort it out. – Jester