Skip to content

Latest commit

 

History

History
883 lines (608 loc) · 41.1 KB

MINA_Instruction_Set_Architecture.md

File metadata and controls

883 lines (608 loc) · 41.1 KB

MINA Instruction Set Architecture

Contents

  1. Introduction
    1. MINA ISA Overview
    2. Events, Faults And Interrupts
    3. Data Types
    4. The Machine Control Register
    5. Event Handling
    6. The Stack
  2. MINA32 Base Integer Instruction Set, Version 1
    1. Overview
    2. Base Instruction Formats
    3. Arithmetic Instructions
    4. Logical Instructions
    5. Compare Instructions
    6. Register Branch Instructions
    7. Memory Access Instructions
    8. Move Instructions
    9. Shift Instructions
    10. Control Instructions
    11. PC-Relative Branch Instructions
  3. FloatingMINA Floating-Point Instruction Set Extension, Version 0
  4. VectorMINA SIMD Instruction Set Extension, Version 0

Introduction

MINA is an open instruction set architecture (ISA) designed to be easy to decode while still providing features similar to those found in earlier ARM processors.

Current and future goals include:

  • An ISA suitable for hardware implementation.
  • An easily extendible base ISA.
  • 32-bit and 64-bit address space variants.

1.1. MINA ISA Overview

The MINA ISA is defined as a base integer ISA with optional floating-point, vector (SIMD) and user-defined extensions. Current base integer ISAs are MINA32 and MINA64, which has not been defined yet. (Currently un-)Available (and optional) extensions include FloatingMINA (floating-point extension) and VectorMINA (single instruction, multiple data extension); other extensions have not been defined yet.

The base integer ISA must be present in any implementation.


1.2. Events, Faults And Interrupts

On MINA systems, unusual conditions occurring at run time (i.e. during instruction execution) are referred to as events.

Events that occur synchronously to the current MINA thread are referred to as faults, and transfer control to a fault handler.

External events that occur asynchronously to the current MINA thread are referred to as interrupts. Interrupt events that must be serviced transfer control to a fault handler at the end of the currently running instruction.

All types of faults that can be generated by instructions are described in the detailed instruction description sections of this ISA manual.


1.3. Data Types

The MINA ISA defines the following data types:

  • Byte (8-bit)
  • Halfword (16-bit)
  • Word (32-bit)
  • Longword (64-bit)

More data types will be defined in future versions of the MINA ISA.


1.4. The Machine Control Register

The Machine Control Register (MCR) is a an important register containing information about the current state of the MINA implementation. It is a 64-bit (longword) register and accessible through special move and load-store instructions.

MCR: [OMCR(32)][zero(12)][ID(1)][T(1)][Mode(2)][zero(4)][Cause(4)][Comment(8)]

OMCR is a special 32-bit field holding a copy of the low 32 bits of MCR during fault handling.

ID is the Interrupt Disable bit. If this bit is set, external events do not generate an External Interrupt fault; the current state of the ID field does not affect the operation of WFI.

T is the Condition True bit. If this bit is set, T variants of conditional instructions execute. If this bit is clear, F variants of conditional instructions execute.

The 2-bit Mode field contains information about the current CPU mode. Possible values are:

  • 00: User
  • 01: Supervisor
  • 10: reserved
  • 11: reserved

Switching to a reserved mode generates an Invalid State fault.

The 4-bit Cause field contains information about the type of the current fault. Possible values are:

  • 0000: Misaligned Load Address
  • 0001: Misaligned Store Address
  • 0010: reserved
  • 0011: reserved
  • 0100: Invalid State
  • 0101: Privilege Mismatch
  • 0110: reserved
  • 0111: reserved
  • 1000: Undefined Instruction
  • 1001: reserved
  • 1010: reserved
  • 1011: reserved
  • 1100: External Interrupt
  • 1101: User Interrupt
  • 1110: Supervisor Call
  • 1111: Reset

The 8-bit Comment field can be used to pass information from the current User mode thread to the Supervisor thread. Control group fault-generating instructions load this field with a user-defined value.


1.5. Event Handling

As soon as a fault event is generated, the MINA implementation saves the address of the current or next instruction (depending on the fault cause) in the Fault Return Address (FRET) register and jumps to a special memory address called the fault handler address (00000000h on MINA32). The low 32 bits of MCR are saved in the high 32 bits of MCR (OMCR), the current CPU mode is set to Supervisor mode, the ID bit is set.

