Class: Udb::ExtensionVersion
- Inherits:
-
Object
- Object
- Udb::ExtensionVersion
- Extended by:
- T::Sig
- Defined in:
- lib/udb/obj/extension.rb,
lib/udb/req_expression.rb
Overview
sorbet needs a forward declration
Instance Attribute Summary collapse
- #arch ⇒ ConfiguredArchitecture readonly
-
#ext ⇒ Extension
readonly
Extension.
-
#name ⇒ String
readonly
Name of the extension.
- #version_spec ⇒ VersionSpec readonly
- #version_str ⇒ String readonly
Class Method Summary collapse
-
.to_ext_req(ext_vers) ⇒ ExtensionRequirement
given a set of extension versions from the same extension, return the minimal set of extension requirements that would cover then all.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
sorts extension by name, then by version.
-
#==(other) ⇒ Boolean
Whether or not this ExtensionVersion has the exact same name and version as other.
-
#breaking? ⇒ Boolean
Whether or not this is a breaking version (i.e., incompatible with all prior versions).
-
#canonical_version ⇒ String
Canonical version string.
- #changes ⇒ Object
-
#compatible?(other) ⇒ Boolean
Whether or not
other
is compatible with self. -
#compatible_versions ⇒ Array<ExtensionVersions>
List of known ExtensionVersions that are compatible with this ExtensionVersion (i.e., have larger version number and are not breaking).
-
#conflicts_condition ⇒ AbstractRequirement
List of extensions that conflict with this ExtensionVersion The list is not transitive; if conflict C1 implies C2, only C1 shows up in the list.
-
#contributors ⇒ Array<Person>
List of contributors to this extension version.
-
#eql?(other) ⇒ Boolean
Whether or not this ExtensionVersion has the exact same name and version as other.
- #exception_codes ⇒ Array<ExceptionCode>
-
#implemented_csrs ⇒ Array<Csr>
The list of CSRs implemented by this extension version (may be empty).
-
#implemented_instructions ⇒ Array<Csr>
The list of insts implemented by this extension version (may be empty).
-
#implications ⇒ ConditionalExtensionVersionList
Returns array of ExtensionVersions implied by this ExtensionVersion, along with a condition under which it is in the list (which may be an AlwaysTrueExtensionRequirementExpression).
-
#implied_by ⇒ Array<ExtensionVersion>
Note that the list returned could include extension versions that conditionally imply this extension version For example, Zcd.implied_by will return C, even though C only implies Zcd if D is also implemented.
-
#implied_by_with_condition ⇒ Array<Hash{Symbol => ExtensionVersion, ExtensionRequirementExpression>] List of extension versions that might imply this ExtensionVersion, along with the condition under which it applies
Array<Hash{Symbol => ExtensionVersion, ExtensionRequirementExpression>] List of extension versions that might imply this ExtensionVersion, along with the condition under which it applies.
-
#in_scope_csrs(design) ⇒ Array<Csr>
List of CSRs in-scope for this design for this extension version (may be empty).
-
#in_scope_instructions(design) ⇒ Array<Instruction>
List of instructions in-scope for this design for this extension version (may be empty).
- #initialize(name, version_str, arch, fail_if_version_does_not_exist: false) constructor
- #interrupt_codes ⇒ Array<InterruptCode>
-
#params ⇒ Array<Parameter>
The list of parameters for this extension version.
- #ratification_date ⇒ Object
-
#requirement_condition ⇒ ExtensionRequirementExpression
Condition that must be met for this version to be allowed.
-
#state ⇒ String
The state of the extension version (‘ratified’, ‘developemnt’, etc).
- #to_ext_req ⇒ ExtensionRequirement
-
#to_rvi_s ⇒ String
Formatted like the RVI manual.
-
#to_s ⇒ String
Ext@Version.
- #url ⇒ Object
Constructor Details
#initialize(name, version_str, arch, fail_if_version_does_not_exist: false)
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/udb/obj/extension.rb', line 246 def initialize(name, version_str, arch, fail_if_version_does_not_exist: false) @name = name @version_str = version_str @version_spec = VersionSpec.new(version_str) @arch = arch @ext = @arch.extension(@name) raise "Extension #{name} not found in architecture" if @ext.nil? @data = @ext.data["versions"].find { |v| VersionSpec.new(v["version"]) == @version_spec } if fail_if_version_does_not_exist && @data.nil? raise ArgumentError, "Version #{version_str} of #{@name} extension is not defined" elsif @data.nil? warn "Version #{version_str} of #{@name} extension is not defined" end end |
Instance Attribute Details
#arch ⇒ ConfiguredArchitecture (readonly)
240 241 242 |
# File 'lib/udb/obj/extension.rb', line 240 def arch @arch end |
#ext ⇒ Extension (readonly)
Returns Extension.
229 230 231 |
# File 'lib/udb/obj/extension.rb', line 229 def ext @ext end |
#name ⇒ String (readonly)
Returns Name of the extension.
225 226 227 |
# File 'lib/udb/obj/extension.rb', line 225 def name @name end |
#version_spec ⇒ VersionSpec (readonly)
233 234 235 |
# File 'lib/udb/obj/extension.rb', line 233 def version_spec @version_spec end |
#version_str ⇒ String (readonly)
237 238 239 |
# File 'lib/udb/obj/extension.rb', line 237 def version_str @version_str end |
Class Method Details
.to_ext_req(ext_vers) ⇒ ExtensionRequirement
given a set of extension versions from the same extension, return the minimal set of extension requirements that would cover then all
268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/udb/obj/extension.rb', line 268 def self.to_ext_req(ext_vers) raise "ext_vers cannot be empty" if ext_vers.empty? raise "All ext_vers must be of the same extension" unless ext_vers.all? { |ev| ev.name == ext_vers.fetch(0).name } sorted = ext_vers.sort unless T.must(sorted.min).compatible?(sorted.max) raise "Impossible to combine because the set contains incompatible versions" end ExtensionRequirement.new(ext_vers.fetch(0).name, "~> #{T.must(sorted.min).version_str}", arch: ext_vers.fetch(0).arch) end |
Instance Method Details
#<=>(other) ⇒ Object
sorts extension by name, then by version
455 456 457 458 459 460 461 462 463 464 465 |
# File 'lib/udb/obj/extension.rb', line 455 def <=>(other) unless other.is_a?(ExtensionVersion) raise ArgumentError, "ExtensionVersions are only comparable to other extension versions" end if other.name != @name @name <=> other.name else @version_spec <=> other.version_spec end end |
#==(other) ⇒ Boolean
Returns whether or not this ExtensionVersion has the exact same name and version as other.
316 317 318 |
# File 'lib/udb/obj/extension.rb', line 316 def ==(other) eql?(other) end |
#breaking? ⇒ Boolean
Returns Whether or not this is a breaking version (i.e., incompatible with all prior versions).
299 300 301 |
# File 'lib/udb/obj/extension.rb', line 299 def breaking? !@data["breaking"].nil? end |
#canonical_version ⇒ String
Returns Canonical version string.
304 |
# File 'lib/udb/obj/extension.rb', line 304 def canonical_version = @version_spec.canonical |
#changes ⇒ Object
325 |
# File 'lib/udb/obj/extension.rb', line 325 def changes = @data["changes"].nil? ? [] : @data["changes"] |
#compatible?(other) ⇒ Boolean
Returns Whether or not other
is compatible with self.
296 |
# File 'lib/udb/obj/extension.rb', line 296 def compatible?(other) = compatible_versions.include?(other) |
#compatible_versions ⇒ Array<ExtensionVersions>
Returns List of known ExtensionVersions that are compatible with this ExtensionVersion (i.e., have larger version number and are not breaking).
281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/udb/obj/extension.rb', line 281 def compatible_versions return @compatible_versions unless @compatible_versions.nil? @compatible_versions = [] @ext.versions.each do |v| @compatible_versions << v if v.version_spec >= @version_spec break if @compatible_versions.size.positive? && v.breaking? end raise "Didn't even find self?" if compatible_versions.empty? @compatible_versions end |
#conflicts_condition ⇒ AbstractRequirement
Returns List of extensions that conflict with this ExtensionVersion The list is not transitive; if conflict C1 implies C2, only C1 shows up in the list.
387 388 389 |
# File 'lib/udb/obj/extension.rb', line 387 def conflicts_condition ext.conflicts_condition end |
#contributors ⇒ Array<Person>
Returns List of contributors to this extension version.
330 331 332 333 334 335 336 337 338 |
# File 'lib/udb/obj/extension.rb', line 330 def contributors return @contributors unless @contributors.nil? @contributors = [] @data["contributors"]&.each do |c| @contributors << Person.new(c) end @contributors end |
#eql?(other) ⇒ Boolean
Returns whether or not this ExtensionVersion has the exact same name and version as other.
308 309 310 311 312 |
# File 'lib/udb/obj/extension.rb', line 308 def eql?(other) raise "ExtensionVersion is not comparable to #{other.class}" unless other.is_a?(ExtensionVersion) @ext.name == other.ext.name && @version_spec.eql?(other.version_spec) end |
#exception_codes ⇒ Array<ExceptionCode>
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
# File 'lib/udb/obj/extension.rb', line 498 def exception_codes @exception_codes ||= if @data.key?("exception_codes") ecodes = [] d = T.cast(@data["exception_codes"], T::Array[T::Hash[String, T.any(Integer, String)]]) d.each do |edata| if ecodes.any? { |e| e.num == edata["num"] || e.name == edata["name"] || e.var == edata["var"] } raise "Duplicate exception code" end cond = T.let(T.cast(edata["when"], T::Hash[String, String]), T.nilable(T::Hash[String, String])) unless cond.nil? || cond["version"].nil? # check version next unless ExtensionRequirement.new(name, T.must(cond["version"]), arch: @cfg_arch).satisfied_by?(self) end ecodes << ExceptionCode.new( T.cast(edata["name"], String), T.cast(edata["var"], String), T.cast(edata["num"], Integer), ext ) end ecodes else [] end end |
#implemented_csrs ⇒ Array<Csr>
Returns the list of CSRs implemented by this extension version (may be empty).
476 477 478 479 480 481 482 483 484 |
# File 'lib/udb/obj/extension.rb', line 476 def implemented_csrs return @implemented_csrs unless @implemented_csrs.nil? raise "implemented_csrs needs an cfg_arch" if @cfg_arch.nil? @implemented_csrs = @cfg_arch.csrs.select do |csr| csr.defined_by_condition.possibly_satisfied_by?(self) end end |
#implemented_instructions ⇒ Array<Csr>
Returns the list of insts implemented by this extension version (may be empty).
487 488 489 490 491 492 493 494 495 |
# File 'lib/udb/obj/extension.rb', line 487 def implemented_instructions return @implemented_instructions unless @implemented_instructions.nil? raise "implemented_instructions needs an cfg_arch" if @cfg_arch.nil? @implemented_instructions = @cfg_arch.instructions.select do |inst| inst.defined_by_condition.possibly_satisfied_by?(self) end end |
#implications ⇒ ConditionalExtensionVersionList
Returns array of ExtensionVersions implied by this ExtensionVersion, along with a condition under which it is in the list (which may be an AlwaysTrueExtensionRequirementExpression)
402 403 404 405 406 |
# File 'lib/udb/obj/extension.rb', line 402 def implications return ConditionalExtensionVersionList.new([], @arch) if @data["implies"].nil? ConditionalExtensionVersionList.new(@data["implies"], @arch) end |
#implied_by ⇒ Array<ExtensionVersion>
Note that the list returned could include extension versions that conditionally imply this extension version For example, Zcd.implied_by will return C, even though C only implies Zcd if D is also implemented
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/udb/obj/extension.rb', line 413 def implied_by return @implied_by unless @implied_by.nil? @implied_by = [] @arch.extensions.each do |ext| next if ext.name == name ext.versions.each do |ext_ver| ext_ver.implications.each do |implication| @implied_by << ext_ver if implication.ext_ver == self && implication.cond.could_be_true?(@arch) end end end @implied_by end |
#implied_by_with_condition ⇒ Array<Hash{Symbol => ExtensionVersion, ExtensionRequirementExpression>] List of extension versions that might imply this ExtensionVersion, along with the condition under which it applies
Returns Array<Hash{Symbol => ExtensionVersion, ExtensionRequirementExpression>] List of extension versions that might imply this ExtensionVersion, along with the condition under which it applies.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/udb/obj/extension.rb', line 437 def implied_by_with_condition return @implied_by_with_condition unless @implied_by_with_condition.nil? @implied_by_with_condition = [] @arch.extensions.each do |ext| next if ext.name == name ext.versions.each do |ext_ver| raise "????" if ext_ver.arch.nil? ext_ver.implications.each do |implication| @implied_by_with_condition << { ext_ver: ext_ver, cond: implication.cond } if implication.ext_ver == self end end end @implied_by_with_condition end |
#in_scope_csrs(design) ⇒ Array<Csr>
Returns List of CSRs in-scope for this design for this extension version (may be empty). Factors in effect of design’s xlen in the appropriate mode for the CSR.
564 565 566 567 568 569 570 571 572 573 |
# File 'lib/udb/obj/extension.rb', line 564 def in_scope_csrs(design) raise ArgumentError, "Require an PortfolioDesign object but got a #{design.class} object" unless design.is_a?(PortfolioDesign) return @in_scope_csrs unless @in_scope_csrs.nil? @in_scope_csrs = @arch.csrs.select do |csr| csr.defined_by_condition.possibly_satisfied_by?(self) && (csr.base.nil? || (design.possible_xlens.include?(csr.base))) end end |
#in_scope_instructions(design) ⇒ Array<Instruction>
Returns List of instructions in-scope for this design for this extension version (may be empty). Factors in effect of design’s xlen in the appropriate mode for the instruction.
578 579 580 581 582 583 584 585 586 587 |
# File 'lib/udb/obj/extension.rb', line 578 def in_scope_instructions(design) raise ArgumentError, "Require an PortfolioDesign object but got a #{design.class} object" unless design.is_a?(PortfolioDesign) return @in_scope_instructions unless @in_scope_instructions.nil? @in_scope_instructions = @arch.instructions.select do |inst| inst.defined_by_condition.possibly_satisfied_by?(self) && (inst.base.nil? || (design.possible_xlens.include?(inst.base))) end end |
#interrupt_codes ⇒ Array<InterruptCode>
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/udb/obj/extension.rb', line 530 def interrupt_codes @interrupt_codes ||= if @data.key?("interrupt_codes") ecodes = [] d = T.cast(@data["interrupt_codes"], T::Array[T::Hash[String, T.any(Integer, String)]]) d.each do |edata| if ecodes.any? { |e| e.num == edata["num"] || e.name == edata["name"] || e.var == edata["var"] } raise "Duplicate interrupt code" end cond = T.let(T.cast(edata["when"], T::Hash[String, String]), T.nilable(T::Hash[String, String])) unless cond.nil? || cond["version"].nil? # check version next unless ExtensionRequirement.new(name, T.must(cond["version"]), arch: @cfg_arch).satisfied_by?(self) end ecodes << InterruptCode.new( T.cast(edata["name"], String), T.cast(edata["var"], String), T.cast(edata["num"], Integer), ext ) end ecodes else [] end end |
#params ⇒ Array<Parameter>
Returns The list of parameters for this extension version.
342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/udb/obj/extension.rb', line 342 def params @ext.params.select do |p| p.when.satisfied_by? do |ext_req| if ext_req.name == name ext_req.satisfied_by?(self) else @arch.possible_extension_versions.any? { |poss_ext_ver| ext_req.satisfied_by?(poss_ext_ver) } end end end end |
#ratification_date ⇒ Object
323 |
# File 'lib/udb/obj/extension.rb', line 323 def ratification_date = @data["ratification_date"] |
#requirement_condition ⇒ ExtensionRequirementExpression
Returns Condition that must be met for this version to be allowed.
368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/udb/obj/extension.rb', line 368 def requirement_condition @requirement_condition ||= begin r = case @data["requires"] when nil AlwaysTrueExtensionRequirementExpression.new when Hash ExtensionRequirementExpression.new(@data["requires"], @arch) else ExtensionRequirementExpression.new({ "oneOf" => [@data["requires"]] }, @arch) end r end end |
#state ⇒ String
Returns The state of the extension version (‘ratified’, ‘developemnt’, etc).
321 |
# File 'lib/udb/obj/extension.rb', line 321 def state = @data["state"] |
#to_ext_req ⇒ ExtensionRequirement
590 591 592 |
# File 'lib/udb/obj/extension.rb', line 590 def to_ext_req ExtensionRequirement.new(name, "= #{version_str}", arch: @arch) end |
#to_rvi_s ⇒ String
Returns formatted like the RVI manual.
358 359 360 |
# File 'lib/udb/obj/extension.rb', line 358 def to_rvi_s "#{name}#{@version_spec.to_rvi_s}" end |
#to_s ⇒ String
Returns Ext@Version.
363 364 365 |
# File 'lib/udb/obj/extension.rb', line 363 def to_s "#{name}@#{@version_spec.canonical}" end |
#url ⇒ Object
327 |
# File 'lib/udb/obj/extension.rb', line 327 def url = @data["url"] |