Class: Indis::ARM::MnemonicLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/indis-arm/instruction_loader.rb

Constant Summary collapse

AUTOMAPPED =

A default map. Would set up the mapping only if the attribute name was passed in #attrs

{
  'C' => :cond,
  'n' => :Rn,
  'm' => :Rm,
  'd' => :Rd,
  't' => :Rt,
  'S' => :setflags,
}
AUTOMAPPED_PROCS =
{
  cond: proc { |k| @cond = h.cond(k.cond) },
  Rn: proc { |k| @Rn = h.reg(k.Rn) },
  Rm: proc { |k| @Rm = h.reg(k.Rm) },
  Rd: proc { |k| @Rd = h.reg(k.Rd) },
  Rt: proc { |k| @Rt = h.reg(k.Rt) },
  setflags: proc { |k| @setflags = k.setflags == 1 },
}

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ MnemonicLoader

Returns a new instance of MnemonicLoader.



102
103
104
# File 'lib/indis-arm/instruction_loader.rb', line 102

def initialize(klass)
  @klass = klass
end

Instance Method Details

#attrs(*attrs) ⇒ Object

Loads instruction attributes



134
135
136
137
# File 'lib/indis-arm/instruction_loader.rb', line 134

def attrs(*attrs)
  @klass_attrs = attrs
  @klass.instance_eval { attr_reader *attrs }
end

#bits(bitstring) ⇒ Object #bits(bitstring, map) ⇒ Object

Loads bit representation of instruction

Overloads:

  • #bits(bitstring) ⇒ Object

    Parameters:

    • bitstring (String)

      a string with no special-mapped bits (either no specail bits at all, or all bits are automapped)

  • #bits(bitstring, map) ⇒ Object

    Parameters:

    • bitstring (String)

      a string with bits map

    • map (Hash{String => Symbol})

      a map from bit string to parsed symbol



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/indis-arm/instruction_loader.rb', line 112

def bits(*args)
  raise "Malformed bits field" if args.length < 1 || args.length > 2
  b = args.first
  @klass.instance_eval { @bits = b }
  
  map = {}
  AUTOMAPPED.each { |k,v| map[k] = v if @klass_attrs.include?(v) }
  map.merge!(args[1]) if args.length == 2
  
  a = map.map do |v, name|
    # TODO: chek on what happens if there is no cond 'C'
    mask = b.gsub(Regexp.new("[^#{v}]"), '0').gsub(/[^0]/, "1")
    ofs = mask.match(/0*$/)[0].length
    mask = mask.to_i(2)
    
    [mask, ofs, name]
  end
  
  @klass.instance_eval { @kmap = a }
end

#format(fmt) ⇒ Object

Loads instruction format



140
141
142
143
144
145
146
147
148
# File 'lib/indis-arm/instruction_loader.rb', line 140

def format(fmt)
  if @klass_attrs.include?(:setflags)
    formats = { operator: '#{self.class.name}#{h.flag @setflags, "S"}#{h.cond_to_s(@cond)}' }
  else
    formats = { operator: '#{self.class.name}#{h.cond_to_s(@cond)}' }
  end
  formats.merge!(fmt)
  @klass.instance_eval { @formats = formats }
end

#process(&block) ⇒ Object

Loads instruction processing block



151
152
153
154
155
156
# File 'lib/indis-arm/instruction_loader.rb', line 151

def process(&block)
  automap_keys = @klass_attrs & AUTOMAPPED.values
  automap_proc = AUTOMAPPED_PROCS.map { |k,p| automap_keys.include?(k) ? p : nil }.compact
  @klass.instance_eval { @process_automap = automap_proc }
  @klass.instance_eval { @process_block = block }
end