To return to the User mode thread and restore MCR, use the SWITCH instruction.


1.6. The Stack

MINA uses a full-descending stack model. Push operations decrement the stack pointer before storing a value on the stack, pull operations increment the stack pointer after loading a value from the stack.


MINA32 Base Integer Instruction Set, Version 1

The following section describes version 1 of the MINA32 base integer ISA.


2.1. Overview

MINA32 has 16 32-bit general-purpose registers (r0-r15), which hold integer values. Registers r8-r15 are banked, each mode has its own copies of these registers. Register r15 (SP) is a hardwired stack pointer, though it can also be used as a regular GPR outside of stack operations. A user-visible program counter (PC) register holds the address of the current instruction.


2.2. Base Instruction Formats

In MINA32, there are five core instruction formats (S/I/M/F/B). Instructions must be aligned on a four-byte boundary; misaligned instructions generate Misaligned Load Address faults.

Instruction Formats:

S-type: [group(4)][opcode(4)][src1(4)][src2 (4)][dest(4)][ SBZ  (4)][ SBZ  (8)]
I-type: [group(4)][opcode(4)][src1(4)][shift(4)][dest(4)][ imm  (4)][ imm  (8)]
M-type: [group(4)][opcode(4)][SBZ (4)][ imm (4)][dest(4)][ imm  (4)][ imm  (8)]
F-type: [group(4)][opcode(4)][src1(4)][src2 (4)][dest(4)][rshift(4)][ SBZ  (8)]
B-type: [group(4)][opcode(4)][              offset             (16)][offset(8)]

S-type: The S-type format is the standard instruction format and used by most arithmetic and logical instructions.

I-type: The I-type format is the immediate type format and provides a specific set of instructions with a shifted 12-bit immediate. The immediate is left-shifted by the 4-bit amount specified in the shift field.

M-type: The M-type format is the move type format and provides instructions supporting this format with a shifted 16-bit immediate. The immediate is left-shifted by either 0 or 16, depending on the instruction.

F-type: The F-type format is the funnel shift type format. It is the only format to provide four register indices and is used exclusively by FLSL and FLSR.

B-type: The B-type format is the branch type format and used by BRA (PC-relative branch), CALL (PC-relative call) and their conditional counterparts (BT/BF/CALLT/CALLF). The offset is left-shifted by 2. Register and immediate offset register branches and calls (RBRA/RCALL/ROBRA/ROCALL) use variations of the S- and I-type formats.

Immediates (imm and offset fields) are sign-extended; I-type immediates are sign-extended before the shift is applied. M-type immediates are an exception: they are not sign-extended.


2.3. Arithmetic Instructions

All arithmetic instructions operate on 32-bit values. Arithmetic instructions use the S- and I-type instruction formats, enabling register-immediate and register-register operations respectively. Arithmetic instructions do not cause any fault events; conditions such as arithmetic overflows are ignored.

The group field is 0000 for these instructions.

Register-Immediate Instructions

[opcode = 0000] ADDI adds the sign-extended and shifted 12-bit immediate to register src1, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers.

[opcode = 0001] MULTI multiplies the sign-extended and shifted 12-bit immediate with register src1, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers.

[opcode = 0010] DIVI divides register src1 by the sign-extended and shifted 12-bit immediate, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. Note: this instruction is optional and generates an Undefined Instruction fault on implementations that do not support this instruction.

[opcode = 0011] REMI computes the remainder of the division of register src1 by the sign-extended and shifted 12-bit immediate, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. Note: this instruction is optional and generates an Undefined Instruction fault on implementations that do not support this instruction.

[opcode = 0100] SLTI sets register dest to 1 if register src1 is less than the sign-extended and shifted 12-bit immediate, 0 otherwise. Both operands are treated as signed numbers.

[opcode = 0101] SLTIU sets register dest to 1 if register src1 is less than the sign-extended and shifted 12-bit immediate, 0 otherwise. Both operands are treated as unsigned numbers.

[opcode = 0110] NOP advances register pc without altering the user-visible state. The src1, shift, dest and imm fields are ignored and should be 0.

[opcode = 0111] PCADDI adds the sign-extended and shifted 12-bit immediate to register pc, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. The src1 field is ignored and should be 0.

Register-Register Instructions

[opcode = 1000] ADD adds register src2 to register src1, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers.

