Class: AVR::OpcodeDecoder

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/avr/opcode_decoder.rb

Defined Under Namespace

Classes: DecodedOpcode, OpcodeDefinition, OperandParser

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeOpcodeDecoder

Returns a new instance of OpcodeDecoder.



167
168
169
# File 'lib/avr/opcode_decoder.rb', line 167

def initialize
  @cache = T.let({}, T::Hash[Integer, DecodedOpcode])
end

Class Attribute Details

.opcode_definitionsObject (readonly)

Returns the value of attribute opcode_definitions.



142
143
144
# File 'lib/avr/opcode_decoder.rb', line 142

def opcode_definitions
  @opcode_definitions
end

.opcode_match_masksObject (readonly)

Returns the value of attribute opcode_match_masks.



145
146
147
# File 'lib/avr/opcode_decoder.rb', line 145

def opcode_match_masks
  @opcode_match_masks
end

.operand_parsersObject (readonly)

Returns the value of attribute operand_parsers.



148
149
150
# File 'lib/avr/opcode_decoder.rb', line 148

def operand_parsers
  @operand_parsers
end

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



164
165
166
# File 'lib/avr/opcode_decoder.rb', line 164

def cache
  @cache
end

Class Method Details

.add_opcode_definition(opcode_definition) ⇒ Object



152
153
154
155
156
# File 'lib/avr/opcode_decoder.rb', line 152

def self.add_opcode_definition(opcode_definition)
  opcode_definitions << opcode_definition
  opcode_match_masks[opcode_definition.match_mask] ||= {}
  opcode_match_masks.fetch(opcode_definition.match_mask)[opcode_definition.match_value] = opcode_definition
end

.add_operand_parser(operand_parser) ⇒ Object



159
160
161
# File 'lib/avr/opcode_decoder.rb', line 159

def self.add_operand_parser(operand_parser)
  operand_parsers[operand_parser.pattern] = operand_parser
end

Instance Method Details

#decode(word) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/avr/opcode_decoder.rb', line 172

def decode(word)
  cached_decoded_opcode = cache[word]
  return cached_decoded_opcode if cached_decoded_opcode

  OpcodeDecoder.opcode_match_masks.each do |mask, values|
    opcode_definition = values[word & mask]
    next unless opcode_definition

    operands = opcode_definition.extract_operands(word)
    decoded_opcode = DecodedOpcode.new(opcode_definition, operands)
    cache[word] = decoded_opcode
    return decoded_opcode
  end
  nil
end


189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/avr/opcode_decoder.rb', line 189

def print_cache
  puts "Opcode decoder cache (#{cache.size} opcodes cached):"
  cache.sort.each do |word, decoded_opcode|
    puts '  %04x = %17s = %-6s (%s)' % [
      word,
      word.to_s(2).rjust(16, '0').split('').each_slice(8).map(&:join).join(' '),
      decoded_opcode.opcode_definition.mnemonic,
      decoded_opcode.operands.map { |k, v| '%s = %5d' % [k, v] }.join(', '),
    ]
  end
  nil
end