started naming instruction arguments properly, starting with compare
This commit is contained in:
@ -2,22 +2,22 @@ module Arm
|
||||
class CompareInstruction < Vm::CompareInstruction
|
||||
include Arm::Constants
|
||||
|
||||
def initialize(first , attributes)
|
||||
super(first , attributes)
|
||||
def initialize(left , right , attributes)
|
||||
super(left , right, attributes)
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@operand = 0
|
||||
@i = 0
|
||||
@attributes[:update_status] = 1
|
||||
@rn = first
|
||||
@rn = left
|
||||
@rd = :r0
|
||||
end
|
||||
# arm intrucioons are pretty sensible, and always 4 bytes (thumb not supported)
|
||||
# arm instructions are pretty sensible, and always 4 bytes (thumb not supported)
|
||||
def length
|
||||
4
|
||||
end
|
||||
|
||||
def build
|
||||
arg = @attributes[:right]
|
||||
arg = @right
|
||||
|
||||
if arg.is_a?(Vm::StringConstant)
|
||||
# do pc relative addressing with the difference to the instuction
|
||||
|
@ -45,28 +45,28 @@ module Vm
|
||||
# Derived machines may use own instructions and define functions for them if so desired
|
||||
def initialize
|
||||
[:push, :pop].each do |inst|
|
||||
define_instruction_for(inst , StackInstruction)
|
||||
define_instruction_one(inst , StackInstruction)
|
||||
end
|
||||
[:adc, :add, :and, :bic, :eor, :orr, :rsb, :rsc, :sbc, :sub].each do |inst|
|
||||
define_instruction_for(inst , LogicInstruction)
|
||||
define_instruction_one(inst , LogicInstruction)
|
||||
end
|
||||
[:mov, :mvn].each do |inst|
|
||||
define_instruction_for(inst , MoveInstruction)
|
||||
define_instruction_one(inst , MoveInstruction)
|
||||
end
|
||||
[:cmn, :cmp, :teq, :tst].each do |inst|
|
||||
define_instruction_for(inst , CompareInstruction)
|
||||
define_instruction_two(inst , CompareInstruction)
|
||||
end
|
||||
[:strb, :str , :ldrb, :ldr].each do |inst|
|
||||
define_instruction_for(inst , MemoryInstruction)
|
||||
define_instruction_one(inst , MemoryInstruction)
|
||||
end
|
||||
[:b, :call , :swi].each do |inst|
|
||||
define_instruction_for(inst , CallInstruction)
|
||||
define_instruction_one(inst , CallInstruction)
|
||||
end
|
||||
# create all possible brach instructions, but the CallInstruction demangles the
|
||||
# code, and has opcode set to :b and :condition_code set to the condition
|
||||
CONDITIONS.each do |suffix|
|
||||
define_instruction_for("b#{suffix}".to_sym , CallInstruction)
|
||||
define_instruction_for("call#{suffix}".to_sym , CallInstruction)
|
||||
define_instruction_one("b#{suffix}".to_sym , CallInstruction)
|
||||
define_instruction_one("call#{suffix}".to_sym , CallInstruction)
|
||||
end
|
||||
end
|
||||
|
||||
@ -74,20 +74,6 @@ module Vm
|
||||
self.class.send(:define_method, name , &block)
|
||||
end
|
||||
|
||||
# define the instruction inst (given as a symbol) on this class as a methods
|
||||
# As we define a standard set of instructions (or memnonics) , this turns this class into a kind of
|
||||
# Assembler, in that you can write .mov() or .pop() and those functions mean the same as if they
|
||||
# were in an assembler file (also options are the same)
|
||||
# defaults gets merged into the instructions options hash, ie passed on to the (machine specific)
|
||||
# Instruction constructor and as such can be used to influence that classes behaviour
|
||||
def define_instruction(inst , clazz , defaults = {} )
|
||||
create_method(inst) do |first , options|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
options[:opcode] = inst
|
||||
clazz.new(first , options)
|
||||
end
|
||||
end
|
||||
|
||||
def self.instance
|
||||
@@instance
|
||||
@ -105,7 +91,28 @@ module Vm
|
||||
# be used to define the mov on an arm machine.
|
||||
# This methods picks up that derived class and calls a define_instruction methods that can
|
||||
# be overriden in subclasses
|
||||
def define_instruction_for(inst , clazz )
|
||||
def define_instruction_one(inst , clazz , defaults = {} )
|
||||
clazz = class_for(clazz)
|
||||
create_method(inst) do |first , options = nil|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
options[:opcode] = inst
|
||||
clazz.new(first , options)
|
||||
end
|
||||
end
|
||||
|
||||
# same for two args (left right, from to etc)
|
||||
def define_instruction_two(inst , clazz , defaults = {} )
|
||||
clazz = class_for(clazz)
|
||||
create_method(inst) do |first ,second , options = nil|
|
||||
options = {} if options == nil
|
||||
options.merge defaults
|
||||
options[:opcode] = inst
|
||||
clazz.new(first , second ,options)
|
||||
end
|
||||
end
|
||||
|
||||
def class_for clazz
|
||||
c_name = clazz.name
|
||||
my_module = self.class.name.split("::").first
|
||||
clazz_name = clazz.name.split("::").last
|
||||
@ -113,7 +120,7 @@ module Vm
|
||||
module_class = eval("#{my_module}::#{clazz_name}") rescue nil
|
||||
clazz = module_class if module_class
|
||||
end
|
||||
define_instruction(inst , clazz )
|
||||
clazz
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -55,8 +55,9 @@ module Vm
|
||||
end
|
||||
end
|
||||
class CompareInstruction < Instruction
|
||||
def initialize first , options
|
||||
@first = first
|
||||
def initialize left , right , options
|
||||
@left = left
|
||||
@right = right
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user