In Nanojit, LIR is the source language for compilation to machine code. LIR stands for low-level intermediate representation. It is a typed assembly language.
The LIR instruction set is best learnt by reading nanojit/LIRopcode.tbl. Code for manipulating LIR is in nanojit/LIR.h.
Nanojit LIR instruction cheat sheet.Also in pdf format see attachment.
Category | OP Code | Code Name | Return Type | Featured | Description |
Miscellaneous | 0 | start | void |
| start of a fragment |
1 | regfence | void |
| A register fence causes no code to be generated, but it affects register allocation so that no registers are live when it is reached. | |
2 | skip | void |
| links code chunks. | |
3 | parami | integer | 32 bit | load an int parameter (register or stack location). | |
4 | paramq | quad | 64 bit | load a quad parameter (register or stack location). | |
5 | allocp | pointer |
| allocate stack space (result is an address) | |
6 | reti | void |
| return an int | |
7 | retq | void | 64 bit | return a quad | |
8 | retd | void |
| return a double | |
9 | livei | void |
| extend live range of an int | |
10 | liveq | void | 64 bit | extend live range of a quad | |
11 | lived | void |
| extend live range of a double | |
12 | file | void |
| source filename for debug symbols | |
13 | line | void |
| source line number for debug symbols | |
14 | comment | void |
| a comment shown, on its own line, in LIR dumps | |
15 | not in use |
|
|
| |
Load | 16 | not in use |
|
|
|
17 | ldc2i | integer |
| load char and sign-extend to an int | |
18 | lds2i | integer |
| load short and sign-extend to an int | |
19 | lduc2ui | integer |
| load unsigned char and zero-extend to an unsigned int | |
20 | ldus2ui | integer |
| load unsigned short and zero-extend to an unsigned int | |
21 | ldi | integer |
| load int | |
22 | ldq | quad | 64 bit | load quad | |
23 | ldd | double |
| load double | |
24 | ldf2d | double |
| load float and extend to a double | |
Store | 25 | sti2c | void |
| store int truncated to char |
26 | sti2s | void |
| store int truncated to short | |
27 | sti | void |
| store int | |
28 | stq | void | 64 bit | store quad | |
29 | std | void |
| store double | |
30 | std2f | void |
| store double as a float (losing precision) | |
31 | not in use |
|
|
| |
Call | 32 | not in use |
|
|
|
33 | callv | void |
| call subroutine that returns void | |
34 | calli | integer |
| call subroutine that returns an int | |
35 | callq | quad | 64 bit | call subroutine that returns a quad | |
36 | calld | double |
| call subroutine that returns a double | |
Branch | 37 | j | void |
| jump always |
38 | jt | void |
| jump if true | |
39 | jf | void |
| jump if false | |
40 | jtbl | void |
| jump to address in table | |
41 | label | void |
| a jump target (no machine code is emitted for this) | |
42 | not in use |
|
|
| |
Guards | 43 | x | void |
| exit always |
44 | xt | void |
| exit if true | |
45 | xf | void |
| exit if false | |
46 | xtbl | void |
| exit via indirect jump | |
47 | xbarrier | void |
| A LIR_xbarrier cause no code to be generated, but it acts like a never-taken guard in that it inhibits certain optimisations, such as dead stack store elimination. | |
48 | not in use |
|
|
| |
Immediate | 49 | immi |
|
| int immediate |
50 | immq |
| 64 bit | quad immediate | |
51 | immd |
|
| double immediate | |
52 | not in use |
|
|
| |
Comparisons | 53 | eqi | integer |
| int equality |
54 | lti | integer |
| signed int less-than | |
55 | gti | integer |
| signed int greater-than | |
56 | lei | integer |
| signed int less-than-or-equal | |
57 | gei | integer |
| signed int greater-than-or-equal | |
58 | ltui | integer |
| unsigned int less-than | |
59 | gtui | integer |
| unsigned int greater-than | |
60 | leui | integer |
| unsigned int less-than-or-equal | |
61 | geui | integer |
| unsigned int greater-than-or-equal | |
62 | not in use |
|
|
| |
63 | eqq | integer | 64 bit | quad equality | |
64 | ltq | integer | 64 bit | signed quad less-than | |
65 | gtq | integer | 64 bit | signed quad greater-than | |
66 | leq | integer | 64 bit | signed quad less-than-or-equal | |
67 | geq | integer | 64 bit | signed quad greater-than-or-equal | |
68 | ltuq | integer | 64 bit | unsigned quad less-than | |
69 | gtuq | integer | 64 bit | unsigned quad greater-than | |
70 | leuq | integer | 64 bit | unsigned quad less-than-or-equal | |
71 | geuq | integer | 64 bit | unsigned quad greater-than-or-equal | |
72 | not in use |
|
|
| |
Arithmetic | 73 | eqd | integer |
| double equality |
74 | ltd | integer |
| double less-than | |
75 | gtd | integer |
| double greater-than | |
76 | led | integer |
| double less-than-or-equal | |
77 | ged | integer |
| double greater-than-or-equal | |
78 | negi | integer |
| negate int | |
79 | addi | integer |
| add int | |
80 | subi | integer |
| subtract int | |
81 | muli | integer |
| multiply int | |
82 | divi | integer | i386/64 | divide int | |
83 | modi | integer |
| modulo int - LIR_modi is a hack. It's only used on i386/X64. The operand is the result of a LIR_divi because on i386/X64 div and mod results are computed by the same instruction. | |
84 | noti | integer |
| bitwise-NOT int | |
85 | andi | integer |
| bitwise-AND int | |
86 | ori | integer |
| bitwise-OR int | |
87 | xori | integer |
| bitwise-XOR int | |
88 | lshi | integer |
| left shift int | |
89 | rshi | integer |
| right shift int (>>) | |
90 | rshui | integer |
| right shift unsigned int (>>>) | |
91 | addq | quad | 64 bit | add quad | |
92 | subq | quad | 64 bit | subtract quad | |
93 | andq | quad | 64 bit | bitwise-AND quad | |
94 | orq | quad | 64 bit | bitwise-OR quad | |
95 | xorq | quad | 64 bit | bitwise-XOR quad | |
96 | lshq | quad | 64 bit | left shift quad,2nd operand is an int | |
97 | rshq | quad | 64 bit | right shift quad, 2nd operand is an int | |
98 | rshuq | quad | 64 bit | right shift unsigned quad; 2nd operand is an int | |
99 | negd | double |
| negate double | |
100 | addd | double |
| add double | |
101 | subd | double |
| subtract double | |
102 | muld | double |
| multiply double | |
103 | divd | double |
| divide double | |
104 | modd | double |
| modulo double LIR_modd is just a place-holder opcode, ie. the back-ends cannot generate code for it.It's used in TraceMonkey briefly but is always demoted to a LIR_modl or converted to a function call before Nanojit has to do anything serious with it. | |
105 | cmovi | integer |
| conditional move int | |
106 | cmovq | quad | 64 bit | conditional move quad | |
107 | cmovd | double |
| conditional move double | |
Conversions | 108 | i2q | quad | 64 bit | sign-extend int to quad |
109 | ui2uq | quad | 64 bit | zero-extend unsigned int to unsigned quad | |
110 | q2i | integer | 64 bit | truncate quad to int (removes the high 32 bits) | |
111 | i2d | double |
| convert int to double | |
112 | ui2d | double |
| convert unsigned int to double | |
113 | d2i | integer |
| convert double to int (no exceptions raised) | |
114 | dasq | quad | 64 bit | interpret the bits of a double as a quad | |
115 | qasd | double | 64 bit | interpret the bits of a quad as a double | |
Overflow arithmetic | 116 | addxovi | integer |
| add int and exit on overflow |
117 | subxovi | integer |
| subtract int and exit on overflow | |
118 | mulxovi | integer |
| multiply int and exit on overflow | |
119 | addjovi | integer |
| add int and branch on overflow | |
120 | subjovi | integer |
| subtract int and branch on overflow | |
121 | muljovi | integer |
| multiply int and branch on overflow | |
122 | addjovq | quad | 64 bit | add quad and branch on overflow | |
123 | subjovq | quad | 64 bit | subtract quad and branch on overflow | |
SoftFloat | 124 | dlo2i | integer | SoftFloat | get the low 32 bits of a double as an int |
125 | dhi2i | integer | SoftFloat | get the high 32 bits of a double as an int | |
126 | ii2d | double | SoftFloat | join two ints (1st arg is low bits, 2nd is high) | |
| 127 | hcalli | integer |
| LIR_hcalli is a hack that's only used on 32-bit platforms that use SoftFloat. Its operand is always a LIR_calli, but one that specifies a function that returns a double. It indicates that the double result is returned via two 32-bit integer registers. The result is always used as the second operand of a LIR_ii2d. |