Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no ICMP instruction?

As some of you might know, we have a ton of opcodes for comparing different types of primitive values:

LCMP
FCMPL
FCMPG
DCMPL
DCMPG
IFEQ
IFNE
IFLT
IFGE
IFGT
IFLE
IF_ICMPEQ
IF_ICMPNE
IF_ICMPLT
IF_ICMPGE
IF_ICMPGT
IF_ICMPLE
IF_ACMPEQ
IF_ACMPNE
...

For obvious reasons the creators of the instruction set did not bother to add all IF_LCMPEQ, IF_FCMPLT, ... instructions, but I am wondering why there is no ICMP instruction, seeing that it would be very useful especially for booleans or Integer.compare(int, int).

like image 978
Clashsoft Avatar asked Mar 18 '15 19:03

Clashsoft


1 Answers

There are already two "primarily opinion based" close votes. Indeed, nobody can give a definite answer here, and there may be some handwaving involved when trying to argue about a decision that a bunch of engineers made 25 years ago. But I'll give it a try...

First of all, I think that the question is justified: The int type is the most "prominent" type in the Java Language (last but not least because of its role as an array index). This goes hand in hand with its special role in the Java Virtual Machine, where all (smaller) integral types that are present in the language, like byte or short, are effectively converted into int for all computations. Or, as mentioned in the Java Virtual Machine Specification, Section 2.11.7:

Because of its emphasis on int comparisons, the Java Virtual Machine provides a rich complement of conditional branch instructions for type int.

Now it is reasonable to ask why this "rich complement" seems to exclude an instruction that is equivalently present for all other types.


The main reason why there is no icmp instruction may be that it is neither necessary, nor beneficial.

The suggested application case of using it for Integer#compare(int, int) can hardly count as an argument: The implementation of such a method (even if an icmp existed) would not be

return icmp, arg0, arg1;

The translation of a method into bytecode can be rather complex, and given the possibilities of the Java Language itself, such a method anyhow has to be implemented equivalently as

if (x > y) return 1;
if (x < y) return -1;
return 0;

which obviously is can be translated into a sequence of the existing if_icmp<?> instructions.

Here, one should keep in mind that the main purpose of these comparison instructions is branching: They cause a jump to a different location. They are not intended for pushing a value on the stack that could then be "used as a return value of a method". Talking about the language and talking about the virtual machine are two completely different things here.


One might also turn the question around, and ask: Why are there lcmp, fcmp_ and dcmp_ instructions available for long, float and double, respectively?

Here, a definite answer is far easier: Offering the whole set of eq, ne, lt, le, gt and ge comparision instructions for long, float and double would imply 18 additional instructions (or even more, with the NaN treatment for the floating point types). That's a lot, considering that there is a hard limit of 256 instructions that are possible with one byte.

By offering the lcmp, fcmp_ and dcmp_ instructions for these types, the remaining instructions that are available for int can be used to emulate all the other possible comparison situations. But again, these are mainly intended for branching, so there simply is no need for an icmp instruction, because for int, all necessary branching instructions ("jump conditions") are already available.

like image 170
Marco13 Avatar answered Oct 31 '22 12:10

Marco13