diff --git a/lib/register/README.md b/lib/register/README.md index 4bd0f1a1..0290528d 100644 --- a/lib/register/README.md +++ b/lib/register/README.md @@ -1,50 +1,48 @@ Register Machine -=============== +================ -This is the logic that uses the compiled virtual object space to produce code and an executable binary. +The RegisterMachine, is an abstract machine with registers. Think of it as an arm machine with +normal instruction names. It is not however an abstraction of existing hardware, but only +of that subset that we need. -There is a mechanism for an actual machine (derived class) to generate harware specific instructions (as the -plain ones in this directory don't assemble to binary). Currently there is only the Arm module to actually do -that. +Our primary objective is to compile Phisol to this level, so the register machine has: +- object access instructions +- object load +- object oriented call semantics +- extended (and extensible) branching +- normal integer operators (but no sub word instructions) -The elf module is used to generate the actual binary from the final Space. Space is a virtual class representing -all objects that will be in the executable. Other than MethodSource, objects get transformed to data. +All data is in objects. -But MethodSource, which are made up of Blocks, are compiled into a stream of bytes, -which are the binary code for the function. +The register machine is aware of Parfait objects, and specifically uses Message and Frame to +express call semantics. -Virtual Objects ----------------- +Calls and syscalls +------------------ -There are four virtual objects that are accessible (we can access their variables): +The RegisterMachine only uses 1 fixed register, the currently worked on Message. -- Self -- Message (arguments, method name, self) -- Frame (local and tmp variables) -- NewMessage ( to build the next message sent) +There is no stack, rather messages form a linked list, and preparing to call, the data is pre-filled +into the next message. Calling then means moving the new message to the current one and jumping +to the address of the method. Returning is the somewhat reverse process. -These are pretty much the first four registers. When the code goes from virtual to register, -we use register instructions to replace virtual ones. +Syscalls are implemented by *one* Syscall instruction. The Register machine does not specify/limit +the meaning or number of syscalls. This is implemented by the level below, eg the arm/interpreter. -Eg: A Virtual::Set can move data around inside those objects. -And since in Arm this can not be done in one instruction, we use two, one to move to an unused register -and then into the destination. And then we need some fiddling of bits to shift the type info. +Interpreter +=========== -Another simple example is a Call. A simple case of a Class function call resolves the class object, -and with the method name the function to be found at compile-time. -And so this results in a Register::Call, which is an Arm instruction. +There is an interpreter that can interpret compiled register machine programs. +This is very handy for debugging (an nothing else). -A C call ---------- +Even more handy is the graphical interface for the interpreter, which is in it's own repository: +salama-debugger. -Ok, there are no c calls. But syscalls are very similar. -This is not at all as simple as the nice Class call described above. +Arm / Elf +========= -For syscall in Arm (linux) you have to load registers 0-x (depending on call), load R7 with the -syscall number and then issue the software interupt instruction. -If you get back something back, it's in R0. +There is also a (very strightforward) transformation to arm instructions. +Together with the also quite minimal elf module, arm binaries can be produced. -In short, lots of shuffling. And to make it fit with our four object architecture, -we need the Message to hold the data for the call and Sys (module) to be self. -And then the actual functions do the shuffle, saving the data and restoring it. -And setting type information according to kernel documentation (as there is no runtime info) +These binaries have no external dependencies and in fact can not even call c at the moment +(only syscalls :-)). diff --git a/lib/register/integer.rb b/lib/register/integer.rb deleted file mode 100644 index dcdb2b77..00000000 --- a/lib/register/integer.rb +++ /dev/null @@ -1,51 +0,0 @@ -module Register - class UnusedAndAbandonedInteger < Word - # needs to be here as Word's constructor is private (to make it abstract) - def initialize reg - super - end - - def less_or_equal block , right - block.cmp( self , right ) - Register::BranchCondition.new :le - end - def greater_or_equal block , right - block.cmp( self , right ) - Register::BranchCondition.new :ge - end - def greater_than block , right - block.cmp( self , right ) - Register::BranchCondition.new :gt - end - def less_than block , right - block.cmp( self , right ) - Register::BranchCondition.new :lt - end - def plus block , first , right - block.add( self , left , right ) - self - end - def minus block , left , right - block.sub( self , left , right ) - self - end - def left_shift block , left , right - block.mov( self , left , shift_lsr: right ) - self - end - def equals block , right - block.cmp( self , right ) - Register::BranchCondition.new :eq - end - - def is_true? function - function.cmp( self , 0 ) - Register::BranchCondition.new :ne - end - - def move block , right - block.mov( self , right ) - self - end - end -end \ No newline at end of file diff --git a/lib/register/transformations.rb b/lib/register/transformations.rb deleted file mode 100644 index 1721572b..00000000 --- a/lib/register/transformations.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Register - -end diff --git a/lib/register/optimisations.rb b/stash/optimisations.rb similarity index 100% rename from lib/register/optimisations.rb rename to stash/optimisations.rb diff --git a/lib/virtual/plock.rb b/stash/plock.rb similarity index 100% rename from lib/virtual/plock.rb rename to stash/plock.rb