clean up intruction instantiation and fix tests
This commit is contained in:
@@ -5,31 +5,10 @@ require_relative "move_instruction"
|
||||
require_relative "compare_instruction"
|
||||
require_relative "memory_instruction"
|
||||
require_relative "call_instruction"
|
||||
require_relative "constants"
|
||||
|
||||
module Arm
|
||||
class ArmMachine < Vm::CMachine
|
||||
|
||||
# defines a method in the current class, with the name inst (first erg)
|
||||
# the method instantiates an instruction of the given class which gets passed a single hash as arg
|
||||
|
||||
# gets called for every "standard" instruction.
|
||||
# may be used for machine specific ones too
|
||||
def define_instruction inst , clazz
|
||||
super
|
||||
return
|
||||
# need to use create_method and move to attributes hash
|
||||
define_method("#{inst}s") do |*args|
|
||||
instruction clazz , inst , :al , 1 , *args
|
||||
end
|
||||
ArmMachine::COND_CODES.keys.each do |suffix|
|
||||
define_method("#{inst}#{suffix}") do |attributes|
|
||||
instruction clazz , inst , suffix , 0 , *args
|
||||
end
|
||||
define_method("#{inst}s#{suffix}") do |attributes|
|
||||
instruction clazz , inst , suffix , 1 , *args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def integer_less_or_equal block , left , right
|
||||
block.add_code cmp(:left => left , :right => right )
|
||||
|
@@ -5,7 +5,6 @@ module Arm
|
||||
|
||||
# A branch could be called a jump as it has no notion of returning
|
||||
|
||||
# A call has the bl code as someone thought "branch with link" is a useful name.
|
||||
# The pc is put into the link register to make a return possible
|
||||
# a return is affected by moving the stored link register into the pc, effectively a branch
|
||||
|
||||
@@ -24,12 +23,12 @@ module Arm
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:update_status_flag] = 0
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
end
|
||||
|
||||
def assemble(io)
|
||||
case @attributes[:opcode]
|
||||
when :b, :bl
|
||||
when :b, :call
|
||||
arg = @attributes[:left]
|
||||
#puts "BLAB #{arg.inspect}"
|
||||
if( arg.is_a? Fixnum ) #HACK to not have to change the code just now
|
||||
@@ -46,9 +45,9 @@ module Arm
|
||||
# TODO add check that the value fits into 24 bits
|
||||
io << packed[0,3]
|
||||
else
|
||||
raise "else not coded #{inspect}"
|
||||
raise "else not coded arg =#{arg}: #{inspect}"
|
||||
end
|
||||
io.write_uint8 OPCODES[opcode] | (COND_CODES[@attributes[:condition_code]] << 4)
|
||||
io.write_uint8 op_bit_code | (COND_CODES[@attributes[:condition_code]] << 4)
|
||||
when :swi
|
||||
arg = @attributes[:left]
|
||||
if( arg.is_a? Fixnum ) #HACK to not have to change the code just now
|
||||
@@ -61,6 +60,8 @@ module Arm
|
||||
else
|
||||
raise "invalid operand argument expected literal not #{arg} #{inspect}"
|
||||
end
|
||||
else
|
||||
raise "Should not be the case #{inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@@ -7,7 +7,7 @@ module Arm
|
||||
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@operand = 0
|
||||
@i = 0
|
||||
@attributes[:update_status_flag] = 1
|
||||
|
@@ -18,12 +18,12 @@ module Arm
|
||||
:tst => 0b1000,
|
||||
|
||||
:b => 0b1010,
|
||||
:bl => 0b1011,
|
||||
:bx => 0b00010010
|
||||
:call=> 0b1011
|
||||
}
|
||||
#return the bit patter that the cpu uses for the current instruction @attributes[:opcode]
|
||||
def op_bit_code
|
||||
OPCODES[@attributes[:opcode]] or throw "no code found for #{@attributes[:opcode].inspect}"
|
||||
bit_code = OPCODES[@attributes[:opcode]]
|
||||
bit_code or raise "no code found for #{@attributes[:opcode].inspect}"
|
||||
end
|
||||
|
||||
#codition codes can be applied to many instructions and thus save branches
|
||||
|
@@ -1,7 +1,7 @@
|
||||
|
||||
module Arm
|
||||
# Many arm instructions may be conditional, where the default condition is always (al)
|
||||
# ArmMachine::COND_CODES names them, and this attribute reflects it
|
||||
# Constants::COND_CODES names them, and this attribute reflects it
|
||||
#attr_reader :condition_code
|
||||
#attr_reader :operand
|
||||
|
||||
|
@@ -8,8 +8,8 @@ module Arm
|
||||
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:update_status_flag] = 0
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:update_status_flag] = 0 if @attributes[:update_status_flag] == nil
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@operand = 0
|
||||
|
||||
@rn = nil
|
||||
|
@@ -8,8 +8,8 @@ module Arm
|
||||
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:update_status_flag] = 0
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:update_status_flag] = 0 if @attributes[:update_status_flag] == nil
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@operand = 0
|
||||
|
||||
@pre_post_index = 0 #P flag
|
||||
|
@@ -8,8 +8,8 @@ module Arm
|
||||
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:update_status_flag] = 0
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:update_status_flag] = 0 if @attributes[:update_status_flag] == nil
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@attributes[:opcode] = attributes[:opcode]
|
||||
@operand = 0
|
||||
|
||||
|
@@ -13,8 +13,8 @@ module Arm
|
||||
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
@attributes[:update_status_flag] = 0
|
||||
@attributes[:condition_code] = :al
|
||||
@attributes[:update_status_flag] = 0 if @attributes[:update_status_flag] == nil
|
||||
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil
|
||||
@attributes[:opcode] = attributes[:opcode]
|
||||
@operand = 0
|
||||
|
||||
|
Reference in New Issue
Block a user