makes memory a three operand instruction, like add etc. But 3 regs are still undone
This commit is contained in:
parent
08bbad0fdc
commit
31a55b07ac
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user