expand constant load
slightly hacky, but in good tradition previous implementation only worked until 16 significant bits, which is getting to little this one just keeps adding more instructions to arrive at the constant by force There are surely cleverer ways of doing this, ie by using the barrel shifter A start on #15, admittedly a hack
This commit is contained in:
parent
b2339dc330
commit
c3b026a180
@ -62,21 +62,25 @@ module Arm
|
||||
# happen, and so they are split into two instructions. An exeption is thrown, that triggers
|
||||
# some position handling and an @extra add instruction generated.
|
||||
def handle_numeric(right)
|
||||
if (right.fits_u8?)
|
||||
operand = right # no shifting needed
|
||||
elsif (op_with_rot = calculate_u8_with_rr(right))
|
||||
operand = op_with_rot
|
||||
else
|
||||
unless @extra
|
||||
@extra = 1
|
||||
# puts "RELINK L at #{Risc::Position.get(self)}"
|
||||
# use sub for sub and add for add, ie same as opcode
|
||||
insert ArmMachine.send( opcode , result , result , 0 ) #noop
|
||||
end
|
||||
return right if (right.fits_u8?) # no shifting needed
|
||||
if (op_with_rot = calculate_u8_with_rr(right))
|
||||
return op_with_rot
|
||||
end
|
||||
unless @extra
|
||||
# puts "RELINK L at #{Risc::Position.get(self)}"
|
||||
# use sub for sub and add for add, ie same as opcode
|
||||
insert ArmMachine.send( opcode , result , result , 0 ) #noop
|
||||
@extra = @next
|
||||
end
|
||||
shift = 0xFF
|
||||
operand = nil
|
||||
until( operand )
|
||||
mask = 0xFFFFFFFF ^ shift
|
||||
# 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} in #{self}" unless operand
|
||||
@next.set_value(right & 0xFF )
|
||||
operand = calculate_u8_with_rr( right & mask )
|
||||
@next.set_value(right & shift )
|
||||
raise "internal #{shift} for #{self}" if shift > 0xFFFFFF
|
||||
shift = (shift << 8) + 0xFF
|
||||
end
|
||||
return operand
|
||||
end
|
||||
@ -97,9 +101,12 @@ module Arm
|
||||
right = Risc::Position.get(left) - 8
|
||||
right -= Risc::Position.get(self).at
|
||||
if( (right < 0) && ((opcode == :add) || (opcode == :sub)) )
|
||||
puts "Inverting, was #{right} , new #{-1*right}"
|
||||
puts "left #{left.class} #{Risc::Position.get(left)}"
|
||||
puts "self #{Risc::Position.get(self)}"
|
||||
right *= -1 # this works as we never issue sub only add
|
||||
set_opcode :sub # so (as we can't change the sign permanently) we can change the opcode
|
||||
end # and the sign even for sub (becuase we created them)
|
||||
end # and the sign even for sub (beucase we created them)
|
||||
raise "No negatives implemented #{self} #{right} " if right < 0
|
||||
return :pc , right
|
||||
else
|
||||
|
@ -76,11 +76,11 @@ module Arm
|
||||
code = @machine.add( :r1 , :r2 , :r3 , shift_lsr: 8)
|
||||
assert_code code , :add , [0x23,0x14,0x92,0xe0] #e0 92 14 23
|
||||
end
|
||||
def test_big_add
|
||||
def test_add_big
|
||||
code = @machine.add :r1 , :r1, 0x220
|
||||
assert_code code , :add , [0x22,0x1e,0x91,0xe2] #e2 91 1e 22
|
||||
end
|
||||
def test_too_big_add
|
||||
def test_add_2ins
|
||||
code = @machine.add :r1 , :r1, 0x222
|
||||
Risc::Position.create(code).set(0)
|
||||
# add 0x02 (first instruction) and then 0x220 shifted
|
||||
@ -88,6 +88,12 @@ module Arm
|
||||
# added extra instruction to add "extra"
|
||||
assert_code code.next , :add , [0x22,0x10,0x91,0xe2] #e2 91 10 22
|
||||
end
|
||||
def test_add_3ins
|
||||
code = @machine.add :r1 , :r1, 0x29d84
|
||||
assert_code code , :add , [0x02,0x18,0x91,0xe2]
|
||||
assert_code code.next , :add , [0x9d,0x1c,0x91,0xe2]
|
||||
assert_code code.next.next , :add , [0x84,0x10,0x91,0xe2]
|
||||
end
|
||||
|
||||
def label( pos = 0x22 + 8)
|
||||
addr = FakeAddress.new(pos)
|
||||
|
Loading…
Reference in New Issue
Block a user