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. |
