Skip to content

Commit d462e6f

Browse files
author
Derek Hower
committed
More robust ext_pdf
1 parent 101043e commit d462e6f

File tree

6 files changed

+122
-49
lines changed

6 files changed

+122
-49
lines changed

backends/arch_gen/lib/arch_gen.rb

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -470,31 +470,51 @@ def interrupt_codes
470470
end
471471
private :env
472472

473-
def merge_helper(base_obj, updates, path_so_far)
474-
obj = path_so_far.empty? ? updates : updates.dig(*path_so_far)
475-
obj.each do |key, value|
476-
if value.is_a?(Hash)
477-
merge_helper(base_obj, updates, (path_so_far + [key]))
473+
# merges patch into base_obj based on JSON Merge Patch (RFC 7386)
474+
#
475+
# @param base_obj [Hash] base object to merge into
476+
# @param patch [Hash] patch to merge into base_obj
477+
# @param path_so_far [Array<String>] path into the current object. Shouldn't be set by user (used during recursion)
478+
# @return [Hash] merged object
479+
def merge_patch(base, patch, path_so_far = [])
480+
patch_obj = path_so_far.empty? ? patch : patch.dig(*path_so_far)
481+
patch_obj.each do |key, patch_value|
482+
if patch_value.is_a?(Hash)
483+
# continue to dig
484+
merge_patch(base, patch, (path_so_far + [key]))
478485
else
479-
(path_so_far + [key]).each_with_index do |k, idx|
480-
base_obj[k] ||= {}
481-
if idx != path_so_far.size
482-
base_obj = base_obj[k]
483-
else
484-
base_obj[k] = value
486+
base_ptr = base.dig(*path_so_far)
487+
base_value = base_ptr&.dig(key)
488+
case patch_value
489+
when nil
490+
# remove from base, if it exists
491+
unless base_value.nil?
492+
base_ptr[key] = nil
493+
end
494+
else
495+
# add or overwrite value in base
496+
if base_ptr.nil?
497+
# need to create intermediate nodes, too
498+
base_ptr = base
499+
path_so_far.each do |k|
500+
base_ptr[k] = {} unless base_ptr.key?(k)
501+
base_ptr = base_ptr[k]
502+
end
503+
base_ptr = base.dig(*path_so_far)
485504
end
505+
base_ptr[key] = patch_value
486506
end
487507
end
488508
end
489509
end
490-
private :merge_helper
510+
private :merge_patch
491511

492512
# overwrites base_obj with any data in update
493513
#
494514
# @param base_obj [Hash] Base object
495515
# @param updates [Hash] Object with overlays
496516
# @return [Hash] Updated object
497-
def merge(base_obj, updates) = merge_helper(base_obj, updates, [])
517+
def merge(base_obj, updates) = merge_patch(base_obj, updates, [])
498518
private :merge
499519

500520
# @param type [Symbol] Type of the object (@see Validator::SCHEMA_PATHS)
@@ -728,6 +748,7 @@ def maybe_add_csr(csr_name, extra_env = {})
728748
end
729749
belongs =
730750
csr_obj.exists_in_cfg?(arch_def_mock)
751+
731752

732753
@implemented_csrs ||= []
733754
@implemented_csrs << csr_name if belongs
@@ -784,7 +805,10 @@ def maybe_add_ext(ext_name)
784805

785806
merged_path = gen_merged_def(:ext, arch_path, arch_overlay_path)
786807

787-
ext_obj = YAML.load_file(merged_path)[ext_name]
808+
yaml_contents = YAML.load_file(merged_path)
809+
raise "In #{merged_path}, key does not match file name" unless yaml_contents.key?(ext_name)
810+
811+
ext_obj = yaml_contents[ext_name]
788812
ext_obj["name"] = ext_name
789813

790814
@implied_ext_map ||= {}

backends/ext_pdf_doc/templates/ext_pdf.adoc.erb

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
FROZEN_STATE
2424
when "development"
2525
<<~DEV_STATE
26-
This document is in the http://riscv.org/spec-state[Development state].
27-
28-
Change should be expected
26+
This document is in the http://riscv.org/spec-state[Development state]. + \\
27+
+ \\
28+
Change should be expected + \\
2929
DEV_STATE
3030
else
3131
raise "TODO: #{ext_version["state"]} description"
@@ -37,11 +37,13 @@
3737
:preface-title: Licensing and Acknowledgements
3838
:colophon:
3939
:appendix-caption: Appendix
40+
<%- if !ext.company.nil? && (ext.company["name"] =~ /RISCV/) -%>
4041
:title-logo-image: image:risc-v_logo.png["RISC-V International Logo",pdfwidth=3.25in,align=center]
42+
:back-cover-image: image:riscv-horizontal-color.svg[opacity=25%]
43+
<%- end -%>
4144
<%- unless ext_version["state"] == "ratified" -%>
4245
:page-background-image: image:draft.png[opacity=20%]
4346
<%- end -%>
44-
:back-cover-image: image:riscv-horizontal-color.svg[opacity=25%]
4547
// Settings
4648
:experimental:
4749
:reproducible:
@@ -121,7 +123,7 @@ endif::[]
121123
== Copyright and license information
122124
This document is released under the <%= ext.doc_license.nil? ? "unknown" : ext.doc_license["url"] %>[<%= ext.doc_license.nil? ? "unknown" : ext.doc_license["name"] %>].
123125

