Instructions

An Elasmosaurus

Overview

InstructionFull NameSummary
addAdd

Adds two registers and places the result in the destination.

addiAdd (Immediate)

Adds a register and an immediate and places the result in the destination.

andLogical AND

Applies the logical AND operation to the given registers and places the result in the destination.

andiAnd (Immediate)

Applies the logical AND operation to the given register and immediate and places the result in the destination.

auipcAdd Upper Immediate to Program Counter

Adds the current PC to the given immediate after shifting the immediate value left 12 bits and sign-extending to the register width.

beqBranch If Equal

Jumps to the given label if the two registers are equal.

beqzBranch If Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is equal to zero.

bgeBranch If Greater Than or Equal

Jumps to the given label if the first given register is greater than or equal to the second when interpreted as signed integers.

bgeuBranch If Greater Than or Equal (Unsigned)

Jumps to the given label if the first given register is greater than or equal to the second when interpreted as unsigned integers.

bgezBranch If Greater Than or Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is positive or zero when interpreted as a signed integer.

bgtBranch If Greater Than

Pseudo-instruction that jumps to the given label if the first given register is greater than the other when interpreted as a signed integer.

bgtuBranch If Greater Than (Unsigned)

Pseudo-instruction that jumps to the given label if the first given register is greater than the other when interpreted as an unsigned integer.

bgtzBranch If Greater Than Zero

Pseudo-instruction that jumps to the given label if the given register is positive when interpreted as a signed integer.

bleBranch If Less Than or Equal

Pseudo-instruction that jumps to the given label if the first given register is less than the other when interpreted as a signed integer.

bleuBranch If Less Than or Equal (Unsigned)

Pseudo-instruction that jumps to the given label if the first given register is less than the other when interpreted as an unsigned integer. (Also the cheesiest instruction)

blezBranch If Less Than or Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is negative or zero when interpreted as a signed integer.

bltBranch If Less Than

Jumps to the given label if the first given register is less than the second when interpreted as signed integers.

bltzBranch If Less Than Zero

Pseudo-instruction that jumps to the given label if the given register is negative when interpreted as a signed integer.

bneBranch If Not Equal

Jumps to the given label if the two registers are not equal.

bnezBranch If Not Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is not equal to zero.

divInteger Divide

Divides the two given registers and places the resulting quotient in the destination register, interpreting every value as a signed integer.

divuInteger Divide (Unsigned)

Divides the two given registers and places the resulting quotient in the destination register, interpreting every value as an unsigned integer.

ebreakEnvironment Break

Pauses execution and yields to the debugger.

ecallEnvironment Call

Performs a call into the operating system.

jJump

Jumps to the given label, unconditionally.

jalJump and Link

Jumps to the given label, unconditionally, and sets the destination register (the ra register by default) to the address of the instruction following this one.

jalrJump and Link to Register

Jumps to the given register, unconditionally, and sets the destination register (the ra register by default) to the address of the instruction following this one.

jrJump to Register

Interprets the given register as a memory address and jumps to that address unconditionally.

laLoad Address

Moves the address represented by the given label to the given register.

lbLoad Byte

Interprets the register value as a memory address and loads one byte at that address, interpreting it as a signed 8-bit integer, into the given register.

lbuLoad Byte (Unsigned)

Interprets the register value as a memory address and loads one byte at that address, interpreting it as an unsigned 8-bit integer, into the given register.

ldLoad Double-word

Interprets the register value as a memory address and loads one double-word at that address, interpreting it as a signed 64-bit integer, into the given register.

lhLoad Half-word

Interprets the register value as a memory address and loads one half-word at that address, interpreting it as a signed 16-bit integer, into the given register.

lhuLoad Half-word (Unsigned)

Interprets the register value as a memory address and loads one half-word at that address, interpreting it as an unsigned 16-bit integer, into the given register.

liLoad Immediate

Pseudo-instruction that simply loads the given immediate value into the given register.

luiLoad Upper Immediate

Loads the given immediate into bits 31 to 12 of the given register after shifting the immediate value left 12 bits and sign extending to the register width.

lwLoad Word

Interprets the register value as a memory address and loads one word at that address, interpreting it as a signed 32-bit integer, into the given register.

lwuLoad Word (Unsigned)

Interprets the register value as a memory address and loads one word at that address, interpreting it as an unsigned 32-bit integer, into the given register.

