makes memory a three operand instruction, like add etc. But 3 regs are still undone

This commit is contained in:
Torsten Ruger 2014-06-01 21:20:44 +03:00
parent 08bbad0fdc
commit 31a55b07ac
4 changed files with 24 additions and 17 deletions

View File

@ -6,8 +6,8 @@ module Arm
class MemoryInstruction < Vm::MemoryInstruction class MemoryInstruction < Vm::MemoryInstruction
include Arm::Constants include Arm::Constants
def initialize(first , attributes) def initialize(result , left , right = nil , attributes = {})
super(first , attributes) super(result , left , right , attributes)
@attributes[:update_status] = 0 if @attributes[:update_status] == nil @attributes[:update_status] = 0 if @attributes[:update_status] == nil
@attributes[:condition_code] = :al if @attributes[:condition_code] == nil @attributes[:condition_code] = :al if @attributes[:condition_code] == nil
@operand = 0 @operand = 0
@ -24,13 +24,13 @@ module Arm
# Build representation for target address # Build representation for target address
def build def build
arg = @attributes[:right] arg = @left
arg = "r#{arg.register}".to_sym if( arg.is_a? Vm::Word ) arg = "r#{arg.register}".to_sym if( arg.is_a? Vm::Word )
#str / ldr are _serious instructions. With BIG possibilities not half are implemented #str / ldr are _serious instructions. With BIG possibilities not half are implemented
if (arg.is_a?(Symbol)) #symbol is register if (arg.is_a?(Symbol)) #symbol is register
@rn = arg @rn = arg
if @attributes[:offset] if @right
@operand = @attributes[:offset] @operand = @right
if (@operand < 0) if (@operand < 0)
@add_offset = 0 @add_offset = 0
#TODO test/check/understand #TODO test/check/understand
@ -62,6 +62,7 @@ module Arm
def assemble(io) def assemble(io)
build build
puts inspect
i = 0 #I flag (third bit) i = 0 #I flag (third bit)
#not sure about these 2 constants. They produce the correct output for str r0 , r1 #not sure about these 2 constants. They produce the correct output for str r0 , r1
# but i can't help thinking that that is because they are not used in that instruction and # but i can't help thinking that that is because they are not used in that instruction and
@ -77,7 +78,7 @@ module Arm
val = reg_code(@operand) if @operand.is_a?(Symbol) val = reg_code(@operand) if @operand.is_a?(Symbol)
val = shift(val , 0 ) # for the test val = shift(val , 0 ) # for the test
@pre_post_index = 0 if @attributes[:flaggie] @pre_post_index = 0 if @attributes[:flaggie]
val |= shift(reg_code(@first) , 12 ) val |= shift(reg_code(@result) , 12 )
val |= shift(reg_code(@rn) , 12+4) #16 val |= shift(reg_code(@rn) , 12+4) #16
val |= shift(@is_load , 12+4 +4) val |= shift(@is_load , 12+4 +4)
val |= shift(w , 12+4 +4+1) val |= shift(w , 12+4 +4+1)

View File

@ -49,8 +49,10 @@ module Vm
end end
end end
class MemoryInstruction < Instruction class MemoryInstruction < Instruction
def initialize first , options = {} def initialize result , left , right = nil , options = {}
@first = first @result = result
@left = left
@right = right
super(options) super(options)
end end
end end

View File

@ -57,7 +57,7 @@ module Vm
define_instruction_two(inst , CompareInstruction) define_instruction_two(inst , CompareInstruction)
end end
[:strb, :str , :ldrb, :ldr].each do |inst| [:strb, :str , :ldrb, :ldr].each do |inst|
define_instruction_one(inst , MemoryInstruction) define_instruction_three(inst , MemoryInstruction)
end end
[:b, :call , :swi].each do |inst| [:b, :call , :swi].each do |inst|
define_instruction_one(inst , CallInstruction) define_instruction_one(inst , CallInstruction)
@ -126,7 +126,7 @@ module Vm
# same for three args (result = left right,) # same for three args (result = left right,)
def define_instruction_three(inst , clazz , defaults = {} ) def define_instruction_three(inst , clazz , defaults = {} )
clazz = self.class_for(clazz) clazz = self.class_for(clazz)
create_method(inst) do |result , left ,right , options = nil| create_method(inst) do |result , left ,right = nil , options = nil|
options = {} if options == nil options = {} if options == nil
options.merge defaults options.merge defaults
options[:opcode] = inst options[:opcode] = inst

View File

@ -4,30 +4,34 @@ class TestMemory < MiniTest::Test
include ArmHelper include ArmHelper
def test_ldr def test_ldr
code = @machine.ldr :r0, right: :r0 code = @machine.ldr :r0, :r0
assert_code code, :ldr , [0x00,0x00,0x90,0xe5] #e5 90 00 00 assert_code code, :ldr , [0x00,0x00,0x90,0xe5] #e5 90 00 00
end end
def test_ldr2 def test_ldr_const_offset
code = @machine.ldr :r0, right: :r0 , :offset => 4 code = @machine.ldr :r0, :r0 , 4
assert_code code, :ldr , [0x04,0x00,0x90,0xe5] #e5 90 00 04 assert_code code, :ldr , [0x04,0x00,0x90,0xe5] #e5 90 00 04
end end
def test_ldr_reg_offset
code = @machine.ldr :r0, :r1 , :r2
assert_code code, :ldr , [0x02,0x00,0x91,0xe6] #e6 91 00 02
end
def test_ldrb def test_ldrb
code = @machine.ldrb :r0, right: :r0 code = @machine.ldrb :r0, :r0
assert_code code, :ldrb , [0x00,0x00,0xd0,0xe5] #e5 d0 00 00 assert_code code, :ldrb , [0x00,0x00,0xd0,0xe5] #e5 d0 00 00
end end
def test_str def test_str
code = @machine.str :r0, right: :r1 code = @machine.str :r0, :r1
assert_code code, :str , [0x00,0x00,0x81,0xe5] #e5 81 00 00 assert_code code, :str , [0x00,0x00,0x81,0xe5] #e5 81 00 00
end end
def test_strb_add def test_strb_add
code = @machine.strb :r0, right: :r1 , :offset => 1 , flaggie: 1 code = @machine.strb :r0, :r1 , 1 , flaggie: 1
assert_code code, :strb , [0x01,0x00,0xc1,0xe4] #e4 c1 00 01 assert_code code, :strb , [0x01,0x00,0xc1,0xe4] #e4 c1 00 01
end end
def test_strb def test_strb
code = @machine.strb :r0, right: :r0 code = @machine.strb :r0, :r0
assert_code code, :strb , [0x00,0x00,0xc0,0xe5] #e5 c0 00 00 assert_code code, :strb , [0x00,0x00,0xc0,0xe5] #e5 c0 00 00
end end
end end