[opcode = 1001] MULT multiplies register src2 with register src1, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers.

[opcode = 1010] DIV divides register src1 by register src2, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. Note: this instruction is optional and generates an Undefined Instruction fault on implementations that do not support this instruction.

[opcode = 1011] REM computes the remainder of the division of register src1 by register src2, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. Note: this instruction is optional and generates an Undefined Instruction fault on implementations that do not support this instruction.

[opcode = 1100] SLT sets register dest to 1 if register src1 is less than register src2, 0 otherwise. Both operands are treated as signed numbers.

[opcode = 1101] SLTU sets register dest to 1 if register src1 is less than register src2, 0 otherwise. Both operands are treated as unsigned numbers.

[opcode = 1110] SUB subtracts register src2 from register src1, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers.

[opcode = 1111] PCADD adds register src1 to register pc, the low 32 bits of the result are placed in register dest. Both operands are treated as unsigned numbers. The src2 field is ignored and should be 0.

# I-type
addi()
{
    dest = src1 + (sign_extend(imm12) << shift)
}

multi()
{
    dest = src1 * (sign_extend(imm12) << shift)
}

divi()
{
    if (unsupported)
    {
        fret = pc + 4
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (8 << 8)
        pc   = [fault handler address]
        return
    }

    if (division_by_0)
    {
        dest = 0
    }
    else
    {
        dest = src1 / (sign_extend(imm12) << shift)
    }
}

remi()
{
    if (unsupported)
    {
        fret = pc + 4
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (8 << 8)
        pc   = [fault handler address]
        return
    }

    if (division_by_0)
    {
        dest = 0
    }
    else
    {
        dest = src1 % (sign_extend(imm12) << shift)
    }
}

slti()
{
    dest = if ((signed)src1 < (signed)(sign_extend(imm12) << shift)) then 1 else 0
}

sltiu()
{
    dest = if (src1 < (sign_extend(imm12) << shift)) then 1 else 0
}

nop()
{
    dest = src1 + (sign_extend(imm12) << shift)
}

pcaddi()
{
    dest = pc + (sign_extend(imm12) << shift)
}

# S-type
add()
{
    dest = src1 + src2
}

mult()
{
    dest = src1 * src2
}

div()
{
    if (unsupported)
    {
        fret = pc + 4
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (8 << 8)
        pc   = [fault handler address]
        return
    }

    if (division_by_0)
    {
        dest = 0
    }
    else
    {
        dest = src1 / src2
    }
}

rem()
{
    if (unsupported)
    {
        fret = pc + 4
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (8 << 8)
        pc   = [fault handler address]
        return
    }

    if (division_by_0)
    {
        dest = 0
    }
    else
    {
        dest = src1 % src2
    }
}

slt()
{
    dest = if ((signed)src1 < (signed)src2) then 1 else 0
}

sltu()
{
    dest = if (src1 < src2) then 1 else 0
}

sub()
{
    dest = src1 - src2
}

pcadd()
{
    dest = src1 + pc
}

2.4. Logical Instructions

All logical instructions operate on 32-bit values. Logical instructions use the S- and I-type instruction formats, enabling register-immediate and register-register operations respectively. Logical instructions do not cause any fault events.

The group field is 0001 for these instructions.

Register-Immediate Instructions

[opcode = 0000] ANDI logically ANDs the sign-extended and shifted 12-bit immediate with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 0001] ORI logically ORs the sign-extended and shifted 12-bit immediate with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 0010] XORI logically XORs the sign-extended and shifted 12-bit immediate with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 0011] NANDI logically NANDs the sign-extended and shifted 12-bit immediate with register src1, the low 32 bits of the result are placed in register dest. Note: this instruction is currently under review.

Register-Register Instructions

[opcode = 1000] AND logically ANDs register src2 with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 1001] OR logically ORs register src2 with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 1010] XOR logically XORs register src2 with register src1, the low 32 bits of the result are placed in register dest.

[opcode = 1011] NAND logically NANDs register src2 with register src1, the low 32 bits of the result are placed in register dest. Note: this instruction is currently under review.

[opcode = 1100] POPCNT computes the population count of register src1, the result is placed in register dest. The src2 field is ignored and should be 0.

[opcode = 1101] CLO computes the number of leading 1s in register src1, the result is placed in register dest. The src2 field is ignored and should be 0.

