diff options
Diffstat (limited to 'mu_summary')
-rw-r--r-- | mu_summary | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/mu_summary b/mu_summary new file mode 100644 index 00000000..676b1151 --- /dev/null +++ b/mu_summary @@ -0,0 +1,192 @@ +Mu programs are lists of functions. Each function has the following form: + + fn _name_ _inouts_with_types_ -> _outputs_with_types_ { + _instructions_ + } + +Instructions may be primitives or function calls. Either way, all instructions +have one of the following forms: + + # defining variables + var _name_: _type_ + var _name_/_register_: _type_ + + # doing things with variables + _operation_ _inouts_ + _outputs_ <- _operation_ _inouts_ + +Instructions and functions may have inouts and outputs. Both inouts and +outputs are variables. + +As seen above, variables can be defined to live in a register, like this: + + n/eax + +Variables not assigned a register live in the stack. + +Function inouts must always be on the stack, and outputs must always be in +registers. A function call must always write to the exact registers its +definition requires. For example: + + fn foo -> x/eax: int { + ... + } + fn main { + a/eax <- foo # ok + a/ebx <- foo # wrong + } + +Primitive inouts may be on the stack or in registers, but outputs must always +be in registers. + +Functions can contain nested blocks inside { and }. Variables defined in a +block don't exist outside it. + +## Primitive instructions + +Primitive instructions currently supported in Mu: + + var/eax <- increment + var/ecx <- increment + var/edx <- increment + var/ebx <- increment + var/esi <- increment + var/edi <- increment + increment var + + var/eax <- decrement + var/ecx <- decrement + var/edx <- decrement + var/ebx <- decrement + var/esi <- decrement + var/edi <- decrement + decrement var + + var1/reg1 <- add var2/reg2 + var/reg <- add var2 + add-to var1, var2/reg + var/eax <- add n + var/reg <- add n + add-to var, n + + var1/reg1 <- sub var2/reg2 + var/reg <- sub var2 + sub-from var1, var2/reg + var/eax <- sub n + var/reg <- sub n + sub-from var, n + + var1/reg1 <- and var2/reg2 + var/reg <- and var2 + and-with var1, var2/reg + var/eax <- and n + var/reg <- and n + and-with var, n + + var1/reg1 <- or var2/reg2 + var/reg <- or var2 + or-with var1, var2/reg + var/eax <- or n + var/reg <- or n + or-with var, n + + var1/reg1 <- xor var2/reg2 + var/reg <- xor var2 + xor-with var1, var2/reg + var/eax <- xor n + var/reg <- xor n + xor-with var, n + + var/eax <- copy n + var/ecx <- copy n + var/edx <- copy n + var/ebx <- copy n + var/esi <- copy n + var/edi <- copy n + var1/reg1 <- copy var2/reg2 + copy-to var1, var2/reg + var/reg <- copy var2 + var/reg <- copy n + copy-to var, n + + compare var1, var2/reg + compare var1/reg, var2 + compare var/eax, n + compare var, n + + var/reg <- multiply var2 + +## Primitive jump instructions + +There are two kinds of jumps, both with many variations: `break` and `loop`. +`break` instructions jump to the end of the containing block. `loop` instructions +jump to the beginning of the containing block. + +Jumps can take an optional label starting with '$': + + loop $foo + +This instruction jumps to the beginning of the block called $foo. It must lie +somewhere inside such a box. Jumps are only legal to containing blocks. + +There are two unconditional jumps: + + loop + loop label + # unconditional break instructions don't seem useful + +The remaining jump instructions are all conditional. Conditional jumps rely on +the result of the most recently executed `compare` instruction. (To keep +programs easy to read, keep compare instructions close to the jump that uses +them.) + + break-if-= + break-if-= label + break-if-!= + break-if-!= label + +Inequalities are similar, but have unsigned and signed variants. We assume +unsigned variants are only ever used to compare addresses. + + break-if-< + break-if-< label + break-if-> + break-if-> label + break-if-<= + break-if-<= label + break-if->= + break-if->= label + + break-if-addr< + break-if-addr< label + break-if-addr> + break-if-addr> label + break-if-addr<= + break-if-addr<= label + break-if-addr>= + break-if-addr>= label + +Similarly, conditional loops: + + loop-if-= + loop-if-= label + loop-if-!= + loop-if-!= label + + loop-if-< + loop-if-< label + loop-if-> + loop-if-> label + loop-if-<= + loop-if-<= label + loop-if->= + loop-if->= label + + loop-if-addr< + loop-if-addr< label + loop-if-addr> + loop-if-addr> label + loop-if-addr<= + loop-if-addr<= label + loop-if-addr>= + loop-if-addr>= label |