In Nanojit, LIR is the source language for compilation to machine code. LIR stands for low-level intermediate representation.
The LIR instruction set
Types in LIR. Values in LIR have a type: either 32-bit or 64-bit. A 32-bit value, additionally, may be a condition or not. Each instruction requires operands of a specific type and produces a result of a specific type.
LIR makes no distinction at all between pointers and integers of the same size, between signed and unsigned integer values, or between 64-bit floating-point and 64-bit integer values. It is acceptable to load a 64-bit value from memory using
ldq and then use the result with a floating-point arithmetic operation such as
The names of the operands and results below indicate the types required by LIR. Names starting with i indicate 32-bit values. Results starting with b are 32-bit integers and additionally are conditions. Operand names starting with b must be conditions. Names starting with q or f indicate 64-bit values. f indicates that the operand is interpreted as a floating-point value, or that the result is a 64-bit float, but the distinction between f and q does not impose a type constraint on LIR code.
Operations that are weird but don't count as special
Allocate stack space, as though with the C standard library function
32-bit load. This instruction is never removed by common subexpression elimination.
8-bit load. This instruction may be removed by common subexpression elimination.
16-bit load. This instruction may be removed by common subexpression elimination.
32-bit load. This instruction may be removed by common subexpression elimination.
64-bit load. This instruction may be removed by common subexpression elimination.
Extend live range of reference.
Indirect subroutine call returning a 32-bit integer value.
Subroutine call returning a 32-bit integer value.
Indirect subroutine call returning a 64-bit value.
Subroutine call returning a 64-bit value.
Exit if true.
Exit if false.
Do not exit but emit writes to flush all values to the stack.
Jump if true.
Jump if false.
A jump target.
32-bit integer equality test.
result = eq i1, i2
There is no not-equal instruction. Instead, flip the instruction that uses the result, or add a
Signed 32-bit integer less-than test.
b = lt i1, i2
Signed 32-bit integer greater-than test.
b = gt i1, i2
Signed 32-bit integer less-than-or-equals test.
b = le i1, i2
Signed 32-bit integer greater-than-or-equals test.
b = ge i1, i2
Unsigned 32-bit integer less-than test.
b = ult i1, i2
Unsigned 32-bit integer greater-than test.
b = ugt i1, i2
Unsigned 32-bit integer less-than-or-equals test.
b = ule i1, i2
Unsigned 32-bit integer greater-than-or-equals test.
b = uge i1, i2
Floating-point equality test.
b = feq f1, f2
Floating-point less-than test.
b = flt f1, f2
Floating-point greater-than test.
b = fgt f1, f2
Floating-point less-than-or-equals test.
b = fle f1, f2
Floating-point greater-than-or-equals test.
b = fge f1, f2
An immediate 32-bit integer that fits in a signed 16-bit integer.
i = short <number>
<number> must be an integer that fits in the range of a signed 16-bit integer (-32768 to 32767). The result of a
short instruction is a 32-bit integer with the same value (sign-extended).
An immediate 32-bit integer.
i = int <number>
An immediate 64-bit value.
q = quad <number>
32-bit integer negation.
result = neg i1
32-bit integer addition.
result = add i1, i2
64-bit integer addition.
result = qiadd q1, q2
32-bit integer subtraction.
result = sub i1, i2
32-bit integer multiplication.
result = mul i1, i2
32-bit bitwise AND.
result = and i1, i2
64-bit bitwise AND.
result = qiand q1, q2
32-bit bitwise OR.
result = or i1, i2
64-bit bitwise OR.
result = qior q1, q2
32-bit bitwise XOR.
result = or i1, i2
32-bit bitwise NOT.
result = not i1
32-bit left shift.
result = lsh i1, i2
64-bit left shift.
result = qilsh q1, q2
32-bit right shift with sign extend.
result = rsh i1, i2
The two most significant bits of the result value are the same.
32-bit unsigned right shift.
result = ush i1, i2
The most significant bit of the result value is 0.
result = ov i1
result = cs i1
result = fneg f1
result = fadd f1, f2
result = fsub f1, f2
result = mul f1, f2
f = div f1, f2
Get the low 32 bits of a 64-bit value.
i = qlo q
Get the high 32 bits of a 64-bit value.
i = qhi q
Join two 32-bit values to form a 64-bit value.
q = qjoin i1, i2
Convert signed 32-bit integer to floating-point number.
f = i2f i1
Convert unsigned 32-bit integer to floating-point number.
f = u2f i1