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 and q indicate the same type as far as LIR is concerned, but f is used here for floating-point operations.) Operand names starting with p must be pointer-sized integers. That is, they must be 64 bits on a 64-bit platform and 32 bits otherwise.
Operations that are weird but don't count as special
Allocate stack space, as though with the C standard library function
Extend live range of reference.
Loads and stores
st p1[offset] = i2
stq p1[offset] = q2
sti p1[offset] = i2
stqi p1[offset] = q2
32-bit load. This instruction is never removed by common subexpression elimination.
i = ld p1[p2]
64-bit load. This instruction is never removed by common subexpression elimination.
q = ldq p1[offset]
8-bit load. This instruction may be removed by common subexpression elimination.
i = ldcb p1[offset]
16-bit load. This instruction may be removed by common subexpression elimination.
i = ldcs p1[offset]
32-bit load. This instruction may be removed by common subexpression elimination.
i = ldc p1[offset]
64-bit load. This instruction may be removed by common subexpression elimination.
q = ldqc p1[offset]
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.
i = neg i1
32-bit integer addition.
i = add i1, i2
64-bit integer addition.
q = qiadd q1, q2
32-bit integer subtraction.
i = sub i1, i2
32-bit integer multiplication.
i = mul i1, i2
32-bit bitwise AND.
i = and i1, i2
64-bit bitwise AND.
q = qiand q1, q2
32-bit bitwise OR.
i = or i1, i2
64-bit bitwise OR.
q = qior q1, q2
32-bit bitwise XOR.
i = or i1, i2
32-bit bitwise NOT.
i = not i1
32-bit left shift.
i = lsh i1, i2
64-bit left shift.
q = qilsh q1, q2
32-bit right shift with sign extend.
i = rsh i1, i2
The two most significant bits of the result value are the same.
32-bit unsigned right shift.
i = 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