Class: Idl::CsrReadExpressionAst

Inherits:
AstNode
  • Object
show all
Includes:
Rvalue
Defined in:
lib/idl/ast.rb

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, idx) ⇒ CsrReadExpressionAst

Returns a new instance of CsrReadExpressionAst.



5832
5833
5834
5835
5836
5837
5838
5839
5840
# File 'lib/idl/ast.rb', line 5832

def initialize(input, interval, idx)
  if idx.is_a?(AstNode)
    super(input, interval, [idx])
  else
    super(input, interval, EMPTY_ARRAY)
  end

  @idx = idx
end

Instance Method Details

#csr_def(symtab) ⇒ Object



5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
# File 'lib/idl/ast.rb', line 5892

def csr_def(symtab)
  archdef = symtab.archdef
  idx_text = @idx.is_a?(String) ? @idx : @idx.text_value
  csr = archdef.csr(idx_text)
  if !csr.nil?
    # this is a known csr name
    csr
  else
    # this is an expression
    value_result = value_try do
      idx_value = @idx.value(symtab)
      return archdef.csrs.find { |csr| csr.address == idx_value }
    end
    # || we don't know at compile time which CSR this is...
    nil
  end
end

#csr_known?(symtab) ⇒ Boolean

Returns:

  • (Boolean)


5910
5911
5912
# File 'lib/idl/ast.rb', line 5910

def csr_known?(symtab)
  !csr_def(symtab).nil?
end

#csr_name(symtab) ⇒ Object



5914
5915
5916
5917
5918
# File 'lib/idl/ast.rb', line 5914

def csr_name(symtab)
  internal_error "No CSR" unless csr_known?(symtab)

  csr_def(symtab).name
end

#freeze_tree(symtab) ⇒ Object



5842
5843
5844
5845
5846
5847
5848
# File 'lib/idl/ast.rb', line 5842

def freeze_tree(symtab)
  return if frozen?

  @archdef = symtab.archdef # remember archdef, used by gen_adoc pass
  @idx.freeze_tree(symtab)
  freeze
end

#to_idlString

Return valid IDL representation of the node (and its subtree)

Returns:

  • (String)

    IDL code for the node



5935
# File 'lib/idl/ast.rb', line 5935

def to_idl = "CSR[#{@idx.to_idl}]"

#type(symtab) ⇒ Type

Given a specific symbol table, return the type of this node.

Should not be called until #type_check is called with the same arguments

Parameters:

Returns:

  • (Type)

    The type of the node

Raises:



5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
# File 'lib/idl/ast.rb', line 5851

def type(symtab)
  archdef = symtab.archdef

  cd = csr_def(symtab)
  if cd.nil?
    # we don't know anything about this index, so we can only
    # treat this as a generic
    if symtab.mxlen == 32
      Bits32Type
    else
      Bits64Type
    end
  else
    CsrType.new(cd, archdef)
  end
end

#type_check(symtab) ⇒ void

This method returns an undefined value.

type check this node and all children

Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

Parameters:

Raises:



5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
# File 'lib/idl/ast.rb', line 5869

def type_check(symtab)
  archdef = symtab.archdef

  idx_text = @idx.is_a?(String) ? @idx : @idx.text_value
  if !archdef.csr(idx_text).nil?
    # this is a known csr name
    # nothing else to check

  else
    # this is an expression
    @idx.type_check(symtab)
    type_error "Csr index must be integral" unless @idx.type(symtab).integral?

    value_result = value_try do
      idx_value = @idx.value(symtab)
      csr_index = archdef.csrs.index { |csr| csr.address == idx_value }
      type_error "No csr number '#{idx_value}' was found" if csr_index.nil?
      :ok
    end
    # OK, index doesn't have to be known
  end
end

#value(symtab) ⇒ Object

Return the compile-time-known value of the node



5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
# File 'lib/idl/ast.rb', line 5921

def value(symtab)
  cd = csr_def(symtab)
  value_error "CSR number not knowable" if cd.nil?
  if symtab.archdef.fully_configured?
    value_error "CSR is not implemented" unless symtab.archdef.implemented_csrs.any? { |icsr| icsr.name == cd.name }
  else
    value_error "CSR is not defined" unless symtab.archdef.csrs.any? { |icsr| icsr.name == cd.name }
  end
  cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type(symtab) == "RO" }

  csr_def(symtab).fields.reduce(0) { |val, f| val | (f.value << f.location.begin) }
end

#values(symtab) ⇒ Array<Integer>, ... Originally defined in module Rvalue

Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

For most AstNodes, this will just be a single-entry array

Parameters:

  • symtab (SymbolTable)

    The context for the evaulation

Returns:

  • (Array<Integer>)

    The complete list of compile-time-known values, when they are integral

  • (Array<Boolean>)

    The complete list of compile-time-known values, when they are booleans

  • (AstNode::ValueError)

    if the list of values is not knowable at compile time