Skip to content

Commit c9691b9

Browse files
Merge remote-tracking branch 'origin/main' into 237-create-separate-profile-pdf-for-each-profile-family-release-eg-rva23-not-one-pdf-for-all-profiles-in-a-family-eg-rva
2 parents 73eadb3 + 1791292 commit c9691b9

File tree

11 files changed

+454
-141
lines changed

11 files changed

+454
-141
lines changed

Rakefile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,20 @@ namespace :serve do
5555
end
5656
end
5757

58-
Minitest::TestTask.create :idl_test do |t|
58+
desc "Run the IDL compiler test suite"
59+
task :idl_test do
60+
t = Minitest::TestTask.new(:lib_test)
5961
t.test_globs = ["#{$root}/lib/idl/tests/test_*.rb"]
62+
t.process_env
63+
ruby t.make_test_cmd
64+
end
65+
66+
desc "Run the Ruby library test suite"
67+
task :lib_test do
68+
t = Minitest::TestTask.new(:lib_test)
69+
t.test_globs = ["#{$root}/lib/test/test_*.rb"]
70+
t.process_env
71+
ruby t.make_test_cmd
6072
end
6173

6274
desc "Clean up all generated files"
@@ -269,6 +281,7 @@ desc <<~DESC
269281
DESC
270282
task :regress do
271283
Rake::Task["idl_test"].invoke
284+
Rake::Task["lib_test"].invoke
272285
Rake::Task["validate"].invoke
273286
ENV["MANUAL_NAME"] = "isa"
274287
ENV["VERSIONS"] = "all"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# yaml-language-server: $schema=../../schemas/inst_variable_metadatas.json
2+
---
3+
4+
itype_imm:
5+
location: 31-20

arch/inst/I/addi.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ addi:
99
match: -----------------000-----0010011
1010
variables:
1111
- name: imm
12-
location: 31-20
12+
$mref: ../../common/inst_variable_types.yaml#/itype_imm
1313
- name: rs1
1414
location: 19-15
1515
- name: rd

arch/inst/I/addiw.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ addiw:
77
base: 64
88
assembly: xd, xs1, imm
99
encoding:
10-
match: -----------------000-----0001011
10+
match: -----------------000-----0011011
1111
variables:
1212
- name: imm
1313
location: 31-20

backends/arch_gen/lib/arch_gen.rb

Lines changed: 27 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
require "rake/application"
77
require "rubygems/requirement"
88
require "tilt"
9-
require "yaml"
109

1110
require_relative "#{$lib}/validate"
1211
require_relative "#{$lib}/arch_def"
@@ -53,7 +52,7 @@ def gen_params_schema
5352
@implemented_extensions.each do |ext|
5453
ext_name = ext["name"]
5554
gen_ext_path = @gen_dir / "arch" / "ext" / "#{ext_name}.yaml"
56-
ext_yaml = YAML.safe_load gen_ext_path.read
55+
ext_yaml = YAML.load_file gen_ext_path.to_s
5756
unless ext_yaml[ext_name]["params"].nil?
5857
ext_yaml[ext_name]["params"].each do |param_name, param_data|
5958
schema["properties"]["params"]["required"] << param_name
@@ -92,7 +91,7 @@ def initialize(config_name)
9291
raise "Validation failed" if @cfg_impl_ext.nil?
9392

9493
cfg_opts_path = @cfg_dir / "cfg.yaml"
95-
@cfg_opts = YAML.load_file(cfg_opts_path)
94+
@cfg_opts = YamlLoader.load(cfg_opts_path, permitted_classes:[Date])
9695
raise "Validation failed" if @cfg_opts.nil?
9796
raise "Validation failed: bad type" unless ["partially configured", "fully configured"].include?(@cfg_opts["type"])
9897

