fcvt.ud.d
LBT intrinsic · group: x86 FPU
Synopsis
Instruction: fcvt.ud.d fd, fj
CPU Flags: LBT
Description
Convert double-precision floating point value in fj to the upper 16 bits (sign and exponent) of x87 80-bit extended precision format, store in fd.
Operation
uint64_t d = a;
unsigned sign = (d >> 63) & 1;
unsigned exp_d = (d >> 52) & 0x7FF;
uint64_t man_d = d & 0x000FFFFFFFFFFFFFULL;
// Re-bias exponent from double (1023) to x87 extended (16383).
// Double uses an implied integer bit (J=1 for normal numbers).
// x87 extended uses an explicit integer bit.
int64_t exp_x87;
if (exp_d == 0x7FF) {
// Infinity or NaN: x87 exponent is also all-ones.
exp_x87 = 0x7FFF;
} else if (exp_d == 0 && man_d == 0) {
// Signed zero: x87 exponent 0, integer bit 0.
exp_x87 = 0;
} else if (exp_d == 0) {
// Denormal double: value = man_d * 2^(-1074).
// Normalize by finding leading bit position p (0-indexed from LSB).
// Resulting x87 exponent: (-1074 + p) biased by 16383.
int p = 63 - __builtin_clzll(man_d);
exp_x87 = -1074 + p + 16383;
} else {
// Normal double → normal x87 extended.
exp_x87 = (int64_t)exp_d - 1023 + 16383;
}
// 16 bits: sign[15] | exponent[14:0]
dst = ((uint64_t)sign << 15) | (exp_x87 & 0x7FFF);
Tested on real machine.
Latency and Throughput
| CPU | µarch | Latency | Throughput (IPC) |
|---|---|---|---|
| 3C5000 | LA464 | 2 | 2 |
| 3C6000 | LA664 | 2 | 2 |