Thursday 13 June 2019

c - Useless jp / jnp assembly instruction on x86_64



I'm trying to figure out what purpose jp/jnp instructions serve in LLVM-generated C code. Sample:




int main(int argc, const char * argv[]) {
double value = 1.5;

if (value == 1.5) {
value = 3.0;
}

return 0;
}



Assembly output:



Ltmp4:
movsd LCPI0_0(%rip), %xmm0
movl $0, -4(%rbp)
movl %edi, -8(%rbp)
movq %rsi, -16(%rbp)
Ltmp5:
movsd %xmm0, -24(%rbp)

Ltmp6:
movsd -24(%rbp), %xmm1
ucomisd %xmm0, %xmm1
jne LBB0_2
jp LBB0_2
## BB#1:
movabsq $3, %rax
cvtsi2sdq %rax, %xmm0
Ltmp7:
movsd %xmm0, -24(%rbp)

Ltmp8:
LBB0_2:
movl $0, %eax
popq %rbp
retq


The jne is checking if value != 1.5 and jumping over the assignment, but what is the jp doing in this context?


Answer



jne is jump if not equal, i.e. jump if the zero flag is not set. jp is jump if parity.




ucomisd is defined to compare two doubles. It will indicate that they are one of four things: unordered, equal, greater than or less than.



The zero flag is set if the numbers are unordered or equal. So the jne avoids the remaining cases of greater than or less than.



Parity is set only if the result is unordered. The jp catches that.



So the two together avoid: unordered, greater than, less than. Leaving only the fourth possibility, of equal.


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...