2017-01-19 08:02:29 +01:00
|
|
|
module Risc
|
2015-10-23 20:27:36 +02:00
|
|
|
|
|
|
|
# A label is a placeholder for it's next Instruction
|
2018-05-30 09:54:18 +02:00
|
|
|
# It's function is not to turn into code, but to be a valid branch target
|
|
|
|
# Labels have the same position as their next instruction (See positioning code)
|
2015-10-23 20:27:36 +02:00
|
|
|
#
|
|
|
|
# So branches and Labels are pairs, fan out, fan in
|
|
|
|
#
|
2018-05-30 09:54:18 +02:00
|
|
|
# For a return, the address (position) of the label has to be loaded.
|
2018-05-30 23:07:58 +02:00
|
|
|
# So a Label carries the ReturnAddress constant that holds the address (it's own
|
2018-05-30 09:54:18 +02:00
|
|
|
# position, again see positioning code).
|
|
|
|
# But currently the label is used in the Risc abstraction layer, and in the
|
|
|
|
# arm/interpreter layer. The integer is only used in the lower layer, but needs
|
|
|
|
# to be created (and positioned)
|
2015-10-23 20:27:36 +02:00
|
|
|
|
|
|
|
class Label < Instruction
|
2018-05-30 09:54:18 +02:00
|
|
|
# See class description. also factory method Risc.label below
|
2018-05-30 23:07:58 +02:00
|
|
|
def initialize( source , name , addr , nekst = nil)
|
2015-10-23 20:27:36 +02:00
|
|
|
super(source , nekst)
|
|
|
|
@name = name
|
2018-05-30 23:07:58 +02:00
|
|
|
@address = addr
|
|
|
|
raise "Not address #{addr}" unless addr.is_a?(Parfait::ReturnAddress)
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
2018-05-30 23:07:58 +02:00
|
|
|
attr_reader :name , :address
|
2015-10-23 20:27:36 +02:00
|
|
|
|
2018-03-25 18:38:59 +02:00
|
|
|
def to_cpu(translator)
|
|
|
|
@cpu_label ||= super
|
|
|
|
end
|
|
|
|
|
2015-10-23 20:27:36 +02:00
|
|
|
def to_s
|
2018-03-22 17:38:19 +01:00
|
|
|
class_source "#{@name} (next: #{self.next.class.name.split("::").last})"
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
2016-12-28 20:40:06 +01:00
|
|
|
|
2018-05-14 11:38:44 +02:00
|
|
|
def rxf_reference_name
|
2015-11-14 23:35:43 +01:00
|
|
|
@name
|
2015-11-14 21:53:01 +01:00
|
|
|
end
|
2015-10-23 20:27:36 +02:00
|
|
|
|
2015-11-03 15:22:24 +01:00
|
|
|
# a method start has a label of the form Class.method , test for that
|
|
|
|
def is_method
|
|
|
|
@name.split(".").length == 2
|
|
|
|
end
|
|
|
|
|
2018-03-26 18:17:30 +02:00
|
|
|
def assemble_all( io )
|
|
|
|
self.each {|ins| ins.assemble(io)}
|
|
|
|
end
|
|
|
|
|
2015-10-25 09:54:19 +01:00
|
|
|
def assemble io
|
|
|
|
end
|
|
|
|
|
2018-03-26 19:05:30 +02:00
|
|
|
def total_byte_length
|
|
|
|
ret = 0
|
|
|
|
self.each{|ins| ret += ins.byte_length}
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
|
2015-11-03 15:22:24 +01:00
|
|
|
# shame we need this, just for logging
|
|
|
|
def byte_length
|
|
|
|
0
|
|
|
|
end
|
2018-03-27 17:47:39 +02:00
|
|
|
alias :padded_length :byte_length
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|
2016-12-28 18:01:58 +01:00
|
|
|
|
2018-05-30 09:54:18 +02:00
|
|
|
# Labels carry what is esentially an integer constant
|
|
|
|
# The int holds the labels position for use at runtime (return address)
|
|
|
|
# An integer is plucked from object_space abd added to the machine constant pool
|
|
|
|
# if none was given
|
2018-05-29 19:26:00 +02:00
|
|
|
def self.label( source , name , position = nil , nekst = nil)
|
2018-08-29 20:02:49 +02:00
|
|
|
position = Parfait.object_space.get_next_for(:ReturnAddress) unless position
|
2018-05-29 19:26:00 +02:00
|
|
|
Label.new( source , name , position, nekst )
|
2016-12-28 18:01:58 +01:00
|
|
|
end
|
2015-10-23 20:27:36 +02:00
|
|
|
end
|