@@ -147,7 +146,7 @@ def params_extra_validation
147146
@implemented_extensions.each do |ext|
148147
ext_name = ext["name"]
149148
gen_ext_path = @gen_dir / "arch" / "ext" / "#{ext_name}.yaml"
150-
ext_yaml = YAML.safe_load gen_ext_path.read
149+
ext_yaml = YAML.load_file gen_ext_path.to_s
151150
unless ext_yaml[ext_name]["params"].nil?
152151
ext_yaml[ext_name]["params"].each do |param_name, param_data|
153152
next unless param_data.key?("extra_validation")
@@ -275,65 +274,65 @@ def implemented_extensions
275274
#
276275
def gen_arch_def
277276
csr_hash = Dir.glob(@gen_dir / "arch" / "csr" / "**" / "*.yaml").map do |f|
278-
csr_obj = YAML.load_file(f)
277+
csr_obj = YamlLoader.load(f, permitted_classes:[Date])
279278
csr_name = csr_obj.keys[0]
280279
[csr_name, csr_obj[csr_name]]
281280
end.to_h
282281
inst_hash = Dir.glob(@gen_dir / "arch" / "inst" / "**" / "*.yaml").map do |f|
283-
inst_obj = YAML.load_file(f)
282+
inst_obj = YamlLoader.load(f, permitted_classes:[Date])
284283
inst_name = inst_obj.keys[0]
285284
[inst_name, inst_obj[inst_name]]
286285
end.to_h
287286
ext_hash = Dir.glob(@gen_dir / "arch" / "ext" / "**" / "*.yaml").map do |f|
288-
ext_obj = YAML.load_file(f)
287+
ext_obj = YamlLoader.load(f, permitted_classes:[Date])
289288
ext_name = ext_obj.keys[0]
290289
[ext_name, ext_obj[ext_name]]
291290
end.to_h
292291
profile_class_hash = Dir.glob($root / "arch" / "profile_class" / "**" / "*.yaml").map do |f|
293-
profile_class_obj = YAML.load_file(f, permitted_classes: [Date])
292+
profile_class_obj = YamlLoader.load(f, permitted_classes:[Date])
294293
profile_class_name = profile_class_obj.keys[0]
295294
profile_class_obj[profile_class_name]["name"] = profile_class_name
296295
profile_class_obj[profile_class_name]["__source"] = f
297296
[profile_class_name, profile_class_obj[profile_class_name]]
298297
end.to_h
299298
profile_release_hash = Dir.glob($root / "arch" / "profile_release" / "**" / "*.yaml").map do |f|
300-
profile_release_obj = YAML.load_file(f, permitted_classes: [Date])
299+
profile_release_obj = YamlLoader.load(f, permitted_classes:[Date])
301300
profile_release_name = profile_release_obj.keys[0]
302301
profile_release_obj[profile_release_name]["name"] = profile_release_name
303302
profile_release_obj[profile_release_name]["__source"] = f
304303
[profile_release_name, profile_release_obj[profile_release_name]]
305304
end.to_h
306305
cert_class_hash = Dir.glob($root / "arch" / "certificate_class" / "**" / "*.yaml").map do |f|
307-
cert_class_obj = YAML.load_file(f, permitted_classes: [Date])
306+
cert_class_obj = YamlLoader.load(f, permitted_classes:[Date])
308307
cert_class_name = cert_class_obj.keys[0]
309308
cert_class_obj[cert_class_name]["name"] = cert_class_name
310309
cert_class_obj[cert_class_name]["__source"] = f
311310
[cert_class_name, cert_class_obj[cert_class_name]]
312311
end.to_h
313312
cert_model_hash = Dir.glob($root / "arch" / "certificate_model" / "**" / "*.yaml").map do |f|
314-
cert_model_obj = YAML.load_file(f, permitted_classes: [Date])
313+
cert_model_obj = YamlLoader.load(f, permitted_classes:[Date])
315314
cert_model_name = cert_model_obj.keys[0]
316315
cert_model_obj[cert_model_name]["name"] = cert_model_name
317316
cert_model_obj[cert_model_name]["__source"] = f
318317
[cert_model_name, cert_model_obj[cert_model_name]]
319318
end.to_h
320319
manual_hash = {}
321320
Dir.glob($root / "arch" / "manual" / "**" / "contents.yaml").map do |f|
322-
manual_version = YAML.load_file(f)
321+
manual_version = YamlLoader.load(f, permitted_classes:[Date])
323322
manual_id = manual_version["manual"]
324323
unless manual_hash.key?(manual_id)
325324
manual_info_files = Dir.glob($root / "arch" / "manual" / "**" / "#{manual_id}.yaml")
326325
raise "Could not find manual info '#{manual_id}'.yaml, needed by #{f}" if manual_info_files.empty?
327326
raise "Found multiple manual infos '#{manual_id}'.yaml, needed by #{f}" if manual_info_files.size > 1
328327

329328
manual_info_file = manual_info_files.first
330-
manual_hash[manual_id] = YAML.load_file(manual_info_file)
329+
manual_hash[manual_id] = YamlLoader.load(manual_info_file, permitted_classes:[Date])
331330
manual_hash[manual_id]["__source"] = manual_info_file
332331
# TODO: schema validation
333332
end
334333

