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:
parent
0a075c0f8a
commit
30ca70e042
@ -47,7 +47,6 @@ module Arm
|
||||
val |= instruction_code
|
||||
val |= condition_code
|
||||
io.write_unsigned_int_32 val
|
||||
assemble_extra(io)
|
||||
end
|
||||
|
||||
def result
|
||||
@ -71,17 +70,24 @@ module Arm
|
||||
unless @extra
|
||||
@extra = 1
|
||||
#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}")
|
||||
end
|
||||
# now we can do the actual breaking of instruction, by splitting the operand
|
||||
operand = calculate_u8_with_rr( right & 0xFFFFFF00 )
|
||||
raise "no fit for #{right}" unless operand
|
||||
# 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
|
||||
return operand
|
||||
end
|
||||
|
||||
def set_value(val)
|
||||
@right = val
|
||||
end
|
||||
|
||||
# don't overwrite instance variables, to make assembly repeatable
|
||||
# this also loads constants, which are issued as pc relative adds
|
||||
def determine_operands
|
||||
@ -101,20 +107,6 @@ module Arm
|
||||
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
|
||||
"#{self.class.name} #{opcode} #{@result} = #{@left} #{@right} extra=#{@extra}"
|
||||
end
|
||||
|
@ -28,7 +28,7 @@ module Arm
|
||||
# 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
|
||||
def byte_length
|
||||
@extra ? 8 : 4
|
||||
4
|
||||
end
|
||||
|
||||
# don't overwrite instance variables, to make assembly repeatable
|
||||
@ -55,8 +55,6 @@ module Arm
|
||||
val |= instruction_code
|
||||
val |= condition_code
|
||||
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
|
||||
|
||||
def instuction_class
|
||||
@ -70,12 +68,15 @@ module Arm
|
||||
raise "No negatives implemented #{right} " if right < 0
|
||||
unless @extra
|
||||
@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}")
|
||||
end
|
||||
# now we can do the actual breaking of instruction, by splitting the operand
|
||||
operand = calculate_u8_with_rr( right & 0xFFFFFF00 )
|
||||
raise "no fit for #{right}" unless operand
|
||||
@extra = ArmMachine.add( to , to , (right & 0xFF) )
|
||||
@next.set_value(right & 0xFF )
|
||||
operand
|
||||
end
|
||||
end
|
||||
|
@ -12,7 +12,7 @@ module Arm
|
||||
|
||||
# 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
|
||||
def assert_code code , op , should
|
||||
def assert_code( code , op , should )
|
||||
assert_equal op , code.opcode
|
||||
io = StringIO.new
|
||||
code.assemble(io)
|
||||
|
@ -83,10 +83,12 @@ module Arm
|
||||
def test_too_big_add
|
||||
code = @machine.add :r1 , :r1, 0x222
|
||||
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
|
||||
retry
|
||||
end
|
||||
# added extra instruction to add "extra"
|
||||
assert_code code.next , :add , [0x22,0x10,0x91,0xe2] #e2 91 10 22
|
||||
end
|
||||
|
||||
def label pos = 0x22 + 8
|
||||
|
@ -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.set_position(0)
|
||||
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
|
||||
retry
|
||||
end
|
||||
assert_code code.next , :add , [ 0x22,0x00,0x90,0xe2]
|
||||
end
|
||||
def test_mvn
|
||||
code = @machine.mvn :r1, 5
|
||||
|
Loading…
Reference in New Issue
Block a user