I just had a couple of utterly sick ideas.
Consider this variant (this example is for a 32-bit immediate on x86-64,
but the obvious macroizations apply):
.section __discard,"a",@progbits
1: movl $0x12345678,%r9d
2:
.previous
.section __immediate,"a",@progbits
.quad foo_immediate, (3f)-4, 4
.previous
.org . + ((-.-(2b-1b)) & 3), 0x90
movl $0x12345678,%r9d
3:
The idea is that the instruction is emitted into a section, which is
marked DISCARD in the linker script. That lets us actually measure the
length, and since we know the immediate is always at the end of the
instruction... done!
-hpa
-