rubyx/lib/arm/passes/syscall_implementation.rb

40 lines
1.2 KiB
Ruby
Raw Normal View History

2015-06-23 18:55:54 +02:00
module Arm
class SyscallImplementation
CALLS_CODES = { :putstring => 4 , :exit => 1 }
2015-06-23 18:55:54 +02:00
def run block
block.codes.dup.each do |code|
next unless code.is_a? Register::Syscall
new_codes = []
int_code = CALLS_CODES[code.name]
raise "Not implemented syscall, #{code.name}" unless int_code
send( code.name , int_code , new_codes )
2015-06-23 18:55:54 +02:00
block.replace(code , new_codes )
end
end
def putstring int_code , codes
2015-07-01 20:42:59 +02:00
codes << ArmMachine.ldr( :r1 , Register.message_reg, 4 * Register.resolve_index(:message , :receiver))
2015-07-02 08:49:52 +02:00
codes << ArmMachine.add( :r1 , :r1 , 8 )
codes << ArmMachine.mov( :r0 , 1 ) # stdout == 1
codes << ArmMachine.mov( :r2 , 12 ) # String length, obvious TODO
syscall(int_code , codes )
end
def exit int_code , codes
syscall int_code , codes
end
private
# syscall is always triggered by swi(0)
# The actual code (ie the index of the kernel function) is in r7
def syscall int_code , codes
codes << ArmMachine.mov( :r7 , int_code )
codes << ArmMachine.swi( 0 )
end
2015-06-23 18:55:54 +02:00
end
Virtual.machine.add_pass "Arm::SyscallImplementation"
2015-06-23 18:55:54 +02:00
end