Class: Udb::Extension

Inherits:
TopLevelDatabaseObject show all
Includes:
Comparable, CertifiableObject
Defined in:
lib/udb/obj/extension.rb,
lib/udb/condition.rb

Overview

Extension definition

Defined Under Namespace

Classes: ConditionallyApplicableParameter

Instance Method Summary collapse

Constructor Details

This class inherits a constructor from Udb::TopLevelDatabaseObject

Instance Method Details

#<=>(other_ext) ⇒ Integer?

Parameters:

  • other_ext (Object)

Returns:

  • (Integer, nil)


385
386
387
388
# File 'lib/udb/obj/extension.rb', line 385

def <=>(other_ext)
  return nil unless other_ext.is_a?(Extension)
  other_ext.name <=> name
end

#all_params_that_must_be_implementedArray<Parameter>

Returns List of parameters that must be defined if some version of this extension is defined.

Returns:

  • (Array<Parameter>)

    List of parameters that must be defined if some version of this extension is defined



188
189
190
# File 'lib/udb/obj/extension.rb', line 188

def all_params_that_must_be_implemented
  @all_params_that_must_be_implemented = params + implied_params
end

#cert_coverage_point(id) ⇒ CertNormativeRule? Originally defined in module CertifiableObject

Parameters:

  • id (String)

    Unique ID for the normative rule

Returns:

  • (CertNormativeRule)
  • (nil)

    if there is no certification normative ruleed with ID of id

#cert_coverage_point_hashHash<String, CertNormativeRule> Originally defined in module CertifiableObject

Returns Hash with ID as key of all normative rules defined by database object.

Returns:

  • (Hash<String, CertNormativeRule>)

    Hash with ID as key of all normative rules defined by database object

#cert_normative_rulesArray<CertNormativeRule> Originally defined in module CertifiableObject

Returns:

#cert_test_procedure(id) ⇒ CertTestProcedure? Originally defined in module CertifiableObject

Parameters:

  • id (String)

    Unique ID for test procedure

Returns:

  • (CertTestProcedure)
  • (nil)

    if there is no certification test procedure with ID id

#cert_test_procedure_hashHash<String, CertTestProcedure> Originally defined in module CertifiableObject

Returns Hash of all normative rules defined by database object.

Returns:

  • (Hash<String, CertTestProcedure>)

    Hash of all normative rules defined by database object

#cert_test_proceduresArray<CertTestProcedure> Originally defined in module CertifiableObject

Returns:

#compact_priv_typeString

Returns Either unpriv or priv.

Returns:

  • (String)

    Either unpriv or priv



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/udb/obj/extension.rb', line 33

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

#companyObject

Returns:

  • if the company isn’t known

  • (Company, nil)

    Company that developed the extension



51
52
53
54
55
# File 'lib/udb/obj/extension.rb', line 51

def company
  if @data.key?("company")
    @company ||= Company.new(@data["company"])
  end
end

#conditional_paramsArray<ConditionallyApplicableParameter>



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/udb/obj/extension.rb', line 143