124-
Copyright <%= ext_version["ratification_date"].split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.
126+
Copyright <%= ext_version["ratification_date"].nil? ? Date.today.year : ext_version["ratification_date"].split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.
125127

126128
[preface]
127129
== Acknowledgements
@@ -131,7 +133,8 @@ Contributors to version <%= version["version"] %> of the specification (in alpha
131133

132134
<%- unless version["contributors"].nil? -%>
133135
<%- version["contributors"].sort { |a, b| a["name"].split(" ").last <=> b["name"].split(" ").last }.each do |c| -%>
134-
* <%= c["name"] %> <<%= c["email"] %>> (<%= c["company"] %>)
136+
* <%= c["name"] %> <<%= c["email"] %>> (<%= c["company"] %>)
137+
135138
<%- end -%>
136139
<%- end -%>
137140
<%- end -%>
@@ -154,21 +157,69 @@ Ratification Date:: <%= version["ratification_date"] %>
154157
<%- if version.key?("url") -%>
155158
Design document:: <%= version["url"] %>
156159
<%- end -%>
157-
<%- if version.key?("change") -%>
160+
<%- if version.key?("changes") -%>
158161
Changes::
159162
<%= version["changes"] %>
160163
<%- end -%>
164+
<%- unless version["implies"].nil? || version["implies"].empty? -%>
165+
Implies::
166+
* <%= version["implies"].map { |name, version| "#{name} (#{version})" }.join("\n* ") %>
167+
<%- end -%>
161168
--
162169
<%- end -%>
163170

171+
164172
<<<
165173
== Extension description
166174

167175
<%= ext.description %>
168176

169177
<%- unless ext.implies.nil? -%>
170-
<%- ext.implies.each do |e| -%>
178+
=== Sub-extensions
179+
The following sub-extensions are defined:
180+
181+
<%- ext.implies.each do |sub_ext| -%>
182+
==== <%= sub_ext.name %>
183+
184+
<%= arch_def.extension(sub_ext.name).description %>
185+
186+
<%- end -%>
187+
<%- end -%>
188+
189+
<%- unless ext.instructions.empty? -%>
190+
<<<
191+
== Instruction summary
192+
193+
The following <%= ext.instructions.size %> instructions are added by this extension:
194+
195+
[%autowidth]
196+
|===
197+
| RV32 | RV64 | Mnemonic | Instruction | <%= ext.versions.map { |v| "v#{v["version"]}" }.join(" | ") %>
198+
199+
<%- ext.instructions.each do |i| -%>
200+
| <%= i.rv32? ? "&#x2713;" : "" %>
201+
| <%= i.rv64? ? "&#x2713;" : "" %>
202+
| `<%= i.name %> <%= i.assembly.gsub("x", "r").strip %>`
203+
| xref:insns-<%= i.name.gsub('.', '_') %>[<%= i.long_name %>]
204+
| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "&#x2713;" : "" }.join(" | ") %>
205+
<%- end -%>
206+
|===
207+
208+
<%- unless ext.implies.empty? -%>
209+
=== Instructions by sub-extension
210+
211+
|===
212+
| Mnemonic | `<%= ext.name %>` | <%= ext.implies.map { |e| "`#{e.name}`" }.join(" | ") %>
213+
214+
<%- ext.instructions.each do |i| -%>
215+
| `<%= i.name %>`
216+
| &#x2713;
217+
| <%= ext.implies.map { |e| i.defined_by?(e.name, arch_def.extension(e.name).max_version) ? "&#x2713;" : "" }.join(" | ") %>
218+
<%- end -%>
219+
|===
220+
171221
<%- end -%>
222+
172223
<%- end -%>
173224

174225
<%- unless ext.csrs.empty? -%>
@@ -327,24 +378,6 @@ This CSR may return a value that is different from what is stored in hardware.
327378
<%- end -%>
328379

