Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.
This quote does not explain hexadecimal literals which behave more like this in FPC:
Every untyped hexadecimal literal smaller than 8 bytes is implicitly extended with zero-bits,
then interpreted as int64(bitpattern). And finally, the storage-size of the int64 value is reduced if possible.
In practice, most hex literals have implicit (byte7 = $00), thus they have a non-negative value.
The storage type can be signed or unsigned.
For hex literal $FFFFFFFFFFFFFFFF and other 64 bit-values with leading 1-bit:
Delphi prefers uint64, but also supports implicit cast (reinterpretation) to provided int64 targets.
But a simpler rule would be more consistent: For negative constants, explicit typecasting is sufficient also for 64 bit, analogously to explicit typecast (in FPC and Delphi) for assigning hex literals to signed targets which have less than 64 bits. Example:
someShortInt := $FF; // out-of-range (disallowed) in FPC/Delphi
someShortInt := shortint($FF); // -1 in FPC/Delphi
In Delphi is:
i64 := -1;
assert( i64 <> $FFFFFFFFFFFFFFFF);
assert( i64 = int64($FFFFFFFFFFFFFFFF));
In FPC is:
assert( i64 = $FFFFFFFFFFFFFFFF);