compiler/asm/regproxy.rb

67 lines
No EOL
1.2 KiB
Ruby

module Assembler
# Acts like a register and can be used as the base or index in an
# effective address.
#
# e.g. [EAX] or [ESI+EBX] or [EAX + 0xff] or [EAX + EDX * 2]
class RegisterProxy
attr_reader :name, :size, :regnum
attr_reader :base, :index, :scale
def initialize(name, size, regnum)
@name = name # attrs are read-only so sharing is ok
@size = size
@regnum = regnum
@base = self
end
def +(index)
raise "index already specified" if @index
new_reg = self.clone
new_reg.instance_variable_set('@index', index)
new_reg
end
def *(scale)
raise "index must come first" unless @index
raise "scale already specified" if scale
raise "unsupported scale: #{scale}" unless scale.to_s.match(/^[1248]$/)
@scale = scale
self
end
def scale?
@scale
end
def index?
@index
end
def register?
@scale.nil? && @index.nil?
end
def to_s
@name.to_s +
(@index ? "+#{@index}" : '') +
(@scale ? "*#{@scale}" : '')
end
def inspect
to_s
end
end
end