A displacement is an 8-, 16-, or 32-bit value.
LLVM integrated assembler silently encodes an out-of-range displacement.
GNU assembler checks the displacement and may report a warning or error
(error is for 64-bit addressing, done as part of
https://sourceware.org/PR10636).
```
movq 0x80000000(%rip), %rax
Error: 0x80000000 out of range of signed 32bit displacement
movq -0x080000001(%rax), %rax
Error: 0xffffffff7fffffff out of range of signed 32bit displacement
movl 0x100000001(%eax), %eax
Warning: 0x100000001 shortened to 0x1
```
For 32-bit addressing, GNU assembler gives no diagnostic when the
displacement is within `[-2**32,2**32)`. 16-bit addressing is similar.
```
movl 0xffffffff(%eax), %eax # no diagnostic
movl -0xffffffff(%eax), %eax # no diagnostic
```
Supporting a larger range is probably because wraparound using a large
constant is more reasonable. E.g. Linux kernel arch/x86/kernel/head_32.S
has `leal -__PAGE_OFFSET(%ecx),%esp` where `__PAGE_OFFSET` is
0xc0000000.
This patch implements a similar behavior.