@@ -12,6 +12,7 @@ class CsrField < DatabaseObject
1212 extend T ::Sig ;
1313
1414 # @return [Csr] The Csr that defines this field
15+ sig { returns ( Csr ) }
1516 attr_reader :parent
1617
1718 # @!attribute field
@@ -22,12 +23,14 @@ class CsrField < DatabaseObject
2223
2324 # @return [Integer] The base XLEN required for this CsrField to exist. One of [32, 64]
2425 # @return [nil] if the CsrField exists in any XLEN
26+ sig { returns ( T . nilable ( Integer ) ) }
2527 def base
2628 @data [ "base" ]
2729 end
2830
2931 # @param parent_csr [Csr] The Csr that defined this field
3032 # @param field_data [Hash<String,Object>] Field data from the arch spec
33+ sig { params ( parent_csr : Csr , field_name : String , field_data : T ::Hash [ String , T . untyped ] ) . void }
3134 def initialize ( parent_csr , field_name , field_data )
3235 super ( field_data , parent_csr . data_path , arch : parent_csr . arch )
3336 @name = field_name
@@ -38,6 +41,7 @@ def initialize(parent_csr, field_name, field_data)
3841 # For a partial config, whether or the it is possible for the field to be implemented
3942 #
4043 # @return [Boolean] True if this field might exist in a config
44+ sig { params ( cfg_arch : ConfiguredArchitecture ) . returns ( T ::Boolean ) }
4145 def exists_in_cfg? ( cfg_arch )
4246 if cfg_arch . fully_configured?
4347 parent . exists_in_cfg? ( cfg_arch ) &&
@@ -53,6 +57,7 @@ def exists_in_cfg?(cfg_arch)
5357 end
5458
5559 # @return [Boolean] For a partially configured cfg_arch, whether or not the field is optional (not mandatory or prohibited)
60+ sig { params ( cfg_arch : ConfiguredArchitecture ) . returns ( T ::Boolean ) }
5661 def optional_in_cfg? ( cfg_arch )
5762 raise "optional_in_cfg? should only be called on a partially configured cfg_arch" unless cfg_arch . partially_configured?
5863
@@ -71,18 +76,22 @@ def optional_in_cfg?(cfg_arch)
7176 # @return [Boolean] Whether or not the presence of ext_ver affects this CSR Field definition
7277 # This does not take the parent CSR into account, i.e., a field can be unaffected
7378 # by ext_ver even if the parent CSR is affected
79+ sig { params ( ext_ver : ExtensionVersion ) . returns ( T ::Boolean ) }
7480 def affected_by? ( ext_ver )
7581 @data [ "definedBy" ] . nil? ? false : defined_by_condition . possibly_satisfied_by? ( ext_ver )
7682 end
7783
7884 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the type() function
7985 # @return [nil] if the type property is not a function
86+ sig { returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
8087 def type_ast
8188 return @type_ast unless @type_ast . nil?
8289 return nil if @data [ "type()" ] . nil?
8390
91+ idl_code = T . must ( @data [ "type()" ] )
92+
8493 @type_ast = @cfg_arch . idl_compiler . compile_func_body (
85- @data [ "type()" ] ,
94+ idl_code ,
8695 name : "CSR[#{ csr . name } ].#{ name } .type()" ,
8796 input_file : csr . __source ,
8897 input_line : csr . source_line ( "fields" , name , "type()" ) ,
@@ -100,6 +109,7 @@ def type_ast
100109 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the type() function, after it has been type checked
101110 # @return [nil] if the type property is not a function
102111 # @param effective_xlen [32, 64] The effective xlen to evaluate for
112+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
103113 def type_checked_type_ast ( effective_xlen )
104114 @type_checked_type_ast ||= { 32 => nil , 64 => nil }
105115 return @type_checked_type_ast [ effective_xlen ] unless @type_checked_type_ast [ effective_xlen ] . nil?
@@ -128,6 +138,7 @@ def type_checked_type_ast(effective_xlen)
128138 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the type() function, after it has been type checked and pruned
129139 # @return [nil] if the type property is not a function
130140 # @param effective_xlen [32, 64] The effective xlen to evaluate for
141+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
131142 def pruned_type_ast ( effective_xlen )
132143 @pruned_type_ast ||= { 32 => nil , 64 => nil }
133144 return @pruned_type_ast [ effective_xlen ] unless @pruned_type_ast [ effective_xlen ] . nil?
@@ -169,6 +180,7 @@ def pruned_type_ast(effective_xlen)
169180 # 'RW-R' => Read-write, with a restricted set of legal values
170181 # 'RW-H' => Read-write, with a hardware update
171182 # 'RW-RH' => Read-write, with a hardware update and a restricted set of legal values
183+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( String ) }
172184 def type ( effective_xlen = nil )
173185 @type ||= { 32 => nil , 64 => nil }
174186 return @type [ effective_xlen ] unless @type [ effective_xlen ] . nil?
@@ -179,11 +191,8 @@ def type(effective_xlen = nil)
179191 @data [ "type" ]
180192 else
181193 # the type is config-specific...
182- idl = @data [ "type()" ]
183- raise "type() is nil for #{ csr . name } .#{ name } #{ @data } ?" if idl . nil?
184194
185- # value_result = Idl::AstNode.value_try do
186- ast = type_checked_type_ast ( effective_xlen )
195+ ast = T . must ( type_checked_type_ast ( effective_xlen ) )
187196 begin
188197 symtab = fill_symtab_for_type ( effective_xlen , ast )
189198
@@ -209,8 +218,8 @@ def type(effective_xlen = nil)
209218 type = nil
210219 end
211220 ensure
212- symtab . pop
213- symtab . release
221+ symtab . pop unless symtab . nil?
222+ symtab . release unless symtab . nil?
214223 end
215224 type
216225 # end
@@ -226,21 +235,21 @@ def type(effective_xlen = nil)
226235
227236 # @return [String] A pretty-printed type string
228237 # @param effective_xlen [32, 64] The effective xlen to evaluate for
238+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( String ) }
229239 def type_pretty ( effective_xlen = nil )
230- raise ArgumentError , "Expecting Integer" unless effective_xlen . nil? || effective_xlen . is_a? ( Integer )
231-
232240 str = T . let ( nil , T . nilable ( String ) )
233241 value_result = Idl ::AstNode . value_try do
234242 str = type ( effective_xlen )
235243 end
236244 Idl ::AstNode . value_else ( value_result ) do
237- ast = type_ast
245+ ast = T . must ( type_ast )
238246 str = ast . gen_option_adoc
239247 end
240- str
248+ T . must ( str )
241249 end
242250
243251 # @return [Alias,nil] The aliased field, or nil if there is no alias
252+ sig { returns ( T . nilable ( Alias ) ) }
244253 def alias
245254 return @alias unless @alias . nil?
246255
@@ -270,6 +279,7 @@ def alias
270279 # @return [Array<Idl::FunctionDefAst>] List of functions called through this field
271280 # @param cfg_arch [ConfiguredArchitecture] a configuration
272281 # @Param effective_xlen [Integer] 32 or 64; needed because fields can change in different XLENs
282+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( T ::Array [ Idl ::FunctionDefAst ] ) }
273283 def reachable_functions ( effective_xlen )
274284 return @reachable_functions unless @reachable_functions . nil?
275285
@@ -307,6 +317,7 @@ def reachable_functions(effective_xlen)
307317
308318 # @return [Boolean] Whether or not the location of the field changes dynamically
309319 # (e.g., based on mstatus.SXL) in the configuration
320+ sig { returns ( T ::Boolean ) }
310321 def dynamic_location?
311322 # if there is no location_rv32, the the field never changes
312323 return false unless @data [ "location" ] . nil?
@@ -317,6 +328,7 @@ def dynamic_location?
317328
318329 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the reset_value function
319330 # @return [nil] If the reset_value is not a function
331+ sig { returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
320332 def reset_value_ast
321333 return @reset_value_ast unless @reset_value_ast . nil?
322334 return nil unless @data . key? ( "reset_value()" )
@@ -332,9 +344,9 @@ def reset_value_ast
332344 )
333345 end
334346
335- # @param symtab [Idl::SymbolTable] A symbol table with globals
336347 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the reset_value function, after being type checked
337348 # @return [nil] If the reset_value is not a function
349+ sig { returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
338350 def type_checked_reset_value_ast
339351 return @type_checked_reset_value_ast unless @type_checked_reset_value_ast . nil?
340352
@@ -355,12 +367,13 @@ def type_checked_reset_value_ast
355367
356368 # @return [Idl::FunctionBodyAst] Abstract syntax tree of the reset_value function, type checked and pruned
357369 # @return [nil] If the reset_value is not a function
370+ sig { returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
358371 def pruned_reset_value_ast
359372 return @pruned_reset_value_ast unless @pruned_reset_value_ast . nil?
360373
361374 return nil unless @data . key? ( "reset_value()" )
362375
363- ast = type_checked_reset_value_ast
376+ ast = T . must ( type_checked_reset_value_ast )
364377
365378 symtab = fill_symtab_for_reset ( ast )
366379 ast = ast . prune ( symtab )
@@ -378,7 +391,7 @@ def reset_value
378391 if @data . key? ( "reset_value" )
379392 @data [ "reset_value" ]
380393 else
381- ast = pruned_reset_value_ast
394+ ast = T . must ( pruned_reset_value_ast )
382395 symtab = fill_symtab_for_reset ( ast )
383396 val = T . let ( nil , T . untyped )
384397 value_result = Idl ::AstNode . value_try do
@@ -394,6 +407,7 @@ def reset_value
394407 end
395408 end
396409
410+ sig { returns ( T ::Boolean ) }
397411 def dynamic_reset_value?
398412 return false unless @data [ "reset_value" ] . nil?
399413
@@ -403,32 +417,29 @@ def dynamic_reset_value?
403417 end || true
404418 end
405419
420+ sig { returns ( String ) }
406421 def reset_value_pretty
407422 str = T . let ( nil , T . nilable ( String ) )
408423 value_result = Idl ::AstNode . value_try do
409424 str = reset_value
410425 end
411426 Idl ::AstNode . value_else ( value_result ) do
412- ast = reset_value_ast
427+ ast = T . must ( reset_value_ast )
413428 str = ast . gen_option_adoc
414429 end
415- str
416- end
417-
418- # @return [Boolean] true if the field could have an undefined value at any point
419- def could_be_undefined?
420- ( reset_value == "UNDEFINED_LEGAL" ) || \
421- ( has_custom_sw_write? && sw_write_ast ( cfg_arch . symtab ) . could_return_undefined? ( cfg_arch . symtab ) )
430+ T . must ( str )
422431 end
423432
424433 # @return [Boolean] true if the CSR field has a custom sw_write function
434+ sig { returns ( T ::Boolean ) }
425435 def has_custom_sw_write?
426436 @data . key? ( "sw_write(csr_value)" ) && !@data [ "sw_write(csr_value)" ] . empty?
427437 end
428438
429439 # @return [FunctionBodyAst] The abstract syntax tree of the sw_write() function, after being type checked
430440 # @param effective_xlen [Integer] 32 or 64; the effective XLEN to evaluate this field in (relevant when fields move in different XLENs)
431441 # @param symtab [Idl::SymbolTable] Symbol table with globals
442+ sig { params ( symtab : Idl ::SymbolTable , effective_xlen : T . nilable ( Integer ) ) . returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
432443 def type_checked_sw_write_ast ( symtab , effective_xlen )
433444 @type_checked_sw_write_asts ||= { }
434445 ast = @type_checked_sw_write_asts [ symtab . hash ]
@@ -453,7 +464,7 @@ def type_checked_sw_write_ast(symtab, effective_xlen)
453464 Idl ::Var . new ( "csr_value" , csr . bitfield_type ( symtab . cfg_arch , effective_xlen ) )
454465 )
455466
456- ast = sw_write_ast ( symtab )
467+ ast = T . must ( sw_write_ast ( symtab ) )
457468 symtab . cfg_arch . idl_compiler . type_check (
458469 ast ,
459470 symtab ,
@@ -466,10 +477,9 @@ def type_checked_sw_write_ast(symtab, effective_xlen)
466477
467478 # @return [Idl::FunctionBodyAst] The abstract syntax tree of the sw_write() function
468479 # @return [nil] If there is no sw_write() function
469- # @param cfg_arch [ConfiguredArchitecture] An architecture definition
480+ # @param symtab [Idl::SymbolTable] Symbols
481+ sig { params ( symtab : Idl ::SymbolTable ) . returns ( T . nilable ( Idl ::FunctionBodyAst ) ) }
470482 def sw_write_ast ( symtab )
471- raise ArgumentError , "Argument should be a symtab" unless symtab . is_a? ( Idl ::SymbolTable )
472-
473483 return @sw_write_ast unless @sw_write_ast . nil?
474484 return nil if @data [ "sw_write(csr_value)" ] . nil?
475485
@@ -489,6 +499,7 @@ def sw_write_ast(symtab)
489499 @sw_write_ast
490500 end
491501
502+ sig { params ( effective_xlen : T . nilable ( Integer ) , ast : Idl ::AstNode ) . returns ( Idl ::SymbolTable ) }
492503 def fill_symtab_for_sw_write ( effective_xlen , ast )
493504 symtab = cfg_arch . symtab . global_clone
494505 symtab . push ( ast )
@@ -520,6 +531,7 @@ def fill_symtab_for_sw_write(effective_xlen, ast)
520531 symtab
521532 end
522533
534+ sig { params ( effective_xlen : T . nilable ( Integer ) , ast : Idl ::AstNode ) . returns ( Idl ::SymbolTable ) }
523535 def fill_symtab_for_type ( effective_xlen , ast )
524536 symtab = cfg_arch . symtab . global_clone
525537 symtab . push ( ast )
@@ -571,7 +583,7 @@ def pruned_sw_write_ast(effective_xlen)
571583
572584 return nil unless @data . key? ( "sw_write(csr_value)" )
573585
574- ast = type_checked_sw_write_ast ( cfg_arch . symtab , effective_xlen )
586+ ast = T . must ( type_checked_sw_write_ast ( cfg_arch . symtab , effective_xlen ) )
575587
576588 return ast if cfg_arch . unconfigured?
577589
@@ -644,24 +656,34 @@ def location(effective_xlen = nil)
644656 end
645657
646658 # @return [Boolean] Whether or not this field only exists when XLEN == 64
659+ sig { returns ( T ::Boolean ) }
647660 def base64_only? = @data . key? ( "base" ) && @data [ "base" ] == 64
648661
649662 # @return [Boolean] Whether or not this field only exists when XLEN == 32
663+ sig { returns ( T ::Boolean ) }
650664 def base32_only? = @data . key? ( "base" ) && @data [ "base" ] == 32
651665
666+ sig { returns ( T ::Boolean ) }
652667 def defined_in_base32? = @data [ "base" ] . nil? || @data [ "base" ] == 32
668+
669+ sig { returns ( T ::Boolean ) }
653670 def defined_in_base64? = @data [ "base" ] . nil? || @data [ "base" ] == 64
671+
672+ sig { params ( xlen : Integer ) . returns ( T ::Boolean ) }
654673 def defined_in_base? ( xlen ) = @data [ "base" ] . nil? || @data [ "base" ] == xlen
655674
656675 # @return [Boolean] Whether or not this field exists for any XLEN
676+ sig { returns ( T ::Boolean ) }
657677 def defined_in_all_bases? = @data [ "base" ] . nil?
658678
659679 # @param effective_xlen [Integer] The effective xlen, needed since some fields change location with XLEN. If the field location is not determined by XLEN, then this parameter can be nil
660680 # @return [Integer] Number of bits in the field
681+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( Integer ) }
661682 def width ( effective_xlen )
662- location ( effective_xlen ) . size
683+ T . must ( location ( effective_xlen ) . size )
663684 end
664685
686+ sig { returns ( Integer ) }
665687 def max_width
666688 @max_width ||=
667689 if base64_only?
@@ -675,6 +697,7 @@ def max_width
675697 end
676698 end
677699
700+ sig { returns ( String ) }
678701 def location_cond32
679702 case csr . priv_mode
680703 when "M"
@@ -688,6 +711,7 @@ def location_cond32
688711 end
689712 end
690713
714+ sig { returns ( String ) }
691715 def location_cond64
692716 case csr . priv_mode
693717 when "M"
@@ -702,6 +726,7 @@ def location_cond64
702726 end
703727
704728 # @return [String] Pretty-printed location string
729+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( String ) }
705730 def location_pretty ( effective_xlen = nil )
706731 derangeify = proc { |loc |
707732 next loc . min . to_s if loc . size == 1
@@ -785,6 +810,7 @@ def location_pretty(effective_xlen = nil)
785810 } . freeze
786811
787812 # @return [String] Long description of the field type
813+ sig { params ( effective_xlen : T . nilable ( Integer ) ) . returns ( String ) }
788814 def type_desc ( effective_xlen = nil )
789815 TYPE_DESC_MAP [ type ( effective_xlen ) ]
790816 end
0 commit comments