udb-gen 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 185afac7b8a6c8e7bdc766345c0963b3507e5196c3b0bf5afc50df2763607617
4
- data.tar.gz: 3176d980ea6d9792b86f27f2b3ed0f3a1ee3a952cbdd4c495a68a7a1e7a7d6df
3
+ metadata.gz: 3f2e3db34409108c4ac83f95a778d24936d06b3d5124ab6138af60020e94c740
4
+ data.tar.gz: f8274018357279d3aa28bfe47a7e77137f29d1238b73336ea8048575b23298d3
5
5
  SHA512:
6
- metadata.gz: 9af5bcc545ef8820a6bcde727b1db168a9b60d5a3185b94846fbb9b212a53aeb9b92e2faba7d55a77643004bf2295e36822be9000dbb97c586342db4859796d0
7
- data.tar.gz: 29ed9637c8140810e849db5f00632090bba16690064cd9694381843114b09871fb55016954ebd2883b9a107fed527ff40e11042ce750cce7406825d0df8da9b3
6
+ metadata.gz: 11d8d5b8a08aa3aa2490c0998ec033538643680b266267f0b1265ea0fac15605e01e0ce8b72e1000fd4eb161e47a6f245f986b5f2170064a665c326c592b7b2b
7
+ data.tar.gz: 2fec5ed54797ae271ce320c31b20b549f559477cf72d9335cc6d9fdd6ea955b12b1a16f3f9717beee13ccdde5b433e2995c6e64fdeecadc0473a78eb93f3fa23
@@ -81,7 +81,9 @@ module UdbGen
81
81
  guard_name = "UDB_CFG_#{cfg_arch.name.upcase.gsub(/[^A-Z0-9]/, "_")}#{guard_suffix}"
82
82
 