335334
manual_hash[manual_id]["versions"] ||= []
336-
manual_hash[manual_id]["versions"] << YAML.load_file(f)
335+
manual_hash[manual_id]["versions"] << YamlLoader.load(f, permitted_classes:[Date])
337336
# TODO: schema validation
338337
manual_hash[manual_id]["versions"].last["__source"] = f
339338
end
@@ -546,99 +545,6 @@ def arch_overlay_path_for(type, name)
546545
def schema_path_for(type) = Validator::SCHEMA_PATHS[type]
547546
private :schema_path_for
548547

549-
# Render a architecture definition file and save it to gen_dir / .rendered_arch
550-
#
551-
# Will not re-render if rendered file already exists and sources have not changed
552-
#
553-
# @param type [Symbol] Type of the object (@see Validator::SCHEMA_PATHS)
554-
# @param name [#to_s] Name of the object
555-
# @param extra_env [Hash,NilObject] Optional hash with extra enviornment variables for the render
556-
# @return [Pathname,nil] Path to generated file, or nil if there is no (valid) definition for type,name
557-
def gen_rendered_arch_def(type, name, extra_env = {})
558-
gen_path = @gen_dir / ".rendered_arch" / type.to_s / "#{name}.yaml"
559-
560-
source_path = arch_path_for(type, name)
561-
return nil if source_path.nil?
562-
563-
schema_path = schema_path_for(type)
564-
565-
if gen_path.exist?
566-
# this already exists...see if we need to regenerate it
567-
dep_mtime = [File.mtime(__FILE__), source_path.mtime, schema_path.mtime].max
568-
return gen_path if gen_path.mtime >= dep_mtime # no update needed
569-
end
570-
571-
trace "Rendering architecture file for #{type}:#{name}"
572-
573-
# render the source template
574-
current_env = env.clone
575-
extra_env&.each { |k, v| current_env.define_singleton_method(k) { v } }
576-
rendered_def = Tilt["erb"].new(source_path, trim: "-").render(current_env)
577-
578-
# see if the rendering was empty, meaning that the def isn't valid in this config
579-
return nil if rendered_def.nil?
580-
581-
# write the object
582-
FileUtils.mkdir_p gen_path.dirname
583-
File.write(gen_path, rendered_def)
584-
585-
# verify
586-
begin
587-
@validator.validate_str(rendered_def, type:)
588-
rescue Validator::SchemaValidationError => e
589-
warn "#{type} definition in #{source_path} did not validate"
590-
raise e
591-
end
592-
593-
def_obj = YAML.safe_load(rendered_def)
594-
595-
raise "#{type} name ('#{name}') must match key in defintion ('#{def_obj.keys[0]}')" if name.to_s != def_obj.keys[0]
596-
597-
# return path to generated file
598-
gen_path
599-
end
600-
private :gen_rendered_arch_def
601-
602-
# Render a architecture overlay definition file and save it to gen_dir / .rendered_overlay_arch
603-
#
604-
# Will not re-render if rendered file already exists and sources have not changed
605-
#
606-
# @param type [Symbol] Type of the object (@see Validator::SCHEMA_PATHS)
607-
# @param name [#to_s] Name of the object
608-
# @param extra_env [Hash,NilObject] Optional hash with extra enviornment variables for the render
609-
# @return [Pathname] Path to generated file
610-
def gen_rendered_arch_overlay_def(type, name, extra_env = {})
611-
gen_path = @gen_dir / ".rendered_overlay_arch" / type.to_s / "#{name}.yaml"
612-
613-
source_path = arch_overlay_path_for(type, name)
614-
return nil if source_path.nil?
615-
616-
if gen_path.exist?
617-
# this already exists...see if we need to regenerate it
618-
dep_mtime = [File.mtime(__FILE__), source_path.mtime].max
619-
return gen_path if gen_path.mtime >= dep_mtime # no update needed
620-
end
621-
622-
trace "Rendering overlay file for #{type}:#{name}"
623-
624-
# render the source template
625-
current_env = env.clone
626-
extra_env&.each { |k, v| current_env.define_singleton_method(k) { v } }
627-
rendered_def = Tilt["erb"].new(source_path, trim: "-").render(current_env)
628-
629-
def_obj = YAML.safe_load(rendered_def)
630-
631-
raise "#{type} name (#{name}) must match key in defintion (#{def_obj.keys[0]})" if name.to_s != def_obj.keys[0]
632-
633-
# write the object
634-
FileUtils.mkdir_p gen_path.dirname
635-
File.write(gen_path, YAML.dump(def_obj))
636-
637-
# return path to generated file
638-
gen_path
639-
end
640-
private :gen_rendered_arch_overlay_def
641-
642548
# generate a merged definition from rendered arch and overlay, and write it to gen / .merged_arch
643549
#
644550
# Skips if gen file already exists and sources are older
@@ -666,14 +572,16 @@ def gen_merged_def(type, arch_path, overlay_path)
666572
FileUtils.mkdir_p merged_path.dirname
667573
if overlay_path.nil?
668574
# no overlay, just copy arch
669-
FileUtils.cp arch_path, merged_path
575+
merged_path.write YAML.dump(YamlLoader.load(arch_path))
576+
# FileUtils.cp arch_path, merged_path
670577
elsif arch_path.nil?
671578
# no arch, overlay is arch
672-
FileUtils.cp overlay_path, merged_path
579+
merged_path.write YAML.dump(YamlLoader.load(overlay_path))
580+
# FileUtils.cp overlay_path, merged_path
673581
else
674582
# arch and overlay, do the merge
675-
arch_obj = YAML.load_file(arch_path)
676-
overlay_obj = YAML.load_file(overlay_path)
583+
arch_obj = YamlLoader.load(arch_path)
584+
overlay_obj = YamlLoader.load(overlay_path)
677585

