It's not a Bug! It's a tricky float handling!
now I think I analysed it completely. It's a little bit hard because C is doing some crazy things.
The result:
C - internaly converts the Integer to Float an store it in memory or a xmm register. But in 64-Bit Float notation.
As next C removes the sing Bit from the Float with
andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
now for Integers, the value (what is a float) ist pushed on the Floating Stack with FLD command
next command is FISTP what converts back to integer and store in memory.
That's completely correct but it is done with 64-Bit notation of floats
At ASM Backend
fild value ; loads the integer into
80Bit Floating-Point
fabs ; abs of a 80 Bit floating point
fistp ; convert back from 80Bit floating point to integer
There is no Bug, but a different floating point notation
here the complete analyse (added C-Code Output 2024/01/05)
Code: Select all
s.s ="123" ; just to find start of the code
xd.d = -7
yd.d = Abs(xd)
xf.f = -7
yf.f = Abs(xf)
xi.i = -7
yi.i = Abs(xi)
xl.l = -7
yl.l = Abs(xl)
MessageRequester("Result", "Abs() = " + yd)
; ----------------------------------------------
; C-Code Output
; ----------------------------------------------
// xd.d = -7
v_xd=-7.0;
// yd.d = Abs(xd)
double r5=PB_Abs_DOUBLE(v_xd);
v_yd=r5;
// xf.f = -7
v_xf=-7.0;
// yf.f = Abs(xf)
double r6=PB_Abs_DOUBLE(v_xf);
v_yf=r6;
// xi.i = -7
v_xi=-7;
// yi.i = Abs(xi)
double r7=PB_Abs_DOUBLE(v_xi);
v_yi=SYS_BankerRoundQuad(r7);
// xl.l = -7
v_xl=-7;
// yl.l = Abs(xl)
double r8=PB_Abs_DOUBLE(v_xl);
v_yl=SYS_BankerRound(r8);
; ----------------------------------------------
; ASM Backend - IDA disassembley
; ----------------------------------------------
; the x.d Version
fld cs:dbl_140005050
fstp cs:dbl_140005578
fld cs:dbl_140005578
fabs
fstp cs:dbl_140005588
; the x.f Version
mov cs:dword_140005598, 0C0E00000h
fld cs:dword_140005598
fabs
fstp cs:flt_1400055A0
; the x.i Version
mov cs:qword_140005580, 0FFFFFFFFFFFFFFF9h
fild cs:qword_140005580
fabs
fistp cs:qword_140005590
; the x.l Version
mov cs:dword_14000559C, 0FFFFFFF9h
fild cs:dword_14000559C
fabs
push rax
fistp [rsp+30h+var_30]
pop rax
mov cs:dword_1400055A4, eax
; ----------------------------------------------
; C Backend - IDA disassembley
; ----------------------------------------------
; the x.d Version
; the C-Compiler moves the -7 float to xmm6 register to reuse it later
movsd xmm6, cs:qword_140003170 ; 0C01C000000000000h ; -7 double
;now it saves the xmm6 Register.But this has now function for the ABS
movsd cs:qword_1400057A0, xmm6
;here starts the ABS()
movapd xmm0, xmm6
call sub_140001CB0 ; andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
movsd cs:qword_140005780, xmm0
; the x.f Version
; store a value in Memory, maybe the -7 as single
mov cs:dword_140005798, 0C0E00000h
; get back the -7 from xmm6 Register
movapd xmm0, xmm6
call sub_140001CB0 ; andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
cvtsd2ss xmm0, xmm0
movss cs:dword_140005778, xmm0
; the x.i Version
; store -7 quad in memory
mov cs:qword_140005790, 0FFFFFFFFFFFFFFF9h
: but after reuse -7 double from xmm6
movapd xmm0, xmm6
call sub_140001CB0 ; andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
movsd [rsp+48h+var_28], xmm0
fld [rsp+48h+var_28]
fistp [rsp+48h+var_20]
mov rax, [rsp+48h+var_20]
mov cs:qword_140005770, rax
; the x.l Version
mov cs:dword_140005788, 0FFFFFFF9h ; = -7 Long notation
movapd xmm0, xmm6
call sub_140001CB0 andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
movsd [rsp+48h+var_28], xmm0
fld [rsp+48h+var_28]
fistp [rsp+48h+var_20]
mov rax, [rsp+48h+var_20]
mov cs:dword_140005768, eax
; the sub to remove the sign bit
sub_140001CB0 proc near
andps xmm0, 7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFh
retn
sub_140001CB0 endp