[opcode = 1110] PLO computes the position of the leading 1 in register src1, the result is placed in register dest. If register src1 is 0, the result is 32. The src2 field is ignored and should be 0.

# I-type
andi()
{
    dest = src1 & (sign_extend(imm12) << shift)
}

ori()
{
    dest = src1 | (sign_extend(imm12) << shift)
}

xori()
{
    dest = src1 ^ (sign_extend(imm12) << shift)
}

nandi()
{
    dest = src1 & ~(sign_extend(imm12) << shift)
}

# S-type
and()
{
    dest = src1 & src2
}

or()
{
    dest = src1 | src2
}

xor()
{
    dest = src1 ^ src2
}

nand()
{
    dest = src1 & ~src2
}

popcnt()
{
    dest = 0

    for (bit in src1)
    {
        dest = dest + if (bit == 1) then 1 else 0
    }
}

clo()
{
    dest = 0

    for (i = 31; i >= 0; i = i - 1)
    {
        if (((src >> i) & 1) == 1)
        {
            dest = dest + 1
        }
        else
        {
            return
        }
    }
}

plo()
{
    dest = 32

    if (src1 == 0)
    {
        return
    }

    for (i = 31; i >= 0; i = i - 1)
    {
        dest = dest - 1

        if (((src1 >> i) & 1) == 1)
        {
            return
        }
    }
}

2.5. Compare Instructions

Unlike SLTI/SLTIU/SLT/SLTU, compare instructions set or clear the T bit for use with conditional branch and move instructions. Compare instructions use the S- and I-type instruction formats, enabling register-immediate and register-register operations respectively. Compare instructions do not cause any fault events.

The group field is 0010 for these instructions.

Register-Immediate Instructions

[opcode = 0000] CMPI/EQ compares the sign-extended and shifted 12-bit immediate with register src1. The T bit is set to the result of src1 == imm. The dest field is ignored and should be 0.

[opcode = 0001] CMPI/LO compares the sign-extended and shifted 12-bit immediate with register src1. The T bit is set to the result of src1 < imm. Both operands are treated as unsigned numbers. The dest field is ignored and should be 0.

[opcode = 0010] CMPI/LS compares the sign-extended and shifted 12-bit immediate with register src1. The T bit is set to the result of src1 <= imm. Both operands are treated as unsigned numbers. The dest field is ignored and should be 0.

[opcode = 0011] CMPI/LT compares the sign-extended and shifted 12-bit immediate with register src1. The T bit is set to the result of src1 < imm. Both operands are treated as signed numbers. The dest field is ignored and should be 0.

[opcode = 0100] CMPI/LE compares the sign-extended and shifted 12-bit immediate with register src1. The T bit is set to the result of src1 <= imm. Both operands are treated as signed numbers. The dest field is ignored and should be 0.

Register-Register Instructions

[opcode = 1000] CMP/EQ compares register src2 with register src1. The T bit is set to the result of src1 == src2. The dest field is ignored and should be 0.

[opcode = 1001] CMP/LO compares register src2 with register src1. The T bit is set to the result of src1 < src2. Both operands are treated as unsigned numbers. The dest field is ignored and should be 0.

[opcode = 1010] CMP/LS compares register src2 with register src1. The T bit is set to the result of src1 <= src2. Both operands are treated as unsigned numbers. The dest field is ignored and should be 0.

[opcode = 1011] CMP/LT compares register src2 with register src1. The T bit is set to the result of src1 < src2. Both operands are treated as signed numbers. The dest field is ignored and should be 0.

[opcode = 1100] CMP/LE compares register src2 with register src1. The T bit is set to the result of src1 <= src2. Both operands are treated as signed numbers. The dest field is ignored and should be 0.

# I-type
cmpieq()
{
    T = if (src1 == (sign_extend(imm12) << shift)) then 1 else 0
}

cmpilo()
{
    T = if (src1 < (sign_extend(imm12) << shift)) then 1 else 0
}

cmpils()
{
    T = if (src1 <= (sign_extend(imm12) << shift)) then 1 else 0
}

cmpilt()
{
    T = if ((signed)src1 < (signed)(sign_extend(imm12) << shift)) then 1 else 0
}

cmpils()
{
    T = if ((signed)src1 <= (signed)(sign_extend(imm12) << shift)) then 1 else 0
}

# S-type
cmpeq()
{
    T = if (src1 == src2) then 1 else 0
}

