Hi all,

I'm writing a routine to multiply signed 64 bit integers with catching overflow. Here's my code

.code

mult proc

; rcx == __int64 a

; rdx == __int64 b

; r8 == __int64 *lret

; r9 == double *dret

xorpd xmm0,xmm0

xorpd xmm1,xmm1

xor rax,rax

cvtsi2sd xmm0,rcx

cvtsi2sd xmm1,rdx

mulsd xmm0,xmm1

neg_chk:

xorpd xmm1,xmm1

xor r10,r10

cvtsi2sd xmm1,r10

comisd xmm0,xmm1

jb neg_int

jae pos_int

pos_int:

xorpd xmm1,xmm1

mov r10,9223372036854775807

cvtsi2sd xmm1,r10

comisd xmm0,xmm1

jbe dbl_as_int

ja as_dbl

neg_int:

xorpd xmm1,xmm1

mov r10,-9223372036854775808

cvtsi2sd xmm1,r10

comisd xmm0,xmm1

jae dbl_as_int

jb as_dbl

as_dbl:

movsd qword ptr[r9],xmm0

mov rax,1

jmp done

dbl_as_int:

cvttsd2si r10,xmm0

mov qword ptr[r8],r10

xor rax,rax

jmp done

done:

ret

mult endp

end

The corresponding signature I use in C

__int8 mult(__int64 a, __int64 b, __int64 *lval, double *dval);

This code works fine until it meets values a=2147452546 b=2147514748, in that case it delivers 4611686013165148160 instead of 4611686013165148408 . I'm just wondering what could possibly be going wrong? This seems to be an issue with the 128 bit arithmetics or conversion to 64 bit. Say, writing

`push rdx`

imul rdx,rcx

delivers correct. So wondering, how such an error can remotely happen with values of even bigger bitness? And, maybe there's a way to check this kind of thing through flags?

Thanks.