Bug report transferred from https://issues.dlang.org/show_bug.cgi?id=6459 :
Another negative immediate value issue:
mov EAX,-2; /* line 1 */
mov EAX,0xFFFFFFFE; /* line 2 */
mov EAX,0xFFFFFFFFFFFFFFFE; /* line 3 */
mov R8D,-2; /* line 4 */
mov R8D,0xFFFFFFFE; /* line 5 */
mov R8D,0xFFFFFFFFFFFFFFFE; /* line 6 */
Anybody writing line 3 or 6 has probably made a mistake, but line 3 is accepted as equivalent to 1 and 2, and line 6 is accepted as equivalent to 4 and 5 (as 32 bit loads clear the top 32 bits of the equivalent 64 bit register they do not sign extend).
Comment #1 by bugzilla — 2020-08-25T07:39:38Z
The problem is, being assembler code, there is no distinction between signed and unsigned values for immediate values. The instruction semantics determine if it is signed or unsigned.
The values are all computed as 64 bit integers.
Hence, -2 is indistinguishable from 0xFFFFFFFFFFFFFFFE. Whether it gets truncated or sign extended is determined by the instruction, there is no concept of a signed or unsigned immediate value.
It's working as designed.