move all position setting into position
Position and subclasses handle the logic, external to the classes, so it can be swapped out later (at runtime positions can’t change)
This commit is contained in:
@ -24,23 +24,7 @@ module Arm
|
||||
def insert(instruction)
|
||||
super
|
||||
my_pos = Risc::Position.get(self)
|
||||
@next.set_position( my_pos + self.byte_length , 0 , my_pos.binary)
|
||||
Risc::Position.set( my_pos + self.byte_length , 0 , my_pos.binary)
|
||||
end
|
||||
|
||||
def set_position( position , count , extra = nil)
|
||||
Risc::Position.set(self,position , extra)
|
||||
position += byte_length
|
||||
if self.next
|
||||
count += 1 #assumes 4 byte instructions, as does the whole setup
|
||||
if( 0 == count % 12) # 12 is the amount of instructions that fit into a BinaryCode
|
||||
count = 0
|
||||
position += 12 # 12=3*4 , 3 for marker,type,next words to jump over
|
||||
end
|
||||
self.next.set_position( position , count , extra)
|
||||
else
|
||||
position
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -1,81 +0,0 @@
|
||||
module Arm
|
||||
class MachineCode
|
||||
|
||||
def function_call( into , call )
|
||||
raise "Not CallSite #{call.inspect}" unless call.is_a? Risc::CallSite
|
||||
raise "Not linked #{call.inspect}" unless call.function
|
||||
into.add_code call( call.function )
|
||||
raise "No return type for #{call.function.name}" unless call.function.return_type
|
||||
call.function.return_type
|
||||
end
|
||||
|
||||
def main_start( context )
|
||||
entry = Risc::Block.new("main_entry",nil,nil)
|
||||
entry.add_code mov( :fp , 0 )
|
||||
entry.add_code call( context.function )
|
||||
entry
|
||||
end
|
||||
def main_exit( context )
|
||||
exit = Risc::Block.new("main_exit",nil,nil)
|
||||
syscall(exit , 1)
|
||||
exit
|
||||
end
|
||||
def function_entry( block, f_name )
|
||||
block.add_code push( [:lr] )
|
||||
block
|
||||
end
|
||||
def function_exit( entry , f_name )
|
||||
entry.add_code pop( [:pc] )
|
||||
entry
|
||||
end
|
||||
|
||||
# assumes string in standard receiver reg (r2) and moves them down for the syscall
|
||||
def write_stdout( function ) #, string
|
||||
# TODO save and restore r0
|
||||
function.mov( :r0 , 1 ) # 1 == stdout
|
||||
function.mov( :r1 , receiver_register )
|
||||
function.mov( receiver_register , :r3 )
|
||||
syscall( function.insertion_point , 4 ) # 4 == write
|
||||
end
|
||||
|
||||
# stop, do not return
|
||||
def exit( function )#, string
|
||||
syscall( function.insertion_point , 1 ) # 1 == exit
|
||||
end
|
||||
|
||||
|
||||
# the number (a Risc::Integer) is (itself) divided by 10, ie overwritten by the result
|
||||
# and the remainder is overwritten (ie an out argument)
|
||||
# not really a function, more a macro,
|
||||
def div10( function, number , remainder )
|
||||
# Note about division: devision is MUCH more expensive than one would have thought
|
||||
# And coding it is a bit of a mind leap: it's all about finding a a result that gets the
|
||||
# remainder smaller than an int. i'll post some links sometime. This is from the arm manual
|
||||
tmp = function.new_local
|
||||
function.instance_eval do
|
||||
sub( remainder , number , 10 )
|
||||
sub( number , number , number , shift_lsr: 2)
|
||||
add( number , number , number , shift_lsr: 4)
|
||||
add( number , number , number , shift_lsr: 8)
|
||||
add( number , number , number , shift_lsr: 16)
|
||||
mov( number , number , shift_lsr: 3)
|
||||
add( tmp , number , number , shift_lsl: 2)
|
||||
sub( remainder , remainder , tmp , shift_lsl: 1 , update_status: 1)
|
||||
add( number , number, 1 , condition_code: :pl )
|
||||
add( remainder , remainder , 10 , condition_code: :mi )
|
||||
end
|
||||
end
|
||||
|
||||
def syscall( block , num )
|
||||
# This is very arm specific, syscall number is passed in r7,
|
||||
# other arguments like a c call ie 0 and up
|
||||
sys = Risc::Integer.new( Risc::RiscValue.new(SYSCALL_REG) )
|
||||
ret = Risc::Integer.new( Risc::RiscValue.new(RETURN_REG) )
|
||||
block.add_code mov( sys , num )
|
||||
block.add_code swi( 0 )
|
||||
#todo should write type into r1 according to syscall
|
||||
ret
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user