SWIM-ucf / SWIM

Simple Web Interface for eMulation
https://swim-ucf.github.io/SWIM/
GNU General Public License v3.0
8 stars 1 forks source link

SWIM (Simple Web Interface for eMulation)

This was originally developed by Kevin Cahalan, Jerrett Longworth, Huy Nguyen, Evan Raiford, and Jimmie Smith at UCF as a senior design project. Version 2 was developed by Ryan Harding, Cay Henning, Cameron McDougal, and Brooks McKinley as their senior design project.

Screenshot of Swim V1

A web-based emulator for MIPS64/RISC-V made for educational purposes. The user interface that provides the following features:

All of this wholly developed with the Rust language with the interface built with the Yew framework which uses WebAssembly and JavaScript to house the emulation core and parser/assembler.

MIPS Support

The following instructions are supported on the MIPS emulator core:

RISC-V Support

The RISC-V core supports the RV32I, RV64I, RV32M, RV64M, RV32F, and RV64F extensions. The following instructions are supported in the RISC-V core:

Data Directives

The following directives are supported in the .data segment:

System Calls and IO

SWIM supports IO through the console. Upon executing the syscall instruction in MIPS or the ecall instruction in RISC-V, SWIM will attempt to perform a syscall based on the values of the argument registers.

In both MIPS and RISC-V, the call number is extracted from the a0 register, and the integer/memory address argument are extracted from the a1 register. For floating point arguments, the value is extracted from the f0 register for MIPS and f10 for RISC-V.

For return values, in MIPS, the return value for a syscall is placed in the v0 register while in RISC-V it's placed in the a1 register. For floating point return values, the result is returned to f0 for MIPS and f10 for RISC-V.

The following table shows a list of the supported syscalls and their arguments.

Name Description Call Number Argument Type Return Type
exit Halts the emulator core 0 None None
print_int Prints the integer value in the argument register 1 Integer None
print_float Prints the float value in the argument register 2 Float None
print_double Prints the double value in the argument register 3 Double None
print_string Prints a string to console, starting at the memory address in the register and ending at a null byte 4 Memory Address None
read_int Reads the next int from the console and stores it in the argument register 5 None Integer
read_float Reads the next float from the console and stores it in the argument register 6 None Float
read_double Reads the next double from the console and stores it in the argument register 7 None Double
read_string Reads from the console until a newline character is encountered and stores it in the provided memory address with a null terminator. Returns the number of bytes read. 8 Memory Address Integer

Each of the syscall names are also pseudo-instructions that translate into the instructions to set the a0 register to the correct value and perform the syscall instruction.

As an example, the following RISC-V assembly reads an integer typed by the user, doubles it, and then prints it out.

read_int
add a1, a1, a1
print_int
exit

Compiling

While SWIM is currently being hosted here, you can compile and run it locally on your browser as long as it supports WebAssembly.

  1. Install the latest stable rust toolchain with rustup at https://www.rust-lang.org/tools/install
    • If you plan on compiling the source yourself, make sure to add WebAssembly as a compile target by typing rustup target add wasm32-unknown-unknown in your terminal
  2. Install trunk
  3. git clone the repository or download the source here
  4. When you are in the root directory of the project, type trunk serve --open in your terminal to load it locally

Licensing

SWIM is licensed under GNU's GPL-3.0 as shown here