-
Notifications
You must be signed in to change notification settings - Fork 0
Instructions
The following are the instructions for this emulator. They will indicate their status of implementation below. For further explanation, check out the cheat sheet in the references below. Any instructions not listed below may not be added in the future. However, instructions that are listed below will be added at some point.
These are instructions that are part of the LEGv8 assembly code. This does not include all LEGv8 instructions. For a list of all instructions, check out the cheat sheet in references.
Implemented? | Name | Mnemonic | Format | Definition | Example |
---|---|---|---|---|---|
YES | ADD | ADD | R | Adds two registers together. | ADD X0, X1, X2 // adds X1 and X2, stores result in X0 |
YES | ADD and Set flags | ADDS | R | Adds two registers together and sets flags. | ADDS X0, X1, X2 // adds X1 and X2, stores result in X0, sets flags |
YES | ADD Immediate | ADDI | I | Adds a register to an immediate value. | ADDI X0, X1, 5 // adds 5 to X1, stores result in X0 |
YES | ADD Immediate and Set flags | ADDIS | I | Adds a register to an immediate value, and sets flags. | ADDIS X0, X1, 5 // adds 5 to X1, stores result in X0, sets flags |
YES | AND | AND | R | Bitwise AND using two registers. | AND X0, X1, X2 // stores result of X1 AND X2 in X0 |
YES | AND and Set flags | ANDS | R | Bitwise AND using two registers, and set flags. | ANDS X0, X1, X2 // stores result of X1 AND X2 in X0, sets flags |
YES | AND Immediate | ANDI | I | Bitwise AND using a register and an immediate value. | ANDI X0, X1, 5 // stores result of X1 AND 5 in X0 |
YES | AND Immedaite and Set flags | ANDIS | I | Bitwise AND using a register and an immediate value, and sets flags. | ANDIS X0, X1, 5 // stores result of X1 AND 5 in X0, sets flags |
YES | Branch unconditionally | B | B | Starts executing instructions at the given label. | B loop // branches to label "loop:" |
YES | Branch conditionally (EQual) | B.EQ | CB | Branches to the given label, if the zero flag is enabled. | B.EQ loop // branches to label "loop:" if last flags call had equal values |
YES | Branch conditionally (Not Equal) | B.NE | CB | Branches to the given label, if the zero flag is not enabled. | B.NE loop // branches to the label "loop:" if the last flags call had not equal values |
YES | Branch conditionally (Less Than) | B.LT | CB | ... | ... |
YES | Branch conditionally (Less than or Equal) | B.LE | CB | ... | ... |
YES | Branch conditionally (Greater Than) | B.GT | CB | ... | ... |
YES | Branch conditionally (Greater than or Equal) | B.GE | CB | ... | ... |
YES | Branch conditionally (HIgher) | B.HI | CB | ... | ... |
YES | Branch conditionally (Higher or Same) | B.HS | CB | ... | ... |
YES | Branch conditionally (LOwer) | B.LO | CB | ... | ... |
YES | Branch conditionally (Lower or Same) | B.LS | CB | ... | ... |
YES | Branch conditionally (on MInus) | B.MI | CB | ... | ... |
YES | Branch conditionally (on PLus) | B.PL | CB | ... | ... |
NO | Branch conditionally (on oVerflow Set) | B.VS | CB | ... | ... |
NO | Branch conditionally (on oVerflow Clear) | B.VC | CB | ... | ... |
YES | Branch with Link | BL | B | Branches to the given label, and sets the return register (LR /X30 ) to the current execution index. |
BL loop // branches to label "loop:", saves execution index for return later |
YES | Branch to Register | BR | R | Branches to the execution index given within the register. | BR X30 // branches to the execution index stored in X30 (could be any register) |
YES | Compare and Branch if Not Zero | CBNZ | CB | Branches to the given label, if the given register is not zero. | CBNZ X0, loop // branches to label "loop:" if the given register is not zero |
YES | Compare and Branch if Zero | CBNZ | CB | Branches to the given label, if the given register is zero. | CBZ X0, loop // branches to label "loop:" if the given register is zero |
YES | Exclusive OR | EOR | R | Exclusive OR using two registers. | EOR X0, X1, X2 // stores result of X1 XOR X2 in X0 |
YES | Exclusive OR Immediate | EORI | I | Exclusive OR using a register and an immediate value. | EOR X0, X1, 5 // stores the result of X1 XOR 5 in X0 |
YES | LoaD Register Unscaled offset | LDUR | D | Retrieves data from memory and stores it in a register. | LDUR X0, [X1, 0] // stores the memory at pointer location X1 + offset (0) in register X0 |
YES | LoaD Byte Unscaled offset | LDURB | D | ... | ... |
YES | LoaD Half Unscaled offset | LDURH | D | ... | ... |
YES | LoaD Signed Word Unscaled offset | LDURSW | D | ... | ... |
YES | Logical Shift Left | LSL | R | Shifts the register to the left (<<) using the immediate value. | LSL X0, X1, 5 // shifts the register X1 5 times to the left, stores result in X0 |
YES | Logical Shift Right | LSR | R | Shifts the register to the right (>>) using the immediate value. | LSR X0, X1, 5 // shifts the register X1 5 times to the right, stores result in X0 |
YES | MOVe wide with Keep | MOVK | IM | Stores the immediate value in the register, but does not change the other bits in the register. | MOVK X0, 5 // sets register to 5, but does not change existing bits |
YES | MOV wide with Zero | MOVZ | IM | Stores the immediate value in the register, and sets the other bits in the register to zero. | MOVZ X0, 5 // sets register to 5, and changes existing bits to 0 |
YES | Inclusive OR | ORR | R | Bitwise OR using two registers. | ORR X0, X1, X2 // stores result of X1 OR X2 in X0 |
YES | Inclusive OR Immediate | ORRI | I | Bitwise OR using a register and an immediate value. | ORRI X0, X1, 5 // stores result of X1 OR 5 in X0 |
YES | STore Register Unscaled offset | STUR | D | Sets data in memory to the register value. | STUR X0, [X1, 0] // stores the value in register X0 to memory at location X1 + offset (0) |
YES | STore Byte Unscaled offset | STURB | D | ... | ... |
YES | STore Half Unscaled offset | STURH | D | ... | ... |
YES | STore Signed Word Unscaled offset | STURSW | D | ... | ... |
YES | SUBtract | SUB | R | Subtracts one register from another. | SUB X0, X1, X2 // subtracts X2 from X1, stores result in X0 |
YES | SUBtract and Set flags | SUBS | R | Subtracts one register from another, and sets flags. | SUB X0, X1, X2 // subtracts X2 from X1, stores result in X0, sets flags |
YES | SUBtract Immediate | SUBI | I | Subtracts an immediate value from a register. | SUBI X0, X1, 5 // subtracts 5 from X1, stores result in X0 |
YES | SUBtract Immediate and Set flags | SUBIS | I | Subtracts an immediate value from a register, and sets flags. | SUB X0, X1, 5 // subtracts 5 from X1, stores result in X0, sets flags |
YES | MULtiply | MUL | R | Multiplies two registers together. | MUL X0, X1, X2 // multiplies X1 and X2 together, stores result in X0 |
YES | Signed DIVide | SDIV | R | Divides two registers together. | SDIV X0, X1, X2 // divides X2 into X1, stores result in X0 |
NO | Signed MULtiply High | SMULH | R | ... | ... |
YES | Unsigned DIVide | UDIV | R | Divides two unsigned registers together. | UDIV X0, X1, X2 // divides X2 into X1, stores result in X0 |
NO | Unsigned MULtiply High | UMULH | R | ... | ... |
These are instructions that are short for another instruction. They can be written in the program and still function as they should. When being assembled, they would be swapped out with their equivalents.
Implemented? | Name | Mnemonic | Equivalent | Definition | Example |
---|---|---|---|---|---|
YES | CoMPare | CMP |
SUBS XZR, m, n where m and n are registers |
Compares the two given registers by setting the flags. | CMP X0, X1 // compares X0 and X1 |
YES | CoMPare Immediate | CMPI |
SUBIS XZR, m, n where m is a register, and n is an immediate value |
Compares the given register and the given value by setting the flags. | CMPI X0, 5 //compares X0 and 5 |
YES | LoaD Address | LDA | ... | Loads the return address. | LDA X0, loop // loads the address of the label "loop" into register X0 |
YES | MOVe | MOV |
ORR m, XZR, n where m and n are registers |
Moves a register value to another register. | MOV X0, X1 // sets X0 to X1 |
These are instructions that are specific to this emulator. Their sole purpose is to aid in the debugging process.
Implemented? | Name | Mnemonic | Definition | Example |
---|---|---|---|---|
YES | DUMP | DUMP | Displays all registers and memory in the output, and stops the program. | D // show all register values and memory at this point in time |
YES | PRNT | Prints a string to the output. | PRNT The value of X0 is {X0} // prints "The value of X0 is 5" to the output |
|
YES | PRiNt Line | PRNL | Prints an empty line to the output. | PRNL // prints an empty line to the output |
PRNT allows for multiple forms of printing.
The first is straightforward. If the instruction reads PRNT X0
, it will print the value of the register to the output.
If the instruction is not just a register identifier, it must use the curly brackets ({
and }
) around it to signify that the value of the register itself is being requested.
PRNT also allows for printing memory values. This can be done in a similar fashion- by using square brackets ([
and ]
). Inside of the square brackets must be a register identifier, which will be used for the address of the memory. For example, PRNT [X0]
will print the byte in memory at the address that is found inside the X0 register.
PRNT can also just be blank (PRNT
) which will act the same as a PRNL.
In addition to displaying registers between the curly brackets, the following can also be used:
- EI - The current Execution Index (index of the instruction being executed)
- EL - The current Execution Line (line in the file that is being executed)
- ET - The current Execution Time (time that has passed since the beginning of the program)
PRNL does one thing, it prints a blank line.