Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

Instructions

Mitchell Talyat edited this page Oct 14, 2022 · 6 revisions

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.

Core Instructions

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

Pseudoinstructions

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

Debug

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

Printing

PRNT

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

PRNL does one thing, it prints a blank line.

Clone this wiki locally