I made some small changes to the IR and renamed the gte, lte and neq instructions as suggested today. If you do a checkout of my latest commit, doing a make run will show the updated mnemonics.
However, if I may, I would have a suggestion for the code generation. Instead of using mnemonics, we should probably "install" code generation functions on the instruction classes. For example:
AddInstr.prototype.genCode = function (...) { ... }
This will avoid relying on mnemonic names, and having redundant code for many variants of the same instruction. The code generation code can then find out the type of the operands by using this.uses[i].type, which refers to an IRType object. It can also find its own expected output type by using this.type.
Also, following todays discussion, I'm pondering whether or not I should have completely distinct HIR/MIR instructions. Right now, the add on boxed values, for example, has the semantic of a call to the add() primitive function (a JavaScript add), whereas the same add instruction on i64 values represents the machine word add instruction. The icast instructions are then needed if we want to directly perform a machine add on boxed values without doing any shifting, to indicate that we want to perform an integer add.
It would be possible to, instead, have HIRAdd and MIRAdd instructions. The HIRAdd instructions would then be translated either into a call or into an MIRAdd which would represent the machine instruction add, depending on the types of the input arguments supplied. This would make it possible to eliminate the cast instructions in this case, and directly perform an MIRAdd on boxed values. It would have the disadvantage that arithmetic, bitwise and comparison instruction classes would be duplicated for the two possible semantics, however.
- Maxime