simple-computer
simple-computer copied to clipboard
Not an issue
Hello Daniel,
Great job!
You might find this funny :=) I liked the book very much (as you apparently did too) and after reading it I started to search the internet for what exists for Scott CPU. I came across your simulator and thought it'd be cool to create a simple compiler for it. This is how a new hobby little project appeared: https://github.com/realkompot/llvm-project-scott-cpu
-rk
Hello! Sorry just seen this
This is absolutely brilliant, I'm completely in awe haha!
This is so cool I'm completely in awe, great work!
updated the README to mention this https://github.com/djhworld/simple-computer/commit/94527f744d495ffd7457498ed821cba411d64eda
Thanks :=)
Running a program on a machine I could fully understand was satisfying. It's also interesting that it took less than ~1000 lines of custom code, the rest - "plumbing" code to integrate with LLVM infrastructure and copied code. I find llvm a highly intelligent piece of software, well written (as far as I can tell, I'm only learning c++). And I didn't have to make any changes to the simulator, it had everything I needed (screen, keyboard input) and worked well :=)
Here's some more info:
-
In LLVM target CPU instructions/registers/calling conventions are described in a declarative way in special "target definition" files (there's a codegen tool integrated in the llvm build process that generates actual c++ code from them). In case of instructions those files contain info how to encode them and what patterns it matches to. For instance, SHL is defined like this: https://github.com/realkompot/llvm-project-scott-cpu/blob/62b517b1b41e05f382d95fa47d741dc822c0781b/llvm/lib/Target/Scott/ScottInstrInfo.td#L109. "let Inst{1-0} = destReg" means that the first 2 bits designate the "destReg".
-
CLF is inserted automatically before every CMP, and after ADD, SHL, SHR: https://github.com/realkompot/llvm-project-scott-cpu/blob/62b517b1b41e05f382d95fa47d741dc822c0781b/llvm/lib/Target/Scott/ScottPasses.cpp#L53
-
While R3 is the stack reg, R2 is a special register too. It's used to facilitate calls (function prologue/epilogue) and register spills/loads (when the register allocator runs out of available regs and decides to store one of them to a stack slot in order not to lose the value). The cpu can't spill regs like this: "STORE SP + <stack_slot_offset>, <target_reg>", we always need another reg to hold memory address, like this: "DATA R2, <stack_slot_offset>; ADD R2, SP; STORE R2, <target_reg>". This leaves the reg allocator with just 2 regs to perform operations :=) Basically generated code consists of 70% spills/loads, function prologues and 30% of "real" operations. This seems not right, and I tried to make this R2 reg available to the allocator as well, but failed and gave up (it required better understanding of llvm). Anyway, it wouldn't be much faster.
-
char, int, long mean the same thing - 16-bit integer. While it'll compile code that uses signed ints, comparison will not work correctly because the cpu can't compare signed ints (it'll evaluate -1 > 0 to true). Thus only unsigned integers can be used safely.
-
Dynamic stack allocations are not supported, no library calls, no floating point (obv), only basic stuff.