You likely won't get an exact reproduction because cvtdq2pd
takes the lower 64 bits of the second operand but since we're limited to 32 bits because we're using eax
here, there are probably better(?) instructions to use.
cvtsi2sd xmm0, eax
will do the same thing as
movd xmm0,eax
cvtdq2pd xmm0,xmm0
See here https://www.felixcloutier.com/x86/CVTDQ2PD.html & https://www.felixcloutier.com/x86/CVTSI2SD.html
So really what it's doing is converting a 32 bit signed integer value into a double precision floating point.
Onto your actual question:
cvtpd2ps xmm0,xmm0 ; double to packed?
CVTPD2PS xmm1, xmm2/m128
Convert two packed double-precision floating-point values in xmm2/mem to two single-precision floating-point values in xmm1.
This will pack the two double precision floats at xmm0[0:63]
& xmm0[64:127]
into the lower 64 bits of xmm0
, converting them from double to single precision floating point values (xmm0[0:31]
& xmm0[32:63]
).
Ref: https://www.felixcloutier.com/x86/CVTPD2PS.html
So if the lower 64 bits of xmm0
represented a double
, it's now been converted to a 32 bit float, which now sits in the lower 32 bits of xmm0
.
movss dword ptr ds:[ebx+0x34],xmm0
MOVSS xmm2/m32, xmm1
Move scalar single-precision floating-point value from xmm1 register to xmm2/m32.
Now stores the 4 byte result from xmm0[0:31]
into [ebx+0x34]
, which we know is a single precision float
from the result of the cvtpd2ps
operation.
So the result of this operation is a 32 bit float
.
Ref: https://www.felixcloutier.com/x86/MOVSS.html
This code here should be a reasonable approximation. In Godbolt it gives me similar assembly to what you have.
double* d_arr = (double*)0x4F6CC0;
int main() {
int in = 4;
int signbit = ((unsigned int)in >> 31);
float result = *(double*)(d_arr + signbit) + in;
return 0;
}
Conclusion:
cvtdq2pd
& cvtpd2ps
are too powerful for what's actually being calculated here. Unless I'm reading this totally wrong, the upper 64 bits of xmm0
are never relevant to the result.
Disclaimer:
I've never used floating point assembly before. I just looked up the docs now. I could be missing something.