Class: Idl::CsrFieldReadExpressionAst
- Includes:
- Rvalue
- Defined in:
- lib/idl/ast.rb
Instance Method Summary collapse
- #calc_type(symtab) ⇒ Object
- #calc_value(symtab) ⇒ Object
- #csr_def(symtab) ⇒ Object
- #csr_name(symtab) ⇒ Object
- #field_def(symtab) ⇒ Object
- #field_name(symtab) ⇒ Object
- #freeze_tree(symtab) ⇒ Object
-
#initialize(input, interval, idx, field_name) ⇒ CsrFieldReadExpressionAst
constructor
A new instance of CsrFieldReadExpressionAst.
-
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree).
-
#type(symtab) ⇒ Type
Given a specific symbol table, return the type of this node.
-
#type_check(symtab) ⇒ void
type check this node and all children.
-
#value(symtab) ⇒ Object
Return the compile-time-known value of the node.
-
#values(symtab) ⇒ Array<Integer>, ...
included
from 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.
Constructor Details
#initialize(input, interval, idx, field_name) ⇒ CsrFieldReadExpressionAst
Returns a new instance of CsrFieldReadExpressionAst.
5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 |
# File 'lib/idl/ast.rb', line 5724 def initialize(input, interval, idx, field_name) if idx.is_a?(AstNode) super(input, interval, [idx]) else super(input, interval, EMPTY_ARRAY) end @idx = idx @field_name = field_name end |
Instance Method Details
#calc_type(symtab) ⇒ Object
5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 |
# File 'lib/idl/ast.rb', line 5799 def calc_type(symtab) fd = field_def(symtab) if fd.nil? if @idx.is_a?(IntLiteralAst) internal_error "Could not find CSR[#{@idx.to_idl}].#{@field_name}" else internal_error "Could not find CSR[#{@idx}].#{@field_name}" end end if fd.defined_in_all_bases? Type.new(:bits, width: symtab.cfg_arch.possible_xlens.map{ |xlen| fd.width(symtab.cfg_arch, xlen) }.max) elsif fd.base64_only? if symtab.cfg_arch.possible_xlens.include?(64) Type.new(:bits, width: fd.width(symtab.cfg_arch, 64)) end elsif fd.base32_only? if symtab.cfg_arch.possible_xlens.include?(32) Type.new(:bits, width: fd.width(symtab.cfg_arch, 32)) end else internal_error "unexpected field base" end end |
#calc_value(symtab) ⇒ Object
5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 |
# File 'lib/idl/ast.rb', line 5832 def calc_value(symtab) # field isn't implemented, so it must be zero return 0 if field_def(symtab).nil? unless field_def(symtab).type(symtab) == "RO" value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" end field_def(symtab).reset_value(symtab.cfg_arch) end |
#csr_def(symtab) ⇒ Object
5763 5764 5765 5766 5767 5768 5769 5770 5771 |
# File 'lib/idl/ast.rb', line 5763 def csr_def(symtab) cfg_arch = symtab.cfg_arch if @idx.is_a?(IntLiteralAst) cfg_arch.csrs.find { |c| c.address == @idx.value(symtab) } else cfg_arch.csr(@idx) end end |
#csr_name(symtab) ⇒ Object
5773 5774 5775 |
# File 'lib/idl/ast.rb', line 5773 def csr_name(symtab) csr_def(symtab).name end |
#field_def(symtab) ⇒ Object
5777 5778 5779 |
# File 'lib/idl/ast.rb', line 5777 def field_def(symtab) csr_def(symtab).fields.find { |f| f.name == @field_name } end |
#field_name(symtab) ⇒ Object
5781 5782 5783 |
# File 'lib/idl/ast.rb', line 5781 def field_name(symtab) field_def(symtab).name end |
#freeze_tree(symtab) ⇒ Object
5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 |
# File 'lib/idl/ast.rb', line 5735 def freeze_tree(symtab) return if frozen? value_result = value_try do @value = calc_value(symtab) end value_else(value_result) do @value = nil end @type = calc_type(symtab) @cfg_arch = symtab.cfg_arch # remember cfg_arch, used in gen_adoc pass freeze end |
#to_idl ⇒ String
Return valid IDL representation of the node (and its subtree)
5786 5787 5788 5789 5790 5791 5792 |
# File 'lib/idl/ast.rb', line 5786 def to_idl if @idx.is_a?(IntLiteralAst) "CSR[#{@idx.to_idl}].#{@field_name}" else "CSR[#{@idx}].#{@field_name}" end end |
#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
5795 5796 5797 |
# File 'lib/idl/ast.rb', line 5795 def type(symtab) @type end |
#type_check(symtab) ⇒ void
5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 |
# File 'lib/idl/ast.rb', line 5750 def type_check(symtab) if @idx.is_a?(IntLiteralAst) type_error "No CSR at address #{@idx.text_value}" if csr_def(symtab).nil? else # idx is a csr name csr_name = @idx type_error "No CSR named #{csr_name}" if csr_def(symtab).nil? end type_error "CSR[#{csr_name(symtab)}] has no field named #{@field_name}" if field_def(symtab).nil? type_error "CSR[#{csr_name(symtab)}].#{@field_name} is not defined in RV32" if symtab.cfg_arch.mxlen == 32 && !field_def(symtab).defined_in_base32? type_error "CSR[#{csr_name(symtab)}].#{@field_name} is not defined in RV64" if symtab.cfg_arch.mxlen == 64 && !field_def(symtab).defined_in_base64? end |
#value(symtab) ⇒ Object
Return the compile-time-known value of the node
5824 5825 5826 5827 5828 5829 5830 |
# File 'lib/idl/ast.rb', line 5824 def value(symtab) if @value.nil? value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" else @value end 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