cmplo()
{
    T = if (src1 < src2) then 1 else 0
}

cmpls()
{
    T = if (src1 <= src2) then 1 else 0
}

cmplt()
{
    T = if ((signed)src1 < (signed)src2) then 1 else 0
}

cmpls()
{
    T = if ((signed)src1 <= (signed)src2) then 1 else 0
}

2.6. Register Branch Instructions

Register branch instructions allow for (offset) indirect jumps, unlike their PC-relative counterparts. It is not possible to execute register branch instructions conditionally. Register branch instructions use variations of the S- and I-type instruction formats, enabling register-immediate and register-register operations respectively. Register branch instructions can generate Misaligned Load Address and Misaligned Store Address fault events.

The group field is 0011 for these instructions.

Register-Immediate Instructions

[opcode = 0000] RBRA computes a target address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The resulting target address is placed in register pc. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 0001] RCALL computes a target address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The address of the next instruction is saved on the stack. The resulting target address is placed in register pc. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated. If r15 is not aligned on a four-byte boundary, a Misaligned Store Address fault event is generated.

[opcode = 0010] RET pulls a 32-bit word off the stack and places it in register pc, enabling applications to return from CALL/RCALL/ROCALL. If the target address and/or r15 are not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

Register-Register Instructions

[opcode = 1000] ROBRA computes a target address by adding the contents of register src2 to register src1. The resulting target address is placed in register pc. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 1001] ROCALL computes a target address by adding the contents of register src2 to register src1. The address of the next instruction is saved on the stack. The resulting target address is placed in register pc. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

