SPE is a simple 12x 32Bit Register Stack-Only Processor Emulator to play with a very small and simple instruction set to get familiar with assembly and how to manage memory by maintaining the stack.
This processor emulator is desinged to do basic maths (add, sub, mul), bitwise functions (and, or, xor, bsl, bsr), branching (f.e jump, jumpr,...) and stack storage to write basic iterative or recursive calulcations (such as fibonacci). Macros get extended to the regular expressions to that 1 instruction = 1 cylce (or per cycle one line of code)
- add float support
- add more functions
- actually assembly it to binary
lim(load immediate):lim reg valuemov:mov from to- moves from to to and sets from to zero
add:add store reg1 reg2sub:sub store reg1 reg2mul:mul reg1 reg2- top 32bit is in R7 and bottom 32bit in R6
and:and store reg1 reg2xor:xor store reg1 reg2or:or store reg1 reg2bsl:bsl store reg1 reg2- bitshift reg1::value by reg2::value bits to the left
bsr:bsr store reg1 reg2- bitshift reg1::value by reg2::value bits to the right
jmp:jmp labeljeq(jump if equal):jeq reg1 reg2 label- reg1 == reg2
jlt(jump less than):jlt reg1 reg2 label- reg1 < reg2
jle(jump if less than or equal):jle reg1 reg2 label- reg1 <= reg2
jgt(jump if greater than):jgt reg1 reg2 label- reg1 > reg2
jge(jump if greater than or equal):jge reg1 reg2 label- reg1 >= reg2
ret(return):ret- returns to the address stored in
rt
- returns to the address stored in
sws(store word stack):sws offset_from_sp reglws(load word stack):lws offset_from_sp regexec(execute)- calls function id (param0) with argument (param1)
r0-r7
Important: r0 is the zero register and should not be set
sp(stack pointer)pc(programm counter)rt(return address)
param0-param1
While r6 and r7 are used for the result of mul its still ok to use it to store data.
SPE has an ti register to store the immediate of the I-Macros for the operation. This should not be used to store data.
Global values can be defined using .global <name_no_spaces> <value_int_or_hex>. Globals are be defined before any instructions, because of the code gen.
Global values can be used in instructions using .<name_no_spaces> and are handled by the code gen with subsitution
All instructions ending with an 'r' set the ret register to current-address +1
jumpr(jump and register):jumpr labeljeqr(jump equals and register):jeqr reg reg labeljltr(jump less than and register):jltr reg reg labeljler(jump less than or equal and register):jler reg reg labeljgtr(jump greater than and register):jgtr reg reg labeljger(jump greater than or equal and register):jger reg reg label
push(pushes register to the stack):push reg- automatically increments stack by 1x int32
pop(pops the top value to the register):pop reg- automatically decrements stack by 1x int32
All instructions ending with an 'i' take an immediate as one paramter
addi(add immediate):addi store reg valuesubi(add immediate):subi store reg valuejei(jump equal immediate):jei reg value labelbsli:bsl store reg1 value- bitshift reg1::value by value bits to the left
bsri:bsr store reg1 value- bitshift reg1::value by values bits to the right
print: ID 0 and 1 Parameter
With the jump-type instructions you can jump to labels. Labels should be used for branching
With the call instruction you can call a function. Call sets the rt-register and jumps to the function.
Functions should be used to delclare contained blocks of logic.