moveMove

Pseudo-instruction that copies the value from the source register into the destination register.

mulMultiply

Multiplies the two given registers and places the lower word of the resulting product in the destination register, interpreting every value as a signed integer.

mulhMultiply and return High

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting every value as a signed integer.

mulhsuMultiply and return High (Signed x Unsigned)

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting the first value as a signed integer and the second as an unsigned integer.

mulhuMultiply and return High (Unsigned)

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting every value as an unsigned integer.

mvMove

Pseudo-instruction that copies the value from the source register into the destination register.

negNegate

Pseudo-instruction that negates the source register, interpreted as a signed 2's-complement integer, and places the result in the destination.

nopNo Operation

Pseudo-instruction that does nothing.

notNot

Applies the logical NOT operation (1's-complement negation) to the given register and places the result in the destination.

orLogical OR

Applies the logical OR operation to the given registers and places the result in the destination.

oriLogical OR (Immediate)

Applies the logical OR operation to the given register and immediate and places the result in the destination.

remInteger Remainder

Divides the two given registers and places the resulting remainder in the destination register, interpreting every value as a signed integer.

remuInteger Remainder (Unsigned)

Divides the two given registers and places the resulting remainder in the destination register, interpreting every value as an unsigned integer.

sbStore Byte

Interprets the register value as a memory address and stores the given value to the 8-bit byte at that address.

sdStore Double-word

Interprets the register value as a memory address and stores the given value to the 64-bit region beginning at that address.

seqzSet If Equal to Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is equal to zero; 0 otherwise.

sgtzSet If Greater Than Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is positive when interpreted as a signed integer; 0 otherwise.

shStore Half-word

Interprets the register value as a memory address and stores the given value to the 16-bit region beginning at that address.

sllShift Left Logical

Shifts a 0 into the right-hand side of the given register the number of times provided by the second register.

slliShift Left Logical (Immediate)

Shifts a 0 into the right-hand side of the given register the number of times provided by the immediate value.

sltSet Less Than

Assigns 1 to the destination register if the first register, interpreted as a signed integer, is less than the second register; 0 otherwise.

sltiSet Less Than (Immediate)

Assigns 1 to the destination register if the first register, interpreted as a signed integer, is less than the given immediate; 0 otherwise.

sltiuSet Less Than (Immediate) (Unsigned)

Assigns 1 to the destination register if the first register, interpreted as an unsigned integer, is less than the given immediate; 0 otherwise.

sltuSet Less Than (Unsigned)

Assigns 1 to the destination register if the first register, interpreted as an unsigned integer, is less than the given immediate; 0 otherwise.

sltzSet If Less Than Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is negative when interpreted as a signed integer; 0 otherwise.

snezSet If Not Equal to Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is not equal to zero; 0 otherwise.

sraShift Right Arithmetic

Copies the most-significant bit into the left-hand side of the given register the number of times provided by the second register.

sraiShift Right Arithmetic (Immediate)

Copies the most-significant bit into the left-hand side of the given register the number of times provided by the immediate.

srlShift Right Logical

Shifts a 0 into the left-hand side of the given register the number of times provided by the second register.

srliShift Right Logical (Immediate)

Shifts a 0 into the left-hand side of the given register the number of times provided by the immediate.

subSubtract

Subtracts the second register from the first given register and places the signed result into the destination register.

swStore Word

Interprets the register value as a memory address and stores the given value to the 32-bit region beginning at that address.

xorLogical XOR

Applies the logical XOR operation to the given registers and places the result in the destination.

xoriLogical XOR (Immediate)

Applies the logical XOR operation to the given register and immediate and places the result in the destination.

add - Add

Adds two registers and places the result in the destination.

    add     t2, t0, t1

This adds t0 and t1 and places the resulting sum in t2.

addi - Add (Immediate)

Adds a register and an immediate and places the result in the destination.

    addi    t2, t0, 42

This adds the value 42 to the t0 register and places the resulting sum in t2.

    add     t2, t0, 42

This performs the same operation as the previous example. The add, here, is a convenient alias for addi when an immediate value is written.

and - Logical AND

Applies the logical AND operation to the given registers and places the result in the destination.

    and     t2, t0, t1

This applies the logical AND to t0 and t1 and places the resulting value in t2.

andi - And (Immediate)

Applies the logical AND operation to the given register and immediate and places the result in the destination.

    andi    t2, t0, 0x18

This applies the logical AND operation to the hexadecimal value 0x18 and the t0 register and places the resulting sum in t2.

    and     t2, t0, 0x18

This performs the same operation as the previous example. The and, here, is a convenient alias for andi when an immediate value is written.

auipc - Add Upper Immediate to Program Counter

Adds the current PC to the given immediate after shifting the immediate value left 12 bits and sign-extending to the register width.

beq - Branch If Equal

Jumps to the given label if the two registers are equal.

_loop:
    beq     t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t1 register is equal to the value in the t0 register. Otherwise, it continues to the addi instruction that follows.

beqz - Branch If Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is equal to zero.

_loop:
    beqz    t0, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is equal to zero. Otherwise, it continues to the addi instruction that follows.

bge - Branch If Greater Than or Equal

Jumps to the given label if the first given register is greater than or equal to the second when interpreted as signed integers.

_loop:
    bge     t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is greater than or equal to the value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bgeu - Branch If Greater Than or Equal (Unsigned)

Jumps to the given label if the first given register is greater than or equal to the second when interpreted as unsigned integers.

_loop:
    bgeu    t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the unsigned value in the t0 register is greater than or equal to the unsigned value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bgez - Branch If Greater Than or Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is positive or zero when interpreted as a signed integer.

_loop:
    bgez    t0, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is greater than or equal to zero. Otherwise, it continues to the addi instruction that follows.

bgt - Branch If Greater Than

Pseudo-instruction that jumps to the given label if the first given register is greater than the other when interpreted as a signed integer.

_loop:
    bgt     t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is strictly greater than the value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bgtu - Branch If Greater Than (Unsigned)

Pseudo-instruction that jumps to the given label if the first given register is greater than the other when interpreted as an unsigned integer.

_loop:
    bgtu    t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the unsigned value in the t0 register is strictly greater than the unsigned value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bgtz - Branch If Greater Than Zero

Pseudo-instruction that jumps to the given label if the given register is positive when interpreted as a signed integer.

_loop:
    bgtz    t0, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is strictly greater than zero. Otherwise, it continues to the addi instruction that follows.

ble - Branch If Less Than or Equal

Pseudo-instruction that jumps to the given label if the first given register is less than the other when interpreted as a signed integer.

_loop:
    ble     t0, t1, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is less than or equal to the value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bleu - Branch If Less Than or Equal (Unsigned)

Pseudo-instruction that jumps to the given label if the first given register is less than the other when interpreted as an unsigned integer. (Also the cheesiest instruction)

_loop:
    bleu    t0, t1, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the unsigned value in the t0 register is less than or equal to the unsigned value in the t1 register. Otherwise, it continues to the addi instruction that follows.

blez - Branch If Less Than or Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is negative or zero when interpreted as a signed integer.

_loop:
    blez    t0, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the unsigned value in the t0 register is less than or equal to zero. Otherwise, it continues to the addi instruction that follows.

blt - Branch If Less Than

Jumps to the given label if the first given register is less than the second when interpreted as signed integers.

_loop:
    blt     t0, t1, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is strictly less than the value in the t1 register. Otherwise, it continues to the addi instruction that follows.

bltz - Branch If Less Than Zero

Pseudo-instruction that jumps to the given label if the given register is negative when interpreted as a signed integer.

_loop:
    bltz    t0, _exit_loop
    addi    t0, t0, -1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the unsigned value in the t0 register is strictly less than zero. Otherwise, it continues to the addi instruction that follows.

bne - Branch If Not Equal

Jumps to the given label if the two registers are not equal.

_loop:
    bne     t0, t1, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t1 register is not equal to the value in the t0 register. Otherwise, it continues to the addi instruction that follows.

bnez - Branch If Not Equal to Zero

Pseudo-instruction that jumps to the given label if the given register is not equal to zero.

_loop:
    bnez    t0, _exit_loop
    addi    t0, t0, 1
    j       _loop
_exit_loop:

This sets the program counter to _exit_loop if and only if the value in the t0 register is not equal to zero. Otherwise, it continues to the addi instruction that follows.

div - Integer Divide

Divides the two given registers and places the resulting quotient in the destination register, interpreting every value as a signed integer.

divu - Integer Divide (Unsigned)

Divides the two given registers and places the resulting quotient in the destination register, interpreting every value as an unsigned integer.

ebreak - Environment Break

Pauses execution and yields to the debugger.

ecall - Environment Call

Performs a call into the operating system.

j - Jump

Jumps to the given label, unconditionally.

func:
    j       _func_skip
    addi    t0, t0, 1
    li      t1, 2
    mul     t0, t0, t1
_func_skip:
    li      t1, -1
    sub     t0, t0, t1

This jumps to the label _func_skip and will not execute the addi, li, nor mul instructions. Instead, it will go on to perform the li pseudo-instruction and then the sub that are written after that label.

jal - Jump and Link

Jumps to the given label, unconditionally, and sets the destination register (the ra register by default) to the address of the instruction following this one.

main:
    # call func(42)
    li      a0, 42
    jal     func

    # exit
    li      a7, 10
    ecall

func:
    # print integer in a0
    li      a7, 1
    ecall

    # return
    jr      ra

This contains a function called func defined by the label of that same name. The jal instruction will assign the ra register to the address of the instruction following the jal, which is the li assigning 10 to a7. Afterward, the jal instruction will jump to the label and start executing the instructions following the label. In this case, it will perform an ecall that will print the argument provided to the function in a0 that was assigned prior to the jal. You will notice that the jal instruction does not, itself, enforce the calling conventions of the function (argument and return value placement) aside from the assignment of the ra register, which is then used by the jr instruction to return to the calling main function.

main:
    jal     t0, _main_getpc
_main_getpc:

    # print integer in t0
    li      a7, 1
    move    a0, t0
    ecall

    # exit
    li      a7, 10
    ecall

This example specifies the destination register for the return address. We can use this to essentially move the value of the pc register into any general-purpose register, such as t0 in this case.

jalr - Jump and Link to Register

Jumps to the given register, unconditionally, and sets the destination register (the ra register by default) to the address of the instruction following this one.

main:
    # call func(42) indirectly
    li      a0, 42
    la      t0, func
    jalr    t0

    # exit
    li      a7, 10
    ecall

func:
    # print integer in a0
    li      a7, 1
    ecall

    # return
    jr      ra

This contains a function called func defined by the label of that same name. The jalr instruction will assign the ra register to the address of the instruction following the jalr, which is the li assigning 10 to a7. Afterward, the jalr instruction will jump to the address given by the value of the specified register. In this case, it is the value assigned to the t0 register, which was assigned to the address of func by the preceeding la instruction. It will then start executing the instructions at that address starting with the li instruction following the func label. In this case, it will perform an ecall that will print the argument provided to the function in a0 that was assigned prior to the jalr. You will notice that the jalr instruction does not, itself, enforce the calling conventions of the function (argument and return value placement) aside from the assignment of the ra register, which is then used by the jr instruction to return to the calling main function.

jr - Jump to Register

Interprets the given register as a memory address and jumps to that address unconditionally.

main:
    # call func(42)
    li      a0, 42
    jal     func

    # exit
    li      a7, 10
    ecall

func:
    # print integer in a0
    li      a7, 1
    ecall

    # return
    jr      ra

The typical use of the jr instruction is to jump to the ra register after calling a function using the jal or jalr instructions. In this case, the function defined at the label func is called via the jal instruction in main, which performs the jump and assigns the address of the following li instruction in main to ra. The purpose of the jr at the end of func will be to assign that instruction address to pc and, thus, jump to the instruction that immediately follows the jal.

la - Load Address

Moves the address represented by the given label to the given register.

lb - Load Byte

Interprets the register value as a memory address and loads one byte at that address, interpreting it as a signed 8-bit integer, into the given register.

lbu - Load Byte (Unsigned)

Interprets the register value as a memory address and loads one byte at that address, interpreting it as an unsigned 8-bit integer, into the given register.

ld - Load Double-word

Interprets the register value as a memory address and loads one double-word at that address, interpreting it as a signed 64-bit integer, into the given register.

lh - Load Half-word

Interprets the register value as a memory address and loads one half-word at that address, interpreting it as a signed 16-bit integer, into the given register.

lhu - Load Half-word (Unsigned)

Interprets the register value as a memory address and loads one half-word at that address, interpreting it as an unsigned 16-bit integer, into the given register.

li - Load Immediate

Pseudo-instruction that simply loads the given immediate value into the given register.

lui - Load Upper Immediate

Loads the given immediate into bits 31 to 12 of the given register after shifting the immediate value left 12 bits and sign extending to the register width.

lw - Load Word

Interprets the register value as a memory address and loads one word at that address, interpreting it as a signed 32-bit integer, into the given register.

lwu - Load Word (Unsigned)

Interprets the register value as a memory address and loads one word at that address, interpreting it as an unsigned 32-bit integer, into the given register.

mul - Multiply

Multiplies the two given registers and places the lower word of the resulting product in the destination register, interpreting every value as a signed integer.

mulh - Multiply and return High

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting every value as a signed integer.

mulhsu - Multiply and return High (Signed x Unsigned)

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting the first value as a signed integer and the second as an unsigned integer.

mulhu - Multiply and return High (Unsigned)

Multiplies the two given registers and places the higher word of the resulting product in the destination register, interpreting every value as an unsigned integer.

mv - Move

Pseudo-instruction that copies the value from the source register into the destination register.

neg - Negate

Pseudo-instruction that negates the source register, interpreted as a signed 2's-complement integer, and places the result in the destination.

nop - No Operation

Pseudo-instruction that does nothing.

not - Not

Applies the logical NOT operation (1's-complement negation) to the given register and places the result in the destination.

or - Logical OR

Applies the logical OR operation to the given registers and places the result in the destination.

ori - Logical OR (Immediate)

Applies the logical OR operation to the given register and immediate and places the result in the destination.

rem - Integer Remainder

Divides the two given registers and places the resulting remainder in the destination register, interpreting every value as a signed integer.

remu - Integer Remainder (Unsigned)

Divides the two given registers and places the resulting remainder in the destination register, interpreting every value as an unsigned integer.

sb - Store Byte

Interprets the register value as a memory address and stores the given value to the 8-bit byte at that address.

sd - Store Double-word

Interprets the register value as a memory address and stores the given value to the 64-bit region beginning at that address.

seqz - Set If Equal to Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is equal to zero; 0 otherwise.

sgtz - Set If Greater Than Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is positive when interpreted as a signed integer; 0 otherwise.

sh - Store Half-word

Interprets the register value as a memory address and stores the given value to the 16-bit region beginning at that address.

sll - Shift Left Logical

Shifts a 0 into the right-hand side of the given register the number of times provided by the second register.

slli - Shift Left Logical (Immediate)

Shifts a 0 into the right-hand side of the given register the number of times provided by the immediate value.

slt - Set Less Than

Assigns 1 to the destination register if the first register, interpreted as a signed integer, is less than the second register; 0 otherwise.

slti - Set Less Than (Immediate)

Assigns 1 to the destination register if the first register, interpreted as a signed integer, is less than the given immediate; 0 otherwise.

sltiu - Set Less Than (Immediate) (Unsigned)

Assigns 1 to the destination register if the first register, interpreted as an unsigned integer, is less than the given immediate; 0 otherwise.

sltu - Set Less Than (Unsigned)

Assigns 1 to the destination register if the first register, interpreted as an unsigned integer, is less than the given immediate; 0 otherwise.

sltz - Set If Less Than Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is negative when interpreted as a signed integer; 0 otherwise.

snez - Set If Not Equal to Zero

Pseudo-instruction that assigns 1 to the destination register if the given register is not equal to zero; 0 otherwise.

sra - Shift Right Arithmetic

Copies the most-significant bit into the left-hand side of the given register the number of times provided by the second register.

srai - Shift Right Arithmetic (Immediate)

Copies the most-significant bit into the left-hand side of the given register the number of times provided by the immediate.

srl - Shift Right Logical

Shifts a 0 into the left-hand side of the given register the number of times provided by the second register.

srli - Shift Right Logical (Immediate)

Shifts a 0 into the left-hand side of the given register the number of times provided by the immediate.

sub - Subtract

Subtracts the second register from the first given register and places the signed result into the destination register.

sw - Store Word

Interprets the register value as a memory address and stores the given value to the 32-bit region beginning at that address.

xor - Logical XOR

Applies the logical XOR operation to the given registers and places the result in the destination.

xori - Logical XOR (Immediate)

Applies the logical XOR operation to the given register and immediate and places the result in the destination.