Class: Udb::Extension
- Inherits:
-
TopLevelDatabaseObject
- Object
- DatabaseObject
- TopLevelDatabaseObject
- Udb::Extension
- Includes:
- Comparable
- Defined in:
- lib/udb/obj/extension.rb,
lib/udb/condition.rb
Overview
Extension definition
Defined Under Namespace
Classes: ConditionallyApplicableParameter
Instance Method Summary collapse
- #<=>(other_ext) ⇒ Integer?
- #all_csrs_that_must_be_implemented ⇒ Array<Csr>
- #all_instructions_that_must_be_implemented ⇒ Object
-
#all_params_that_must_be_implemented ⇒ Array<Parameter>
List of parameters that must be defined if some version of this extension is defined.
-
#compact_priv_type ⇒ String
Either unpriv or priv.
- #company ⇒ Object
- #conditional_params ⇒ Array<ConditionallyApplicableParameter>
-
#conflicting_extensions ⇒ Object
List of extensions that conflict with self.
-
#csrs ⇒ Array<Csr>
not including those defined by requirements of this extension.
-
#csrs_that_must_be_implemented ⇒ Array<Csr>
The list of csrs that must be defined when any version of this extension is defined includes both those defined directly by self and those implied by self's requirements.
- #doc_license ⇒ nil, Hash{String => String}
-
#exception_codes ⇒ Array<ExceptionCode>
returns list of exception codes that are defined by any version of this extension.
-
#general_extension_requirements_condition ⇒ AbstractCondition
A condition representing the requirements that apply to all versions of this extension.
-
#implied_csrs ⇒ Array<Csr>
a requirement of the extension directly defines the csr.
-
#implied_instructions ⇒ Array<Instruction>
a requirement of the extension directly defines the instruction.
- #implied_instructions_set ⇒ Set<Instruction> private
-
#implied_params ⇒ Array<Parameter>
List of parameters that must be defined if this extension is defined due to one of the extension's requirements excluding those required because of a requirement of extension def implied_params.
-
#instructions ⇒ Array<Instruction>
The list of instructions implemented directly by any version of this extension (may be empty) Direct means that the instruction must be defined when the extension is implemented and may not be implemented when just the extension's requirements are met.
- #instructions_set ⇒ Set<Instruction> private
-
#interrupt_codes ⇒ Array<InterruptCode>
returns list of interrupt codes that are defined by any version of this extension.
-
#long_name ⇒ String
Long name of the extension.
-
#max_version ⇒ ExtensionVersion
Maximum defined version of this extension.
-
#min_ratified_version ⇒ ExtensionVersion?
Mimumum defined ratified version of this extension, or nil if there is none.
-
#min_version ⇒ ExtensionVersion
Mimumum defined version of this extension.
-
#mmrs ⇒ Array<Mmr>
The list of MMRs implemented by any version of this extension (may be empty).
-
#params ⇒ Array<Parameter>
List of parameters that must be defined if some version of this extension is defined, excluding those required because of a requirement of extension.
-
#priv_type ⇒ String
Either unprivileged or privileged.
-
#ratified ⇒ Boolean
Any version ratified?.
-
#ratified_versions ⇒ Array<ExtensionVersion>
Ratified versions hash from config.
-
#reachable_functions ⇒ Array<Idl::FunctionDefAst>
return the set of reachable functions from any of this extensions's CSRs or instructions in the given evaluation context.
-
#requirements_condition ⇒ AbstractCondition
A condition representing the requirements that apply to all versions of this extension (not just the generic requirements).
-
#to_condition ⇒ Condition
returns a condition representing any version of this extension being implemented.
-
#to_ext_req ⇒ ExtensionRequirement
returns an ext req that will be satisfied by any known version of this extension.
-
#versions ⇒ Array<ExtensionVersion>
Versions hash from config, sorted by version number.
Constructor Details
This class inherits a constructor from Udb::TopLevelDatabaseObject
Instance Method Details
#<=>(other_ext) ⇒ Integer?
404 405 406 407 |
# File 'lib/udb/obj/extension.rb', line 404 def <=>(other_ext) return nil unless other_ext.is_a?(Extension) name <=> other_ext.name end |
#all_csrs_that_must_be_implemented ⇒ Array<Csr>
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/udb/obj/extension.rb', line 273 def all_csrs_that_must_be_implemented @all_csrs_that_must_be_implemented ||= begin pb = Udb.( "Finding all required csrs for #{name} [:bar] :current/:total", total: @arch.csrs.size, clear: true ) @arch.csrs.select do |csr| pb.advance (-csr.defined_by_condition & to_condition).unsatisfiable_by_arch?(@arch) end end end |
#all_instructions_that_must_be_implemented ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/udb/obj/extension.rb', line 207 def all_instructions_that_must_be_implemented @all_instructions_that_must_be_implemented ||= begin pb = Udb.( "Finding all required instructions for #{name} [:bar] :current/:total", total: @arch.instructions.size, clear: true ) @arch.instructions.select do |i| pb.advance (-i.defined_by_condition & to_condition).unsatisfiable_by_arch?(@arch) end end end |
#all_params_that_must_be_implemented ⇒ Array<Parameter>
Returns List of parameters that must be defined if some version of this extension is defined.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/udb/obj/extension.rb', line 161 def all_params_that_must_be_implemented @all_params_that_must_be_implemented ||= begin pb = Udb.( "Finding implied params for #{name} [:bar] :current/:total", total: cfg_arch.params.size, clear: true ) cfg_arch.params.select do |p| pb.advance param_defined = p.defined_by_condition (-param_defined & to_condition).unsatisfiable_by_arch?(cfg_arch) end end end |
#compact_priv_type ⇒ String
Returns Either unpriv or priv.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/udb/obj/extension.rb', line 30 def compact_priv_type case priv_type when "unprivileged" "unpriv" when "privileged" "priv" else if priv_type.nil? || priv_type.empty? raise ArgumentError, "Extension #{name} missing its type in database (must be privileged or unprivileged)" else raise ArgumentError, "Extension #{name} has illegal privileged/unprivileged type of #{priv_type}" end end end |
#company ⇒ Object
48 49 50 51 52 |
# File 'lib/udb/obj/extension.rb', line 48 def company if @data.key?("company") @company ||= Company.new(@data["company"]) end end |
#conditional_params ⇒ Array<ConditionallyApplicableParameter>
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/udb/obj/extension.rb', line 116 def conditional_params @cond_params ||= begin pb = Udb.( "Finding conditional params for #{name} [:bar] :current/:total", total: cfg_arch.params.size, clear: true ) cfg_arch.params.filter_map do |p| pb.advance next if params.include?(p) next unless p.defined_by_condition.mentions?(self) next unless (p.defined_by_condition & self.to_condition).satisfiable? cond = p.defined_by_condition.partial_eval(ext_reqs: [self.to_ext_req]).minimize(expand: false) ConditionallyApplicableParameter.new(cond:, param: p) end end end |
#conflicting_extensions ⇒ Object
Returns list of extensions that conflict with self.
201 202 203 204 205 |
# File 'lib/udb/obj/extension.rb', line 201 def conflicting_extensions @cfg_arch.extensions.select do |ext| (to_condition & ext.to_condition).unsatisfiable? end end |
#csrs ⇒ Array<Csr>
not including those defined by requirements of this extension
310 311 312 |
# File 'lib/udb/obj/extension.rb', line 310 def csrs @csrs ||= all_csrs_that_must_be_implemented - implied_csrs end |
#csrs_that_must_be_implemented ⇒ Array<Csr>
Returns the list of csrs that must be defined when any version of this extension is defined includes both those defined directly by self and those implied by self's requirements.
344 345 346 |
# File 'lib/udb/obj/extension.rb', line 344 def csrs_that_must_be_implemented @csrs_that_must_be_implemented ||= csrs + implied_csrs end |
#doc_license ⇒ nil, Hash{String => String}
57 58 59 |
# File 'lib/udb/obj/extension.rb', line 57 def doc_license @data["doc_license"] end |
#exception_codes ⇒ Array<ExceptionCode>
returns list of exception codes that are defined by any version of this extension
411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/udb/obj/extension.rb', line 411 def exception_codes @exception_codes ||= @cfg_arch.exception_codes.select do |ecode| if ecode.defined_by_condition.mentions?(self) ecode.defined_by_condition.satisfied_by_ext_req?(to_ext_req, include_requirements: false) || ecode.defined_by_condition.satisfiability_depends_on_ext_req?(to_ext_req) else false end end end |
#general_extension_requirements_condition ⇒ AbstractCondition
Returns a condition representing the requirements that apply to all versions of this extension.
187 188 189 190 191 192 |
# File 'lib/udb/obj/extension.rb', line 187 def general_extension_requirements_condition @general_extension_requirements_condition ||= @data.key?("requirements") \ ? Condition.new(@data.fetch("requirements"), @cfg_arch, input_file: Pathname.new(__source), input_line: source_line(["requirements"])) : AlwaysTrueCondition.new(@cfg_arch) end |
#implied_csrs ⇒ Array<Csr>
a requirement of the extension directly defines the csr
This list may be empty
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/udb/obj/extension.rb', line 290 def implied_csrs @implied_csrs ||= begin pb = Udb.( "Finding implied csrs for #{name} [:bar] :current/:total", total: @arch.csrs.size, clear: true ) @arch.csrs.select do |csr| pb.advance (-csr.defined_by_condition & requirements_condition).unsatisfiable_by_arch?(@arch) end end end |
#implied_instructions ⇒ Array<Instruction>
a requirement of the extension directly defines the instruction
For example, the "C" extension implies c.addi because c.addi is directly defined by Zca and C requires Zca to be implemented
This list may be empty
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/udb/obj/extension.rb', line 232 def implied_instructions @implied_instructions ||= begin pb = Udb.( "Finding implied instructions for #{name} [:bar] :current/:total", total: @arch.instructions.size, clear: true ) @arch.instructions.select do |i| pb.advance (-i.defined_by_condition & requirements_condition).unsatisfiable_by_arch?(@arch) end end end |
#implied_instructions_set ⇒ Set<Instruction>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
268 269 270 |
# File 'lib/udb/obj/extension.rb', line 268 def implied_instructions_set @implied_instructions_set ||= Set.new(implied_instructions) end |
#implied_params ⇒ Array<Parameter>
Returns List of parameters that must be defined if this extension is defined due to one of the extension's requirements excluding those required because of a requirement of extension def implied_params.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/udb/obj/extension.rb', line 140 def implied_params @implied_params ||= begin pb = Udb.( "Finding implied params for #{name} [:bar] :current/:total", total: cfg_arch.params.size, clear: true ) cfg_arch.params.select do |p| pb.advance param_defined = p.defined_by_condition preconditions_met = requirements_condition (-param_defined & preconditions_met).unsatisfiable_by_arch?(cfg_arch) end end end |
#instructions ⇒ Array<Instruction>
Returns the list of instructions implemented directly by any version of this extension (may be empty) Direct means that the instruction must be defined when the extension is implemented and may not be implemented when just the extension's requirements are met
In other words, direct is the set of instructions that are defined without transitivity.
255 256 257 |
# File 'lib/udb/obj/extension.rb', line 255 def instructions @instructions ||= all_instructions_that_must_be_implemented - implied_instructions end |
#instructions_set ⇒ Set<Instruction>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
261 262 263 |
# File 'lib/udb/obj/extension.rb', line 261 def instructions_set @instructions_set ||= Set.new(instructions) end |
#interrupt_codes ⇒ Array<InterruptCode>
returns list of interrupt codes that are defined by any version of this extension
425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/udb/obj/extension.rb', line 425 def interrupt_codes @interrupt_codes ||= @cfg_arch.interrupt_codes.select do |icode| if icode.defined_by_condition.mentions?(self) icode.defined_by_condition.satisfied_by_ext_req?(to_ext_req, include_requirements: false) || icode.defined_by_condition.satisfiability_depends_on_ext_req?(to_ext_req) else false end end end |
#long_name ⇒ String
Returns Long name of the extension.
22 |
# File 'lib/udb/obj/extension.rb', line 22 def long_name = @data.fetch("long_name") |
#max_version ⇒ ExtensionVersion
Returns Maximum defined version of this extension.
91 92 93 |
# File 'lib/udb/obj/extension.rb', line 91 def max_version T.must(versions.max { |a, b| T.must(a.version_spec <=> b.version_spec) }) end |
#min_ratified_version ⇒ ExtensionVersion?
Returns Mimumum defined ratified version of this extension, or nil if there is none.
97 98 99 100 101 |
# File 'lib/udb/obj/extension.rb', line 97 def min_ratified_version return nil if ratified_versions.empty? ratified_versions.min { |a, b| T.must(a.version_spec <=> b.version_spec) } end |
#min_version ⇒ ExtensionVersion
Returns Mimumum defined version of this extension.
85 86 87 |
# File 'lib/udb/obj/extension.rb', line 85 def min_version T.must(versions.min { |a, b| T.must(a.version_spec <=> b.version_spec) }) end |
#mmrs ⇒ Array<Mmr>
Returns the list of MMRs implemented by any version of this extension (may be empty).
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/udb/obj/extension.rb', line 350 def mmrs @mmrs ||= begin pb = Udb.( "Finding mmrs for #{name} [:bar] :current/:total", total: cfg_arch.mmrs.size, clear: true ) cfg_arch.mmrs.select do |mmr| pb.advance mmr_defined = mmr.defined_by_condition next unless mmr_defined.mentions?(self) requirement_met = to_condition preconditions_met = requirements_condition # mmr is defined exclusively by self if: ( (-mmr_defined & requirement_met) # it must be defined when self is met, and ).unsatisfiable? & ( (-mmr_defined & preconditions_met) # it may not be defined when only self's requirements are met ).satisfiable? end end end |
#params ⇒ Array<Parameter>
Returns List of parameters that must be defined if some version of this extension is defined, excluding those required because of a requirement of extension.
106 107 108 |
# File 'lib/udb/obj/extension.rb', line 106 def params @params ||= all_params_that_must_be_implemented - implied_params end |
#priv_type ⇒ String
Returns Either unprivileged or privileged.
26 |
# File 'lib/udb/obj/extension.rb', line 26 def priv_type = @data.fetch("type") |
#ratified ⇒ Boolean
Returns Any version ratified?.
81 |
# File 'lib/udb/obj/extension.rb', line 81 def ratified = ratified_versions.any? |
#ratified_versions ⇒ Array<ExtensionVersion>
Returns Ratified versions hash from config.
75 76 77 |
# File 'lib/udb/obj/extension.rb', line 75 def ratified_versions versions.select { |v| v.state == "ratified" } end |
#reachable_functions ⇒ Array<Idl::FunctionDefAst>
return the set of reachable functions from any of this extensions's CSRs or instructions in the given evaluation context
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/udb/obj/extension.rb', line 381 def reachable_functions return @reachable_functions unless @reachable_functions.nil? funcs = T.let([], T::Array[Idl::FunctionDefAst]) Udb.logger.info "Finding all reachable functions from extension #{name}" cache = T.let({ 32 => {}, 64 => {}, nil => {} }, T::Hash[Integer, Idl::AstNode::ReachableFunctionCacheType]) instructions.each do |inst| funcs += inst.reachable_functions(32, cache.fetch(32)) if inst.defined_in_base?(32) funcs += inst.reachable_functions(64, cache.fetch(64)) if inst.defined_in_base?(64) end csrs.each do |csr| funcs += csr.reachable_functions(32, cache) if csr.defined_in_base?(32) funcs += csr.reachable_functions(64, cache) if csr.defined_in_base?(64) end @reachable_functions = funcs.uniq end |
#requirements_condition ⇒ AbstractCondition
Returns a condition representing the requirements that apply to all versions of this extension (not just the generic requirements).
196 197 198 |
# File 'lib/udb/obj/extension.rb', line 196 def requirements_condition @requirements_condition ||= to_ext_req.requirements_condition end |
#to_condition ⇒ Condition
returns a condition representing any version of this extension being implemented
181 182 183 |
# File 'lib/udb/obj/extension.rb', line 181 def to_condition @condition ||= Condition.new({ "extension" => { "name" => name } }, @cfg_arch) end |
#to_ext_req ⇒ ExtensionRequirement
returns an ext req that will be satisfied by any known version of this extension
439 440 441 |
# File 'lib/udb/obj/extension.rb', line 439 def to_ext_req @ext_req ||= @cfg_arch.extension_requirement(name, ">= 0") end |
#versions ⇒ Array<ExtensionVersion>
Returns versions hash from config, sorted by version number.
63 64 65 66 67 68 69 70 71 |
# File 'lib/udb/obj/extension.rb', line 63 def versions return @versions unless @versions.nil? @versions = @data["versions"].map do |v| cfg_arch.extension_version(name, v["version"]) end @versions.sort! @versions end |