commit d23a3e49ffd17322c16ec8b23b760a72da34f102 Author: cannoli-fruit Date: Fri Jul 24 02:56:45 2026 -0400 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ef9604 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1a426d8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Lazyc"] + path = Lazyc + url = https://youra.monster/git/Cody/Lazyc.git diff --git a/ISA.md b/ISA.md new file mode 100644 index 0000000..eab87de --- /dev/null +++ b/ISA.md @@ -0,0 +1,352 @@ +# FP-Isa +Isa mostly made to run a version of a programming language i once made called flagpole +The compiler for that was written in python and used llvm so that's kinda yucky yk +and whole new isa so that i can have some fun idk + +Registers (64 bit): +xSp -> Stack pointer (11111100) +xBp -> Base pointer (11111101) +xPc -> Program Counter (11111111) +r0-r127 -> General purpose (0xxxxxxx) xxxxxxx = r# in bin + +Registers (32 bit): +h0-h127 -> General purpose (0xxxxxxx) xxxxxxx = h# in bin +^ Just the bottom 32 bits of r0-r127 + +r0 & h0 are both null registers +in general programming only use h0-h95, the rest are for assembler (or i guess compiler if yours lets you control registers?) + +Flag Register: +Flag register is small with flags Zero, Negative, Positive, Oddness all as single bits (See SetF instructions) + +Endianness: +everything is big endian bru (if you don't know what that means you can ignore it) + +Memory addresses: +Every program is loaded at memory address 0x4000000000000000 +All data between 0xC000000000000000 and 0xD000000000000000 are for MMIO (implementation specific!) +the stack's base is at 0x7FFFFFFFFFFFFFFF and grows down + +Instructions: +All instructions start with a 1 byte opcode +depending on the first bits the operands change +000: no operands +001: ^ +010: 1 byte of operands (likely reg) +011: 2 bytes of operands (likely 2 reg) +100: ^ +101: 4 bytes of operands (likely immediate) +110: 1 byte of operands (jump addr reg) +111: 9 bytes of operands (likely reg, immediate) + +Opcode Table + ++-----------+----------+---------------------------------------------------------------------------+ +| Mneumonic | Opcode | Description | ++-----------+----------+---------------------------------------------------------------------------+ +| AddR32 | 011xxxxx | AddR32 dst, src adds the value in src to dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| SubR32 | 011xxxxx | SubR32 dst, src subtracts the value in src from dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| MulR32 | 011xxxxx | MulR32 dst, src multiplies the value in dst by src, result in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IMulR32 | 011xxxxx | IMulR32 dst, src multiplies the value in dst by src, result in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| DivR32 | 011xxxxx | DivR32 dst, src divides dst by src, Quo in dst, Rem is ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IDivR32 | 011xxxxx | IDivR32 dst, src divides dst by src, Quo in dst, Rem is ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| ModR32 | 011xxxxx | ModR32 dst, src divides dst by src, Rem in dst, Quo is ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IModR32 | 011xxxxx | IModR32 dst, src divides dst by src, Rem in dst, Quo is ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| Shr32 | 011xxxxx | Shr32 dst, src logical shifts dst right by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Shl32 | 011xxxxx | Shl32 dst, src logical shifts dst left by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Sar32 | 011xxxxx | Sar32 dst, src arithmetic shifts dst right by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| And32 | 011xxxxx | And32 dst, src performs logical ands dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Or32 | 011xxxxx | Or32 dst, src performs logical ors dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Xor32 | 011xxxxx | Xor32 dst, src performs logical xors dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Not32 | 010xxxxx | Not reg performs bitwise not operation on the 32 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| AddR64 | 011xxxxx | AddR64 dst, src adds the value in src to dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| SubR64 | 011xxxxx | SubR64 dst, src subtracts the value in src from dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| MulR64 | 011xxxxx | MulR64 dst, src multiplies the value in dst by src, result in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IMulR64 | 011xxxxx | IMulR64 dst, src multiplies the value in dst by src, result in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| ModR64 | 011xxxxx | ModR64 dst, src divides dst by src, Rem in dst, Quo is ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IModR64 | 011xxxxx | IModR64 dst, src divides dst by src, Rem in dst, Quo is ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| DivR64 | 011xxxxx | DivR64 dst, src divides dst by src, Quo in dst, Rem is ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IDivR64 | 011xxxxx | IDivR64 dst, src divides dst by src, Quo in dst, Rem is ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| Shr64 | 011xxxxx | Shr64 dst, src logical shifts dst right by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Shl64 | 011xxxxx | Shl64 dst, src logical shifts dst left by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Sar64 | 011xxxxx | Sar64 dst, src arithmetic shifts dst right by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| And64 | 011xxxxx | And64 dst, src performs logical ands dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Or64 | 011xxxxx | Or64 dst, src performs logical ors dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Xor64 | 011xxxxx | Xor64 dst, src performs logical xors dst with src and returns in dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Not64 | 010xxxxx | Not reg performs bitwise not operation on the 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| FAdd | 011xxxxx | FAdd dst, src adds src to dst as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FSub | 011xxxxx | FSub dst, src subtracts src from dst as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FMul | 011xxxxx | FMul dst, src multiplies dst by src as a 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FDiv | 011xxxxx | FDiv dst, src divides dst by src as a 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| DAdd | 011xxxxx | DAdd dst, src adds src to dst as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DSub | 011xxxxx | DSub dst, src subtracts src from dst as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DMul | 011xxxxx | DMul dst, src multiplies dst by src as a 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DDiv | 011xxxxx | DDiv dst, src divides dst by src as a 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| FtoI | 011xxxxx | FtoI dst, src converts src from 32b float to int (trunc), save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| DtoI | 011xxxxx | DtoI dst, src converts src from 64b double to int (trunc), save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| ItoF | 011xxxxx | ItoF dst, src converts src from int to 32b float, save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| ItoD | 011xxxxx | ItoD dst, src converts src from int to 64b double, save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| Jmp | 110xxxxx | Jump Absolutely With 64 bit register value | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIZ | 110xxxxx | Jump Absolutely With 64 bit register value If Zero flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIN | 110xxxxx | Jump Absolutely With 64 bit register value If Negative flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIP | 110xxxxx | Jump Absolutely With 64 bit register value If Positive flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIO | 110xxxxx | Jump Absolutely With 64 bit register value If Parity flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNZ | 110xxxxx | Jump Absolutely With 64 bit register value If Zero flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNN | 110xxxxx | Jump Absolutely With 64 bit register value If Negative flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNP | 110xxxxx | Jump Absolutely With 64 bit register value If Positive flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIE | 110xxxxx | Jump Absolutely With 64 bit register value If Parity flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| St64 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(64b)| ++-----------+----------+---------------------------------------------------------------------------+ +| Ld64 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (64b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St32 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(32b)| ++-----------+----------+---------------------------------------------------------------------------+ +| Ld32 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (32b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St16 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(16b)| ++-----------+----------+---------------------------------------------------------------------------+ +| Ld16 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (16b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St8 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register (8b)| ++-----------+----------+---------------------------------------------------------------------------+ +| Ld8 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (8b) | ++-----------+----------+---------------------------------------------------------------------------+ +| RSetF | 010xxxxx | Set flags from 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| HSetF | 010xxxxx | Set flags from 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| HSetFF | 010xxxxx | Set flags from 32 bit register as a float value (no parity flag) | ++-----------+----------+---------------------------------------------------------------------------+ +| RSetFD | 010xxxxx | Set flags from 64 bit register as a double value (no parity flag) | ++-----------+----------+---------------------------------------------------------------------------+ +| Mov64 | 100xxxxx | MovRR dst, src copies the value from src to dst (64 bit registers) | ++-----------+----------+---------------------------------------------------------------------------+ +| Mov32 | 100xxxxx | MovHR dst, src copies the value from src to dst (32 bit registers) | ++-----------+----------+---------------------------------------------------------------------------+ +| MovI64 | 110xxxxx | MovI64 dst, imm (7 byte imm) moves imm into the dst register (64 bit) | ++-----------+----------+---------------------------------------------------------------------------+ +| Halt | 00000000 | Halts the program execution and tells interpreter to kill the process | ++-----------+----------+---------------------------------------------------------------------------+ +| Nop | 00010000 | Does nothing, interpreter is free to delay around 1ms to calm cpu | ++-----------+----------+---------------------------------------------------------------------------+ +| Call | 01000000 | Calls the function at the memory address in the register (see call alg) | ++-----------+----------+---------------------------------------------------------------------------+ +| Ret | 00000001 | Returns from the current function to the parent function (see call alg) | ++-----------+----------+---------------------------------------------------------------------------+ + +# real one -> ++-----------+----------+---------------------------------------------------------------------------+ +| Mneumonic | Opcode | Description | ++-----------+----------+---------------------------------------------------------------------------+ +| AddR32 | 01100000 | AddR32 dst, src adds the value in src to dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| SubR32 | 01100001 | SubR32 dst, src subtracts the value in src from dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| MulR32 | 01100010 | MulR32 dst, src multiplies the value in dst by src, result in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IMulR32 | 01100011 | IMulR32 dst, src multiplies the value in dst by src, result in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| DivR32 | 01100100 | DivR32 dst, src divides dst by src, Quo in dst, Rem ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IDivR32 | 01100101 | IDivR32 dst, src divides dst by src, Quo in dst, Rem ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| ModR32 | 01100110 | ModR32 dst, src divides dst by src, Rem in dst, Quo ignored (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IModR32 | 01100111 | IModR32 dst, src divides dst by src, Rem in dst, Quo ignored (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| Shr32 | 01101000 | Shr32 dst, src logical shifts dst right by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Shl32 | 01101001 | Shl32 dst, src logical shifts dst left by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Sar32 | 01101010 | Sar32 dst, src arithmetic shifts dst right by src&0b11111 | ++-----------+----------+---------------------------------------------------------------------------+ +| And32 | 01101011 | And32 dst, src performs logical and dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| Or32 | 01101100 | Or32 dst, src performs logical or dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| Xor32 | 01101101 | Xor32 dst, src performs logical xor dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| AddR64 | 01101110 | AddR64 dst, src adds the value in src to dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| SubR64 | 01101111 | SubR64 dst, src subtracts the value in src from dst, result in dst (int) | ++-----------+----------+---------------------------------------------------------------------------+ +| MulR64 | 01110000 | MulR64 dst, src multiplies dst by src, result in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IMulR64 | 01110001 | IMulR64 dst, src multiplies dst by src, result in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| DivR64 | 01110010 | DivR64 dst, src divides dst by src, Quo in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IDivR64 | 01110011 | IDivR64 dst, src divides dst by src, Quo in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| ModR64 | 01110100 | ModR64 dst, src divides dst by src, Rem in dst (uint) | ++-----------+----------+---------------------------------------------------------------------------+ +| IModR64 | 01110101 | IModR64 dst, src divides dst by src, Rem in dst (sint) | ++-----------+----------+---------------------------------------------------------------------------+ +| Shr64 | 01110110 | Shr64 dst, src logical shifts dst right by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Shl64 | 01110111 | Shl64 dst, src logical shifts dst left by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| Sar64 | 01111000 | Sar64 dst, src arithmetic shifts dst right by src&0b111111 | ++-----------+----------+---------------------------------------------------------------------------+ +| And64 | 01111001 | And64 dst, src performs logical and dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| Or64 | 01111010 | Or64 dst, src performs logical or dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| Xor64 | 01111011 | Xor64 dst, src performs logical xor dst with src | ++-----------+----------+---------------------------------------------------------------------------+ +| FAdd | 10000000 | FAdd dst, src adds src to dst as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FSub | 10000001 | FSub dst, src subtracts src from dst as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FMul | 10000010 | FMul dst, src multiplies dst by src as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| FDiv | 10000011 | FDiv dst, src divides dst by src as 32 bit float | ++-----------+----------+---------------------------------------------------------------------------+ +| DAdd | 10000100 | DAdd dst, src adds src to dst as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DSub | 10000101 | DSub dst, src subtracts src from dst as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DMul | 10000110 | DMul dst, src multiplies dst by src as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| DDiv | 10000111 | DDiv dst, src divides dst by src as 64 bit double | ++-----------+----------+---------------------------------------------------------------------------+ +| FtoI | 10001000 | FtoI dst, src converts src from 32b float to int (trunc), save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| DtoI | 10001001 | DtoI dst, src converts src from 64b double to int (trunc), save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| ItoF | 10001010 | ItoF dst, src converts src from int to 32b float, save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| ItoD | 10001011 | ItoD dst, src converts src from int to 64b double, save to dst | ++-----------+----------+---------------------------------------------------------------------------+ +| St64 | 10001100 | St64 src, addr writes src to address in addr register (64b) | ++-----------+----------+---------------------------------------------------------------------------+ +| Ld64 | 10001101 | Ld64 dst, addr reads address in addr register and writes dst (64b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St32 | 10001110 | St32 src, addr writes src to address in addr register (32b) | ++-----------+---------+---------------------------------------------------------------------------+ +| Ld32 | 10001111 | Ld32 dst, addr reads address in addr register and writes dst (32b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St16 | 10010000 | St16 src, addr writes src to address in addr register (16b) | ++-----------+----------+---------------------------------------------------------------------------+ +| Ld16 | 10010001 | Ld16 dst, addr reads address in addr register and writes dst (16b) | ++-----------+----------+---------------------------------------------------------------------------+ +| St8 | 10010010 | St8 src, addr writes src to address in addr register (8b) | ++-----------+----------+---------------------------------------------------------------------------+ +| Ld8 | 10010011 | Ld8 dst, addr reads address in addr register and writes dst (8b) | ++-----------+----------+---------------------------------------------------------------------------+ +| Mov64 | 10010100 | Mov64 dst, src copies value from src to dst (64 bit registers) | ++-----------+----------+---------------------------------------------------------------------------+ +| Mov32 | 10010101 | Mov32 dst, src copies value from src to dst (32 bit registers) | ++-----------+----------+---------------------------------------------------------------------------+ +| Jmp | 11000000 | Jump absolutely to 64 bit address | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIZ | 11000001 | Jump absolutely to 64 bit address if Zero flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIN | 11000010 | Jump absolutely to 64 bit address if Negative flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIP | 11000011 | Jump absolutely to 64 bit address if Positive flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIO | 11000100 | Jump absolutely to 64 bit address if Parity flag set | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNZ | 11000101 | Jump absolutely to 64 bit address if Zero flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNN | 11000110 | Jump absolutely to 64 bit address if Negative flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpNP | 11000111 | Jump absolutely to 64 bit address if Positive flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| JmpIE | 11001000 | Jump absolutely to 64 bit address if Parity flag unset | ++-----------+----------+---------------------------------------------------------------------------+ +| MovI64 | 11101001 | MovI64 dst, imm moves 8 byte immediate into 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| Not32 | 01000000 | Not32 reg performs bitwise not on 32 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| Not64 | 01000001 | Not64 reg performs bitwise not on 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| RSetF | 01000010 | Set flags from 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| HSetF | 01000011 | Set flags from 64 bit register | ++-----------+----------+---------------------------------------------------------------------------+ +| HSetFF | 01000100 | Set flags from 32 bit register as float value (no parity flag) | ++-----------+----------+---------------------------------------------------------------------------+ +| RSetFD | 01000101 | Set flags from 64 bit register as double value (no parity flag) | ++-----------+----------+---------------------------------------------------------------------------+ +| Call | 01000110 | Calls function at memory address in register | ++-----------+----------+---------------------------------------------------------------------------+ +| Halt | 00000000 | Halts program execution and tells interpreter to kill process | ++-----------+----------+---------------------------------------------------------------------------+ +| Nop | 00000001 | Does nothing, interpreter may delay around 1ms | ++-----------+----------+---------------------------------------------------------------------------+ +| Ret | 00000010 | Returns from current function to parent function | ++-----------+----------+---------------------------------------------------------------------------+ + +Calling algorithm: +This is some horrific mix of c and asm but yk +void call(uint64_t addr) { + xSp -= 8; + mem[xSp] = xBp; + xSp -= 8; + mem[xSp] = xPc + 2; // 2 bytes is call instr size + xBp = xSp; + xPc = addr; +} + +void ret() { + uint64_t addr = mem[xBp]; + uint64_t oldBase = mem[xBp+8]; + + xPc = addr; + xSp = xBp+16; + xBp = oldBase; +} + diff --git a/Lazyc b/Lazyc new file mode 160000 index 0000000..5bb6ab1 --- /dev/null +++ b/Lazyc @@ -0,0 +1 @@ +Subproject commit 5bb6ab1d1bf289e01e8fa2e482e1c1bd51fd3867 diff --git a/README.md b/README.md new file mode 100644 index 0000000..38088c9 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# FlagVM +A custom VM for an ISA, very beta right now don't touch it +I think it's technically turing complete with the current implementation +but i'll finish implementing the spec eventually diff --git a/bldit.lua b/bldit.lua new file mode 100644 index 0000000..a963e45 --- /dev/null +++ b/bldit.lua @@ -0,0 +1,63 @@ +bldit_version = "1.1.3" +package_version = "1.1.3" + +dependencies = {} + +exec_name = "flagvm" +libs = "-Wall -Wextra" +includes = "-I./Lazyc" + +execute = function(str) + print(str) + return os.execute(str) +end + +targets = { + default = { + build = function() + e,h,c = execute("rm -fr build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + e,h,c = execute("mkdir build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + cmd = [[find src -type f -name "*.c" -print]] + p = io.popen(cmd) + assert(p, "File detection error, GIVEN UP") + + for f in p:lines() do + base = f:match("([^/]+)%.c$") + obj = "build/"..base..".o" + cc = "cc -c '"..f.."' -o '"..obj.."' "..includes + e,h,c = execute(cc) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + end + p:close() + e,h,c = execute("cc build/*.o "..libs.." -o "..exec_name) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + return 0 + end, + install = function() + e,h,c = execute("cp "..exec_name.." /bin") + return c or 0 + end, + uninstall = function() + e,h,c = execute("rm /bin"..exec_name) + return c or 0 + end, + } +} diff --git a/flagvm b/flagvm new file mode 100755 index 0000000..364a20f Binary files /dev/null and b/flagvm differ diff --git a/hexer.sh b/hexer.sh new file mode 100755 index 0000000..08f79ea --- /dev/null +++ b/hexer.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -e + +if [ $# -lt 1 ]; then + echo "Usage: $0 input.hex [output.bin]" + exit 1 +fi + +input="$1" + +if [ $# -ge 2 ]; then + output="$2" +else + output="${input%.*}.bin" +fi + +perl -ne 's/#.*//; print pack("H*", $_ =~ s/\s+//gr)' "$input" > "$output" + +echo "Wrote $output" \ No newline at end of file diff --git a/src/interp.c b/src/interp.c new file mode 100644 index 0000000..81d2d56 --- /dev/null +++ b/src/interp.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#define LAZY_IMPL +#include "lazy.h" + +#define PAGE_SIZE 4096 +#define DEBUG false +// MMIO is defined between 0xC000000000000000 and 0xD000000000000000 +// Some of that is still normal memory though +#define UART_TX 0xCFFFFFFFFFFFFFFD +#define UART_RX 0xCFFFFFFFFFFFFFFE +#define UART_CT 0xCFFFFFFFFFFFFFFF +static_assert(PAGE_SIZE%8 == 0); + +static size_t flag_bytecnt[] = { + 0, 0, 1, 2, 2, 4, 1, 9 +}; + +typedef Lz_HM(uint64_t, void*) pageMap; +static pageMap memPages; +uint64_t registers[256]; +#define xPc registers[255] +#define xSp registers[251] +#define xBp registers[252] + +bool isMMIO(uint64_t addr) { + if (addr == UART_TX) return true; + if (addr == UART_RX) return true; + + return false; +} + +void memory_set8(uint64_t addr, unsigned char byte) { + if (isMMIO(addr)) { + if (addr == UART_TX) { + putchar(byte); + } + } + uint64_t pageAddr = addr / PAGE_SIZE; + uint64_t inPageAddr = addr % PAGE_SIZE; + if (lz_hm_exists(memPages, pageAddr)) { + void *page = lz_hm_get(memPages, pageAddr); + ((unsigned char*)page)[inPageAddr] = byte; + } else { + void *newpage = malloc(PAGE_SIZE); + if (!newpage) { + printf("Buy more ram lol\n"); + exit(1); + } + lz_hm_add(memPages, pageAddr, newpage); + ((unsigned char*)newpage)[inPageAddr] = byte; + } +} + +unsigned char memory_get8(uint64_t addr) { + if (isMMIO(addr)) { + if (addr == UART_RX) { + return fgetc(stdin); + } + } + uint64_t pageAddr = addr / PAGE_SIZE; + uint64_t inPageAddr = addr % PAGE_SIZE; + if (lz_hm_exists(memPages, pageAddr)) { + void *page = lz_hm_get(memPages, pageAddr); + return ((unsigned char*)page)[inPageAddr]; + } else { + return 0; // CBF + } +} + +int load_program(const char *fname) { + FILE *f = fopen(fname, "rb"); + int byte; + xPc = 0x4000000000000000; + uint64_t i = xPc; + while ((byte = fgetc(f)) != EOF) { + memory_set8(i, byte); + ++i; + } + fclose(f); + printf("[Info] Loaded file %s to addr 0x%lX\n", fname, xPc); +} + +int main(int argc, char **argv) { + if (argc < 2) { + printf("[Usage]: %s \n", argv[0]); + exit(1); + } + char *filename = argv[1]; + lz_hm_init(memPages); + load_program(filename); + + bool zeroFlag = false; + bool positiveFlag = false; + bool negativeFlag = false; + bool parityFlag = false; + + while (1) { + unsigned char inst = memory_get8(xPc); + if (DEBUG) printf("INST: %02X\n", inst); + if (DEBUG) printf("IP: %16lX\n", xPc); + size_t inpflag = (inst & 0xE0) >> 5; + size_t inpcnt = flag_bytecnt[inpflag]; + if (DEBUG) printf("Cnt: %zu\n", inpcnt); + unsigned char inputs[9]; + for (size_t i = 0; i < inpcnt; ++i) { + inputs[i] = memory_get8(xPc+i+1); + } + xPc += 1; + xPc += inpcnt; + switch (inst) { + case 0x00: { // Halt + printf("\nHALT\n"); + exit(0); + break; + } + case 0xE9: { // MovI64 + unsigned char reg = inputs[0]; + unsigned char x1 = inputs[1]; + unsigned char x2 = inputs[2]; + unsigned char x3 = inputs[3]; + unsigned char x4 = inputs[4]; + unsigned char x5 = inputs[5]; + unsigned char x6 = inputs[6]; + unsigned char x7 = inputs[7]; + unsigned char x8 = inputs[8]; + uint64_t val = + ((uint64_t)x1 << 56) + + ((uint64_t)x2 << 48) + + ((uint64_t)x3 << 40) + + ((uint64_t)x4 << 32) + + ((uint64_t)x5 << 24) + + ((uint64_t)x6 << 16) + + ((uint64_t)x7 << 8) + + ((uint64_t)x8 << 0); + registers[reg] = val; + //printf("Moved value 0x%lX into r%d\n", val, reg); + registers[0] = 0; + break; + } + case 0x92: { // St8 + unsigned char src = inputs[0]; + unsigned char addr = inputs[1]; + memory_set8(registers[addr], registers[src]&0xFF); + break; + } + case 0x93: { // Ld8 + unsigned char dst = inputs[0]; + unsigned char addr = inputs[1]; + registers[dst] = memory_get8(registers[addr]); + break; + } + case 0x42: { // RSetF + unsigned char reg = inputs[0]; + int64_t val = *(int64_t*)(®isters[reg]); //Fuckery + zeroFlag = (val == 0); + parityFlag = (val & 1); + positiveFlag = (val > 0); + negativeFlag = (val < 0); + break; + } + case 0x60: { + unsigned char dst = inputs[0]; + unsigned char src = inputs[1]; + registers[dst] += registers[src]; + break; + } + case 0xC0: { // Jmp + unsigned char addr = inputs[0]; + xPc = registers[addr]; + break; + } + case 0xC1: { // JmpIZ + unsigned char addr = inputs[0]; + if (zeroFlag) { + if (DEBUG) printf("Jump!\n"); + xPc = registers[addr]; + } + break; + } + default: { + printf("Unknown instruction: 0x%02X\n", inst); + exit(1); + } + } + } +} + + + diff --git a/tests/UARTcat.bin b/tests/UARTcat.bin new file mode 100644 index 0000000..f9b07e0 Binary files /dev/null and b/tests/UARTcat.bin differ diff --git a/tests/UARTcat.hex b/tests/UARTcat.hex new file mode 100644 index 0000000..7febfe2 --- /dev/null +++ b/tests/UARTcat.hex @@ -0,0 +1,9 @@ +E9 7F CFFFFFFFFFFFFFFD # UART TX +E9 7E CFFFFFFFFFFFFFFE # UART RX +# my assembler is shit and doesn't have labels +# this point is 0x4000000000000014 though +93 01 7E # Ld8 r1, RX +92 01 7F # St8 r1, TX +E9 03 4000000000000014 # jumpback addr +C0 03 # jump back +00 diff --git a/tests/UARTtruthMachine.hex b/tests/UARTtruthMachine.hex new file mode 100644 index 0000000..57fce3b --- /dev/null +++ b/tests/UARTtruthMachine.hex @@ -0,0 +1,8 @@ +E9 7D CFFFFFFFFFFFFFFD # MovI64 7F UART_TX +E9 7E CFFFFFFFFFFFFFFE # MovI64 7F UART_RX +93 02 7E # Ld8 02, UART_RX +E9 01 0000000000000030 # MovI64 R1, 48 +6F 01 02 # SubR64, R1, R2 (if R1 > 0 loop) +82 01 # RSetF R1 +# This is 0x4000000000000026 + diff --git a/tests/cat b/tests/cat new file mode 100644 index 0000000..998d4bc Binary files /dev/null and b/tests/cat differ diff --git a/tests/cat.asm b/tests/cat.asm new file mode 100644 index 0000000..816ce62 --- /dev/null +++ b/tests/cat.asm @@ -0,0 +1,11 @@ +include 'fvm.inc' +org 0x4000000000000000 +start: + MovI64 r95, UART_TX + MovI64 r94, UART_RX +LoopHead: + Ld8 r1, r94 + St8 r1, r95 + MovI64 r3, LoopHead + JmpR r3 + Halt diff --git a/tests/fvm.inc b/tests/fvm.inc new file mode 100644 index 0000000..8aefca8 --- /dev/null +++ b/tests/fvm.inc @@ -0,0 +1,267 @@ +define NULL 0 + +define r0 0 +define r1 1 +define r2 2 +define r3 3 +define r4 4 +define r5 5 +define r6 6 +define r7 7 +define r8 8 +define r9 9 +define r10 10 +define r11 11 +define r12 12 +define r13 13 +define r14 14 +define r15 15 +define r16 16 +define r17 17 +define r18 18 +define r19 19 +define r20 20 +define r21 21 +define r22 22 +define r23 23 +define r24 24 +define r25 25 +define r26 26 +define r27 27 +define r28 28 +define r29 29 +define r30 30 +define r31 31 +define r32 32 +define r33 33 +define r34 34 +define r35 35 +define r36 36 +define r37 37 +define r38 38 +define r39 39 +define r40 40 +define r41 41 +define r42 42 +define r43 43 +define r44 44 +define r45 45 +define r46 46 +define r47 47 +define r48 48 +define r49 49 +define r50 50 +define r51 51 +define r52 52 +define r53 53 +define r54 54 +define r55 55 +define r56 56 +define r57 57 +define r58 58 +define r59 59 +define r60 60 +define r61 61 +define r62 62 +define r63 63 +define r64 64 +define r65 65 +define r66 66 +define r67 67 +define r68 68 +define r69 69 +define r70 70 +define r71 71 +define r72 72 +define r73 73 +define r74 74 +define r75 75 +define r76 76 +define r77 77 +define r78 78 +define r79 79 +define r80 80 +define r81 81 +define r82 82 +define r83 83 +define r84 84 +define r85 85 +define r86 86 +define r87 87 +define r88 88 +define r89 89 +define r90 90 +define r91 91 +define r92 92 +define r93 93 +define r94 94 +define r95 95 + +define xSp 252 +define xBp 253 +define xPc 255 + +define h0 0 +define h1 1 +define h2 2 +define h3 3 +define h4 4 +define h5 5 +define h6 6 +define h7 7 +define h8 8 +define h9 9 +define h10 10 +define h11 11 +define h12 12 +define h13 13 +define h14 14 +define h15 15 +define h16 16 +define h17 17 +define h18 18 +define h19 19 +define h20 20 +define h21 21 +define h22 22 +define h23 23 +define h24 24 +define h25 25 +define h26 26 +define h27 27 +define h28 28 +define h29 29 +define h30 30 +define h31 31 +define h32 32 +define h33 33 +define h34 34 +define h35 35 +define h36 36 +define h37 37 +define h38 38 +define h39 39 +define h40 40 +define h41 41 +define h42 42 +define h43 43 +define h44 44 +define h45 45 +define h46 46 +define h47 47 +define h48 48 +define h49 49 +define h50 50 +define h51 51 +define h52 52 +define h53 53 +define h54 54 +define h55 55 +define h56 56 +define h57 57 +define h58 58 +define h59 59 +define h60 60 +define h61 61 +define h62 62 +define h63 63 +define h64 64 +define h65 65 +define h66 66 +define h67 67 +define h68 68 +define h69 69 +define h70 70 +define h71 71 +define h72 72 +define h73 73 +define h74 74 +define h75 75 +define h76 76 +define h77 77 +define h78 78 +define h79 79 +define h80 80 +define h81 81 +define h82 82 +define h83 83 +define h84 84 +define h85 85 +define h86 86 +define h87 87 +define h88 88 +define h89 89 +define h90 90 +define h91 91 +define h92 92 +define h93 93 +define h94 94 +define h95 95 + +define UART_TX 0xCFFFFFFFFFFFFFFD +define UART_RX 0xCFFFFFFFFFFFFFFE + +macro _dq_be val + db (val shr 56) and 0FFh + db (val shr 48) and 0FFh + db (val shr 40) and 0FFh + db (val shr 32) and 0FFh + db (val shr 24) and 0FFh + db (val shr 16) and 0FFh + db (val shr 8) and 0FFh + db (val shr 0) and 0FFh +end macro + +macro MovI64 dst, val + db 0xE9 + db dst + _dq_be val +end macro + +macro Ld8 dst, addr + db 0x93 + db dst + db addr +end macro + +macro St8 dst, addr + db 0x92 + db dst + db addr +end macro + +macro AddR64 dst, src + db 0x60 + db dst + db src +end macro + +macro RSetF reg + db 0x42 + db reg +end macro + +macro JmpR addr + db 0xC0 + db addr +end macro + +macro Jmp addr + MovI64 127, addr + JmpR 127 +end macro + +macro JmpRIZ addr + db 0xC1 + db addr +end macro + +macro JmpIZ addr + MovI64 127, addr + JmpRIZ 127 +end macro + +macro Halt + db 0 +end macro + diff --git a/tests/halt.bin b/tests/halt.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/tests/halt.bin differ diff --git a/tests/hw b/tests/hw new file mode 100644 index 0000000..c46187b Binary files /dev/null and b/tests/hw differ diff --git a/tests/hw.asm b/tests/hw.asm new file mode 100644 index 0000000..6fac8d9 --- /dev/null +++ b/tests/hw.asm @@ -0,0 +1,17 @@ +include 'fvm.inc' + +org 0x4000000000000000 +start: + MovI64 r3, msg + MovI64 r1, 1 + MovI64 r95, UART_TX +LoopHead: + Ld8 r2, r3 + RSetF r2 + JmpIZ LoopTail + St8 r2, r95 + AddR64 r3, r1 + Jmp LoopHead +LoopTail: + Halt +msg db 'Hello World!', 10, 0 diff --git a/tests/movi64.bin b/tests/movi64.bin new file mode 100644 index 0000000..72bfa75 Binary files /dev/null and b/tests/movi64.bin differ diff --git a/tests/uartH.bin b/tests/uartH.bin new file mode 100644 index 0000000..04ccbd0 Binary files /dev/null and b/tests/uartH.bin differ diff --git a/tests/uartHW.bin b/tests/uartHW.bin new file mode 100644 index 0000000..c5117c3 Binary files /dev/null and b/tests/uartHW.bin differ diff --git a/tests/uartHW.hex b/tests/uartHW.hex new file mode 100644 index 0000000..7e18baa --- /dev/null +++ b/tests/uartHW.hex @@ -0,0 +1,29 @@ +E9 01 CFFFFFFFFFFFFFFD # MovI64 r1, ... +E9 02 0000000000000048 # MovI64 r2, 'H' +92 02 01 # send 2 uart +E9 02 0000000000000065 # 'e' +92 02 01 +E9 02 000000000000006C # 'l'*2 +92 02 01 +92 02 01 +E9 02 000000000000006F # 'o' +92 02 01 +E9 02 000000000000002C # ',' +92 02 01 +E9 02 0000000000000020 # ' ' +92 02 01 +E9 02 0000000000000057 # 'W' +92 02 01 +E9 02 000000000000006F # 'o' +92 02 01 +E9 02 0000000000000072 # 'r' +92 02 01 +E9 02 000000000000006C # 'l' +92 02 01 +E9 02 0000000000000064 # 'd' +92 02 01 +E9 02 0000000000000021 # '!' +92 02 01 +E9 02 000000000000000A # '\n' +92 02 01 +00