83
83
  convention_lines = [
84
+ # REUSE-IgnoreStart
84
85
  "SPDX-License-Identifier: BSD-3-Clause-Clear",
86
+ # REUSE-IgnoreEnd
85
87
  "",
86
88
  "Auto-generated by riscv-unified-db (udb-gen #{command_name})",
87
89
  "Config: #{cfg_arch.name}",
@@ -0,0 +1,81 @@
1
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
2
+ # SPDX-FileCopyrightText: Copyright (c) Charlie Jenkins
3
+
4
+ # typed: true
5
+ # frozen_string_literal: true
6
+
7
+ require "tty-exit"
8
+
9
+ require_relative "../../common_opts"
10
+ require_relative "../../defines"
11
+ require_relative "../../template_helpers"
12
+ require_relative "table_builder"
13
+
14
+ require "udb/obj/extension"
15
+
16
+ module UdbGen
17
+ class InstTableOptions < SubcommandWithCommonOptions
18
+ include TTY::Exit
19
+
20
+ NAME = "inst-table"
21
+
22
+ sig { void }
23
+ def initialize
24
+ super(name: NAME, desc: "Generate an instruction table")
25
+ end
26
+
27
+ usage \
28
+ command: NAME,
29
+ desc: "Generate an instruction table for extensions defined in UDB",
30
+ example: <<~EXAMPLE
31
+ Generate an instruction table for all extensions, printed to stdout
32
+ $ #{File.basename($PROGRAM_NAME)} #{NAME}
33
+
34
+ Generate an instruction table for all extensions, written to a file
35
+ $ #{File.basename($PROGRAM_NAME)} #{NAME} -o inst_table.txt
36
+ EXAMPLE
37
+
38
+ option :output_file do
39
+ T.bind(self, TTY::Option::Parameter::Option)
40
+ short "-o"
41
+ long "--out=file"
42
+ desc "Output file (default: stdout)"
43
+ convert :path
44
+ end
45
+
46
+ sig { void }
47
+ def gen_inst_table
48
+ target_file = params[:output_file]
49
+ builder = InstTable::TableBuilder.new(cfg_arch, target_file&.basename&.to_s)
50
+
51
+ if target_file.nil?
52
+ $stdout.write(builder.generate)
53
+ else
54
+ File.write(target_file, builder.generate)
55
+ end
56
+ end
57
+
58
+ sig { override.params(argv: T::Array[String]).returns(T.noreturn) }
59
+ def run(argv)
60
+ parse(argv)
61
+
62
+ if params[:help]
63
+ print help
64
+ exit_with(:success)
65
+ end
66
+
67
+ if params.errors.any?
68
+ exit_with(:usage_error, "#{params.errors.summary}\n\n#{help}")
69
+ end
70
+
71
+ unless params.remaining.empty?
72
+ exit_with(:usage_error, "Unknown arguments: #{params.remaining}\n")
73
+ end
74
+
75
+ gen_inst_table
76
+
77
+ exit_with(:success)
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,127 @@
1
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
2
+ # SPDX-FileCopyrightText: Copyright (c) Charlie Jenkins
3
+
4
+ # typed: false
5
+ # frozen_string_literal: true
6
+
7
+ require "pathname"
8
+ require "fileutils"
9
+ require "optparse"
10
+ require "udb/resolver"
11
+
12
+ module UdbGen
13
+ module InstTable
14
+ class TableBuilder
15
+ extend T::Sig
16
+
17
+ sig { params(arch: Udb::ConfiguredArchitecture, file_name: T.nilable(String)).void }
18
+ def initialize(arch, file_name)
19
+ @arch = arch
20
+ @file_name = file_name
21
+ end
22
+
23
+ def get_encoding(inst, base)
24
+ return [] unless inst.defined_in_base?(base)
25
+
26
+ fields = []
27
+
28
+ enc_obj = inst.encoding(base)
29
+ fixed = enc_obj.opcode_fields.map do |fo|
30
+ "#{fo.name}<#{fo.range.first}"
31
+ end
32
+
33
+ fields.append(fixed.join("|"))
34
+
35
+ dvs = inst.decode_variables(base)
36
+
37
+ dvs.each do |d|
38
+ field = "#{d.name}"
39
+
40
+ if d.sext?
41
+ field += "~"
42
+ end
43
+
44
+ unless d.excludes.empty?
45
+ field += "!#{d.excludes.join('!')}"
46
+ end
47
+
48
+ if d.left_shift > 0
49
+ field += "<#{d.left_shift}"
50
+ end
51
+
52
+ field += "=#{d.location}"
53
+
54
+ fields.append(field)
55
+ end
56
+
57
+ return fields
58
+ end
59
+
60
+ sig { returns(String) }
61
+ def generate
62
+ lines = []
63
+ @arch.instructions.each do |inst|
64
+ enc_32 = get_encoding(inst, 32)
65
+ enc_64 = get_encoding(inst, 64)
66
+
67
+ if enc_32.empty? && enc_64.empty?
68
+ puts "instruction #{inst.name} not supported by 32-bit or 64-bit"
69
+ next
70
+ end
71
+
72
+ # Same encoding for 32/64-bit
73
+ if (enc_32 == enc_64)
74
+ lines << ([inst.name, "common"] + enc_64).join(" ")
75
+ next
76
+ end
77
+
78
+ # There are some instructions that have different encodings on 32/64-bit
79
+ unless enc_32.empty? || enc_64.empty?
80
+ lines << ([inst.name, "common,32"] + enc_32).join(" ")
81
+ lines << ([inst.name, "common,64"] + enc_64).join(" ")
82
+ next
83
+ end
84
+
85
+ if enc_32.any?
86
+ lines << ([inst.name, "32"] + enc_32).join(" ")
87
+ next
88
+ end
89
+
90
+ if enc_64.any?
91
+ lines << ([inst.name, "64"] + enc_64).join(" ")
92
+ next
93
+ end
94
+ end
95
+
96
+ command = "./bin/generate inst-table"
97
+ command += " -o #{@file_name}" unless @file_name.nil?
98
+
99
+ header = <<EOM
100
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
101
+ #
102
+ # GENERATED WITH https://github.com/riscv-software-src/riscv-unified-db
103
+ # "#{command}"
104
+ #
105
+ # Each line of the instruction table should have the following format:
106
+ # NAME BASE FIXED_BITS [VARIABLE_LIST]
107
+ # NAME instruction name
108
+ # BASE instruction base size (common[,(32|64)])
109
+ # "common" means the instruction is valid on both architecture sizes
110
+ # "32" or "64" means the instruction is valid on that size
111
+ # if the instruction is valid on both architectures but has unique
112
+ # encodings, use a 32-bit entry "common,32" and 64-bit entry
113
+ # FIXED_BITS bitfields of the fixed bits of an instruction concatenated with '|'
114
+ # continuous grouping of fixed bits are in the form of 'bits<offset'
115
+ # VARIABLE_LIST a variable sized list of all variables in the instruction definition
116
+ # in the form of name[~][<num][!num...]=(high[-low])|...
117
+ # symbols after the name represent different modifiers:
118
+ # ~ sign extension, can only appear once
119
+ # < left shift by 'num' amount on extraction, can only appear once
120
+ # ! mark 'num' as an invalid input for this variable
121
+ EOM
122
+
123
+ header + lines.join("\n") + "\n"
124
+ end
125
+ end
126
+ end
127
+ end
@@ -74,7 +74,7 @@ module UdbGen
74
74
  urlPrefix = formatterParams.fetch(:urlPrefix)
75
75
  fp.write ", formatterParams:{\n"
76
76
  fp.write " labelField:\"#{column_name}\",\n"
77
- fp.write " urlPrefix:\"#{urlPrefix}\"\n"
77
+ fp.write " url: function(cell) { return \"#{urlPrefix}\" + cell.getValue().replace(/\\./g, \"_\"); }\n"
78
78
  fp.write " }\n"
79
79
  end
80
80
  fp.write " },\n"
@@ -140,7 +140,7 @@ module UdbGen
140
140
  row = [
141
141
  inst.name,
142
142
  inst.long_name,
143
- inst.name + " " + inst.assembly.gsub("x", "r")
143
+ inst.name + " " + inst.assembly
144
144
  ]
145
145
 
146
146
  sorted_releases.each do |pr|
@@ -6,6 +6,14 @@
6
6
 
7
7
  require "digest"
8
8
 
9
+ def sanitized_inst_lookup
10
+ Rake.application.instance_variable_get(:@sanitized_inst_lookup) ||
11
+ Rake.application.instance_variable_set(
12
+ :@sanitized_inst_lookup,
13
+ Rake.application.cfg_arch.instructions.each_with_object({}) { |i, h| h[i.name.sanitize] = i }
14
+ )
15
+ end
16
+
9
17
  def versions_from_env(versions)
10
18
  manual_name = "isa"
11
19
  output_hash = nil
@@ -184,11 +192,11 @@ rule %r{#{Rake.application.gen_dir}/.*/.*/antora/modules/insts/pages/.*.adoc} =>
184
192
  __FILE__,
185
193
  (UdbGen.root / "templates" / "manual" / "instruction.adoc.erb").to_s
186
194
  ] do |t|
187
- inst_name = File.basename(t.name, ".adoc")
195
+ inst_sanitized_name = File.basename(t.name, ".adoc")
188
196
 
189
197
  cfg_arch = Rake.application.cfg_arch
190
- inst = cfg_arch.instruction(inst_name)
191
- raise "Can't find instruction '#{inst_name}'" if inst.nil?
198
+ inst = sanitized_inst_lookup[inst_sanitized_name]
199
+ raise "Can't find instruction with sanitized name '#{inst_sanitized_name}'" if inst.nil?
192
200
 
193
201
  inst_template_path = UdbGen.root / "templates" / "manual" / "instruction.adoc.erb"
194
202
  erb = ERB.new(inst_template_path.read, trim_mode: "-")
@@ -406,7 +414,7 @@ namespace :gen do
406
414
 
407
415
  Udb.logger.info "Generating Instructions"
408
416
  version_obj.instructions.each do |inst|
409
- Rake::Task[antora_path / "modules" / "insts" / "pages" / "#{inst.name}.adoc"].invoke
417
+ Rake::Task[antora_path / "modules" / "insts" / "pages" / "#{inst.name.sanitize}.adoc"].invoke
410
418
  end
411
419
 
412
420
  Udb.logger.info "Generating Extensions"
@@ -5,5 +5,5 @@
5
5
  # frozen_string_literal: true
6
6
 
7
7
  module UdbGen
8
- def self.version = "0.1.12"
8
+ def self.version = "0.1.13"
9
9
  end
@@ -11,7 +11,7 @@ Synopsis::
11
11
 
12
12
  Mnemonic::
13
13
  ----
14
- <%= inst.name %> <%= inst.assembly.gsub('x', 'r') %>
14
+ <%= inst.name %> <%= inst.assembly %>
15
15
  ----
16
16
 
17
17
  Encoding::
@@ -27,7 +27,7 @@ The following <%= insts.size %> instructions must be implemented when <%= ext_re
27
27
  <%- insts.each do |i| -%>
28
28
  | <%= i.rv32? ? "&#x2713;" : "" %>
29
29
  | <%= i.rv64? ? "&#x2713;" : "" %>
30
- | `<%= [i.name, i.assembly.gsub("x", "r").strip].join(" ").strip %>`
30
+ | `<%= [i.name, i.assembly.strip].join(" ").strip %>`
31
31
  | <%= link_to(i, i.long_name) %>
32
32
  <%- if versions.size > 1 -%>
33
33
  | <%= versions.map { |v| (-i.defined_by_condition & v.to_condition_exclusive).unsatisfiable_by_arch?(cfg_arch) ? "&#x2713;" : "" }.join(" | ") %>
@@ -55,7 +55,7 @@ of this extension.
55
55
  ^ Mnemonic ^ Instruction ^ Defined by
56
56
 
57
57
  <%- implied_insts.sort.each do |i| -%>
58
- ^ `<%= [i.name, i.assembly.gsub("x", "r").strip].join(" ").strip %>`
58
+ ^ `<%= [i.name, i.assembly.strip].join(" ").strip %>`
59
59
  ^ <%= link_to(i, i.long_name) %>
60
60
  a^ <%= i.defined_by_condition.to_asciidoc %>
61
61
  <%- end -%>
@@ -17,7 +17,7 @@ This instruction must have data-independent timing when extension `Zkt` is enabl
17
17
 
18
18
  == Assembly format
19
19
 
20
- `<%= inst.name %> <%= inst.assembly.gsub('x', 'r') %>`
20
+ `<%= inst.name %> <%= inst.assembly %>`
21
21
 
22
22
  == Decode Variables
23
23
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: udb-gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Hower
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-19 00:00:00.000000000 Z
10
+ date: 2026-07-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: asciidoctor
@@ -141,14 +141,14 @@ dependencies:
141
141
  requirements:
142
142
  - - '='
143
143
  - !ruby/object:Gem::Version
144
- version: 0.1.13
144
+ version: 0.1.14
145
145
  type: :runtime
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - '='
150
150
  - !ruby/object:Gem::Version
151
- version: 0.1.13
151
+ version: 0.1.14
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: write_xlsx
154
154
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +163,20 @@ dependencies:
163
163
  - - ">="
164
164
  - !ruby/object:Gem::Version
165
165
  version: '0'
166
+ - !ruby/object:Gem::Dependency
167
+ name: mocha
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
166
180
  - !ruby/object:Gem::Dependency
167
181
  name: sorbet
168
182
  requirement: !ruby/object:Gem::Requirement
@@ -212,6 +226,8 @@ files:
212
226
  - lib/udb-gen/generators/cfg_svh_header/generator.rb
213
227
  - lib/udb-gen/generators/ext_doc/generator.rb
214
228
  - lib/udb-gen/generators/ext_doc/helpers.rb
229
+ - lib/udb-gen/generators/inst_table/generator.rb
230
+ - lib/udb-gen/generators/inst_table/table_builder.rb
215
231
  - lib/udb-gen/generators/isa_explorer/generator.rb
216
232
  - lib/udb-gen/generators/isa_explorer/js_xlsx_writer.rb
217
233
  - lib/udb-gen/generators/isa_explorer/table_builder.rb