678586
merge(arch_obj, overlay_obj)
679587
merged_path.write YAML.dump(arch_obj)
@@ -696,8 +604,8 @@ def gen_merged_def(type, arch_path, overlay_path)
696604
# @param csr_name [#to_s] CSR name
697605
# @param extra_env [Hash] Extra enviornment variables to be used when parsing the CSR definition template
698606
def maybe_add_csr(csr_name, extra_env = {})
699-
arch_path = arch_path_for(:csr, csr_name) # gen_rendered_arch_def(:csr, csr_name, extra_env)
700-
arch_overlay_path = arch_overlay_path_for(:csr, csr_name) # gen_rendered_arch_overlay_def(:csr, csr_name, extra_env)
607+
arch_path = arch_path_for(:csr, csr_name)
608+
arch_overlay_path = arch_overlay_path_for(:csr, csr_name)
701609

702610
# return immediately if this CSR isn't defined in this config
703611
raise "No arch or overlay for sr #{csr_name}" if arch_path.nil? && arch_overlay_path.nil?
@@ -797,8 +705,8 @@ def all_known_exts
797705
end
798706

799707
def maybe_add_ext(ext_name)
800-
arch_path = arch_path_for(:ext, ext_name) # gen_rendered_arch_def(:ext, ext_name)
801-
arch_overlay_path = arch_overlay_path_for(:ext, ext_name) # gen_rendered_arch_overlay_def(:ext, ext_name)
708+
arch_path = arch_path_for(:ext, ext_name)
709+
arch_overlay_path = arch_overlay_path_for(:ext, ext_name)
802710

803711
# return immediately if this ext isn't defined
804712
return if arch_path.nil? && arch_overlay_path.nil?
@@ -884,7 +792,7 @@ def exception_codes
884792

885793
@exception_codes = {}
886794
Dir.glob(@gen_dir / "arch" / "ext" / "*.yaml") do |ext_path|
887-
ext_obj = YAML.load_file(ext_path)
795+
ext_obj = YamlLoader.load(ext_path, permitted_classes:[Date])
888796
ext_obj = ext_obj[ext_obj.keys[0]]
889797
if ext_obj.key?("exception_codes")
890798
ext_obj["exception_codes"].each do |exception_code|
@@ -905,7 +813,7 @@ def interrupt_codes
905813

906814
@interrupt_codes = {}
907815
Dir.glob(@gen_dir / "arch" / "ext" / "*.yaml") do |ext_path|
908-
ext_obj = YAML.load_file(ext_path)
816+
ext_obj = YamlLoader.load(ext_path, permitted_classes:[Date])
909817
ext_obj = ext_obj[ext_obj.keys[0]]
910818
if ext_obj.key?("interrupt_codes")
911819
ext_obj["interrupt_codes"].each do |interrupt_code|
@@ -941,8 +849,8 @@ def possible_xlens
941849
# @param inst_name [#to_s] instruction name
942850
# @param extra_env [Hash] Extra options to add into the rendering enviornment
943851
def maybe_add_inst(inst_name, extra_env = {})
944-
arch_path = arch_path_for(:inst, inst_name) # gen_rendered_arch_def(:inst, inst_name, extra_env)
945-
arch_overlay_path = arch_overlay_path_for(:inst, inst_name) # gen_rendered_arch_overlay_def(:inst, inst_name, extra_env)
852+
arch_path = arch_path_for(:inst, inst_name)
853+
arch_overlay_path = arch_overlay_path_for(:inst, inst_name)
946854

947855
# return immediately if inst isn't defined in this config
948856
raise "No arch or overlay for instruction #{inst_name}" if arch_path.nil? && arch_overlay_path.nil?

0 commit comments

Comments
 (0)