crystal says Hello.
This commit is contained in:
@ -33,8 +33,16 @@ module Arm
|
||||
def word_load value , reg
|
||||
mov( :left => reg , :right => value )
|
||||
end
|
||||
def string_load str_lit , reg
|
||||
[ add( :left => "r#{reg}".to_sym , :extra => str_lit ) , #right is pc, implicit
|
||||
#second arg is a hack to get the stringlength without coding
|
||||
mov( :left => "r#{reg+1}".to_sym , :right => str_lit.length ) ]
|
||||
end
|
||||
|
||||
def function_call call
|
||||
raise "Not FunctionCall #{call.inspect}" unless call.is_a? Vm::FunctionCall
|
||||
call.args.each do | arg |
|
||||
end
|
||||
bl( :left => call.function )
|
||||
end
|
||||
|
||||
@ -44,18 +52,28 @@ module Arm
|
||||
end
|
||||
def main_exit
|
||||
entry = Vm::Block.new("main_exit")
|
||||
entry.add_code syscall(0)
|
||||
entry.add_code syscall(1)
|
||||
end
|
||||
def function_entry f_name
|
||||
entry = Vm::Block.new("#{f_name}_entry")
|
||||
entry.add_code push( :left => :lr )
|
||||
# entry.add_code push( :left => :lr )
|
||||
end
|
||||
def function_exit f_name
|
||||
entry = Vm::Block.new("#{f_name}_exit")
|
||||
entry.add_code pop( :left => :pc )
|
||||
entry.add_code mov( :left => :pc , :right => :lr )
|
||||
end
|
||||
def putstring
|
||||
put = Vm::Block.new("putstring_code")
|
||||
# should be another level of indirection, ie write(io,str)
|
||||
put.add_code mov( :left => :r2 , :right => :r1 )
|
||||
put.add_code mov( :left => :r1 , :right => :r0 )
|
||||
put.add_code mov( :left => :r0 , :right => 1 ) #stdout
|
||||
put.add_code syscall(4)
|
||||
end
|
||||
private
|
||||
def syscall num
|
||||
[mov( :left => :r7 , :right => num ) , swi( :left => 0 )]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -4,11 +4,6 @@ module Arm
|
||||
module LogicHelper
|
||||
# ADDRESSING MODE 1
|
||||
# Logic ,Maths, Move and compare instructions (last three below)
|
||||
# Build representation for source value
|
||||
def build
|
||||
@rn = @args[1]
|
||||
do_build @args[2]
|
||||
end
|
||||
|
||||
# arm intrucioons are pretty sensible, and always 4 bytes (thumb not supported)
|
||||
def length
|
||||
@ -21,6 +16,7 @@ module Arm
|
||||
# do pc relative addressing with the difference to the instuction
|
||||
# 8 is for the funny pipeline adjustment (ie oc pointing to fetch and not execute)
|
||||
arg = Arm::NumLiteral.new( arg.position - self.position - 8 )
|
||||
@rn = :pc
|
||||
end
|
||||
if( arg.is_a? Fixnum ) #HACK to not have to change the code just now
|
||||
arg = Arm::NumLiteral.new( arg )
|
||||
@ -36,7 +32,7 @@ module Arm
|
||||
else
|
||||
raise "cannot fit numeric literal argument in operand #{arg}"
|
||||
end
|
||||
elsif (arg.is_a?(Arm::Register))
|
||||
elsif (arg.is_a?(Symbol))
|
||||
@operand = arg
|
||||
@i = 0
|
||||
elsif (arg.is_a?(Arm::Shift))
|
||||
@ -64,7 +60,7 @@ module Arm
|
||||
|
||||
@operand = rm_ref | (shift_op << 4) | (shift_imm << 4+3)
|
||||
else
|
||||
raise "invalid operand argument #{arg.inspect}"
|
||||
raise "invalid operand argument #{arg.inspect} , #{inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
@ -87,7 +83,7 @@ module Arm
|
||||
include LogicHelper
|
||||
|
||||
def initialize(options)
|
||||
super(options)
|
||||
super(options)
|
||||
@update_status_flag = 0
|
||||
@condition_code = :al
|
||||
@opcode = options[:opcode]
|
||||
@ -96,9 +92,14 @@ module Arm
|
||||
|
||||
@rn = nil
|
||||
@i = 0
|
||||
@rd = args[0]
|
||||
@rd = @args[0]
|
||||
end
|
||||
attr_accessor :i, :rn, :rd
|
||||
# Build representation for source value
|
||||
def build
|
||||
@rn = @args[1]
|
||||
do_build @args[2]
|
||||
end
|
||||
|
||||
end
|
||||
class CompareInstruction < Vm::CompareInstruction
|
||||
|
@ -7,16 +7,22 @@ module Arm
|
||||
class MemoryInstruction < Vm::MemoryInstruction
|
||||
include Arm::Constants
|
||||
|
||||
def initialize(opcode , condition_code , update_status , args)
|
||||
super(opcode , condition_code , update_status , args)
|
||||
def initialize(options)
|
||||
super(options)
|
||||
@update_status_flag = 0
|
||||
@condition_code = :al
|
||||
@opcode = options[:opcode]
|
||||
@args = [options[:left] , options[:right] ]
|
||||
@operand = 0
|
||||
|
||||
@i = 0 #I flag (third bit)
|
||||
@pre_post_index = 0 #P flag
|
||||
@add_offset = 0 #U flag
|
||||
@byte_access = opcode.to_s[-1] == "b" ? 1 : 0 #B (byte) flag
|
||||
@w = 0 #W flag
|
||||
@is_load = opcode.to_s[0] == "l" ? 1 : 0 #L (load) flag
|
||||
@rn = reg "r0" # register zero = zero bit pattern
|
||||
@rd = reg "r0" # register zero = zero bit pattern
|
||||
@rn = :r0 # register zero = zero bit pattern
|
||||
@rd = :r0 # register zero = zero bit pattern
|
||||
end
|
||||
attr_accessor :i, :pre_post_index, :add_offset,
|
||||
:byte_access, :w, :is_load, :rn, :rd
|
||||
@ -29,17 +35,17 @@ module Arm
|
||||
# Build representation for target address
|
||||
def build
|
||||
if( @is_load )
|
||||
@rd = args[0]
|
||||
arg = args[1]
|
||||
@rd = @args[0]
|
||||
arg = @args[1]
|
||||
else #store
|
||||
@rd = args[1]
|
||||
arg = args[0]
|
||||
@rd = @args[1]
|
||||
arg = @args[0]
|
||||
end
|
||||
#str / ldr are _serious instructions. With BIG possibilities not half are implemented
|
||||
if (arg.is_a?(Arm::Register))
|
||||
if (arg.is_a?(Symbol)) #symbol is register
|
||||
@rn = arg
|
||||
if(arg.offset != 0)
|
||||
@operand = arg.offset
|
||||
if options[:offset]
|
||||
@operand = options[:offset]
|
||||
if (@operand < 0)
|
||||
@add_offset = 0
|
||||
#TODO test/check/understand
|
||||
@ -51,6 +57,13 @@ module Arm
|
||||
raise "reference offset too large/small (max 4095) #{arg} #{inspect}"
|
||||
end
|
||||
end
|
||||
elsif (arg.is_a?(Vm::StringLiteral)) #use pc relative
|
||||
@rn = :pc
|
||||
@operand = arg.position - self.position - 8 #stringtable is after code
|
||||
@add_offset = 1
|
||||
if (@operand.abs > 4095)
|
||||
raise "reference offset too large/small (max 4095) #{arg} #{inspect}"
|
||||
end
|
||||
elsif (arg.is_a?(Arm::Label) or arg.is_a?(Arm::NumLiteral))
|
||||
@pre_post_index = 1
|
||||
@rn = pc
|
||||
@ -69,9 +82,9 @@ module Arm
|
||||
@add_offset = 1
|
||||
@pre_post_index = 1
|
||||
instuction_class = 0b01 # OPC_MEMORY_ACCESS
|
||||
val = operand
|
||||
val |= (rd.bits << 12 )
|
||||
val |= (rn.bits << 12+4) #16
|
||||
val = @operand.is_a?(Symbol) ? reg_code(@operand) : @operand
|
||||
val |= (reg_code(rd) << 12 )
|
||||
val |= (reg_code(rn) << 12+4) #16
|
||||
val |= (is_load << 12+4 +4)
|
||||
val |= (w << 12+4 +4+1)
|
||||
val |= (byte_access << 12+4 +4+1+1)
|
||||
@ -81,6 +94,7 @@ module Arm
|
||||
val |= (instuction_class<<12+4 +4+1+1+1+1 +1+1)
|
||||
val |= (cond_bit_code << 12+4 +4+1+1+1+1 +1+1+2)
|
||||
io.write_uint32 val
|
||||
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user