remove extra instruction and use next instead

was messing with binary writing as the assumption of 1 word writes is
baked in
This commit is contained in:
Torsten Ruger 2018-04-03 14:46:07 +03:00
parent 0a075c0f8a
commit 30ca70e042
5 changed files with 19 additions and 23 deletions

View File

@ -47,7 +47,6 @@ module Arm
val |= instruction_code val |= instruction_code
val |= condition_code val |= condition_code
io.write_unsigned_int_32 val io.write_unsigned_int_32 val
assemble_extra(io)
end end
def result def result
@ -71,17 +70,24 @@ module Arm
unless @extra unless @extra
@extra = 1 @extra = 1
#puts "RELINK L at #{self.position.to_s(16)}" #puts "RELINK L at #{self.position.to_s(16)}"
extra = ArmMachine.send( opcode , result , result , 0 ) #noop
extra.set_next( @next )
@next = extra
raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}") raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}")
end end
# now we can do the actual breaking of instruction, by splitting the operand # now we can do the actual breaking of instruction, by splitting the operand
operand = calculate_u8_with_rr( right & 0xFFFFFF00 ) operand = calculate_u8_with_rr( right & 0xFFFFFF00 )
raise "no fit for #{right}" unless operand raise "no fit for #{right}" unless operand
# use sub for sub and add for add, ie same as opcode # use sub for sub and add for add, ie same as opcode
@extra = ArmMachine.send( opcode , result , result , (right & 0xFF) ) @next.set_value(right & 0xFF )
end end
return operand return operand
end end
def set_value(val)
@right = val
end
# don't overwrite instance variables, to make assembly repeatable # don't overwrite instance variables, to make assembly repeatable
# this also loads constants, which are issued as pc relative adds # this also loads constants, which are issued as pc relative adds
def determine_operands def determine_operands
@ -101,20 +107,6 @@ module Arm
end end
end end
# by now we have the extra add so assemble that
def assemble_extra(io)
return unless @extra
if(@extra == 1) # unles things have changed and then we add a noop (to keep the length same)
@extra = ArmMachine.mov( :r1 , :r1 )
end
@extra.assemble(io)
#puts "Assemble extra at #{val.to_s(16)}"
end
def byte_length
@extra ? 8 : 4
end
def to_s def to_s
"#{self.class.name} #{opcode} #{@result} = #{@left} #{@right} extra=#{@extra}" "#{self.class.name} #{opcode} #{@result} = #{@left} #{@right} extra=#{@extra}"
end end

View File

@ -28,7 +28,7 @@ module Arm
# know where the other object is, and that position is only set after code positions have been # know where the other object is, and that position is only set after code positions have been
# determined (in link) and so see below in assemble # determined (in link) and so see below in assemble
def byte_length def byte_length
@extra ? 8 : 4 4
end end
# don't overwrite instance variables, to make assembly repeatable # don't overwrite instance variables, to make assembly repeatable
@ -55,8 +55,6 @@ module Arm
val |= instruction_code val |= instruction_code
val |= condition_code val |= condition_code
io.write_unsigned_int_32 val io.write_unsigned_int_32 val
# by now we have the extra add so assemble that
@extra.assemble(io) if(@extra) #puts "Assemble extra at #{val.to_s(16)}"
end end
def instuction_class def instuction_class
@ -70,12 +68,15 @@ module Arm
raise "No negatives implemented #{right} " if right < 0 raise "No negatives implemented #{right} " if right < 0
unless @extra unless @extra
@extra = 1 # puts "RELINK M at #{self.position.to_s(16)}" @extra = 1 # puts "RELINK M at #{self.position.to_s(16)}"
extra = ArmMachine.add( to , to , 0 ) #noop that we change below
extra.set_next(@next)
@next = extra
raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}") raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}")
end end
# now we can do the actual breaking of instruction, by splitting the operand # now we can do the actual breaking of instruction, by splitting the operand
operand = calculate_u8_with_rr( right & 0xFFFFFF00 ) operand = calculate_u8_with_rr( right & 0xFFFFFF00 )
raise "no fit for #{right}" unless operand raise "no fit for #{right}" unless operand
@extra = ArmMachine.add( to , to , (right & 0xFF) ) @next.set_value(right & 0xFF )
operand operand
end end
end end

View File

@ -12,7 +12,7 @@ module Arm
# code is what the generator spits out, at least one instruction worth (.first) # code is what the generator spits out, at least one instruction worth (.first)
# the op code is wat was witten as assembler in the first place and the binary result # the op code is wat was witten as assembler in the first place and the binary result
def assert_code code , op , should def assert_code( code , op , should )
assert_equal op , code.opcode assert_equal op , code.opcode
io = StringIO.new io = StringIO.new
code.assemble(io) code.assemble(io)

View File

@ -83,10 +83,12 @@ module Arm
def test_too_big_add def test_too_big_add
code = @machine.add :r1 , :r1, 0x222 code = @machine.add :r1 , :r1, 0x222
begin # add 0x02 (first instruction) and then 0x220 shifted begin # add 0x02 (first instruction) and then 0x220 shifted
assert_code code , :add , [0x02,0x1c,0x91,0xe2, 0x22,0x10,0x91,0xe2] #e2 91 1e 22 assert_code code , :add , [0x02,0x1c,0x91,0xe2] #e2 91 1e 02
rescue Risc::LinkException rescue Risc::LinkException
retry retry
end end
# added extra instruction to add "extra"
assert_code code.next , :add , [0x22,0x10,0x91,0xe2] #e2 91 10 22
end end
def label pos = 0x22 + 8 def label pos = 0x22 + 8

View File

@ -24,10 +24,11 @@ module Arm
code = @machine.mov :r0, 0x222 # is not 8 bit and can't be rotated by the arm system in one instruction code = @machine.mov :r0, 0x222 # is not 8 bit and can't be rotated by the arm system in one instruction
code.set_position(0) code.set_position(0)
begin # mov 512(0x200) = e3 a0 0c 02 add 34(0x22) = e2 90 00 22 begin # mov 512(0x200) = e3 a0 0c 02 add 34(0x22) = e2 90 00 22
assert_code code , :mov , [ 0x02,0x0c,0xb0,0xe3 , 0x22,0x00,0x90,0xe2] assert_code code , :mov , [ 0x02,0x0c,0xb0,0xe3]
rescue Risc::LinkException rescue Risc::LinkException
retry retry
end end
assert_code code.next , :add , [ 0x22,0x00,0x90,0xe2]
end end
def test_mvn def test_mvn
code = @machine.mvn :r1, 5 code = @machine.mvn :r1, 5