-
Notifications
You must be signed in to change notification settings - Fork 3
List of Majiro IL instructions
Shorthand name is MjIL (Majiro Intermediate Language).
Important: As of 2021-05-11, breaking changes have been made to instruction names: bge.v, bgt.v, ble.v, blt.v (all comparison types were mislabeled). Additionally, since then, b_.case is now the primary name for these instructions, while b_.v remains only as an alias.
Operand | Types |
---|---|
field | <uint16 (flags), uint32 (hash), int16 (offs)> |
method | <uint32 (hash)> |
The postfix .r stands for real, which follows CIL instruction naming conventions.
Type | Code | Postfix |
---|---|---|
int | 0 |
.i |
float | 1 |
.r |
string | 2 |
.s |
int[] | 3 |
.iarr |
float[] | 4 |
.rarr |
string[] | 5 |
.sarr |
Operator and assignment opcodes (0x100~0x320) all follow a pattern for their code number. Each base operator code is a multiple of 8, and the supported type is a number (0~5) added to that value (i.e. 0x118 : add.i, 0x119 : add.r, 0x11A : add.s).
All remaining opcodes (0x800~0x850) serve various purposes, from stack management and branching, to more specific VN-related commands.
All opcode names are chosen to best match conventions used by CIL instructions. However many opcodes have no counterpart, or have a hugely different scope (e.g. ld for all variables in MjIL / and ldloc, ldarg, ldfld, etc. in CIL).
MjIL text parsers should support the op.%03x
alias for all opcodes (e.g. 0x845 : op.845).
The name nop.%03x
is used for all nop -no operation- opcodes (e.g. 0x191 : nop.191). These opcodes must still be defined, as many may have an effect on the stack, or may originally have had a function. [citation needed]
All operators that only implement int types will not include the .i
postfix in the name. There still must be an alias that includes the postfix (e.g. xor / xor.i). This rule extends to operators that implement other types that are nop's (e.g. notl / notl.i, and notl.r : aka nop.191).
Opcode | Instruction | Description |
---|---|---|
0x100 | mul.i |
Multiply integer values. |
0x101 | mul.r |
Multiply floating-point values. (accepts int) |
0x108 | div.i |
Divide two values to return an integer quotient. |
0x109 | div.r |
Divide two values to return a floating-point result. (accepts int) |
0x110 | rem |
Remainder when dividing one value by another. (can return negative results, signed modulus) |
0x110 | rem.i |
(alias for rem) |
0x118 | add.i |
Add two integer values, returning a new value. |
0x119 | add.r |
Add two floating-point values, returning a new value. (accepts int) |
0x11A | add.s |
Concatenate two string values, returning a new value. |
0x120 | sub.i |
Subtract integer value2 from integer value1, returning a new value. |
0x121 | sub.r |
Subtract floating-point value2 from value1, returning a new value. (allows integers) |
0x128 | shr |
Shift an integer right (shift in zero), return an integer. |
0x128 | shr.i |
(alias for shr) |
0x130 | shl |
Shift an integer left (shifting in zeros), return an integer. |
0x130 | shl.i |
(alias for shl) |
0x138 | cle.i |
Push 1 (of type int) if integer value1 lower or equals value2, else push 0. |
0x139 | cle.r |
Push 1 (of type int) if floating-point value1 lower or equals value2, else push 0. (accepts int) |
0x13A | cle.s |
Push 1 (of type int) if string value1 lower or equals value2, else push 0. (case insensitive) |
0x140 | clt.i |
Push 1 (of type int) if integer value1 lower than value2, else push 0. |
0x141 | clt.r |
Push 1 (of type int) if floating-point value1 lower than value2, else push 0. |
0x142 | clt.s |
Push 1 (of type int) if string value1 lower than value2, else push 0. (case insensitive) |
0x148 | cge.i |
Push 1 (of type int) if integer value1 greater or equals value2, else push 0. |
0x149 | cge.r |
Push 1 (of type int) if floating-point value1 greater or equals value2, else push 0. (accepts int) |
0x14A | cge.s |
Push 1 (of type int) if string value1 greater or equals value2, else push 0. (case insensitive) |
0x150 | cgt.i |
Push 1 (of type int) if integer value1 greater than value2, else push 0. |
0x151 | cgt.r |
Push 1 (of type int) if floating-point value1 greater than value2, else push 0. (accepts int) |
0x152 | cgt.s |
Push 1 (of type int) if string value1 greater than value2, else push 0. (case insensitive) |
0x158 | ceq.i |
Push 1 (of type int) if integer value1 equals value2, else push 0. |
0x159 | ceq.r |
Push 1 (of type int) if floating-point value1 equals value2, else push 0. (accepts int) |
0x15A | ceq.s |
Push 1 (of type int) if string value1 equals value2, else push 0. (case insensitive) |
0x15B | ceq.iarr |
Push 1 (of type int) if integer array1 equals array2, else push 0. |
0x15C | ceq.rarr |
Push 1 (of type int) if floating-point array1 equals array2, else push 0. (accepts int) |
0x15D | ceq.sarr |
Push 1 (of type int) if string array1 equals array2, else push 0. (case insensitive) |
0x160 | cne.i |
Push 1 (of type int) if integer value1 not equals value2, else push 0. |
0x161 | cne.r |
Push 1 (of type int) if floating-point value1 not equals value2, else push 0. (accepts int) |
0x162 | cne.s |
Push 1 (of type int) if string value1 not equals value2, else push 0. (case insensitive) |
0x163 | cne.iarr |
Push 1 (of type int) if integer array1 not equals array2, else push 0. |
0x164 | cne.rarr |
Push 1 (of type int) if floating-point array1 not equals array2, else push 0. (accepts int) |
0x165 | cne.sarr |
Push 1 (of type int) if string array1 not equals array2, else push 0. (case insensitive) |
0x168 | xor |
Bitwise XOR of integer values, returns an integer. |
0x168 | xor.i |
(alias for xor) |
0x170 | andl |
Push 1 (of type int) if both of two integer values are non-zero, else push 0. |
0x170 | andl.i |
(alias for andl) |
0x178 | orl |
Push 1 (of type int) if either of two integer values are non-zero, else push 0. |
0x178 | orl.i |
(alias for orl) |
0x180 | and |
Bitwise AND of two integral values, returns an integral value. |
0x180 | and.i |
(alias for and) |
0x188 | or |
Bitwise OR of two integer values, returns an integer. |
0x188 | or.i |
(alias for or) |
0x190 | notl |
Push 1 (of type int) if integer value is zero, else push 0 (comparison not ! ). |
0x190 | notl.i |
(alias for notl) |
0x191 | nop.191 |
(this is a nop) Push 1 (of type int) if floating-point value is zero, else push 0. |
0x191 | notl.r |
(this is a nop) Push 1 (of type int) if floating-point value is zero, else push 0. |
0x198 | not |
Bitwise complement (logical not ~ ). |
0x198 | not.i |
(alias for not) |
0x1A0 | neg.i |
Negate integer value. |
0x1A1 | neg.r |
Negate floating-point value. |
0x1A8 | nop.1a8 |
(this is a nop) Positive integer value. |
0x1A8 | pos.i |
(alias for nop.1a8) Positive integer value. |
0x1A9 | nop.1a9 |
(this is a nop) Positive floating-point value. |
0x1A9 | pos.r |
(alias for nop.1a9) Positive floating-point value. |
0x1B0 | st.i <field> |
Store value of type int into variable. |
0x1B1 | st.f <field> |
Store value of type float into variable. |
0x1B2 | st.s <field> |
Store value of type string into variable. |
0x1B3 | st.iarr <field> |
Store value of type int[] into variable. |
0x1B4 | st.rarr <field> |
Store value of type float[] into variable. |
0x1B5 | st.sarr <field> |
Store value of type string[] into variable. |
0x1B8 | st.mul.i <field> |
Compound multiply, then store value of type int into variable. |
0x1B9 | st.mul.r <field> |
Compound multiply, then store value of type float into variable. (accepts int) |
0x1C0 | st.div.i <field> |
Compound divide, then store value of type int into variable. |
0x1C1 | st.div.r <field> |
Compound divide, then store value of type float into variable. (accepts int) |
0x1C8 | st.rem <field> |
Compound remainder, then store value of type int into variable. |
0x1C8 | st.rem.i <field> |
(alias for st.rem) |
0x1D0 | st.add.i <field> |
Compound add, then store value of type int into variable. |
0x1D1 | st.add.r <field> |
Compound add, then store value of type float into variable. (accepts int) |
0x1D2 | st.add.s <field> |
Compound concatenate, then store value of type string into variable. |
0x1D8 | st.sub.i <field> |
Compound subtract, then store value of type int into variable. |
0x1D9 | st.sub.r <field> |
Compound subtract, then store value of type float into variable. (accepts int) |
0x1E0 | st.shl <field> |
Compound shift left, then store value of type int into variable. |
0x1E0 | st.shl.i <field> |
(alias for st.shl) |
0x1E8 | st.shr <field> |
Compound shift right, then store value of type int into variable. |
0x1E8 | st.shr.i <field> |
(alias for st.shr) |
0x1F0 | st.and <field> |
Compound bitwise AND, then store value of type int into variable. |
0x1F0 | st.and.i <field> |
(alias for st.and) |
0x1F8 | st.xor <field> |
Compound bitwise XOR, then store value of type int into variable. |
0x1F8 | st.xor.i <field> |
(alias for st.xor) |
0x200 | st.or <field> |
Compound bitwise OR, then store value of type int into variable. |
0x200 | st.or.i <field> |
(alias for st.or) |
0x210 | stp.i <field> |
Pop a value of type int into variable. |
0x211 | stp.f <field> |
Pop a value of type float into variable. |
0x212 | stp.s <field> |
Pop a value of type string into variable. |
0x213 | stp.iarr <field> |
Pop a value of type int[] into variable. |
0x214 | stp.rarr <field> |
Pop a value of type float[] into variable. |
0x215 | stp.sarr <field> |
Pop a value of type string[] into variable. |
0x218 | stp.mul.i <field> |
Compound multiply, then pop value of type int into variable. |
0x219 | stp.mul.r <field> |
Compound multiply, then pop value of type float into variable. (accepts int) |
0x220 | stp.div.i <field> |
Compound divide, then pop value of type int into variable. |
0x221 | stp.div.r <field> |
Compound divide, then pop value of type float into variable. (accepts int) |
0x228 | stp.rem <field> |
Compound remainder, then pop value of type int into variable. |
0x228 | stp.rem.i <field> |
(alias for stp.rem) |
0x230 | stp.add.i <field> |
Compound add, then pop value of type int into variable. |
0x231 | stp.add.r <field> |
Compound add, then pop value of type float into variable. (accepts int) |
0x232 | stp.add.s <field> |
Compound concatenate, then pop value of type string into variable. |
0x238 | stp.sub.i <field> |
Compound subtract, then pop value of type int into variable. |
0x239 | stp.sub.r <field> |
Compound subtract, then pop value of type float into variable. (accepts int) |
0x240 | stp.shl <field> |
Compound shift left, then pop value of type int into variable. |
0x240 | stp.shl.i <field> |
(alias for stp.shl) |
0x248 | stp.shr <field> |
Compound shift right, then pop value of type int into variable. |
0x248 | stp.shr.i <field> |
(alias for stp.shr) |
0x250 | stp.and <field> |
Compound bitwise AND, then pop value of type int into variable. |
0x250 | stp.and.i <field> |
(alias for stp.and) |
0x258 | stp.xor <field> |
Compound bitwise XOR, then pop value of type int into variable. |
0x258 | stp.xor.i <field> |
(alias for stp.xor) |
0x260 | stp.or <field> |
Compound bitwise OR, then pop value of type int into variable. |
0x260 | stp.or.i <field> |
(alias for stp.or) |
0x270 | stelem.i <field> |
Store value of type int into array element at indices. |
0x271 | stelem.f <field> |
Store value of type float into array element at indices. |
0x272 | stelem.s <field> |
Store value of type string into array element at indices. |
0x278 | stelem.mul.i <field> |
Compound multiply, then store value of type int into array element at indices. |
0x279 | stelem.mul.r <field> |
Compound multiply, then store value of type float into array element at indices. (accepts int) |
0x280 | stelem.div.i <field> |
Compound divide, then store value of type int into array element at indices. |
0x281 | stelem.div.r <field> |
Compound divide, then store value of type float into array element at indices. (accepts int) |
0x288 | stelem.rem <field> |
Compound remainder, then store value of type int into array element at indices. |
0x288 | stelem.rem.i <field> |
(alias for stelem.rem) |
0x290 | stelem.add.i <field> |
Compound add, then store value of type int into array element at indices. |
0x291 | stelem.add.r <field> |
Compound add, then store value of type float into array element at indices. (accepts int) |
0x292 | stelem.add.s <field> |
Compound concatenate, then store value of type string into array element at indices. |
0x298 | stelem.sub.i <field> |
Compound subtract, then store value of type int into array element at indices. |
0x299 | stelem.sub.r <field> |
Compound subtract, then store value of type float into array element at indices. (accepts int) |
0x2A0 | stelem.shl <field> |
Compound shift left, then store value of type int into array element at indices. |
0x2A0 | stelem.shl.i <field> |
(alias for stelem.shl) |
0x2A8 | stelem.shr <field> |
Compound shift right, then store value of type int into array element at indices. |
0x2A8 | stelem.shr.i <field> |
(alias for stelem.shr) |
0x2B0 | stelem.and <field> |
Compound bitwise AND, then store value of type int into array element at indices. |
0x2B0 | stelem.and.i <field> |
(alias for stelem.and) |
0x2B8 | stelem.xor <field> |
Compound bitwise XOR, then store value of type int into array element at indices. |
0x2B8 | stelem.xor.i <field> |
(alias for stelem.xor) |
0x2C0 | stelem.or <field> |
Compound bitwise OR, then store value of type int into array element at indices. |
0x2C0 | stelem.or.i <field> |
(alias for stelem.or) |
0x2D0 | stelemp.i <field> |
Pop a value of type int into array element at indices. |
0x2D1 | stelemp.f <field> |
Pop a value of type float into array element at indices. |
0x2D2 | stelemp.s <field> |
Pop a value of type string into array element at indices. |
0x2D8 | stelemp.mul.i <field> |
Compound multiply, then pop value of type int into array element at indices. |
0x2D9 | stelemp.mul.r <field> |
Compound multiply, then pop value of type float into array element at indices. (accepts int) |
0x2E0 | stelemp.div.i <field> |
Compound divide, then pop value of type int into array element at indices. |
0x2E1 | stelemp.div.r <field> |
Compound divide, then pop value of type float into array element at indices. (accepts int) |
0x2E8 | stelemp.rem <field> |
Compound remainder, then pop value of type int into array element at indices. |
0x2E8 | stelemp.rem.i <field> |
(alias for stelemp.rem) |
0x2F0 | stelemp.add.i <field> |
Compound add, then pop value of type int into array element at indices. |
0x2F1 | stelemp.add.r <field> |
Compound add, then pop value of type float into array element at indices. (accepts int) |
0x2F2 | stelemp.add.s <field> |
Compound concatenate, then pop value of type string into array element at indices. |
0x2F8 | stelemp.sub.i <field> |
Compound subtract, then pop value of type int into array element at indices. |
0x2F9 | stelemp.sub.r <field> |
Compound subtract, then pop value of type float into array element at indices. (accepts int) |
0x300 | stelemp.shl <field> |
Compound shift left, then pop value of type int into array element at indices. |
0x300 | stelemp.shl.i <field> |
(alias for stelemp.shl) |
0x308 | stelemp.shr <field> |
Compound shift right, then pop value of type int into array element at indices. |
0x308 | stelemp.shr.i <field> |
(alias for stelemp.shr) |
0x310 | stelemp.and <field> |
Compound bitwise AND, then pop value of type int into array element at indices. |
0x310 | stelemp.and.i <field> |
(alias for stelemp.and) |
0x318 | stelemp.xor <field> |
Compound bitwise XOR, then pop value of type int into array element at indices. |
0x318 | stelemp.xor.i <field> |
(alias for stelemp.xor) |
0x320 | stelemp.or <field> |
Compound bitwise OR, then pop value of type int into array element at indices. |
0x320 | stelemp.or.i <field> |
(alias for stelemp.or) |
0x800 | ldc.i <int32 (num)> |
Push num of type int onto the stack. |
0x801 | ldstr <string> |
Push a string object for the literal string onto the stack. |
0x802 | ld <field> |
Push the value of the variable on the stack. |
0x803 | ldc.r <float32 (num)> |
Push num of type float onto the stack. |
0x80F | call <method, int32 (0), uint16 (argC)> |
Call user-defined function with argC arguments from the stack. |
0x810 | callp <method, int32 (0), uint16 (argC)> |
Call (void return) user-defined function with argC arguments from the stack. |
0x829 | alloca <uint16 (N), uint8 (t1..tN)> |
Allocate n local variables of type t. |
0x82B | ret |
Return from method, with value on the stack (pops depending on call type). |
0x82C | br <int32 (target)> |
Branch to target (unconditional). |
0x82D | brtrue <int32 (target)> |
Branch to target if value is non-zero (true). |
0x82E | brfalse <int32 (target)> |
Branch to target if value is zero (false). |
0x82F | pop |
Pop value from the stack. |
0x830 | br.case <int32 (target)> |
Branch to target and store value as case condition in thread-local var $11F91FD3 %Op_internalCase~@MAJIRO_INTER .Start of switch statement. |
0x830 | br.v <int32 (target)> |
(old alias for br.case) |
0x831 | bne.case <int32 (target)> |
Branch to target if br.case condition not equals value. |
0x831 | bne.v <int32 (target)> |
(old alias for bne.case) |
0x832 | bge.case <int32 (target)> |
Branch to target if br.case condition greater or equals value. |
0x832 | bge.v <int32 (target)> |
(old alias for bge.case) |
0x833 | ble.case <int32 (target)> |
Branch to target if br.case condition lower or equals value. |
0x833 | ble.v <int32 (target)> |
(old alias for ble.case) |
0x834 | syscall <method, uint16 (argC)> |
Call system function with argC arguments from the stack. |
0x835 | syscallp <method, uint16 (argC)> |
Call (void return) system function with argC arguments from the stack. |
0x836 | argcheck <uint16 (N), uint8 (t1..tN)> |
Confirms n arguments on stack match t types (func sig check). |
0x837 | ldelem <field> |
Load the array element at indices onto the top of the stack. |
0x838 | blt.case <int32 (target)> |
Branch to target if br.case condition lower than value. |
0x838 | blt.v <int32 (target)> |
(old alias for blt.case) |
0x839 | bgt.case <int32 (target)> |
Branch to target if br.case condition greater than value. |
0x839 | bgt.v <int32 (target)> |
(old alias for bgt.case) |
0x83A | line <uint16 (num)> |
Inform a debugger of the script source line number. Used to mark read lines in scenarios. |
0x83B | bsel.1 <int32 (target)> |
(unk) Set branch target AIP:1 (lclick). |
0x83C | bsel.3 <int32 (target)> |
(unk) Set branch target AIP:3 (mclick). |
0x83D | bsel.2 <int32 (target)> |
(unk) Set branch target AIP:2 (rclick). |
0x83E | conv.i |
Convert float to int, pushing int on stack. |
0x83F | conv.r |
Convert int to float, pushing float on stack. |
0x840 | text <string> |
(VN) Append to text/message buffer. |
0x841 | proc |
(unk, VN) Process text buffer created by text. Listed as marker in mjdisasm.ml, and as ProcessString in MjoParser.py. In asm, opcode has int param. 2 passed in bytecode, 8 passed in syscall $wait ($59180bbb). |
0x842 | ctrl <string> |
(VN) Process escape sequences based on the defined string character. "p" : pause, "w" : cls |
0x843 | bsel.x <int32 (target)> |
(unk) Set branch targets AIP:1, AIP:2, AIP:3 (lclick, rclick, mclick). |
0x844 | bsel.clr |
(unk) Clear branch targets set by bsel.# instructions. MjoParser.py : ClearJumpTbl. |
0x845 | bsel.4 <int32 (target)> |
(unk) Set branch target AIP:4. MjoParser.py : SetJmpAddr3. |
0x846 | bsel.jmp.4 |
(unk) Jump to branch target AIP:4 (set by bsel.4, op.845). |
0x847 | bsel.5 <int32 (target)> |
Set branch target AIP:5 (destructor). MjoParser.py : SetJmpAddr4. |
0x850 | switch <uint16 (N), int32 (t1..tN)> |
Jump to one of n targets t. (Note: target offsets are relative to the end of operand, not end of instruction) |