# I-type
rbra()
{
    target = src1 + (sign_extend(imm12) << (shift + 2))

    if ((target & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    pc = target
}

rcall()
{
    if ((r15 & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (1 << 8)
        pc   = [fault handler address]
        return
    }

    target = src1 + (sign_extend(imm12) << (shift + 2))

    if ((target & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    r15 = r15 - 4

    mem[r15] = pc + 4

    pc = target
}

ret()
{
    if ((r15 & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    target = mem[r15]

    if ((target & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    r15 = r15 + 4

    pc = target
}

# S-type
robra()
{
    target = src1 + src2

    if ((target & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    pc = target
}

rocall()
{
    if ((r15 & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (1 << 8)
        pc   = [fault handler address]
        return
    }

    target = src1 + src2

    if ((target & 3) != 0)
    {
        fret = pc
        mcr  = mcr << 32
        mcr  = mcr | (1 << 19) | (1 << 16) | (0 << 8)
        pc   = [fault handler address]
        return
    }

    r15 = r15 - 4

    mem[r15] = pc + 4

    pc = target
}

2.7. Memory Access Instructions

MINA is a load-store architecture, which means that load-store instructions access memory and computational instructions only operate on registers. MINA32 is Little Endian and provides a byte-addressable 32-bit address space. Memory access instructions use the S- and I-type instruction formats, enabling register-immediate and register-register operations respectively. Memory access instructions can generate Misaligned Load Address, Misaligned Store Address and Privilege Mismatch fault events.

The group field is 0100 for these instructions.

Register-Immediate Instructions

[opcode = 0000] LD computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The 32-bit word located at the memory address is placed in register dest. If the memory address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 0001] LDH computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 1 is implicitly added to the shift field. The 16-bit halfword located at the memory address is placed in register dest. If the memory address is not aligned on a two-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 0010] LDB computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. The 8-bit byte located at the memory address is placed in register dest.

[opcode = 0011] ST computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The 32-bit word in register dest is stored at the memory address. If the memory address is not aligned on a four-byte boundary, a Misaligned Store Address fault event is generated.

[opcode = 0100] STH computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 1 is implicitly added to the shift field. The 16-bit halfword in the lower half of register dest is stored at the memory address. If the memory address is not aligned on a two-byte boundary, a Misaligned Store Address fault event is generated.

[opcode = 0101] STB computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. The low 8-bit byte of register dest is stored at the memory address.

[opcode = 0110] LDC computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The 32-bit word located at the memory address is placed in the machine control register. The dest field is ignored and should be 0. If the memory address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 0111] STC computes a memory address by adding the sign-extended and shifted 12-bit immediate to register src1. 2 is implicitly added to the shift field. The machine control register is stored at the memory address. The dest field is ignored and should be 0. If the memory address is not aligned on a four-byte boundary, a Misaligned Store Address fault event is generated.

Register-Register Instructions

[opcode = 1000] RLD computes a memory address by adding the signed representation of register src2 to register src1. The 32-bit word located at the memory address is placed in register dest. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 1001] RLDH computes a memory address by adding the signed representation of register src2 to register src1. The 16-bit halfword located at the memory address is placed in register dest. If the target address is not aligned on a two-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 1010] RLDB computes a memory address by adding the signed representation of register src2 to register src1. The 8-bit byte located at the memory address is placed in register dest. LDB does not generate a Misaligned Load Address fault event.

[opcode = 1011] RST computes a memory address by adding the signed representation of register src2 to register src1. The 32-bit word in register dest is stored at the memory address. If the target address is not aligned on a four-byte boundary, a Misaligned Store Address fault event is generated.

[opcode = 1100] RSTH computes a memory address by adding the signed representation of register src2 to register src1. The 16-bit halfword in the lower half of register dest is stored at the memory address. If the target address is not aligned on a two-byte boundary, a Misaligned Store Address fault event is generated.

[opcode = 1101] RSTB computes a memory address by adding the signed representation of register src2 to register src1. The low 8-bit byte of register dest is stored at the memory address. STB does not generate a Misaligned Store Address fault event.

[opcode = 1110] POP pulls a 32-bit word off the stack and places it in register dest. The src1 and src2 fields are ignored and should be 0. If the target address is not aligned on a four-byte boundary, a Misaligned Load Address fault event is generated.

[opcode = 1111] PUSH pushes register dest onto the stack. The src1 and src2 fields are ignored and should be 0. If the target address is not aligned on a four-byte boundary, a Misaligned Store Address fault event is generated.


2.8. Move Instructions

Move instructions load immediate data and registers into other registers. Move instructions use the S-type, I-type and M-type instruction formats, enabling register-immediate, register-register and special move operations respectively. Move instructions may generate a Privilege Mismatch fault event.

The group field is 0101 for these instructions.

Register-Immediate Instructions

[opcode = 0000] MOVI moves the sign-extended and shifted 12-bit immediate to register dest. The src1 field is ignored and should be 0.

[opcode = 0001] MTI moves the sign-extended and shifted 12-bit immediate to register dest if the T bit is set. The src1 field is ignored and should be 0.

[opcode = 0010] MFI moves the sign-extended and shifted 12-bit immediate to register dest if the T bit is clear. The src1 field is ignored and should be 0.

Special Move Instructions

[opcode = 0011] MOVL moves the 16-bit immediate to the lower half of register dest without clearing the upper half. The 16-bit immediate is not sign-extended.

[opcode = 0100] MOVU moves the 16-bit immediate to the upper half of register dest and clears the lower half. The 16-bit immediate is not sign-extended.

Register-Register Instructions

[opcode = 1000] MOV moves register src1 to register dest. The src2 field is ignored and should be 0.

[opcode = 1001] MT moves register src1 to register dest if the T bit is set. The src2 field is ignored and should be 0.

[opcode = 1010] MF moves register src1 to register dest if the T bit is clear. The src2 field is ignored and should be 0.

[opcode = 1011] MTOC moves register dest to the machine control register. The src1 and src2 fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 1100] MFRC moves the machine control register to register dest. The src1 and src2 fields are ignored and should be 0.

[opcode = 1101] MTOU moves the Supervisor mode register src1 to the User mode register dest. The src2 field is ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 1110] MFRU moves the User mode register src1 to the Supervisor mode register dest. The src2 field is ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.


2.9. Shift Instructions

All shift instructions operate on either 32-bit or 64-bit values. Shift instructions use the S-type, I-type and F-type instruction formats, enabling register-immediate, register-register and special (funnel) shift operations respectively. Shift instructions do not cause any fault events.

The group field is 0110 for these instructions.

Register-Immediate Instructions

[opcode = 0000] LSL left-shifts register src1 by the 4-bit amount in the shift field. The result is placed in register dest. The imm field is ignored and should be 0.

[opcode = 0001] LSR right-shifts register src1 by the 4-bit amount in the shift field. LSR does not preserve the most significant bit and shifts in 0s. The result is placed in register dest. The imm field is ignored and should be 0.

[opcode = 0010] ASR right-shifts register src1 by the 4-bit amount in the shift field. ASR preserves the most significant bit. The result is placed in register dest. The imm field is ignored and should be 0.

[opcode = 0011] ROR right-rotates register src1 by the 4-bit amount in the shift field. The result is placed in register dest. The imm field is ignored and should be 0.

Register-Register Instructions

[opcode = 1000] RLSL left-shifts register src1 by the amount in register src2. The shift amount is masked to 5 bits. The result is placed in register dest.

[opcode = 1001] RLSR right-shifts register src1 by the amount in register src2. The shift amount is masked to 5 bits. RLSR does not preserve the most significant bit and shifts in 0s. The result is placed in register dest.

[opcode = 1010] RASR right-shifts register src1 by the amount in register src2. The shift amount is masked to 5 bits. RASR preserves the most significant bit. The result is placed in register dest.

[opcode = 1011] RROR right-rotates register src1 by the 4-bit amount in register src2. The shift amount is masked to 5 bits. The result is placed in register dest.

Special Shift Instructions

[opcode = 1100] FLSL concatenates register src1 and src2 and left-shifts the resulting 64-bit longword by the amount in register rshift. The shift amount is masked to 5 bits. The high 32 bits of the result are placed in register dest.

[opcode = 1101] FLSR concatenates register src1 and src2 and right-shifts the resulting 64-bit longword by the amount in register rshift. The shift amount is masked to 5 bits. FLSR does not preserve the most significant bit and shifts in 0s. The low 32 bits of the result are placed in register dest.


2.10. Control Instructions

Control instructions control the state of a MINA implementation. Control instructions use the S-type and I-type instruction formats. Control instructions may generate fault events.

The group field is 0111 for these instructions.

Register-Immediate Instructions

[opcode = 0000] STOP effectively shuts down a MINA implementation until a reset occurs. The src1, shift, dest and imm fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 0001] WFI effectively puts a MINA implementation to sleep until an external event (interrupt) occurs. The src1, shift, dest and imm fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 0010] SETT unconditionally sets the T bit. The src1, shift, dest and imm fields are ignored and should be 0.

[opcode = 0011] CLRT unconditionally clears the T bit. The src1, shift, dest and imm fields are ignored and should be 0.

[opcode = 0100] SWITCH restores the old state of a MINA implementation at the end of fault handlers. The high 32 bits of the MCR are moved to the low 32 bits of the MCR and register pc is set to the Fault Return Address register. The src1, shift, dest and imm fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

Register-Immediate Instructions

[opcode = 1000] SVCALL moves the low byte of register dest to the Comment field in the machine control register and generates a Supervisor Call fault event, enabling User mode programs to communicate with a Supervisor program. The src1 and src2 fields are ignored and should be 0.

[opcode = 1001] FAULT moves the low byte of register dest to the Comment field in the machine control register and generates a fault event according to the low 4 bits of register src1, enabling Supervisor programs to test fault handlers. The src2 field is ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 1010] MTOF moves register dest to the Fault Return Address register. The src1 and src2 fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.

[opcode = 1011] MFRF moves the Fault Return Address register to register dest. The src1 and src2 fields are ignored and should be 0. This is a privileged instruction; executing this instruction in User mode generates a Privilege Mismatch fault event.


2.11. PC-Relative Branch Instructions

PC-relative branch instructions enable branches relative to the memory address of the current location. PC-relative branch instructions use the B-type instruction format. These instructions can be executed conditionally. The offset is left-shifted by 2 after it has been sign-extended. PC-relative branch instructions do not cause any fault events.

The group field is 1000 for these instructions.

PC-Relative Branch Instructions

[opcode = 0000] BRA computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The resulting target address is placed in register pc.

[opcode = 0001] BT computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The resulting target address is placed in register pc if the T bit is set.

[opcode = 0010] BF computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The resulting target address is placed in register pc if the T bit is clear.

PC-Relative Call Instructions

[opcode = 1000] CALL computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The address of the next instruction is pushed onto the stack. The resulting target address is placed in register pc.

[opcode = 1001] CT computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The address of the next instruction is pushed onto the stack and the resulting target address is placed in register pc only if the T bit is set.

[opcode = 1010] CF computes a target address by adding the sign-extended and shifted 24-bit offset to register pc. The offset is implicitly left-shifted by 2. The address of the next instruction is pushed onto the stack and the resulting target address is placed in register pc only if the T bit is clear.