329380
<%- unless ext.instructions.empty? -%>
330-
<<<
331-
== Instruction summary
332-
333-
The following <%= ext.instructions.size %> instructions are added by this extension:
334-
335-
[%autowidth]
336-
|===
337-
| RV32 | RV64 | Mnemonic | Instruction | <%= ext.versions.map { |v| "v#{v["version"]}" }.join(" | ") %>
338-
339-
<%- ext.instructions.each do |i| -%>
340-
| <%= i.rv32? ? "&#x2713;" : "" %>
341-
| <%= i.rv64? ? "&#x2713;" : "" %>
342-
| `<%= i.name %> <%= i.assembly.gsub("x", "r") %>`
343-
| xref:insns-<%= i.name.gsub('.', '_') %>[<%= i.long_name %>]
344-
| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "&#x2713;" : "" }.join(" | ") %>
345-
<%- end -%>
346-
|===
347-
348381
<<<
349382
[#insns,reftext="Instructions (in alphabetical order)"]
350383
== Instructions (in alphabetical order)
@@ -387,8 +420,14 @@ RV64::
387420
Description::
388421
<%= i.description %>
389422

423+
390424
Decode Variables::
391425

426+
<%- if i.multi_encoding? ? (i.decode_variables(32).empty? && i.decode_variables(64).empty?) : i.decode_variables(i.base.nil? ? 64 : i.base).empty? -%>
427+
428+
<%= i.name %> has no decode variables.
429+
430+
<%- else -%>
392431
<%- if i.multi_encoding? -%>
393432
RV32::
394433
+
@@ -414,7 +453,8 @@ RV64::
414453
<%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>;
415454
<%- end -%>
416455
----
417-
<%- end -%>
456+
<%- end # if multi_encoding? -%>
457+
<%- end # if no decode variables-%>
418458
419459
Operation::
420460
<%- unless i.data["operation()"].nil? -%>
@@ -455,4 +495,4 @@ h| Arguments l| <%= f.arguments_list_str.join (', ') %>
455495
----
456496
<%- end -%>
457497
458-
<%- end -%>
498+
<%- end -%>

lib/idl/ast.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3601,7 +3601,11 @@ def initialize(input, interval, condition, true_expression, false_expression)
36013601
# @!macro type_check
36023602
def type_check(symtab)
36033603
condition.type_check(symtab)
3604-
type_error "ternary selector must be bool" unless condition.type(symtab).kind == :boolean
3604+
if condition.type(symtab).kind == :bits
3605+
type_error "ternary selector must be bool (maybe you meant '#{condition.text_value} != 0'?)"
3606+
else
3607+
type_error "ternary selector must be bool" unless condition.type(symtab).kind == :boolean
3608+
end
36053609
36063610
value_result = value_try do
36073611
cond = condition.value(symtab)
@@ -5740,9 +5744,9 @@ def calc_type(symtab)
57405744
fd = field_def(symtab)
57415745
if fd.nil?
57425746
if @idx.is_a?(IntLiteralAst)
5743-
internal_error "Could not find CSR[#{@idx.to_idl}]"
5747+
internal_error "Could not find CSR[#{@idx.to_idl}].#{@field_name}"
57445748
else
5745-
internal_error "Could not find CSR[#{@idx}]"
5749+
internal_error "Could not find CSR[#{@idx}].#{@field_name}"
57465750
end
57475751
end
57485752
if fd.defined_in_all_bases?
@@ -6026,7 +6030,7 @@ def value(symtab)
60266030
when "sw_read"
60276031
value_error "CSR not knowable" unless csr_known?(symtab)
60286032
cd = csr_def(symtab)
6029-
cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" }
6033+
cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type(symtab) == "RO" }
60306034
60316035
value_error "TODO: CSRs with sw_read function"
60326036
when "address"

schemas/arch_schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
"type": "array",
9191
"items": {
9292
"type": "string",
93-
"pattern": "^[a-z][a-zA-Z0-9]+$",
93+
"pattern": "^[a-z][a-zA-Z0-9_]+$",
9494
"description": "CSR name"
9595
}
9696
},

schemas/csr_schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@
278278
"misa:\\n long_name: Machine ISA Control\\n address: 0x301\\n priv_mode: M\\n length: 64\\n description: Reports the XLEN and 'major' extensions supported by the ISA.\\n definedBy: I\\n fields:\\n MXL:\\n location: 63-62\\n description: XLEN in M-mode.\\n type: RO\\n value: 2\\n Extensions: location: 25-0\\n description: |\\n Indicates support for major (single letter) ISA extensions.\\n\\n Value corresponds to A, D, F, H, I, M, S, U\\n type: RO\\n value: 0x1411A9"
279279
],
280280
"patternProperties": {
281-
"^[a-z][a-z0-9A-Z]+$": {
281+
"^[a-z][a-z0-9A-Z_]+$": {
282282
"description": "CSR name",
283283
"$ref": "#/$defs/csr_register"
284284
}

schemas/inst_schema.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@
6262
"properties": {
6363
"match": {
6464
"oneOf": [
65+
{
66+
"type": "string",
67+
"pattern": "^[01-]{43}11111$",
68+
"description": "48-bit encoding"
69+
},
6570
{
6671
"type": "string",
6772
"pattern": "^[01-]{30}11$",
@@ -217,4 +222,4 @@
217222
},
218223
"additionalProperties": false,
219224
"maxProperties": 1
220-
}
225+
}

0 commit comments

Comments
 (0)