Class: Idl::CsrFunctionCallAst
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_name ⇒ String
Returns 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
#args ⇒ Object
9665
|
# File 'lib/idlc/ast.rb', line 9665
def args = @children[1..]
|
#const_eval?(symtab) ⇒ 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
|
#csr ⇒ Object
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
9699
9700
9701
|
# File 'lib/idlc/ast.rb', line 9699
def csr_known?(symtab)
csr.csr_known?(symtab)
end
|
#csr_name ⇒ Object
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_h ⇒ Object
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_idl ⇒ Object
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
|