Certain behaviors are CPU model-specific. One example is floating point rounding/approximation functions: https://www.felixcloutier.com/x86/rsqrtss
The semantics are vagueposted:
DEST[31:0] := APPROXIMATE(1/SQRT(SRC2[31:0]))
DEST[MAXVL-1:32] (Unmodified)
Currently it's implemented like this:
template <typename D, typename S1, typename S2>
DEF_SEM(RSQRTSS, D dst, S1 src1, S2 src2) {
// Extract a "single-precision" (32-bit) float from [31:0] of src2 vector:
auto src_float = FExtractV32(FReadV32(src2), 0);
// Initialize dest vector, while also copying src1[127:32] -> dst[127:32].
auto temp_vec = FReadV32(src1);
// Store the square root result in dest[31:0]:
auto square_root = SquareRoot32(memory, state, src_float);
temp_vec = FInsertV32(temp_vec, 0, FDiv(1.0f, square_root));
// Write out the result and return memory state:
FWriteV32(dst, temp_vec); // SSE: Writes to XMM, AVX: Zero-extends XMM.
return memory;
}
But this isn't strictly correct and doesn't match on the bit-level. Ghidra implements this as a pcodeop:
define pcodeop rsqrtss;
:RSQRTSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x52; XmmReg ... & m32 { XmmReg = rsqrtss(XmmReg, m32); }
:RSQRTSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x52; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = rsqrtss(XmmReg1, XmmReg2); }
Should we do the same and use an intrinsic for things like this? There is a similar issue with undefined flags, which you might want to implement in different ways depending on the CPU the software runs on which would require a 'similar' intrinsic. Just opening this for discussion.
Certain behaviors are CPU model-specific. One example is floating point rounding/approximation functions: https://www.felixcloutier.com/x86/rsqrtss
The semantics are vagueposted:
Currently it's implemented like this:
But this isn't strictly correct and doesn't match on the bit-level. Ghidra implements this as a
pcodeop:Should we do the same and use an intrinsic for things like this? There is a similar issue with undefined flags, which you might want to implement in different ways depending on the CPU the software runs on which would require a 'similar' intrinsic. Just opening this for discussion.