diff --git a/arch/csr/medelegh.yaml b/arch/csr/medelegh.yaml index 271e198859..4a75e09e47 100644 --- a/arch/csr/medelegh.yaml +++ b/arch/csr/medelegh.yaml @@ -8,5 +8,7 @@ medelegh: base: 32 description: | Alias of the upper 32 bits of `medeleg`. - definedBy: I + definedBy: + name: S + version: ">= 1.13" fields: {} diff --git a/arch/csr/mseccfg.yaml b/arch/csr/mseccfg.yaml index 7f90c9de3b..2cbc905e68 100644 --- a/arch/csr/mseccfg.yaml +++ b/arch/csr/mseccfg.yaml @@ -8,6 +8,6 @@ mseccfg: description: Machine Security Configuration definedBy: name: Sm - version: ">=1.12" + version: ">= 1.12" fields: {} \ No newline at end of file diff --git a/arch/csr/mseccfgh.yaml b/arch/csr/mseccfgh.yaml index 6aa15924cb..80a5a721f6 100644 --- a/arch/csr/mseccfgh.yaml +++ b/arch/csr/mseccfgh.yaml @@ -8,6 +8,6 @@ mseccfgh: description: Machine Security Configuration definedBy: name: Sm - version: ">=1.12" + version: ">= 1.12" fields: {} \ No newline at end of file diff --git a/arch/csr/mstatush.yaml b/arch/csr/mstatush.yaml index bf306ef997..eec243033b 100644 --- a/arch/csr/mstatush.yaml +++ b/arch/csr/mstatush.yaml @@ -7,7 +7,9 @@ mstatush: base: 32 length: 32 description: The mstatus register tracks and controls the hart's current operating state. - definedBy: Sm + definedBy: + name: Sm + version: ">= 1.12" fields: MPV: location: 7 diff --git a/backends/crd_doc/templates/crd.adoc.erb b/backends/crd_doc/templates/crd.adoc.erb index 0a05769cb3..79580fbbaa 100644 --- a/backends/crd_doc/templates/crd.adoc.erb +++ b/backends/crd_doc/templates/crd.adoc.erb @@ -176,7 +176,7 @@ None == CSR Summary <% - csrs = crd.in_scope_extensions.map { |ext_crd| ext_crd.csrs }.flatten.uniq + csrs = crd.in_scope_ext_reqs.map { |ext_crd_req| ext_crd_req.csrs(crd.arch_def) }.flatten.uniq -%> === By Name @@ -476,7 +476,7 @@ This instruction may result in the following synchronous exceptions: == CSR Details <% - csrs = crd.in_scope_extensions.map { |ext_crd| ext_crd.csrs }.flatten.uniq + csrs = crd.in_scope_ext_reqs.map { |ext_crd_req| ext_crd_req.csrs(crd.arch_def) }.flatten.uniq csrs.sort_by!(&:name) -%> diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 4516d8d6f3..f8675e9425 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -422,15 +422,24 @@ def satisfying_versions(archdef) # @param extension_version [ExtensionVersion] A specific extension version # @return [Boolean] whether or not the extension_version meets this requirement # @overload + # @param extension_requirement [ExtensionRequirement] A range of extension versions + # @return [Boolean] whether or not extension_requirement is satisfied by this requirement + # @overload # @param extension_name [#to_s] An extension name # @param extension_name [#to_s] An extension version # @return [Boolean] whether or not the extension_version meets this requirement def satisfied_by?(*args) if args.size == 1 - raise ArgumentError, "Single argument must be an ExtensionVersion" unless args[0].is_a?(ExtensionVersion) - - args[0].name == @name && - @requirement.satisfied_by?(Gem::Version.new(args[0].version)) + if args[0].is_a?(ExtensionVersion) + args[0].name == @name && + @requirement.satisfied_by?(Gem::Version.new(args[0].version)) + elsif args[0].is_a?(ExtensionRequirement) + satisfying_versions.all? do |ext_ver| + satified_by?(ext_ver) + end + else + raise ArgumentError, "Single argument must be an ExtensionVersion or ExtensionRquirement" + end elsif args.size == 2 raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) raise ArgumentError, "First parameter must be an extension version" unless args[1].respond_to?(:to_s) @@ -442,6 +451,17 @@ def satisfied_by?(*args) end end + # @return [Array] List of CSRs defined by any extension satisfying this requirement + def csrs(arch_def) + return @csrs unless @csrs.nil? + + @csrs = arch_def.csrs.select do |csr| + satisfying_versions(arch_def).any? do |ext_ver| + csr.defined_by?(ext_ver) + end + end + end + # sorts by name def <=>(other) raise ArgumentError, "ExtensionRequirements are only comparable to other extension requirements" unless other.is_a?(ExtensionRequirement) diff --git a/lib/arch_obj_models/obj.rb b/lib/arch_obj_models/obj.rb index 090bc2f501..7ed012adb8 100644 --- a/lib/arch_obj_models/obj.rb +++ b/lib/arch_obj_models/obj.rb @@ -151,6 +151,8 @@ def defined_by?(*args) # @return [SchemaCondition] Extension(s) that define the instruction. If *any* requirement is met, the instruction is defined. def defined_by + raise "ERROR: definedBy is nul for #{name}" if @data["definedBy"].nil? + SchemaCondition.new(@data["definedBy"]) end