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.
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.
The following instructions are supported on the MIPS emulator core:
Conventional Instructions:
Note: This is currently a stubbed instruction to halt emulation.
Floating-Point Instructions:
Pseudo-instructions:
(followed by a label)
(followed by a label)
The RISC-V core supports the RV32I, RV64I, RV32M, RV64M, RV32F, and RV64F extensions. The following instructions are supported in the RISC-V core:
The following directives are supported in the .data segment:
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
While SWIM is currently being hosted here, you can compile and run it locally on your browser as long as it supports WebAssembly.
rustup
at https://www.rust-lang.org/tools/install
rustup target add wasm32-unknown-unknown
in your terminalgit clone
the repository or download the source heretrunk serve --open
in your terminal to load it locallySWIM is licensed under GNU's GPL-3.0 as shown here