2014-08-22 17:40:09 +03:00
|
|
|
module Register
|
2014-05-03 15:13:44 +03:00
|
|
|
|
2014-10-03 11:05:17 +03:00
|
|
|
# the register machine has at least 8 registers, named r0-r5 , :lr and :pc (for historical reasons)
|
|
|
|
# we can load and store their contents and
|
|
|
|
# access (get/set) memory at a constant offset from a register
|
2015-05-24 20:00:11 +03:00
|
|
|
# while the vm works with objects, the register machine has registers,
|
2014-10-03 11:05:17 +03:00
|
|
|
# but we keep the names for better understanding, r4/5 are temporary/scratch
|
|
|
|
# there is no direct memory access, only through registers
|
|
|
|
# constants can/must be loaded into registers before use
|
2014-10-03 10:25:10 +03:00
|
|
|
class Instruction
|
|
|
|
|
2015-07-18 11:21:49 +03:00
|
|
|
def initialize source
|
|
|
|
@source = source
|
|
|
|
end
|
2015-07-27 12:13:39 +03:00
|
|
|
attr_reader :source
|
2015-07-18 11:21:49 +03:00
|
|
|
|
2014-06-14 10:59:25 +03:00
|
|
|
# returns an array of registers (RegisterReferences) that this instruction uses.
|
2015-05-24 20:00:11 +03:00
|
|
|
# ie for r1 = r2 + r3
|
2014-06-08 01:41:56 +03:00
|
|
|
# which in assembler is add r1 , r2 , r3
|
|
|
|
# it would return [r2,r3]
|
|
|
|
# for pushes the list may be longer, whereas for a jump empty
|
|
|
|
def uses
|
|
|
|
raise "abstract called for #{self.class}"
|
|
|
|
end
|
2014-06-14 10:59:25 +03:00
|
|
|
# returns an array of registers (RegisterReferences) that this instruction assigns to.
|
2015-05-24 20:00:11 +03:00
|
|
|
# ie for r1 = r2 + r3
|
2014-06-08 01:41:56 +03:00
|
|
|
# which in assembler is add r1 , r2 , r3
|
|
|
|
# it would return [r1]
|
|
|
|
# for most instruction this is one, but comparisons and jumps 0 , and pop's as long as 16
|
|
|
|
def assigns
|
|
|
|
raise "abstract called for #{self.class}"
|
|
|
|
end
|
2014-10-03 11:05:17 +03:00
|
|
|
|
2014-10-07 12:23:08 +03:00
|
|
|
# wrap symbols into regsiter reference if needed
|
|
|
|
def wrap_register reg
|
|
|
|
return reg if reg.is_a? RegisterReference
|
|
|
|
RegisterReference.new(reg)
|
|
|
|
end
|
2014-05-02 08:02:25 +03:00
|
|
|
end
|
2015-05-24 20:00:11 +03:00
|
|
|
|
2014-05-02 08:02:25 +03:00
|
|
|
end
|
2014-10-03 11:05:17 +03:00
|
|
|
|
2014-10-03 11:07:18 +03:00
|
|
|
require_relative "instructions/set_slot"
|
|
|
|
require_relative "instructions/get_slot"
|
|
|
|
require_relative "instructions/load_constant"
|
2015-06-22 22:48:42 +03:00
|
|
|
require_relative "instructions/syscall"
|
2014-10-04 12:52:47 +03:00
|
|
|
require_relative "instructions/function_call"
|
|
|
|
require_relative "instructions/function_return"
|
|
|
|
require_relative "instructions/save_return"
|
|
|
|
require_relative "instructions/register_transfer"
|
2015-07-17 13:21:57 +03:00
|
|
|
require_relative "instructions/branch"
|
2015-08-04 22:01:20 +03:00
|
|
|
require_relative "instructions/operator_instruction"
|