def conditional_params
  @cond_params ||=
    begin
      pb =
        Udb.create_progressbar(
          "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_extensionsObject

Returns list of extensions that conflict with self.

Returns:

  • list of extensions that conflict with self



214
215
216
217
218
# File 'lib/udb/obj/extension.rb', line 214

def conflicting_extensions
  @cfg_arch.extensions.select do |ext|
    (to_condition & ext.to_condition).unsatisfiable?
  end
end

#csrsArray<Csr>

not including those defined by requirements of this extension

Returns:

  • (Array<Csr>)

    the list of CSRs implemented by *any version* of this extension (may be empty),



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/udb/obj/extension.rb', line 300

def csrs
  @csrs ||=
    begin
      pb =
        Udb.create_progressbar(
          "Finding csrs for #{name} [:bar] :current/:total",
          total: cfg_arch.csrs.size,
          clear: true
        )
      cfg_arch.csrs.select do |csr|
        pb.advance
        csr_defined = csr.defined_by_condition
        next unless csr_defined.mentions?(self)
        requirement_met = to_condition
        preconditions_met = requirements_condition

        # csr is defined exclusively by self if:
        (
          (-csr_defined & requirement_met) # it must be defined when self is met, and
        ).unsatisfiable? &
        (
          (-csr_defined & preconditions_met)  # it may not be defined when only self's requirements are met
        ).satisfiable?
      end
    end
end

#csrs_that_must_be_implementedArray<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.

Returns:

  • (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



357
358
359
# File 'lib/udb/obj/extension.rb', line 357

def csrs_that_must_be_implemented
  @csrs_that_must_be_implemented ||= csrs + implied_csrs
end

#doc_licensenil, Hash{String => String}

Returns:

  • (nil)

    if the license isn’t known

  • (Hash{String => String}, nil)

    The name and URL of a document license the doc falls under



60
61
62
# File 'lib/udb/obj/extension.rb', line 60

def doc_license
  @data["doc_license"]
end

#exception_codesArray<ExceptionCode>

returns list of exception codes that are defined by any version of this extension

Returns:



392
393
394
395
396
397
398
399
400
401
402
# File 'lib/udb/obj/extension.rb', line 392

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_conditionAbstractCondition

Returns a condition representing the requirements that apply to all versions of this extension.

Returns:

  • (AbstractCondition)

    a condition representing the requirements that apply to all versions of this extension



200
201
202
203
204
205
# File 'lib/udb/obj/extension.rb', line 200

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_csrsArray<Csr>

a requirement of the extension directly defines the csr

This list may be empty

Returns:

  • (Array<Csr>)

    the list of csrs implemented indirectly by *any version* of this extension because



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/udb/obj/extension.rb', line 332

def implied_csrs
  @implied_csrs ||=
    begin
      pb =
        Udb.create_progressbar(
          "Finding implied csrs for #{name} [:bar] :current/:total",
          total: cfg_arch.csrs.size,
          clear: true
        )
      cfg_arch.csrs.select do |csr|
        pb.advance
        csr_defined = csr.defined_by_condition
        preconditions_met = requirements_condition

        # csr is defined transitively by self if:
        (
          (-csr_defined & preconditions_met) # it must be defined when preconditions are met, and
        ).unsatisfiable?
      end
    end
end

#implied_instructionsArray<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

Returns:

  • (Array<Instruction>)

    the list of instructions implemented indirectly by *any version* of this extension because



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/udb/obj/extension.rb', line 267

def implied_instructions
  @instructions ||=
    begin
      pb =
        Udb.create_progressbar(
          "Finding implied instructions for #{name} [:bar] :current/:total",
          total: cfg_arch.instructions.size,
          clear: true
        )
      cfg_arch.instructions.select do |i|
        pb.advance
        if i.defined_by_condition.mentions?(to_ext_req)
          inst_defined = i.defined_by_condition
          preconditions_met = requirements_condition

          # inst is defined transitively by self if:
          (
            (-inst_defined & preconditions_met) # it must be defined when preconditions are met, and
          ).unsatisfiable?
        end
      end
    end
end

#implied_instructions_setSet<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.

Returns:



293
294
295
# File 'lib/udb/obj/extension.rb', line 293

def implied_instructions_set
  @implied_instructions_set ||= Set.new(implied_instructions)
end

#implied_paramsArray<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.

Returns:

  • (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



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/udb/obj/extension.rb', line 167

def implied_params
  @implied_params ||=
    begin
      pb =
        Udb.create_progressbar(
          "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?
      end
    end
end

#instructionsArray<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.

Returns:

  • (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

    In other words, direct is the set of instructions that are defined without transitivity



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/udb/obj/extension.rb', line 226

def instructions
  @instructions ||=
    begin
      pb =
        Udb.create_progressbar(
          "Finding instructions for #{name} [:bar] :current/:total",
          total: cfg_arch.instructions.size,
          clear: true
        )
      cfg_arch.instructions.select do |i|
        pb.advance
        inst_defined = i.defined_by_condition
        next unless inst_defined.mentions?(self)
        requirement_met = to_condition
        preconditions_met = requirements_condition

        # inst is defined exclusively by self if:
        (
          (-inst_defined & requirement_met) # it must be defined when self is met, and
        ).unsatisfiable? &
        (
          (-inst_defined & preconditions_met)  # it may not be defined when only self's requirements are met
        ).satisfiable?
      end
    end
end

#instructions_setSet<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.

Returns:



255
256
257
# File 'lib/udb/obj/extension.rb', line 255

def instructions_set
  @instructions_set ||= Set.new(instructions)
end

#interrupt_codesArray<InterruptCode>

returns list of interrupt codes that are defined by any version of this extension

Returns:



406
407
408
409
410
411
412
413
414
415
416
# File 'lib/udb/obj/extension.rb', line 406

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_nameString

Returns Long name of the extension.

Returns:

  • (String)

    Long name of the extension



25
# File 'lib/udb/obj/extension.rb', line 25

def long_name = @data.fetch("long_name")

#max_versionExtensionVersion

Returns Maximum defined version of this extension.

Returns:



94
95
96
# File 'lib/udb/obj/extension.rb', line 94

def max_version
  T.must(versions.max { |a, b| T.must(a.version_spec <=> b.version_spec) })
end

#min_ratified_versionExtensionVersion?

Returns Mimumum defined ratified version of this extension, or nil if there is none.

Returns:

  • (ExtensionVersion, nil)

    Mimumum defined ratified version of this extension, or nil if there is none



100
101
102
103
104
# File 'lib/udb/obj/extension.rb', line 100

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_versionExtensionVersion

Returns Mimumum defined version of this extension.

Returns:



88
89
90
# File 'lib/udb/obj/extension.rb', line 88

def min_version
  T.must(versions.min { |a, b| T.must(a.version_spec <=> b.version_spec) })
end

#paramsArray<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.

Returns:

  • (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



109
110
111
112
113
114
115
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 109

def params
  @params ||=
    begin
      pb =
        Udb.create_progressbar(
          "Finding params for #{name} [:bar] :current/:total",
          total: cfg_arch.params.size,
          clear: true
        )
      cfg_arch.params.select do |p|
        pb.advance
        if p.defined_by_condition.mentions?(self)
          param_defined = p.defined_by_condition
          ext_implemented = to_condition
          preconditions_met = requirements_condition

          # inst is defined transitively by self if:
          (
            (-param_defined & ext_implemented) # it must be defined when preconditions are met, and
          ).unsatisfiable? && \
          (
            (-param_defined & preconditions_met) # it may not be defined when only self's requirements are met
          ).satisfiable?
        end
      end
    end
end

#priv_typeString

Returns Either unprivileged or privileged.

Returns:

  • (String)

    Either unprivileged or privileged



29
# File 'lib/udb/obj/extension.rb', line 29

def priv_type = @data.fetch("type")

#ratifiedBoolean

Returns Any version ratified?.

Returns:

  • (Boolean)

    Any version ratified?



84
# File 'lib/udb/obj/extension.rb', line 84

def ratified = ratified_versions.any?

#ratified_versionsArray<ExtensionVersion>

Returns Ratified versions hash from config.

Returns:



78
79
80
# File 'lib/udb/obj/extension.rb', line 78

def ratified_versions
  versions.select { |v| v.state == "ratified" }
end

#reachable_functionsArray<Idl::FunctionDefAst>

return the set of reachable functions from any of this extensions’s CSRs or instructions in the given evaluation context

Returns:

  • (Array<Idl::FunctionDefAst>)

    Array of IDL functions reachable from any instruction or CSR in the extension



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/udb/obj/extension.rb', line 365

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}"

  instructions.each do |inst|
    funcs += inst.reachable_functions(32) if inst.defined_in_base?(32)
    funcs += inst.reachable_functions(64) if inst.defined_in_base?(64)
  end

  csrs.each do |csr|
    funcs += csr.reachable_functions
  end

  @reachable_functions = funcs.uniq
end

#requirements_conditionAbstractCondition

Returns a condition representing the requirements that apply to all versions of this extension (not just the generic requirements).

Returns:

  • (AbstractCondition)

    a condition representing the requirements that apply to all versions of this extension (not just the generic requirements)



209
210
211
# File 'lib/udb/obj/extension.rb', line 209

def requirements_condition
  @requirements_condition ||= to_ext_req.requirements_condition
end

#to_conditionCondition

returns a condition representing any version of this extension being implemented

Returns:



194
195
196
# File 'lib/udb/obj/extension.rb', line 194

def to_condition
  @condition ||= Condition.new({ "extension" => { "name" => name } }, @cfg_arch)
end

#to_ext_reqExtensionRequirement

returns an ext req that will be satisfied by any known version of this extension



420
421
422
# File 'lib/udb/obj/extension.rb', line 420

def to_ext_req
  @ext_req ||= @cfg_arch.extension_requirement(name, ">= 0")
end

#versionsArray<ExtensionVersion>

Returns versions hash from config, sorted by version number.

Returns:

  • (Array<ExtensionVersion>)

    versions hash from config, sorted by version number



66
67
68
69
70
71
72
73
74
# File 'lib/udb/obj/extension.rb', line 66

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