Class: Idl::CsrFunctionCallAst

Inherits:
AstNode
  • Object
show all
Includes:
Rvalue
Defined in:
lib/idlc/ast.rb,
lib/idlc/passes/gen_adoc.rb

Overview

represents a function call for a CSR register for example:

CSR[mstatus].address()
CSR[mtval].sw_read()

Constant Summary

Constants inherited from AstNode

AstNode::Bits1Type, AstNode::Bits32Type, AstNode::Bits64Type, AstNode::BoolType, AstNode::ConstBoolType, AstNode::PossiblyUnknownBits1Type, AstNode::PossiblyUnknownBits32Type, AstNode::PossiblyUnknownBits64Type, AstNode::ReachableFunctionCacheType, AstNode::StringType, AstNode::VoidType

Instance Attribute Summary collapse

Attributes inherited from AstNode

#children, #input, #interval, #parent

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rvalue

#max_value, #min_value, #truncate, #values

Methods inherited from AstNode

#always_terminates?, #declaration?, #executable?, extract_base_var_name, #find_ancestor, #find_dst_registers, #find_referenced_csrs, #find_src_registers, #freeze_tree, #gen_option_adoc, #input_file, input_from_source_yaml, #inspect, #internal_error, interval_from_source_yaml, #lineno, #lines_around, #nullify_assignments, #pass_find_return_values, #path, #print_ast, #prune, #reachable_exceptions, #reachable_functions, #set_input_file, #set_input_file_unless_already_set, #source_line_file_offsets, #source_starting_offset, #source_yaml, #starting_line, #text_value, #truncation_warn, #type_error, #unindent, value_else, #value_else, value_error, #value_error, value_try, #value_try, write_back_nested

Constructor Details

#initialize(input, interval, function_name, csr, args) ⇒ CsrFunctionCallAst

Returns a new instance of CsrFunctionCallAst.



9667
9668
9669
9670
# File 'lib/idlc/ast.rb', line 9667

def initialize(input, interval, function_name, csr, args)
  super(input, interval, [csr] + args)
  @function_name = function_name
end

Instance Attribute Details

#function_nameString (readonly)

Returns The function being called.

Returns:

  • (String)

    The function being called



9662
9663
9664
# File 'lib/idlc/ast.rb', line 9662

def function_name
  @function_name
end

Class Method Details

.from_h(yaml, source_mapper) ⇒ Object



9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
# File 'lib/idlc/ast.rb', line 9743

def self.from_h(yaml, source_mapper)
  raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "csr_funcall_expr"

  input = input_from_source_yaml(yaml.fetch("source"), source_mapper)
  interval = interval_from_source_yaml(yaml.fetch("source"))
  CsrFunctionCallAst.new(
    input, interval,
    yaml.fetch("function_name"),
    AstNode.from_h(yaml.fetch("csr"), source_mapper),
    yaml.fetch("arguments").map { |a| AstNode.from_h(a, source_mapper) }
  )
end

Instance Method Details

#argsObject



9665
# File 'lib/idlc/ast.rb', line 9665

def args = @children[1..]

#const_eval?(symtab) ⇒ Boolean

Returns:

  • (Boolean)


9653
9654
9655
9656
9657
9658
9659
# File 'lib/idlc/ast.rb', line 9653

def const_eval?(symtab)
  if csr.csr_known?(symtab) && function_name == "address"
    true
  else
    false
  end
end

#csrObject



9664
# File 'lib/idlc/ast.rb', line 9664

def csr = @children[0]

#csr_def(symtab) ⇒ Object



9705
9706
9707
# File 'lib/idlc/ast.rb', line 9705

def csr_def(symtab)
  csr.csr_def(symtab)
end

#csr_known?(symtab) ⇒ Boolean

Returns:

  • (Boolean)


9699
9700
9701
# File 'lib/idlc/ast.rb', line 9699

def csr_known?(symtab)
  csr.csr_known?(symtab)
end

#csr_nameObject



9703
# File 'lib/idlc/ast.rb', line 9703

def csr_name = csr.csr_name

#gen_adoc(indent, indent_spaces: 2) ⇒ Object



81
82
83
84
# File 'lib/idlc/passes/gen_adoc.rb', line 81

def gen_adoc(indent, indent_spaces: 2)
  args_adoc = args.map { |arg| arg.gen_adoc(0) }
  "#{' ' * indent}#{csr.gen_adoc(indent, indent_spaces:)}.#{function_name}(#{args_adoc.join(', ')})"
end

#to_hObject



9734
9735
9736
9737
9738
9739
9740
# File 'lib/idlc/ast.rb', line 9734

def to_h = {
  "kind" => "csr_funcall_expr",
  "csr" => csr.to_h,
  "function_name" => function_name,
  "arguments" => args.map(&:to_h),
  "source" => source_yaml
}

#to_idlObject



9729
9730
9731
# File 'lib/idlc/ast.rb', line 9729

def to_idl
  "#{csr_name}.#{function_name}(#{args.map(&:to_idl).join(', ')})"
end

#type(symtab) ⇒ Object



9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
# File 'lib/idlc/ast.rb', line 9682

def type(symtab)

  case function_name
  when "sw_read"
    if csr_known?(symtab)
      l = symtab.csr(csr.csr_name).length
      Type.new(:bits, width: (l.nil? ? :unknown : l))
    else
      Type.new(:bits, width: symtab.mxlen.nil? ? :unknown : symtab.mxlen)
    end
  when "address"
    Type.new(:bits, width: 12, qualifiers: [:const, :known])
  else
    internal_error "No function '#{function_name}' for CSR. call type check first!"
  end
end

#type_check(symtab, strict:) ⇒ Object



9672
9673
9674
9675
9676
9677
9678
9679
9680
# File 'lib/idlc/ast.rb', line 9672

def type_check(symtab, strict:)
  csr.type_check(symtab, strict:)

  if ["sw_read", "address"].include?(function_name)
    type_error "unexpected argument(s)" unless args.empty?
  else
    type_error "'#{function_name}' is not a supported CSR function call"
  end
end

#value(symtab) ⇒ Object

TODO:

check the sw_read function body



9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
# File 'lib/idlc/ast.rb', line 9710

def value(symtab)
  case function_name
  when "sw_read"
    value_error "CSR not knowable" unless csr_known?(symtab)
    cd = csr_def(symtab)
    cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" }

    value_error "TODO: CSRs with sw_read function"
  when "address"
    value_error "CSR not knowable" unless csr_known?(symtab)
    cd = csr_def(symtab)
    cd.address
  else
    internal_error "TODO: #{function_name}"
  end
end