From 3df6bcd47cd2788a79eb1581b66eb3b65e9465fb Mon Sep 17 00:00:00 2001 From: Derek Hower Date: Thu, 18 Jul 2024 13:39:31 -0700 Subject: [PATCH] Many updates: * Added pruning pass to remove dead/unreachable code * Added backend to generate an extension-specific document * Removed dependence on riscv-opcodes; all instruction .yaml files have their encoding now * Updated schema to be more version-centric with extensions * Started process of refactoring so that AstNodes don't have any irrelevant SyntaxNodes * Added some unit tests for the IDL compiler * Numerous bug fixes --- .github/workflows/regress.yml | 2 + .rubocop.yml | 2 + Gemfile | 3 + Gemfile.lock | 52 + arch/csr/mtval.yaml | 2 +- arch/csr/stval.yaml | 2 +- arch/csr/vstval.yaml | 96 + arch/ext/A.yaml | 1 + arch/ext/B.yaml | 1 + arch/ext/C.yaml | 1 + arch/ext/D.yaml | 1 + arch/ext/F.yaml | 1 + arch/ext/H.yaml | 1 + arch/ext/I.yaml | 1 + arch/ext/M.yaml | 1 + arch/ext/S.yaml | 3 +- arch/ext/Smaia.yaml | 1 + arch/ext/Smcdeleg.yaml | 1 + arch/ext/Smcntrpmf.yaml | 1 + arch/ext/Ssaia.yaml | 1 + arch/ext/Ssccfg.yaml | 1 + arch/ext/Sscofpmf.yaml | 1 + arch/ext/Sstc.yaml | 1 + arch/ext/Sv32.yaml | 1 + arch/ext/Sv39.yaml | 1 + arch/ext/Sv48.yaml | 1 + arch/ext/Sv57.yaml | 1 + arch/ext/U.yaml | 1 + arch/ext/Zaamo.yaml | 1 + arch/ext/Zalrsc.yaml | 1 + arch/ext/Zba.yaml | 1 + arch/ext/Zbb.yaml | 1 + arch/ext/Zbc.yaml | 1 + arch/ext/Zicbom.yaml | 1 + arch/ext/Zicboz.yaml | 1 + arch/ext/Zicntr.yaml | 1 + arch/ext/Zicsr.yaml | 1 + arch/ext/Zihpm.yaml | 1 + arch/ext/Zmmul.yaml | 1 + arch/inst/B/add.uw.yaml | 16 +- arch/inst/B/andn.yaml | 11 + arch/inst/B/bclr.yaml | 11 + arch/inst/B/bclri.yaml | 23 + arch/inst/B/bext.yaml | 13 + arch/inst/B/bexti.yaml | 23 + arch/inst/B/binv.yaml | 13 + arch/inst/B/binvi.yaml | 23 + arch/inst/B/bset.yaml | 13 + arch/inst/B/bseti.yaml | 23 + arch/inst/B/clmul.yaml | 13 + arch/inst/B/clmulh.yaml | 13 + arch/inst/B/clmulr.yaml | 13 + arch/inst/B/clz.yaml | 11 + arch/inst/B/clzw.yaml | 11 + arch/inst/B/cpop.yaml | 11 + arch/inst/B/cpopw.yaml | 11 + arch/inst/B/ctz.yaml | 11 + arch/inst/B/ctzw.yaml | 11 + arch/inst/B/max.yaml | 13 + arch/inst/B/maxu.yaml | 13 + arch/inst/B/min.yaml | 13 + arch/inst/B/minu.yaml | 13 + arch/inst/B/orc.b.yaml | 11 + arch/inst/B/orn.yaml | 13 + arch/inst/B/rev8.yaml | 22 +- arch/inst/B/rol.yaml | 13 + arch/inst/B/rolw.yaml | 13 + arch/inst/B/ror.yaml | 13 + arch/inst/B/rori.yaml | 23 + arch/inst/B/roriw.yaml | 13 + arch/inst/B/rorw.yaml | 13 + arch/inst/B/sext.b.yaml | 11 + arch/inst/B/sext.h.yaml | 11 + arch/inst/B/sh1add.uw.yaml | 13 + arch/inst/B/sh1add.yaml | 13 + arch/inst/B/sh2add.uw.yaml | 13 + arch/inst/B/sh2add.yaml | 13 + arch/inst/B/sh3add.uw.yaml | 13 + arch/inst/B/sh3add.yaml | 13 + arch/inst/B/slli.uw.yaml | 13 + arch/inst/B/xnor.yaml | 13 + arch/inst/B/zext.h.yaml | 12 +- arch/inst/F/fmv.w.x.yaml | 7 + arch/inst/I/add.yaml | 11 +- arch/inst/I/addi.yaml | 9 + arch/inst/I/addiw.yaml | 9 + arch/inst/I/addw.yaml | 9 + arch/inst/I/and.yaml | 9 + arch/inst/I/andi.yaml | 9 + arch/inst/I/auipc.yaml | 8 + arch/inst/I/beq.yaml | 10 + arch/inst/I/bge.yaml | 10 + arch/inst/I/bgeu.yaml | 10 + arch/inst/I/blt.yaml | 10 + arch/inst/I/bltu.yaml | 10 + arch/inst/I/bne.yaml | 10 + arch/inst/I/ebreak.yaml | 4 +- arch/inst/I/ecall.yaml | 8 +- arch/inst/I/fence.yaml | 13 + arch/inst/I/jal.yaml | 4 +- arch/inst/I/jalr.yaml | 9 + arch/inst/I/lb.yaml | 9 + arch/inst/I/lbu.yaml | 9 + arch/inst/I/ld.yaml | 9 + arch/inst/I/lh.yaml | 9 + arch/inst/I/lhu.yaml | 9 + arch/inst/I/lui.yaml | 8 + arch/inst/I/lw.yaml | 9 + arch/inst/I/lwu.yaml | 9 + arch/inst/I/mret.yaml | 2 + arch/inst/I/or.yaml | 9 + arch/inst/I/ori.yaml | 9 + arch/inst/I/sb.yaml | 9 + arch/inst/I/sd.yaml | 4 +- arch/inst/I/sh.yaml | 9 + arch/inst/I/sll.yaml | 11 +- arch/inst/I/slli.yaml | 19 + arch/inst/I/slliw.yaml | 9 + arch/inst/I/sllw.yaml | 9 + arch/inst/I/slt.yaml | 9 + arch/inst/I/slti.yaml | 9 + arch/inst/I/sltiu.yaml | 9 + arch/inst/I/sltu.yaml | 9 + arch/inst/I/sra.yaml | 11 +- arch/inst/I/srai.yaml | 19 + arch/inst/I/sraiw.yaml | 9 + arch/inst/I/sraw.yaml | 9 + arch/inst/I/srl.yaml | 9 + arch/inst/I/srli.yaml | 19 + arch/inst/I/srliw.yaml | 9 + arch/inst/I/srlw.yaml | 9 + arch/inst/I/sub.yaml | 9 + arch/inst/I/subw.yaml | 9 + arch/inst/I/sw.yaml | 9 + arch/inst/I/wfi.yaml | 10 +- arch/inst/I/xor.yaml | 9 + arch/inst/I/xori.yaml | 9 + arch/inst/M/div.yaml | 13 + arch/inst/M/divu.yaml | 13 + arch/inst/M/divuw.yaml | 13 + arch/inst/M/divw.yaml | 13 + arch/inst/M/mul.yaml | 13 + arch/inst/M/mulh.yaml | 19 +- arch/inst/M/mulhsu.yaml | 19 +- arch/inst/M/mulhu.yaml | 19 +- arch/inst/M/mulw.yaml | 13 + arch/inst/M/rem.yaml | 13 + arch/inst/M/remu.yaml | 13 + arch/inst/M/remuw.yaml | 13 + arch/inst/M/remw.yaml | 13 + arch/inst/S/sfence.vma.yaml | 7 + arch/inst/S/sret.yaml | 22 +- arch/inst/Zicbom/cbo.clean.yaml | 5 + arch/inst/Zicbom/cbo.flush.yaml | 5 + arch/inst/Zicbom/cbo.inval.yaml | 5 + arch/inst/Zicboz/cbo.zero.yaml | 5 + arch/inst/Zicsr/csrrs.yaml | 9 + arch/inst/Zicsr/csrrw.yaml | 9 + arch/inst/Zicsr/csrrwi.yaml | 11 +- arch/isa/globals.isa | 312 ++- arch/prose/idl.adoc | 6 +- cfgs/config_validation.rb | 30 + .../arch_overlay/ext/Xcustom.yaml | 1 + cfgs/generic_rv64/params.yaml | 42 +- docs/ruby/ArchDef.html | 504 +++-- docs/ruby/ArchDefObject.html | 30 +- docs/ruby/ArchGen.html | 2 +- docs/ruby/Csr.html | 310 ++- docs/ruby/CsrField.html | 208 +- docs/ruby/CsrField/Alias.html | 10 +- docs/ruby/DecodeField.html | 2 +- docs/ruby/DecodeVariable.html | 2 +- docs/ruby/EncodingField.html | 2 +- docs/ruby/Extension.html | 42 +- docs/ruby/ExtensionVersion.html | 98 +- docs/ruby/Idl.html | 8 +- docs/ruby/Idl/ArrayLiteralAst.html | 175 +- docs/ruby/Idl/AryElementAccessAst.html | 462 ++++- docs/ruby/Idl/AryElementAssignmentAst.html | 118 +- docs/ruby/Idl/AryRangeAccessAst.html | 579 +++++- docs/ruby/Idl/AryRangeAssignmentAst.html | 114 +- docs/ruby/Idl/AssignmentAst.html | 20 +- docs/ruby/Idl/AstNode.html | 4 +- docs/ruby/Idl/AstNode/InternalError.html | 40 +- docs/ruby/Idl/AstNode/TypeError.html | 40 +- docs/ruby/Idl/AstNode/ValueError.html | 30 +- docs/ruby/Idl/AstNodeFuncs.html | 144 +- docs/ruby/Idl/BinaryExpressionAst.html | 810 ++++++-- .../ruby/Idl/BitfieldAccessExpressionAst.html | 245 ++- docs/ruby/Idl/BitfieldDefinitionAst.html | 195 +- docs/ruby/Idl/BitfieldType.html | 60 +- docs/ruby/Idl/BitsCastAst.html | 209 +- docs/ruby/Idl/BitsTypeAst.html | 113 +- docs/ruby/Idl/BuiltinEnumDefinitionAst.html | 22 +- docs/ruby/Idl/BuiltinTypeNameAst.html | 123 +- docs/ruby/Idl/Compiler.html | 128 +- docs/ruby/Idl/ConcatenationExpressionAst.html | 199 +- .../Idl/ConditionalReturnStatementAst.html | 98 +- docs/ruby/Idl/ConditionalStatementAst.html | 471 ++++- docs/ruby/Idl/CsrFieldReadExpressionAst.html | 319 ++- docs/ruby/Idl/CsrReadExpressionAst.html | 439 +++- docs/ruby/Idl/CsrSoftwareReadAst.html | 276 ++- docs/ruby/Idl/CsrSoftwareWriteAst.html | 172 +- docs/ruby/Idl/CsrType.html | 26 +- docs/ruby/Idl/CsrWriteAst.html | 368 +++- docs/ruby/Idl/DontCareLvalueAst.html | 151 +- docs/ruby/Idl/DontCareReturnAst.html | 181 +- docs/ruby/Idl/EnumDefinitionAst.html | 199 +- docs/ruby/Idl/EnumRefAst.html | 169 +- docs/ruby/Idl/EnumerationType.html | 74 +- docs/ruby/Idl/Executable.html | 10 +- docs/ruby/Idl/ExecutionCommentAst.html | 6 +- docs/ruby/Idl/FieldAssignmentAst.html | 132 +- docs/ruby/Idl/FieldNameAst.html | 91 +- docs/ruby/Idl/ForLoopAst.html | 289 ++- docs/ruby/Idl/FunctionBodyAst.html | 478 +++-- docs/ruby/Idl/FunctionCallExpressionAst.html | 500 +++-- docs/ruby/Idl/FunctionDefAst.html | 830 ++++---- docs/ruby/Idl/FunctionStatementAst.html | 10 +- docs/ruby/Idl/FunctionType.html | 314 +-- docs/ruby/Idl/GlobalAst.html | 18 +- .../ruby/Idl/GlobalWithInitializationAst.html | 36 +- docs/ruby/Idl/IdAst.html | 175 +- docs/ruby/Idl/IfAst.html | 1147 ++++++++--- docs/ruby/Idl/InstructionOperationAst.html | 74 +- docs/ruby/Idl/IntAst.html | 541 ++++- docs/ruby/Idl/IsaAst.html | 134 +- docs/ruby/Idl/MultiVariableAssignmentAst.html | 110 +- .../ruby/Idl/MultiVariableDeclarationAst.html | 122 +- docs/ruby/Idl/ParenExpressionAst.html | 147 +- docs/ruby/Idl/PostDecrementExpressionAst.html | 38 +- docs/ruby/Idl/PostIncrementExpressionAst.html | 42 +- docs/ruby/Idl/ReplicationExpressionAst.html | 181 +- docs/ruby/Idl/ReturnStatementAst.html | 338 +++- docs/ruby/Idl/Returns.html | 78 +- docs/ruby/Idl/Rvalue.html | 139 +- docs/ruby/Idl/SignCastAst.html | 169 +- docs/ruby/Idl/StatementAst.html | 389 +++- docs/ruby/Idl/SymbolTable.html | 943 +++++++-- .../Idl/SymbolTable/DuplicateSymError.html | 2 +- .../Idl/TernaryOperatorExpressionAst.html | 267 ++- docs/ruby/Idl/Type.html | 458 +++-- docs/ruby/Idl/UnaryOperatorExpressionAst.html | 245 ++- docs/ruby/Idl/UserTypeNameAst.html | 26 +- docs/ruby/Idl/Var.html | 343 +++- docs/ruby/Idl/VarReadExpressionAst.html | 181 +- docs/ruby/Idl/VariableAssignmentAst.html | 124 +- docs/ruby/Idl/VariableDeclarationAst.html | 207 +- ...iableDeclarationWithInitializationAst.html | 446 +++- docs/ruby/Idl/XregType.html | 26 +- docs/ruby/Instruction.html | 264 ++- docs/ruby/Instruction/Encoding.html | 74 +- docs/ruby/Instruction/Encoding/Field.html | 36 +- docs/ruby/Opcodes.html | 2 +- docs/ruby/RiscvOpcodes.html | 2 +- docs/ruby/Treetop.html | 4 +- docs/ruby/Treetop/Runtime.html | 4 +- docs/ruby/Treetop/Runtime/CompiledParser.html | 2 +- docs/ruby/Treetop/Runtime/SyntaxNode.html | 422 ++-- docs/ruby/Validator.html | 2 +- docs/ruby/Validator/SchemaError.html | 2 +- docs/ruby/Validator/ValidationError.html | 2 +- docs/ruby/_index.html | 96 +- docs/ruby/class_list.html | 2 +- docs/ruby/file.README.html | 67 +- docs/ruby/index.html | 67 +- docs/ruby/method_list.html | 1426 +++++++++---- docs/ruby/top-level-namespace.html | 4 +- lib/arch_def.rb | 438 ++-- lib/arch_gen.rb | 68 +- lib/idl.rb | 85 +- lib/idl/ast.rb | 1787 ++++++++++++----- lib/idl/idl.treetop | 134 +- lib/idl/passes/gen_adoc.rb | 250 ++- lib/idl/passes/prune.rb | 223 ++ lib/idl/symbol_table.rb | 2 +- lib/idl/tests/helpers.rb | 23 + lib/idl/tests/test_expressions.rb | 129 ++ lib/idl/tests/test_variables.rb | 22 + lib/idl/type.rb | 41 +- lib/opcodes.rb | 11 +- schemas/config_schema.json | 208 +- schemas/ext_schema.json | 92 +- schemas/inst_schema.json | 47 +- schemas/schema_defs.json | 34 +- tasks/adoc_gen.rake | 2 + tasks/ext_pdf_gen.rake | 95 + tasks/html_gen.rake | 16 +- tasks/top.rake | 6 + views/adoc/csr.adoc.erb | 2 +- views/adoc/ext.adoc.erb | 6 +- views/adoc/ext_pdf.adoc.erb | 193 ++ views/adoc/func.adoc.erb | 19 +- views/adoc/inst.adoc.erb | 26 +- views/adoc/toc.adoc.erb | 6 +- 295 files changed, 20052 insertions(+), 6150 deletions(-) create mode 100644 arch/csr/vstval.yaml create mode 100644 lib/idl/passes/prune.rb create mode 100644 lib/idl/tests/helpers.rb create mode 100644 lib/idl/tests/test_expressions.rb create mode 100644 lib/idl/tests/test_variables.rb create mode 100644 tasks/ext_pdf_gen.rake create mode 100644 views/adoc/ext_pdf.adoc.erb diff --git a/.github/workflows/regress.yml b/.github/workflows/regress.yml index b34a18dc4..aea0b81a6 100644 --- a/.github/workflows/regress.yml +++ b/.github/workflows/regress.yml @@ -14,5 +14,7 @@ jobs: uses: eWaterCycle/setup-apptainer@v2.0.0 - name: Setup project run: apptainer run --home ${{ github.workspace }}/.home oras://docker.io/riscvintl/spec-generator:0.1 ./bin/setup + - name: Run IDL tests + run: ./do idl_test - name: Build html documentation for generic_rv64 run: apptainer run --home ${{ github.workspace }}/.home oras://docker.io/riscvintl/spec-generator:0.1 bundle exec rake gen:html[generic_rv64] diff --git a/.rubocop.yml b/.rubocop.yml index bc0890133..ca2d2a8fd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +require: rubocop-minitest + AllCops: TargetRubyVersion: 3.2.3 diff --git a/Gemfile b/Gemfile index 13598962a..e2d8a24e7 100644 --- a/Gemfile +++ b/Gemfile @@ -6,9 +6,11 @@ source "https://rubygems.org" gem "asciidoctor-diagram", "~> 2.2" gem "asciidoctor-multipage" +gem "asciidoctor-pdf" gem "base64" gem "bigdecimal" gem "json_schemer", "~> 1.0" +gem "minitest" gem "rake", "~> 13.0" gem "slim", "~> 5.1" gem "treetop", "1.6.12" @@ -17,4 +19,5 @@ gem "yard" group :development do gem "solargraph" + gem 'rubocop-minitest' end diff --git a/Gemfile.lock b/Gemfile.lock index c42a4f193..aee88f915 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,10 @@ GEM remote: https://rubygems.org/ specs: + Ascii85 (1.1.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + afm (0.2.2) asciidoctor (2.0.23) asciidoctor-diagram (2.3.0) asciidoctor (>= 1.5.7, < 3.x) @@ -13,14 +17,28 @@ GEM asciidoctor-diagram-batik (~> 1.17) asciidoctor-multipage (0.0.19) asciidoctor (>= 2.0.11, < 2.1) + asciidoctor-pdf (2.3.14) + asciidoctor (~> 2.0) + concurrent-ruby (~> 1.1) + matrix (~> 0.4) + prawn (~> 2.4.0) + prawn-icon (~> 3.0.0) + prawn-svg (~> 0.34.0) + prawn-table (~> 0.2.0) + prawn-templates (~> 0.1.0) + treetop (~> 1.6.0) ast (2.4.2) backport (1.2.0) base64 (0.2.0) benchmark (0.3.0) bigdecimal (3.1.8) + concurrent-ruby (1.3.3) + css_parser (1.17.1) + addressable diff-lcs (1.5.1) e2mmap (0.1.0) hana (1.3.7) + hashery (2.1.2) jaro_winkler (1.6.0) json (2.7.2) json_schemer (1.0.3) @@ -32,13 +50,38 @@ GEM kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) + matrix (0.4.2) + minitest (5.24.1) nokogiri (1.16.5-x86_64-linux) racc (~> 1.4) parallel (1.24.0) parser (3.3.2.0) ast (~> 2.4.1) racc + pdf-core (0.9.0) + pdf-reader (2.12.0) + Ascii85 (~> 1.0) + afm (~> 0.2.1) + hashery (~> 2.0) + ruby-rc4 + ttfunk polyglot (0.3.5) + prawn (2.4.0) + pdf-core (~> 0.9.0) + ttfunk (~> 1.7) + prawn-icon (3.0.0) + prawn (>= 1.1.0, < 3.0.0) + prawn-svg (0.34.2) + css_parser (~> 1.6) + matrix (~> 0.4.2) + prawn (>= 0.11.1, < 3) + rexml (~> 3.2) + prawn-table (0.2.2) + prawn (>= 1.3.0, < 3.0.0) + prawn-templates (0.1.2) + pdf-reader (~> 2.0) + prawn (~> 2.2) + public_suffix (6.0.0) racc (1.8.0) rainbow (3.1.1) rake (13.2.1) @@ -61,7 +104,11 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) + rubocop-minitest (0.35.1) + rubocop (>= 1.61, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) + ruby-rc4 (0.1.5) simpleidn (0.2.3) slim (5.2.1) temple (~> 0.10.0) @@ -88,6 +135,8 @@ GEM tilt (2.3.0) treetop (1.6.12) polyglot (~> 0.3) + ttfunk (1.8.0) + bigdecimal (~> 3.1) unicode-display_width (2.5.0) webrick (1.8.1) yard (0.9.36) @@ -98,10 +147,13 @@ PLATFORMS DEPENDENCIES asciidoctor-diagram (~> 2.2) asciidoctor-multipage + asciidoctor-pdf base64 bigdecimal json_schemer (~> 1.0) + minitest rake (~> 13.0) + rubocop-minitest slim (~> 5.1) solargraph treetop (= 1.6.12) diff --git a/arch/csr/mtval.yaml b/arch/csr/mtval.yaml index 217119e65..d2222d5c5 100644 --- a/arch/csr/mtval.yaml +++ b/arch/csr/mtval.yaml @@ -22,7 +22,7 @@ mtval: ! [1] Instruction access fault ! The <% if ext?(:C) %> portion of the <% end %> virtual PC causing the access fault <%- unless ext?(:C) -%>(same as the value written to `mepc`)<%- end -%>. ! [2] Illegal Instruction ! The encoding of the illegal instruction. ! [3] Breakpoint - ! <%- if REPORT_EBREAK_PC_IN_TVAL -%> + ! <%- if REPORT_VA_IN_MTVAL_ON_BREAKPOINT -%> When caused by an EBREAK instruction, the virtual PC of the breakpoint instruction. <%- else -%> When caused by an EBREAK instruction, zero. diff --git a/arch/csr/stval.yaml b/arch/csr/stval.yaml index 6f297e6d2..52be3f540 100644 --- a/arch/csr/stval.yaml +++ b/arch/csr/stval.yaml @@ -22,7 +22,7 @@ stval: ! [1] Instruction access fault ! The <% if ext?(:C) %> portion of the <% end %> virtual PC causing the access fault <%- unless ext?(:C) -%>(same as the value written to `mepc`)<%- end -%>. ! [2] Illegal Instruction ! The encoding of the illegal instruction. ! [3] Breakpoint - ! <%- if REPORT_EBREAK_PC_IN_TVAL -%> + ! <%- if REPORT_VA_IN_STVAL_ON_BREAKPOINT -%> When caused by an EBREAK instruction, the virtual PC of the breakpoint instruction. <%- else -%> When caused by an EBREAK instruction, zero. diff --git a/arch/csr/vstval.yaml b/arch/csr/vstval.yaml new file mode 100644 index 000000000..a02d7ea61 --- /dev/null +++ b/arch/csr/vstval.yaml @@ -0,0 +1,96 @@ +# yaml-language-server: $schema=../../schemas/csr_schema.json + +vstval: + long_name: Virtual supervisor Trap Value + address: 0x243 + virtual_address: 0x143 + description: Holds trap-specific information + priv_mode: S + length: VSXLEN + definedBy: H + fields: + VALUE: + location_rv32: 31-0 + location_rv64: 63-0 + description: | + Written with trap-specific information when a trap is taken into VS-mode. + + The values are: + + !=== + ! Exception type ! Value + + ! [0] Instruction address misaligned ! The misaligned virtual PC (same as the value written to `mepc`). + ! [1] Instruction access fault ! The <% if ext?(:C) %> portion of the <% end %> virtual PC causing the access fault <%- unless ext?(:C) -%>(same as the value written to `mepc`)<%- end -%>. + ! [2] Illegal Instruction ! The encoding of the illegal instruction. + ! [3] Breakpoint + ! <%- if REPORT_VA_IN_STVAL_ON_BREAKPOINT -%> + When caused by an EBREAK instruction, the virtual PC of the breakpoint instruction. + <%- else -%> + When caused by an EBREAK instruction, zero. + <%- end -%> + + When caused by a data address (_i.e._, watchpoint) breakpoint, the faulting virtual address. + When caused by an instruction address breakpoint, the faulting virtual PC. + ! [4] Load address misaligned ! The misaligned virtual load address. + ! [5] Load access fault + ! The part of virtual load address causing in the access fault. + + When the load is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte load is equally split across a page and the fault occurs on the second page, + address + 4 is reported). + + (Even though the access fault arises on a physical address, the virtual address is reported) + ! [6] Store/AMO address misaligned ! The misaligned virtual store/AMO address. + ! [7] Store/AMO access fault + ! The virtual store/AMO address causing the access fault. + + When the store/AMO is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte store is equally split across a page and the fault occurs on the second page, + address + 4 is reported). + + (Even though the access fault arises on a physical address, the virtual address is reported) + ! [8] Environment call from U-mode <% if ext?(:H) %>or VU-mode<% end %> ! Zero + ! [9] Environment call from (H)S-mode ! Zero + <%- if ext?(:H) -%> + ! [10] Environment call from VS-mode ! Zero + <%- end -%> + ! [12] Instruction page fault + ! The <% if ext?(:C) %> portion of the <% end %> virtual PC causing the page fault + <% unless ext?(:C) %>(same as the value written to `mepc`)<% end %>. + ! [13] Load page fault + ! The part of the virtual load address causing in the page fault. + + When the load is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte load is equally split across a page and the fault occurs on the second page, address + 4 is reported). + ! [15] Store/AMO page fault + ! The virtual store/AMO address causing in the page fault. + + When the store/AMO is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte store is equally split across a page and the fault occurs on the second page, address + 4 is reported). + <%- if ext?(:H) -%> + ! [20] Instruction guest-page fault + ! The <% if ext?(:C) %> portion of the <% end %> virtual PC causing the fault <% unless ext?(:C) %>(same as the value written to `mepc`)<% end %>. + + The guest physical address is reported in `mtval2`. + ! [21] Load guest-page fault + ! The part of the virtual address causing the fault. + + When the load is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte load is equally split across a page and the fault occurs on the second page, address + 4 is reported). + + The guest physical address is reported in `mtval2`. + ! [22] Virutal instruction + ! The encoding of the faulting virtual instruction. + ! [23] Store/AMO guest-page fault + ! The part of the virtual address causing the fault. + + When the store/AMO is misaligned, the reported value is the smallest address on the page causing a fault + (_e.g._, if an 8-byte store is equally split across a page and the fault occurs on the second page, address + 4 is reported). + + The guest physical address is reported in `htval`. + <%- end -%> + !=== + + type: RW-H + reset_value: 0 diff --git a/arch/ext/A.yaml b/arch/ext/A.yaml index c889fb64f..8aeab5392 100644 --- a/arch/ext/A.yaml +++ b/arch/ext/A.yaml @@ -4,6 +4,7 @@ A: type: unprivileged versions: - version: 2.1 + state: ratified ratification_date: 2019-12 implies: - [Zaamo, 1.0] diff --git a/arch/ext/B.yaml b/arch/ext/B.yaml index fa9b981c6..98225589a 100644 --- a/arch/ext/B.yaml +++ b/arch/ext/B.yaml @@ -4,6 +4,7 @@ B: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2024-04 url: https://drive.google.com/file/d/1SgLoasaBjs5WboQMaU3wpHkjUwV71UZn/view implies: diff --git a/arch/ext/C.yaml b/arch/ext/C.yaml index 05ba14b75..7468e3950 100644 --- a/arch/ext/C.yaml +++ b/arch/ext/C.yaml @@ -4,6 +4,7 @@ C: type: unprivileged versions: - version: 2.2 + state: ratified ratification_date: 2019-12 description: | The `C` extension reduces static and dynamic code size by diff --git a/arch/ext/D.yaml b/arch/ext/D.yaml index b2b1d0289..626e4e0e8 100644 --- a/arch/ext/D.yaml +++ b/arch/ext/D.yaml @@ -4,6 +4,7 @@ D: type: unprivileged versions: - version: 2.2 + state: ratified ratification_date: 2019-12 changes: Define NaN-boxing scheme, changed definition of FMAX and FMIN implies: [F, 2.2] diff --git a/arch/ext/F.yaml b/arch/ext/F.yaml index d9805d841..16c224648 100644 --- a/arch/ext/F.yaml +++ b/arch/ext/F.yaml @@ -4,6 +4,7 @@ F: type: unprivileged versions: - version: 2.2 + state: ratified ratification_date: 2019-12 changes: Define NaN-boxing scheme, changed definition of FMAX and FMIN description: | diff --git a/arch/ext/H.yaml b/arch/ext/H.yaml index 6daf63d9e..83daea8b3 100644 --- a/arch/ext/H.yaml +++ b/arch/ext/H.yaml @@ -4,6 +4,7 @@ H: type: privileged versions: - version: 1.0 + state: ratified ratification_date: 2019-12 requires: [S, '>= 1.12'] interrupt_codes: diff --git a/arch/ext/I.yaml b/arch/ext/I.yaml index a3ca6d4cb..a1197bdb2 100644 --- a/arch/ext/I.yaml +++ b/arch/ext/I.yaml @@ -4,6 +4,7 @@ I: type: unprivileged versions: - version: 2.1 + state: ratified ratification_date: 2019-06 changes: atified RVWMO memory model and exclusion of FENCE.I, counters, and CSR instructions that were in previous base ISA description: | diff --git a/arch/ext/M.yaml b/arch/ext/M.yaml index 48f13d8fb..46881e086 100644 --- a/arch/ext/M.yaml +++ b/arch/ext/M.yaml @@ -4,6 +4,7 @@ M: type: unprivileged versions: - version: 2.0 + state: ratified ratification_date: 2019-12 description: | This chapter describes the standard integer multiplication and division diff --git a/arch/ext/S.yaml b/arch/ext/S.yaml index 67bfb1aae..2c5a5bc37 100644 --- a/arch/ext/S.yaml +++ b/arch/ext/S.yaml @@ -4,8 +4,9 @@ S: type: privileged versions: - version: 1.12 + state: ratified ratification_date: 2019-12 - requires: [U, 1.12] + requires: [U, "= 1.12"] description: | This chapter describes the RISC-V supervisor-level architecture, which contains a common core that is used with various supervisor-level diff --git a/arch/ext/Smaia.yaml b/arch/ext/Smaia.yaml index e52de05df..090868454 100644 --- a/arch/ext/Smaia.yaml +++ b/arch/ext/Smaia.yaml @@ -5,5 +5,6 @@ Smaia: type: privileged versions: - version: 1.0 + state: ratified ratification_date: 2023-06 url: https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf diff --git a/arch/ext/Smcdeleg.yaml b/arch/ext/Smcdeleg.yaml index e35012472..d6c4fe7e8 100644 --- a/arch/ext/Smcdeleg.yaml +++ b/arch/ext/Smcdeleg.yaml @@ -5,5 +5,6 @@ Smcdeleg: type: privileged versions: - version: 0 + state: ratified ratification_date: null url: https://docs.google.com/document/d/1s-GeH5XpHBLzbQZucA8DPA7vvF7Xvf_nrPbrU2YLBcE/edit#heading=h.yyrgtolcaczx diff --git a/arch/ext/Smcntrpmf.yaml b/arch/ext/Smcntrpmf.yaml index d8b718c54..6719a6812 100644 --- a/arch/ext/Smcntrpmf.yaml +++ b/arch/ext/Smcntrpmf.yaml @@ -5,5 +5,6 @@ Smcntrpmf: type: privileged versions: - version: 1.0 + state: ratified ratification_date: 2023-08 url: https://github.com/riscv/riscv-smcntrpmf/releases/download/v1.0_rc4-frozen/riscv-smcntrpmf-v1.0_rc4.pdf diff --git a/arch/ext/Ssaia.yaml b/arch/ext/Ssaia.yaml index ae4f3a155..49a5218d2 100644 --- a/arch/ext/Ssaia.yaml +++ b/arch/ext/Ssaia.yaml @@ -5,6 +5,7 @@ Ssaia: type: privileged versions: - version: 1.0 + state: ratified ratification_date: 2023-06 url: https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf requires: [S, ">= 1.12"] diff --git a/arch/ext/Ssccfg.yaml b/arch/ext/Ssccfg.yaml index 70b47dc5d..04261f5c2 100644 --- a/arch/ext/Ssccfg.yaml +++ b/arch/ext/Ssccfg.yaml @@ -5,5 +5,6 @@ Ssccfg: type: privileged versions: - version: 0 + state: ratified ratification_date: null url: https://docs.google.com/document/d/1s-GeH5XpHBLzbQZucA8DPA7vvF7Xvf_nrPbrU2YLBcE/edit#heading=h.yyrgtolcaczx diff --git a/arch/ext/Sscofpmf.yaml b/arch/ext/Sscofpmf.yaml index 5755c3973..cc67f3b0b 100644 --- a/arch/ext/Sscofpmf.yaml +++ b/arch/ext/Sscofpmf.yaml @@ -5,5 +5,6 @@ Sscofpmf: type: privileged versions: - version: 1.0 + state: ratified ratification_date: 2023-08 url: https://drive.google.com/file/d/1KcjgbLM5L1ZKY8934aJl8aQwGlMz6Cbo/view?usp=drive_link diff --git a/arch/ext/Sstc.yaml b/arch/ext/Sstc.yaml index a25987372..8b11436b7 100644 --- a/arch/ext/Sstc.yaml +++ b/arch/ext/Sstc.yaml @@ -5,5 +5,6 @@ Sstc: type: privileged versions: - version: 0.9 + state: ratified ratification_date: null url: https://drive.google.com/file/d/1m84Re2yK8m_vbW7TspvevCDR82MOBaSX/view?usp=drive_link diff --git a/arch/ext/Sv32.yaml b/arch/ext/Sv32.yaml index cb5dfc853..251d3779b 100644 --- a/arch/ext/Sv32.yaml +++ b/arch/ext/Sv32.yaml @@ -5,5 +5,6 @@ Sv32: type: privileged versions: - version: 1.12 + state: ratified ratification_date: unknown url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf diff --git a/arch/ext/Sv39.yaml b/arch/ext/Sv39.yaml index 416eb04fe..f3ef68b2a 100644 --- a/arch/ext/Sv39.yaml +++ b/arch/ext/Sv39.yaml @@ -5,5 +5,6 @@ Sv39: type: privileged versions: - version: 1.12 + state: ratified ratification_date: unknown url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf diff --git a/arch/ext/Sv48.yaml b/arch/ext/Sv48.yaml index cd5ef2b11..b522e5af7 100644 --- a/arch/ext/Sv48.yaml +++ b/arch/ext/Sv48.yaml @@ -5,6 +5,7 @@ Sv48: type: privileged versions: - version: 1.12 + state: ratified ratification_date: unknown url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf requires: [Sv39, ">= 1.12"] diff --git a/arch/ext/Sv57.yaml b/arch/ext/Sv57.yaml index e55ca2f26..e25626ea6 100644 --- a/arch/ext/Sv57.yaml +++ b/arch/ext/Sv57.yaml @@ -5,6 +5,7 @@ Sv57: type: privileged versions: - version: 1.12 + state: ratified ratification_date: unknown url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf requires: [Sv48, ">= 1.12"] diff --git a/arch/ext/U.yaml b/arch/ext/U.yaml index 343164626..ce24796cc 100644 --- a/arch/ext/U.yaml +++ b/arch/ext/U.yaml @@ -5,4 +5,5 @@ U: type: privileged versions: - version: 1.12 + state: ratified ratification_date: 2019-12 diff --git a/arch/ext/Zaamo.yaml b/arch/ext/Zaamo.yaml index 0a18d25c7..37e23565e 100644 --- a/arch/ext/Zaamo.yaml +++ b/arch/ext/Zaamo.yaml @@ -4,6 +4,7 @@ Zaamo: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2024-04 description: | The atomic memory operation (AMO) instructions perform read-modify-write diff --git a/arch/ext/Zalrsc.yaml b/arch/ext/Zalrsc.yaml index b7006a68d..4a0f9bd28 100644 --- a/arch/ext/Zalrsc.yaml +++ b/arch/ext/Zalrsc.yaml @@ -4,6 +4,7 @@ Zalrsc: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2024-04 description: | diff --git a/arch/ext/Zba.yaml b/arch/ext/Zba.yaml index 785c14490..89bd4ab76 100644 --- a/arch/ext/Zba.yaml +++ b/arch/ext/Zba.yaml @@ -18,4 +18,5 @@ Zba: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2021-06 diff --git a/arch/ext/Zbb.yaml b/arch/ext/Zbb.yaml index 8ff5e9d5b..a115d783d 100644 --- a/arch/ext/Zbb.yaml +++ b/arch/ext/Zbb.yaml @@ -6,4 +6,5 @@ Zbb: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2021-06 diff --git a/arch/ext/Zbc.yaml b/arch/ext/Zbc.yaml index 63ad1efc4..c812ab1a7 100644 --- a/arch/ext/Zbc.yaml +++ b/arch/ext/Zbc.yaml @@ -6,4 +6,5 @@ Zbc: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2021-06 diff --git a/arch/ext/Zicbom.yaml b/arch/ext/Zicbom.yaml index 90177d1e8..d59644fe7 100644 --- a/arch/ext/Zicbom.yaml +++ b/arch/ext/Zicbom.yaml @@ -5,4 +5,5 @@ Zicbom: type: unprivileged versions: - version: 1.0.1-b34ea8a + state: ratified ratification_date: 2022-05 diff --git a/arch/ext/Zicboz.yaml b/arch/ext/Zicboz.yaml index 3df7c1669..4db1cda01 100644 --- a/arch/ext/Zicboz.yaml +++ b/arch/ext/Zicboz.yaml @@ -5,4 +5,5 @@ Zicboz: type: unprivileged versions: - version: 1.0.1-b34ea8a + state: ratified ratification_date: 2022-05 diff --git a/arch/ext/Zicntr.yaml b/arch/ext/Zicntr.yaml index 26db173aa..6ba295262 100644 --- a/arch/ext/Zicntr.yaml +++ b/arch/ext/Zicntr.yaml @@ -5,5 +5,6 @@ Zicntr: type: unprivileged versions: - version: 2.0 + state: ratified ratification_date: 2019-12 requires: [Zicsr, ">= 2.0"] diff --git a/arch/ext/Zicsr.yaml b/arch/ext/Zicsr.yaml index 3ba2417fd..2d8495334 100644 --- a/arch/ext/Zicsr.yaml +++ b/arch/ext/Zicsr.yaml @@ -5,4 +5,5 @@ Zicsr: type: unprivileged versions: - version: 2.0 + state: ratified ratification_date: null diff --git a/arch/ext/Zihpm.yaml b/arch/ext/Zihpm.yaml index d5de323c6..d70eef526 100644 --- a/arch/ext/Zihpm.yaml +++ b/arch/ext/Zihpm.yaml @@ -5,4 +5,5 @@ Zihpm: type: unprivileged versions: - version: 2.0 + state: ratified ratification_date: unknown diff --git a/arch/ext/Zmmul.yaml b/arch/ext/Zmmul.yaml index 675429576..24e07b6fc 100644 --- a/arch/ext/Zmmul.yaml +++ b/arch/ext/Zmmul.yaml @@ -18,4 +18,5 @@ Zmmul: type: unprivileged versions: - version: 1.0 + state: ratified ratification_date: 2022-06 diff --git a/arch/inst/B/add.uw.yaml b/arch/inst/B/add.uw.yaml index acce1df0d..a02245e6b 100644 --- a/arch/inst/B/add.uw.yaml +++ b/arch/inst/B/add.uw.yaml @@ -8,12 +8,26 @@ add.uw: zero-extended least-significant word of rs1. definedBy: [B, Zba] assembly: xd, xs1, xs2 + encoding: + match: 0000100----------000-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always + pseudoinstructions: + when: rs2 == 0 + to: zext.w xd, xs1 operation(): | - raise (ExceptionCode::IllegalInstruction) if (CSR[misa].B == 1'b0); + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } X[rd] = X[rs2] + X[rs1][31:0]; diff --git a/arch/inst/B/andn.yaml b/arch/inst/B/andn.yaml index 8af42503c..badb3e1c2 100644 --- a/arch/inst/B/andn.yaml +++ b/arch/inst/B/andn.yaml @@ -7,10 +7,21 @@ andn: bitwise inversion of `rs2`. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 0100000----------111-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + raise (ExceptionCode::IllegalInstruction, $encoding) if (CSR[misa].B == 1'b0); + X[rd] = X[rs2] & ~X[rs1]; diff --git a/arch/inst/B/bclr.yaml b/arch/inst/B/bclr.yaml index f49dd426b..a6c0cdf6a 100644 --- a/arch/inst/B/bclr.yaml +++ b/arch/inst/B/bclr.yaml @@ -7,11 +7,22 @@ bclr: The index is read from the lower log2(XLEN) bits of rs2. definedBy: [B, Zbs] assembly: xd, xs1, xs2 + encoding: + match: 0100100----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + raise (ExceptionCode::IllegalInstruction, $encoding) if (CSR[misa].B == 1'b0); + XReg index = X[rs2] & (xlen() - 1); X[rd] = X[rs1] & ~(1 << index); diff --git a/arch/inst/B/bclri.yaml b/arch/inst/B/bclri.yaml index 22d996ddd..f2b93aced 100644 --- a/arch/inst/B/bclri.yaml +++ b/arch/inst/B/bclri.yaml @@ -8,11 +8,34 @@ bclri: to shamt[5]=1 are reserved. definedBy: [B, Zbs] assembly: xd, xs1, shamt + encoding: + RV32: + match: 0100100----------001-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 010010-----------001-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = shamt & (xlen() - 1); X[rd] = X[rs1] & ~(1 << index); diff --git a/arch/inst/B/bext.yaml b/arch/inst/B/bext.yaml index b48d90ce7..a8a6c8501 100644 --- a/arch/inst/B/bext.yaml +++ b/arch/inst/B/bext.yaml @@ -7,11 +7,24 @@ bext: The index is read from the lower log2(XLEN) bits of rs2. definedBy: [B, Zbs] assembly: xd, xs1, xs2 + encoding: + match: 0100100----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = X[rs2] & (xlen() - 1); X[rd] = (X[rs1] >> index) & 1; diff --git a/arch/inst/B/bexti.yaml b/arch/inst/B/bexti.yaml index 287835b77..bbf455710 100644 --- a/arch/inst/B/bexti.yaml +++ b/arch/inst/B/bexti.yaml @@ -8,11 +8,34 @@ bexti: corresponding to shamt[5]=1 are reserved. definedBy: [B, Zbs] assembly: xd, xs1, shamt + encoding: + RV32: + match: 0100100----------101-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 010010-----------101-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = shamt & (xlen() - 1); X[rd] = (X[rs1] >> index) & 1; diff --git a/arch/inst/B/binv.yaml b/arch/inst/B/binv.yaml index 7fcd1353a..a4d019dd4 100644 --- a/arch/inst/B/binv.yaml +++ b/arch/inst/B/binv.yaml @@ -7,11 +7,24 @@ binv: The index is read from the lower log2(XLEN) bits of rs2. definedBy: [B, Zbs] assembly: xd, xs1, xs2 + encoding: + match: 0110100----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = X[rs2] & (xlen() - 1); X[rd] = X[rs1] ^ (1 << index); diff --git a/arch/inst/B/binvi.yaml b/arch/inst/B/binvi.yaml index abb9fe7e6..c230a39bb 100644 --- a/arch/inst/B/binvi.yaml +++ b/arch/inst/B/binvi.yaml @@ -8,11 +8,34 @@ binvi: For RV32, the encodings corresponding to shamt[5]=1 are reserved. definedBy: [B, Zbs] assembly: xd, xs1, shamt + encoding: + RV32: + match: 0110100----------001-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 011010-----------001-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = shamt & (xlen() - 1); X[rd] = X[rs1] ^ (1 << index); diff --git a/arch/inst/B/bset.yaml b/arch/inst/B/bset.yaml index 7aec522a7..7ed6d5858 100644 --- a/arch/inst/B/bset.yaml +++ b/arch/inst/B/bset.yaml @@ -7,11 +7,24 @@ bset: The index is read from the lower log2(XLEN) bits of rs2. definedBy: [B, Zbs] assembly: xd, xs1, xs2 + encoding: + match: 0010100----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = X[rs2] & (xlen() - 1); X[rd] = X[rs1] | (1 << index); diff --git a/arch/inst/B/bseti.yaml b/arch/inst/B/bseti.yaml index 480e7b93f..66c7a1558 100644 --- a/arch/inst/B/bseti.yaml +++ b/arch/inst/B/bseti.yaml @@ -8,11 +8,34 @@ bseti: For RV32, the encodings corresponding to shamt[5]=1 are reserved. definedBy: [B, Zbs] assembly: xd, xs1, shamt + encoding: + RV32: + match: 0010100----------001-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 001010-----------001-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg index = shamt & (xlen() - 1); X[rd] = X[rs1] | (1 << index); diff --git a/arch/inst/B/clmul.yaml b/arch/inst/B/clmul.yaml index 522bf7939..85568eca8 100644 --- a/arch/inst/B/clmul.yaml +++ b/arch/inst/B/clmul.yaml @@ -6,12 +6,25 @@ clmul: `clmul` produces the lower half of the 2*XLEN carry-less product definedBy: [B, Zbc] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_val = X[rs1]; XReg rs2_val = X[rs2]; XReg output = 0; diff --git a/arch/inst/B/clmulh.yaml b/arch/inst/B/clmulh.yaml index 0b2b0362c..d0175bf74 100644 --- a/arch/inst/B/clmulh.yaml +++ b/arch/inst/B/clmulh.yaml @@ -6,12 +6,25 @@ clmulh: `clmulh` produces the upper half of the 2*XLEN carry-less product definedBy: [B, Zbc] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------011-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_val = X[rs1]; XReg rs2_val = X[rs2]; XReg output = 0; diff --git a/arch/inst/B/clmulr.yaml b/arch/inst/B/clmulr.yaml index 92358d659..9d5b7574e 100644 --- a/arch/inst/B/clmulr.yaml +++ b/arch/inst/B/clmulr.yaml @@ -11,7 +11,20 @@ clmulr: u: always vs: always vu: always + encoding: + match: 0000101----------010-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_val = X[rs1]; XReg rs2_val = X[rs2]; XReg output = 0; diff --git a/arch/inst/B/clz.yaml b/arch/inst/B/clz.yaml index efe19836c..f9c937289 100644 --- a/arch/inst/B/clz.yaml +++ b/arch/inst/B/clz.yaml @@ -9,10 +9,21 @@ clz: bit of the input is a 1, the output is 0. definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000000-----001-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = (xlen() - 1) - $signed(highest_set_bit(X[rs1])); diff --git a/arch/inst/B/clzw.yaml b/arch/inst/B/clzw.yaml index c7144bddd..37ebcb612 100644 --- a/arch/inst/B/clzw.yaml +++ b/arch/inst/B/clzw.yaml @@ -9,10 +9,21 @@ clzw: base: 64 definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000000-----001-----0011011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = 31 - $signed(highest_set_bit(X[rs1][31:0])); diff --git a/arch/inst/B/cpop.yaml b/arch/inst/B/cpop.yaml index 3ae7fbf8c..d186ee31d 100644 --- a/arch/inst/B/cpop.yaml +++ b/arch/inst/B/cpop.yaml @@ -18,12 +18,23 @@ cpop: ---- definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000010-----001-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg bitcount = 0; XReg rs1_val = X[rs1]; diff --git a/arch/inst/B/cpopw.yaml b/arch/inst/B/cpopw.yaml index fd104a027..c938b5722 100644 --- a/arch/inst/B/cpopw.yaml +++ b/arch/inst/B/cpopw.yaml @@ -19,12 +19,23 @@ cpopw: definedBy: [B, Zbb] base: 64 assembly: xd, xs1 + encoding: + match: 011000000010-----001-----0011011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg bitcount = 0; XReg rs1_val = X[rs1]; diff --git a/arch/inst/B/ctz.yaml b/arch/inst/B/ctz.yaml index 36e2f500b..2af94bfc3 100644 --- a/arch/inst/B/ctz.yaml +++ b/arch/inst/B/ctz.yaml @@ -10,10 +10,21 @@ ctz: of the input is a 1, the output is 0. definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000001-----001-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = (xlen() - 1) - $signed(lowest_set_bit(X[rs1])); diff --git a/arch/inst/B/ctzw.yaml b/arch/inst/B/ctzw.yaml index f7ea3fa9a..614a25768 100644 --- a/arch/inst/B/ctzw.yaml +++ b/arch/inst/B/ctzw.yaml @@ -11,10 +11,21 @@ ctzw: definedBy: [B, Zbb] base: 64 assembly: xd, xs1 + encoding: + match: 011000000001-----001-----0011011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = (xlen() - 1) - $signed(lowest_set_bit(X[rs1][31:0])); diff --git a/arch/inst/B/max.yaml b/arch/inst/B/max.yaml index 7a8e2b916..338e3baf1 100644 --- a/arch/inst/B/max.yaml +++ b/arch/inst/B/max.yaml @@ -14,10 +14,23 @@ max: together. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------110-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = ($signed(X[rs1]) > $signed(X[rs2])) ? X[rs1] : X[rs2]; diff --git a/arch/inst/B/maxu.yaml b/arch/inst/B/maxu.yaml index 9cc72638d..c43123762 100644 --- a/arch/inst/B/maxu.yaml +++ b/arch/inst/B/maxu.yaml @@ -6,10 +6,23 @@ maxu: This instruction returns the larger of two unsigned integers. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------111-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = (X[rs1] > X[rs2]) ? X[rs1] : X[rs2]; diff --git a/arch/inst/B/min.yaml b/arch/inst/B/min.yaml index a499535ad..94a01c747 100644 --- a/arch/inst/B/min.yaml +++ b/arch/inst/B/min.yaml @@ -6,10 +6,23 @@ min: This instruction returns the smaller of two signed integers. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------100-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = ($signed(X[rs1]) < $signed(X[rs2])) ? X[rs1] : X[rs2]; diff --git a/arch/inst/B/minu.yaml b/arch/inst/B/minu.yaml index 235b6bec0..2466a7606 100644 --- a/arch/inst/B/minu.yaml +++ b/arch/inst/B/minu.yaml @@ -6,10 +6,23 @@ minu: This instruction returns the smaller of two unsigned integers. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 0000101----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = (X[rs1] < X[rs2]) ? X[rs1] : X[rs2]; diff --git a/arch/inst/B/orc.b.yaml b/arch/inst/B/orc.b.yaml index 5c3ae727f..5ee8c9413 100644 --- a/arch/inst/B/orc.b.yaml +++ b/arch/inst/B/orc.b.yaml @@ -8,12 +8,23 @@ orc.b: of rs is set, or to all ones if any bit within the respective byte of rs is set. definedBy: [B, Zbb] assembly: xd, xs1, xs2 + encoding: + match: 001010000111-----101-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg input = X[rs1]; XReg output = 0; diff --git a/arch/inst/B/orn.yaml b/arch/inst/B/orn.yaml index 9cd1e701e..6b0c3f134 100644 --- a/arch/inst/B/orn.yaml +++ b/arch/inst/B/orn.yaml @@ -6,10 +6,23 @@ orn: This instruction performs the bitwise logical OR operation between rs1 and the bitwise inversion of rs2. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 + encoding: + match: 0100000----------110-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs1] | ~X[rs2]; diff --git a/arch/inst/B/rev8.yaml b/arch/inst/B/rev8.yaml index ee7498a08..6148a9d34 100644 --- a/arch/inst/B/rev8.yaml +++ b/arch/inst/B/rev8.yaml @@ -14,20 +14,38 @@ rev8: is XLEN-32 and XLEN-16, respectively. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1 - # TODO: this instruction has different encodings in RV32 / RV64 + encoding: + RV32: + match: 011010011000-----101-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 011010111000-----101-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg input = X[rs1]; XReg output = 0; XReg j = xlen() - 1; for (U32 i=0; i<(xlen()-8); i = i+8) { - output[i:(i+7)] = input[(j-7):j]; + output[(i+7):i] = input[j:(j-7)]; j = j - 8; } diff --git a/arch/inst/B/rol.yaml b/arch/inst/B/rol.yaml index b87b732f3..38406e432 100644 --- a/arch/inst/B/rol.yaml +++ b/arch/inst/B/rol.yaml @@ -6,12 +6,25 @@ rol: This instruction performs a rotate left of rs1 by the amount in least-significant `log2(XLEN)` bits of rs2. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 + encoding: + match: 0110000----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg shamt = (xlen() == 32) ? X[rs2][4:0] : X[rs2][5:0]; X[rd] = (X[rs1] << shamt) | (X[rs1] >> (xlen() - shamt)); diff --git a/arch/inst/B/rolw.yaml b/arch/inst/B/rolw.yaml index d0d637f65..9e6d892df 100644 --- a/arch/inst/B/rolw.yaml +++ b/arch/inst/B/rolw.yaml @@ -8,12 +8,25 @@ rolw: definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 base: 64 + encoding: + match: 0110000----------001-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_word = X[rs1][31:0]; XReg shamt = X[rs2][4:0]; diff --git a/arch/inst/B/ror.yaml b/arch/inst/B/ror.yaml index a97730560..f45acdea8 100644 --- a/arch/inst/B/ror.yaml +++ b/arch/inst/B/ror.yaml @@ -6,12 +6,25 @@ ror: This instruction performs a rotate right of rs1 by the amount in least-significant `log2(XLEN)` bits of rs2. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 + encoding: + match: 0110000----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg shamt = (xlen() == 32) ? X[rs2][4:0] : X[rs2][5:0]; X[rd] = (X[rs1] >> shamt) | (X[rs1] << (xlen() - shamt)); diff --git a/arch/inst/B/rori.yaml b/arch/inst/B/rori.yaml index b14f257a4..bf7ce3d42 100644 --- a/arch/inst/B/rori.yaml +++ b/arch/inst/B/rori.yaml @@ -7,12 +7,35 @@ rori: For RV32, the encodings corresponding to shamt[5]=1 are reserved. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, shamt + encoding: + RV32: + match: 0110000----------101-----0110011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 011000-----------101-----0110011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg shamt = (xlen() == 32) ? shamt[4:0] : shamt[5:0]; X[rd] = (X[rs1] >> shamt) | (X[rs1] << (xlen() - shamt)); diff --git a/arch/inst/B/roriw.yaml b/arch/inst/B/roriw.yaml index 240462433..3ec88044f 100644 --- a/arch/inst/B/roriw.yaml +++ b/arch/inst/B/roriw.yaml @@ -9,12 +9,25 @@ roriw: definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, shamt base: 64 + encoding: + match: 0110000----------101-----0011011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_word = X[rs1][31:0]; XReg unextended_result = (X[rs1] >> shamt) | (X[rs1] << (32 - shamt)); diff --git a/arch/inst/B/rorw.yaml b/arch/inst/B/rorw.yaml index 0d77044f1..b711fc043 100644 --- a/arch/inst/B/rorw.yaml +++ b/arch/inst/B/rorw.yaml @@ -9,12 +9,25 @@ rorw: definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 base: 64 + encoding: + match: 0110000----------101-----0111011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg rs1_word = X[rs1][31:0]; XReg shamt = X[rs1][4:0]; diff --git a/arch/inst/B/sext.b.yaml b/arch/inst/B/sext.b.yaml index e165ab145..0b3a4d2a6 100644 --- a/arch/inst/B/sext.b.yaml +++ b/arch/inst/B/sext.b.yaml @@ -7,12 +7,23 @@ sext.b: most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits. definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000100-----001-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + if (xlen() == 32) { X[rd] = {{24{X[rs1][7]}}, X[rs1][7:0]}; } else if (xlen() == 64) { diff --git a/arch/inst/B/sext.h.yaml b/arch/inst/B/sext.h.yaml index 0dfc99d01..b97b009a8 100644 --- a/arch/inst/B/sext.h.yaml +++ b/arch/inst/B/sext.h.yaml @@ -7,12 +7,23 @@ sext.h: most-significant bit in the halfword (i.e., bit 15) to all of the more-significant bits. definedBy: [B, Zbb] assembly: xd, xs1 + encoding: + match: 011000000101-----001-----0010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + if (xlen() == 32) { X[rd] = {{16{X[rs1][15]}}, X[rs1][15:0]}; } else if (xlen() == 64) { diff --git a/arch/inst/B/sh1add.uw.yaml b/arch/inst/B/sh1add.uw.yaml index a55a3daf8..252f96e3f 100644 --- a/arch/inst/B/sh1add.uw.yaml +++ b/arch/inst/B/sh1add.uw.yaml @@ -8,6 +8,15 @@ sh1add.uw: and shifting it left by 1 place. definedBy: [B, Zba] base: 64 + encoding: + match: 0010000----------010-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 assembly: xd, xs1, xs2 access: s: always @@ -15,4 +24,8 @@ sh1add.uw: vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1][31:0] << 1); diff --git a/arch/inst/B/sh1add.yaml b/arch/inst/B/sh1add.yaml index 7dfce976e..6caa659b4 100644 --- a/arch/inst/B/sh1add.yaml +++ b/arch/inst/B/sh1add.yaml @@ -6,10 +6,23 @@ sh1add: This instruction shifts `rs1` to the left by 1 bit and adds it to `rs2`. definedBy: [B, Zba] assembly: xd, xs1, xs2 + encoding: + match: 0010000----------010-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1] << 1); diff --git a/arch/inst/B/sh2add.uw.yaml b/arch/inst/B/sh2add.uw.yaml index 76c0e0f59..734516f32 100644 --- a/arch/inst/B/sh2add.uw.yaml +++ b/arch/inst/B/sh2add.uw.yaml @@ -9,10 +9,23 @@ sh2add.uw: definedBy: [B, Zba] base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0010000----------100-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1][31:0] << 2); diff --git a/arch/inst/B/sh2add.yaml b/arch/inst/B/sh2add.yaml index 094ace1d1..0fd311000 100644 --- a/arch/inst/B/sh2add.yaml +++ b/arch/inst/B/sh2add.yaml @@ -6,10 +6,23 @@ sh2add: This instruction shifts `rs1` to the left by 2 places and adds it to `rs2`. definedBy: [B, Zba] assembly: xd, xs1, xs2 + encoding: + match: 0010000----------100-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1] << 2); diff --git a/arch/inst/B/sh3add.uw.yaml b/arch/inst/B/sh3add.uw.yaml index a84d59780..f490f3c78 100644 --- a/arch/inst/B/sh3add.uw.yaml +++ b/arch/inst/B/sh3add.uw.yaml @@ -9,10 +9,23 @@ sh3add.uw: definedBy: [B, Zba] base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0010000----------110-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1][31:0] << 3); diff --git a/arch/inst/B/sh3add.yaml b/arch/inst/B/sh3add.yaml index 921b74e48..4272241f3 100644 --- a/arch/inst/B/sh3add.yaml +++ b/arch/inst/B/sh3add.yaml @@ -6,10 +6,23 @@ sh3add: This instruction shifts `rs1` to the left by 3 places and adds it to `rs2`. definedBy: [B, Zba] assembly: xd, xs1, xs2 + encoding: + match: 0010000----------110-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs2] + (X[rs1] << 3); diff --git a/arch/inst/B/slli.uw.yaml b/arch/inst/B/slli.uw.yaml index 50fce0791..e048579aa 100644 --- a/arch/inst/B/slli.uw.yaml +++ b/arch/inst/B/slli.uw.yaml @@ -10,6 +10,15 @@ slli.uw: This instruction is the same as `slli` with `zext.w` performed on rs1 before shifting. definedBy: [B, Zba] base: 64 + encoding: + match: 0000010----------001-----0011011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 assembly: xd, xs1, shamt access: s: always @@ -17,4 +26,8 @@ slli.uw: vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs1][31:0] << shamt; diff --git a/arch/inst/B/xnor.yaml b/arch/inst/B/xnor.yaml index 729f0e23c..ac9db14a4 100644 --- a/arch/inst/B/xnor.yaml +++ b/arch/inst/B/xnor.yaml @@ -6,10 +6,23 @@ xnor: This instruction performs the bit-wise exclusive-NOR operation on rs1 and rs2. definedBy: [B, Zbb, Zbkb] assembly: xd, xs1, xs2 + encoding: + match: 0100000----------100-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = ~(X[rs1] ^ X[rs2]); diff --git a/arch/inst/B/zext.h.yaml b/arch/inst/B/zext.h.yaml index 2b2c7a8df..044e3d118 100644 --- a/arch/inst/B/zext.h.yaml +++ b/arch/inst/B/zext.h.yaml @@ -14,15 +14,15 @@ zext.h: definedBy: [B, Zbb] encoding: RV32: - mask: 000010000000-----100-----0110011 - fields: + match: 000010000000-----100-----0110011 + variables: - name: rs1 location: 19-15 - name: rd location: 11-7 RV64: - mask: 000010000000-----100-----0111011 - fields: + match: 000010000000-----100-----0111011 + variables: - name: rs1 location: 19-15 - name: rd @@ -35,4 +35,8 @@ zext.h: vs: always vu: always operation(): | + if (implemented?(ExtensionName::B) && (CSR[misa].B == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + X[rd] = X[rs1][15:0]; diff --git a/arch/inst/F/fmv.w.x.yaml b/arch/inst/F/fmv.w.x.yaml index 9f8ce8902..d25dddec6 100644 --- a/arch/inst/F/fmv.w.x.yaml +++ b/arch/inst/F/fmv.w.x.yaml @@ -9,6 +9,13 @@ fmv.w.x: the payloads of non-canonical NaNs are preserved. definedBy: F assembly: fd, xs1 + encoding: + match: 111100000000-----000-----1010011 + variables: + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/add.yaml b/arch/inst/I/add.yaml index a7384c3d9..fc6bf2429 100644 --- a/arch/inst/I/add.yaml +++ b/arch/inst/I/add.yaml @@ -1,12 +1,21 @@ # yaml-language-server: $schema=../../../schemas/inst_schema.json add: - long_name: Add + long_name: Integer add description: | Add the value in rs1 to rs2, and store the result in rd. Any overflow is thrown away. definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------000-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/addi.yaml b/arch/inst/I/addi.yaml index 29a46d01f..b6c3d7bc9 100644 --- a/arch/inst/I/addi.yaml +++ b/arch/inst/I/addi.yaml @@ -5,6 +5,15 @@ addi: description: Add an immediate to the value in rs1, and store the result in rd definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------000-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/addiw.yaml b/arch/inst/I/addiw.yaml index d3c73ffc4..b3b58be43 100644 --- a/arch/inst/I/addiw.yaml +++ b/arch/inst/I/addiw.yaml @@ -6,6 +6,15 @@ addiw: definedBy: I base: 64 assembly: xd, xs1, imm + encoding: + match: -----------------000-----0001011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/addw.yaml b/arch/inst/I/addw.yaml index 07a9e4606..c3d2c5e3c 100644 --- a/arch/inst/I/addw.yaml +++ b/arch/inst/I/addw.yaml @@ -8,6 +8,15 @@ addw: definedBy: I base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0000000----------000-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/and.yaml b/arch/inst/I/and.yaml index 3dcccdce5..7f29c55c8 100644 --- a/arch/inst/I/and.yaml +++ b/arch/inst/I/and.yaml @@ -5,6 +5,15 @@ and: description: And rs1 with rs2, and store the result in rd definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------111-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/andi.yaml b/arch/inst/I/andi.yaml index 5dea6fa4b..fa90164d8 100644 --- a/arch/inst/I/andi.yaml +++ b/arch/inst/I/andi.yaml @@ -5,6 +5,15 @@ andi: description: And an immediate to the value in rs1, and store the result in rd definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------111-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/auipc.yaml b/arch/inst/I/auipc.yaml index 8bed804b2..99e32304a 100644 --- a/arch/inst/I/auipc.yaml +++ b/arch/inst/I/auipc.yaml @@ -5,6 +5,14 @@ auipc: description: Add an immediate to the current PC. definedBy: I assembly: xd, imm + encoding: + match: --------------------------001011 + variables: + - name: imm + location: 31-12 + left_shift: 12 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/beq.yaml b/arch/inst/I/beq.yaml index a3ff95cad..a8afb46c9 100644 --- a/arch/inst/I/beq.yaml +++ b/arch/inst/I/beq.yaml @@ -9,6 +9,16 @@ beq: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------000-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/bge.yaml b/arch/inst/I/bge.yaml index 250ae9670..537a47c11 100644 --- a/arch/inst/I/bge.yaml +++ b/arch/inst/I/bge.yaml @@ -9,6 +9,16 @@ bge: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------101-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/bgeu.yaml b/arch/inst/I/bgeu.yaml index 2ca485678..639486d51 100644 --- a/arch/inst/I/bgeu.yaml +++ b/arch/inst/I/bgeu.yaml @@ -9,6 +9,16 @@ bgeu: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------111-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/blt.yaml b/arch/inst/I/blt.yaml index 0ea068385..11c156f4c 100644 --- a/arch/inst/I/blt.yaml +++ b/arch/inst/I/blt.yaml @@ -9,6 +9,16 @@ blt: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------100-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/bltu.yaml b/arch/inst/I/bltu.yaml index 3b08882c7..d62d94e4b 100644 --- a/arch/inst/I/bltu.yaml +++ b/arch/inst/I/bltu.yaml @@ -9,6 +9,16 @@ bltu: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------110-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/bne.yaml b/arch/inst/I/bne.yaml index aa590b895..bd3242711 100644 --- a/arch/inst/I/bne.yaml +++ b/arch/inst/I/bne.yaml @@ -9,6 +9,16 @@ bne: Raise a `MisalignedAddress` exception if PC + imm is misaligned. definedBy: I assembly: xs1, xs2, imm + encoding: + match: -----------------001-----1100011 + variables: + - name: imm + location: 31|7|30-25|11-8 + left_shift: 1 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/ebreak.yaml b/arch/inst/I/ebreak.yaml index 7374b3b44..87b83f97a 100644 --- a/arch/inst/I/ebreak.yaml +++ b/arch/inst/I/ebreak.yaml @@ -17,10 +17,12 @@ ebreak: and should not increment the `minstret` CSR. definedBy: I assembly: '' + encoding: + match: '00000000000100000000000001110011' access: s: always u: always vs: always vu: always operation(): | - raise (ExceptionCode::Breakpoint); + raise (ExceptionCode::Breakpoint, $pc); diff --git a/arch/inst/I/ecall.yaml b/arch/inst/I/ecall.yaml index 35516e174..0fc49bcdd 100644 --- a/arch/inst/I/ecall.yaml +++ b/arch/inst/I/ecall.yaml @@ -20,6 +20,8 @@ ecall: and should not increment the `minstret` CSR. definedBy: I assembly: '' + encoding: + match: '00000000000000000000000001110011' access: s: always u: always @@ -27,9 +29,9 @@ ecall: vu: always operation(): | if (mode() == PrivilegeMode::M) { - raise(ExceptionCode::Mcall); + raise(ExceptionCode::Mcall, 0); } else if (mode() == PrivilegeMode::S) { - raise (ExceptionCode::Scall); + raise (ExceptionCode::Scall, 0); } else if (mode() == PrivilegeMode::U) { - raise (ExceptionCode::Ucall); + raise (ExceptionCode::Ucall, 0); } diff --git a/arch/inst/I/fence.yaml b/arch/inst/I/fence.yaml index 320868349..542b13e27 100644 --- a/arch/inst/I/fence.yaml +++ b/arch/inst/I/fence.yaml @@ -120,6 +120,19 @@ fence: definedBy: I assembly: "TODO" + encoding: + match: -----------------000-----0001111 + variables: + - name: fm + location: 31-28 + - name: pred + location: 27-24 + - name: succ + location: 23-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/jal.yaml b/arch/inst/I/jal.yaml index 47c041f42..2b3564870 100644 --- a/arch/inst/I/jal.yaml +++ b/arch/inst/I/jal.yaml @@ -8,8 +8,8 @@ jal: definedBy: I assembly: xd, imm encoding: - mask: -------------------------1101111 - fields: + match: -------------------------1101111 + variables: - name: imm location: 31|19-12|20|30-21 left_shift: 1 diff --git a/arch/inst/I/jalr.yaml b/arch/inst/I/jalr.yaml index 3611d427d..e6320746a 100644 --- a/arch/inst/I/jalr.yaml +++ b/arch/inst/I/jalr.yaml @@ -7,6 +7,15 @@ jalr: to a signed offset, and store the return address in rd. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------000-----1100111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lb.yaml b/arch/inst/I/lb.yaml index 0c5c8b5f9..d3801e604 100644 --- a/arch/inst/I/lb.yaml +++ b/arch/inst/I/lb.yaml @@ -8,6 +8,15 @@ lb: Sign extend the result. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------000-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lbu.yaml b/arch/inst/I/lbu.yaml index 70b00dcce..cf5dc0a55 100644 --- a/arch/inst/I/lbu.yaml +++ b/arch/inst/I/lbu.yaml @@ -8,6 +8,15 @@ lbu: Zero extend the result. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------100-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/ld.yaml b/arch/inst/I/ld.yaml index d17ee9660..dfdec74f1 100644 --- a/arch/inst/I/ld.yaml +++ b/arch/inst/I/ld.yaml @@ -8,6 +8,15 @@ ld: definedBy: I base: 64 assembly: xd, imm(rs1) + encoding: + match: -----------------011-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lh.yaml b/arch/inst/I/lh.yaml index b4aa8b276..a6db7b6c8 100644 --- a/arch/inst/I/lh.yaml +++ b/arch/inst/I/lh.yaml @@ -8,6 +8,15 @@ lh: Sign extend the result. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------001-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lhu.yaml b/arch/inst/I/lhu.yaml index e75335902..1ffcb4ce7 100644 --- a/arch/inst/I/lhu.yaml +++ b/arch/inst/I/lhu.yaml @@ -8,6 +8,15 @@ lhu: Zero extend the result. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------101-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lui.yaml b/arch/inst/I/lui.yaml index 5c6cd5534..4ff132852 100644 --- a/arch/inst/I/lui.yaml +++ b/arch/inst/I/lui.yaml @@ -5,6 +5,14 @@ lui: description: Load the zero-extended imm into rd. definedBy: I assembly: xd, imm + encoding: + match: -------------------------0000111 + variables: + - name: imm + location: 31-12 + left_shift: 12 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lw.yaml b/arch/inst/I/lw.yaml index cc4e87edc..e53527bbe 100644 --- a/arch/inst/I/lw.yaml +++ b/arch/inst/I/lw.yaml @@ -8,6 +8,15 @@ lw: Sign extend the result. definedBy: I assembly: xd, imm(rs1) + encoding: + match: -----------------010-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/lwu.yaml b/arch/inst/I/lwu.yaml index 66fc37425..7447a8c2d 100644 --- a/arch/inst/I/lwu.yaml +++ b/arch/inst/I/lwu.yaml @@ -9,6 +9,15 @@ lwu: definedBy: I base: 64 assembly: xd, imm(rs1) + encoding: + match: -----------------110-----0000111 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/mret.yaml b/arch/inst/I/mret.yaml index ff6a2d700..c35223060 100644 --- a/arch/inst/I/mret.yaml +++ b/arch/inst/I/mret.yaml @@ -9,6 +9,8 @@ mret: u: never vs: never vu: never + encoding: + match: '00110000001000000000000001110011' operation(): | if (implemented?(ExtensionName::S) && CSR[mstatus].MPP != 2'b11) { CSR[mstatus].MPRV = 0; diff --git a/arch/inst/I/or.yaml b/arch/inst/I/or.yaml index ada1c0064..454e5f5c5 100644 --- a/arch/inst/I/or.yaml +++ b/arch/inst/I/or.yaml @@ -5,6 +5,15 @@ or: description: Or rs1 with rs2, and store the result in rd definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------110-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/ori.yaml b/arch/inst/I/ori.yaml index 7ebe288cb..eeb03c54d 100644 --- a/arch/inst/I/ori.yaml +++ b/arch/inst/I/ori.yaml @@ -5,6 +5,15 @@ ori: description: Or an immediate to the value in rs1, and store the result in rd definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------110-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sb.yaml b/arch/inst/I/sb.yaml index 109429e6d..cc52aadc6 100644 --- a/arch/inst/I/sb.yaml +++ b/arch/inst/I/sb.yaml @@ -7,6 +7,15 @@ sb: address formed by adding `rs1` to a signed offset. definedBy: I assembly: xs2, imm(xs1) + encoding: + match: -----------------000-----0100011 + variables: + - name: imm + location: 31-25|11-7 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/sd.yaml b/arch/inst/I/sd.yaml index 375dcd018..ef04eb4eb 100644 --- a/arch/inst/I/sd.yaml +++ b/arch/inst/I/sd.yaml @@ -9,8 +9,8 @@ sd: base: 64 assembly: xs2, imm(xs1) encoding: - mask: -----------------011-----0100011 - fields: + match: -----------------011-----0100011 + variables: - name: imm location: 31-25|11-7 sign_extend: true diff --git a/arch/inst/I/sh.yaml b/arch/inst/I/sh.yaml index bbee22f6b..799b89ea3 100644 --- a/arch/inst/I/sh.yaml +++ b/arch/inst/I/sh.yaml @@ -7,6 +7,15 @@ sh: address formed by adding `rs1` to a signed offset. definedBy: I assembly: xs2, imm(xs1) + encoding: + match: -----------------001-----0100011 + variables: + - name: imm + location: 31-25|11-7 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/sll.yaml b/arch/inst/I/sll.yaml index 9611ae256..ea94c511a 100644 --- a/arch/inst/I/sll.yaml +++ b/arch/inst/I/sll.yaml @@ -6,13 +6,22 @@ sll: Shift the value in `rs1` left by the value in the lower 6 bits of `rs2`, and store the result in `rd`. definedBy: I assembly: xd, xs1, xs2 + encoding: + match: -----------------001-----0010011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | - if (XLEN == 64) { + if (xlen() == 64) { X[rd] = X[rs1] << X[rs2][5:0]; } else { X[rd] = X[rs1] << X[rs2][4:0]; diff --git a/arch/inst/I/slli.yaml b/arch/inst/I/slli.yaml index 2fa0c21f6..d1d32b606 100644 --- a/arch/inst/I/slli.yaml +++ b/arch/inst/I/slli.yaml @@ -5,6 +5,25 @@ slli: description: Shift the value in rs1 left by shamt, and store the result in rd definedBy: I assembly: xd, xs1, shamt + encoding: + RV32: + match: 0000000----------001-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 000000-----------001-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/slliw.yaml b/arch/inst/I/slliw.yaml index d9c118f2e..ebb67c5bd 100644 --- a/arch/inst/I/slliw.yaml +++ b/arch/inst/I/slliw.yaml @@ -6,6 +6,15 @@ slliw: definedBy: I base: 64 assembly: xd, xs1, shamt + encoding: + match: 0000000----------001-----0011011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sllw.yaml b/arch/inst/I/sllw.yaml index c52ea7062..29da5ee5f 100644 --- a/arch/inst/I/sllw.yaml +++ b/arch/inst/I/sllw.yaml @@ -7,6 +7,15 @@ sllw: definedBy: I base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0000000----------001-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/slt.yaml b/arch/inst/I/slt.yaml index 75a49d56a..e8498a3c8 100644 --- a/arch/inst/I/slt.yaml +++ b/arch/inst/I/slt.yaml @@ -7,6 +7,15 @@ slt: both sources are treated as signed numbers, else 0 is written to `rd`. definedBy: I assembly: xd, xs1, rs2 + encoding: + match: 0000000----------010-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/slti.yaml b/arch/inst/I/slti.yaml index c71af1c11..dff628dbb 100644 --- a/arch/inst/I/slti.yaml +++ b/arch/inst/I/slti.yaml @@ -7,6 +7,15 @@ slti: when both are treated as signed numbers, else 0 is written to `rd`. definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------010-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sltiu.yaml b/arch/inst/I/sltiu.yaml index c60dd7886..0d91a8940 100644 --- a/arch/inst/I/sltiu.yaml +++ b/arch/inst/I/sltiu.yaml @@ -11,6 +11,15 @@ sltiu: (assembler pseudoinstruction `SEQZ rd, rs`). definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------011-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sltu.yaml b/arch/inst/I/sltu.yaml index ffebd12f8..9e421ac8d 100644 --- a/arch/inst/I/sltu.yaml +++ b/arch/inst/I/sltu.yaml @@ -7,6 +7,15 @@ sltu: both sources are treated as unsigned numbers, else 0 is written to `rd`. definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------011-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sra.yaml b/arch/inst/I/sra.yaml index c0358e0db..6f1f1a8f3 100644 --- a/arch/inst/I/sra.yaml +++ b/arch/inst/I/sra.yaml @@ -6,13 +6,22 @@ sra: Arithmetic shift the value in `rs1` right by the value in the lower 5 bits of `rs2`, and store the result in `rd`. definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0100000----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | - if (XLEN == 64) { + if (xlen() == 64) { X[rd] = X[rs1] >>> X[rs2][5:0]; } else { X[rd] = X[rs1] >>> X[rs2][4:0]; diff --git a/arch/inst/I/srai.yaml b/arch/inst/I/srai.yaml index f285cd264..312e96ade 100644 --- a/arch/inst/I/srai.yaml +++ b/arch/inst/I/srai.yaml @@ -7,6 +7,25 @@ srai: value in rs1 right by shamt, and store the result in rd. definedBy: I assembly: xd, xs1, shamt + encoding: + RV32: + match: 0100000----------101-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 010000-----------101-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sraiw.yaml b/arch/inst/I/sraiw.yaml index c7efdd0ad..0bf6cdffc 100644 --- a/arch/inst/I/sraiw.yaml +++ b/arch/inst/I/sraiw.yaml @@ -8,6 +8,15 @@ sraiw: definedBy: I base: 64 assembly: xd, xs1, shamt + encoding: + match: 0100000----------101-----0011011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sraw.yaml b/arch/inst/I/sraw.yaml index f0d165ff7..b4e0b5887 100644 --- a/arch/inst/I/sraw.yaml +++ b/arch/inst/I/sraw.yaml @@ -7,6 +7,15 @@ sraw: definedBy: I base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0100000----------101-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/srl.yaml b/arch/inst/I/srl.yaml index 7ef0e5709..460a3442b 100644 --- a/arch/inst/I/srl.yaml +++ b/arch/inst/I/srl.yaml @@ -6,6 +6,15 @@ srl: Logical shift the value in `rs1` right by the value in the lower bits of `rs2`, and store the result in `rd`. definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/srli.yaml b/arch/inst/I/srli.yaml index a3910cd5b..4aa8c1ec7 100644 --- a/arch/inst/I/srli.yaml +++ b/arch/inst/I/srli.yaml @@ -4,6 +4,25 @@ srli: description: Shift the value in rs1 right by shamt, and store the result in rd definedBy: I assembly: xd, xs1, shamt + encoding: + RV32: + match: 0000000----------101-----0010011 + variables: + - name: shamt + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 + RV64: + match: 000000-----------101-----0010011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/srliw.yaml b/arch/inst/I/srliw.yaml index 2fb386991..0eaff1773 100644 --- a/arch/inst/I/srliw.yaml +++ b/arch/inst/I/srliw.yaml @@ -6,6 +6,15 @@ srliw: definedBy: I base: 64 assembly: xd, xs1, shamt + encoding: + match: 0000000----------101-----0011011 + variables: + - name: shamt + location: 25-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/srlw.yaml b/arch/inst/I/srlw.yaml index 0615c9b8d..7e47cbac9 100644 --- a/arch/inst/I/srlw.yaml +++ b/arch/inst/I/srlw.yaml @@ -7,6 +7,15 @@ srlw: definedBy: I base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0000000----------101-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sub.yaml b/arch/inst/I/sub.yaml index 310dbbe97..620aab65b 100644 --- a/arch/inst/I/sub.yaml +++ b/arch/inst/I/sub.yaml @@ -5,6 +5,15 @@ sub: description: Subtract the value in rs2 from rs1, and store the result in rd definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0100000----------000-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/subw.yaml b/arch/inst/I/subw.yaml index e0e045523..b212c65b5 100644 --- a/arch/inst/I/subw.yaml +++ b/arch/inst/I/subw.yaml @@ -6,6 +6,15 @@ subw: definedBy: I base: 64 assembly: xd, xs1, xs2 + encoding: + match: 0100000----------000-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/sw.yaml b/arch/inst/I/sw.yaml index c337475da..aa81c9c9f 100644 --- a/arch/inst/I/sw.yaml +++ b/arch/inst/I/sw.yaml @@ -7,6 +7,15 @@ sw: address formed by adding `rs1` to a signed offset. definedBy: I assembly: xs2, imm(xs1) + encoding: + match: -----------------010-----0100011 + variables: + - name: imm + location: 31-25|11-7 + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/I/wfi.yaml b/arch/inst/I/wfi.yaml index 409eaa794..1fe8f469b 100644 --- a/arch/inst/I/wfi.yaml +++ b/arch/inst/I/wfi.yaml @@ -44,6 +44,8 @@ wfi: above). definedBy: I assembly: "" + encoding: + match: '00010000010100000000000001110011' access: s: sometimes u: sometimes @@ -85,21 +87,21 @@ wfi: operation(): | # first, perform all the access checks if (mode() == PrivilegeMode::U) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } if ((CSR[misa].S == 1) && (CSR[mstatus].TW == 1'b1)) { if (mode() != PrivilegeMode::M) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } } if (CSR[misa].H == 1) { if (CSR[hstatus].VTW == 1'b0) { if (mode() == PrivilegeMode::VU) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } else if (CSR[hstatus].VTW == 1'b1) { if ((mode() == PrivilegeMode::VS) || (mode() == PrivilegeMode::VU)) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } } diff --git a/arch/inst/I/xor.yaml b/arch/inst/I/xor.yaml index 090e229dd..215c3defc 100644 --- a/arch/inst/I/xor.yaml +++ b/arch/inst/I/xor.yaml @@ -5,6 +5,15 @@ xor: description: Exclusive or rs1 with rs2, and store the result in rd definedBy: I assembly: xd, xs1, xs2 + encoding: + match: 0000000----------100-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/I/xori.yaml b/arch/inst/I/xori.yaml index d6b032ea5..d879c2db8 100644 --- a/arch/inst/I/xori.yaml +++ b/arch/inst/I/xori.yaml @@ -5,6 +5,15 @@ xori: description: Exclusive or an immediate to the value in rs1, and store the result in rd definedBy: I assembly: xd, xs1, imm + encoding: + match: -----------------100-----0010011 + variables: + - name: imm + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/M/div.yaml b/arch/inst/M/div.yaml index ba23c12f4..dc5883415 100644 --- a/arch/inst/M/div.yaml +++ b/arch/inst/M/div.yaml @@ -11,12 +11,25 @@ div: will put the most negative number into rd; definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------100-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg src1 = X[rs1]; XReg src2 = X[rs2]; diff --git a/arch/inst/M/divu.yaml b/arch/inst/M/divu.yaml index fa5f729f4..83a671bac 100644 --- a/arch/inst/M/divu.yaml +++ b/arch/inst/M/divu.yaml @@ -10,12 +10,25 @@ divu: If the value in rs2 is zero, rd gets the largest unsigned value. definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------101-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg src1 = X[rs1]; XReg src2 = X[rs2]; diff --git a/arch/inst/M/divuw.yaml b/arch/inst/M/divuw.yaml index 4ae0d86c1..9108ca79b 100644 --- a/arch/inst/M/divuw.yaml +++ b/arch/inst/M/divuw.yaml @@ -10,12 +10,25 @@ divuw: If the value in rs2 is zero, rd is written with all 1s. definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------101-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + Bits<32> src1 = X[rs1][31:0]; Bits<32> src2 = X[rs2][31:0]; diff --git a/arch/inst/M/divw.yaml b/arch/inst/M/divw.yaml index 6a4b04979..998c61cf7 100644 --- a/arch/inst/M/divw.yaml +++ b/arch/inst/M/divw.yaml @@ -14,12 +14,25 @@ divw: will put the most negative number into rd; definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------100-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + Bits<32> src1 = X[rs1][31:0]; Bits<32> src2 = X[rs2][31:0]; diff --git a/arch/inst/M/mul.yaml b/arch/inst/M/mul.yaml index 41388bc34..688428de0 100644 --- a/arch/inst/M/mul.yaml +++ b/arch/inst/M/mul.yaml @@ -17,12 +17,25 @@ mul: definedBy: [M, Zmmul] assembly: xd, xs1, xs2 + encoding: + match: 0000001----------000-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg src1 = X[rs1]; XReg src2 = X[rs2]; diff --git a/arch/inst/M/mulh.yaml b/arch/inst/M/mulh.yaml index 28bbab77b..d291a8461 100644 --- a/arch/inst/M/mulh.yaml +++ b/arch/inst/M/mulh.yaml @@ -16,18 +16,31 @@ mulh: Microarchitectures may look for that sequence and fuse the operations. definedBy: [M, Zmmul] assembly: xd, xs1, xs2 + encoding: + match: 0000001----------001-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + # enlarge and sign extend the sources Bits<1> rs1_sign_bit = X[rs1][XLEN-1]; - Bits src1 = {{XLEN{rs1_sign_bit}}, X[rs1]}; + Bits src1 = {{XLEN{rs1_sign_bit}}, X[rs1]}; Bits<1> rs2_sign_bit = X[rs2][XLEN-1]; - Bits src2 = {{XLEN{rs2_sign_bit}}, X[rs2]}; + Bits src2 = {{XLEN{rs2_sign_bit}}, X[rs2]}; # grab the high half of the result, and put it in rd - X[rd] = (src1 * src2)[(XLEN*2)-1:XLEN]; \ No newline at end of file + X[rd] = (src1 * src2)[(XLEN*8'd2)-1:XLEN]; \ No newline at end of file diff --git a/arch/inst/M/mulhsu.yaml b/arch/inst/M/mulhsu.yaml index 8acb7cf1e..3836e7b95 100644 --- a/arch/inst/M/mulhsu.yaml +++ b/arch/inst/M/mulhsu.yaml @@ -16,15 +16,28 @@ mulhsu: Microarchitectures may look for that sequence and fuse the operations. definedBy: [M, Zmmul] assembly: xd, xs1, xs2 + encoding: + match: 0000001----------010-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + # enlarge and extend the sources Bits<1> rs1_sign_bit = X[rs1][XLEN-1]; - Bits src1 = {{XLEN{rs1_sign_bit}}, X[rs1]}; - Bits src2 = {{XLEN{1'b0}}, X[rs2]}; + Bits src1 = {{XLEN{rs1_sign_bit}}, X[rs1]}; + Bits src2 = {{XLEN{1'b0}}, X[rs2]}; - X[rd] = (src1 * src2)[(XLEN*2)-1:XLEN]; \ No newline at end of file + X[rd] = (src1 * src2)[(XLEN*8'd2)-1:XLEN]; \ No newline at end of file diff --git a/arch/inst/M/mulhu.yaml b/arch/inst/M/mulhu.yaml index 06b26c3b1..2a1449bc9 100644 --- a/arch/inst/M/mulhu.yaml +++ b/arch/inst/M/mulhu.yaml @@ -16,14 +16,27 @@ mulhu: Microarchitectures may look for that sequence and fuse the operations. definedBy: [M, Zmmul] assembly: xd, xs1, xs2 + encoding: + match: 0000001----------011-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + # enlarge and zero-extend the sources - Bits src1 = {{XLEN{1'b0}}, X[rs1]}; - Bits src2 = {{XLEN{1'b0}}, X[rs2]}; + Bits src1 = {{XLEN{1'b0}}, X[rs1]}; + Bits src2 = {{XLEN{1'b0}}, X[rs2]}; - X[rd] = (src1 * src2)[(XLEN*2)-1:XLEN]; \ No newline at end of file + X[rd] = (src1 * src2)[(XLEN*8'd2)-1:XLEN]; \ No newline at end of file diff --git a/arch/inst/M/mulw.yaml b/arch/inst/M/mulw.yaml index 050c88b37..dbb6985be 100644 --- a/arch/inst/M/mulw.yaml +++ b/arch/inst/M/mulw.yaml @@ -15,12 +15,25 @@ mulw: an alternative is to shift both arguments left by 32 bits, then use MULH[[S]U]. definedBy: [M, Zmmul] assembly: xd, xs1, xs2 + encoding: + match: 0000001----------000-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + Bits<32> src1 = X[rs1][31:0]; Bits<32> src2 = X[rs2][31:0]; diff --git a/arch/inst/M/rem.yaml b/arch/inst/M/rem.yaml index acfc2c27c..676af77fb 100644 --- a/arch/inst/M/rem.yaml +++ b/arch/inst/M/rem.yaml @@ -10,12 +10,25 @@ rem: If the result of the division overflows, write zero into rd; definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------110-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg src1 = X[rs1]; XReg src2 = X[rs2]; diff --git a/arch/inst/M/remu.yaml b/arch/inst/M/remu.yaml index 54405fecd..63fda287a 100644 --- a/arch/inst/M/remu.yaml +++ b/arch/inst/M/remu.yaml @@ -6,12 +6,25 @@ remu: Calculate the remainder of unsigned division of rs1 by rs2, and store the result in rd. definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------111-----0110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + XReg src1 = X[rs1]; XReg src2 = X[rs2]; diff --git a/arch/inst/M/remuw.yaml b/arch/inst/M/remuw.yaml index 3aa58db0b..686f6ead1 100644 --- a/arch/inst/M/remuw.yaml +++ b/arch/inst/M/remuw.yaml @@ -9,12 +9,25 @@ remuw: If the value in rs2 is zero, rd gets the sign-extended value in rs1. definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------111-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + Bits<32> src1 = X[rs1][31:0]; Bits<32> src2 = X[rs2][31:0]; diff --git a/arch/inst/M/remw.yaml b/arch/inst/M/remw.yaml index bc80a4545..1d384e6bb 100644 --- a/arch/inst/M/remw.yaml +++ b/arch/inst/M/remw.yaml @@ -11,12 +11,25 @@ remw: If the result of the division overflows, write zero into rd; definedBy: M assembly: xd, xs1, xs2 + encoding: + match: 0000001----------110-----0111011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always vs: always vu: always operation(): | + if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) { + raise (ExceptionCode::IllegalInstruction, $encoding); + } + Bits<32> src1 = X[rs1][31:0]; Bits<32> src2 = X[rs2][31:0]; diff --git a/arch/inst/S/sfence.vma.yaml b/arch/inst/S/sfence.vma.yaml index 467d7e242..e7c3c959c 100644 --- a/arch/inst/S/sfence.vma.yaml +++ b/arch/inst/S/sfence.vma.yaml @@ -206,6 +206,13 @@ sfence.vma: attempts to execute an SFENCE.VMA instruction might raise an illegal-instruction exception. assembly: xs1, xs2 + encoding: + match: 0001001----------000000001110011 + variables: + - name: rs2 + location: 24-20 + - name: rs1 + location: 19-15 access: s: always u: always diff --git a/arch/inst/S/sret.yaml b/arch/inst/S/sret.yaml index 5e405a55b..412a49550 100644 --- a/arch/inst/S/sret.yaml +++ b/arch/inst/S/sret.yaml @@ -44,6 +44,8 @@ sret: definedBy: S assembly: "" + encoding: + match: '00010000001000000000000001110011' access: s: sometimes u: never @@ -67,32 +69,32 @@ sret: if (implemented?(ExtensionName::H)) { if (CSR[mstatus].TSR == 1'b0 && CSR[hstatus].VTSR == 1'b0) { if (mode() == PrivilegeMode::U) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } else if (mode() == PrivilegeMode::VU) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } else if (CSR[mstatus].TSR == 1'b0 && CSR[hstatus].VTSR == 1'b1) { if (mode() == PrivilegeMode::U) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } else if (mode() == PrivilegeMode::VU || mode() == PrivilegeMode::VS) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } else if (CSR[mstatus].TSR == 1'b1 && CSR[hstatus].VTSR == 1'b0) { if (mode() == PrivilegeMode::U || mode() == PrivilegeMode::S) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } else if (mode() == PrivilegeMode::VU) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } else if (CSR[mstatus].TSR == 1'b1 && CSR[hstatus].VTSR == 1'b1) { if (mode() == PrivilegeMode::U || mode() == PrivilegeMode::S) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } else if (mode() == PrivilegeMode::VU || mode() == PrivilegeMode::VS) { - raise (ExceptionCode::VirtualInstruction); + raise (ExceptionCode::VirtualInstruction, $encoding); } } } else { if (mode() != PrivilegeMode::U) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } } @@ -114,7 +116,7 @@ sret: PC = $bits(CSR[sepc]); } else { if (CSR[mstatus].TSR == 1'b1) { - raise (ExceptionCode::IllegalInstruction); + raise (ExceptionCode::IllegalInstruction, $encoding); } CSR[vsstatus].SPP = 0; CSR[vsstatus].SIE = CSR[vsstatus].SPIE; diff --git a/arch/inst/Zicbom/cbo.clean.yaml b/arch/inst/Zicbom/cbo.clean.yaml index 06bf91071..1e60bf9bf 100644 --- a/arch/inst/Zicbom/cbo.clean.yaml +++ b/arch/inst/Zicbom/cbo.clean.yaml @@ -35,6 +35,11 @@ cbo.clean: definedBy: Zicbom assembly: "TODO" + encoding: + match: 000000000001-----010000000001111 + variables: + - name: rs1 + location: 19-15 access: m: always s: sometimes diff --git a/arch/inst/Zicbom/cbo.flush.yaml b/arch/inst/Zicbom/cbo.flush.yaml index 33c8ade6b..397bc921f 100644 --- a/arch/inst/Zicbom/cbo.flush.yaml +++ b/arch/inst/Zicbom/cbo.flush.yaml @@ -28,6 +28,11 @@ cbo.flush: CBO operations never raise a misaligned address fault. definedBy: Zicbom assembly: "TODO" + encoding: + match: 000000000010-----010000000001111 + variables: + - name: rs1 + location: 19-15 access: m: always s: sometimes diff --git a/arch/inst/Zicbom/cbo.inval.yaml b/arch/inst/Zicbom/cbo.inval.yaml index cd895a22d..73bebfbc0 100644 --- a/arch/inst/Zicbom/cbo.inval.yaml +++ b/arch/inst/Zicbom/cbo.inval.yaml @@ -67,6 +67,11 @@ cbo.inval: CBO operations never raise a misaligned address fault. definedBy: Zicbom assembly: "TODO" + encoding: + match: 000000000000-----010000000001111 + variables: + - name: rs1 + location: 19-15 access: m: always s: sometimes diff --git a/arch/inst/Zicboz/cbo.zero.yaml b/arch/inst/Zicboz/cbo.zero.yaml index b01552725..423e077d6 100644 --- a/arch/inst/Zicboz/cbo.zero.yaml +++ b/arch/inst/Zicboz/cbo.zero.yaml @@ -30,6 +30,11 @@ cbo.zero: CBO operations never raise a misaligned address fault. definedBy: Zicboz assembly: "TODO" + encoding: + match: 000000000100-----010000000001111 + variables: + - name: rs1 + location: 19-15 access: m: always s: sometimes diff --git a/arch/inst/Zicsr/csrrs.yaml b/arch/inst/Zicsr/csrrs.yaml index 16bc5a02c..2af31cf8d 100644 --- a/arch/inst/Zicsr/csrrs.yaml +++ b/arch/inst/Zicsr/csrrs.yaml @@ -13,6 +13,15 @@ csrrs: Other bits in the CSR are not explicitly written. definedBy: Zicsr assembly: xd, xs1, csr + encoding: + match: -----------------000-----0010011 + variables: + - name: csr + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/Zicsr/csrrw.yaml b/arch/inst/Zicsr/csrrw.yaml index 71320dd28..30e2efb29 100644 --- a/arch/inst/Zicsr/csrrw.yaml +++ b/arch/inst/Zicsr/csrrw.yaml @@ -12,6 +12,15 @@ csrrw: cause any of the side effects that might occur on a CSR read. definedBy: Zicsr assembly: xd, xs1, csr + encoding: + match: -----------------001-----1110011 + variables: + - name: csr + location: 31-20 + - name: rs1 + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always diff --git a/arch/inst/Zicsr/csrrwi.yaml b/arch/inst/Zicsr/csrrwi.yaml index 1fe8de5dc..f0b87c423 100644 --- a/arch/inst/Zicsr/csrrwi.yaml +++ b/arch/inst/Zicsr/csrrwi.yaml @@ -12,6 +12,15 @@ csrrwi: cause any of the side effects that might occur on a CSR read. definedBy: Zicsr assembly: xd, zimm, csr + encoding: + match: -----------------101-----1110011 + variables: + - name: csr + location: 31-20 + - name: imm + location: 19-15 + - name: rd + location: 11-7 access: s: always u: always @@ -24,4 +33,4 @@ csrrwi: # writes the zero-extended immediate to the CSR, # performing any WARL transformations first - CSR[csr].sw_write({{XLEN-5{1'b0}}, zimm}); + CSR[csr].sw_write({{XLEN-5{1'b0}}, imm}); diff --git a/arch/isa/globals.isa b/arch/isa/globals.isa index bc3196391..b144b756b 100644 --- a/arch/isa/globals.isa +++ b/arch/isa/globals.isa @@ -105,7 +105,9 @@ enum ExceptionCode { LoadPageFault 13 // reserved 14 StoreAmoPageFault 15 - // reserved 16-19 + // reserved 16-17 + SoftwareCheck 18 + HardwareError 19 InstructionGuestPageFault 20 LoadGuestPageFault 21 VirtualInstruction 22 @@ -258,8 +260,203 @@ function exception_handling_mode { } } +function mtval_readonly? { + returns Boolean + description { + Returns whether or not CSR[mtval] is read-only based on implementation options + } + body { + return !( + REPORT_VA_IN_MTVAL_ON_BREAKPOINT || + REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT || + REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION || + REPORT_CAUSE_IN_MTVAL_ON_SOFTWARE_CHECK || + implemented?(ExtensionName::Sdext) + ); + } +} + +function stval_readonly? { + returns Boolean + description { + Returns whether or not CSR[stval] is read-only based on implementation options + } + body { + if (implemented?(ExtensionName::S)) { + return !( + REPORT_VA_IN_STVAL_ON_BREAKPOINT || + REPORT_VA_IN_STVAL_ON_LOAD_MISALIGNED || + REPORT_VA_IN_STVAL_ON_STORE_AMO_MISALIGNED || + REPORT_VA_IN_STVAL_ON_INSTRUCTION_MISALIGNED || + REPORT_VA_IN_STVAL_ON_LOAD_ACCESS_FAULT || + REPORT_VA_IN_STVAL_ON_STORE_AMO_ACCESS_FAULT || + REPORT_VA_IN_STVAL_ON_INSTRUCTION_ACCESS_FAULT || + REPORT_VA_IN_STVAL_ON_LOAD_PAGE_FAULT || + REPORT_VA_IN_STVAL_ON_STORE_AMO_PAGE_FAULT || + REPORT_VA_IN_STVAL_ON_INSTRUCTION_PAGE_FAULT || + REPORT_ENCODING_IN_STVAL_ON_ILLEGAL_INSTRUCTION || + REPORT_CAUSE_IN_STVAL_ON_SOFTWARE_CHECK || + implemented?(ExtensionName::Sdext) + ); + } else { + return true; + } + } +} + +function vstval_readonly? { + returns Boolean + description { + Returns whether or not CSR[vstval] is read-only based on implementation options + } + body { + if (implemented?(ExtensionName::H)) { + return !( + REPORT_VA_IN_VSTVAL_ON_BREAKPOINT || + REPORT_VA_IN_VSTVAL_ON_LOAD_MISALIGNED || + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_MISALIGNED || + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_MISALIGNED || + REPORT_VA_IN_VSTVAL_ON_LOAD_ACCESS_FAULT || + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_ACCESS_FAULT || + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_ACCESS_FAULT || + REPORT_VA_IN_VSTVAL_ON_LOAD_PAGE_FAULT || + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_PAGE_FAULT || + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_PAGE_FAULT || + REPORT_ENCODING_IN_VSTVAL_ON_ILLEGAL_INSTRUCTION || + REPORT_CAUSE_IN_VSTVAL_ON_SOFTWARE_CHECK || + implemented?(ExtensionName::Sdext) + ); + } else { + return true; + } + } +} + +function mtval_for { + returns XReg + arguments ExceptionCode exception_code, XReg tval + description { + Given an exception code and a *legal* non-zero value for mtval, + returns the value to be written in mtval considering implementation options + } + body { + if (exception_code == ExceptionCode::Breakpoint) { + return REPORT_VA_IN_MTVAL_ON_BREAKPOINT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAddressMisaligned) { + return REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAddressMisaligned) { + return REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAddressMisaligned) { + return REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAccessFault) { + return REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAccessFault) { + return REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAccessFault) { + return REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadPageFault) { + return REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoPageFault) { + return REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionPageFault) { + return REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::IllegalInstruction) { + return REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION ? tval : 0; + } else if (exception_code == ExceptionCode::SoftwareCheck) { + return REPORT_CAUSE_IN_MTVAL_ON_SOFTWARE_CHECK ? tval : 0; + } else { + return 0; + } + } +} + +function stval_for { + returns XReg + arguments ExceptionCode exception_code, XReg tval + description { + Given an exception code and a *legal* non-zero value for stval, + returns the value to be written in stval considering implementation options + } + body { + if (exception_code == ExceptionCode::Breakpoint) { + return REPORT_VA_IN_STVAL_ON_BREAKPOINT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAddressMisaligned) { + return REPORT_VA_IN_STVAL_ON_LOAD_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAddressMisaligned) { + return REPORT_VA_IN_STVAL_ON_STORE_AMO_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAddressMisaligned) { + return REPORT_VA_IN_STVAL_ON_INSTRUCTION_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAccessFault) { + return REPORT_VA_IN_STVAL_ON_LOAD_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAccessFault) { + return REPORT_VA_IN_STVAL_ON_STORE_AMO_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAccessFault) { + return REPORT_VA_IN_STVAL_ON_INSTRUCTION_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadPageFault) { + return REPORT_VA_IN_STVAL_ON_LOAD_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoPageFault) { + return REPORT_VA_IN_STVAL_ON_STORE_AMO_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionPageFault) { + return REPORT_VA_IN_STVAL_ON_INSTRUCTION_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::IllegalInstruction) { + return REPORT_ENCODING_IN_STVAL_ON_ILLEGAL_INSTRUCTION ? tval : 0; + } else if (exception_code == ExceptionCode::SoftwareCheck) { + return REPORT_CAUSE_IN_STVAL_ON_SOFTWARE_CHECK ? tval : 0; + } else { + return 0; + } + } +} + + +function vstval_for { + returns XReg + arguments ExceptionCode exception_code, XReg tval + description { + Given an exception code and a *legal* non-zero value for vstval, + returns the value to be written in vstval considering implementation options + } + body { + if (exception_code == ExceptionCode::Breakpoint) { + return REPORT_VA_IN_VSTVAL_ON_BREAKPOINT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAddressMisaligned) { + return REPORT_VA_IN_VSTVAL_ON_LOAD_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAddressMisaligned) { + return REPORT_VA_IN_VSTVAL_ON_STORE_AMO_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAddressMisaligned) { + return REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_MISALIGNED ? tval : 0; + } else if (exception_code == ExceptionCode::LoadAccessFault) { + return REPORT_VA_IN_VSTVAL_ON_LOAD_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoAccessFault) { + return REPORT_VA_IN_VSTVAL_ON_STORE_AMO_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionAccessFault) { + return REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_ACCESS_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::LoadPageFault) { + return REPORT_VA_IN_VSTVAL_ON_LOAD_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::StoreAmoPageFault) { + return REPORT_VA_IN_VSTVAL_ON_STORE_AMO_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::InstructionPageFault) { + return REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_PAGE_FAULT ? tval : 0; + } else if (exception_code == ExceptionCode::IllegalInstruction) { + return REPORT_ENCODING_IN_VSTVAL_ON_ILLEGAL_INSTRUCTION ? tval : 0; + } else if (exception_code == ExceptionCode::SoftwareCheck) { + return REPORT_CAUSE_IN_VSTVAL_ON_SOFTWARE_CHECK ? tval : 0; + } else { + return 0; + } + } +} + function raise { - arguments ExceptionCode exception_code + arguments ExceptionCode exception_code, XReg tval description { Raise synchronous exception number `exception_code`. } @@ -268,16 +465,24 @@ function raise { if (handling_mode == PrivilegeMode::M) { CSR[mepc] = PC; + if (!mtval_readonly?()) { + CSR[mtval] = mtval_for(exception_code, tval); + } PC = {CSR[mtvec].BASE, 2'b00}; CSR[mcause] = exception_code.value; - // note that mtval is set elsewhere } else if (implemented?(ExtensionName::S) && (handling_mode == PrivilegeMode::HS)) { CSR[sepc] = PC; + if (!stval_readonly?()) { + CSR[stval] = stval_for(exception_code, tval); + } PC = {CSR[stvec].BASE, 2'b00}; CSR[scause] = exception_code.value; // note that stval is set elsewhere } else if (implemented?(ExtensionName::H) && (handling_mode == PrivilegeMode::VS)) { CSR[vsepc] = PC; + if (!vstval_readonly?()) { + CSR[vstval] = vstval_for(exception_code, tval); + } PC = {CSR[vstvec].BASE, 2'b00}; CSR[vscause] = exception_code.value; } @@ -300,9 +505,9 @@ function jump { if (implemented?(ExtensionName::C) && # C is implemented (CSR[misa].C == 0x1) && # and C is enabled dynamically ((target_addr & 0x1) != 0)) { # and the target PC is odd - raise(ExceptionCode::InstructionAddressMisaligned); + raise(ExceptionCode::InstructionAddressMisaligned, target_addr); } else if ((target_addr & 0x3) != 0) { - raise(ExceptionCode::InstructionAddressMisaligned); + raise(ExceptionCode::InstructionAddressMisaligned, target_addr); } PC = target_addr; @@ -882,7 +1087,7 @@ function pmp_check { function access_check { template U32 access_size returns Boolean, ExceptionCode - arguments Bits paddr, MemoryOperation type + arguments Bits paddr, XReg vaddr, MemoryOperation type description { Returns True if the current privilege mode cannot access the physical address paddr. } @@ -890,11 +1095,11 @@ function access_check { # check if this is a valid physical address if (paddr > ((1 << PHYS_ADDR_WIDTH) - access_size)) { if (type == MemoryOperation::Write) { - raise (ExceptionCode::StoreAmoAccessFault); + raise (ExceptionCode::StoreAmoAccessFault, vaddr); } else if (type == MemoryOperation::Read) { - raise (ExceptionCode::LoadAccessFault); + raise (ExceptionCode::LoadAccessFault, vaddr); } else if (type == MemoryOperation::Fetch) { - raise (ExceptionCode::InstructionAccessFault); + raise (ExceptionCode::InstructionAccessFault, vaddr); } } @@ -902,11 +1107,11 @@ function access_check { # can return either AccessFault or AddressMisalignedException if (!pmp_check(paddr[PHYS_ADDR_WIDTH-1:0], type)) { if (type == MemoryOperation::Write) { - raise (ExceptionCode::StoreAmoAccessFault); + raise (ExceptionCode::StoreAmoAccessFault, vaddr); } else if (type == MemoryOperation::Read) { - raise (ExceptionCode::LoadAccessFault); + raise (ExceptionCode::LoadAccessFault, vaddr); } else if (type == MemoryOperation::Fetch) { - raise (ExceptionCode::InstructionAccessFault); + raise (ExceptionCode::InstructionAccessFault, vaddr); } } return false, -; @@ -1119,14 +1324,14 @@ function translate_sv39 { # non-canonical virtual address raises a page fault # note that if pointer masking is enabled, # vaddr has already been transformed before reaching here - raise (ecode); + raise (ecode, vaddr); } for (U32 i = 2; i >= 0; i--) { XReg pte_addr = (ppn << 12) + ((vaddr >> (12 + 9*i)) & 0x1ff); # perform access check on the physical address of pte before it's used - access_check<64>(pte_addr, op); + access_check<64>(pte_addr, vaddr, op); Sv39PageTableEntry pte = read_physical_memory<64>(pte_addr); if (pte.V == 0 # invalid entry @@ -1135,7 +1340,7 @@ function translate_sv39 { # || (!implemented?(ExtensionName::Svnapot) && pte.N != 0) # || (!implemented?(ExtensionName::Svpbmt) && pte.PBMT != 0)) { # found invalid PTE - raise (ecode); + raise (ecode, vaddr); } else if (pte.R == 1 || pte.X == 1) { # found a leaf PTE @@ -1143,27 +1348,27 @@ function translate_sv39 { if ((CSR[mstatus].MXR == 0 && pte.R == 0) || (CSR[mstatus].MXR == 1 && pte.X == 0 && pte.R == 0)) { # no read permission - raise (ExceptionCode::LoadPageFault); + raise (ExceptionCode::LoadPageFault, vaddr); } if ((mode() == PrivilegeMode::U && pte.U == 0) || (mode() == PrivilegeMode::M && CSR[mstatus].MPRV == 1 && CSR[mstatus].MPP == $bits(PrivilegeMode::HS) && pte.U == 1 && CSR[mstatus].SUM == 0) || (mode() == PrivilegeMode::S && pte.U == 1 && CSR[mstatus].SUM == 0)) { # supervisor cannot read U unless mstatus.SUM = 1 - raise (ExceptionCode::LoadPageFault); + raise (ExceptionCode::LoadPageFault, vaddr); } } else if ((op == MemoryOperation::Write) && (pte.W == 0)) { # no write permission - raise (ExceptionCode::StoreAmoPageFault); + raise (ExceptionCode::StoreAmoPageFault, vaddr); } else if ((op == MemoryOperation::Fetch) && (pte.X == 0)) { # no execute permission - raise (ExceptionCode::InstructionPageFault); + raise (ExceptionCode::InstructionPageFault, vaddr); } if (pte.U == 0) { # supervisor page if (mode() == PrivilegeMode::U) { # user access to supervisor page is never allowed - raise (ecode); + raise (ecode, vaddr); } } else { # user page @@ -1172,26 +1377,26 @@ function translate_sv39 { if (op == MemoryOperation::Read) { if (CSR[mstatus].SUM == 0) { # supervisor can only read user pages when mstatus.SUM == 1 - raise (ExceptionCode::LoadPageFault); + raise (ExceptionCode::LoadPageFault, vaddr); } } else { # supervisor can never write or execute a user page - raise (ecode); + raise (ecode, vaddr); } } } # ensure remaining PPN bits are zero, otherwise there is a misaligned super page - raise (ecode) if (i >= 1 && pte.PPN0 != 0); - raise (ecode) if (i == 2 && pte.PPN1 != 0); + raise (ecode, vaddr) if (i >= 1 && pte.PPN0 != 0); + raise (ecode, vaddr) if (i == 2 && pte.PPN1 != 0); if (false) { // implemented?(ExtensionName::Svadu)) { # svadu requires page tables to be located in memory with hardware page-table write access # and RsrvEventual PMA if (!check_pma(pte_addr, PmaAttribute::RsrvEventual)) { - raise (ExceptionCode::LoadAccessFault); + raise (ExceptionCode::LoadAccessFault, vaddr); } - access_check<64>(pte_addr, MemoryOperation::Write); + access_check<64>(pte_addr, vaddr, MemoryOperation::Write); # if (implemented?(ExtensionName::H) && CSR[henvcfg].ADUE == 0b1) { # update the A bit # this should be atomic with the translation @@ -1205,7 +1410,7 @@ function translate_sv39 { if (//implemented?(ExtensionName::Svade) && pte.A == 0) { # trap on access with A == 0 - raise (ecode); + raise (ecode, vaddr); } # translation succeeded @@ -1215,12 +1420,12 @@ function translate_sv39 { if (i == 0) { # a pointer can't exist on the last level - raise (ecode); + raise (ecode, vaddr); } if (pte.D == 1 || pte.A == 1 || pte.U == 1) { # D, A, and U are reserved in non-leaf PTEs - raise (ecode); + raise (ecode, vaddr); } ppn = pte.PPN << 12; @@ -1293,12 +1498,12 @@ function translate { # bare == no translation if (vaddr > ((1 << PHYS_ADDR_WIDTH) - 1)) { if (op == MemoryOperation::Read) { - raise (ExceptionCode::LoadAccessFault); + raise (ExceptionCode::LoadAccessFault, vaddr); } else if (op == MemoryOperation::Write) { - raise (ExceptionCode::StoreAmoAccessFault); + raise (ExceptionCode::StoreAmoAccessFault, vaddr); } else { assert(op == MemoryOperation::Fetch); - raise (ExceptionCode::InstructionAccessFault); + raise (ExceptionCode::InstructionAccessFault, vaddr); } } return vaddr; @@ -1335,7 +1540,7 @@ function read_memory_aligned { : virtual_address; # may raise an exception - access_check(physical_address, MemoryOperation::Read); + access_check(physical_address, virtual_address, MemoryOperation::Read); return read_physical_memory(physical_address); } @@ -1354,7 +1559,7 @@ function read_memory { if (aligned) { return read_memory_aligned(virtual_address); } else if (!aligned && !MISALIGNED_LDST) { - raise (ExceptionCode::LoadAddressMisaligned); + raise (ExceptionCode::LoadAddressMisaligned, virtual_address); } else { # misaligned, must break into multiple reads Bits result = 0; @@ -1366,6 +1571,10 @@ function read_memory { } } +//function load_reserved { +// +//} + @@ -1383,7 +1592,7 @@ function write_memory_aligned { : virtual_address; # may raise an exception - access_check(physical_address, MemoryOperation::Write); + access_check(physical_address, virtual_address, MemoryOperation::Write); write_physical_memory(physical_address, value); } @@ -1401,7 +1610,7 @@ function write_memory { if (aligned) { write_memory_aligned(virtual_address, value); } else if (!aligned && !MISALIGNED_LDST) { - raise (ExceptionCode::StoreAmoAddressMisaligned); + raise (ExceptionCode::StoreAmoAddressMisaligned, virtual_address); } else { # misaligned, must break into multiple writes for (U32 i = 0; i <= len; i++) { @@ -1411,34 +1620,3 @@ function write_memory { } } -// function Mem { -// template U32 len -// returns XReg -// arguments XReg eaddr -// description { -// Read memory. -// } -// body { -// XReg vaddr, paddr; -// Boolean has_fault; -// ExceptionCode ecode; -// -// # by default, vaddr = eaddr -// vaddr = mask_eaddr(eaddr); -// -// (paddr, ecode) = translate_load(vaddr); -// raise (ExceptionCode::LoadPageFault) if (ecode == ExceptionCode::LoadPageFault); -// raise (ExceptionCode::LoadGuestPageFault) if (ecode == ExceptionCode::LoadGuestPageFault); -// raise (ExceptionCode::LoadAccessFault) if (ecode == ExceptionCode::LoadAccessFault); -// -// (has_fault, ecode) = access_check(paddr, MemoryOperation::Read); -// -// # Load Address Misaligned is a lower-priority exception than Page Fault -// # it is higher-priority than access fault if Zihpme (High-Priority Misaligned Exception) is implemented -// raise (ExceptionCode::LoadAddressMisaligned) if implemented?(ExtensionName::Zihpme) && has_fault && (ecode == ExceptionCode::LoadAddressMisaligned); -// raise (ExceptionCode::LoadAccessFault) if has_fault && (ecode == ExceptionCode::LoadAccessFault); -// raise (ExceptionCode::LoadAddressMisaligned) if !implemented?(ExtensionName::Zihpme) && has_fault && (ecode == ExceptionCode::LoadAddressMisaligned); -// -// return read_physical_memory(paddr); -// } -// } diff --git a/arch/prose/idl.adoc b/arch/prose/idl.adoc index 7811f9d62..7c1ffe08d 100644 --- a/arch/prose/idl.adoc +++ b/arch/prose/idl.adoc @@ -219,7 +219,8 @@ Literals may contain any number of underscores after the initial digit for clari -8'sd13 # -13 decimal, signed, 8-bit wide -16'shd # -13 decimal, signed, 16-bit wide -12'so15 # -13 decimal, signed, 12-bit wide --4'sb1101 # -13 decimal, signed, 4-bit wide +4'sb1101 # -3 decimal, signed, 4-bit wide +-4'sb1101 # 3 decimal, signed, 4-bit wide 32'h80000000 # 0x8000000, unsigned, 32-bit wide 32'h8000_0000 # same as above (underscores ignored) @@ -228,11 +229,12 @@ Literals may contain any number of underscores after the initial digit for clari '13 # 13 decimal, unsigned XLEN-bit wide 's13 # 13 decimal, signed XLEN-bit wide +# 'h100000000 # compilation error when XLEN == 32; does not fit in XLEN bits -4'd13 # 3 decimal: the literal is 13, unsigned, in 4-bits. when negated, the sign bit is lost # -8'sd200 # compilation error: -200 does not fit in 8 bits # 0'15 # compilation error: cannot have integer with 0 length -# 4'xff # compilation error: value does not fit in 4 bits +# 4'hff # compilation error: value does not fit in 4 bits ---- .C style literals diff --git a/cfgs/config_validation.rb b/cfgs/config_validation.rb index 0936d2a5b..2af4f1061 100644 --- a/cfgs/config_validation.rb +++ b/cfgs/config_validation.rb @@ -21,6 +21,36 @@ # is SXLEN is fixed to 32, then UXLEN cannot be > 32 assert [nil, 32].include?(UXLEN) if ext?(:S) && ext?(:U) && SXLEN == 32 +max_va_width = + if ext?(:Sv57) + 57 + elsif ext?(:Sv48) + 48 + elsif ext?(:Sv39) + 39 + elsif ext?(:Sv32) + 32 + else + PHYS_ADDR_WIDTH + end +mtval_holds_va = + REPORT_VA_IN_MTVAL_ON_BREAKPOINT || + REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED || + REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT || + REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT || + REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT || + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT || + ext?(:Sdext) + +assert(MTVAL_WIDTH >= max_va_width) if mtval_holds_va + +# 32 stands for ILEN below. Update this if/when instructions become longer than 32 +assert(MTVAL_WIDTH >= [XLEN, 32].min) if REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION + # check for conditionally required params require_param :MUTABLE_MISA_A if ext?(:A) require_param :MUTABLE_MISA_B if ext?(:B) diff --git a/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml b/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml index 2f6885833..bbc9db3e0 100644 --- a/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml +++ b/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml @@ -4,5 +4,6 @@ Xcustom: versions: - version: 0.1 ratification_date: null + state: development description: | A new custom extension! diff --git a/cfgs/generic_rv64/params.yaml b/cfgs/generic_rv64/params.yaml index 7e898f37e..5f9ef8b58 100644 --- a/cfgs/generic_rv64/params.yaml +++ b/cfgs/generic_rv64/params.yaml @@ -77,7 +77,47 @@ params: # when false, *tval is written with 0 on an EBREAK instruction # # regardless, *tval is always written with a virtual PC when an external breakpoint is generated - REPORT_EBREAK_PC_IN_TVAL: false + REPORT_VA_IN_MTVAL_ON_BREAKPOINT: true + + REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT: true + REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT: true + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT: true + REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT: true + REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT: true + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT: true + REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION: true + REPORT_CAUSE_IN_MTVAL_ON_SOFTWARE_CHECK: true + MTVAL_WIDTH: 64 # must check that this can hold any valid VA if any REPORT_VA* or Sdext, and, if REPORT_ENCODING*, at least [MXLEN, ILEN].min bits + + REPORT_VA_IN_STVAL_ON_BREAKPOINT: true + REPORT_VA_IN_STVAL_ON_STORE_AMO_MISALIGNED: true + REPORT_VA_IN_STVAL_ON_INSTRUCTION_MISALIGNED: true + REPORT_VA_IN_STVAL_ON_LOAD_ACCESS_FAULT: true + REPORT_VA_IN_STVAL_ON_STORE_AMO_ACCESS_FAULT: true + REPORT_VA_IN_STVAL_ON_INSTRUCTION_ACCESS_FAULT: true + REPORT_VA_IN_STVAL_ON_LOAD_PAGE_FAULT: true + REPORT_VA_IN_STVAL_ON_STORE_AMO_PAGE_FAULT: true + REPORT_VA_IN_STVAL_ON_INSTRUCTION_PAGE_FAULT: true + REPORT_ENCODING_IN_STVAL_ON_ILLEGAL_INSTRUCTION: true + REPORT_CAUSE_IN_STVAL_ON_SOFTWARE_CHECK: true + STVAL_WIDTH: 64 # must check that this can hold any valid VA, and, if REPORT_ENCODING*, at least [SXLEN, ILEN].min bits + + REPORT_VA_IN_VSTVAL_ON_BREAKPOINT: true + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_MISALIGNED: true + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_MISALIGNED: true + REPORT_VA_IN_VSTVAL_ON_LOAD_ACCESS_FAULT: true + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_ACCESS_FAULT: true + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_ACCESS_FAULT: true + REPORT_VA_IN_VSTVAL_ON_LOAD_PAGE_FAULT: true + REPORT_VA_IN_VSTVAL_ON_STORE_AMO_PAGE_FAULT: true + REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_PAGE_FAULT: true + REPORT_ENCODING_IN_VSTVAL_ON_ILLEGAL_INSTRUCTION: true + REPORT_CAUSE_IN_VSTVAL_ON_SOFTWARE_CHECK: true + # VSTVAL_WIDTH not needed; "vstval is a WARL register that must be able to hold the same set of values that stval can hold" + # address of the unified discovery configuration data structure # this address is reported in the mconfigptr CSR diff --git a/docs/ruby/ArchDef.html b/docs/ruby/ArchDef.html index 83c19aead..badaa367d 100644 --- a/docs/ruby/ArchDef.html +++ b/docs/ruby/ArchDef.html @@ -143,6 +143,35 @@

Instance Attribute Summary collaps

The configuration parameters.

+ + + +
  • + + + #global_ast ⇒ Idl::AstNode + + + + + + + + + readonly + + + + + + + + + +
    +

    Abstract syntax tree of global scope.

    +
    +
  • @@ -754,34 +783,34 @@

     
     
    -1220
    -1221
    -1222
    -1223
    -1224
    -1225
    -1226
    -1227
    -1228
    -1229
    -1230
    -1231
    -1232
    -1233
    -1234
    -1235
    -1236
    -1237
    -1238
    -1239
    -1240
    -1241
    -1242
    -1243
    -1244
    +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 -
    # File 'lib/arch_def.rb', line 1220
    +      
    # File 'lib/arch_def.rb', line 1251
     
     def initialize(config_name)
       @name = config_name.to_s
    @@ -803,7 +832,7 @@ 

    @idl_compiler = Idl::Compiler.new(self) # load the globals into the symbol table - @idl_compiler.compile_file( + @global_ast = @idl_compiler.compile_file( $root / "arch" / "isa" / "globals.isa", @sym_table ) @@ -864,12 +893,12 @@

     
     
    -1211
    -1212
    -1213
    +1239 +1240 +1241

    -
    # File 'lib/arch_def.rb', line 1211
    +      
    # File 'lib/arch_def.rb', line 1239
     
     def config_params
       @config_params
    @@ -880,6 +909,67 @@ 

    + +
    +

    + + #global_astIdl::AstNode (readonly) + + + + + +

    +
    + +

    Returns Abstract syntax tree of global scope.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Idl::AstNode) + + + + — +
      +

      Abstract syntax tree of global scope

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +1245
    +1246
    +1247
    +
    +
    # File 'lib/arch_def.rb', line 1245
    +
    +def global_ast
    +  @global_ast
    +end
    +
    +
    + +

    @@ -925,12 +1015,12 @@

     
     
    -1214
    -1215
    -1216
    +1242 +1243 +1244

    -
    # File 'lib/arch_def.rb', line 1214
    +      
    # File 'lib/arch_def.rb', line 1242
     
     def idl_compiler
       @idl_compiler
    @@ -986,12 +1076,12 @@ 

     
     
    -1205
    -1206
    -1207
    +1233 +1234 +1235

    -
    # File 'lib/arch_def.rb', line 1205
    +      
    # File 'lib/arch_def.rb', line 1233
     
     def name
       @name
    @@ -1047,12 +1137,12 @@ 

     
     
    -1208
    -1209
    -1210
    +1236 +1237 +1238

    -
    # File 'lib/arch_def.rb', line 1208
    +      
    # File 'lib/arch_def.rb', line 1236
     
     def sym_table
       @sym_table
    @@ -1113,12 +1203,12 @@ 

     
     
    -1343
    -1344
    -1345
    +1374 +1375 +1376

    -
    # File 'lib/arch_def.rb', line 1343
    +      
    # File 'lib/arch_def.rb', line 1374
     
     def all_known_csr_names
       @arch_def["csrs"].map { |csr| csr[0] }
    @@ -1192,12 +1282,12 @@ 

     
     
    -1377
    -1378
    -1379
    +1408 +1409 +1410

    -
    # File 'lib/arch_def.rb', line 1377
    +      
    # File 'lib/arch_def.rb', line 1408
     
     def csr(csr_name)
       csr_hash[csr_name]
    @@ -1251,18 +1341,18 @@ 

     
     
    -1359
    -1360
    -1361
    -1362
    -1363
    -1364
    -1365
    -1366
    -1367
    +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398

    -
    # File 'lib/arch_def.rb', line 1359
    +      
    # File 'lib/arch_def.rb', line 1390
     
     def csr_hash
       return @csr_hash unless @csr_hash.nil?
    @@ -1322,16 +1412,16 @@ 

     
     
    -1333
    -1334
    -1335
    -1336
    -1337
    -1338
    -1339
    +1364 +1365 +1366 +1367 +1368 +1369 +1370

    -
    # File 'lib/arch_def.rb', line 1333
    +      
    # File 'lib/arch_def.rb', line 1364
     
     def csrs
       return @csrs unless @csrs.nil?
    @@ -1389,12 +1479,12 @@ 

     
     
    -1319
    -1320
    -1321
    +1350 +1351 +1352

    -
    # File 'lib/arch_def.rb', line 1319
    +      
    # File 'lib/arch_def.rb', line 1350
     
     def data
       @arch_def
    @@ -1596,19 +1686,19 @@ 

     
     
    -1307
    -1308
    -1309
    -1310
    -1311
    -1312
    -1313
    -1314
    -1315
    -1316
    +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347

    -
    # File 'lib/arch_def.rb', line 1307
    +      
    # File 'lib/arch_def.rb', line 1338
     
     def ext?(ext_name, *ext_version_requirements)
       implemented_extensions.any? do |e|
    @@ -1701,12 +1791,12 @@ 

     
     
    -1289
    -1290
    -1291
    +1320 +1321 +1322

    -
    # File 'lib/arch_def.rb', line 1289
    +      
    # File 'lib/arch_def.rb', line 1320
     
     def extension(name)
       extension_hash[name.to_s]
    @@ -1731,18 +1821,18 @@ 

     
     
    -1276
    -1277
    -1278
    -1279
    -1280
    -1281
    -1282
    -1283
    -1284
    +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315

    -
    # File 'lib/arch_def.rb', line 1276
    +      
    # File 'lib/arch_def.rb', line 1307
     
     def extension_hash
       return @extension_hash unless @extension_hash.nil?
    @@ -1802,18 +1892,18 @@ 

     
     
    -1265
    -1266
    -1267
    -1268
    -1269
    -1270
    -1271
    -1272
    -1273
    +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304

    -
    # File 'lib/arch_def.rb', line 1265
    +      
    # File 'lib/arch_def.rb', line 1296
     
     def extensions
       return @extensions unless @extensions.nil?
    @@ -1893,27 +1983,27 @@ 
    -
    # File 'lib/arch_def.rb', line 1429
    +      
    # File 'lib/arch_def.rb', line 1460
     
     def find_replace_links(adoc)
       adoc.gsub(/`([\w.]+)`/) do |match|
    @@ -1921,13 +2011,13 @@ 

     
     
    -1371
    -1372
    -1373
    +1402 +1403 +1404

    -
    # File 'lib/arch_def.rb', line 1371
    +      
    # File 'lib/arch_def.rb', line 1402
     
     def implemented_csr(csr_name)
       implemented_csr_hash[csr_name]
    @@ -2061,18 +2151,18 @@ 

     
     
    -1348
    -1349
    -1350
    -1351
    -1352
    -1353
    -1354
    -1355
    -1356
    +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387

    -
    # File 'lib/arch_def.rb', line 1348
    +      
    # File 'lib/arch_def.rb', line 1379
     
     def implemented_csr_hash
       return @implemented_csr_hash unless @implemented_csr_hash.nil?
    @@ -2132,16 +2222,16 @@ 

     
     
    -1324
    -1325
    -1326
    -1327
    -1328
    -1329
    -1330
    +1355 +1356 +1357 +1358 +1359 +1360 +1361

    -
    # File 'lib/arch_def.rb', line 1324
    +      
    # File 'lib/arch_def.rb', line 1355
     
     def implemented_csrs
       return @implemented_csrs unless @implemented_csrs.nil?
    @@ -2199,19 +2289,19 @@ 

     
     
    -1253
    -1254
    -1255
    -1256
    -1257
    -1258
    -1259
    -1260
    -1261
    -1262
    +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293

    -
    # File 'lib/arch_def.rb', line 1253
    +      
    # File 'lib/arch_def.rb', line 1284
     
     def implemented_extensions
       return @implemented_extensions unless @implemented_extensions.nil?
    @@ -2272,20 +2362,20 @@ 

     
     
    -1406
    -1407
    -1408
    -1409
    -1410
    -1411
    -1412
    -1413
    -1414
    -1415
    -1416
    +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447

    -
    # File 'lib/arch_def.rb', line 1406
    +      
    # File 'lib/arch_def.rb', line 1437
     
     def implemented_instructions
       return @implemented_instructions unless @implemented_instructions.nil?
    @@ -2367,12 +2457,12 @@ 

     
     
    -1420
    -1421
    -1422
    +1451 +1452 +1453

    -
    # File 'lib/arch_def.rb', line 1420
    +      
    # File 'lib/arch_def.rb', line 1451
     
     def inst(inst_name)
       instruction_hash[inst_name.to_s]
    @@ -2426,18 +2516,18 @@ 

     
     
    -1395
    -1396
    -1397
    -1398
    -1399
    -1400
    -1401
    -1402
    -1403
    +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434

    -
    # File 'lib/arch_def.rb', line 1395
    +      
    # File 'lib/arch_def.rb', line 1426
     
     def instruction_hash
       return @instruction_hash unless @instruction_hash.nil?
    @@ -2497,20 +2587,20 @@ 

     
     
    -1382
    -1383
    -1384
    -1385
    -1386
    -1387
    -1388
    -1389
    -1390
    -1391
    -1392
    +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423

    -
    # File 'lib/arch_def.rb', line 1382
    +      
    # File 'lib/arch_def.rb', line 1413
     
     def instructions
       return @instructions unless @instructions.nil?
    @@ -2572,12 +2662,12 @@ 

     
     
    -1248
    -1249
    -1250
    +1279 +1280 +1281

    -
    # File 'lib/arch_def.rb', line 1248
    +      
    # File 'lib/arch_def.rb', line 1279
     
     def multi_xlen?
       ["SXLEN", "UXLEN", "VSXLEN", "VUXLEN"].any? { |key| @config_params[key] == 3264 }
    @@ -2592,7 +2682,7 @@ 

    diff --git a/docs/ruby/ArchDefObject.html b/docs/ruby/ArchDefObject.html index c3bc59380..3118f3095 100644 --- a/docs/ruby/ArchDefObject.html +++ b/docs/ruby/ArchDefObject.html @@ -326,14 +326,14 @@

     
     
    -41
     42
     43
     44
    -45
    +45 +46

    -
    # File 'lib/arch_def.rb', line 41
    +      
    # File 'lib/arch_def.rb', line 42
     
     def initialize(data)
       raise "Bad data" unless data.is_a?(Hash)
    @@ -379,7 +379,6 @@ 

     
     
    -59
     60
     61
     62
    @@ -389,10 +388,11 @@ 

    66 67 68 -69

    +69 +70

    -
    # File 'lib/arch_def.rb', line 59
    +      
    # File 'lib/arch_def.rb', line 60
     
     def method_missing(method_name, *args, &block)
       if @data.key?(method_name.to_s)
    @@ -432,12 +432,12 @@ 

     
     
    -47
     48
    -49
    +49 +50

    -
    # File 'lib/arch_def.rb', line 47
    +      
    # File 'lib/arch_def.rb', line 48
     
     def inspect
       self.class.name
    @@ -491,10 +491,10 @@ 

     
     
    -56
    +57

    -
    # File 'lib/arch_def.rb', line 56
    +      
    # File 'lib/arch_def.rb', line 57
     
     def keys = @data.keys
    @@ -539,12 +539,12 @@

     
     
    -71
     72
    -73
    +73 +74

    -
    # File 'lib/arch_def.rb', line 71
    +      
    # File 'lib/arch_def.rb', line 72
     
     def respond_to_missing?(method_name, include_private = false)
       @data.key?(method_name.to_s) || super
    @@ -559,7 +559,7 @@ 

    diff --git a/docs/ruby/ArchGen.html b/docs/ruby/ArchGen.html index fcb5b5639..c67899ba9 100644 --- a/docs/ruby/ArchGen.html +++ b/docs/ruby/ArchGen.html @@ -1363,7 +1363,7 @@

    diff --git a/docs/ruby/Csr.html b/docs/ruby/Csr.html index 1b0af927b..5d2b2805f 100644 --- a/docs/ruby/Csr.html +++ b/docs/ruby/Csr.html @@ -639,15 +639,15 @@

     
     
    -351
    -352
    -353
    -354
    -355
    -356
    +363 +364 +365 +366 +367 +368

    -
    # File 'lib/arch_def.rb', line 351
    +      
    # File 'lib/arch_def.rb', line 363
     
     def initialize(csr_data, sym_table, arch_def)
       super(csr_data)
    @@ -721,12 +721,12 @@ 

     
     
    -343
    -344
    -345
    +355 +356 +357

    -
    # File 'lib/arch_def.rb', line 343
    +      
    # File 'lib/arch_def.rb', line 355
     
     def arch_def
       @arch_def
    @@ -782,12 +782,12 @@ 

     
     
    -346
    -347
    -348
    +358 +359 +360

    -
    # File 'lib/arch_def.rb', line 346
    +      
    # File 'lib/arch_def.rb', line 358
     
     def sym_table
       @sym_table
    @@ -848,12 +848,12 @@ 

     
     
    -460
    -461
    -462
    +471 +472 +473

    -
    # File 'lib/arch_def.rb', line 460
    +      
    # File 'lib/arch_def.rb', line 471
     
     def description_html
       Asciidoctor.convert description
    @@ -907,24 +907,24 @@ 

     
     
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
     372
     373
    -374
    +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386

    -
    # File 'lib/arch_def.rb', line 360
    +      
    # File 'lib/arch_def.rb', line 372
     
     def dynamic_length?
       return false if @data["length"].is_a?(Integer)
    @@ -972,12 +972,12 @@ 

     
     
    -547
    -548
    -549
    +558 +559 +560

    -
    # File 'lib/arch_def.rb', line 547
    +      
    # File 'lib/arch_def.rb', line 558
     
     def field(field_name)
       field_hash[field_name.to_s]
    @@ -1031,12 +1031,12 @@ 

     
     
    -542
    -543
    -544
    +553 +554 +555

    -
    # File 'lib/arch_def.rb', line 542
    +      
    # File 'lib/arch_def.rb', line 553
     
     def field?(field_name)
       field_hash.key?(field_name.to_s)
    @@ -1090,19 +1090,19 @@ 

     
     
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    +541 +542 +543 +544 +545 +546 +547 +548 +549 +550

    -
    # File 'lib/arch_def.rb', line 530
    +      
    # File 'lib/arch_def.rb', line 541
     
     def field_hash
       @field_hash unless @field_hash.nil?
    @@ -1163,18 +1163,18 @@ 

     
     
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    +476 +477 +478 +479 +480 +481 +482 +483 +484

    -
    # File 'lib/arch_def.rb', line 465
    +      
    # File 'lib/arch_def.rb', line 476
     
     def fields
       return @fields unless @fields.nil?
    @@ -1234,12 +1234,12 @@ 

     
     
    -552
    -553
    -554
    +563 +564 +565

    -
    # File 'lib/arch_def.rb', line 552
    +      
    # File 'lib/arch_def.rb', line 563
     
     def has_custom_sw_read?
       @data.key?("sw_read") && !sw_read.empty?
    @@ -1293,17 +1293,6 @@ 

     
     
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
     512
     513
     514
    @@ -1319,10 +1308,21 @@ 

    524 525 526 -527

    +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538

    -
    # File 'lib/arch_def.rb', line 501
    +      
    # File 'lib/arch_def.rb', line 512
     
     def implemented_fields
       return @implemented_fields unless @implemented_fields.nil?
    @@ -1400,17 +1400,6 @@ 

     
     
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
     488
     489
     490
    @@ -1420,10 +1409,21 @@ 

    494 495 496 -497

    +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508

    -
    # File 'lib/arch_def.rb', line 477
    +      
    # File 'lib/arch_def.rb', line 488
     
     def implemented_fields_for(effective_xlen)
       @implemented_fields_for ||= {}
    @@ -1517,18 +1517,6 @@ 

     
     
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
     390
     391
     392
    @@ -1548,10 +1536,21 @@ 

    406 407 408 -409

    +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420

    -
    # File 'lib/arch_def.rb', line 378
    +      
    # File 'lib/arch_def.rb', line 390
     
     def length(effective_xlen = nil)
       case @data["length"]
    @@ -1563,7 +1562,6 @@ 

    effective_xlen else - puts arch_def.implemented_csrs.map { |c| c.name } raise "CSR #{name} is not implemented" if arch_def.implemented_csrs.none? { |c| c.name == name } raise "CSR #{name} is not implemented" if arch_def.config_params["SXLEN"].nil? @@ -1634,19 +1632,19 @@

     
     
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    +423 +424 +425 +426 +427 +428 +429 +430 +431 +432

    -
    # File 'lib/arch_def.rb', line 412
    +      
    # File 'lib/arch_def.rb', line 423
     
     def length_cond32
       case @data["length"]
    @@ -1707,19 +1705,19 @@ 

     
     
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    +435 +436 +437 +438 +439 +440 +441 +442 +443 +444

    -
    # File 'lib/arch_def.rb', line 424
    +      
    # File 'lib/arch_def.rb', line 435
     
     def length_cond64
       case @data["length"]
    @@ -1780,17 +1778,6 @@ 

     
     
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
     447
     448
     449
    @@ -1799,10 +1786,21 @@ 

    452 453 454 -455

    +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466

    -
    # File 'lib/arch_def.rb', line 436
    +      
    # File 'lib/arch_def.rb', line 447
     
     def length_pretty
       if dynamic_length?
    @@ -1911,17 +1909,6 @@ 

     
     
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
     584
     585
     586
    @@ -1933,10 +1920,21 @@ 

    592 593 594 -595

    +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606

    -
    # File 'lib/arch_def.rb', line 573
    +      
    # File 'lib/arch_def.rb', line 584
     
     def wavedrom_desc(effective_xlen)
       desc = {
    @@ -1971,7 +1969,7 @@ 

    diff --git a/docs/ruby/CsrField.html b/docs/ruby/CsrField.html index c5c6ec881..db00531df 100644 --- a/docs/ruby/CsrField.html +++ b/docs/ruby/CsrField.html @@ -648,13 +648,13 @@

     
     
    -89
     90
     91
    -92
    +92 +93

    -
    # File 'lib/arch_def.rb', line 89
    +      
    # File 'lib/arch_def.rb', line 90
     
     def initialize(parent_csr, field_data)
       super(field_data)
    @@ -730,12 +730,12 @@ 

     
     
    -79
     80
    -81
    +81 +82

    -
    # File 'lib/arch_def.rb', line 79
    +      
    # File 'lib/arch_def.rb', line 80
     
     def parent
       @parent
    @@ -796,11 +796,6 @@ 

     
     
    -156
    -157
    -158
    -159
    -160
     161
     162
     163
    @@ -820,10 +815,15 @@ 

    177 178 179 -180

    +180 +181 +182 +183 +184 +185

    -
    # File 'lib/arch_def.rb', line 156
    +      
    # File 'lib/arch_def.rb', line 161
     
     def alias
       return @alias unless @alias.nil?
    @@ -899,12 +899,12 @@ 

     
     
    -95
     96
    -97
    +97 +98

    -
    # File 'lib/arch_def.rb', line 95
    +      
    # File 'lib/arch_def.rb', line 96
     
     def arch_def
       @parent.arch_def
    @@ -958,10 +958,10 @@ 

     
     
    -266
    +278

    -
    # File 'lib/arch_def.rb', line 266
    +      
    # File 'lib/arch_def.rb', line 278
     
     def base32_only? = @data.key?("base") && @data["base"] == 32
    @@ -1013,10 +1013,10 @@

     
     
    -263
    +275

    -
    # File 'lib/arch_def.rb', line 263
    +      
    # File 'lib/arch_def.rb', line 275
     
     def base64_only? = @data.key?("base") && @data["base"] == 64
    @@ -1068,10 +1068,10 @@

     
     
    -269
    +281

    -
    # File 'lib/arch_def.rb', line 269
    +      
    # File 'lib/arch_def.rb', line 281
     
     def defined_in_all_bases? = @data["base"].nil?
    @@ -1123,14 +1123,14 @@

     
     
    -192
    -193
    -194
    -195
    -196
    +197 +198 +199 +200 +201

    -
    # File 'lib/arch_def.rb', line 192
    +      
    # File 'lib/arch_def.rb', line 197
     
     def dynamic_location?
       return false if @data.key?("location")
    @@ -1186,12 +1186,12 @@ 

     
     
    -183
    -184
    -185
    +188 +189 +190

    -
    # File 'lib/arch_def.rb', line 183
    +      
    # File 'lib/arch_def.rb', line 188
     
     def has_custom_write?
       @data.key?("write(csr_value)") && !@data["write(csr_value)"].empty?
    @@ -1267,18 +1267,6 @@ 

     
     
    -232
    -233
    -234
    -235
    -236
    -237
    -238
    -239
    -240
    -241
    -242
    -243
     244
     245
     246
    @@ -1295,10 +1283,22 @@ 

    257 258 259 -260

    +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272

    -
    # File 'lib/arch_def.rb', line 232
    +      
    # File 'lib/arch_def.rb', line 244
     
     def location(effective_xlen = nil)
       key =
    @@ -1378,18 +1378,6 @@ 

     
     
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
     290
     291
     292
    @@ -1402,10 +1390,22 @@ 

    299 300 301 -302

    +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314

    -
    # File 'lib/arch_def.rb', line 278
    +      
    # File 'lib/arch_def.rb', line 290
     
     def location_pretty
       derangeify = proc { |loc|
    @@ -1493,31 +1493,45 @@ 

     
     
    -218
    -219
    -220
    -221
    -222
     223
     224
     225
     226
     227
    -228
    +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240

    -
    # File 'lib/arch_def.rb', line 218
    +      
    # File 'lib/arch_def.rb', line 223
     
     def reset_value
       return @reset_value unless @reset_value.nil?
     
    -  @reset_value =
    -    if @data.key?("reset_value")
    -      @data["reset_value"]
    -    else
    -      puts "evaluating #{name}"
    -      reset_value_func.return_value(arch_def.sym_table)
    -    end
    +  symtab = arch_def.sym_table
    +
    +  symtab.push # for consistency with template functions
    +
    +  begin
    +    @reset_value =
    +      if @data.key?("reset_value")
    +        @data["reset_value"]
    +      else
    +        reset_value_func.return_value(arch_def.sym_table)
    +      end
    +  ensure
    +    symtab.pop
    +  end
     end
    @@ -1586,11 +1600,6 @@

     
     
    -200
    -201
    -202
    -203
    -204
     205
     206
     207
    @@ -1600,10 +1609,15 @@ 

    211 212 213 -214

    +214 +215 +216 +217 +218 +219

    -
    # File 'lib/arch_def.rb', line 200
    +      
    # File 'lib/arch_def.rb', line 205
     
     def reset_value_func
       raise "Not an IDL value" unless @data.key?("reset_value()")
    @@ -1685,7 +1699,6 @@ 

     
     
    -107
     108
     109
     110
    @@ -1731,10 +1744,15 @@ 

    150 151 152 -153

    +153 +154 +155 +156 +157 +158

    -
    # File 'lib/arch_def.rb', line 107
    +      
    # File 'lib/arch_def.rb', line 108
     
     def type
       return @type unless @type.nil?
    @@ -1759,6 +1777,8 @@ 

    parent: "#{csr.name}.#{name}" ) + sym_table.push # for consistency with template functions + begin case ast.return_value(sym_table) when 0 @@ -1780,6 +1800,8 @@

    warn "In parsing #{csr.name}.#{name}::type()" warn " Return of type() function cannot be evaluated at compile time" raise e + ensure + sym_table.pop end end end

    @@ -1832,12 +1854,12 @@

     
     
    -335
    -336
    -337
    +347 +348 +349

    -
    # File 'lib/arch_def.rb', line 335
    +      
    # File 'lib/arch_def.rb', line 347
     
     def type_desc
       TYPE_DESC_MAP[type]
    @@ -1911,12 +1933,12 @@ 

     
     
    -273
    -274
    -275
    +285 +286 +287

    -
    # File 'lib/arch_def.rb', line 273
    +      
    # File 'lib/arch_def.rb', line 285
     
     def width(effective_xlen)
       location(effective_xlen).size
    @@ -1931,7 +1953,7 @@ 

    diff --git a/docs/ruby/CsrField/Alias.html b/docs/ruby/CsrField/Alias.html index 8b20f586a..496f1f056 100644 --- a/docs/ruby/CsrField/Alias.html +++ b/docs/ruby/CsrField/Alias.html @@ -218,10 +218,10 @@

     
     
    -85
    +86

    -
    # File 'lib/arch_def.rb', line 85
    +      
    # File 'lib/arch_def.rb', line 86
     
     Alias = Struct.new(:field, :range)
    @@ -275,10 +275,10 @@

     
     
    -85
    +86

    -
    # File 'lib/arch_def.rb', line 85
    +      
    # File 'lib/arch_def.rb', line 86
     
     Alias = Struct.new(:field, :range)
    @@ -292,7 +292,7 @@

    diff --git a/docs/ruby/DecodeField.html b/docs/ruby/DecodeField.html index d930aae02..316fad41e 100644 --- a/docs/ruby/DecodeField.html +++ b/docs/ruby/DecodeField.html @@ -1109,7 +1109,7 @@

    diff --git a/docs/ruby/DecodeVariable.html b/docs/ruby/DecodeVariable.html index f31437036..4f7310cb8 100644 --- a/docs/ruby/DecodeVariable.html +++ b/docs/ruby/DecodeVariable.html @@ -1316,7 +1316,7 @@

    diff --git a/docs/ruby/EncodingField.html b/docs/ruby/EncodingField.html index 507ee5f61..6887fe6dc 100644 --- a/docs/ruby/EncodingField.html +++ b/docs/ruby/EncodingField.html @@ -680,7 +680,7 @@

    diff --git a/docs/ruby/Extension.html b/docs/ruby/Extension.html index 82e6274a5..19c088a2b 100644 --- a/docs/ruby/Extension.html +++ b/docs/ruby/Extension.html @@ -282,13 +282,13 @@

     
     
    -1123
    -1124
    -1125
    -1126
    +1151 +1152 +1153 +1154

    -
    # File 'lib/arch_def.rb', line 1123
    +      
    # File 'lib/arch_def.rb', line 1151
     
     def initialize(ext_data, arch_def)
       super(ext_data)
    @@ -360,12 +360,12 @@ 

     
     
    -1119
    -1120
    -1121
    +1147 +1148 +1149

    -
    # File 'lib/arch_def.rb', line 1119
    +      
    # File 'lib/arch_def.rb', line 1147
     
     def arch_def
       @arch_def
    @@ -426,19 +426,19 @@ 

     
     
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166

    -
    # File 'lib/arch_def.rb', line 1129
    +      
    # File 'lib/arch_def.rb', line 1157
     
     def implies
       case @data["implies"]
    @@ -460,7 +460,7 @@ 

    diff --git a/docs/ruby/ExtensionVersion.html b/docs/ruby/ExtensionVersion.html index 0702b9900..6bbc1456e 100644 --- a/docs/ruby/ExtensionVersion.html +++ b/docs/ruby/ExtensionVersion.html @@ -426,15 +426,15 @@

     
     
    -1158
    -1159
    -1160
    -1161
    -1162
    -1163
    +1186 +1187 +1188 +1189 +1190 +1191

    -
    # File 'lib/arch_def.rb', line 1158
    +      
    # File 'lib/arch_def.rb', line 1186
     
     def initialize(name, version, arch_def)
       @name = name.to_s
    @@ -498,12 +498,12 @@ 

     
     
    -1150
    -1151
    -1152
    +1178 +1179 +1180

    -
    # File 'lib/arch_def.rb', line 1150
    +      
    # File 'lib/arch_def.rb', line 1178
     
     def arch_def
       @arch_def
    @@ -559,12 +559,12 @@ 

     
     
    -1153
    -1154
    -1155
    +1181 +1182 +1183

    -
    # File 'lib/arch_def.rb', line 1153
    +      
    # File 'lib/arch_def.rb', line 1181
     
     def extension
       @extension
    @@ -620,12 +620,12 @@ 

     
     
    -1144
    -1145
    -1146
    +1172 +1173 +1174

    -
    # File 'lib/arch_def.rb', line 1144
    +      
    # File 'lib/arch_def.rb', line 1172
     
     def name
       @name
    @@ -681,12 +681,12 @@ 

     
     
    -1147
    -1148
    -1149
    +1175 +1176 +1177

    -
    # File 'lib/arch_def.rb', line 1147
    +      
    # File 'lib/arch_def.rb', line 1175
     
     def version
       @version
    @@ -742,18 +742,18 @@ 

     
     
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227

    -
    # File 'lib/arch_def.rb', line 1191
    +      
    # File 'lib/arch_def.rb', line 1219
     
     def <=>(other)
       raise ArgumentError, "ExtensionVersions are only comparable to other extension versions" unless other.is_a?(ExtensionVersion)
    @@ -784,19 +784,19 @@ 

     
     
    -1171
    -1172
    -1173
    -1174
    -1175
    -1176
    -1177
    -1178
    -1179
    -1180
    +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208

    -
    # File 'lib/arch_def.rb', line 1171
    +      
    # File 'lib/arch_def.rb', line 1199
     
     def ==(other)
       case other
    @@ -900,12 +900,12 @@ 

     
     
    -1186
    -1187
    -1188
    +1214 +1215 +1216

    -
    # File 'lib/arch_def.rb', line 1186
    +      
    # File 'lib/arch_def.rb', line 1214
     
     def satisfies?(ext_name, *ext_version_requirements)
       @name == ext_name && Gem::Requirement.new(ext_version_requirements).satisfied_by?(@version)
    @@ -920,7 +920,7 @@ 

    diff --git a/docs/ruby/Idl.html b/docs/ruby/Idl.html index db8406614..e3b546ace 100644 --- a/docs/ruby/Idl.html +++ b/docs/ruby/Idl.html @@ -79,7 +79,7 @@
    Defined in:
    lib/idl.rb,
    - lib/idl/ast.rb,
    lib/idl/type.rb,
    lib/idl/symbol_table.rb,
    lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    + lib/idl/ast.rb,
    lib/idl/type.rb,
    lib/idl/passes/prune.rb,
    lib/idl/symbol_table.rb,
    lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    @@ -89,11 +89,11 @@

    Defined Under Namespace

    - Modules: AstNodeFuncs, Executable, FunctionStatementAst, IntAst, Returns, Rvalue, VarReadExpressionAst + Modules: AstNodeFuncs, Declaration, Executable, FunctionStatementAst, IntAst, Returns, Rvalue, VarReadExpressionAst - Classes: ArrayLiteralAst, AryAccess, AryElementAccessAst, AryElementAssignmentAst, AryRangeAccessAst, AryRangeAssignmentAst, AssignmentAst, AstNode, BinaryExpressionAst, BinaryExpressionRightAst, BitfieldAccessExpressionAst, BitfieldDefinitionAst, BitfieldType, BitsCastAst, BitsTypeAst, BuiltinEnumDefinitionAst, BuiltinTypeNameAst, Compiler, ConcatenationExpressionAst, ConditionalReturnStatementAst, ConditionalStatementAst, CsrFieldReadExpressionAst, CsrReadExpressionAst, CsrSoftwareReadAst, CsrSoftwareWriteAst, CsrType, CsrWriteAst, DontCareLvalueAst, DontCareReturnAst, EnumDefinitionAst, EnumRefAst, EnumerationType, ExecutionCommentAst, FieldAssignmentAst, FieldNameAst, ForLoopAst, FunctionBodyAst, FunctionCallExpressionAst, FunctionDefAst, FunctionType, GlobalAst, GlobalWithInitializationAst, IdAst, IfAst, InstructionOperationAst, IsaAst, MultiVariableAssignmentAst, MultiVariableDeclarationAst, ParenExpressionAst, PostDecrementExpressionAst, PostIncrementExpressionAst, ReplicationExpressionAst, ReturnStatementAst, SignCastAst, StatementAst, SymbolTable, TemplateFunctionType, TernaryOperatorExpressionAst, Type, UnaryOperatorExpressionAst, UserTypeNameAst, Var, VariableAssignmentAst, VariableDeclarationAst, VariableDeclarationWithInitializationAst, XregType + Classes: ArrayLiteralAst, AryAccessSyntaxNode, AryElementAccessAst, AryElementAssignmentAst, AryRangeAccessAst, AryRangeAssignmentAst, AssignmentAst, AstNode, BinaryExpressionAst, BinaryExpressionRightSyntaxNode, BitfieldAccessExpressionAst, BitfieldDefinitionAst, BitfieldType, BitsCastAst, BitsTypeAst, BuiltinEnumDefinitionAst, BuiltinTypeNameAst, Compiler, ConcatenationExpressionAst, ConditionalReturnStatementAst, ConditionalStatementAst, ConditionalStatementSyntaxNode, CsrFieldReadExpressionAst, CsrReadExpressionAst, CsrSoftwareReadAst, CsrSoftwareWriteAst, CsrType, CsrWriteAst, DontCareLvalueAst, DontCareReturnAst, ElseIfAst, EnumDefinitionAst, EnumRefAst, EnumerationType, ExecutionCommentAst, FieldAssignmentAst, FieldNameAst, ForLoopAst, FunctionBodyAst, FunctionBodySyntaxNode, FunctionCallExpressionAst, FunctionDefAst, FunctionType, GlobalAst, GlobalWithInitializationAst, IdAst, IfAst, IfBodyAst, IfSyntaxNode, InstructionOperationAst, IsaAst, MultiVariableAssignmentAst, MultiVariableDeclarationAst, NoopAst, ParenExpressionAst, PostDecrementExpressionAst, PostIncrementExpressionAst, ReplicationExpressionAst, ReturnStatementAst, SignCastAst, StatementAst, StatementSyntaxNode, SymbolTable, TernaryOperatorExpressionAst, Type, UnaryOperatorExpressionAst, UserTypeNameAst, Var, VariableAssignmentAst, VariableDeclarationAst, VariableDeclarationWithInitializationAst, XregType

    @@ -109,7 +109,7 @@

    Defined Under Namespace

    diff --git a/docs/ruby/Idl/ArrayLiteralAst.html b/docs/ruby/Idl/ArrayLiteralAst.html index bc63ea2d8..1fb9b5bc4 100644 --- a/docs/ruby/Idl/ArrayLiteralAst.html +++ b/docs/ruby/Idl/ArrayLiteralAst.html @@ -232,6 +232,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -267,12 +296,12 @@

     
     
    -1728
    -1729
    -1730
    +1872 +1873 +1874

    -
    # File 'lib/idl/ast.rb', line 1728
    +      
    # File 'lib/idl/ast.rb', line 1872
     
     def element_nodes
       [first] + rest.elements.map(&:expression)
    @@ -297,10 +326,10 @@ 

     
     
    -1751
    +1895

    -
    # File 'lib/idl/ast.rb', line 1751
    +      
    # File 'lib/idl/ast.rb', line 1895
     
     def to_idl = "[#{element_nodes.map(&:to_idl).join(',')}]"
    @@ -323,12 +352,12 @@

     
     
    -1743
    -1744
    -1745
    +1887 +1888 +1889

    -
    # File 'lib/idl/ast.rb', line 1743
    +      
    # File 'lib/idl/ast.rb', line 1887
     
     def type(symtab)
       Type.new(:array, width: element_nodes.size, sub_type: element_nodes[0].type(symtab))
    @@ -418,18 +447,18 @@ 

     
     
    -1733
    -1734
    -1735
    -1736
    -1737
    -1738
    -1739
    -1740
    -1741
    +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885

    -
    # File 'lib/idl/ast.rb', line 1733
    +      
    # File 'lib/idl/ast.rb', line 1877
     
     def type_check(symtab)
       element_nodes.each do |node|
    @@ -460,12 +489,12 @@ 

     
     
    -1747
    -1748
    -1749
    +1891 +1892 +1893

    -
    # File 'lib/idl/ast.rb', line 1747
    +      
    # File 'lib/idl/ast.rb', line 1891
     
     def value(symtab)
       element_nodes.map { |e| e.value(symtab) }
    @@ -473,6 +502,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -480,7 +605,7 @@

    diff --git a/docs/ruby/Idl/AryElementAccessAst.html b/docs/ruby/Idl/AryElementAccessAst.html index fd5172051..b12f37233 100644 --- a/docs/ruby/Idl/AryElementAccessAst.html +++ b/docs/ruby/Idl/AryElementAccessAst.html @@ -103,7 +103,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb
    +
    @@ -189,6 +191,28 @@

  • + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + #initialize(input, interval, var, index) ⇒ AryElementAccessAst @@ -209,6 +233,52 @@

    A new instance of AryElementAccessAst.

    +

  • + + +
  • + + + #prune(symtab) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -277,6 +347,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -320,14 +419,14 @@

     
     
    -783
    -784
    -785
    -786
    -787
    +812 +813 +814 +815 +816

    -
    # File 'lib/idl/ast.rb', line 783
    +      
    # File 'lib/idl/ast.rb', line 812
     
     def initialize(input, interval, var, index)
       super(input, interval, [var, index])
    @@ -372,12 +471,12 @@ 

     
     
    -781
    -782
    -783
    +810 +811 +812

    -
    # File 'lib/idl/ast.rb', line 781
    +      
    # File 'lib/idl/ast.rb', line 810
     
     def index
       @index
    @@ -415,12 +514,12 @@ 

     
     
    -781
    -782
    -783
    +810 +811 +812

    -
    # File 'lib/idl/ast.rb', line 781
    +      
    # File 'lib/idl/ast.rb', line 810
     
     def var
       @var
    @@ -438,7 +537,122 @@ 

    Instance Method Details

    -

    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +48
    +49
    +50
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 48
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  "#{var.gen_adoc(indent, indent_spaces:)}[#{index.gen_adoc(0, indent_spaces:)}]"
    +end
    +
    +
    + +
    +

    + + #prune(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +91
    +92
    +93
    +
    +
    # File 'lib/idl/passes/prune.rb', line 91
    +
    +def prune(symtab)
    +  AryElementAccessAst.new(input, interval, @var.prune(symtab), @index.prune(symtab))
    +end
    +
    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +879
    +
    +
    # File 'lib/idl/ast.rb', line 879
    +
    +def to_idl = "#{@var.to_idl}[#{@index.to_idl}]"
    +
    +
    + +
    +

    #type(symtab) ⇒ Object @@ -452,18 +666,18 @@

     
     
    -821
    -822
    -823
    -824
    -825
    -826
    -827
    -828
    -829
    +850 +851 +852 +853 +854 +855 +856 +857 +858

    -
    # File 'lib/idl/ast.rb', line 821
    +      
    # File 'lib/idl/ast.rb', line 850
     
     def type(symtab)
       if @var.type(symtab).kind == :array
    @@ -559,39 +773,39 @@ 

     
     
    -790
    -791
    -792
    -793
    -794
    -795
    -796
    -797
    -798
    -799
    -800
    -801
    -802
    -803
    -804
    -805
    -806
    -807
    -808
    -809
    -810
    -811
    -812
    -813
    -814
    -815
    -816
    -817
    -818
    -819
    +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848

    -
    # File 'lib/idl/ast.rb', line 790
    +      
    # File 'lib/idl/ast.rb', line 819
     
     def type_check(symtab)
       @var.type_check(symtab)
    @@ -643,26 +857,26 @@ 

     
     
    -831
    -832
    -833
    -834
    -835
    -836
    -837
    -838
    -839
    -840
    -841
    -842
    -843
    -844
    -845
    -846
    -847
    +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876

    -
    # File 'lib/idl/ast.rb', line 831
    +      
    # File 'lib/idl/ast.rb', line 860
     
     def value(symtab)
       if @var.type(symtab).integral?
    @@ -684,6 +898,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -691,7 +1001,7 @@

    diff --git a/docs/ruby/Idl/AryElementAssignmentAst.html b/docs/ruby/Idl/AryElementAssignmentAst.html index d450c16c1..f9a0c0fce 100644 --- a/docs/ruby/Idl/AryElementAssignmentAst.html +++ b/docs/ruby/Idl/AryElementAssignmentAst.html @@ -284,27 +284,27 @@

     
     
    -1002
    -1003
    -1004
    -1005
    -1006
    -1007
    -1008
    -1009
    -1010
    -1011
    -1012
    -1013
    -1014
    +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057

    -
    # File 'lib/idl/ast.rb', line 1002
    +      
    # File 'lib/idl/ast.rb', line 1045
     
     def execute(symtab)
       case var.type(symtab).kind
       when :array
    -    value_error "TODO: array element assignement execution"
    +    var.value(symtab)[idx.value] = rhs.value(symtab)
       when :bits
         v = rhs.value(symtab)
         var = symtab.get(var.text_value)
    @@ -334,12 +334,12 @@ 

     
     
    -994
    -995
    -996
    +1037 +1038 +1039

    -
    # File 'lib/idl/ast.rb', line 994
    +      
    # File 'lib/idl/ast.rb', line 1037
     
     def lhs
       internal_error "What's this used for?"
    @@ -364,12 +364,12 @@ 

     
     
    -998
    -999
    -1000
    +1041 +1042 +1043

    -
    # File 'lib/idl/ast.rb', line 998
    +      
    # File 'lib/idl/ast.rb', line 1041
     
     def rhs
       rval
    @@ -423,10 +423,10 @@ 

     
     
    -1017
    +1060

    -
    # File 'lib/idl/ast.rb', line 1017
    +      
    # File 'lib/idl/ast.rb', line 1060
     
     def to_idl = "#{var.to_idl}[#{idx.to_idl}] = #{rval.to_idl}"
    @@ -514,40 +514,40 @@

     
     
    -962
    -963
    -964
    -965
    -966
    -967
    -968
    -969
    -970
    -971
    -972
    -973
    -974
    -975
    -976
    -977
    -978
    -979
    -980
    -981
    -982
    -983
    -984
    -985
    -986
    -987
    -988
    -989
    -990
    -991
    -992
    +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035

    -
    # File 'lib/idl/ast.rb', line 962
    +      
    # File 'lib/idl/ast.rb', line 1005
     
     def type_check(symtab)
       var.type_check(symtab)
    @@ -560,7 +560,7 @@ 

    begin idx_value = idx.value(symtab) - type_error "Array index out of range" if idx_value(symtab) >= var.type(symtab).width + type_error "Array index (#{idx.text_value} = #{idx_value}) out of range (< #{var.type(symtab).width})" if idx_value >= var.type(symtab).width rescue ValueError # OK, doesn't need to be known end @@ -590,7 +590,7 @@

    diff --git a/docs/ruby/Idl/AryRangeAccessAst.html b/docs/ruby/Idl/AryRangeAccessAst.html index dc489927f..79e80270f 100644 --- a/docs/ruby/Idl/AryRangeAccessAst.html +++ b/docs/ruby/Idl/AryRangeAccessAst.html @@ -104,7 +104,7 @@
    Defined in:
    lib/idl/ast.rb,
    - lib/idl/passes/gen_adoc.rb
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb
    @@ -268,7 +268,7 @@

  • - #type(symtab) ⇒ Object + #prune(symtab) ⇒ Object @@ -290,7 +290,7 @@

  • - #type_check(symtab) ⇒ Object + #to_idl ⇒ String @@ -304,7 +304,57 @@

    -
    +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    + +

  • + + +
  • + + + #type(symtab) ⇒ Type + + + + + + + + + + + + + +
    +

    Given a specific symbol table, return the type of this node.

    +
    + +
  • + + +
  • + + + #type_check(symtab) ⇒ void + + + + + + + + + + + + + +
    +

    type check this node and all children.

    +
  • @@ -326,7 +376,38 @@

    -
    +
    +

    Return the compile-time-known value of the node.

    +
    + +

  • + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
  • @@ -371,15 +452,15 @@

     
     
    -855
    -856
    -857
    -858
    -859
    -860
    +887 +888 +889 +890 +891 +892

    -
    # File 'lib/idl/ast.rb', line 855
    +      
    # File 'lib/idl/ast.rb', line 887
     
     def initialize(input, interval, var, msb, lsb)
       super(input, interval, [var, msb, lsb])
    @@ -425,12 +506,12 @@ 

     
     
    -853
    -854
    -855
    +885 +886 +887

    -
    # File 'lib/idl/ast.rb', line 853
    +      
    # File 'lib/idl/ast.rb', line 885
     
     def lsb
       @lsb
    @@ -468,12 +549,12 @@ 

     
     
    -853
    -854
    -855
    +885 +886 +887

    -
    # File 'lib/idl/ast.rb', line 853
    +      
    # File 'lib/idl/ast.rb', line 885
     
     def msb
       @msb
    @@ -511,12 +592,12 @@ 

     
     
    -853
    -854
    -855
    +885 +886 +887

    -
    # File 'lib/idl/ast.rb', line 853
    +      
    # File 'lib/idl/ast.rb', line 885
     
     def var
       @var
    @@ -548,35 +629,15 @@ 

     
     
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
     42
    -43
    +43 +44

    -
    # File 'lib/idl/passes/gen_adoc.rb', line 31
    +      
    # File 'lib/idl/passes/gen_adoc.rb', line 42
     
     def gen_adoc(indent = 0, indent_spaces: 2)
    -  adoc = ''
    -  unless var.is_a?(AryRangeAccessAst) || var.is_a?(AryElementAccessAst)
    -    adoc << input[interval.begin...var.interval.begin]
    -    adoc << var.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces)
    -  end
    -  adoc << input[var.interval.end...msb.interval.begin]
    -  adoc << msb.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces)
    -  adoc << input[msb.interval.end...lsb.interval.begin]
    -  adoc << lsb.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces)
    -  adoc << input[lsb.interval.end...interval.end]
    -  adoc
    +  "#{var.gen_adoc(indent, indent_spaces:)}[#{msb.gen_adoc(0, indent_spaces:)}:#{msb.gen_adoc(0, indent_spaces:)}]"
     end
    @@ -584,9 +645,9 @@

    -

    +

    - #type(symtab) ⇒ Object + #prune(symtab) ⇒ Object @@ -598,20 +659,174 @@

     
     
    -887
    -888
    -889
    -890
    -891
    -892
    -893
    -894
    -895
    -896
    -897
    +96 +97 +98

    -
    # File 'lib/idl/ast.rb', line 887
    +      
    # File 'lib/idl/passes/prune.rb', line 96
    +
    +def prune(symtab)
    +  AryRangeAccessAst.new(input, interval, @var.prune(symtab), @msb.prune(symtab), @lsb.prune(symtab))
    +end
    + + + + + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +940
    +
    +
    # File 'lib/idl/ast.rb', line 940
    +
    +def to_idl = "#{@var.to_idl}[#{@msb.to_idl}:#{@lsb.to_idl}]"
    +
    +
    + +
    +

    + + #type(symtab) ⇒ Type + + + + + +

    +
    + +

    Given a specific symbol table, return the type of this node.

    + +

    Should not be called until #type_check is called with the same arguments

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table for lookup

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Type) + + + + — +
      +

      The type of the node

      +
      + +
    • + +
    +

    Raises:

    +
      + +
    • + + + (AstNode::InternalError) + + + + — +
      +

      if the type is dependent on symtab, and type_check was not called first

      +
      + +
    • + +
    + +
    + + +
    +
    +
    +
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +
    +
    # File 'lib/idl/ast.rb', line 921
     
     def type(symtab)
       begin
    @@ -632,45 +847,110 @@ 

    - #type_check(symtab) ⇒ Object + #type_check(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    type check this node and all children

    + +

    Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table for lookup

      +
      + +
    • + +
    + +

    Raises:

    + + +
    @@ -520,36 +520,36 @@

     
     
    -1026
    -1027
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095

    @@ -843,12 +843,12 @@

     
     
    -306
    +288

     
     
    -862
    -863
    -864
    -865
    -866
    -867
    -868
    -869
    -870
    -871
    -872
    -873
    -874
    -875
    -876
    -877
    -878
    -879
    -880
    -881
    -882
    -883
    -884
    -885
    +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918
    -
    # File 'lib/idl/ast.rb', line 862
    +      
    # File 'lib/idl/ast.rb', line 895
     
     def type_check(symtab)
       @var.type_check(symtab)
    @@ -710,19 +990,30 @@ 

    -

    +
    +
    + +

    Return the compile-time-known value of the node

    + + +
    +
    +
    + + +
     
     
    -899
    -900
    -901
    -902
    +934 +935 +936 +937
    -
    # File 'lib/idl/ast.rb', line 899
    +      
    # File 'lib/idl/ast.rb', line 934
     
     def value(symtab)
       mask = (1 << (@msb.value(symtab) - @lsb.value(symtab) + 1)) - 1
    @@ -731,6 +1022,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -738,7 +1125,7 @@

    diff --git a/docs/ruby/Idl/AryRangeAssignmentAst.html b/docs/ruby/Idl/AryRangeAssignmentAst.html index 7316e85f1..ecae1df4d 100644 --- a/docs/ruby/Idl/AryRangeAssignmentAst.html +++ b/docs/ruby/Idl/AryRangeAssignmentAst.html @@ -284,25 +284,25 @@

     
     
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120

    -
    # File 'lib/idl/ast.rb', line 1062
    +      
    # File 'lib/idl/ast.rb', line 1105
     
     def execute(symtab)
       var_val = var.value(symtab)
    @@ -310,7 +310,7 @@ 

    msb_val = msb.value(symtab) lsb_val = lsb.value(symtab) - type_error "MSB is <= LSB" if msb_val <= lsb_val + type_error "MSB (#{msb_val}) is <= LSB (#{lsb_val})" if msb_val <= lsb_val rval_val = rval.value(symtab) @@ -340,12 +340,12 @@

     
     
    -1054
    -1055
    -1056
    +1097 +1098 +1099

    -
    # File 'lib/idl/ast.rb', line 1054
    +      
    # File 'lib/idl/ast.rb', line 1097
     
     def lhs
       internal_error "What's this used for?"
    @@ -370,12 +370,12 @@ 

     
     
    -1058
    -1059
    -1060
    +1101 +1102 +1103

    -
    # File 'lib/idl/ast.rb', line 1058
    +      
    # File 'lib/idl/ast.rb', line 1101
     
     def rhs
       rval
    @@ -429,10 +429,10 @@ 

     
     
    -1080
    +1123

    -
    # File 'lib/idl/ast.rb', line 1080
    +      
    # File 'lib/idl/ast.rb', line 1123
     
     def to_idl = "#{var.to_idl}[#{msb.to_idl}:#{lsb.to_idl}] = #{rval.to_idl}"
    -
    # File 'lib/idl/ast.rb', line 1026
    +      
    # File 'lib/idl/ast.rb', line 1069
     
     def type_check(symtab)
       var.type_check(symtab)
    @@ -588,7 +588,7 @@ 

    diff --git a/docs/ruby/Idl/AssignmentAst.html b/docs/ruby/Idl/AssignmentAst.html index 58d98a294..4ff68db68 100644 --- a/docs/ruby/Idl/AssignmentAst.html +++ b/docs/ruby/Idl/AssignmentAst.html @@ -125,7 +125,7 @@

    Overview

    @@ -328,12 +328,12 @@

     
     
    -911
    -912
    -913
    +950 +951 +952

    -
    # File 'lib/idl/ast.rb', line 911
    +      
    # File 'lib/idl/ast.rb', line 950
     
     def lhs
       internal_error "#{self.class} must implement lhs"
    @@ -369,12 +369,12 @@ 

     
     
    -916
    -917
    -918
    +955 +956 +957

    -
    # File 'lib/idl/ast.rb', line 916
    +      
    # File 'lib/idl/ast.rb', line 955
     
     def rhs
       internal_error "#{calss} must implement rhs"
    @@ -389,7 +389,7 @@ 

    diff --git a/docs/ruby/Idl/AstNode.html b/docs/ruby/Idl/AstNode.html index d6d8ef388..51fa0221a 100644 --- a/docs/ruby/Idl/AstNode.html +++ b/docs/ruby/Idl/AstNode.html @@ -121,7 +121,7 @@

    Overview

    Direct Known Subclasses

    -

    ArrayLiteralAst, AryElementAccessAst, AryRangeAccessAst, AssignmentAst, BinaryExpressionAst, BinaryExpressionRightAst, BitfieldAccessExpressionAst, BitfieldDefinitionAst, BitsCastAst, BitsTypeAst, BuiltinTypeNameAst, ConcatenationExpressionAst, CsrFieldReadExpressionAst, CsrReadExpressionAst, CsrSoftwareReadAst, CsrSoftwareWriteAst, CsrWriteAst, DontCareLvalueAst, DontCareReturnAst, EnumDefinitionAst, EnumRefAst, ExecutionCommentAst, FieldNameAst, ForLoopAst, FunctionBodyAst, FunctionCallExpressionAst, FunctionDefAst, GlobalAst, GlobalWithInitializationAst, IdAst, IfAst, InstructionOperationAst, IsaAst, ParenExpressionAst, PostDecrementExpressionAst, PostIncrementExpressionAst, ReplicationExpressionAst, ReturnStatementAst, SignCastAst, StatementAst, TernaryOperatorExpressionAst, UnaryOperatorExpressionAst, UserTypeNameAst, VariableDeclarationAst

    +

    ArrayLiteralAst, AryElementAccessAst, AryRangeAccessAst, AssignmentAst, BinaryExpressionAst, BitfieldAccessExpressionAst, BitfieldDefinitionAst, BitsCastAst, BitsTypeAst, BuiltinTypeNameAst, ConcatenationExpressionAst, ConditionalStatementAst, CsrFieldReadExpressionAst, CsrReadExpressionAst, CsrSoftwareReadAst, CsrSoftwareWriteAst, CsrWriteAst, DontCareLvalueAst, DontCareReturnAst, ElseIfAst, EnumDefinitionAst, EnumRefAst, ExecutionCommentAst, FieldNameAst, ForLoopAst, FunctionBodyAst, FunctionCallExpressionAst, FunctionDefAst, GlobalAst, GlobalWithInitializationAst, IdAst, IfAst, IfBodyAst, InstructionOperationAst, IsaAst, MultiVariableDeclarationAst, NoopAst, ParenExpressionAst, PostDecrementExpressionAst, PostIncrementExpressionAst, ReplicationExpressionAst, ReturnStatementAst, SignCastAst, StatementAst, StatementSyntaxNode, TernaryOperatorExpressionAst, UnaryOperatorExpressionAst, UserTypeNameAst, VariableDeclarationAst

    Defined Under Namespace

    @@ -1020,7 +1020,7 @@

    diff --git a/docs/ruby/Idl/AstNode/InternalError.html b/docs/ruby/Idl/AstNode/InternalError.html index 0b6ae4fd8..8e3f7517e 100644 --- a/docs/ruby/Idl/AstNode/InternalError.html +++ b/docs/ruby/Idl/AstNode/InternalError.html @@ -249,19 +249,19 @@

     
     
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    +143 +144 +145 +146 +147 +148 +149 +150 +151 +152

    -
    # File 'lib/idl/ast.rb', line 161
    +      
    # File 'lib/idl/ast.rb', line 143
     
     def initialize(what)
       super(what)
    @@ -331,12 +331,12 @@ 

     
     
    -159
    -160
    -161
    +141 +142 +143

    -
    # File 'lib/idl/ast.rb', line 159
    +      
    # File 'lib/idl/ast.rb', line 141
     
     def bt
       @bt
    @@ -392,12 +392,12 @@ 

     
     
    -152
    -153
    -154
    +134 +135 +136

    -
    # File 'lib/idl/ast.rb', line 152
    +      
    # File 'lib/idl/ast.rb', line 134
     
     def what
       @what
    @@ -413,7 +413,7 @@ 

    diff --git a/docs/ruby/Idl/AstNode/TypeError.html b/docs/ruby/Idl/AstNode/TypeError.html index a89fbe45b..a6f70398d 100644 --- a/docs/ruby/Idl/AstNode/TypeError.html +++ b/docs/ruby/Idl/AstNode/TypeError.html @@ -269,19 +269,19 @@

     
     
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    +119 +120 +121 +122 +123 +124 +125 +126 +127 +128

    -
    # File 'lib/idl/ast.rb', line 137
    +      
    # File 'lib/idl/ast.rb', line 119
     
     def initialize(what)
       super(what)
    @@ -351,12 +351,12 @@ 

     
     
    -134
    -135
    -136
    +116 +117 +118

    -
    # File 'lib/idl/ast.rb', line 134
    +      
    # File 'lib/idl/ast.rb', line 116
     
     def bt
       @bt
    @@ -412,12 +412,12 @@ 

     
     
    -127
    -128
    -129
    +109 +110 +111

    -
    # File 'lib/idl/ast.rb', line 127
    +      
    # File 'lib/idl/ast.rb', line 109
     
     def what
       @what
    @@ -433,7 +433,7 @@ 

    diff --git a/docs/ruby/Idl/AstNode/ValueError.html b/docs/ruby/Idl/AstNode/ValueError.html index 213fd94f9..b21c3a813 100644 --- a/docs/ruby/Idl/AstNode/ValueError.html +++ b/docs/ruby/Idl/AstNode/ValueError.html @@ -249,14 +249,14 @@

     
     
    -178
    -179
    -180
    -181
    -182
    +160 +161 +162 +163 +164

    -
    # File 'lib/idl/ast.rb', line 178
    +      
    # File 'lib/idl/ast.rb', line 160
     
     def initialize(what, lineno, file)
       super(what)
    @@ -301,12 +301,12 @@ 

     
     
    -176
    -177
    -178
    +158 +159 +160

    -
    # File 'lib/idl/ast.rb', line 176
    +      
    # File 'lib/idl/ast.rb', line 158
     
     def file
       @file
    @@ -344,12 +344,12 @@ 

     
     
    -176
    -177
    -178
    +158 +159 +160

    -
    # File 'lib/idl/ast.rb', line 176
    +      
    # File 'lib/idl/ast.rb', line 158
     
     def lineno
       @lineno
    @@ -365,7 +365,7 @@ 

    diff --git a/docs/ruby/Idl/AstNodeFuncs.html b/docs/ruby/Idl/AstNodeFuncs.html index 77390ed5a..364ce6855 100644 --- a/docs/ruby/Idl/AstNodeFuncs.html +++ b/docs/ruby/Idl/AstNodeFuncs.html @@ -383,17 +383,17 @@

     
     
    -241
    -242
    -243
    -244
    -245
    -246
    -247
    -248
    +223 +224 +225 +226 +227 +228 +229 +230

    -
    # File 'lib/idl/ast.rb', line 241
    +      
    # File 'lib/idl/ast.rb', line 223
     
     def children
       if terminal?
    @@ -472,18 +472,18 @@ 

     
     
    -206
    -207
    -208
    -209
    -210
    -211
    -212
    -213
    -214
    +188 +189 +190 +191 +192 +193 +194 +195 +196

    -
    # File 'lib/idl/ast.rb', line 206
    +      
    # File 'lib/idl/ast.rb', line 188
     
     def internal_error(reason)
       msg = <<~WHAT
    @@ -543,24 +543,24 @@ 

     
     
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261

    -
    # File 'lib/idl/ast.rb', line 265
    +      
    # File 'lib/idl/ast.rb', line 247
     
     def nodes
       return @nodes unless @nodes.nil?
    @@ -666,15 +666,15 @@ 
    -
    # File 'lib/idl/ast.rb', line 286
    +      
    # File 'lib/idl/ast.rb', line 268
     
     def print_ast(indent = 0, indent_size: 2, io: $stdout)
       io.puts "#{' ' * indent}#{self.class.name}:"
    @@ -748,10 +748,10 @@ 

     
     
    -315
    +297

    -
    # File 'lib/idl/ast.rb', line 315
    +      
    # File 'lib/idl/ast.rb', line 297
     
     def to_idl = raise NotImplementedError, "#{self.class.name} must implement to_idl"
    -
    # File 'lib/idl/ast.rb', line 306
    +      
    # File 'lib/idl/ast.rb', line 288
     
    -def type_check(symtab) = raise NotImplementedError, "Subclass of AstNode must implement type_check"
    +def type_check(symtab) = raise NotImplementedError, "#{self.class.name} must implement type_check"
    @@ -918,18 +918,18 @@

     
     
    -192
    -193
    -194
    -195
    -196
    -197
    -198
    -199
    -200
    +174 +175 +176 +177 +178 +179 +180 +181 +182

    -
    # File 'lib/idl/ast.rb', line 192
    +      
    # File 'lib/idl/ast.rb', line 174
     
     def type_error(reason)
       msg = <<~WHAT
    @@ -1011,12 +1011,12 @@ 

     
     
    -236
    -237
    -238
    +218 +219 +220

    -
    # File 'lib/idl/ast.rb', line 236
    +      
    # File 'lib/idl/ast.rb', line 218
     
     def unindent(s)
       s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, "")
    @@ -1090,18 +1090,18 @@ 

     
     
    -220
    -221
    -222
    -223
    -224
    -225
    -226
    -227
    -228
    +202 +203 +204 +205 +206 +207 +208 +209 +210

    -
    # File 'lib/idl/ast.rb', line 220
    +      
    # File 'lib/idl/ast.rb', line 202
     
     def value_error(reason)
       msg = <<~WHAT
    @@ -1122,7 +1122,7 @@ 

    diff --git a/docs/ruby/Idl/BinaryExpressionAst.html b/docs/ruby/Idl/BinaryExpressionAst.html index 5355c1036..7258d1b4f 100644 --- a/docs/ruby/Idl/BinaryExpressionAst.html +++ b/docs/ruby/Idl/BinaryExpressionAst.html @@ -103,7 +103,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb
    +
    @@ -249,6 +251,28 @@

  • + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + #initialize(input, interval, lhs, op, rhs) ⇒ BinaryExpressionAst @@ -293,6 +317,30 @@

    This expression, but with an inverted condition.

    +

  • + + +
  • + + + #prune(symtab) ⇒ AstNode + + + + + + + + + + + + + +
    +

    A new abstract syntax tree with all dead/unreachable code removed.

    +
    +
  • @@ -389,6 +437,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -432,16 +509,16 @@

     
     
    -1540
    -1541
    -1542
    -1543
    -1544
    -1545
    -1546
    +1607 +1608 +1609 +1610 +1611 +1612 +1613

    -
    # File 'lib/idl/ast.rb', line 1540
    +      
    # File 'lib/idl/ast.rb', line 1607
     
     def initialize(input, interval, lhs, op, rhs)
       super(input, interval, [lhs, op, rhs])
    @@ -488,12 +565,12 @@ 

     
     
    -1694
    -1695
    -1696
    +1838 +1839 +1840

    -
    # File 'lib/idl/ast.rb', line 1694
    +      
    # File 'lib/idl/ast.rb', line 1838
     
     def lhs
       @lhs
    @@ -531,12 +608,12 @@ 

     
     
    -1700
    -1701
    -1702
    +1844 +1845 +1846

    -
    # File 'lib/idl/ast.rb', line 1700
    +      
    # File 'lib/idl/ast.rb', line 1844
     
     def op
       @op
    @@ -574,12 +651,12 @@ 

     
     
    -1697
    -1698
    -1699
    +1841 +1842 +1843

    -
    # File 'lib/idl/ast.rb', line 1697
    +      
    # File 'lib/idl/ast.rb', line 1841
     
     def rhs
       @rhs
    @@ -597,7 +674,37 @@ 

    Instance Method Details

    -

    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +54
    +55
    +56
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 54
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  "#{rhs.gen_adoc(0, indent_spaces:)} #{op} #{lhs.gen_adoc(0, indent_spaces:)}"
    +end
    +
    +
    + +
    +

    #invert(symtab) ⇒ BinaryExpressionAst @@ -640,35 +747,35 @@

     
     
    -1549
    -1550
    -1551
    -1552
    -1553
    -1554
    -1555
    -1556
    -1557
    -1558
    -1559
    -1560
    -1561
    -1562
    -1563
    -1564
    -1565
    -1566
    -1567
    -1568
    -1569
    -1570
    -1571
    -1572
    -1573
    -1574
    +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641

    -
    # File 'lib/idl/ast.rb', line 1549
    +      
    # File 'lib/idl/ast.rb', line 1616
     
     def invert(symtab)
       type_error "Not a boolean operator" unless type(symtab).kind == :boolean
    @@ -699,6 +806,129 @@ 

    +
    + +
    +

    + + #prune(symtab) ⇒ AstNode + + + + + +

    +
    + +

    Returns A new abstract syntax tree with all dead/unreachable code removed.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (Idl::SymbolTable) + + + + — +
      +

      Context of the compilation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (AstNode) + + + + — +
      +

      A new abstract syntax tree with all dead/unreachable code removed

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +
    +
    # File 'lib/idl/passes/prune.rb', line 102
    +
    +def prune(symtab)
    +  if op == "&&"
    +    begin
    +      if @lhs.value(symtab) == false
    +        @rhs.prune(symtab)
    +      else
    +        self
    +      end
    +    rescue ValueError
    +      self
    +    end
    +  elsif op == "||"
    +    begin
    +      if @lhs.value(symtab) == true
    +        @rhs.prune(symtab)
    +      else
    +        self
    +      end
    +    rescue ValueError
    +      self
    +    end
    +  else
    +    self
    +  end
    +end
    +
    @@ -745,15 +975,15 @@

     
     
    -1577
    -1578
    -1579
    +1644 +1645 +1646

    -
    # File 'lib/idl/ast.rb', line 1577
    +      
    # File 'lib/idl/ast.rb', line 1644
     
     def to_idl
    -  "#{lhs.to_idl} #{op} #{rhs.to_idl}"
    +  "(#{lhs.to_idl} #{op} #{rhs.to_idl})"
     end
    @@ -844,29 +1074,29 @@

     
     
    -1582
    -1583
    -1584
    -1585
    -1586
    -1587
    -1588
    -1589
    -1590
    -1591
    -1592
    -1593
    -1594
    -1595
    -1596
    -1597
    -1598
    -1599
    -1600
    -1601
    +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668

    -
    # File 'lib/idl/ast.rb', line 1582
    +      
    # File 'lib/idl/ast.rb', line 1649
     
     def type(symtab)
       qualifiers = []
    @@ -973,67 +1203,67 @@ 

     
     
    -1604
    -1605
    -1606
    -1607
    -1608
    -1609
    -1610
    -1611
    -1612
    -1613
    -1614
    -1615
    -1616
    -1617
    -1618
    -1619
    -1620
    -1621
    -1622
    -1623
    -1624
    -1625
    -1626
    -1627
    -1628
    -1629
    -1630
    -1631
    -1632
    -1633
    -1634
    -1635
    -1636
    -1637
    -1638
    -1639
    -1640
    -1641
    -1642
    -1643
    -1644
    -1645
    -1646
    -1647
    -1648
    -1649
    -1650
    -1651
    -1652
    -1653
    -1654
    -1655
    -1656
    -1657
    -1658
    -1659
    -1660
    -1661
    +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728

    -
    # File 'lib/idl/ast.rb', line 1604
    +      
    # File 'lib/idl/ast.rb', line 1671
     
     def type_check(symtab)
       internal_error "No type_check function #{@lhs.inspect}" unless @lhs.respond_to?(:type_check)
    @@ -1124,37 +1354,114 @@ 

     
     
    -1664
    -1665
    -1666
    -1667
    -1668
    -1669
    -1670
    -1671
    -1672
    -1673
    -1674
    -1675
    -1676
    -1677
    -1678
    -1679
    -1680
    -1681
    -1682
    -1683
    -1684
    -1685
    -1686
    -1687
    -1688
    -1689
    -1690
    -1691
    +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835

    -
    # File 'lib/idl/ast.rb', line 1664
    +      
    # File 'lib/idl/ast.rb', line 1731
     
     def value(symtab)
       if op == ">>>"
    @@ -1180,13 +1487,186 @@ 

    else eval "lhs_value #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ end + elsif op == "==" + begin + @lhs.value(symtab) == @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that == is false if the possible values of each do not overlap + if @lhs.values(symtab).intersection(@rhs.value(symtab)).empty? + false + else + value_error "There is overlap in the lhs/rhs return values" + end + end + elsif op == "!=" + begin + @lhs.value(symtab) != @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of each do not overlap + if @lhs.values(symtab).intersection(@rhs.value(symtab)).empty? + true + else + value_error "There is overlap in the lhs/rhs return values" + end + end + elsif op == "<=" + begin + @lhs.value(symtab) <= @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all <= the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value <= rhs_value} } + true + else + value_error "Some value of lhs is not <= some value of rhs" + end + end + elsif op == ">=" + begin + @lhs.value(symtab) >= @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all >= the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value >= rhs_value} } + true + else + value_error "Some value of lhs is not >= some value of rhs" + end + end + elsif op == "<" + begin + @lhs.value(symtab) < @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all < the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value < rhs_value} } + true + else + value_error "Some value of lhs is not < some value of rhs" + end + end + elsif op == ">" + begin + @lhs.value(symtab) > @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all > the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value > rhs_value} } + true + else + value_error "Some value of lhs is not > some value of rhs" + end + end else - eval "lhs.value(symtab) #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ + v = eval "lhs.value(symtab) #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ + v & ((1 << type(symtab).width) - 1) end end

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -1194,7 +1674,7 @@

    diff --git a/docs/ruby/Idl/BitfieldAccessExpressionAst.html b/docs/ruby/Idl/BitfieldAccessExpressionAst.html index ec31a8332..4159a505b 100644 --- a/docs/ruby/Idl/BitfieldAccessExpressionAst.html +++ b/docs/ruby/Idl/BitfieldAccessExpressionAst.html @@ -253,6 +253,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -288,12 +317,12 @@

     
     
    -1906
    -1907
    -1908
    +2050 +2051 +2052

    -
    # File 'lib/idl/ast.rb', line 1906
    +      
    # File 'lib/idl/ast.rb', line 2050
     
     def kind(symtab)
       rval.type(symtab).kind
    @@ -347,10 +376,10 @@ 

     
     
    -1966
    +2110

    -
    # File 'lib/idl/ast.rb', line 1966
    +      
    # File 'lib/idl/ast.rb', line 2110
     
     def to_idl = "#{rval.to_idl}.#{field_name.to_idl}"
    @@ -442,20 +471,20 @@

     
     
    -1911
    -1912
    -1913
    -1914
    -1915
    -1916
    -1917
    -1918
    -1919
    -1920
    -1921
    +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065

    -
    # File 'lib/idl/ast.rb', line 1911
    +      
    # File 'lib/idl/ast.rb', line 2055
     
     def type(symtab)
       rval_type = rval.type(symtab)
    @@ -488,38 +517,38 @@ 

     
     
    -1923
    -1924
    -1925
    -1926
    -1927
    -1928
    -1929
    -1930
    -1931
    -1932
    -1933
    -1934
    -1935
    -1936
    -1937
    -1938
    -1939
    -1940
    -1941
    -1942
    -1943
    -1944
    -1945
    -1946
    -1947
    -1948
    -1949
    -1950
    -1951
    +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095

    -
    # File 'lib/idl/ast.rb', line 1923
    +      
    # File 'lib/idl/ast.rb', line 2067
     
     def type_check(symtab)
       rval.type_check(symtab)
    @@ -581,19 +610,19 @@ 

     
     
    -1954
    -1955
    -1956
    -1957
    -1958
    -1959
    -1960
    -1961
    -1962
    -1963
    +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107

    -
    # File 'lib/idl/ast.rb', line 1954
    +      
    # File 'lib/idl/ast.rb', line 2098
     
     def value(symtab)
       if kind(symtab) == :bitfield
    @@ -608,6 +637,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -615,7 +740,7 @@

    diff --git a/docs/ruby/Idl/BitfieldDefinitionAst.html b/docs/ruby/Idl/BitfieldDefinitionAst.html index b38456cc1..3f688704c 100644 --- a/docs/ruby/Idl/BitfieldDefinitionAst.html +++ b/docs/ruby/Idl/BitfieldDefinitionAst.html @@ -153,6 +153,30 @@

  • + #add_symbol(symtab) ⇒ Object + + + + + + + + + + + + + +
    +

    Add symbol(s) at the outermost scope of the symbol table.

    +
    + +
  • + + +
  • + + #element_names ⇒ Array<String> @@ -334,7 +358,70 @@

    Instance Method Details

    -

    +

    + + #add_symbol(symtab) ⇒ Object + + + + + +

    +
    + +

    Add symbol(s) at the outermost scope of the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table at the scope that the symbol(s) will be inserted

      +
      + +
    • + +
    + + +
    + + + + +
    +
    +
    +
    +725
    +726
    +727
    +728
    +
    +
    # File 'lib/idl/ast.rb', line 725
    +
    +def add_symbol(symtab)
    +  t = type(symtab)
    +  symtab.add!(name, t)
    +end
    +
    +
    + +
    +

    #element_namesArray<String> @@ -377,14 +464,14 @@

     
     
    -662
    -663
    -664
    -665
    -666
    +686 +687 +688 +689 +690

  • -
    # File 'lib/idl/ast.rb', line 662
    +      
    # File 'lib/idl/ast.rb', line 686
     
     def element_names
       return @element_names unless @element_names.nil?
    @@ -440,22 +527,22 @@ 

     
     
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706

    -
    # File 'lib/idl/ast.rb', line 670
    +      
    # File 'lib/idl/ast.rb', line 694
     
     def element_ranges
       return @element_ranges unless @element_ranges.nil?
    @@ -519,10 +606,10 @@ 

     
     
    -705
    +734

    -
    # File 'lib/idl/ast.rb', line 705
    +      
    # File 'lib/idl/ast.rb', line 734
     
     def name = user_type_name.text_value
    @@ -574,17 +661,17 @@

     
     
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    +740 +741 +742 +743 +744 +745 +746 +747

    -
    # File 'lib/idl/ast.rb', line 711
    +      
    # File 'lib/idl/ast.rb', line 740
     
     def to_idl
       idl = "bitfield (#{bf_size}) #{name} { "
    @@ -663,10 +750,10 @@ 

     
     
    -702
    +731

    -
    # File 'lib/idl/ast.rb', line 702
    +      
    # File 'lib/idl/ast.rb', line 731
     
     def type(symtab) = BitfieldType.new(name, int.value(symtab), element_names, element_ranges)
    @@ -754,24 +841,23 @@

     
     
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722

    -
    # File 'lib/idl/ast.rb', line 685
    +      
    # File 'lib/idl/ast.rb', line 709
     
     def type_check(symtab)
       int.type_check(symtab)
    @@ -785,8 +871,7 @@ 

    type_error "Field position (#{b}) is larger than the bitfield width (#{bf_size})" if b >= bf_size end - t = type(symtab) - symtab.add!(name, t) + add_symbol(symtab) end

    @@ -889,10 +974,10 @@

     
     
    -708
    +737

    -
    # File 'lib/idl/ast.rb', line 708
    +      
    # File 'lib/idl/ast.rb', line 737
     
     def value(_symtab, _archdef) = raise AstNode::InternalError, "Bitfield defintions have no value"
    @@ -905,7 +990,7 @@

    diff --git a/docs/ruby/Idl/BitfieldType.html b/docs/ruby/Idl/BitfieldType.html index 178d22567..0b9febed2 100644 --- a/docs/ruby/Idl/BitfieldType.html +++ b/docs/ruby/Idl/BitfieldType.html @@ -242,17 +242,17 @@

     
     
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    +387 +388 +389 +390 +391 +392 +393 +394

    -
    # File 'lib/idl/type.rb', line 376
    +      
    # File 'lib/idl/type.rb', line 387
     
     def initialize(type_name, width, field_names, field_ranges)
       super(:bitfield, name: type_name, width: width)
    @@ -289,17 +289,17 @@ 

     
     
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    +407 +408 +409 +410 +411 +412 +413 +414

    -
    # File 'lib/idl/type.rb', line 396
    +      
    # File 'lib/idl/type.rb', line 407
     
     def clone
       BitfieldType.new(
    @@ -329,12 +329,12 @@ 

     
     
    -392
    -393
    -394
    +403 +404 +405

    -
    # File 'lib/idl/type.rb', line 392
    +      
    # File 'lib/idl/type.rb', line 403
     
     def field_names
       @field_names
    @@ -359,15 +359,15 @@ 

     
     
    -385
    -386
    -387
    -388
    -389
    -390
    +396 +397 +398 +399 +400 +401

    -
    # File 'lib/idl/type.rb', line 385
    +      
    # File 'lib/idl/type.rb', line 396
     
     def range(field_name)
       i = @field_names.index(field_name)
    @@ -385,7 +385,7 @@ 

    diff --git a/docs/ruby/Idl/BitsCastAst.html b/docs/ruby/Idl/BitsCastAst.html index 86f9b0e1b..921591a65 100644 --- a/docs/ruby/Idl/BitsCastAst.html +++ b/docs/ruby/Idl/BitsCastAst.html @@ -232,6 +232,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -296,10 +325,10 @@

     
     
    -1528
    +1595

    -
    # File 'lib/idl/ast.rb', line 1528
    +      
    # File 'lib/idl/ast.rb', line 1595
     
     def to_idl = "$signed(#{expression.to_idl})"
    @@ -391,22 +420,22 @@

     
     
    -1498
    -1499
    -1500
    -1501
    -1502
    -1503
    -1504
    -1505
    -1506
    -1507
    -1508
    -1509
    -1510
    +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575

    -
    # File 'lib/idl/ast.rb', line 1498
    +      
    # File 'lib/idl/ast.rb', line 1563
     
     def type(symtab)
       etype = expression.type(symtab)
    @@ -506,16 +535,16 @@ 

     
     
    -1489
    -1490
    -1491
    -1492
    -1493
    -1494
    -1495
    +1554 +1555 +1556 +1557 +1558 +1559 +1560

    -
    # File 'lib/idl/ast.rb', line 1489
    +      
    # File 'lib/idl/ast.rb', line 1554
     
     def type_check(symtab)
       expression.type_check(symtab)
    @@ -555,22 +584,24 @@ 

     
     
    -1513
    -1514
    -1515
    -1516
    -1517
    -1518
    -1519
    -1520
    -1521
    -1522
    -1523
    -1524
    -1525
    +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592

    -
    # File 'lib/idl/ast.rb', line 1513
    +      
    # File 'lib/idl/ast.rb', line 1578
     
     def value(symtab)
       etype = expression.type(symtab)
    @@ -582,12 +613,110 @@ 

    element_name = expression.text_value.split(":")[2] etype.enum_class.value(element_name) when :csr - internal_error "TODO" + expression.value(symtab) + else + internal_error "TODO: Bits cast for #{etype.kind}" end end

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -595,7 +724,7 @@

    diff --git a/docs/ruby/Idl/BitsTypeAst.html b/docs/ruby/Idl/BitsTypeAst.html index 5102fe4e9..eef5221bd 100644 --- a/docs/ruby/Idl/BitsTypeAst.html +++ b/docs/ruby/Idl/BitsTypeAst.html @@ -121,6 +121,30 @@

  • + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    + +
  • + + +
  • + + #type(symtab) ⇒ Type @@ -182,7 +206,62 @@

    Instance Method Details

    -

    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +2670
    +
    +
    # File 'lib/idl/ast.rb', line 2670
    +
    +def to_idl = "Bits<#{i.to_idl}>"
    +
    +
    + +
    +

    #type(symtab) ⇒ Type @@ -265,12 +344,12 @@

     
     
    -2430
    -2431
    -2432
    +2665 +2666 +2667

  • -
    # File 'lib/idl/ast.rb', line 2430
    +      
    # File 'lib/idl/ast.rb', line 2665
     
     def type(symtab)
       Type.new(:bits, width: i.value(symtab).to_i)
    @@ -360,19 +439,19 @@ 

     
     
    -2418
    -2419
    -2420
    -2421
    -2422
    -2423
    -2424
    -2425
    -2426
    -2427
    +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662

    -
    # File 'lib/idl/ast.rb', line 2418
    +      
    # File 'lib/idl/ast.rb', line 2653
     
     def type_check(symtab)
       i.type_check(symtab)
    @@ -394,7 +473,7 @@ 

    diff --git a/docs/ruby/Idl/BuiltinEnumDefinitionAst.html b/docs/ruby/Idl/BuiltinEnumDefinitionAst.html index 6794d1662..f85fd75c5 100644 --- a/docs/ruby/Idl/BuiltinEnumDefinitionAst.html +++ b/docs/ruby/Idl/BuiltinEnumDefinitionAst.html @@ -264,10 +264,10 @@

     
     
    -636
    +660

    -
    # File 'lib/idl/ast.rb', line 636
    +      
    # File 'lib/idl/ast.rb', line 660
     
     def to_idl = "builtin enum #{user_type_name.text_value}"
    @@ -290,10 +290,10 @@

     
     
    -633
    +657

    -
    # File 'lib/idl/ast.rb', line 633
    +      
    # File 'lib/idl/ast.rb', line 657
     
     def type(symtab) = symtab.get(user_type_name.text_value)
    @@ -316,14 +316,14 @@

     
     
    -626
    -627
    -628
    -629
    -630
    +650 +651 +652 +653 +654

    -
    # File 'lib/idl/ast.rb', line 626
    +      
    # File 'lib/idl/ast.rb', line 650
     
     def type_check(_symtab)
       unless user_type_name.text_value == "ExtensionName"
    @@ -340,7 +340,7 @@ 

    diff --git a/docs/ruby/Idl/BuiltinTypeNameAst.html b/docs/ruby/Idl/BuiltinTypeNameAst.html index 110f09ba6..e06f7eca9 100644 --- a/docs/ruby/Idl/BuiltinTypeNameAst.html +++ b/docs/ruby/Idl/BuiltinTypeNameAst.html @@ -121,6 +121,30 @@

  • + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    + +
  • + + +
  • + + #type(symtab) ⇒ Type @@ -182,7 +206,62 @@

    Instance Method Details

    -

    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +2698
    +
    +
    # File 'lib/idl/ast.rb', line 2698
    +
    +def to_idl = text_value
    +
    +
    + +
    +

    #type(symtab) ⇒ Type @@ -265,24 +344,24 @@

     
     
    -2443
    -2444
    -2445
    -2446
    -2447
    -2448
    -2449
    -2450
    -2451
    -2452
    -2453
    -2454
    -2455
    -2456
    -2457
    +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695

  • -
    # File 'lib/idl/ast.rb', line 2443
    +      
    # File 'lib/idl/ast.rb', line 2681
     
     def type(symtab)
       archdef = symtab.archdef
    @@ -384,12 +463,12 @@ 

     
     
    -2438
    -2439
    -2440
    +2676 +2677 +2678

    -
    # File 'lib/idl/ast.rb', line 2438
    +      
    # File 'lib/idl/ast.rb', line 2676
     
     def type_check(symtab)
       type_error "Unimplemented builtin type #{text_value}" unless ["XReg", "Boolean", "U32", "U64"].include?(text_value)
    @@ -404,7 +483,7 @@ 

    diff --git a/docs/ruby/Idl/Compiler.html b/docs/ruby/Idl/Compiler.html index db936c242..e6400f9f8 100644 --- a/docs/ruby/Idl/Compiler.html +++ b/docs/ruby/Idl/Compiler.html @@ -128,6 +128,28 @@

  • + #compile_expression(expression, symtab) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + #compile_file(path, symtab) ⇒ Object @@ -298,7 +320,85 @@

    Instance Method Details

    -

    +

    + + #compile_expression(expression, symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +199
    +200
    +201
    +202
    +203
    +204
    +205
    +206
    +207
    +208
    +209
    +210
    +211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +
    +
    # File 'lib/idl.rb', line 192
    +
    +def compile_expression(expression, symtab)
    +  m = @parser.parse(expression, root: :expression)
    +  if m.nil?
    +    raise SyntaxError, <<~MSG
    +      While parsing #{expression}:#{@parser.failure_line}:#{@parser.failure_column}
    +
    +      #{@parser.failure_reason}
    +    MSG
    +  end
    +
    +  ast = m.to_ast
    +  begin
    +    ast.type_check(symtab)
    +  rescue AstNode::TypeError => e
    +    warn "Compiling #{expression}"
    +    warn e.what
    +    warn e.backtrace
    +    exit 1
    +  rescue AstNode::InternalError => e
    +    warn "Compiling #{expression}"
    +    warn e.what
    +    warn e.backtrace
    +    exit 1
    +  end
    +
    +  ast
    +end
    +
    +
    + +
    +

    #compile_file(path, symtab) ⇒ Object @@ -358,17 +458,17 @@

    raise "unexpected type #{m.class.name}" unless m.is_a?(IsaAst) - m.make_left + ast = m.to_ast - m.set_input_file(path.to_s) + ast.set_input_file(path.to_s) begin - m.type_check(symtab) + ast.type_check(symtab) rescue AstNode::TypeError, AstNode::InternalError => e warn e.what warn e.bt exit 1 end - m + ast end

  • @@ -632,8 +732,8 @@

    cloned_symtab.pop end - ast = @parser.parse(body, root: :function_body) - if ast.nil? + m = @parser.parse(body, root: :function_body) + if m.nil? raise SyntaxError, <<~MSG While parsing #{parent}::#{name} #{@parser.failure_line}:#{@parser.failure_column} @@ -642,15 +742,15 @@

    end # fix up left recursion - ast.make_left + ast = m.to_ast # type check cloned_symtab.push cloned_symtab.add("__expected_return_type", return_type) unless return_type.nil? begin - ast.func_stmt_list.elements.each do |e| - e.choice.type_check(cloned_symtab) + ast.statements.each do |s| + s.type_check(cloned_symtab) end rescue AstNode::TypeError => e raise e if no_rescue @@ -888,8 +988,8 @@

    def compile_inst_operation(operation, symtab: SymbolTable.new, name: nil, parent: nil, input_file: nil, input_line: 0) @parser.set_input_file(input_file, input_line) - ast = @parser.parse(operation, root: :instruction_operation) - if ast.nil? + m = @parser.parse(operation, root: :instruction_operation) + if m.nil? raise SyntaxError, <<~MSG While parsing #{input_file}:#{@parser.failure_line}:#{@parser.failure_column} @@ -898,7 +998,7 @@

    end # fix up left recursion - ast.make_left + ast = m.to_ast # type check symtab.push @@ -938,7 +1038,7 @@

    diff --git a/docs/ruby/Idl/ConcatenationExpressionAst.html b/docs/ruby/Idl/ConcatenationExpressionAst.html index f59d576bd..7c163db17 100644 --- a/docs/ruby/Idl/ConcatenationExpressionAst.html +++ b/docs/ruby/Idl/ConcatenationExpressionAst.html @@ -232,6 +232,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -296,10 +325,10 @@

     
     
    -1799
    +1943

    -
    # File 'lib/idl/ast.rb', line 1799
    +      
    # File 'lib/idl/ast.rb', line 1943
     
     def to_idl = "{#{first.to_idl},#{rest.elements.map { |e| e.expression.to_idl }.join(',')}}"
    @@ -391,18 +420,18 @@

     
     
    -1777
    -1778
    -1779
    -1780
    -1781
    -1782
    -1783
    -1784
    -1785
    +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929

    -
    # File 'lib/idl/ast.rb', line 1777
    +      
    # File 'lib/idl/ast.rb', line 1921
     
     def type(symtab)
       total_width = first.type(symtab).width
    @@ -498,22 +527,22 @@ 

     
     
    -1762
    -1763
    -1764
    -1765
    -1766
    -1767
    -1768
    -1769
    -1770
    -1771
    -1772
    -1773
    -1774
    +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918

    -
    # File 'lib/idl/ast.rb', line 1762
    +      
    # File 'lib/idl/ast.rb', line 1906
     
     def type_check(symtab)
       first.type_check(symtab)
    @@ -559,18 +588,18 @@ 

     
     
    -1788
    -1789
    -1790
    -1791
    -1792
    -1793
    -1794
    -1795
    -1796
    +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940

    -
    # File 'lib/idl/ast.rb', line 1788
    +      
    # File 'lib/idl/ast.rb', line 1932
     
     def value(symtab)
       result = first.value(symtab)
    @@ -584,6 +613,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -591,7 +716,7 @@

    diff --git a/docs/ruby/Idl/ConditionalReturnStatementAst.html b/docs/ruby/Idl/ConditionalReturnStatementAst.html index 3352254af..865af920a 100644 --- a/docs/ruby/Idl/ConditionalReturnStatementAst.html +++ b/docs/ruby/Idl/ConditionalReturnStatementAst.html @@ -164,6 +164,28 @@

    +
    + + + + +
  • + + + #return_values(symtab) ⇒ Object + + + + + + + + + + + + +
  • @@ -203,12 +225,12 @@

     
     
    -2395
    -2396
    -2397
    +2618 +2619 +2620

    -
    # File 'lib/idl/ast.rb', line 2395
    +      
    # File 'lib/idl/ast.rb', line 2618
     
     def condition
       expression
    @@ -233,20 +255,20 @@ 

     
     
    -2399
    -2400
    -2401
    -2402
    -2403
    -2404
    -2405
    -2406
    -2407
    -2408
    -2409
    +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633

    -
    # File 'lib/idl/ast.rb', line 2399
    +      
    # File 'lib/idl/ast.rb', line 2623
     
     def return_value(symtab)
       cond = condition.value(symtab)
    @@ -262,6 +284,48 @@ 

    + + +
    +

    + + #return_values(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +2636
    +2637
    +2638
    +2639
    +2640
    +2641
    +2642
    +2643
    +2644
    +
    +
    # File 'lib/idl/ast.rb', line 2636
    +
    +def return_values(symtab)
    +  cond = condition.value(symtab)
    +
    +  cond ? return_value_nodes.map { |n| n.values(symtab) }.flatten.uniq : []
    +
    +rescue ValueError
    +  # condition isn't known, so the return value is always possible
    +  return_value_nodes.map { |n| n.values(symtab) }.flatten
    +end
    +
    @@ -269,7 +333,7 @@

    diff --git a/docs/ruby/Idl/ConditionalStatementAst.html b/docs/ruby/Idl/ConditionalStatementAst.html index c84feb74b..b4a98dfde 100644 --- a/docs/ruby/Idl/ConditionalStatementAst.html +++ b/docs/ruby/Idl/ConditionalStatementAst.html @@ -69,7 +69,7 @@
    Inherits:
    - StatementAst + AstNode @@ -100,7 +98,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb
    +
    @@ -125,6 +125,69 @@

    Overview

    +

    Instance Attribute Summary collapse

    +
      + +
    • + + + #action ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute action.

      +
      + +
    • + + +
    • + + + #condition ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute condition.

      +
      + +
    • + + +
    + @@ -139,7 +202,7 @@

  • - #action ⇒ Object + #execute(symtab) ⇒ void @@ -153,7 +216,9 @@

    -
    +
    +

    “execute” the statement by updating the variables in the symbol table.

    +

  • @@ -161,7 +226,7 @@

  • - #condition ⇒ Object + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object @@ -183,7 +248,33 @@

  • - #execute(symtab) ⇒ Object + #initialize(action, condition) ⇒ ConditionalStatementAst + + + + + + + constructor + + + + + + + + +
    +

    A new instance of ConditionalStatementAst.

    +
    + +
  • + + +
  • + + + #prune(symtab) ⇒ Object @@ -199,6 +290,30 @@

    +

  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -235,108 +350,372 @@

    +
    +

    Constructor Details

    +
    +

    + #initialize(action, condition) ⇒ ConditionalStatementAst + + +

    +
    + +

    Returns a new instance of ConditionalStatementAst.

    -
    -

    Instance Method Details

    +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +2410
    +2411
    +2412
    +2413
    +2414
    +
    +
    # File 'lib/idl/ast.rb', line 2410
    +
    +def initialize(action, condition)
    +  super(action.input, action.interval.first..action.interval.end, [action, condition])
    +  @action = action
    +  @condition = condition
    +end
    +
    +
    + +
    + +
    +

    Instance Attribute Details

    + +

    - #actionObject + #actionObject (readonly) -

    +
    +
    + +

    Returns the value of attribute action.

    + + +
    +
    +
    + + +
     
     
    -2224
    +2408 +2409 +2410
    -
    # File 'lib/idl/ast.rb', line 2224
    +      
    # File 'lib/idl/ast.rb', line 2408
     
    -def action = a
    +def action + @action +end
    + +

    - #conditionObject + #conditionObject (readonly) -

    +
    +
    + +

    Returns the value of attribute condition.

    + + +
    +
    +
    + + +
     
     
    -2226
    -2227
    -2228
    +2408 +2409 +2410
    -
    # File 'lib/idl/ast.rb', line 2226
    +      
    # File 'lib/idl/ast.rb', line 2408
     
     def condition
    -  expression
    +  @condition
     end
    -
    -

    +

    + + +
    +

    Instance Method Details

    + + +
    +

    - #execute(symtab) ⇒ Object + #execute(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    “execute” the statement by updating the variables in the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The symbol table for the context

      +
      + +
    • + +
    + +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      ValueError if some part of the statement cannot be executed at compile time

      +
      + +
    • + +
    + +
     
     
    -2230
    -2231
    -2232
    -2233
    -2234
    -2235
    -2236
    +2424 +2425 +2426 +2427 +2428 +2429 +2430
    -
    # File 'lib/idl/ast.rb', line 2230
    +      
    # File 'lib/idl/ast.rb', line 2424
     
     def execute(symtab)
    -  cond = condition.value(symtab)
    +  cond = @condition.value(symtab)
     
       if (cond)
    -    action.execute(symtab)
    +    @action.execute(symtab)
       end
     end
    +
    + +
    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +79
    +80
    +81
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 79
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  "#{action.gen_adoc(indent, indent_spaces:)} if (#{condition.gen_adoc(0, indent_spaces:)});"
    +end
    +
    +
    + +
    +

    + + #prune(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +188
    +189
    +190
    +191
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +
    +
    # File 'lib/idl/passes/prune.rb', line 188
    +
    +def prune(symtab)
    +  puts "pruning #{condition.text_value}"
    +  if condition.value(symtab)
    +    StatementAst.new(action.prune(symtab))
    +  else
    +    NoopAst.new()
    +  end
    +rescue ValueError
    +  # condition not known
    +  self
    +end
    +
    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +2433
    +2434
    +2435
    +
    +
    # File 'lib/idl/ast.rb', line 2433
    +
    +def to_idl
    +  "#{@action.to_idl} if (#{@condition.to_idl});"
    +end
    +
    @@ -419,19 +798,19 @@

     
     
    -2218
    -2219
    -2220
    -2221
    -2222
    +2417 +2418 +2419 +2420 +2421

  • -
    # File 'lib/idl/ast.rb', line 2218
    +      
    # File 'lib/idl/ast.rb', line 2417
     
     def type_check(symtab)
    -  action.type_check(symtab)
    -  condition.type_check(symtab)
    -  type_error "condition is not boolean" unless condition.type(symtab).convertable_to?(:boolean)
    +  @action.type_check(symtab)
    +  @condition.type_check(symtab)
    +  type_error "condition is not boolean" unless @condition.type(symtab).convertable_to?(:boolean)
     end
    @@ -443,7 +822,7 @@

    diff --git a/docs/ruby/Idl/CsrFieldReadExpressionAst.html b/docs/ruby/Idl/CsrFieldReadExpressionAst.html index bb0d6b9d1..ede12d9af 100644 --- a/docs/ruby/Idl/CsrFieldReadExpressionAst.html +++ b/docs/ruby/Idl/CsrFieldReadExpressionAst.html @@ -103,7 +103,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/gen_adoc.rb
    +
    @@ -206,6 +208,28 @@

    +
    + + + + +
  • + + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + +
  • @@ -304,6 +328,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -339,18 +392,18 @@

     
     
    -3290
    -3291
    -3292
    -3293
    -3294
    -3295
    -3296
    -3297
    -3298
    +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927

    -
    # File 'lib/idl/ast.rb', line 3290
    +      
    # File 'lib/idl/ast.rb', line 3919
     
     def csr_def(symtab)
       archdef = symtab.archdef
    @@ -381,12 +434,12 @@ 

     
     
    -3300
    -3301
    -3302
    +3929 +3930 +3931

    -
    # File 'lib/idl/ast.rb', line 3300
    +      
    # File 'lib/idl/ast.rb', line 3929
     
     def csr_name(symtab)
       csr_def(symtab).name
    @@ -411,12 +464,12 @@ 

     
     
    -3304
    -3305
    -3306
    +3933 +3934 +3935

    -
    # File 'lib/idl/ast.rb', line 3304
    +      
    # File 'lib/idl/ast.rb', line 3933
     
     def field_def(symtab)
       csr_def(symtab).implemented_fields.find { |f| f.name == csr_field_name.text_value }
    @@ -441,12 +494,12 @@ 

     
     
    -3308
    -3309
    -3310
    +3937 +3938 +3939

    -
    # File 'lib/idl/ast.rb', line 3308
    +      
    # File 'lib/idl/ast.rb', line 3937
     
     def field_name(symtab)
       field_def(symtab).name
    @@ -454,6 +507,46 @@ 

    + + +
    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 98
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  csr_text = "CSR[#{idx.text_value}].#{csr_field_name.text_value}"
    +  if idx.text_value =~ /[0-9]+/
    +    csr_text
    +  else
    +    "%%LINK%csr_field;#{idx.text_value}.#{csr_field_name.text_value};#{csr_text}%%"
    +  end
    +end
    +
    @@ -500,16 +593,16 @@

     
     
    -3313
    -3314
    -3315
    -3316
    -3317
    -3318
    -3319
    +3942 +3943 +3944 +3945 +3946 +3947 +3948

    -
    # File 'lib/idl/ast.rb', line 3313
    +      
    # File 'lib/idl/ast.rb', line 3942
     
     def to_idl
       if idx.is_a?(IntAst)
    @@ -607,21 +700,21 @@ 

     
     
    -3322
    -3323
    -3324
    -3325
    -3326
    -3327
    -3328
    -3329
    -3330
    -3331
    -3332
    -3333
    +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962

    -
    # File 'lib/idl/ast.rb', line 3322
    +      
    # File 'lib/idl/ast.rb', line 3951
     
     def type(symtab)
       fd = field_def(symtab)
    @@ -720,29 +813,21 @@ 

     
     
    -3275
    -3276
    -3277
    -3278
    -3279
    -3280
    -3281
    -3282
    -3283
    -3284
    -3285
    -3286
    -3287
    -3288
    +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917

    -
    # File 'lib/idl/ast.rb', line 3275
    +      
    # File 'lib/idl/ast.rb', line 3908
     
     def type_check(symtab)
    -  archdef = symtab.archdef
    -
    -
    -
       if idx.is_a?(IntAst)
         type_error "No CSR at address #{idx.text_value}" if csr_def(symtab).nil?
       else
    @@ -783,13 +868,13 @@ 

     
     
    -3336
    -3337
    -3338
    -3339
    +3965 +3966 +3967 +3968

    -
    # File 'lib/idl/ast.rb', line 3336
    +      
    # File 'lib/idl/ast.rb', line 3965
     
     def value(symtab)
       value_error "'#{csr_name(symtab)}.#{field_name(symtab)}' is not RO" unless field_def(symtab).type == "RO"
    @@ -798,6 +883,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -805,7 +986,7 @@

    diff --git a/docs/ruby/Idl/CsrReadExpressionAst.html b/docs/ruby/Idl/CsrReadExpressionAst.html index 5f2b14597..1cdb79fe2 100644 --- a/docs/ruby/Idl/CsrReadExpressionAst.html +++ b/docs/ruby/Idl/CsrReadExpressionAst.html @@ -103,7 +103,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/gen_adoc.rb
    +
    @@ -186,6 +188,52 @@

    + + + +
  • + + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -254,7 +302,38 @@

    -
    +
    +

    Return the compile-time-known value of the node.

    +
    + + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
  • @@ -291,29 +370,29 @@

     
     
    -3382
    -3383
    -3384
    -3385
    -3386
    -3387
    -3388
    -3389
    -3390
    -3391
    -3392
    -3393
    -3394
    -3395
    -3396
    -3397
    -3398
    -3399
    -3400
    -3401
    +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030

    -
    # File 'lib/idl/ast.rb', line 3382
    +      
    # File 'lib/idl/ast.rb', line 4011
     
     def csr_def(symtab)
       archdef = symtab.archdef
    @@ -377,12 +456,12 @@ 

     
     
    -3403
    -3404
    -3405
    +4032 +4033 +4034

    -
    # File 'lib/idl/ast.rb', line 3403
    +      
    # File 'lib/idl/ast.rb', line 4032
     
     def csr_known?(symtab)
       !csr_def(symtab).nil?
    @@ -407,14 +486,14 @@ 

     
     
    -3407
    -3408
    -3409
    -3410
    -3411
    +4036 +4037 +4038 +4039 +4040

    -
    # File 'lib/idl/ast.rb', line 3407
    +      
    # File 'lib/idl/ast.rb', line 4036
     
     def csr_name(symtab)
       internal_error "No CSR" unless csr_known?(symtab)
    @@ -424,6 +503,101 @@ 

    + + +
    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 109
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  csr_text = "CSR[#{idx.text_value}]"
    +  if idx.text_value =~ /[0-9]+/
    +    csr_text
    +  else
    +    "%%LINK%csr;#{idx.text_value};#{csr_text}%%"
    +  end
    +end
    +
    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +4053
    +
    +
    # File 'lib/idl/ast.rb', line 4053
    +
    +def to_idl = "CSR[#{idx.text_value}]"
    +
    @@ -510,21 +684,21 @@

     
     
    -3346
    -3347
    -3348
    -3349
    -3350
    -3351
    -3352
    -3353
    -3354
    -3355
    -3356
    -3357
    +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986

    -
    # File 'lib/idl/ast.rb', line 3346
    +      
    # File 'lib/idl/ast.rb', line 3975
     
     def type(symtab)
       archdef = symtab.archdef
    @@ -623,30 +797,30 @@ 

     
     
    -3360
    -3361
    -3362
    -3363
    -3364
    -3365
    -3366
    -3367
    -3368
    -3369
    -3370
    -3371
    -3372
    -3373
    -3374
    -3375
    -3376
    -3377
    -3378
    -3379
    -3380
    +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009

    -
    # File 'lib/idl/ast.rb', line 3360
    +      
    # File 'lib/idl/ast.rb', line 3989
     
     def type_check(symtab)
       archdef = symtab.archdef
    @@ -683,23 +857,34 @@ 

    -

    +
    +
    + +

    Return the compile-time-known value of the node

    + + +
    +
    +
    + + +
     
     
    -3413
    -3414
    -3415
    -3416
    -3417
    -3418
    -3419
    -3420
    +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050
    -
    # File 'lib/idl/ast.rb', line 3413
    +      
    # File 'lib/idl/ast.rb', line 4043
     
     def value(symtab)
       cd = csr_def(symtab)
    @@ -712,6 +897,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -719,7 +1000,7 @@

    diff --git a/docs/ruby/Idl/CsrSoftwareReadAst.html b/docs/ruby/Idl/CsrSoftwareReadAst.html index bc60fcf93..b0b824747 100644 --- a/docs/ruby/Idl/CsrSoftwareReadAst.html +++ b/docs/ruby/Idl/CsrSoftwareReadAst.html @@ -186,6 +186,30 @@

    + + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -252,6 +276,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -287,12 +340,12 @@

     
     
    -3476
    -3477
    -3478
    +4115 +4116 +4117

    -
    # File 'lib/idl/ast.rb', line 3476
    +      
    # File 'lib/idl/ast.rb', line 4115
     
     def csr_def(symtab)
       csr.csr_def(symtab)
    @@ -339,12 +392,12 @@ 

     
     
    -3468
    -3469
    -3470
    +4107 +4108 +4109

    -
    # File 'lib/idl/ast.rb', line 3468
    +      
    # File 'lib/idl/ast.rb', line 4107
     
     def csr_known?(symtab)
       csr.csr_known?(symtab)
    @@ -369,12 +422,12 @@ 

     
     
    -3472
    -3473
    -3474
    +4111 +4112 +4113

    -
    # File 'lib/idl/ast.rb', line 3472
    +      
    # File 'lib/idl/ast.rb', line 4111
     
     def csr_name(symtab)
       csr.csr_name(symtab)
    @@ -382,6 +435,61 @@ 

    + + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +4129
    +
    +
    # File 'lib/idl/ast.rb', line 4129
    +
    +def to_idl = "CSR[#{csr.to_idl}].sw_read()"
    +
    @@ -399,18 +507,18 @@

     
     
    -3458
    -3459
    -3460
    -3461
    -3462
    -3463
    -3464
    -3465
    -3466
    +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105

    -
    # File 'lib/idl/ast.rb', line 3458
    +      
    # File 'lib/idl/ast.rb', line 4097
     
     def type(symtab)
       archdef = symtab.archdef
    @@ -441,12 +549,12 @@ 

     
     
    -3454
    -3455
    -3456
    +4093 +4094 +4095

    -
    # File 'lib/idl/ast.rb', line 3454
    +      
    # File 'lib/idl/ast.rb', line 4093
     
     def type_check(symtab)
       csr.type_check(symtab)
    @@ -488,19 +596,19 @@ 

     
     
    -3481
    -3482
    -3483
    -3484
    -3485
    -3486
    -3487
    +4120 +4121 +4122 +4123 +4124 +4125 +4126

    -
    # File 'lib/idl/ast.rb', line 3481
    +      
    # File 'lib/idl/ast.rb', line 4120
     
     def value(symtab)
    -  value_error "CSR not knowable" unless csr_known?
    +  value_error "CSR not knowable" unless csr_known?(symtab)
       cd = csr_def(symtab)
       cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" }
     
    @@ -509,6 +617,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -516,7 +720,7 @@

    diff --git a/docs/ruby/Idl/CsrSoftwareWriteAst.html b/docs/ruby/Idl/CsrSoftwareWriteAst.html index f157c8608..2694fcf90 100644 --- a/docs/ruby/Idl/CsrSoftwareWriteAst.html +++ b/docs/ruby/Idl/CsrSoftwareWriteAst.html @@ -170,17 +170,12 @@

  • - #execute(symtab) ⇒ void + #execute(_symtab) ⇒ void - - included - from Executable - - @@ -193,6 +188,30 @@

    “execute” the statement by updating the variables in the symbol table.

    +

  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -235,7 +254,9 @@

    -
    +
    +

    Return the compile-time-known value of the node.

    +
    @@ -294,12 +315,12 @@

     
     
    -3437
    -3438
    -3439
    +4070 +4071 +4072

    -
    # File 'lib/idl/ast.rb', line 3437
    +      
    # File 'lib/idl/ast.rb', line 4070
     
     def csr_known?(symtab)
       csr.csr_known?(symtab)
    @@ -324,12 +345,12 @@ 

     
     
    -3441
    -3442
    -3443
    +4074 +4075 +4076

    -
    # File 'lib/idl/ast.rb', line 3441
    +      
    # File 'lib/idl/ast.rb', line 4074
     
     def csr_name(symtab)
       csr.csr_name(symtab)
    @@ -342,17 +363,12 @@ 

    - #execute(symtab) ⇒ void + #execute(_symtab) ⇒ void - - Originally defined in module - Executable - -

    This method returns an undefined value.

    @@ -402,7 +418,76 @@

    +

    + + + + +
    +
    +
    +
    +4084
    +
    +
    # File 'lib/idl/ast.rb', line 4084
    +
    +def execute(_symtab) = value_error "CSR writes are global"
    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +4087
    +
    +
    # File 'lib/idl/ast.rb', line 4087
    +
    +def to_idl = "CSR[#{csr.to_idl}].sw_write(#{expression.to_idl})"
    +
    @@ -420,19 +505,19 @@

     
     
    -3426
    -3427
    -3428
    -3429
    -3430
    -3431
    -3432
    -3433
    -3434
    -3435
    +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068

    -
    # File 'lib/idl/ast.rb', line 3426
    +      
    # File 'lib/idl/ast.rb', line 4059
     
     def type_check(symtab)
       archdef = symtab.archdef
    @@ -458,18 +543,29 @@ 

    -

    +
    +
    + +

    Return the compile-time-known value of the node

    + + +
    +
    +
    + + +
    @@ -578,17 +665,17 @@

     
     
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    +633 +634 +635 +636 +637 +638 +639 +640

    @@ -887,10 +972,10 @@

     
     
    -603
    +627

    @@ -903,7 +988,7 @@

    diff --git a/docs/ruby/Idl/EnumRefAst.html b/docs/ruby/Idl/EnumRefAst.html index ba26f888f..49e8af76a 100644 --- a/docs/ruby/Idl/EnumRefAst.html +++ b/docs/ruby/Idl/EnumRefAst.html @@ -229,6 +229,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -293,10 +322,10 @@

     
     
    -2000
    +2144

    @@ -319,14 +348,14 @@

     
     
    -1986
    -1987
    -1988
    -1989
    -1990
    +2130 +2131 +2132 +2133 +2134

     
     
    -3445
    -3446
    -3447
    +4079 +4080 +4081
    -
    # File 'lib/idl/ast.rb', line 3445
    +      
    # File 'lib/idl/ast.rb', line 4079
     
     def value(_symtab)
       value_error "CSR writes are global"
    @@ -484,7 +580,7 @@ 

    diff --git a/docs/ruby/Idl/CsrType.html b/docs/ruby/Idl/CsrType.html index 2e1d54179..406f85c5e 100644 --- a/docs/ruby/Idl/CsrType.html +++ b/docs/ruby/Idl/CsrType.html @@ -243,12 +243,12 @@

     
     
    -411
    -412
    -413
    +422 +423 +424

    -
    # File 'lib/idl/type.rb', line 411
    +      
    # File 'lib/idl/type.rb', line 422
     
     def initialize(csr, qualifiers: [])
       super(:csr, name: csr.name, csr: csr, qualifiers: qualifiers)
    @@ -291,12 +291,12 @@ 

     
     
    -409
    -410
    -411
    +420 +421 +422

    -
    # File 'lib/idl/type.rb', line 409
    +      
    # File 'lib/idl/type.rb', line 420
     
     def csr
       @csr
    @@ -328,12 +328,12 @@ 

     
     
    -415
    -416
    -417
    +426 +427 +428

    -
    # File 'lib/idl/type.rb', line 415
    +      
    # File 'lib/idl/type.rb', line 426
     
     def fields
       @csr.fields
    @@ -348,7 +348,7 @@ 

    diff --git a/docs/ruby/Idl/CsrWriteAst.html b/docs/ruby/Idl/CsrWriteAst.html index ff3981df9..6041886f6 100644 --- a/docs/ruby/Idl/CsrWriteAst.html +++ b/docs/ruby/Idl/CsrWriteAst.html @@ -148,7 +148,7 @@

  • - #execute(symtab) ⇒ Object + #execute(symtab) ⇒ void @@ -162,7 +162,9 @@

    -
    +
    +

    “execute” the statement by updating the variables in the symbol table.

    +

  • @@ -192,7 +194,7 @@

  • - #type(symtab) ⇒ Object + #to_idl ⇒ String @@ -206,7 +208,9 @@

    -
    +
    +

    Return valid IDL representation of the node (and its subtree).

    +

  • @@ -214,7 +218,7 @@

  • - #type_check(symtab) ⇒ Object + #type(symtab) ⇒ Type @@ -228,7 +232,33 @@

    -
    +
    +

    Given a specific symbol table, return the type of this node.

    +
    + +

  • + + +
  • + + + #type_check(symtab) ⇒ void + + + + + + + + + + + + + +
    +

    type check this node and all children.

    +
  • @@ -265,20 +295,20 @@

     
     
    -3506
    -3507
    -3508
    -3509
    -3510
    -3511
    -3512
    -3513
    -3514
    -3515
    -3516
    +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159

    -
    # File 'lib/idl/ast.rb', line 3506
    +      
    # File 'lib/idl/ast.rb', line 4149
     
     def csr_def(symtab)
       index =
    @@ -299,24 +329,73 @@ 

    - #execute(symtab) ⇒ Object + #execute(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    “execute” the statement by updating the variables in the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The symbol table for the context

      +
      + +
    • + +
    + +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      ValueError if some part of the statement cannot be executed at compile time

      +
      + +
    • + +
    + +
     
     
    -3526
    -3527
    -3528
    +4171 +4172 +4173
    -
    # File 'lib/idl/ast.rb', line 3526
    +      
    # File 'lib/idl/ast.rb', line 4171
     
     def execute(symtab)
       value_error "CSR write"
    @@ -341,12 +420,12 @@ 

     
     
    -3522
    -3523
    -3524
    +4166 +4167 +4168

    -
    # File 'lib/idl/ast.rb', line 3522
    +      
    # File 'lib/idl/ast.rb', line 4166
     
     def name(symtab)
       csr_def(symtab).name
    @@ -354,29 +433,153 @@ 

    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +4176
    +
    +
    # File 'lib/idl/ast.rb', line 4176
    +
    +def to_idl = "CSR[#{idx.text_value}]"
    +

    - #type(symtab) ⇒ Object + #type(symtab) ⇒ Type -

    +
    +
    + +

    Given a specific symbol table, return the type of this node.

    + +

    Should not be called until #type_check is called with the same arguments

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table for lookup

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Type) + + + + — +
      +

      The type of the node

      +
      + +
    • + +
    +

    Raises:

    +
      + +
    • + + + (AstNode::InternalError) + + + + — +
      +

      if the type is dependent on symtab, and type_check was not called first

      +
      + +
    • + +
    + +
    @@ -390,12 +419,12 @@

     
     
    -2252
    -2253
    -2254
    +2451 +2452 +2453

     
     
    -3518
    -3519
    -3520
    +4162 +4163 +4164
    -
    # File 'lib/idl/ast.rb', line 3518
    +      
    # File 'lib/idl/ast.rb', line 4162
     
     def type(symtab)
       CsrType.new(csr_def(symtab))
    @@ -389,33 +592,98 @@ 

    - #type_check(symtab) ⇒ Object + #type_check(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    type check this node and all children

    + +

    Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table for lookup

      +
      + +
    • + +
    + +

    Raises:

    + + +
    @@ -322,12 +351,12 @@

     
     
    -2286
    -2287
    -2288
    +2485 +2486 +2487

     
     
    -3493
    -3494
    -3495
    -3496
    -3497
    -3498
    -3499
    -3500
    -3501
    -3502
    -3503
    -3504
    +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147
    -
    # File 'lib/idl/ast.rb', line 3493
    +      
    # File 'lib/idl/ast.rb', line 4136
     
     def type_check(symtab)
       if idx.is_a?(IntAst)
    @@ -439,7 +707,7 @@ 

    diff --git a/docs/ruby/Idl/DontCareLvalueAst.html b/docs/ruby/Idl/DontCareLvalueAst.html index b72cc2f03..6a08c0755 100644 --- a/docs/ruby/Idl/DontCareLvalueAst.html +++ b/docs/ruby/Idl/DontCareLvalueAst.html @@ -212,6 +212,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -247,10 +276,10 @@

     
     
    -2293
    +2492

    -
    # File 'lib/idl/ast.rb', line 2293
    +      
    # File 'lib/idl/ast.rb', line 2492
     
     def to_idl = "-"
    -
    # File 'lib/idl/ast.rb', line 2286
    +      
    # File 'lib/idl/ast.rb', line 2485
     
     def type(_symtab, _archdef)
       Type.new(:dontcare)
    @@ -352,12 +381,12 @@ 

     
     
    -2281
    -2282
    -2283
    +2480 +2481 +2482

    -
    # File 'lib/idl/ast.rb', line 2281
    +      
    # File 'lib/idl/ast.rb', line 2480
     
     def type_check(_symtab)
       # nothing to do!
    @@ -463,15 +492,111 @@ 

     
     
    -2291
    +2490

    -
    # File 'lib/idl/ast.rb', line 2291
    +      
    # File 'lib/idl/ast.rb', line 2490
     
     def value(_symtab, _archdef) = internal_error "Why are you calling value for an lval?"
    +
    + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -479,7 +604,7 @@

    diff --git a/docs/ruby/Idl/DontCareReturnAst.html b/docs/ruby/Idl/DontCareReturnAst.html index d0b472c78..1549f2f39 100644 --- a/docs/ruby/Idl/DontCareReturnAst.html +++ b/docs/ruby/Idl/DontCareReturnAst.html @@ -250,6 +250,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -285,12 +314,12 @@

     
     
    -2270
    -2271
    -2272
    +2469 +2470 +2471

    -
    # File 'lib/idl/ast.rb', line 2270
    +      
    # File 'lib/idl/ast.rb', line 2469
     
     def set_expected_type(t)
       @expected_type = t
    @@ -315,10 +344,10 @@ 

     
     
    -2274
    +2473

    -
    # File 'lib/idl/ast.rb', line 2274
    +      
    # File 'lib/idl/ast.rb', line 2473
     
     def to_idl = "-"
    -
    # File 'lib/idl/ast.rb', line 2252
    +      
    # File 'lib/idl/ast.rb', line 2451
     
     def type(_symtab)
       Type.new(:dontcare)
    @@ -420,12 +449,12 @@ 

     
     
    -2247
    -2248
    -2249
    +2446 +2447 +2448

    -
    # File 'lib/idl/ast.rb', line 2247
    +      
    # File 'lib/idl/ast.rb', line 2446
     
     def type_check(_symtab)
       # nothing to do!
    @@ -531,21 +560,21 @@ 

     
     
    -2257
    -2258
    -2259
    -2260
    -2261
    -2262
    -2263
    -2264
    -2265
    -2266
    -2267
    -2268
    +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467

    -
    # File 'lib/idl/ast.rb', line 2257
    +      
    # File 'lib/idl/ast.rb', line 2456
     
     def value(_symtab, _archdef)
       internal_error "Must call set_expected_type first" if @expected_type.nil?
    @@ -562,6 +591,102 @@ 

    +
    + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -569,7 +694,7 @@

    diff --git a/docs/ruby/Idl/EnumDefinitionAst.html b/docs/ruby/Idl/EnumDefinitionAst.html index d27ac2724..9adbc011e 100644 --- a/docs/ruby/Idl/EnumDefinitionAst.html +++ b/docs/ruby/Idl/EnumDefinitionAst.html @@ -147,6 +147,30 @@

  • + #add_symbol(symtab) ⇒ Object + + + + + + + + + + + + + +
    +

    Add symbol(s) at the outermost scope of the symbol table.

    +
    + +
  • + + +
  • + + #element_names ⇒ Array<String> @@ -328,7 +352,70 @@

    Instance Method Details

    -

    +

    + + #add_symbol(symtab) ⇒ Object + + + + + +

    +
    + +

    Add symbol(s) at the outermost scope of the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table at the scope that the symbol(s) will be inserted

      +
      + +
    • + +
    + + +
    + + + + +
    +
    +
    +
    +616
    +617
    +618
    +619
    +
    +
    # File 'lib/idl/ast.rb', line 616
    +
    +def add_symbol(symtab)
    +  et = EnumerationType.new(user_type_name.text_value, element_names, element_values)
    +  symtab.add!(et.name, et)
    +end
    +
    +
    + +
    +

    #element_namesArray<String> @@ -371,14 +458,14 @@

     
     
    -557
    -558
    -559
    -560
    -561
    +576 +577 +578 +579 +580

  • -
    # File 'lib/idl/ast.rb', line 557
    +      
    # File 'lib/idl/ast.rb', line 576
     
     def element_names
       return @element_names unless @element_names.nil?
    @@ -434,27 +521,27 @@ 

     
     
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602

    -
    # File 'lib/idl/ast.rb', line 566
    +      
    # File 'lib/idl/ast.rb', line 585
     
     def element_values
       return @element_values unless @element_values.nil?
    @@ -523,10 +610,10 @@ 

     
     
    -606
    +630

    -
    # File 'lib/idl/ast.rb', line 606
    +      
    # File 'lib/idl/ast.rb', line 630
     
     def name = user_type_name.text_value
    -
    # File 'lib/idl/ast.rb', line 609
    +      
    # File 'lib/idl/ast.rb', line 633
     
     def to_idl
       idl = "enum #{name} { "
    @@ -667,12 +754,12 @@ 

     
     
    -598
    -599
    -600
    +622 +623 +624

    -
    # File 'lib/idl/ast.rb', line 598
    +      
    # File 'lib/idl/ast.rb', line 622
     
     def type(_symtab, _archdef)
       EnumerationType.new(user_type_name.text_value, element_names, element_values)
    @@ -762,19 +849,18 @@ 

     
     
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    +605 +606 +607 +608 +609 +610 +611 +612 +613

    -
    # File 'lib/idl/ast.rb', line 586
    +      
    # File 'lib/idl/ast.rb', line 605
     
     def type_check(symtab)
       e.elements.each do |e|
    @@ -783,8 +869,7 @@ 

    end end - et = EnumerationType.new(user_type_name.text_value, element_names, element_values) - symtab.add!(et.name, et) + add_symbol(symtab) end

    -
    # File 'lib/idl/ast.rb', line 603
    +      
    # File 'lib/idl/ast.rb', line 627
     
     def value(_symtab, _archdef) = raise InternalError, "Enum defintions have no value"
    -
    # File 'lib/idl/ast.rb', line 2000
    +      
    # File 'lib/idl/ast.rb', line 2144
     
     def to_idl = "#{enum_class.to_idl}::#{member.to_idl}"
    -
    # File 'lib/idl/ast.rb', line 1986
    +      
    # File 'lib/idl/ast.rb', line 2130
     
     def type(symtab)
       internal_error "Must call type_check first" if symtab.get(enum_class.text_value).nil?
    @@ -418,15 +447,15 @@ 

     
     
    -1978
    -1979
    -1980
    -1981
    -1982
    -1983
    +2122 +2123 +2124 +2125 +2126 +2127

    -
    # File 'lib/idl/ast.rb', line 1978
    +      
    # File 'lib/idl/ast.rb', line 2122
     
     def type_check(symtab)
       enum_def_type = symtab.get(enum_class.text_value)
    @@ -454,14 +483,14 @@ 

     
     
    -1993
    -1994
    -1995
    -1996
    -1997
    +2137 +2138 +2139 +2140 +2141

    -
    # File 'lib/idl/ast.rb', line 1993
    +      
    # File 'lib/idl/ast.rb', line 2137
     
     def value(symtab)
       internal_error "Must call type_check first" if symtab.get(enum_class.text_value).nil?
    @@ -471,6 +500,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -478,7 +603,7 @@

    diff --git a/docs/ruby/Idl/EnumerationType.html b/docs/ruby/Idl/EnumerationType.html index 8efcbd2e2..394bd0a0c 100644 --- a/docs/ruby/Idl/EnumerationType.html +++ b/docs/ruby/Idl/EnumerationType.html @@ -312,25 +312,25 @@

     
     
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
     357
     358
     359
     360
    -361
    +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372

    -
    # File 'lib/idl/type.rb', line 346
    +      
    # File 'lib/idl/type.rb', line 357
     
     def initialize(type_name, element_names, element_values)
       width = element_values.max.bit_length
    @@ -386,12 +386,12 @@ 

     
     
    -344
    -345
    -346
    +355 +356 +357

    -
    # File 'lib/idl/type.rb', line 344
    +      
    # File 'lib/idl/type.rb', line 355
     
     def element_names
       @element_names
    @@ -429,12 +429,12 @@ 

     
     
    -344
    -345
    -346
    +355 +356 +357

    -
    # File 'lib/idl/type.rb', line 344
    +      
    # File 'lib/idl/type.rb', line 355
     
     def element_values
       @element_values
    @@ -472,12 +472,12 @@ 

     
     
    -344
    -345
    -346
    +355 +356 +357

    -
    # File 'lib/idl/type.rb', line 344
    +      
    # File 'lib/idl/type.rb', line 355
     
     def width
       @width
    @@ -509,12 +509,12 @@ 

     
     
    -363
    -364
    -365
    +374 +375 +376

    -
    # File 'lib/idl/type.rb', line 363
    +      
    # File 'lib/idl/type.rb', line 374
     
     def clone
       EnumerationType.new(@name, @element_names, @element_values)
    @@ -539,15 +539,15 @@ 

     
     
    -367
    -368
    -369
    -370
    -371
    -372
    +378 +379 +380 +381 +382 +383

    -
    # File 'lib/idl/type.rb', line 367
    +      
    # File 'lib/idl/type.rb', line 378
     
     def value(element_name)
       i = @element_names.index(element_name)
    @@ -565,7 +565,7 @@ 

    diff --git a/docs/ruby/Idl/Executable.html b/docs/ruby/Idl/Executable.html index b88fc31d1..147712d99 100644 --- a/docs/ruby/Idl/Executable.html +++ b/docs/ruby/Idl/Executable.html @@ -76,7 +76,7 @@
    Included in:
    -
    AssignmentAst, CsrSoftwareWriteAst, CsrWriteAst, ForLoopAst, FunctionBodyAst, FunctionCallExpressionAst, FunctionStatementAst, GlobalAst, GlobalWithInitializationAst, IfAst, InstructionOperationAst, PostDecrementExpressionAst, PostIncrementExpressionAst, StatementAst, VariableDeclarationAst, VariableDeclarationWithInitializationAst
    +
    AssignmentAst, CsrSoftwareWriteAst, CsrWriteAst, ForLoopAst, FunctionBodyAst, FunctionCallExpressionAst, FunctionStatementAst, GlobalAst, GlobalWithInitializationAst, IfAst, IfBodyAst, InstructionOperationAst, PostDecrementExpressionAst, PostIncrementExpressionAst, StatementAst, VariableDeclarationWithInitializationAst
    @@ -211,12 +211,12 @@

     
     
    -333
    +315

    -
    # File 'lib/idl/ast.rb', line 333
    +      
    # File 'lib/idl/ast.rb', line 315
     
    -def execute(symtab) = raise NotImplementedError, "#{self.class.name} must implement update_value"
    +def execute(symtab) = raise NotImplementedError, "#{self.class.name} must implement execute"
    @@ -227,7 +227,7 @@

    diff --git a/docs/ruby/Idl/ExecutionCommentAst.html b/docs/ruby/Idl/ExecutionCommentAst.html index 9039191f5..01d4de20c 100644 --- a/docs/ruby/Idl/ExecutionCommentAst.html +++ b/docs/ruby/Idl/ExecutionCommentAst.html @@ -170,10 +170,10 @@

     
     
    -2413
    +2648

    -
    # File 'lib/idl/ast.rb', line 2413
    +      
    # File 'lib/idl/ast.rb', line 2648
     
     def type_check(_symtab, _global); end
    @@ -186,7 +186,7 @@

    diff --git a/docs/ruby/Idl/FieldAssignmentAst.html b/docs/ruby/Idl/FieldAssignmentAst.html index a69cfef96..bf573e493 100644 --- a/docs/ruby/Idl/FieldAssignmentAst.html +++ b/docs/ruby/Idl/FieldAssignmentAst.html @@ -386,14 +386,14 @@

     
     
    -1099
    -1100
    -1101
    -1102
    -1103
    +1142 +1143 +1144 +1145 +1146

    -
    # File 'lib/idl/ast.rb', line 1099
    +      
    # File 'lib/idl/ast.rb', line 1142
     
     def bf_type(symtab)
       internal_error "Not a bitfield variable" unless kind(symtab) == :bitfield
    @@ -420,12 +420,12 @@ 

     
     
    -1158
    -1159
    -1160
    +1201 +1202 +1203

    -
    # File 'lib/idl/ast.rb', line 1158
    +      
    # File 'lib/idl/ast.rb', line 1201
     
     def execute(symtab)
       value_error "TODO: Field assignement execution"
    @@ -497,13 +497,13 @@ 

     
     
    -1107
    -1108
    -1109
    -1110
    +1150 +1151 +1152 +1153

    -
    # File 'lib/idl/ast.rb', line 1107
    +      
    # File 'lib/idl/ast.rb', line 1150
     
     def field(symtab)
       internal_error "Not a CSR field type" unless kind(symtab) == :csr
    @@ -558,12 +558,12 @@ 

     
     
    -1093
    -1094
    -1095
    +1136 +1137 +1138

    -
    # File 'lib/idl/ast.rb', line 1093
    +      
    # File 'lib/idl/ast.rb', line 1136
     
     def kind(symtab)
       var.type(symtab).kind
    @@ -617,10 +617,10 @@ 

     
     
    -1163
    +1206

    -
    # File 'lib/idl/ast.rb', line 1163
    +      
    # File 'lib/idl/ast.rb', line 1206
     
     def to_idl = "#{var.to_idl}.#{field_name.to_idl} = #{rval.to_idl}"
    @@ -712,27 +712,27 @@

     
     
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173

    -
    # File 'lib/idl/ast.rb', line 1113
    +      
    # File 'lib/idl/ast.rb', line 1156
     
     def type(symtab)
       case kind(symtab)
    @@ -837,33 +837,33 @@ 

     
     
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -1150
    -1151
    -1152
    -1153
    -1154
    -1155
    -1156
    +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199

    -
    # File 'lib/idl/ast.rb', line 1133
    +      
    # File 'lib/idl/ast.rb', line 1176
     
     def type_check(symtab)
       var.type_check(symtab)
    @@ -899,7 +899,7 @@ 

    diff --git a/docs/ruby/Idl/FieldNameAst.html b/docs/ruby/Idl/FieldNameAst.html index a8bc49005..c47aba5c0 100644 --- a/docs/ruby/Idl/FieldNameAst.html +++ b/docs/ruby/Idl/FieldNameAst.html @@ -121,6 +121,30 @@

  • + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    + +
  • + + +
  • + + #type_check(_symtab, _archdef) ⇒ void @@ -158,7 +182,62 @@

    Instance Method Details

    -

    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +3074
    +
    +
    # File 'lib/idl/ast.rb', line 3074
    +
    +def to_idl = text_value
    +
    +
    + +
    +

    #type_check(_symtab, _archdef) ⇒ void @@ -237,12 +316,12 @@

     
     
    -2709
    -2710
    -2711
    +3068 +3069 +3070

  • -
    # File 'lib/idl/ast.rb', line 2709
    +      
    # File 'lib/idl/ast.rb', line 3068
     
     def type_check(_symtab, _archdef)
       # nothing to do
    @@ -257,7 +336,7 @@ 

    diff --git a/docs/ruby/Idl/ForLoopAst.html b/docs/ruby/Idl/ForLoopAst.html index d15827e19..2d776fb65 100644 --- a/docs/ruby/Idl/ForLoopAst.html +++ b/docs/ruby/Idl/ForLoopAst.html @@ -144,6 +144,52 @@

    + + + +
  • + + + #return_values(symtab) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -209,38 +255,37 @@

     
     
    -3095
    -3096
    -3097
    -3098
    -3099
    -3100
    -3101
    -3102
    -3103
    -3104
    -3105
    -3106
    -3107
    -3108
    -3109
    -3110
    -3111
    -3112
    -3113
    -3114
    -3115
    -3116
    -3117
    -3118
    -3119
    -3120
    -3121
    -3122
    -3123
    +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541

    -
    # File 'lib/idl/ast.rb', line 3095
    +      
    # File 'lib/idl/ast.rb', line 3514
     
     def return_value(symtab)
       symtab.push
    @@ -254,7 +299,6 @@ 

    v = s.s.return_value(symtab) unless v.nil? symtab.pop - puts "value = #{v}" return v end else @@ -274,6 +318,163 @@

    + + +
    +

    + + #return_values(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +3544
    +3545
    +3546
    +3547
    +3548
    +3549
    +3550
    +3551
    +3552
    +3553
    +3554
    +3555
    +3556
    +3557
    +3558
    +3559
    +3560
    +3561
    +3562
    +3563
    +3564
    +3565
    +3566
    +3567
    +3568
    +3569
    +3570
    +3571
    +3572
    +3573
    +3574
    +3575
    +
    +
    # File 'lib/idl/ast.rb', line 3544
    +
    +def return_values(symtab)
    +  # if there is a known return value, then we are done
    +  [return_value(symtab)]
    +rescue ValueError
    +  # see if we can collect a list
    +  values = []
    +  symtab.push
    +
    +  begin
    +    single_declaration_with_initialization.execute(symtab)
    +
    +    while condition.value(symtab)
    +      stmts.elements.each do |s|
    +        if s.s.is_a?(Returns)
    +          begin
    +            v = s.s.return_value(symtab)
    +            return values.push(v).uniq unless v.nil?
    +          rescue ValueError
    +            values += s.s.return_values(symtab)
    +          end
    +        else
    +          s.s.execute(symtab)
    +        end
    +      end
    +      action.execute(symtab)
    +    end
    +  ensure
    +    symtab.pop
    +  end
    +
    +  values.uniq
    +end
    +
    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +3581
    +3582
    +3583
    +3584
    +3585
    +3586
    +3587
    +3588
    +
    +
    # File 'lib/idl/ast.rb', line 3581
    +
    +def to_idl
    +  idl = "for (#{single_declaration_with_initialization.to_idl}; #{condition.to_idl}; #{action.to_idl}) {"
    +  stmts.elements.each do |s|
    +    idl << s.s.to_idl
    +  end
    +  idl << "}"
    +  idl
    +end
    +
    @@ -356,20 +557,20 @@

     
     
    -3083
    -3084
    -3085
    -3086
    -3087
    -3088
    -3089
    -3090
    -3091
    -3092
    -3093
    +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511

    -
    # File 'lib/idl/ast.rb', line 3083
    +      
    # File 'lib/idl/ast.rb', line 3501
     
     def type_check(symtab)
       symtab.push
    @@ -392,7 +593,7 @@ 

    diff --git a/docs/ruby/Idl/FunctionBodyAst.html b/docs/ruby/Idl/FunctionBodyAst.html index cd92a5b18..87b39c408 100644 --- a/docs/ruby/Idl/FunctionBodyAst.html +++ b/docs/ruby/Idl/FunctionBodyAst.html @@ -104,7 +104,7 @@
    Defined in:
    lib/idl/ast.rb,
    - lib/idl/passes/find_return_values.rb
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    @@ -128,6 +128,54 @@

  • + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #initialize(stmts) ⇒ FunctionBodyAst + + + + + + + constructor + + + + + + + + +
    +

    A new instance of FunctionBodyAst.

    +
    + +
  • + + +
  • + + #pass_find_return_values(symtab) ⇒ Array<Ast, Array<Ast>> @@ -146,6 +194,28 @@

    List of possible return values, along with the condition it occurs under.

    +

  • + + +
  • + + + #prune(symtab) ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -176,7 +246,7 @@

  • - #return_values(symtab) ⇒ Array + #return_values(symtab) ⇒ Object @@ -190,9 +260,7 @@

    -
    -

    An array of all possible return values.

    -
    +

  • @@ -278,14 +346,91 @@

    +
    +

    Constructor Details

    + +
    +

    + + #initialize(stmts) ⇒ FunctionBodyAst + + + + + +

    +
    + +

    Returns a new instance of FunctionBodyAst.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +3116
    +3117
    +3118
    +3119
    +
    +
    # File 'lib/idl/ast.rb', line 3116
    +
    +def initialize(stmts)
    +  super(stmts[0].input, stmts[0].interval.first..stmts.last.interval.end, stmts)
    +  @stmts = stmts
    +end
    +
    +
    +
    +

    Instance Method Details

    -

    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +92
    +93
    +94
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 92
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  statements.map{ |s| "#{' ' * indent}#{s.gen_adoc(indent, indent_spaces:)}" }.join("\n")
    +end
    +
    +
    + +
    +

    #pass_find_return_values(symtab) ⇒ Array<Ast, Array<Ast>> @@ -351,6 +496,96 @@

    +

    + +
    +

    + + #prune(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +
    +
    # File 'lib/idl/passes/prune.rb', line 40
    +
    +def prune(symtab)
    +  symtab.push
    +  begin
    +    func_def = find_ancestor(FunctionDefAst)
    +    unless func_def.nil?
    +      # push template values
    +      func_def.template_names.each_with_index do |tname, idx|
    +        symtab.add(tname, Var.new(tname, func_def.template_types(symtab)[idx]))
    +      end
    +
    +      # push args
    +      func_def.arguments(symtab).each do |arg_type, arg_name|
    +        symtab.add(arg_name, Var.new(arg_name, arg_type))
    +      end
    +    end
    +
    +    # go through the statements, and stop if we find one that retuns
    +    statements.each_with_index do |s, idx|
    +      if s.is_a?(Returns)
    +        v = s.return_value(symtab)
    +        return FunctionBodyAst.new(statements[0..idx].map { |s| s.prune(symtab) }) unless v.nil?
    +      else
    +        s.execute(symtab)
    +      end
    +    end
    +
    +    FunctionBodyAst.new(statements.map { |s| s.prune(symtab) })
    +  rescue ValueError
    +    FunctionBodyAst.new(statements.map { |s| s.prune(symtab) })
    +  ensure
    +    symtab.pop
    +  end
    +end
    +
    @@ -389,26 +624,30 @@

     
     
    -2773
    -2774
    -2775
    -2776
    -2777
    -2778
    -2779
    -2780
    -2781
    -2782
    -2783
    -2784
    -2785
    +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166

    -
    # File 'lib/idl/ast.rb', line 2773
    +      
    # File 'lib/idl/ast.rb', line 3152
     
     def return_value(symtab)
    +  internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2
    +
       # go through the statements, and return the first one that has a return value
    -  statements.each do |s|
    +  @stmts.each do |s|
         if s.is_a?(Returns)
           v = s.return_value(symtab)
           return v unless v.nil?
    @@ -417,7 +656,7 @@ 

    end end - internal_error "No function body statement returned a value" + value_error "No function body statement returned a value" end

    @@ -427,84 +666,73 @@

    - #return_values(symtab) ⇒ Array + #return_values(symtab) ⇒ Object -

    -
    - -
    - Note: -
    -

    arguments and template arguments must be put on the symtab before calling

    -
    -
    - - -

    Returns An array of all possible return values.

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Array) - - - - — -
      -

      An array of all possible return values

      -
      - -
    • - -
    - -
    +
    @@ -526,15 +754,15 @@

     
     
    -2744
    -2745
    -2746
    +3121 +3122 +3123

    @@ -556,22 +784,22 @@

     
     
    -2805
    -2806
    -2807
    -2808
    -2809
    -2810
    -2811
    -2812
    +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204

    @@ -464,12 +519,12 @@

     
     
    -2678
    -2679
    -2680
    +3029 +3030 +3031

     
     
    -2791
    -2792
    -2793
    -2794
    -2795
    -2796
    -2797
    -2798
    -2799
    -2800
    -2801
    -2802
    -2803
    +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195
    -
    # File 'lib/idl/ast.rb', line 2791
    +      
    # File 'lib/idl/ast.rb', line 3170
     
     def return_values(symtab)
    -  # go through the statements, and find all return values
    -  rts = []
    -  statements.each do |s|
    -    if s.is_a?(Returns)
    -      rts += s.return_values(symtab)
    -    else
    -      s.execute(symtab)
    +  internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2
    +
    +  values = []
    +  begin
    +    # if there is a definate return value, then just return that
    +    return [return_value(symtab)]
    +  rescue ValueError
    +    # go through the statements, and collect return values
    +    # we can stop if we encounter a statement with a known return value
    +    @stmts.each do |s|
    +      if s.is_a?(Returns)
    +        begin
    +          v = s.return_value(symtab)
    +          return values.push(v).uniq unless v.nil?
    +        rescue ValueError
    +          values += s.return_values(symtab)
    +        end
    +      else
    +        s.execute(symtab)
    +      end
         end
       end
     
    -  rts
    +  values.uniq
     end
    -
    # File 'lib/idl/ast.rb', line 2744
    +      
    # File 'lib/idl/ast.rb', line 3121
     
     def statements
    -  func_stmt_list.elements.map(&:choice)
    +  @stmts
     end
    -
    # File 'lib/idl/ast.rb', line 2805
    +      
    # File 'lib/idl/ast.rb', line 3197
     
     def to_idl
       result = ""
       # go through the statements, and return the first one that has a return value
    -  statements.each do |s|
    +  @stmts.each do |s|
         result << s.to_idl
       end
       result
    @@ -661,42 +889,46 @@ 

     
     
    -2749
    -2750
    -2751
    -2752
    -2753
    -2754
    -2755
    -2756
    -2757
    -2758
    -2759
    -2760
    -2761
    -2762
    -2763
    -2764
    -2765
    -2766
    -2767
    -2768
    +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147

    -
    # File 'lib/idl/ast.rb', line 2749
    +      
    # File 'lib/idl/ast.rb', line 3126
     
     def type_check(symtab)
    +  internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2
    +
       return_value_might_be_known = true
     
    -  statements.each do |s|
    +  @stmts.each do |s|
         s.type_check(symtab)
    -    next if return_value_might_be_known
    +    next unless return_value_might_be_known
     
         begin
           if s.is_a?(Returns)
             s.return_value(symtab)
             # if we reach here, the return value is known, so we don't have to go futher
    -        return
    +        break
           else
             s.execute(symtab)
           end
    @@ -715,7 +947,7 @@ 

    diff --git a/docs/ruby/Idl/FunctionCallExpressionAst.html b/docs/ruby/Idl/FunctionCallExpressionAst.html index 090f0908c..8874ba4e1 100644 --- a/docs/ruby/Idl/FunctionCallExpressionAst.html +++ b/docs/ruby/Idl/FunctionCallExpressionAst.html @@ -260,6 +260,30 @@

    + + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -334,6 +358,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -400,14 +453,14 @@

     
     
    -2573
    -2574
    -2575
    -2576
    -2577
    +2938 +2939 +2940 +2941 +2942

    -
    # File 'lib/idl/ast.rb', line 2573
    +      
    # File 'lib/idl/ast.rb', line 2938
     
     def arg_nodes
       nodes = []
    @@ -434,15 +487,17 @@ 

     
     
    -47
    -48
    -49
    +85 +86 +87 +88

    -
    # File 'lib/idl/passes/gen_adoc.rb', line 47
    +      
    # File 'lib/idl/passes/gen_adoc.rb', line 85
     
     def gen_adoc(indent = 0, indent_spaces: 2)
    -  "xref:funcs:funcs.adoc##{name}-func-def[#{name}]" << t.gen_adoc << "(#{function_arg_list.gen_adoc})"
    +  after_name = "#{t.gen_adoc}(#{function_arg_list.gen_adoc})"
    +  "%%LINK%func;#{name};#{name}%%#{after_name}"
     end
    -
    # File 'lib/idl/ast.rb', line 2678
    +      
    # File 'lib/idl/ast.rb', line 3029
     
     def name
       function_name.text_value
    @@ -523,12 +578,12 @@ 

     
     
    -2555
    -2556
    -2557
    +2920 +2921 +2922

    -
    # File 'lib/idl/ast.rb', line 2555
    +      
    # File 'lib/idl/ast.rb', line 2920
     
     def template?
       !t.empty?
    @@ -582,14 +637,14 @@ 

     
     
    -2560
    -2561
    -2562
    -2563
    -2564
    +2925 +2926 +2927 +2928 +2929

    -
    # File 'lib/idl/ast.rb', line 2560
    +      
    # File 'lib/idl/ast.rb', line 2925
     
     def template_arg_nodes
       return [] unless template?
    @@ -616,14 +671,14 @@ 

     
     
    -2566
    -2567
    -2568
    -2569
    -2570
    +2931 +2932 +2933 +2934 +2935

    -
    # File 'lib/idl/ast.rb', line 2566
    +      
    # File 'lib/idl/ast.rb', line 2931
     
     def template_values(symtab)
       return [] unless template?
    @@ -633,6 +688,73 @@ 

    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +3034
    +3035
    +3036
    +3037
    +3038
    +3039
    +3040
    +
    +
    # File 'lib/idl/ast.rb', line 3034
    +
    +def to_idl
    +  if template?
    +    "#{name}<#{template_arg_nodes.map(&:to_idl).join(',')}>(#{arg_nodes.map(&:to_idl).join(',')})"
    +  else
    +    "#{name}(#{arg_nodes.map(&:to_idl).join(',')})"
    +  end
    +end
    +
    @@ -719,17 +841,17 @@

     
     
    -2633
    -2634
    -2635
    -2636
    +2998 +2999 +3000 +3001

    -
    # File 'lib/idl/ast.rb', line 2633
    +      
    # File 'lib/idl/ast.rb', line 2998
     
     def type(symtab)
       func_def_type = symtab.get(name)
    -  func_def_type.return_type(template_values(symtab), arg_nodes, symtab)
    +  func_def_type.return_type(template_values(symtab))
     end
    @@ -816,60 +938,60 @@

     
     
    -2580
    -2581
    -2582
    -2583
    -2584
    -2585
    -2586
    -2587
    -2588
    -2589
    -2590
    -2591
    -2592
    -2593
    -2594
    -2595
    -2596
    -2597
    -2598
    -2599
    -2600
    -2601
    -2602
    -2603
    -2604
    -2605
    -2606
    -2607
    -2608
    -2609
    -2610
    -2611
    -2612
    -2613
    -2614
    -2615
    -2616
    -2617
    -2618
    -2619
    -2620
    -2621
    -2622
    -2623
    -2624
    -2625
    -2626
    -2627
    -2628
    -2629
    -2630
    +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995

    -
    # File 'lib/idl/ast.rb', line 2580
    +      
    # File 'lib/idl/ast.rb', line 2945
     
     def type_check(symtab)
       level = symtab.levels
    @@ -893,7 +1015,7 @@ 

    template_arg_nodes.each_with_index do |t, idx| t.type_check(symtab) - unless t.type(symtab).convertable_to?(func_def_type.template_types[idx]) + unless t.type(symtab).convertable_to?(func_def_type.template_types(symtab)[idx]) type_error "Template argument #{idx + 1} has wrong type" end end @@ -916,7 +1038,7 @@

    end end - if func_def_type.return_type(template_values(symtab), arg_nodes, symtab).nil? + if func_def_type.return_type(template_values(symtab)).nil? internal_error "No type determined for function" end @@ -957,87 +1079,155 @@

     
     
    -2639
    -2640
    -2641
    -2642
    -2643
    -2644
    -2645
    -2646
    -2647
    -2648
    -2649
    -2650
    -2651
    -2652
    -2653
    -2654
    -2655
    -2656
    -2657
    -2658
    -2659
    -2660
    -2661
    -2662
    -2663
    -2664
    -2665
    -2666
    -2667
    -2668
    -2669
    -2670
    -2671
    -2672
    -2673
    -2674
    -2675
    +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026

    -
    # File 'lib/idl/ast.rb', line 2639
    +      
    # File 'lib/idl/ast.rb', line 3004
     
     def value(symtab)
       func_def_type = symtab.get(name)
    +  type_error "not a function" unless func_def_type.is_a?(FunctionType)
       if func_def_type.builtin?
         if name == "implemented?"
    -      extname = arg_nodes[0].text_value
    -      return symtab.archdef.ext?(extname)
    +      extname_ref = arg_nodes[0]
    +      type_error "First argument should be a ExtensionName" unless extname_ref.type(symtab).kind == :enum_ref && extname_ref.type(symtab).enum_class.name == "ExtensionName"
    +
    +      return symtab.archdef.ext?(arg_nodes[0].text_value.split(":").last)
         else
           value_error "value of builtin function cannot be known"
         end
       end
     
    -  symtab.push
    -
    -  begin
    -    template_arg_nodes.each_with_index do |targ, idx|
    -      targ_name = func_def_type.template_names[idx]
    -      targ_type = func_def_type.template_types[idx]
    -      symtab.add(targ_name, Var.new(targ_name, targ_type, targ.value(symtab)))
    -    end
    -
    -    arg_nodes.each_with_index do |arg, idx|
    -      arg_name = func_def_type.argument_name(idx, template_values(symtab))
    -      arg_type = func_def_type.argument_type(idx, template_values(symtab), arg_nodes, symtab)
    -      begin
    -        symtab.add!(arg_name, Var.new(arg_name, arg_type, arg.value(symtab)))
    -      rescue SymbolTable::DuplicateSymError
    -        type_error "Argument '#{arg_name}' shadows another symbol (level = #{symtab.levels})"
    -      end
    -    end
    -
    -    v = func_def_type.body.return_value(symtab)
    -  ensure
    -    symtab.pop
    +  template_values = []
    +  template_arg_nodes.each_with_index do |targ, idx|
    +    # targ_name = func_def_type.template_names[idx]
    +    # targ_type = func_def_type.template_types[idx]
    +    template_values << targ.value(symtab)
       end
     
    -  v
    +  func_def_type.return_value(template_values, arg_nodes, symtab)
     end
    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -1045,7 +1235,7 @@

    diff --git a/docs/ruby/Idl/FunctionDefAst.html b/docs/ruby/Idl/FunctionDefAst.html index 9997bc6aa..98c968814 100644 --- a/docs/ruby/Idl/FunctionDefAst.html +++ b/docs/ruby/Idl/FunctionDefAst.html @@ -107,42 +107,21 @@ -

    Instance Attribute Summary collapse

    -
    -
    # File 'lib/idl/ast.rb', line 2831
    +      
    # File 'lib/idl/ast.rb', line 3223
     
     def arguments(symtab)
       if templated?
    @@ -826,19 +795,19 @@ 

     
     
    -2858
    -2859
    -2860
    -2861
    -2862
    -2863
    -2864
    -2865
    -2866
    -2867
    +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259

    -
    # File 'lib/idl/ast.rb', line 2858
    +      
    # File 'lib/idl/ast.rb', line 3250
     
     def arguments_list_str
       list = []
    @@ -870,14 +839,14 @@ 

     
     
    -3056
    -3057
    -3058
    -3059
    -3060
    +3474 +3475 +3476 +3477 +3478

    -
    # File 'lib/idl/ast.rb', line 3056
    +      
    # File 'lib/idl/ast.rb', line 3474
     
     def body
       internal_error "Function has no body" if builtin?
    @@ -939,12 +908,12 @@ 

     
     
    -3072
    -3073
    -3074
    +3490 +3491 +3492

    -
    # File 'lib/idl/ast.rb', line 3072
    +      
    # File 'lib/idl/ast.rb', line 3490
     
     def builtin?
       !respond_to?(:body_block)
    @@ -969,12 +938,12 @@ 

     
     
    -2816
    -2817
    -2818
    +3208 +3209 +3210

    -
    # File 'lib/idl/ast.rb', line 2816
    +      
    # File 'lib/idl/ast.rb', line 3208
     
     def description
       unindent(desc.text_value)
    @@ -999,12 +968,12 @@ 

     
     
    -2927
    -2928
    -2929
    +3310 +3311 +3312

    -
    # File 'lib/idl/ast.rb', line 2927
    +      
    # File 'lib/idl/ast.rb', line 3310
     
     def name
       function_name.text_value
    @@ -1029,14 +998,14 @@ 

     
     
    -2824
    -2825
    -2826
    -2827
    -2828
    +3216 +3217 +3218 +3219 +3220

    -
    # File 'lib/idl/ast.rb', line 2824
    +      
    # File 'lib/idl/ast.rb', line 3216
     
     def num_args
       return 0 if args.empty?
    @@ -1074,39 +1043,47 @@ 

     
     
    -2883
    -2884
    -2885
    -2886
    -2887
    -2888
    -2889
    -2890
    -2891
    -2892
    -2893
    -2894
    -2895
    -2896
    -2897
    -2898
    -2899
    -2900
    -2901
    -2902
    -2903
    -2904
    -2905
    -2906
    -2907
    -2908
    -2909
    -2910
    +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293

    -
    # File 'lib/idl/ast.rb', line 2883
    +      
    # File 'lib/idl/ast.rb', line 3262
     
     def return_type(symtab)
    +  unless symtab.levels == 2
    +    internal_error "Function bodies should be at global + 1 scope (at global + #{symtab.levels - 1})"
    +  end
    +
       if templated?
         template_names.each do |tname|
           internal_error "Template values missing" unless symtab.get(tname)
    @@ -1165,21 +1142,21 @@ 

     
     
    -2914
    -2915
    -2916
    -2917
    -2918
    -2919
    -2920
    -2921
    -2922
    -2923
    -2924
    -2925
    +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308

    -
    # File 'lib/idl/ast.rb', line 2914
    +      
    # File 'lib/idl/ast.rb', line 3297
     
     def return_type_list_str
       list = []
    @@ -1199,9 +1176,9 @@ 

    -

    +

    - #return_types(symtab) ⇒ Object + #template_namesArray<String> @@ -1210,13 +1187,31 @@

    -

    return an array of all the return types, in order function (or template instance) must be resolved

    +

    Returns Template arugment names, in order.

    +

    Returns:

    +
      + +
    • + + + (Array<String>) + + + + — +
      +

      Template arugment names, in order

      +
      + +
    • + +
    @@ -1224,29 +1219,128 @@

     
     
    -2871
    -2872
    -2873
    -2874
    -2875
    -2876
    -2877
    -2878
    -2879
    -2880
    +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376

    + +
    -
    # File 'lib/idl/ast.rb', line 2871
    -
    -def return_types(symtab)
    -  t = return_type(symtab)
    -  if t.kind == :tuple
    -    t.tuple_types
    -  elsif t.kind == :void
    -    []
    -  else
    -    [t]
    +      
    # File 'lib/idl/ast.rb', line 3368
    +
    +def template_names
    +  return [] unless templated?
    +
    +  tnames = [targs.first.id.text_value]
    +  targs.rest.elements.each do |a|
    +    tnames << a.function_argument_definition.id.text_value
       end
    +  tnames
    +end
    +
    +
    + +
    +

    + + #template_types(symtab) ⇒ Array<Type> + + + + + +

    +
    + +

    Returns Template argument types, in order.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for evaluation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Type>) + + + + — +
      +

      Template argument types, in order

      +
      + +
    • + +
    + +
    + + + @@ -1290,12 +1384,12 @@

     
     
    -2820
    -2821
    -2822
    +3212 +3213 +3214

    @@ -1439,32 +1519,32 @@

     
     
    -3021
    -3022
    -3023
    -3024
    -3025
    -3026
    -3027
    -3028
    -3029
    -3030
    -3031
    -3032
    -3033
    -3034
    -3035
    -3036
    -3037
    -3038
    -3039
    -3040
    -3041
    -3042
    -3043
    +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461

    @@ -776,10 +808,10 @@

     
     
    -433
    +444

    @@ -802,12 +834,12 @@

     
     
    -429
    -430
    -431
    +440 +441 +442

    @@ -846,7 +878,7 @@

    - #return_type(template_values, argument_nodes, call_site_symtab) ⇒ Object + #return_type(template_values) ⇒ Object @@ -880,22 +912,6 @@

    -
  • - - argument_nodes - - - (Array<Ast::Node>) - - - - — -
    -

    Arguments at the call site

    -
    - -
  • -
  • call_site_symtab @@ -921,20 +937,20 @@

     
     
    -488
    -489
    -490
    -491
    -492
    -493
    +508 +509 +510 +511 +512 +513

  • @@ -1006,15 +1022,15 @@

     
     
    -497
    -498
    -499
    -500
    -501
    -502
    +524 +525 +526 +527 +528 +529

    +
    +
    +
    +3380
    +3381
    +3382
    +3383
    +3384
    +3385
    +3386
    +3387
    +3388
    +3389
    +3390
    +3391
    +3392
    +3393
    +
    +
    # File 'lib/idl/ast.rb', line 3380
    +
    +def template_types(symtab)
    +  return [] unless templated?
    +
    +  ttype = targs.first.type_name.type(symtab)
    +  ttype = Type.new(:enum_ref, enum_class: ttype) if ttype.kind == :enum
    +
    +  ttypes = [ttype.clone]
    +  targs.rest.elements.each do |a|
    +    ttype = a.function_argument_definition.type_name.type(symtab)
    +    ttype = Type.new(:enum_ref, enum_class: ttype) if ttype.kind == :enum
    +    ttypes << ttype
    +  end
    +  ttypes
     end
    -
    # File 'lib/idl/ast.rb', line 2820
    +      
    # File 'lib/idl/ast.rb', line 3212
     
     def templated?
       !targs.empty?
    @@ -1385,39 +1479,25 @@ 

     
     
    -2959
    -2960
    -2961
    -2962
    -2963
    -2964
    -2965
    -2966
    -2967
    -2968
    -2969
    -2970
    -2971
    -2972
    -2973
    +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353

    -
    # File 'lib/idl/ast.rb', line 2959
    +      
    # File 'lib/idl/ast.rb', line 3346
     
     def type_check(symtab)
       internal_error "Functions must be declared at global scope (at #{symtab.levels})" unless symtab.levels == 1
     
       type_check_targs(symtab)
     
    -  # now add the function in global scope
    -  def_type = FunctionType.new(
    -      name,
    -      self,
    -      symtab.deep_clone
    -    )
    -
       # recursion isn't supported (doesn't map well to hardware), so we can add the function after type checking the body
    -  symtab.add!(name, def_type)
    +  add_symbol(symtab)
     end
    -
    # File 'lib/idl/ast.rb', line 3021
    +      
    # File 'lib/idl/ast.rb', line 3439
     
     def type_check_args(symtab)
       @arguments = []
    @@ -1509,19 +1589,19 @@ 

     
     
    -3045
    -3046
    -3047
    -3048
    -3049
    -3050
    -3051
    -3052
    -3053
    -3054
    +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472

    -
    # File 'lib/idl/ast.rb', line 3045
    +      
    # File 'lib/idl/ast.rb', line 3463
     
     def type_check_body(symtab)
     
    @@ -1564,21 +1644,25 @@ 

     
     
    -2947
    -2948
    -2949
    -2950
    -2951
    -2952
    -2953
    -2954
    -2955
    -2956
    +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343

    -
    # File 'lib/idl/ast.rb', line 2947
    +      
    # File 'lib/idl/ast.rb', line 3332
     
     def type_check_from_call(symtab)
    +  internal_error "Function definitions should be at global + 1 scope" unless symtab.levels == 2
    +
       global_scope = symtab.deep_clone
       global_scope.pop while global_scope.levels != 1
     
    @@ -1608,25 +1692,25 @@ 

     
     
    -3004
    -3005
    -3006
    -3007
    -3008
    -3009
    -3010
    -3011
    -3012
    -3013
    -3014
    -3015
    -3016
    -3017
    -3018
    -3019
    +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437

    -
    # File 'lib/idl/ast.rb', line 3004
    +      
    # File 'lib/idl/ast.rb', line 3422
     
     def type_check_return(symtab)
       return if ret.empty?
    @@ -1664,35 +1748,35 @@ 

     
     
    -2977
    -2978
    -2979
    -2980
    -2981
    -2982
    -2983
    -2984
    -2985
    -2986
    -2987
    -2988
    -2989
    -2990
    -2991
    -2992
    -2993
    -2994
    -2995
    -2996
    -2997
    -2998
    -2999
    -3000
    -3001
    -3002
    +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420

    -
    # File 'lib/idl/ast.rb', line 2977
    +      
    # File 'lib/idl/ast.rb', line 3395
     
     def type_check_targs(symtab)
       @template_names = []
    @@ -1769,22 +1853,26 @@ 

     
     
    -2932
    -2933
    -2934
    -2935
    -2936
    -2937
    -2938
    -2939
    -2940
    -2941
    -2942
    +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327

    -
    # File 'lib/idl/ast.rb', line 2932
    +      
    # File 'lib/idl/ast.rb', line 3315
     
     def type_check_template_instance(symtab)
    +  internal_error "Function definitions should be at global + 1 scope" unless symtab.levels == 2
    +
       internal_error "Not a template function" unless templated?
     
       template_names.each do |tname|
    @@ -1805,7 +1893,7 @@ 

    diff --git a/docs/ruby/Idl/FunctionStatementAst.html b/docs/ruby/Idl/FunctionStatementAst.html index 75f8eb99f..1be382533 100644 --- a/docs/ruby/Idl/FunctionStatementAst.html +++ b/docs/ruby/Idl/FunctionStatementAst.html @@ -460,12 +460,12 @@

     
     
    -2718
    -2719
    -2720
    +3081 +3082 +3083

    -
    # File 'lib/idl/ast.rb', line 2718
    +      
    # File 'lib/idl/ast.rb', line 3081
     
     def execute(symtab)
       raise "WHere is this AST?"
    @@ -1027,7 +1027,7 @@ 

    diff --git a/docs/ruby/Idl/FunctionType.html b/docs/ruby/Idl/FunctionType.html index ca1eb7dd3..41747fc80 100644 --- a/docs/ruby/Idl/FunctionType.html +++ b/docs/ruby/Idl/FunctionType.html @@ -323,7 +323,7 @@

  • - #return_type(template_values, argument_nodes, call_site_symtab) ⇒ Object + #return_type(template_values) ⇒ Object @@ -365,6 +365,28 @@

    Return types.

    +

  • + + +
  • + + + #return_value(template_values, argument_nodes, call_site_symtab) ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -393,7 +415,7 @@

  • - #template_types ⇒ Object + #template_types(symtab) ⇒ Object @@ -490,21 +512,21 @@

     
     
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    +432 +433 +434 +435 +436 +437 +438

  • -
    # File 'lib/idl/type.rb', line 421
    +      
    # File 'lib/idl/type.rb', line 432
     
     def initialize(func_name, func_def_ast, symtab)
       super(:function, name: func_name)
       @func_def_ast = func_def_ast
    -  @symtab = symtab.deep_clone
    +  @symtab = symtab
     
       raise "symtab should be at level 1" unless symtab.levels == 1
     end
    @@ -546,20 +568,20 @@

     
     
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503

    -
    # File 'lib/idl/type.rb', line 472
    +      
    # File 'lib/idl/type.rb', line 493
     
     def apply_arguments(symtab, argument_nodes, call_site_symtab)
       idx = 0
    @@ -592,23 +614,28 @@ 

     
     
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489

    -
    # File 'lib/idl/type.rb', line 455
    +      
    # File 'lib/idl/type.rb', line 471
     
     def apply_template_values(template_values = [])
       raise "Missing template values" if templated? && template_values.empty?
    @@ -616,11 +643,16 @@ 

    raise "wrong number of template values" unless template_names.size == template_values.size symtab = @symtab.deep_clone + symtab.pop while symtab.levels != 1 + + raise "Symbol table should be at global scope" unless symtab.levels == 1 symtab.push template_values.each_with_index do |value, idx| - symtab.add!(template_names[idx], Var.new(template_names[idx], template_types[idx], value)) + raise "template value should be an Integer" unless value.is_a?(Integer) + + symtab.add!(template_names[idx], Var.new(template_names[idx], template_types(symtab)[idx], value, template_index: idx, function_name: @func_def_ast.name)) end symtab end

    @@ -644,18 +676,18 @@

     
     
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    +541 +542 +543 +544 +545 +546 +547 +548 +549

    -
    # File 'lib/idl/type.rb', line 514
    +      
    # File 'lib/idl/type.rb', line 541
     
     def argument_name(index, template_values = [])
       return nil if index >= @func_def_ast.num_args
    @@ -686,18 +718,18 @@ 

     
     
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    +531 +532 +533 +534 +535 +536 +537 +538 +539

    -
    # File 'lib/idl/type.rb', line 504
    +      
    # File 'lib/idl/type.rb', line 531
     
     def argument_type(index, template_values, argument_nodes, call_site_symtab)
       return nil if index >= @func_def_ast.num_args
    @@ -728,10 +760,10 @@ 

     
     
    -524
    +551

    -
    # File 'lib/idl/type.rb', line 524
    +      
    # File 'lib/idl/type.rb', line 551
     
     def body = @func_def_ast.body
    -
    # File 'lib/idl/type.rb', line 433
    +      
    # File 'lib/idl/type.rb', line 444
     
     def builtin? = @func_def_ast.builtin?
    -
    # File 'lib/idl/type.rb', line 429
    +      
    # File 'lib/idl/type.rb', line 440
     
     def clone
       FunctionType.new(name, @func_def_ast, @symtab)
    @@ -832,10 +864,10 @@ 

     
     
    -435
    +446

    -
    # File 'lib/idl/type.rb', line 435
    +      
    # File 'lib/idl/type.rb', line 446
     
     def num_args = @func_def_ast.num_args
    -
    # File 'lib/idl/type.rb', line 488
    +      
    # File 'lib/idl/type.rb', line 508
     
    -def return_type(template_values, argument_nodes, call_site_symtab)
    +def return_type(template_values)
       symtab = apply_template_values(template_values)
    -  apply_arguments(symtab, argument_nodes, call_site_symtab)
    -
    +  # apply_arguments(symtab, argument_nodes, call_site_symtab)
    +
       @func_def_ast.return_type(symtab).clone
     end
    -
    # File 'lib/idl/type.rb', line 497
    +      
    # File 'lib/idl/type.rb', line 524
     
     def return_types(template_values, argument_nodes, call_site_symtab)
       symtab = apply_template_values(template_values)
    @@ -1025,6 +1041,42 @@ 

    +
    + +
    +

    + + #return_value(template_values, argument_nodes, call_site_symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +515
    +516
    +517
    +518
    +519
    +520
    +
    +
    # File 'lib/idl/type.rb', line 515
    +
    +def return_value(template_values, argument_nodes, call_site_symtab)
    +  symtab = apply_template_values(template_values)
    +  apply_arguments(symtab, argument_nodes, call_site_symtab)
    +
    +  @func_def_ast.body.return_value(symtab)
    +end
    +
    @@ -1042,10 +1094,10 @@

     
     
    -449
    +465

    -
    # File 'lib/idl/type.rb', line 449
    +      
    # File 'lib/idl/type.rb', line 465
     
     def template_names = @func_def_ast.template_names
    @@ -1056,7 +1108,7 @@

    - #template_typesObject + #template_types(symtab) ⇒ Object @@ -1068,12 +1120,12 @@

     
     
    -451
    +467

    -
    # File 'lib/idl/type.rb', line 451
    +      
    # File 'lib/idl/type.rb', line 467
     
    -def template_types = @func_def_ast.template_types
    +def template_types(symtab) = @func_def_ast.template_types(symtab)
    @@ -1116,10 +1168,10 @@

     
     
    -453
    +469

    -
    # File 'lib/idl/type.rb', line 453
    +      
    # File 'lib/idl/type.rb', line 469
     
     def templated? = @func_def_ast.templated?
    @@ -1142,30 +1194,40 @@

     
     
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463

    -
    # File 'lib/idl/type.rb', line 437
    +      
    # File 'lib/idl/type.rb', line 448
     
     def type_check_call(template_values = [])
    -  raise "Missing template values" if templated? and template_values.empty?
    +  raise "Missing template values" if templated? && template_values.empty?
     
       if templated?
         symtab = apply_template_values(template_values)
     
         @func_def_ast.type_check_template_instance(symtab)
       else
    -    @func_def_ast.type_check_from_call(@symtab)
    +    symtab = @symtab.deep_clone
    +    symtab.pop while symtab.levels != 1
    +
    +    symtab.push # to keep things consistent with template functions, push a scope
    +
    +    @func_def_ast.type_check_from_call(symtab)
       end
     end
    @@ -1178,7 +1240,7 @@

    diff --git a/docs/ruby/Idl/GlobalAst.html b/docs/ruby/Idl/GlobalAst.html index 232835243..2878cdf8f 100644 --- a/docs/ruby/Idl/GlobalAst.html +++ b/docs/ruby/Idl/GlobalAst.html @@ -294,12 +294,12 @@

     
     
    -469
    -470
    -471
    +488 +489 +490

    -
    # File 'lib/idl/ast.rb', line 469
    +      
    # File 'lib/idl/ast.rb', line 488
     
     def type(symtab)
       declaration.type
    @@ -324,12 +324,12 @@ 

     
     
    -465
    -466
    -467
    +484 +485 +486

    -
    # File 'lib/idl/ast.rb', line 465
    +      
    # File 'lib/idl/ast.rb', line 484
     
     def type_check(symtab)
       declaration.type_check(symtab)
    @@ -344,7 +344,7 @@ 

    diff --git a/docs/ruby/Idl/GlobalWithInitializationAst.html b/docs/ruby/Idl/GlobalWithInitializationAst.html index fc2e7265f..775cd7d27 100644 --- a/docs/ruby/Idl/GlobalWithInitializationAst.html +++ b/docs/ruby/Idl/GlobalWithInitializationAst.html @@ -358,12 +358,12 @@

     
     
    -457
    -458
    -459
    +476 +477 +478

    -
    # File 'lib/idl/ast.rb', line 457
    +      
    # File 'lib/idl/ast.rb', line 476
     
     def to_idl
       "TODO"
    @@ -388,12 +388,12 @@ 

     
     
    -449
    -450
    -451
    +468 +469 +470

    -
    # File 'lib/idl/ast.rb', line 449
    +      
    # File 'lib/idl/ast.rb', line 468
     
     def type(symtab)
       single_declartion_with_initialization.type(symtab)
    @@ -418,16 +418,14 @@ 

     
     
    -444
    -445
    -446
    -447
    +464 +465 +466

    -
    # File 'lib/idl/ast.rb', line 444
    +      
    # File 'lib/idl/ast.rb', line 464
     
     def type_check(symtab)
    -  puts "global #{text_value}"
       single_declaration_with_initialization.type_check(symtab)
     end
    @@ -450,12 +448,12 @@

     
     
    -453
    -454
    -455
    +472 +473 +474

    -
    # File 'lib/idl/ast.rb', line 453
    +      
    # File 'lib/idl/ast.rb', line 472
     
     def value(symtab)
       single_declartion_with_initialization.value(symtab)
    @@ -470,7 +468,7 @@ 

    diff --git a/docs/ruby/Idl/IdAst.html b/docs/ruby/Idl/IdAst.html index 90bf95bb5..a6aa0c8de 100644 --- a/docs/ruby/Idl/IdAst.html +++ b/docs/ruby/Idl/IdAst.html @@ -249,6 +249,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -313,10 +342,10 @@

     
     
    -408
    +428

    -
    # File 'lib/idl/ast.rb', line 408
    +      
    # File 'lib/idl/ast.rb', line 428
     
     def name = text_value
    @@ -368,10 +397,10 @@

     
     
    -429
    +449

    -
    # File 'lib/idl/ast.rb', line 429
    +      
    # File 'lib/idl/ast.rb', line 449
     
     def to_idl = text_value
    @@ -394,14 +423,14 @@

     
     
    -411
    -412
    -413
    -414
    -415
    +431 +432 +433 +434 +435

    -
    # File 'lib/idl/ast.rb', line 411
    +      
    # File 'lib/idl/ast.rb', line 431
     
     def type(symtab)
       internal_error "Symbol not found (should have called type_check)" if symtab.get(text_value).nil?
    @@ -493,12 +522,12 @@ 

     
     
    -403
    -404
    -405
    +423 +424 +425

    -
    # File 'lib/idl/ast.rb', line 403
    +      
    # File 'lib/idl/ast.rb', line 423
     
     def type_check(symtab)
       type_error "no symbol named '#{text_value}' on line #{lineno}" if symtab.get(text_value).nil?
    @@ -523,18 +552,18 @@ 

     
     
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    +438 +439 +440 +441 +442 +443 +444 +445 +446

    -
    # File 'lib/idl/ast.rb', line 418
    +      
    # File 'lib/idl/ast.rb', line 438
     
     def value(symtab)
       var = symtab.get(text_value)
    @@ -548,6 +577,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -555,7 +680,7 @@

    diff --git a/docs/ruby/Idl/IfAst.html b/docs/ruby/Idl/IfAst.html index dd5249f61..c1fe1d525 100644 --- a/docs/ruby/Idl/IfAst.html +++ b/docs/ruby/Idl/IfAst.html @@ -104,7 +104,7 @@
    Defined in:
    lib/idl/ast.rb,
    - lib/idl/passes/find_return_values.rb
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    @@ -114,6 +114,127 @@ +

    Instance Attribute Summary collapse

    +
      + +
    • + + + #elseifs ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute elseifs.

      +
      + +
    • + + +
    • + + + #final_else_body ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute final_else_body.

      +
      + +
    • + + +
    • + + + #if_body ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute if_body.

      +
      + +
    • + + +
    • + + + #if_cond ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute if_cond.

      +
      + +
    • + + +
    + @@ -128,17 +249,36 @@

  • - #execute(symtab) ⇒ void + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #initialize(if_cond, if_body, elseifs, final_else_body) ⇒ IfAst - - included - from Executable - + constructor @@ -148,7 +288,7 @@

    -

    “execute” the statement by updating the variables in the symbol table.

    +

    A new instance of IfAst.

  • @@ -173,6 +313,30 @@

    + + + +
  • + + + #prune(symtab) ⇒ AstNode + + + + + + + + + + + + + +
    +

    A new abstract syntax tree with all dead/unreachable code removed.

    +
    +
  • @@ -183,6 +347,8 @@

    + (also: #execute) + @@ -201,7 +367,7 @@

  • - #return_values(symtab) ⇒ Object + #return_values(symtab) ⇒ Array<Integer,Bool> @@ -215,7 +381,9 @@

    -
    +
    +

    Returns a list of all possible return values, if known.

    +

  • @@ -247,7 +415,7 @@

  • - #to_idl ⇒ Object + #to_idl ⇒ String @@ -261,7 +429,9 @@

    -
    +
    +

    Return valid IDL representation of the node (and its subtree).

    +

  • @@ -303,76 +473,334 @@

    +
    +

    Constructor Details

    + +
    +

    + + #initialize(if_cond, if_body, elseifs, final_else_body) ⇒ IfAst + + + + + +

    +
    + +

    Returns a new instance of IfAst.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +3762
    +3763
    +3764
    +3765
    +3766
    +3767
    +3768
    +3769
    +3770
    +3771
    +3772
    +3773
    +3774
    +3775
    +3776
    +3777
    +3778
    +3779
    +3780
    +3781
    +3782
    +
    +
    # File 'lib/idl/ast.rb', line 3762
    +
    +def initialize(if_cond, if_body, elseifs, final_else_body)
    +  children_nodes = [if_cond, if_body]
    +  children_nodes += elseifs
    +  children_nodes << final_else_body
    +
    +  interval_end =
    +    if !final_else_body.stmts.empty?
    +      final_else_body.stmts.last.interval.end
    +    elsif !elseifs.empty?
    +      elseifs.last.body.stmts.last.interval.end
    +    else
    +      if_body.stmts.last.interval.end
    +    end
    +
    +  super(if_cond.input, if_cond.interval.first..interval_end, children_nodes)
    +
    +  @if_cond = if_cond
    +  @if_body = if_body
    +  @elseifs = elseifs
    +  @final_else_body = final_else_body
    +end
    +
    +
    + +
    + +
    +

    Instance Attribute Details

    + + + +
    +

    + + #elseifsObject (readonly) + + + + + +

    +
    + +

    Returns the value of attribute elseifs.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +3760
    +3761
    +3762
    +
    +
    # File 'lib/idl/ast.rb', line 3760
    +
    +def elseifs
    +  @elseifs
    +end
    +
    +
    + + + +
    +

    + + #final_else_bodyObject (readonly) + + + + + +

    +
    + +

    Returns the value of attribute final_else_body.

    + + +
    +
    +
    +
    + + + + +
    +
    +
    +
    +3760
    +3761
    +3762
    +
    +
    # File 'lib/idl/ast.rb', line 3760
    +
    +def final_else_body
    +  @final_else_body
    +end
    +
    +
    + + + +
    +

    + + #if_bodyObject (readonly) + + + + + +

    +
    + +

    Returns the value of attribute if_body.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +3760
    +3761
    +3762
    +
    +
    # File 'lib/idl/ast.rb', line 3760
    +
    +def if_body
    +  @if_body
    +end
    +
    +
    + + + +
    +

    + + #if_condObject (readonly) + + + + + +

    +
    + +

    Returns the value of attribute if_cond.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +3760
    +3761
    +3762
    +
    +
    # File 'lib/idl/ast.rb', line 3760
    +
    +def if_cond
    +  @if_cond
    +end
    +
    +
    + +
    + +

    Instance Method Details

    -

    +

    - #execute(symtab) ⇒ void + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object - - Originally defined in module - Executable - - -

    -
    -

    This method returns an undefined value.

    -

    “execute” the statement by updating the variables in the symbol table

    +

    + + + + +
    +
     
     
    -  
    -
    -
    -

    Parameters:

    -
      - -
    • - - symtab - - - (SymbolTable) - - - - — -
      -

      The symbol table for the context

      -
      - -
    • - -
    +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 120
     
    -

    Raises:

    -
      - -
    • - - - - - - - -
      -

      ValueError if some part of the statement cannot be executed at compile time

      -
      - -
    • - -
    +def gen_adoc(indent = 0, indent_spaces: 2) + lines = ["if (#{if_cond.gen_adoc(0, indent_spaces:)}) {"] + if_body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + elseifs.each do |eif| + lines << "} else if (#{eif.cond.gen_adoc(0, indent_spaces:)}) {" + eif.body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + end + unless final_else_body.stmts.empty? + lines << "} else {" + final_else_body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + end + lines << "}" - + lines.map { |l| "#{' ' * indent}#{l}"}.join("\n") +end
    +
    @@ -453,6 +881,155 @@

    +

    + +
    +

    + + #prune(symtab) ⇒ AstNode + + + + + +

    +
    + +

    Returns A new abstract syntax tree with all dead/unreachable code removed.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (Idl::SymbolTable) + + + + — +
      +

      Context of the compilation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (AstNode) + + + + — +
      +

      A new abstract syntax tree with all dead/unreachable code removed

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +183
    +184
    +
    +
    # File 'lib/idl/passes/prune.rb', line 147
    +
    +def prune(symtab)
    +  if if_cond.value(symtab)
    +    if_body.prune(symtab)
    +  elsif !elseifs.empty?
    +    # we know that the if condition is false, so now we treat the else if
    +    # as the starting point and try again
    +    IfAst.new(
    +      elseifs[0].cond.prune(symtab),
    +      elseifs[0].body.prune(symtab),
    +      elseifs[1..].map { |e| e.prune(symtab) },
    +      final_else_body.prune(symtab))
    +  elsif !final_else_body.stmts.empty?
    +    # the if is false, and there are no else ifs, so the result of the prune is just the pruned else body
    +    final_else_body.prune(symtab)
    +  else
    +    # the if is false, and there are no else ifs or elses. This is just a no-op
    +    NoopAst.new
    +  end
    +rescue ValueError
    +  # we don't know the value of the if condition
    +  # we still might know the value of an else if
    +  unknown_elsifs = []
    +  elseifs.each do |eif|
    +    begin
    +      if eif.cond.value(symtab)
    +        # this elseif is true, so turn it into an else and then we are done
    +        return IfAst.new(if_cond.prune(symtab), if_body.prune(symtab), unknown_elsifs.map { |u| u.prune(symtab)}, eif.body.prune(symtab))
    +      else
    +        # this elseif is false, so we can remove it
    +        next
    +      end
    +    rescue ValueError
    +      unknown_elsifs << eif
    +    end
    +  end
    +  # we get here, then we don't know the value of anything. just return this if with everything pruned
    +  IfAst.new(if_cond.prune(symtab), if_body.prune(symtab), elseifs.map { |eif| eif.prune(symtab)}, final_else_body.prune(symtab))
    +end
    +
    @@ -462,6 +1039,10 @@

    + Also known as: + execute + +

    @@ -470,55 +1051,23 @@

     
     
    -3224
    -3225
    -3226
    -3227
    -3228
    -3229
    -3230
    -3231
    -3232
    -3233
    -3234
    -3235
    -3236
    -3237
    -3238
    -3239
    -3240
    -3241
    -3242
    -3243
    -3244
    -3245
    -3246
    +3832 +3833 +3834 +3835 +3836 +3837 +3838

    @@ -528,41 +1077,114 @@

    - #return_values(symtab) ⇒ Object + #return_values(symtab) ⇒ Array<Integer,Bool> -

    -
    # File 'lib/idl/ast.rb', line 3224
    +      
    # File 'lib/idl/ast.rb', line 3832
     
     def return_value(symtab)
     
       body = taken_body(symtab)
       return nil if body.nil?
     
    -  symtab.push
    -  begin
    -    body.elements.each do |e|
    -      if e.e.is_a?(Returns)
    -        v = e.e.return_value(symtab)
    -        unless v.nil?
    -          return v
    -        end
    -      else
    -        e.e.execute(symtab)
    -      end
    -    end
    -  ensure
    -    symtab.pop
    -  end
    -
    -  nil
    +  body.return_value(symtab)
     end
    +
    +
    + +

    Returns a list of all possible return values, if known. Otherwise, raises a ValueError

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Context for the evaluation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer,Bool>) + + + + — +
      +

      List of all possible return values

      +
      + +
    • + +
    +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      ValueError if it is not possible to determine all return values at compile time

      +
      + +
    • + +
    + +
    @@ -631,31 +1253,31 @@

     
     
    -3201
    -3202
    -3203
    -3204
    -3205
    -3206
    -3207
    -3208
    -3209
    -3210
    -3211
    +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829

    @@ -665,63 +1287,78 @@

    - #to_idlObject + #to_idlString -

     
     
    -3213
    -3214
    -3215
    -3216
    -3217
    -3218
    -3219
    -3220
    -3221
    -3222
    +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885
    -
    # File 'lib/idl/ast.rb', line 3213
    +      
    # File 'lib/idl/ast.rb', line 3873
     
     def return_values(symtab)
    -  begin
    -    # the if condition is known
    -    if if_cond.value(symtab)
    -
    -    else
    -    end
    -  rescue ValueError
    +  if_cond_value = @if_cond.value(symtab)
    +  if if_cond_value
    +    # if is taken, so the only possible return values are those in the if body
    +    @if_body.return_values(symtab)
    +  else
    +    # if cond not taken; check else ifs and possibly final else
    +    return_values_after_if(symtab)
       end
    +rescue ValueError
    +  # if condition not known; both paths are possible
    +  (@if_body.return_values(symtab) + return_values_after_if(symtab)).uniq
     end
    -
    # File 'lib/idl/ast.rb', line 3201
    +      
    # File 'lib/idl/ast.rb', line 3819
     
     def taken_body(symtab)
    -  return if_body if if_cond.value(symtab)
    +  return @if_body if @if_cond.value(symtab)
     
    -  unless elseifs.empty?
    -    elseifs.elements.each do |eif|
    -      return eif.body if eif.expression.value(symtab)
    +  unless @elseifs.empty?
    +    @elseifs.each do |eif|
    +      return eif.body if eif.cond.value(symtab)
         end
       end
     
    -  final_else.empty? ? nil : final_else.body
    +  @final_else_body.stmts.empty? ? nil : @final_else_body
     end
    +
    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    @@ -808,75 +1445,40 @@

     
     
    -3132
    -3133
    -3134
    -3135
    -3136
    -3137
    -3138
    -3139
    -3140
    -3141
    -3142
    -3143
    -3144
    -3145
    -3146
    -3147
    -3148
    -3149
    -3150
    -3151
    -3152
    -3153
    -3154
    -3155
    -3156
    -3157
    -3158
    -3159
    -3160
    -3161
    -3162
    -3163
    -3164
    -3165
    -3166
    -3167
    -3168
    -3169
    -3170
    -3171
    -3172
    -3173
    -3174
    -3175
    -3176
    -3177
    -3178
    -3179
    -3180
    -3181
    -3182
    -3183
    -3184
    -3185
    -3186
    -3187
    -3188
    -3189
    -3190
    -3191
    -3192
    -3193
    -3194
    -3195
    -3196
    -3197
    +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815

     
     
    -3248
    -3249
    -3250
    -3251
    -3252
    -3253
    -3254
    -3255
    -3256
    -3257
    -3258
    -3259
    -3260
    -3261
    -3262
    -3263
    -3264
    -3265
    -3266
    -3267
    -3268
    +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901
    -
    # File 'lib/idl/ast.rb', line 3248
    +      
    # File 'lib/idl/ast.rb', line 3888
     
     def to_idl
    -  result = "if (#{if_cond.to_idl}) { "
    -  if_body.elements.each do |e|
    -    result << e.e.to_idl
    -  end
    +  result = "if (#{@if_cond.to_idl}) { "
    +  result << @if_body.to_idl
       result << "} "
    -  elseifs.elements.each do |eif|
    -    result << " else if (#{eif.expression.to_idl}) { "
    -    eif.body.elements.each do |e|
    -      result << e.e.to_idl
    -    end
    -    result << "} "
    +  @elseifs.each do |eif|
    +    result << eif.to_idl
       end
    -  unless final_else.empty?
    +  unless @final_else_body.stmts.empty?
         result << " else { "
    -    final_else.body.elements.each do |e|
    -      result << e.e.to_idl
    -    end
    +    result << @final_else_body.to_idl
         result << "} "
       end
    +  result
     end
    -
    # File 'lib/idl/ast.rb', line 3132
    +      
    # File 'lib/idl/ast.rb', line 3785
     
     def type_check(symtab)
       level = symtab.levels
    @@ -884,63 +1486,28 @@ 

    type_error "'#{if_cond.text_value}' is not boolean" unless if_cond.type(symtab).convertable_to?(:boolean) - symtab.push - begin # only type check the body if it is reachable - if if_cond.value(symtab) == true - if_body.elements.each do |e| - e.e.type_check(symtab) - end + if @if_cond.value(symtab) == true + @if_body.type_check(symtab) return # don't bother with the rest end rescue ValueError # we don't know if the body is reachable; type check it - if_body.elements.each do |e| - e.e.type_check(symtab) - end - ensure - symtab.pop + @if_body.type_check(symtab) end internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels - unless elseifs.empty? - elseifs.elements.each do |eif| - eif.expression.type_check(symtab) - unless eif.expression.type(symtab).convertable_to?(:boolean) - type_error "'#{eif.expression.text_value}' is not boolean" - end - - symtab.push - begin - # only type check the body if it is reachable - if eif.expression.value(symtab) == true - eif.body.elements.each do |e| - e.e.type_check(symtab) - end - return # don't bother with the rest - end - rescue ValueError - # condition isn't compile-time-known; have to check the body - eif.body.elements.each do |e| - e.e.type_check(symtab) - end - ensure - symtab.pop - end + unless @elseifs.empty? + @elseifs.each do |eif| + eif.type_check(symtab) end end - return if final_else.empty? - internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels - symtab.push - final_else.body.elements.each do |e| - e.e.type_check(symtab) - end - symtab.pop + @final_else_body.type_check(symtab) internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels end

    @@ -954,7 +1521,7 @@

    diff --git a/docs/ruby/Idl/InstructionOperationAst.html b/docs/ruby/Idl/InstructionOperationAst.html index 83d0c4e85..36f8c45c1 100644 --- a/docs/ruby/Idl/InstructionOperationAst.html +++ b/docs/ruby/Idl/InstructionOperationAst.html @@ -140,6 +140,28 @@

    +
    + + + + +
  • + + + #to_idl ⇒ Object + + + + + + + + + + + + +
  • @@ -201,14 +223,14 @@

     
     
    -2733
    -2734
    -2735
    -2736
    -2737
    +3096 +3097 +3098 +3099 +3100

    -
    # File 'lib/idl/ast.rb', line 2733
    +      
    # File 'lib/idl/ast.rb', line 3096
     
     def execute(symtab)
       op_stmt_list.elements.each do |e|
    @@ -218,6 +240,32 @@ 

    +
    + +
    +

    + + #to_idlObject + + + + + +

    + + + + +
    +
    +
    +
    +3102
    +
    +
    # File 'lib/idl/ast.rb', line 3102
    +
    +def to_idl = op_stmt_list.elements.map { |e| e.choice.to_idl }.join("")
    +
    @@ -300,14 +348,14 @@

     
     
    -2727
    -2728
    -2729
    -2730
    -2731
    +3090 +3091 +3092 +3093 +3094

    -
    # File 'lib/idl/ast.rb', line 2727
    +      
    # File 'lib/idl/ast.rb', line 3090
     
     def type_check(symtab)
       op_stmt_list.elements.each do |e|
    @@ -324,7 +372,7 @@ 

    diff --git a/docs/ruby/Idl/IntAst.html b/docs/ruby/Idl/IntAst.html index 7b487cf03..e2a139af7 100644 --- a/docs/ruby/Idl/IntAst.html +++ b/docs/ruby/Idl/IntAst.html @@ -399,6 +399,35 @@

    raise a value error, indicating that the value is not known at compile time.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -703,10 +732,10 @@

     
     
    -2546
    +2911

    -
    # File 'lib/idl/ast.rb', line 2546
    +      
    # File 'lib/idl/ast.rb', line 2911
     
     def to_idl = text_value
    @@ -798,15 +827,151 @@

     
     
    -2534
    -2535
    -2536
    +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845

    -
    # File 'lib/idl/ast.rb', line 2534
    +      
    # File 'lib/idl/ast.rb', line 2775
     
     def type(symtab)
    -  @type
    +  text_value_no_underscores = text_value.delete("_")
    +  if text_value_no_underscores =~ /([0-9]+)?'(s?)([bodh]?)(.*)/
    +    width = ::Regexp.last_match(1)
    +    signed = ::Regexp.last_match(2)
    +    radix_id = ::Regexp.last_match(3)
    +    value = ::Regexp.last_match(4)
    +
    +    if width.nil?
    +      archdef = symtab.archdef
    +      width = archdef.config_params["XLEN"] if width.nil?
    +    end
    +    radix_id = "d" if radix_id.empty?
    +
    +    # ensure we actually have enough bits to represent the value
    +    case radix_id
    +    when "b"
    +      @value = value.to_i(2)
    +      type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i
    +    when "o"
    +      @value = value.to_i(8)
    +      type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i
    +    when "d"
    +      @value = value.to_i(10)
    +      type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i
    +    when "h"
    +      @value = value.to_i(16)
    +      type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i
    +    end
    +
    +    qualifiers = signed == "s" ? [:signed, :const] : [:const]
    +    @type = Type.new(:bits, width: width.to_i, qualifiers:)
    +  elsif text_value_no_underscores =~ /0([bdx]?)([0-9a-fA-F]*)(s?)/
    +    radix_id = ::Regexp.last_match(1)
    +    value = ::Regexp.last_match(2)
    +    signed = ::Regexp.last_match(3)
    +
    +    radix_id = "o" if radix_id.empty?
    +
    +    case radix_id
    +    when "b"
    +      @value = value.to_i(2)
    +    when "o"
    +      @value = value.to_i(8)
    +    when "d"
    +      @value = value.to_i(10)
    +    when "x"
    +      @value = value.to_i(16)
    +    end
    +
    +    qualifiers = signed == "s" ? [:signed, :const] : [:const]
    +    width = signed == "s" ? @value.bit_length + 1 : @value.bit_length
    +    width = 1 if width.zero? # happens when the literal is '0'
    +    @type = Type.new(:bits, width:, qualifiers:)
    +  elsif text_value_no_underscores =~ /([0-9]*)(s?)/
    +    value = ::Regexp.last_match(1)
    +    signed = ::Regexp.last_match(2)
    +
    +    @value = value.to_i(10)
    +
    +    qualifiers = signed == "s" ? [:signed, :const] : [:const]
    +    width = signed == "s" ? @value.bit_length + 1 : @value.bit_length
    +    width = 1 if width.zero? # happens when the literal is '0'
    +    @type = Type.new(:bits, width:, qualifiers:)
    +  else
    +    internal_error "Unhandled int value"
    +  end
    +  type_error(text_value) if @value.nil?
    +
    +  return @type
     end
    @@ -893,76 +1058,76 @@

     
     
    -2465
    -2466
    -2467
    -2468
    -2469
    -2470
    -2471
    -2472
    -2473
    -2474
    -2475
    -2476
    -2477
    -2478
    -2479
    -2480
    -2481
    -2482
    -2483
    -2484
    -2485
    -2486
    -2487
    -2488
    -2489
    -2490
    -2491
    -2492
    -2493
    -2494
    -2495
    -2496
    -2497
    -2498
    -2499
    -2500
    -2501
    -2502
    -2503
    -2504
    -2505
    -2506
    -2507
    -2508
    -2509
    -2510
    -2511
    -2512
    -2513
    -2514
    -2515
    -2516
    -2517
    -2518
    -2519
    -2520
    -2521
    -2522
    -2523
    -2524
    -2525
    -2526
    -2527
    -2528
    -2529
    -2530
    -2531
    +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772

    -
    # File 'lib/idl/ast.rb', line 2465
    +      
    # File 'lib/idl/ast.rb', line 2706
     
     def type_check(symtab)
       archdef = symtab.archdef
    @@ -1196,19 +1361,131 @@ 

     
     
    -2539
    -2540
    -2541
    -2542
    -2543
    +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908

    -
    # File 'lib/idl/ast.rb', line 2539
    +      
    # File 'lib/idl/ast.rb', line 2848
     
     def value(symtab)
    -  internal_error("Did not type check #{text_value}") if @value.nil?
    +  text_value_no_underscores = text_value.delete("_")
    +  if text_value_no_underscores =~ /([0-9]+)?'(s?)([bodh]?)(.*)/
    +    width = ::Regexp.last_match(1)
    +    _signed = ::Regexp.last_match(2)
    +    radix_id = ::Regexp.last_match(3)
    +    value = ::Regexp.last_match(4)
    +
    +    if width.nil?
    +      archdef = symtab.archdef
    +      width = archdef.config_params["XLEN"] if width.nil?
    +    end
    +
    +    radix_id = "d" if radix_id.empty?
    +
    +    # ensure we actually have enough bits to represent the value
    +    case radix_id
    +    when "b"
    +      v = value.to_i(2)
    +      type_error("#{value} cannot be represented in #{width} bits") if v.bit_length > width.to_i
    +    when "o"
    +      v = value.to_i(8)
    +      type_error("#{value} cannot be represented in #{width} bits") if v.bit_length > width.to_i
    +    when "d"
    +      v = value.to_i(10)
    +      type_error("#{value} cannot be represented in #{width} bits") if v.bit_length > width.to_i
    +    when "h"
    +      v = value.to_i(16)
    +      type_error("#{value} cannot be represented in #{width} bits") if v.bit_length > width.to_i
    +    end
    +    
    +    v
    +
    +  elsif text_value_no_underscores =~ /0([bdx]?)([0-9a-fA-F]*)(s?)/
    +    radix_id = ::Regexp.last_match(1)
    +    value = ::Regexp.last_match(2)
    +    signed = ::Regexp.last_match(3)
    +
    +    radix_id = "o" if radix_id.empty?
     
    -  @value
    +    case radix_id
    +    when "b"
    +      value.to_i(2)
    +    when "o"
    +      value.to_i(8)
    +    when "d"
    +      value.to_i(10)
    +    when "x"
    +      value.to_i(16)
    +    end
    +
    +  elsif text_value_no_underscores =~ /([0-9]*)(s?)/
    +    value = ::Regexp.last_match(1)
    +    signed = ::Regexp.last_match(2)
    +
    +    value.to_i(10)
    +
    +  else
    +    internal_error "Unhandled int value"
    +  end
     end
    @@ -1278,6 +1555,102 @@

    + + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    +
    @@ -1286,7 +1659,7 @@

    diff --git a/docs/ruby/Idl/IsaAst.html b/docs/ruby/Idl/IsaAst.html index 35c15fbf9..eaf927884 100644 --- a/docs/ruby/Idl/IsaAst.html +++ b/docs/ruby/Idl/IsaAst.html @@ -315,18 +315,18 @@

     
     
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    +522 +523 +524 +525 +526 +527 +528 +529 +530

    -
    # File 'lib/idl/ast.rb', line 503
    +      
    # File 'lib/idl/ast.rb', line 522
     
     def bitfields
       return @bitfields unless @bitfields.nil?
    @@ -357,12 +357,12 @@ 

     
     
    -476
    -477
    -478
    +495 +496 +497

    -
    # File 'lib/idl/ast.rb', line 476
    +      
    # File 'lib/idl/ast.rb', line 495
     
     def children
       enums + bitfields + functions + globals
    @@ -398,19 +398,19 @@ 

     
     
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    +511 +512 +513 +514 +515 +516 +517 +518 +519 +520

    -
    # File 'lib/idl/ast.rb', line 492
    +      
    # File 'lib/idl/ast.rb', line 511
     
     def enums
       return @enums unless @enums.nil?
    @@ -442,19 +442,19 @@ 

     
     
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    +532 +533 +534 +535 +536 +537 +538 +539 +540 +541

    -
    # File 'lib/idl/ast.rb', line 513
    +      
    # File 'lib/idl/ast.rb', line 532
     
     def functions
       return @functions unless @functions.nil?
    @@ -486,19 +486,19 @@ 

     
     
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    +499 +500 +501 +502 +503 +504 +505 +506 +507 +508

    -
    # File 'lib/idl/ast.rb', line 480
    +      
    # File 'lib/idl/ast.rb', line 499
     
     def globals
       return @globals unless @globals.nil?
    @@ -530,18 +530,18 @@ 

     
     
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    +552 +553 +554 +555 +556 +557 +558 +559 +560

    -
    # File 'lib/idl/ast.rb', line 533
    +      
    # File 'lib/idl/ast.rb', line 552
     
     def instructions
       return @instructions unless @instructions.nil?
    @@ -572,17 +572,17 @@ 

     
     
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    +543 +544 +545 +546 +547 +548 +549 +550

    -
    # File 'lib/idl/ast.rb', line 524
    +      
    # File 'lib/idl/ast.rb', line 543
     
     def type_check(symtab)
       definitions.elements.each do |e|
    @@ -602,7 +602,7 @@ 

    diff --git a/docs/ruby/Idl/MultiVariableAssignmentAst.html b/docs/ruby/Idl/MultiVariableAssignmentAst.html index 5d0350449..8f680d87f 100644 --- a/docs/ruby/Idl/MultiVariableAssignmentAst.html +++ b/docs/ruby/Idl/MultiVariableAssignmentAst.html @@ -286,24 +286,24 @@

     
     
    -1211
    -1212
    -1213
    -1214
    -1215
    -1216
    -1217
    -1218
    -1219
    -1220
    -1221
    -1222
    +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265

    -
    # File 'lib/idl/ast.rb', line 1211
    +      
    # File 'lib/idl/ast.rb', line 1254
     
     def execute(symtab)
    -  values = functin_call.execute(symtab)
    +  values = function_call.execute(symtab)
     
       i = 0
       vars.each do |v|
    @@ -334,12 +334,12 @@ 

     
     
    -1176
    -1177
    -1178
    +1219 +1220 +1221

    -
    # File 'lib/idl/ast.rb', line 1176
    +      
    # File 'lib/idl/ast.rb', line 1219
     
     def rhs
       function_call
    @@ -393,10 +393,10 @@ 

     
     
    -1225
    +1268

    -
    # File 'lib/idl/ast.rb', line 1225
    +      
    # File 'lib/idl/ast.rb', line 1268
     
     def to_idl = "(#{vars.map(&:to_idl).join(', ')}) = #{function_call.to_idl}"
    @@ -484,38 +484,38 @@

     
     
    -1181
    -1182
    -1183
    -1184
    -1185
    -1186
    -1187
    -1188
    -1189
    -1190
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    -1200
    -1201
    -1202
    -1203
    -1204
    -1205
    -1206
    -1207
    -1208
    -1209
    +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252

    -
    # File 'lib/idl/ast.rb', line 1181
    +      
    # File 'lib/idl/ast.rb', line 1224
     
     def type_check(symtab)
       function_call.type_check(symtab)
    @@ -595,12 +595,12 @@ 

     
     
    -1172
    -1173
    -1174
    +1215 +1216 +1217

    -
    # File 'lib/idl/ast.rb', line 1172
    +      
    # File 'lib/idl/ast.rb', line 1215
     
     def vars
       [first] + rest.elements.map(&:var)
    @@ -615,7 +615,7 @@ 

    diff --git a/docs/ruby/Idl/MultiVariableDeclarationAst.html b/docs/ruby/Idl/MultiVariableDeclarationAst.html index 42fb4dc83..176afb27d 100644 --- a/docs/ruby/Idl/MultiVariableDeclarationAst.html +++ b/docs/ruby/Idl/MultiVariableDeclarationAst.html @@ -69,7 +69,7 @@
    Inherits:
    - AssignmentAst + AstNode @@ -93,6 +91,11 @@ +
    +
    Includes:
    +
    Declaration
    +
    + @@ -140,7 +143,7 @@

  • - #execute(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object @@ -154,7 +157,9 @@

    -
    +
    +

    Add symbol(s) at the outermost scope of the symbol table.

    +

  • @@ -243,40 +248,69 @@

    - -

    Instance Method Details

    -

    +

    - #execute(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object -

    +
    +
    + +

    Add symbol(s) at the outermost scope of the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table at the scope that the symbol(s) will be inserted

      +
      + +
    • + +
    + + +
    @@ -328,10 +362,10 @@

     
     
    -1284
    +1328

    @@ -419,27 +453,23 @@

     
     
    -1267
    -1268
    -1269
    -1270
    -1271
    -1272
    -1273
    -1274
    -1275
    +1312 +1313 +1314 +1315 +1316 +1317 +1318

    @@ -490,19 +520,19 @@

     
     
    -1255
    -1256
    -1257
    -1258
    -1259
    -1260
    -1261
    -1262
    -1263
    -1264
    +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309

    @@ -344,10 +373,10 @@

     
     
    -1722
    +1866

    @@ -439,10 +468,10 @@

     
     
    -1716
    +1860

    @@ -530,10 +559,10 @@

     
     
    -1713
    +1857

    @@ -567,15 +596,111 @@

     
     
    -1719
    +1863

     
     
    -1277
    -1278
    -1279
    -1280
    -1281
    +1321 +1322 +1323 +1324 +1325
    -
    # File 'lib/idl/ast.rb', line 1277
    +      
    # File 'lib/idl/ast.rb', line 1321
     
    -def execute(symtab)
    -  var_names.each do |name|
    -    symtab.add(name, Var.new(name, type.clone))
    +def add_symbol(symtab)
    +  var_names.each do |vname|
    +    symtab.add(vname, Var.new(vname, type.clone, type.default))
       end
     end
    -
    # File 'lib/idl/ast.rb', line 1284
    +      
    # File 'lib/idl/ast.rb', line 1328
     
     def to_idl = "#{type.to_idl} #{var_names.map(&:to_idl).join(', ')}"
    -
    # File 'lib/idl/ast.rb', line 1267
    +      
    # File 'lib/idl/ast.rb', line 1312
     
     def type_check(symtab)
       type_error "No type named '#{type_name.text_value}' on line #{lineno}" if type.nil?
     
       type_error "Attempt to write read-only/constant variable #{text_value}" if type.const?
     
    -  var_names.each do |vname|
    -    symtab.add(vname, Var.new(vname, type.clone))
    -  end
    +  add_symbol(symtab)
     end
    -
    # File 'lib/idl/ast.rb', line 1255
    +      
    # File 'lib/idl/ast.rb', line 1300
     
     def var_names
       return @var_names unless @var_names.nil?
    @@ -524,7 +554,7 @@ 

    diff --git a/docs/ruby/Idl/ParenExpressionAst.html b/docs/ruby/Idl/ParenExpressionAst.html index b1556749c..325051b66 100644 --- a/docs/ruby/Idl/ParenExpressionAst.html +++ b/docs/ruby/Idl/ParenExpressionAst.html @@ -254,6 +254,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -289,10 +318,10 @@

     
     
    -1710
    +1854

    -
    # File 'lib/idl/ast.rb', line 1710
    +      
    # File 'lib/idl/ast.rb', line 1854
     
     def invert(symtab) = e.invert(symtab)
    -
    # File 'lib/idl/ast.rb', line 1722
    +      
    # File 'lib/idl/ast.rb', line 1866
     
     def to_idl = "(#{e.to_idl})"
    -
    # File 'lib/idl/ast.rb', line 1716
    +      
    # File 'lib/idl/ast.rb', line 1860
     
     def type(symtab) = e.type(symtab)
    -
    # File 'lib/idl/ast.rb', line 1713
    +      
    # File 'lib/idl/ast.rb', line 1857
     
     def type_check(symtab) = e.type_check(symtab)
    -
    # File 'lib/idl/ast.rb', line 1719
    +      
    # File 'lib/idl/ast.rb', line 1863
     
     def value(symtab) = e.value(symtab)
    +
    + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -583,7 +708,7 @@

    diff --git a/docs/ruby/Idl/PostDecrementExpressionAst.html b/docs/ruby/Idl/PostDecrementExpressionAst.html index 0f5932a84..f09bff11b 100644 --- a/docs/ruby/Idl/PostDecrementExpressionAst.html +++ b/docs/ruby/Idl/PostDecrementExpressionAst.html @@ -310,15 +310,15 @@

     
     
    -1858
    -1859
    -1860
    -1861
    -1862
    -1863
    +2002 +2003 +2004 +2005 +2006 +2007

    -
    # File 'lib/idl/ast.rb', line 1858
    +      
    # File 'lib/idl/ast.rb', line 2002
     
     def execute(symtab)
       var = symtab.get(rval.text_value)
    @@ -346,10 +346,10 @@ 

     
     
    -1865
    +2009

    -
    # File 'lib/idl/ast.rb', line 1865
    +      
    # File 'lib/idl/ast.rb', line 2009
     
     def to_idl = "#{rval.to_idl}--"
    @@ -372,12 +372,12 @@

     
     
    -1853
    -1854
    -1855
    +1997 +1998 +1999

    -
    # File 'lib/idl/ast.rb', line 1853
    +      
    # File 'lib/idl/ast.rb', line 1997
     
     def type(symtab)
       rval.type(symtab)
    @@ -402,13 +402,13 @@ 

     
     
    -1848
    -1849
    -1850
    -1851
    +1992 +1993 +1994 +1995

    -
    # File 'lib/idl/ast.rb', line 1848
    +      
    # File 'lib/idl/ast.rb', line 1992
     
     def type_check(symtab)
       rval.type_check(symtab)
    @@ -424,7 +424,7 @@ 

    diff --git a/docs/ruby/Idl/PostIncrementExpressionAst.html b/docs/ruby/Idl/PostIncrementExpressionAst.html index 4035b614a..3aca399ef 100644 --- a/docs/ruby/Idl/PostIncrementExpressionAst.html +++ b/docs/ruby/Idl/PostIncrementExpressionAst.html @@ -316,19 +316,19 @@

     
     
    -1887
    -1888
    -1889
    -1890
    -1891
    -1892
    +2031 +2032 +2033 +2034 +2035 +2036

    -
    # File 'lib/idl/ast.rb', line 1887
    +      
    # File 'lib/idl/ast.rb', line 2031
     
     def execute(symtab)
    -  var = symtab.get(rval)
    -  internal_error "Call type check first" if var.nil?
    +  var = symtab.get(rval.text_value)
    +  internal_error "No symbol named '#{rval.text_value}'" if var.nil?
     
       var.value = var.value + 1
     end
    @@ -381,10 +381,10 @@

     
     
    -1895
    +2039

    -
    # File 'lib/idl/ast.rb', line 1895
    +      
    # File 'lib/idl/ast.rb', line 2039
     
     def to_idl = "#{rval.to_idl}++"
    @@ -476,12 +476,12 @@

     
     
    -1882
    -1883
    -1884
    +2026 +2027 +2028

    -
    # File 'lib/idl/ast.rb', line 1882
    +      
    # File 'lib/idl/ast.rb', line 2026
     
     def type(symtab)
       rval.type(symtab)
    @@ -571,13 +571,13 @@ 

     
     
    -1876
    -1877
    -1878
    -1879
    +2020 +2021 +2022 +2023

    -
    # File 'lib/idl/ast.rb', line 1876
    +      
    # File 'lib/idl/ast.rb', line 2020
     
     def type_check(symtab)
       rval.type_check(symtab)
    @@ -593,7 +593,7 @@ 

    diff --git a/docs/ruby/Idl/ReplicationExpressionAst.html b/docs/ruby/Idl/ReplicationExpressionAst.html index 57c6fc520..80d939c73 100644 --- a/docs/ruby/Idl/ReplicationExpressionAst.html +++ b/docs/ruby/Idl/ReplicationExpressionAst.html @@ -232,6 +232,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -296,10 +325,10 @@

     
     
    -1838
    +1982

    -
    # File 'lib/idl/ast.rb', line 1838
    +      
    # File 'lib/idl/ast.rb', line 1982
     
     def to_idl = "{#{n.to_idl}{#{v.to_idl}}}"
    @@ -391,13 +420,13 @@

     
     
    -1832
    -1833
    -1834
    -1835
    +1976 +1977 +1978 +1979

    -
    # File 'lib/idl/ast.rb', line 1832
    +      
    # File 'lib/idl/ast.rb', line 1976
     
     def type(symtab)
       width = (n.value(symtab) * v.type(symtab).width)
    @@ -488,20 +517,20 @@ 

     
     
    -1810
    -1811
    -1812
    -1813
    -1814
    -1815
    -1816
    -1817
    -1818
    -1819
    -1820
    +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964

    -
    # File 'lib/idl/ast.rb', line 1810
    +      
    # File 'lib/idl/ast.rb', line 1954
     
     def type_check(symtab)
       n.type_check(symtab)
    @@ -545,16 +574,16 @@ 

     
     
    -1823
    -1824
    -1825
    -1826
    -1827
    -1828
    -1829
    +1967 +1968 +1969 +1970 +1971 +1972 +1973

    -
    # File 'lib/idl/ast.rb', line 1823
    +      
    # File 'lib/idl/ast.rb', line 1967
     
     def value(symtab)
       result = 0
    @@ -566,6 +595,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -573,7 +698,7 @@

    diff --git a/docs/ruby/Idl/ReturnStatementAst.html b/docs/ruby/Idl/ReturnStatementAst.html index 72ca92d5e..65f2955a8 100644 --- a/docs/ruby/Idl/ReturnStatementAst.html +++ b/docs/ruby/Idl/ReturnStatementAst.html @@ -104,7 +104,7 @@
    Defined in:
    lib/idl/ast.rb,
    - lib/idl/passes/find_return_values.rb
    + lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    @@ -189,6 +189,28 @@

    The expected return type (as defined by the encolsing function).

    + + + +
  • + + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -285,7 +307,7 @@

  • - #return_value_nodes ⇒ Object + #return_value_nodes ⇒ Array<AstNode> @@ -300,9 +322,31 @@

    -

    list of return value nodes.

    +

    List of return value nodes.

    +

  • + + +
  • + + + #return_values(symtab) ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -384,12 +428,12 @@

     
     
    -2377
    -2378
    -2379
    +2590 +2591 +2592

    -
    # File 'lib/idl/ast.rb', line 2377
    +      
    # File 'lib/idl/ast.rb', line 2590
     
     def enclosing_function
       find_ancestor(FunctionDefAst)
    @@ -443,21 +487,35 @@ 

     
     
    -2328
    -2329
    -2330
    -2331
    -2332
    -2333
    -2334
    -2335
    -2336
    -2337
    -2338
    -2339
    +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552

    -
    # File 'lib/idl/ast.rb', line 2328
    +      
    # File 'lib/idl/ast.rb', line 2527
     
     def expected_return_type(symtab)
       func_def = find_ancestor(FunctionDefAst)
    @@ -468,12 +526,58 @@ 

    symtab.get("__expected_return_type") else - func_def.return_type(symtab) + # need to find the type to get the right symbol table + func_type = symtab.get_global(func_def.name) + internal_error "Couldn't find function type for '#{func_def.name}' #{symtab.keys} " if func_type.nil? + + # to get the return type, we need to find the template values in case this is + # a templated function definition + # + # that information should be up the stack in the symbol table + template_values = symtab.find_all(single_scope: true) do |o| + o.is_a?(Var) && o.template_value_for?(func_def.name) + end + unless template_values.size == func_type.template_names.size + internal_error "Did not find correct number of template arguments (found #{template_values.size}, need #{func_type.template_names.size}) #{symtab.keys_pretty}" + end + func_type.return_type(template_values.sort { |a, b| a.template_index <=> b.template_index }.map(&:value)) end end

    + + +
    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +72
    +73
    +74
    +75
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 72
    +
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  values = [first.gen_adoc(0, indent_spaces:)] + rest.elements.each { |e| e.e.gen_adoc(0, indent_spaces: )}
    +  "#{' ' * indent}return #{values.join(', ')};"
    +end
    +
    @@ -541,17 +645,17 @@

     
     
    -2318
    -2319
    -2320
    -2321
    -2322
    -2323
    -2324
    -2325
    +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524

    -
    # File 'lib/idl/ast.rb', line 2318
    +      
    # File 'lib/idl/ast.rb', line 2517
     
     def return_type(symtab)
       types = return_types(symtab)
    @@ -610,20 +714,20 @@ 

     
     
    -2305
    -2306
    -2307
    -2308
    -2309
    -2310
    -2311
    -2312
    -2313
    -2314
    -2315
    +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514

    -
    # File 'lib/idl/ast.rb', line 2305
    +      
    # File 'lib/idl/ast.rb', line 2504
     
     def return_types(symtab)
       if first.type(symtab).kind == :tuple
    @@ -656,16 +760,16 @@ 

     
     
    -2381
    -2382
    -2383
    -2384
    -2385
    -2386
    -2387
    +2595 +2596 +2597 +2598 +2599 +2600 +2601

    -
    # File 'lib/idl/ast.rb', line 2381
    +      
    # File 'lib/idl/ast.rb', line 2595
     
     def return_value(symtab)
       if return_value_nodes.size == 1
    @@ -682,7 +786,7 @@ 

    - #return_value_nodesObject + #return_value_nodesArray<AstNode> @@ -691,13 +795,31 @@

    -

    list of return value nodes

    +

    Returns List of return value nodes.

    +

    Returns:

    +
      + +
    • + + + (Array<AstNode>) + + + + — +
      +

      List of return value nodes

      +
      + +
    • + +
    @@ -705,18 +827,18 @@

     
     
    -2367
    -2368
    -2369
    -2370
    -2371
    -2372
    -2373
    -2374
    -2375
    +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588

    -
    # File 'lib/idl/ast.rb', line 2367
    +      
    # File 'lib/idl/ast.rb', line 2580
     
     def return_value_nodes
       v = [first]
    @@ -730,6 +852,44 @@ 

    +
    + +
    +

    + + #return_values(symtab) ⇒ Object + + + + + +

    + + + + +
    +
    +
    +
    +2604
    +2605
    +2606
    +2607
    +2608
    +2609
    +2610
    +
    +
    # File 'lib/idl/ast.rb', line 2604
    +
    +def return_values(symtab)
    +  if return_value_nodes.size == 1
    +    return_value_nodes[0].values(symtab)
    +  else
    +    return_value_nodes.map { |v| v.values(symtab) }.flatten.uniq
    +  end
    +end
    +
    @@ -747,10 +907,10 @@

     
     
    -2389
    +2612

    -
    # File 'lib/idl/ast.rb', line 2389
    +      
    # File 'lib/idl/ast.rb', line 2612
     
     def to_idl = "return #{return_value_nodes.map(&:to_idl).join(',')};"
    @@ -838,32 +998,32 @@

     
     
    -2342
    -2343
    -2344
    -2345
    -2346
    -2347
    -2348
    -2349
    -2350
    -2351
    -2352
    -2353
    -2354
    -2355
    -2356
    -2357
    -2358
    -2359
    -2360
    -2361
    -2362
    -2363
    -2364
    +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577

    -
    # File 'lib/idl/ast.rb', line 2342
    +      
    # File 'lib/idl/ast.rb', line 2555
     
     def type_check(symtab)
       first.type_check(symtab)
    @@ -898,7 +1058,7 @@ 

    diff --git a/docs/ruby/Idl/Returns.html b/docs/ruby/Idl/Returns.html index d6c367cee..ed0ce45b3 100644 --- a/docs/ruby/Idl/Returns.html +++ b/docs/ruby/Idl/Returns.html @@ -76,7 +76,7 @@
    Included in:
    -
    ConditionalReturnStatementAst, ForLoopAst, FunctionBodyAst, IfAst, ReturnStatementAst
    +
    ConditionalReturnStatementAst, ElseIfAst, ForLoopAst, FunctionBodyAst, IfAst, IfBodyAst, ReturnStatementAst
    @@ -131,6 +131,28 @@

    +
    + + + + +
  • + + + #return_values(symtab) ⇒ Object + + + + + + + + + + + + +
  • @@ -182,15 +204,63 @@

     
     
    -348
    +332

    -
    # File 'lib/idl/ast.rb', line 348
    +      
    # File 'lib/idl/ast.rb', line 332
     
     def return_value(symtab) = raise NotImplementedError, "#{self.class.name} must implement return_value"
    + + +
    +

    + + #return_values(symtab) ⇒ Object + + + + + +

    +
    + + +
    +
    +
    + +

    Raises:

    +
      + +
    • + + + (NotImplementedError) + + + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +345
    +
    +
    # File 'lib/idl/ast.rb', line 345
    +
    +def return_values(symtab) = raise NotImplementedError, "#{self.class.name} must implement return_values"
    +
    @@ -198,7 +268,7 @@

    diff --git a/docs/ruby/Idl/Rvalue.html b/docs/ruby/Idl/Rvalue.html index 0256b8e65..5b4f50fd2 100644 --- a/docs/ruby/Idl/Rvalue.html +++ b/docs/ruby/Idl/Rvalue.html @@ -159,6 +159,30 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -259,10 +283,10 @@

     
     
    -370
    +367

    -
    # File 'lib/idl/ast.rb', line 370
    +      
    # File 'lib/idl/ast.rb', line 367
     
     def type(symtab) = raise NotImplementedError, "#{self.class.name} has no type"
    @@ -313,15 +337,120 @@

     
     
    -393
    +390

    -
    # File 'lib/idl/ast.rb', line 393
    +      
    # File 'lib/idl/ast.rb', line 390
     
     def value(symtab) = raise NotImplementedError, "#{self.class.name} must implement value(symtab)"
    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +404
    +
    +
    # File 'lib/idl/ast.rb', line 404
    +
    +def values(symtab) = [value(symtab)]
    +
    @@ -329,7 +458,7 @@

    diff --git a/docs/ruby/Idl/SignCastAst.html b/docs/ruby/Idl/SignCastAst.html index 11eecf15c..048e14617 100644 --- a/docs/ruby/Idl/SignCastAst.html +++ b/docs/ruby/Idl/SignCastAst.html @@ -216,6 +216,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -280,10 +309,10 @@

     
     
    -1477
    +1542

    -
    # File 'lib/idl/ast.rb', line 1477
    +      
    # File 'lib/idl/ast.rb', line 1542
     
     def to_idl = "$signed(#{expression.to_idl})"
    @@ -375,10 +404,10 @@

     
     
    -1460
    +1525

    -
    # File 'lib/idl/ast.rb', line 1460
    +      
    # File 'lib/idl/ast.rb', line 1525
     
     def type(symtab) = expression.type(symtab).clone.make_signed
    @@ -466,12 +495,12 @@

     
     
    -1455
    -1456
    -1457
    +1520 +1521 +1522

    -
    # File 'lib/idl/ast.rb', line 1455
    +      
    # File 'lib/idl/ast.rb', line 1520
     
     def type_check(symtab)
       expression.type_check(symtab)
    @@ -507,21 +536,21 @@ 

     
     
    -1463
    -1464
    -1465
    -1466
    -1467
    -1468
    -1469
    -1470
    -1471
    -1472
    -1473
    -1474
    +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539

    -
    # File 'lib/idl/ast.rb', line 1463
    +      
    # File 'lib/idl/ast.rb', line 1528
     
     def value(symtab)
       t = expression.type(symtab)
    @@ -538,6 +567,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -545,7 +670,7 @@

    diff --git a/docs/ruby/Idl/StatementAst.html b/docs/ruby/Idl/StatementAst.html index 1acd09a30..826c73788 100644 --- a/docs/ruby/Idl/StatementAst.html +++ b/docs/ruby/Idl/StatementAst.html @@ -103,7 +103,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb
    +
    @@ -126,13 +128,43 @@

    Overview

    -
    -

    Direct Known Subclasses

    -

    ConditionalStatementAst

    +

    Instance Attribute Summary collapse

    +
      + +
    • + + + #action ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
      +

      Returns the value of attribute action.

      +
      + +
    • + + +
    @@ -148,7 +180,7 @@

  • - #action ⇒ Object + #execute(symtab) ⇒ void @@ -162,7 +194,9 @@

    -
    +
    +

    “execute” the statement by updating the variables in the symbol table.

    +

  • @@ -170,7 +204,7 @@

  • - #execute(symtab) ⇒ Object + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object @@ -192,7 +226,33 @@

  • - #to_idl ⇒ Object + #initialize(action) ⇒ StatementAst + + + + + + + constructor + + + + + + + + +
    +

    A new instance of StatementAst.

    +
    + +
  • + + +
  • + + + #prune(symtab) ⇒ Object @@ -208,6 +268,30 @@

    +

  • + + +
  • + + + #to_idl ⇒ String + + + + + + + + + + + + + +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    +
  • @@ -246,42 +330,200 @@

    +
    +

    Constructor Details

    + +
    +

    + #initialize(action) ⇒ StatementAst + + + + + +

    +
    + +

    Returns a new instance of StatementAst.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +2373
    +2374
    +2375
    +2376
    +
    +
    # File 'lib/idl/ast.rb', line 2373
    +
    +def initialize(action)
    +  super(action.input, action.interval, [action])
    +  @action = action
    +end
    +
    +
    + +
    + +
    +

    Instance Attribute Details

    + + + +
    +

    + + #actionObject (readonly) + + + + + +

    +
    + +

    Returns the value of attribute action.

    + + +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +2371
    +2372
    +2373
    +
    +
    # File 'lib/idl/ast.rb', line 2371
    +
    +def action
    +  @action
    +end
    +
    +
    + +
    +

    Instance Method Details

    -

    +

    - #actionObject + #execute(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    “execute” the statement by updating the variables in the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The symbol table for the context

      +
      + +
    • + +
    + +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      ValueError if some part of the statement cannot be executed at compile time

      +
      + +
    • + +
    + +
     
     
    -2198
    +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391
    -
    # File 'lib/idl/ast.rb', line 2198
    +      
    # File 'lib/idl/ast.rb', line 2384
     
    -def action = a
    +def execute(symtab) + if @action.is_a?(Declaration) + @action.add_symbol(symtab) + end + if @action.is_a?(Executable) + @action.execute(symtab) + end +end
    -

    +

    - #execute(symtab) ⇒ Object + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object @@ -293,15 +535,15 @@

     
     
    -2205
    -2206
    -2207
    +66 +67 +68

  • -
    # File 'lib/idl/ast.rb', line 2205
    +      
    # File 'lib/idl/passes/gen_adoc.rb', line 66
     
    -def execute(symtab)
    -  a.execute(symtab)
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  "#{' ' * indent}#{action.gen_adoc(0, indent_spaces:)};"
     end
    @@ -309,9 +551,9 @@

    -

    +

    - #to_idlObject + #prune(symtab) ⇒ Object @@ -323,12 +565,93 @@

     
     
    -2209
    +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88

    + + +
    # File 'lib/idl/passes/prune.rb', line 75
    +
    +def prune(symtab)
    +  s = StatementAst.new(action.prune(symtab))
    +  if s.action.is_a?(Declaration)
    +    s.action.add_symbol(symtab)
    +  end
    +  if (s.action.is_a?(Executable))
    +    begin
    +      s.action.execute(symtab)
    +    rescue ValueError
    +      # ok
    +    end
    +  end
    +  s
    +end
    + + + + + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + +
    +
    +
    +
    +2394
    -
    # File 'lib/idl/ast.rb', line 2209
    +      
    # File 'lib/idl/ast.rb', line 2394
     
    -def to_idl = "#{action.to_idl};"
    +def to_idl = "#{@action.to_idl};"
    @@ -414,15 +737,15 @@

     
     
    -2201
    -2202
    -2203
    +2379 +2380 +2381

    -
    # File 'lib/idl/ast.rb', line 2201
    +      
    # File 'lib/idl/ast.rb', line 2379
     
     def type_check(symtab)
    -  a.type_check(symtab)
    +  @action.type_check(symtab)
     end
    @@ -434,7 +757,7 @@

    diff --git a/docs/ruby/Idl/SymbolTable.html b/docs/ruby/Idl/SymbolTable.html index 42ab969d7..e1df427f2 100644 --- a/docs/ruby/Idl/SymbolTable.html +++ b/docs/ruby/Idl/SymbolTable.html @@ -186,7 +186,9 @@

    -
    +
    +

    add a new symbol at the outermost scope.

    +
    @@ -209,7 +211,7 @@

    -

    add, and make sure name is unique.

    +

    add a new symbol at the outermost scope, unless that symbol is already defined.

    @@ -266,7 +268,31 @@

  • - #deep_clone(clone_values: false) ⇒ Object + #deep_clone(clone_values: false) ⇒ SymbolTable + + + + + + + + + + + + + +
    +

    A deep clone of this SymbolTable.

    +
    + +
  • + + +
  • + + + #find_all(single_scope: false) {|obj| ... } ⇒ Array<Object> @@ -281,7 +307,7 @@

    -

    return a deep clone of this SymbolTable.

    +

    searches the symbol table scope-by-scope to find all entries for which the block returns true.

  • @@ -304,8 +330,56 @@

    +
    +

    searches the symbol table scope-by-scope to find ‘name’.

    +
    + + + + +
  • + + + #get_from(name, level) ⇒ Object + + + + + + + + + + + + +
    +
  • + + +
  • + + + #get_global(name) ⇒ Object + + + + + + + + + + + + + +
    +

    The symbol named ‘name’ from global scope, or nil if not found.

    +
    +
  • @@ -352,7 +426,9 @@

    -
    +
    +

    Whether or not any symbol ‘name’ is defined at any level in the symbol table.

    +
    @@ -360,7 +436,7 @@

  • - #levels ⇒ Object + #keys_pretty ⇒ Object @@ -376,6 +452,30 @@

    +

  • + + +
  • + + + #levels ⇒ Integer + + + + + + + + + + + + + +
    +

    Number of scopes on the symbol table (global at 1).

    +
    +
  • @@ -396,7 +496,9 @@

    -
    +
    +

    pops the top of the scope stack.

    +
    @@ -418,7 +520,9 @@

    -
    +
    +

    pretty-print the symbol table contents.

    +
    @@ -440,7 +544,9 @@

    -
    +
    +

    pushes a new scope.

    +
    @@ -477,26 +583,6 @@

     
     
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
     74
     75
     76
    @@ -549,10 +635,30 @@ 

    123 124 125 -126

    +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146

    -
    # File 'lib/idl/symbol_table.rb', line 54
    +      
    # File 'lib/idl/symbol_table.rb', line 74
     
     def initialize(arch_def)
       @archdef = arch_def
    @@ -665,12 +771,12 @@ 

     
     
    -49
    -50
    -51
    +69 +70 +71

    -
    # File 'lib/idl/symbol_table.rb', line 49
    +      
    # File 'lib/idl/symbol_table.rb', line 69
     
     def archdef
       @archdef
    @@ -696,18 +802,65 @@ 

    -

    +
    +
    + +

    add a new symbol at the outermost scope

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + name + + + (#to_s) + + + + — +
      +

      Symbol name

      +
      + +
    • + +
    • + + var + + + (Object) + + + + — +
      +

      Symbol object (usually a Var or a Type)

      +
      + +
    • + +
    + + +
    + +
     
     
    -154
    -155
    -156
    +226 +227 +228
    -
    # File 'lib/idl/symbol_table.rb', line 154
    +      
    # File 'lib/idl/symbol_table.rb', line 226
     
     def add(name, var)
       @scopes.last[name] = var
    @@ -729,23 +882,64 @@ 

    -

    add, and make sure name is unique

    +

    add a new symbol at the outermost scope, unless that symbol is already defined

    +

    Parameters:

    +
      + +
    • + + name + + + (#to_s) + + + + — +
      +

      Symbol name

      +
      + +
    • + +
    • + + var + + + (Object) + + + + — +
      +

      Symbol object (usually a Var or a Type)

      +
      + +
    • +
    +

    Raises:

    • - (DuplicateSymError) + (DuplicationSymError) + — +
      +

      if ‘name’ is already in the symbol table

      +
      +
    @@ -756,14 +950,14 @@

     
     
    -159
    -160
    -161
    -162
    -163
    +235 +236 +237 +238 +239

    -
    # File 'lib/idl/symbol_table.rb', line 159
    +      
    # File 'lib/idl/symbol_table.rb', line 235
     
     def add!(name, var)
       raise DuplicateSymError, "Symbol #{name} already defined as #{get(name)}" unless @scopes.select { |h| h.key? name }.empty?
    @@ -801,16 +995,16 @@ 

     
     
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    +242 +243 +244 +245 +246 +247 +248

    -
    # File 'lib/idl/symbol_table.rb', line 166
    +      
    # File 'lib/idl/symbol_table.rb', line 242
     
     def add_above!(name, var)
       raise "There is only one scope" if @scopes.size <= 1
    @@ -850,16 +1044,16 @@ 

     
     
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    +251 +252 +253 +254 +255 +256 +257

    -
    # File 'lib/idl/symbol_table.rb', line 175
    +      
    # File 'lib/idl/symbol_table.rb', line 251
     
     def add_at!(level, name, var)
       raise "Level #{level} is too large #{@scopes.size}" if  level >= @scopes.size
    @@ -876,7 +1070,7 @@ 

    - #deep_clone(clone_values: false) ⇒ Object + #deep_clone(clone_values: false) ⇒ SymbolTable @@ -885,13 +1079,31 @@

    -

    return a deep clone of this SymbolTable

    +

    Returns a deep clone of this SymbolTable.

    +

    Returns:

    +
      + +
    • + + + (SymbolTable) + + + + — +
      +

      a deep clone of this SymbolTable

      +
      + +
    • + +
    @@ -899,26 +1111,26 @@

     
     
    -196
    -197
    -198
    -199
    -200
    -201
    -202
    -203
    -204
    -205
    -206
    -207
    -208
    -209
    -210
    -211
    -212
    +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290

    + + +
    -
    # File 'lib/idl/symbol_table.rb', line 196
    +      
    # File 'lib/idl/symbol_table.rb', line 274
     
     def deep_clone(clone_values: false)
       copy = SymbolTable.new(@archdef)
    @@ -943,45 +1155,9 @@ 

    -

    - - #get(name) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -147
    -148
    -149
    -150
    -151
    -152
    -
    -
    # File 'lib/idl/symbol_table.rb', line 147
    -
    -def get(name)
    -  @scopes.reverse_each do |s|
    -    return s[name] if s.key?(name)
    -  end
    -  nil
    -end
    -
    -
    - -
    -

    +

    - #key?(name) ⇒ Boolean + #find_all(single_scope: false) {|obj| ... } ⇒ Array<Object> @@ -990,12 +1166,360 @@

    +

    searches the symbol table scope-by-scope to find all entries for which the block returns true

    +
    +

    Parameters:

    +
      -

      Returns:

      +
    • + + single_scope + + + (Boolean) + + + (defaults to: false) + + + — +
      +

      If true, stop searching more scope as soon as there are matches

      +
      + +
    • + +
    + +

    Yield Parameters:

    +
      + +
    • + + obj + + + (Object) + + + + — +
      +

      A object stored in the symbol table

      +
      + +
    • + +
    +

    Yield Returns:

    +
      + +
    • + + + (Boolean) + + + + — +
      +

      Whether or not the object is the one you are looking for

      +
      + +
    • + +
    +

    Returns:

    +
      + +
    • + + + (Array<Object>) + + + + — +
      +

      All matches

      +
      + +
    • + +
    +

    Raises:

    +
      + +
    • + + + (ArgumentError) + + + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +206
    +207
    +208
    +209
    +210
    +211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +219
    +220
    +
    +
    # File 'lib/idl/symbol_table.rb', line 206
    +
    +def find_all(single_scope: false, &block)
    +  raise ArgumentError, "Block needed" unless block_given?
    +
    +  raise ArgumentError, "Find block takes one argument" unless block.arity == 1
    +
    +  matches = []
    +
    +  @scopes.reverse_each do |s|
    +    s.each_value do |v|
    +      matches << v if yield v
    +    end
    +    break if single_scope && !matches.empty?
    +  end
    +  matches
    +end
    +
    +
    + +
    +

    + + #get(name) ⇒ Object + + + + + +

    +
    + +

    searches the symbol table scope-by-scope to find ‘name’

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Object) + + + + — +
      +

      A symbol named ‘name’, or nil if not found

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +177
    +178
    +179
    +180
    +181
    +182
    +
    +
    # File 'lib/idl/symbol_table.rb', line 177
    +
    +def get(name)
    +  @scopes.reverse_each do |s|
    +    return s[name] if s.key?(name)
    +  end
    +  nil
    +end
    +
    +
    + +
    +

    + + #get_from(name, level) ⇒ Object + + + + + +

    +
    + + +
    +
    +
    + +

    Raises:

    +
      + +
    • + + + (ArgumentError) + + + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +184
    +185
    +186
    +187
    +188
    +189
    +190
    +191
    +192
    +193
    +
    +
    # File 'lib/idl/symbol_table.rb', line 184
    +
    +def get_from(name, level)
    +  raise ArgumentError, "level must be positive" unless level.positive?
    +
    +  raise "There is no level #{level}" unless level < levels
    +
    +  @scopes[0..level - 1].reverse_each do |s|
    +    return s[name] if s.key?(name)
    +  end
    +  nil
    +end
    +
    +
    + +
    +

    + + #get_global(name) ⇒ Object + + + + + +

    +
    + +

    Returns the symbol named ‘name’ from global scope, or nil if not found.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Object) + + + + — +
      +

      the symbol named ‘name’ from global scope, or nil if not found

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +196
    +197
    +198
    +
    +
    # File 'lib/idl/symbol_table.rb', line 196
    +
    +def get_global(name)
    +  get_from(name, 1)
    +end
    +
    +
    + +
    +

    + + #key?(name) ⇒ Boolean + + + + + +

    +
    + +

    Returns whether or not any symbol ‘name’ is defined at any level in the symbol table.

    + + +
    +
    +
    + +

    Returns:

    • @@ -1005,6 +1529,11 @@

      + — +
      +

      whether or not any symbol ‘name’ is defined at any level in the symbol table

      +
      +

    @@ -1015,12 +1544,12 @@

     
     
    -143
    -144
    -145
    +166 +167 +168

    -
    # File 'lib/idl/symbol_table.rb', line 143
    +      
    # File 'lib/idl/symbol_table.rb', line 166
     
     def key?(name)
       @scopes.each { |s| return true if s.key?(name) }
    @@ -1031,9 +1560,9 @@ 

    -

    +

    - #levelsObject + #keys_prettyObject @@ -1045,12 +1574,71 @@

     
     
    -183
    -184
    -185
    +170 +171 +172

    +
    +
    # File 'lib/idl/symbol_table.rb', line 170
    +
    +def keys_pretty
    +  @scopes.map { |s| s.map { |k, v| v.is_a?(Var) && v.template_val? ? "#{k} (template)" : k }}
    +end
    +
    +
    + +
    +

    + + #levelsInteger + + + + + +

    +
    + +

    Returns Number of scopes on the symbol table (global at 1).

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Integer) + + + + — +
      +

      Number of scopes on the symbol table (global at 1)

      +
      + +
    • + +
    + +
    + + @@ -291,12 +291,12 @@

     
     
    -2699
    -2700
    -2701
    +3058 +3059 +3060

    @@ -276,14 +305,14 @@

     
     
    -2168
    -2169
    -2170
    -2171
    -2172
    +2319 +2320 +2321 +2322 +2323

    +
    +
    +
    +260
    +261
    +262
    -
    # File 'lib/idl/symbol_table.rb', line 183
    +      
    # File 'lib/idl/symbol_table.rb', line 260
     
     def levels
       @scopes.size
    @@ -1069,27 +1657,38 @@ 

    -

    +
    +
    + +

    pops the top of the scope stack

    + + +
    +
    +
    + + +
    @@ -541,19 +570,19 @@

     
     
    -2013
    -2014
    -2015
    -2016
    -2017
    -2018
    -2019
    -2020
    -2021
    -2022
    +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166

     
     
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    +157 +158 +159 +160 +161 +162 +163
    -
    # File 'lib/idl/symbol_table.rb', line 135
    +      
    # File 'lib/idl/symbol_table.rb', line 157
     
     def pop
       # puts "pop #{caller[0]}"
       # puts "    from #{@scope_caller.pop}"
    -  raise 'Error: popping the symbol table would remove global scope' if @scopes.size == 1
    +  raise "Error: popping the symbol table would remove global scope" if @scopes.size == 1
     
       @scopes.pop
     end
    @@ -1107,22 +1706,33 @@ +
    +
    + +

    pretty-print the symbol table contents

    + + +
    +
    +
    + + +
     
     
    -187
    -188
    -189
    -190
    -191
    -192
    -193
    +265 +266 +267 +268 +269 +270 +271
    -
    # File 'lib/idl/symbol_table.rb', line 187
    +      
    # File 'lib/idl/symbol_table.rb', line 265
     
     def print
       @scopes.each do |s|
    @@ -1145,21 +1755,32 @@ 

    -

    +
    +
    + +

    pushes a new scope

    + + +
    +
    +
    + + +
    @@ -449,12 +473,12 @@

     
     
    -2138
    -2139
    -2140
    +2282 +2283 +2284

     
     
    -128
    -129
    -130
    -131
    -132
    -133
    +149 +150 +151 +152 +153 +154
    -
    # File 'lib/idl/symbol_table.rb', line 128
    +      
    # File 'lib/idl/symbol_table.rb', line 149
     
     def push
       # puts "push #{caller[0]}"
    @@ -1177,7 +1798,7 @@ 

    diff --git a/docs/ruby/Idl/SymbolTable/DuplicateSymError.html b/docs/ruby/Idl/SymbolTable/DuplicateSymError.html index 302a3cf00..bf7b40dd7 100644 --- a/docs/ruby/Idl/SymbolTable/DuplicateSymError.html +++ b/docs/ruby/Idl/SymbolTable/DuplicateSymError.html @@ -114,7 +114,7 @@ diff --git a/docs/ruby/Idl/TernaryOperatorExpressionAst.html b/docs/ruby/Idl/TernaryOperatorExpressionAst.html index 6601a91c3..050c7a9ad 100644 --- a/docs/ruby/Idl/TernaryOperatorExpressionAst.html +++ b/docs/ruby/Idl/TernaryOperatorExpressionAst.html @@ -299,6 +299,30 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -334,12 +358,12 @@

     
     
    -2134
    -2135
    -2136
    +2278 +2279 +2280

    -
    # File 'lib/idl/ast.rb', line 2134
    +      
    # File 'lib/idl/ast.rb', line 2278
     
     def condition
       p9_binary_expression
    @@ -364,12 +388,12 @@ 

     
     
    -2142
    -2143
    -2144
    +2286 +2287 +2288

    -
    # File 'lib/idl/ast.rb', line 2142
    +      
    # File 'lib/idl/ast.rb', line 2286
     
     def false_expression
       f
    @@ -423,10 +447,10 @@ 

     
     
    -2152
    +2303

    -
    # File 'lib/idl/ast.rb', line 2152
    +      
    # File 'lib/idl/ast.rb', line 2303
     
     def to_idl = "#{condition.to_idl} ? #{true_expression.to_idl} : #{false_expression.to_idl}"
    -
    # File 'lib/idl/ast.rb', line 2138
    +      
    # File 'lib/idl/ast.rb', line 2282
     
     def true_expression
       t
    @@ -548,27 +572,27 @@ 

     
     
    -2115
    -2116
    -2117
    -2118
    -2119
    -2120
    -2121
    -2122
    -2123
    -2124
    -2125
    -2126
    -2127
    -2128
    -2129
    -2130
    -2131
    -2132
    +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276

    -
    # File 'lib/idl/ast.rb', line 2115
    +      
    # File 'lib/idl/ast.rb', line 2259
     
     def type(symtab)
       p9_binary_expression.type_check(symtab)
    @@ -673,35 +697,35 @@ 

     
     
    -2087
    -2088
    -2089
    -2090
    -2091
    -2092
    -2093
    -2094
    -2095
    -2096
    -2097
    -2098
    -2099
    -2100
    -2101
    -2102
    -2103
    -2104
    -2105
    -2106
    -2107
    -2108
    -2109
    -2110
    -2111
    -2112
    +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256

    -
    # File 'lib/idl/ast.rb', line 2087
    +      
    # File 'lib/idl/ast.rb', line 2231
     
     def type_check(symtab)
       p9_binary_expression.type_check(symtab)
    @@ -760,12 +784,12 @@ 

     
     
    -2147
    -2148
    -2149
    +2291 +2292 +2293

    -
    # File 'lib/idl/ast.rb', line 2147
    +      
    # File 'lib/idl/ast.rb', line 2291
     
     def value(symtab)
       condition.value(symtab) ? t.value(symtab) : f.value(symtab)
    @@ -773,6 +797,119 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +2296
    +2297
    +2298
    +2299
    +2300
    +
    +
    # File 'lib/idl/ast.rb', line 2296
    +
    +def values(symtab)
    +  condition.value(symtab) ? t.values(symtab) : f.values(symtab)
    +rescue ValueError
    +  (t.values(symtab) + f.values(symtab)).uniq
    +end
    +
    @@ -780,7 +917,7 @@

    diff --git a/docs/ruby/Idl/Type.html b/docs/ruby/Idl/Type.html index b9d1c7f92..81b7218c4 100644 --- a/docs/ruby/Idl/Type.html +++ b/docs/ruby/Idl/Type.html @@ -112,7 +112,7 @@

    Overview

    @@ -569,6 +569,28 @@

    returns true if self can be converted to ‘type’ ‘type’ can be a Type object or a kind (as a Symbol).

    + + + +
  • + + + #default ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -878,17 +900,6 @@

     
     
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
     62
     63
     64
    @@ -923,10 +934,21 @@ 

    93 94 95 -96

    +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107

    -
    # File 'lib/idl/type.rb', line 51
    +      
    # File 'lib/idl/type.rb', line 62
     
     def initialize(kind, qualifiers: [], width: nil, sub_type: nil, name: nil, tuple_types: nil, return_type: nil, arguments: nil, enum_class: nil, csr: nil)
       raise "Invalid kind '#{kind}'" unless KINDS.include?(kind)
    @@ -1012,12 +1034,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def arguments
       @arguments
    @@ -1055,12 +1077,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def enum_class
       @enum_class
    @@ -1098,12 +1120,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def kind
       @kind
    @@ -1141,12 +1163,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def qualifiers
       @qualifiers
    @@ -1184,12 +1206,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def return_type
       @return_type
    @@ -1227,12 +1249,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def sub_type
       @sub_type
    @@ -1270,12 +1292,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def tuple_types
       @tuple_types
    @@ -1313,12 +1335,12 @@ 

     
     
    -30
    -31
    -32
    +41 +42 +43

    -
    # File 'lib/idl/type.rb', line 30
    +      
    # File 'lib/idl/type.rb', line 41
     
     def width
       @width
    @@ -1350,21 +1372,21 @@ 

     
     
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60

    -
    # File 'lib/idl/type.rb', line 38
    +      
    # File 'lib/idl/type.rb', line 49
     
     def self.from_typename(type_name, arch_def)
       case type_name
    @@ -1426,12 +1448,12 @@ 

     
     
    -315
    -316
    -317
    +326 +327 +328

    -
    # File 'lib/idl/type.rb', line 315
    +      
    # File 'lib/idl/type.rb', line 326
     
     def ary?
       @kind == :array
    @@ -1467,16 +1489,16 @@ 

     
     
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    +178 +179 +180 +181 +182 +183 +184

    -
    # File 'lib/idl/type.rb', line 167
    +      
    # File 'lib/idl/type.rb', line 178
     
     def ary_type(ary)
       if ary.sub_type == :array
    @@ -1505,23 +1527,23 @@ 

     
     
    -98
    -99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
     109
     110
    -111
    +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122

    -
    # File 'lib/idl/type.rb', line 98
    +      
    # File 'lib/idl/type.rb', line 109
     
     def clone
       Type.new(
    @@ -1581,17 +1603,6 @@ 

     
     
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
     126
     127
     128
    @@ -1608,10 +1619,21 @@ 

    139 140 141 -142

    +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153

    -
    # File 'lib/idl/type.rb', line 115
    +      
    # File 'lib/idl/type.rb', line 126
     
     def comparable_to?(type)
       if type.is_a?(Symbol)
    @@ -1683,12 +1705,12 @@ 

     
     
    -319
    -320
    -321
    +330 +331 +332

    -
    # File 'lib/idl/type.rb', line 319
    +      
    # File 'lib/idl/type.rb', line 330
     
     def const?
       @qualifiers.include?(:const)
    @@ -1737,17 +1759,6 @@ 

     
     
    -177
    -178
    -179
    -180
    -181
    -182
    -183
    -184
    -185
    -186
    -187
     188
     189
     190
    @@ -1793,10 +1804,21 @@ 

    230 231 232 -233

    +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244

    -
    # File 'lib/idl/type.rb', line 177
    +      
    # File 'lib/idl/type.rb', line 188
     
     def convertable_to?(type)
       if type.is_a?(Symbol)
    @@ -1858,6 +1880,50 @@ 

    + + +
    +

    + + #defaultObject + + + + + +

    + + + + +
    +
    +
    +
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +
    +
    # File 'lib/idl/type.rb', line 30
    +
    +def default
    +  case @kind
    +  when :bits, :enum_ref, :bitfield
    +    0
    +  when :boolean
    +    false
    +  else
    +    raise "No default for #{@kind}"
    +  end
    +end
    +
    @@ -1899,17 +1965,6 @@

     
     
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
     156
     157
     158
    @@ -1918,10 +1973,21 @@ 

    161 162 163 -164

    +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175

    -
    # File 'lib/idl/type.rb', line 145
    +      
    # File 'lib/idl/type.rb', line 156
     
     def equal_to?(type)
       if type.is_a?(Symbol)
    @@ -2017,13 +2083,13 @@ 

     
     
    -336
    -337
    -338
    -339
    +347 +348 +349 +350

    -
    # File 'lib/idl/type.rb', line 336
    +      
    # File 'lib/idl/type.rb', line 347
     
     def make_const
       @qualifiers.append(:const).uniq!
    @@ -2049,13 +2115,13 @@ 

     
     
    -331
    -332
    -333
    -334
    +342 +343 +344 +345

    -
    # File 'lib/idl/type.rb', line 331
    +      
    # File 'lib/idl/type.rb', line 342
     
     def make_signed
       @qualifiers.append(:signed).uniq!
    @@ -2103,12 +2169,12 @@ 

     
     
    -323
    -324
    -325
    +334 +335 +336

    -
    # File 'lib/idl/type.rb', line 323
    +      
    # File 'lib/idl/type.rb', line 334
     
     def mutable?
       return !const?
    @@ -2133,26 +2199,26 @@ 

     
     
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
     308
     309
     310
     311
     312
    -313
    +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324

    -
    # File 'lib/idl/type.rb', line 297
    +      
    # File 'lib/idl/type.rb', line 308
     
     def name
       if @kind == :bits
    @@ -2191,14 +2257,14 @@ 

     
     
    -32
    -33
    -34
    -35
    -36
    +43 +44 +45 +46 +47

    -
    # File 'lib/idl/type.rb', line 32
    +      
    # File 'lib/idl/type.rb', line 43
     
     def qualify(qualifier)
       @qualifiers << qualifier
    @@ -2247,12 +2313,12 @@ 

     
     
    -327
    -328
    -329
    +338 +339 +340

    -
    # File 'lib/idl/type.rb', line 327
    +      
    # File 'lib/idl/type.rb', line 338
     
     def signed?
       @qualifiers.include?(:signed)
    @@ -2277,13 +2343,13 @@ 

     
     
    -292
    -293
    -294
    -295
    +303 +304 +305 +306

    -
    # File 'lib/idl/type.rb', line 292
    +      
    # File 'lib/idl/type.rb', line 303
     
     def to_cxx
       ((@qualifiers.nil? || @qualifiers.empty?) ? '' : "#{@qualifiers.include?(:const) ? 'const' : ''} ") + \
    @@ -2309,17 +2375,6 @@ 

     
     
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
     274
     275
     276
    @@ -2336,10 +2391,21 @@ 

    287 288 289 -290

    +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301

    -
    # File 'lib/idl/type.rb', line 263
    +      
    # File 'lib/idl/type.rb', line 274
     
     def to_cxx_no_qualifiers
         if @kind == :bits
    @@ -2393,17 +2459,6 @@ 

     
     
    -235
    -236
    -237
    -238
    -239
    -240
    -241
    -242
    -243
    -244
    -245
     246
     247
     248
    @@ -2418,10 +2473,21 @@ 

    257 258 259 -260

    +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271

    -
    # File 'lib/idl/type.rb', line 235
    +      
    # File 'lib/idl/type.rb', line 246
     
     def to_s
       ((@qualifiers.nil? || @qualifiers.empty?) ? '' : "#{@qualifiers.map(&:to_s).join(' ')} ") + \
    @@ -2459,7 +2525,7 @@ 

    diff --git a/docs/ruby/Idl/UnaryOperatorExpressionAst.html b/docs/ruby/Idl/UnaryOperatorExpressionAst.html index 7fecbe0f7..6b1e9ae87 100644 --- a/docs/ruby/Idl/UnaryOperatorExpressionAst.html +++ b/docs/ruby/Idl/UnaryOperatorExpressionAst.html @@ -282,6 +282,35 @@

    Return the compile-time-known value of the node.

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -328,12 +357,12 @@

     
     
    -2065
    -2066
    -2067
    +2209 +2210 +2211

    -
    # File 'lib/idl/ast.rb', line 2065
    +      
    # File 'lib/idl/ast.rb', line 2209
     
     def exp
       e
    @@ -387,12 +416,12 @@ 

     
     
    -2070
    -2071
    -2072
    +2214 +2215 +2216

    -
    # File 'lib/idl/ast.rb', line 2070
    +      
    # File 'lib/idl/ast.rb', line 2214
     
     def op
       o.text_value
    @@ -446,10 +475,10 @@ 

     
     
    -2075
    +2219

    -
    # File 'lib/idl/ast.rb', line 2075
    +      
    # File 'lib/idl/ast.rb', line 2219
     
     def to_idl = "#{op}#{e.to_idl}"
    -
    # File 'lib/idl/ast.rb', line 2013
    +      
    # File 'lib/idl/ast.rb', line 2157
     
     def type(symtab)
       case op
    @@ -650,31 +679,31 @@ 

     
     
    -2025
    -2026
    -2027
    -2028
    -2029
    -2030
    -2031
    -2032
    -2033
    -2034
    -2035
    -2036
    -2037
    -2038
    -2039
    -2040
    -2041
    -2042
    -2043
    -2044
    -2045
    -2046
    +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190

    -
    # File 'lib/idl/ast.rb', line 2025
    +      
    # File 'lib/idl/ast.rb', line 2169
     
     def type_check(symtab)
       exp.type_check(symtab)
    @@ -729,23 +758,23 @@ 

     
     
    -2049
    -2050
    -2051
    -2052
    -2053
    -2054
    -2055
    -2056
    -2057
    -2058
    -2059
    -2060
    -2061
    -2062
    +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206

    -
    # File 'lib/idl/ast.rb', line 2049
    +      
    # File 'lib/idl/ast.rb', line 2193
     
     def value(symtab)
       val = eval("#{op}#{exp.value(symtab)}", binding, __FILE__, __LINE__)
    @@ -764,6 +793,102 @@ 

    + + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -771,7 +896,7 @@

    diff --git a/docs/ruby/Idl/UserTypeNameAst.html b/docs/ruby/Idl/UserTypeNameAst.html index 1503f2d68..bb5731910 100644 --- a/docs/ruby/Idl/UserTypeNameAst.html +++ b/docs/ruby/Idl/UserTypeNameAst.html @@ -265,10 +265,10 @@

     
     
    -2704
    +3063

    -
    # File 'lib/idl/ast.rb', line 2704
    +      
    # File 'lib/idl/ast.rb', line 3063
     
     def to_idl = text_value
    -
    # File 'lib/idl/ast.rb', line 2699
    +      
    # File 'lib/idl/ast.rb', line 3058
     
     def type(symtab)
       symtab.get(text_value)
    @@ -386,14 +386,14 @@ 

     
     
    -2692
    -2693
    -2694
    -2695
    -2696
    +3051 +3052 +3053 +3054 +3055

    -
    # File 'lib/idl/ast.rb', line 2692
    +      
    # File 'lib/idl/ast.rb', line 3051
     
     def type_check(symtab)
       type = symtab.get(text_value)
    @@ -410,7 +410,7 @@ 

    diff --git a/docs/ruby/Idl/Var.html b/docs/ruby/Idl/Var.html index 6bcbe39d4..a8a19b627 100644 --- a/docs/ruby/Idl/Var.html +++ b/docs/ruby/Idl/Var.html @@ -284,7 +284,7 @@

  • - #initialize(name, type, value = nil, decode_var: false) ⇒ Var + #initialize(name, type, value = nil, decode_var: false, template_index: nil, function_name: nil) ⇒ Var @@ -304,6 +304,76 @@

    A new instance of Var.

    +

  • + + +
  • + + + #template_index ⇒ Integer + + + + + + + + + + + + + +
    +

    The template value position.

    +
    + +
  • + + +
  • + + + #template_val? ⇒ Boolean + + + + + + + + + + + + + +
    + +
  • + + +
  • + + + #template_value_for?(function_name) ⇒ Boolean + + + + + + + + + + + + + +
    +

    Whether or not this variable is a function template argument from a call site for the function ‘function_name’.

    +
    +
  • @@ -338,7 +408,7 @@

    Constructor Details

    - #initialize(name, type, value = nil, decode_var: false) ⇒ Var + #initialize(name, type, value = nil, decode_var: false, template_index: nil, function_name: nil) ⇒ Var @@ -354,6 +424,19 @@

    +

    Raises:

    +
      + +
    • + + + (ArgumentError) + + + +
    • + +
    @@ -370,20 +453,24 @@

    16 17 18 -19 +19 +20 +21

    @@ -546,17 +633,17 @@

     
     
    -21
    -22
     23
     24
     25
     26
     27
    -28
    +28 +29 +30

    # File 'lib/idl/symbol_table.rb', line 10
     
    -def initialize(name, type, value = nil, decode_var: false)
    +def initialize(name, type, value = nil, decode_var: false, template_index: nil, function_name: nil)
       @name = name
    -  raise 'unexpected' unless type.is_a?(Type)
    +  raise ArgumentError, "Expecting a Type, got #{type.class.name}" unless type.is_a?(Type)
     
       @type = type
       @value = value
       raise 'unexpected' unless decode_var.is_a?(TrueClass) || decode_var.is_a?(FalseClass)
     
       @decode_var = decode_var
    +  @template_index = template_index
    +  @function_name = function_name
     end
    -
    # File 'lib/idl/symbol_table.rb', line 21
    +      
    # File 'lib/idl/symbol_table.rb', line 23
     
     def clone
       Var.new(
    @@ -608,12 +695,12 @@ 

     
     
    -30
    -31
    -32
    +32 +33 +34

    -
    # File 'lib/idl/symbol_table.rb', line 30
    +      
    # File 'lib/idl/symbol_table.rb', line 32
     
     def const?
       @type.const?
    @@ -660,12 +747,12 @@ 

     
     
    -34
    -35
    -36
    +36 +37 +38

    -
    # File 'lib/idl/symbol_table.rb', line 34
    +      
    # File 'lib/idl/symbol_table.rb', line 36
     
     def decode_var?
       @decode_var
    @@ -673,6 +760,218 @@ 

    + + +
    +

    + + #template_indexInteger + + + + + +

    +
    + +

    Returns the template value position.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Integer) + + + + — +
      +

      the template value position

      +
      + +
    • + +
    +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      if Var is not a template value

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +48
    +49
    +50
    +51
    +52
    +
    +
    # File 'lib/idl/symbol_table.rb', line 48
    +
    +def template_index
    +  raise "Not a template value" if @template_index.nil?
    +
    +  @template_index
    +end
    +
    +
    + +
    +

    + + #template_val?Boolean + + + + + +

    +
    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (Boolean) + + + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +54
    +55
    +56
    +
    +
    # File 'lib/idl/symbol_table.rb', line 54
    +
    +def template_val?
    +  !@template_index.nil?
    +end
    +
    +
    + +
    +

    + + #template_value_for?(function_name) ⇒ Boolean + + + + + +

    +
    + +

    Returns whether or not this variable is a function template argument from a call site for the function ‘function_name’.

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + function_name + + + (#to_s) + + + + — +
      +

      A function name

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Boolean) + + + + — +
      +

      whether or not this variable is a function template argument from a call site for the function ‘function_name’

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +42
    +43
    +44
    +
    +
    # File 'lib/idl/symbol_table.rb', line 42
    +
    +def template_value_for?(function_name)
    +  !@template_index.nil? && (function_name.to_s == @function_name)
    +end
    +
    @@ -690,12 +989,12 @@

     
     
    -38
    -39
    -40
    +58 +59 +60

    -
    # File 'lib/idl/symbol_table.rb', line 38
    +      
    # File 'lib/idl/symbol_table.rb', line 58
     
     def to_cxx
       @name
    @@ -710,7 +1009,7 @@ 

    diff --git a/docs/ruby/Idl/VarReadExpressionAst.html b/docs/ruby/Idl/VarReadExpressionAst.html index a467df070..ac52995b4 100644 --- a/docs/ruby/Idl/VarReadExpressionAst.html +++ b/docs/ruby/Idl/VarReadExpressionAst.html @@ -192,6 +192,35 @@

    + + + +
  • + + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + included + from Rvalue + + + + + + + + + + +
    +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined.

    +
    +
  • @@ -250,10 +279,10 @@

     
     
    -2186
    +2337

    -
    # File 'lib/idl/ast.rb', line 2186
    +      
    # File 'lib/idl/ast.rb', line 2337
     
     def to_idl = text_value
    -
    # File 'lib/idl/ast.rb', line 2168
    +      
    # File 'lib/idl/ast.rb', line 2319
     
     def type(symtab)
       internal_error "While checking VarRead type, no symbol '#{text_value}' found" if symtab.get(text_value).nil?
    @@ -375,16 +404,16 @@ 

     
     
    -2159
    -2160
    -2161
    -2162
    -2163
    -2164
    -2165
    +2310 +2311 +2312 +2313 +2314 +2315 +2316

    -
    # File 'lib/idl/ast.rb', line 2159
    +      
    # File 'lib/idl/ast.rb', line 2310
     
     def type_check(symtab)
       var = symtab.get(text_value)
    @@ -413,23 +442,23 @@ 

     
     
    -2175
    -2176
    -2177
    -2178
    -2179
    -2180
    -2181
    -2182
    -2183
    +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334

    -
    # File 'lib/idl/ast.rb', line 2175
    +      
    # File 'lib/idl/ast.rb', line 2326
     
     def value(symtab)
       var = symtab.get(text_value)
     
    -  internal_error "Call type_check first" if var.nil?
    +  internal_error "Cannot find variable #{text_value}" if var.nil?
     
       value_error "The value of '#{text_value}' is not known" if var.value.nil?
       
    @@ -438,6 +467,102 @@ 

    +
    + +
    +

    + + #values(symtab) ⇒ Array<Integer>, ... + + + + + + + Originally defined in module + Rvalue + + +

    +
    + +

    Return a complete list of possible compile-time-known values of the node, or raise a ValueError if the full list cannot be determined

    + +

    For most AstNodes, this will just be a single-entry array

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The context for the evaulation

      +
      + +
    • + +
    + +

    Returns:

    +
      + +
    • + + + (Array<Integer>) + + + + — +
      +

      The complete list of compile-time-known values, when they are integral

      +
      + +
    • + +
    • + + + (Array<Boolean>) + + + + — +
      +

      The complete list of compile-time-known values, when they are booleans

      +
      + +
    • + +
    • + + + (AstNode::ValueError) + + + + — +
      +

      if the list of values is not knowable at compile time

      +
      + +
    • + +
    + +
    @@ -445,7 +570,7 @@

    diff --git a/docs/ruby/Idl/VariableAssignmentAst.html b/docs/ruby/Idl/VariableAssignmentAst.html index 6124d35d7..195cdc959 100644 --- a/docs/ruby/Idl/VariableAssignmentAst.html +++ b/docs/ruby/Idl/VariableAssignmentAst.html @@ -100,7 +100,9 @@
    Defined in:
    -
    lib/idl/ast.rb
    +
    lib/idl/ast.rb,
    + lib/idl/passes/gen_adoc.rb
    +
    @@ -154,6 +156,28 @@

    +
    + + + + +
  • + + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + + + + + + + + +
  • @@ -285,23 +309,61 @@

     
     
    -944
    -945
    -946
    -947
    -948
    -949
    -950
    +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993

    -
    # File 'lib/idl/ast.rb', line 944
    +      
    # File 'lib/idl/ast.rb', line 983
     
     def execute(symtab)
    -  var = symtab.get(var.text_value)
    +  if var.is_a?(CsrWriteAst)
    +    value_error "CSR writes are never compile-time-known"
    +  else
    +    variable = symtab.get(var.text_value)
    +
    +    internal_error "No variable #{var.text_value}" if variable.nil?
     
    -  internal_error "Call type check first" if var.nil?
    +    variable.value = rval.value(symtab)
    +  end
    +end
    +
    + + +
    +

    + + #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object + + + + + +

    + + + @@ -323,12 +385,12 @@

     
     
    -936
    -937
    -938
    +975 +976 +977

    @@ -503,16 +565,16 @@

     
     
    -928
    -929
    -930
    -931
    -932
    -933
    -934
    +967 +968 +969 +970 +971 +972 +973

    +
    +
    +
    +60
    +61
    +62
    +
    +
    # File 'lib/idl/passes/gen_adoc.rb', line 60
     
    -  var.value = rval.value(symtab)
    +def gen_adoc(indent = 0, indent_spaces: 2)
    +  "#{var.gen_adoc(0, indent_spaces:)} = #{rval.gen_adoc(0, indent_spaces:)}"
     end
    -
    # File 'lib/idl/ast.rb', line 936
    +      
    # File 'lib/idl/ast.rb', line 975
     
     def lhs
       var
    @@ -353,12 +415,12 @@ 

     
     
    -940
    -941
    -942
    +979 +980 +981

    -
    # File 'lib/idl/ast.rb', line 940
    +      
    # File 'lib/idl/ast.rb', line 979
     
     def rhs
       rval
    @@ -412,10 +474,10 @@ 

     
     
    -953
    +996

    -
    # File 'lib/idl/ast.rb', line 953
    +      
    # File 'lib/idl/ast.rb', line 996
     
     def to_idl = "#{var.to_idl} = #{rval.to_idl}"
    -
    # File 'lib/idl/ast.rb', line 928
    +      
    # File 'lib/idl/ast.rb', line 967
     
     def type_check(symtab)
       var.type_check(symtab)
    @@ -531,7 +593,7 @@ 

    diff --git a/docs/ruby/Idl/VariableDeclarationAst.html b/docs/ruby/Idl/VariableDeclarationAst.html index fb9e56c55..13953ff20 100644 --- a/docs/ruby/Idl/VariableDeclarationAst.html +++ b/docs/ruby/Idl/VariableDeclarationAst.html @@ -93,7 +93,7 @@
    Includes:
    -
    Executable
    +
    Declaration
    @@ -143,7 +143,7 @@

  • - #decl_type(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object @@ -157,7 +157,9 @@

    -
    +
    +

    Add symbol(s) at the outermost scope of the symbol table.

    +

  • @@ -165,7 +167,7 @@

  • - #execute(symtab) ⇒ Object + #decl_type(symtab) ⇒ Object @@ -250,53 +252,60 @@

    Instance Method Details

    -

    +

    - #decl_type(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object -

    +
    +
    + +

    Add symbol(s) at the outermost scope of the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table at the scope that the symbol(s) will be inserted

      +
      + +
    • + +
    + + +
    @@ -304,9 +313,9 @@

    -

    +

    - #execute(symtab) ⇒ Object + #decl_type(symtab) ⇒ Object @@ -318,17 +327,53 @@

     
     
    -1334
    -1335
    -1336
    -1337
    +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360

    @@ -379,22 +424,22 @@

     
     
    -1340
    -1341
    -1342
    -1343
    -1344
    -1345
    -1346
    +1391 +1392 +1393 +1394 +1395 +1396 +1397

    @@ -482,30 +527,30 @@

     
     
    -1312
    -1313
    -1314
    -1315
    -1316
    -1317
    -1318
    -1319
    -1320
    -1321
    -1322
    -1323
    -1324
    -1325
    -1326
    -1327
    -1328
    -1329
    -1330
    -1331
    -1332
    +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383

    @@ -872,12 +848,12 @@

     
     
    -77
    -78
    -79
    +59 +60 +61

     
     
    -1295
    -1296
    -1297
    -1298
    -1299
    -1300
    -1301
    -1302
    -1303
    -1304
    -1305
    -1306
    -1307
    -1308
    -1309
    +1386 +1387 +1388
    -
    # File 'lib/idl/ast.rb', line 1295
    -
    -def decl_type(symtab)
    -  dtype = type_name.type(symtab)
    -
    -  return nil if dtype.nil?
    -
    -  dtype = Type.new(:enum_ref, enum_class: dtype) if dtype.kind == :enum
    -
    -  dtype = dtype.clone.qualify(q.text_value.to_sym) unless q.empty?
    -
    -  unless ary_size.empty?
    -    dtype = Type.new(:array, width: ary_size.expression.value(symtab), sub_type: dtype.clone)
    -  end
    +      
    # File 'lib/idl/ast.rb', line 1386
     
    -  dtype
    +def add_symbol(symtab)
    +  symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab), decl_type(symtab).default))
     end
    -
    # File 'lib/idl/ast.rb', line 1334
    +      
    # File 'lib/idl/ast.rb', line 1339
    +
    +def decl_type(symtab)
    +  dtype = type_name.type(symtab)
    +
    +  return nil if dtype.nil?
    +
    +  qualifiers =
    +    if var_write.text_value[0].upcase == var_write.text_value[0]
    +      [:const]
    +    else
    +      []
    +    end
    +
    +  dtype = Type.new(:enum_ref, enum_class: dtype, qualifiers:) if dtype.kind == :enum
     
    -def execute(symtab)
    -  value_error "TODO: array declration execution" unless ary_size.empty?
    -  symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab)))
    +  dtype = dtype.clone.qualify(q.text_value.to_sym) unless q.empty?
    +
    +  unless ary_size.empty?
    +    dtype = Type.new(:array, width: ary_size.expression.value(symtab), sub_type: dtype.clone, qualifiers:)
    +  end
    +
    +  dtype
     end
    -
    # File 'lib/idl/ast.rb', line 1340
    +      
    # File 'lib/idl/ast.rb', line 1391
     
     def to_idl
       if ary_size.empty?
    -    "#{type.to_idl} #{var_write.to_idl}"
    +    "#{type_name.to_idl} #{var_write.to_idl}"
       else
    -    "#{type.to_idl} #{var_write.to_idl}[#{ary_size.expression.to_idl}]"
    +    "#{type_name.to_idl} #{var_write.to_idl}[#{ary_size.expression.to_idl}]"
       end
     end
    -
    # File 'lib/idl/ast.rb', line 1312
    +      
    # File 'lib/idl/ast.rb', line 1363
     
     def type_check(symtab)
       type_name.type_check(symtab)
    @@ -524,7 +569,7 @@ 

    end end - symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab))) + add_symbol(symtab) var_write.type_check(symtab) end

    @@ -538,7 +583,7 @@

    diff --git a/docs/ruby/Idl/VariableDeclarationWithInitializationAst.html b/docs/ruby/Idl/VariableDeclarationWithInitializationAst.html index e104fd190..663f76c9a 100644 --- a/docs/ruby/Idl/VariableDeclarationWithInitializationAst.html +++ b/docs/ruby/Idl/VariableDeclarationWithInitializationAst.html @@ -95,7 +95,7 @@
    Includes:
    -
    Executable
    +
    Declaration, Executable
    @@ -145,7 +145,7 @@

  • - #execute(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object @@ -159,7 +159,33 @@

    -
    +
    +

    Add symbol(s) at the outermost scope of the symbol table.

    +
    + +

  • + + +
  • + + + #execute(symtab) ⇒ void + + + + + + + + + + + + + +
    +

    “execute” the statement by updating the variables in the symbol table.

    +
  • @@ -233,7 +259,7 @@

  • - #type_check(symtab) ⇒ Object + #to_idl ⇒ String @@ -247,7 +273,33 @@

    -
    +
    +

    Return valid IDL representation of the node (and its subtree).

    +
    + +

  • + + +
  • + + + #type_check(symtab) ⇒ void + + + + + + + + + + + + + +
    +

    type check this node and all children.

    +
  • @@ -266,33 +318,149 @@

    + +

    Instance Method Details

    -

    +

    - #execute(symtab) ⇒ Object + #add_symbol(symtab) ⇒ Object -

    +
    +
    + +

    Add symbol(s) at the outermost scope of the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table at the scope that the symbol(s) will be inserted

      +
      + +
    • + +
    + + +
    + + +
     
     
    -1420
    -1421
    -1422
    -1423
    +1474 +1475 +1476 +1477 +1478 +
    +
    # File 'lib/idl/ast.rb', line 1474
    +
    +def add_symbol(symtab)
    +  symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs.value(symtab)))
    +rescue ValueError
    +  symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab)))
    +end
    +
    +
    + +
    +

    + + #execute(symtab) ⇒ void + + + + + +

    +
    +

    This method returns an undefined value.

    +

    “execute” the statement by updating the variables in the symbol table

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      The symbol table for the context

      +
      + +
    • + +
    + +

    Raises:

    +
      + +
    • + + + + + + + +
      +

      ValueError if some part of the statement cannot be executed at compile time

      +
      + +
    • + +
    + +
    + +
    +
    +
    +
    +1481
    +1482
    +1483
    +1484
    -
    # File 'lib/idl/ast.rb', line 1420
    +      
    # File 'lib/idl/ast.rb', line 1481
     
     def execute(symtab)
       value_error "TODO: Array declaration" unless ary_size.empty?
    @@ -318,12 +486,12 @@ 

     
     
    -1405
    -1406
    -1407
    +1458 +1459 +1460

    -
    # File 'lib/idl/ast.rb', line 1405
    +      
    # File 'lib/idl/ast.rb', line 1458
     
     def lhs
       var_write
    @@ -348,19 +516,19 @@ 

     
     
    -1357
    -1358
    -1359
    -1360
    -1361
    -1362
    -1363
    -1364
    -1365
    -1366
    +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418

    -
    # File 'lib/idl/ast.rb', line 1357
    +      
    # File 'lib/idl/ast.rb', line 1409
     
     def lhs_type(symtab)
       decl_type = type_name.type(symtab).clone
    @@ -392,19 +560,19 @@ 

     
     
    -1409
    -1410
    -1411
    -1412
    -1413
    -1414
    -1415
    -1416
    -1417
    -1418
    +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471

    -
    # File 'lib/idl/ast.rb', line 1409
    +      
    # File 'lib/idl/ast.rb', line 1462
     
     def rhs
       # if rhs is nil, this is the non-initializing variant
    @@ -419,62 +587,182 @@ 

    +
    + +
    +

    + + #to_idlString + + + + + +

    +
    + +

    Return valid IDL representation of the node (and its subtree)

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      IDL code for the node

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +1487
    +
    +
    # File 'lib/idl/ast.rb', line 1487
    +
    +def to_idl = "#{type_name.to_idl} #{var_write.to_idl} = #{rval.to_idl}"
    +

    - #type_check(symtab) ⇒ Object + #type_check(symtab) ⇒ void -

    +
    +
    +

    This method returns an undefined value.

    +

    type check this node and all children

    + +

    Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

    + + +
    +
    +
    +

    Parameters:

    +
      + +
    • + + symtab + + + (SymbolTable) + + + + — +
      +

      Symbol table for lookup

      +
      + +
    • + +
    + +

    Raises:

    + + +
     
     
    -1368
    -1369
    -1370
    -1371
    -1372
    -1373
    -1374
    -1375
    -1376
    -1377
    -1378
    -1379
    -1380
    -1381
    -1382
    -1383
    -1384
    -1385
    -1386
    -1387
    -1388
    -1389
    -1390
    -1391
    -1392
    -1393
    -1394
    -1395
    -1396
    -1397
    -1398
    -1399
    -1400
    -1401
    -1402
    -1403
    +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456
    -
    # File 'lib/idl/ast.rb', line 1368
    +      
    # File 'lib/idl/ast.rb', line 1421
     
     def type_check(symtab)
       rval.type_check(symtab)
    @@ -522,7 +810,7 @@ 

    diff --git a/docs/ruby/Idl/XregType.html b/docs/ruby/Idl/XregType.html index 9e5d5dec1..aeb74a243 100644 --- a/docs/ruby/Idl/XregType.html +++ b/docs/ruby/Idl/XregType.html @@ -231,12 +231,12 @@

     
     
    -542
    -543
    -544
    +569 +570 +571

    -
    # File 'lib/idl/type.rb', line 542
    +      
    # File 'lib/idl/type.rb', line 569
     
     def initialize(xlen)
       super(:bits, width: xlen)
    @@ -268,12 +268,12 @@ 

     
     
    -550
    -551
    -552
    +577 +578 +579

    -
    # File 'lib/idl/type.rb', line 550
    +      
    # File 'lib/idl/type.rb', line 577
     
     def to_cxx
       'XReg'
    @@ -298,12 +298,12 @@ 

     
     
    -546
    -547
    -548
    +573 +574 +575

    -
    # File 'lib/idl/type.rb', line 546
    +      
    # File 'lib/idl/type.rb', line 573
     
     def to_s
       'XReg'
    @@ -318,7 +318,7 @@ 

    diff --git a/docs/ruby/Instruction.html b/docs/ruby/Instruction.html index 0562db108..f08eb3462 100644 --- a/docs/ruby/Instruction.html +++ b/docs/ruby/Instruction.html @@ -360,6 +360,28 @@

    The operation() IDL code.

    + + + +
  • + + + #pruned_operation_ast ⇒ Object + + + + + + + + + + + + + +
    +
  • @@ -422,36 +444,6 @@

     
     
    -952
    -953
    -954
    -955
    -956
    -957
    -958
    -959
    -960
    -961
    -962
    -963
    -964
    -965
    -966
    -967
    -968
    -969
    -970
    -971
    -972
    -973
    -974
    -975
    -976
    -977
    -978
    -979
    -980
    -981
     982
     983
     984
    @@ -485,10 +477,40 @@ 

    1012 1013 1014 -1015

    +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045

    -
    # File 'lib/arch_def.rb', line 952
    +      
    # File 'lib/arch_def.rb', line 982
     
     def initialize(inst_data, full_opcode_data, sym_table, arch_def)
       @arch_def = arch_def
    @@ -620,12 +642,12 @@ 

     
     
    -863
    -864
    -865
    +893 +894 +895

    -
    # File 'lib/arch_def.rb', line 863
    +      
    # File 'lib/arch_def.rb', line 893
     
     def arch_def
       @arch_def
    @@ -686,12 +708,12 @@ 

     
     
    -1092
    -1093
    -1094
    +1120 +1121 +1122

    -
    # File 'lib/arch_def.rb', line 1092
    +      
    # File 'lib/arch_def.rb', line 1120
     
     def access_detail?
       @data.key?("access_detail")
    @@ -745,12 +767,12 @@ 

     
     
    -1071
    -1072
    -1073
    +1099 +1100 +1101

    -
    # File 'lib/arch_def.rb', line 1071
    +      
    # File 'lib/arch_def.rb', line 1099
     
     def decode_variables(base)
       @encodings[base].decode_variables
    @@ -804,12 +826,12 @@ 

     
     
    -1066
    -1067
    -1068
    +1094 +1095 +1096

    -
    # File 'lib/arch_def.rb', line 1066
    +      
    # File 'lib/arch_def.rb', line 1094
     
     def encoding(base)
       @encodings[base].format
    @@ -875,18 +897,18 @@ 

     
     
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117

    -
    # File 'lib/arch_def.rb', line 1081
    +      
    # File 'lib/arch_def.rb', line 1109
     
     def extension
       @data["definedBy"]
    @@ -946,12 +968,12 @@ 

     
     
    -1018
    -1019
    -1020
    +1048 +1049 +1050

    -
    # File 'lib/arch_def.rb', line 1018
    +      
    # File 'lib/arch_def.rb', line 1048
     
     def multi_encoding?
       @data.key?("encoding") && @data["encoding"].key?("RV32")
    @@ -1005,14 +1027,14 @@ 

     
     
    -856
    -857
    -858
    -859
    -860
    +867 +868 +869 +870 +871

    -
    # File 'lib/arch_def.rb', line 856
    +      
    # File 'lib/arch_def.rb', line 867
     
     def operation_ast
       parse_operation(@sym_table) if @operation_ast.nil?
    @@ -1068,15 +1090,15 @@ 

     
     
    -1023
    -1024
    -1025
    -1026
    -1027
    -1028
    +1053 +1054 +1055 +1056 +1057 +1058

    -
    # File 'lib/arch_def.rb', line 1023
    +      
    # File 'lib/arch_def.rb', line 1053
     
     def operation_source
       return "" if @data["operation()"].nil?
    @@ -1087,6 +1109,66 @@ 

    +
    + +
    +

    + + #pruned_operation_astObject + + + + + +

    + + + + +
    +
    +
    +
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +
    +
    # File 'lib/arch_def.rb', line 873
    +
    +def pruned_operation_ast
    +  return @pruned_operation_ast unless @pruned_operation_ast.nil?
    +
    +  cloned_symtab = @sym_table.deep_clone(clone_values: true)
    +  cloned_symtab.push
    +
    +  @encodings[@arch_def.config_params["XLEN"]].decode_variables.each do |d|
    +    qualifiers = []
    +    qualifiers << :signed if d.sext?
    +    width = d.size
    +
    +    var = Idl::Var.new(d.name, Idl::Type.new(:bits, qualifiers:, width:), decode_var: true)
    +    cloned_symtab.add(d.name, var)
    +  end
    +
    +  puts "PRUNING        #{name}"
    +  @pruned_operation_ast = operation_ast.prune(cloned_symtab)
    +end
    +
    @@ -1153,23 +1235,23 @@

     
     
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141

    -
    # File 'lib/arch_def.rb', line 1100
    +      
    # File 'lib/arch_def.rb', line 1128
     
     def wavedrom_desc(base)
       desc = {
    @@ -1195,7 +1277,7 @@ 

    diff --git a/docs/ruby/Instruction/Encoding.html b/docs/ruby/Instruction/Encoding.html index 26edd8a54..6fb6e3b78 100644 --- a/docs/ruby/Instruction/Encoding.html +++ b/docs/ruby/Instruction/Encoding.html @@ -345,28 +345,28 @@

     
     
    -907
    -908
    -909
    -910
    -911
    -912
    -913
    -914
    -915
    -916
    -917
    -918
    -919
    -920
    -921
    -922
    -923
    -924
    -925
    +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955

    -
    # File 'lib/arch_def.rb', line 907
    +      
    # File 'lib/arch_def.rb', line 937
     
     def initialize(format, decode_vars)
       @format = format
    @@ -443,12 +443,12 @@ 

     
     
    -878
    -879
    -880
    +908 +909 +910

    -
    # File 'lib/arch_def.rb', line 878
    +      
    # File 'lib/arch_def.rb', line 908
     
     def decode_variables
       @decode_variables
    @@ -516,12 +516,12 @@ 

     
     
    -870
    -871
    -872
    +900 +901 +902

    -
    # File 'lib/arch_def.rb', line 870
    +      
    # File 'lib/arch_def.rb', line 900
     
     def format
       @format
    @@ -589,12 +589,12 @@ 

     
     
    -875
    -876
    -877
    +905 +906 +907

    -
    # File 'lib/arch_def.rb', line 875
    +      
    # File 'lib/arch_def.rb', line 905
     
     def opcode_fields
       @opcode_fields
    @@ -655,12 +655,12 @@ 

     
     
    -928
    -929
    -930
    +958 +959 +960

    -
    # File 'lib/arch_def.rb', line 928
    +      
    # File 'lib/arch_def.rb', line 958
     
     def size
       @format.size
    @@ -675,7 +675,7 @@ 

    diff --git a/docs/ruby/Instruction/Encoding/Field.html b/docs/ruby/Instruction/Encoding/Field.html index 7fdfb286c..94f3769cb 100644 --- a/docs/ruby/Instruction/Encoding/Field.html +++ b/docs/ruby/Instruction/Encoding/Field.html @@ -306,13 +306,13 @@

     
     
    -894
    -895
    -896
    -897
    +924 +925 +926 +927

    -
    # File 'lib/arch_def.rb', line 894
    +      
    # File 'lib/arch_def.rb', line 924
     
     def initialize(name, range)
       @name = name.to_s
    @@ -393,12 +393,12 @@ 

     
     
    -887
    -888
    -889
    +917 +918 +919

    -
    # File 'lib/arch_def.rb', line 887
    +      
    # File 'lib/arch_def.rb', line 917
     
     def name
       @name
    @@ -454,12 +454,12 @@ 

     
     
    -890
    -891
    -892
    +920 +921 +922

    -
    # File 'lib/arch_def.rb', line 890
    +      
    # File 'lib/arch_def.rb', line 920
     
     def range
       @range
    @@ -520,12 +520,12 @@ 

     
     
    -900
    -901
    -902
    +930 +931 +932

    -
    # File 'lib/arch_def.rb', line 900
    +      
    # File 'lib/arch_def.rb', line 930
     
     def opcode?
       name.match?(/^[01]+$/)
    @@ -540,7 +540,7 @@ 

    diff --git a/docs/ruby/Opcodes.html b/docs/ruby/Opcodes.html index 9351ed69e..3c63f19e2 100644 --- a/docs/ruby/Opcodes.html +++ b/docs/ruby/Opcodes.html @@ -436,7 +436,7 @@

    diff --git a/docs/ruby/RiscvOpcodes.html b/docs/ruby/RiscvOpcodes.html index 9790b2c30..0086f6a41 100644 --- a/docs/ruby/RiscvOpcodes.html +++ b/docs/ruby/RiscvOpcodes.html @@ -370,7 +370,7 @@

    diff --git a/docs/ruby/Treetop.html b/docs/ruby/Treetop.html index 96dcd45d3..e30fd1d4f 100644 --- a/docs/ruby/Treetop.html +++ b/docs/ruby/Treetop.html @@ -79,7 +79,7 @@
    Defined in:
    lib/idl/passes/find_return_values.rb,
    - lib/idl.rb,
    lib/idl/ast.rb
    + lib/idl.rb,
    lib/idl/ast.rb,
    lib/idl/passes/prune.rb
    @@ -118,7 +118,7 @@

    Overview

    diff --git a/docs/ruby/Treetop/Runtime.html b/docs/ruby/Treetop/Runtime.html index b4412f310..d8c41d287 100644 --- a/docs/ruby/Treetop/Runtime.html +++ b/docs/ruby/Treetop/Runtime.html @@ -79,7 +79,7 @@
    Defined in:
    lib/idl.rb,
    - lib/idl/ast.rb,
    lib/idl/passes/find_return_values.rb
    + lib/idl/ast.rb,
    lib/idl/passes/prune.rb,
    lib/idl/passes/find_return_values.rb
    @@ -107,7 +107,7 @@

    Defined Under Namespace

    diff --git a/docs/ruby/Treetop/Runtime/CompiledParser.html b/docs/ruby/Treetop/Runtime/CompiledParser.html index acaff4d34..daff675d5 100644 --- a/docs/ruby/Treetop/Runtime/CompiledParser.html +++ b/docs/ruby/Treetop/Runtime/CompiledParser.html @@ -405,7 +405,7 @@

    diff --git a/docs/ruby/Treetop/Runtime/SyntaxNode.html b/docs/ruby/Treetop/Runtime/SyntaxNode.html index b53ef33ee..5c9886a39 100644 --- a/docs/ruby/Treetop/Runtime/SyntaxNode.html +++ b/docs/ruby/Treetop/Runtime/SyntaxNode.html @@ -95,7 +95,7 @@
    Defined in:
    lib/idl/ast.rb,
    - lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    + lib/idl/passes/prune.rb,
    lib/idl/passes/gen_adoc.rb,
    lib/idl/passes/find_return_values.rb
    @@ -114,7 +114,7 @@

    Overview

    @@ -310,7 +310,7 @@

  • - #make_left ⇒ SyntaxNode + #pass_find_return_values(values, current_conditions) ⇒ Object @@ -324,9 +324,7 @@

    -
    -

    Fix up left recursion for the PEG.

    -
    +

  • @@ -334,7 +332,7 @@

  • - #parsing_in_template? ⇒ Boolean + #prune(symtab) ⇒ AstNode @@ -349,7 +347,7 @@

    -

    Whether or not this SyntaxNode is being parsed as a template argument without being enclosed in parenthesis.

    +

    A new abstract syntax tree with all dead/unreachable code removed.

  • @@ -358,7 +356,7 @@

  • - #pass_find_return_values(values, current_conditions) ⇒ Object + #set_input_file(filename, starting_line = 0) ⇒ Object @@ -372,7 +370,9 @@

    -
    +
    +

    remember where the code for this SyntaxNode comes from.

    +

  • @@ -380,7 +380,7 @@

  • - #set_input_file(filename, starting_line = 0) ⇒ Object + #to_ast ⇒ SyntaxNode @@ -395,7 +395,7 @@

    -

    remember where the code for this SyntaxNode comes from.

    +

    convert SyntaxNode into an AstNode.

  • @@ -502,32 +502,32 @@

     
     
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
     93
     94
     95
     96
    -97
    -98
    -99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    +97

    -
    # File 'lib/idl/ast.rb', line 93
    +      
    # File 'lib/idl/ast.rb', line 75
     
     def clone
       new_elements = nil
    @@ -601,18 +601,18 @@ 

     
     
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    -89
    -90
    +64 +65 +66 +67 +68 +69 +70 +71 +72

    -
    # File 'lib/idl/ast.rb', line 82
    +      
    # File 'lib/idl/ast.rb', line 64
     
     def find_ancestor(klass)
       if parent.nil?
    @@ -653,19 +653,7 @@ 

    11 12 13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26

    +14
    # File 'lib/idl/passes/gen_adoc.rb', line 4
    @@ -674,23 +662,11 @@ 

    if terminal? text_value else - adoc = '' - next_pos = interval.begin + adoc = [] elements.each do |e| - if e.interval.size > 0 && e.interval.begin != next_pos - adoc << input[next_pos..(e.interval.begin - 1)] - end - adoc << e.gen_adoc(indent+2, indent_spaces: 2) - next_pos = e.interval.exclude_end? ? e.interval.end : (e.interval.end + 1) - end - if next_pos != (interval.exclude_end? ? interval.end : (interval.end + 1)) - end_pos = interval.exclude_end? ? interval.end - 1 : interval.end - adoc << input[next_pos..end_pos] - end - if adoc != text_value && !text_value.index('xref').nil? - raise + adoc << e.gen_adoc(indent, indent_spaces:) end - adoc + adoc.map{ |a| "#{' '*indent}#{a}" }.join('') end end

    -
    # File 'lib/idl/ast.rb', line 77
    +      
    # File 'lib/idl/ast.rb', line 59
     
     def lineno
       input[0..interval.first].count("\n") + 1 + (@starting_line.nil? ? 0 : @starting_line)
    @@ -888,76 +864,33 @@ 

    -

    - - #make_leftSyntaxNode +

    - + #pass_find_return_values(values, current_conditions) ⇒ Object -

    -
    - -
    - Note: -
    -

    This may alter the SyntaxTree. You shouldn’t use pointers within the tree from before a call to make_left

    -
    -
    - - -

    Fix up left recursion for the PEG

    - -

    This is the default for anything that isn’t a left-recursive binary op

    -

    Only left-recursive binary ops need to override this

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (SyntaxNode) - - - - — -
      -

      A fixed syntax tree

      -
      - -
    • -
    - -
    +
    @@ -965,9 +898,9 @@

    -

    +

    - #parsing_in_template?Boolean + #prune(symtab) ⇒ AstNode @@ -976,26 +909,46 @@

    -

    Returns whether or not this SyntaxNode is being parsed as a template argument without being enclosed in parenthesis.

    +

    Returns A new abstract syntax tree with all dead/unreachable code removed.

    +

    Parameters:

    +
      + +
    • + + symtab + + + (Idl::SymbolTable) + + + + — +
      +

      Context of the compilation

      +
      + +
    • +
    +

    Returns:

    • - (Boolean) + (AstNode)
      -

      whether or not this SyntaxNode is being parsed as a template argument without being enclosed in parenthesis

      +

      A new abstract syntax tree with all dead/unreachable code removed

    • @@ -1008,77 +961,55 @@

       
       
      +11
      +12
      +13
      +14
      +15
      +16
      +17
      +18
      +19
      +20
      +21
      +22
      +23
      +24
      +25
      +26
      +27
      +28
      +29
      +30
      +31
       32
      -33
      -34
      -35
      -36
      -37
      -38
      -39
      -40
      -41
      -42
      -43
      -44
      -45
      -46
      -47
      -48
      - -

    - -
     
     
    -59
    -60
    -61
    -62
    -63
    -64
    +8 +9 +10 +11 +12
    -
    # File 'lib/idl/ast.rb', line 59
    +      
    # File 'lib/idl/passes/find_return_values.rb', line 8
     
    -def make_left
    -  elements.nil? || elements.length.times do |i|
    -    elements[i] = elements[i].make_left
    +def pass_find_return_values(values, current_conditions)
    +  children.each do |c|
    +    c.pass_find_return_values(values, current_conditions)
       end
    -  self
     end
    -
    # File 'lib/idl/ast.rb', line 32
    -
    -def parsing_in_template?
    -  # since this is called in the middle of parsing, the parent pointer hasn't been set up yet
    -  puts self.class.ancestors
    -  puts "text = #{text_value}"
    -  puts parent.class.name
    -  exit
    -  if parent.nil?
    -    nil
    -  elsif parent.is_a?(ParenExpressionAst)
    -    false # once we hit a paren expression, we are cleared
    -  elsif parent.is_a?(BitsTypeAst)
    -    puts "FOund bits!!"
    -    true # must be the expression on the BitsType
    -  else
    -    parent.parsing_in_template?
    -  end
    -end
    +33
    -
    - -
    -

    - - #pass_find_return_values(values, current_conditions) ⇒ Object - - - - - -

    - - @@ -1149,14 +1080,14 @@

     
     
    -70
    -71
    -72
    -73
    -74
    +52 +53 +54 +55 +56

    -
    +      
    # File 'lib/idl/passes/prune.rb', line 11
     
    +def prune(symtab)
     
    -8
    -9
    -10
    -11
    -12
    -
    -
    # File 'lib/idl/passes/find_return_values.rb', line 8
    +  new_elements = elements.nil? ? [] : elements.map { |e| e.prune(symtab) }
    +  new_node = self.class.new(input, interval, new_elements)
    +  extension_modules.each do |m|
    +    new_node.extend m
    +  end
     
    -def pass_find_return_values(values, current_conditions)
    -  children.each do |c|
    -    c.pass_find_return_values(values, current_conditions)
    +  if is_a?(Idl::AstNode)
    +    begin
    +      if new_node.is_a?(Idl::Declaration)
    +        new_node.add_symbol(symtab)
    +      end
    +      if new_node.is_a?(Idl::Executable)
    +        new_node.execute(symtab) # to update values
    +      end
    +    rescue Idl::AstNode::ValueError
    +      new_node.type_check(symtab)
    +    end
       end
    +
    +  new_node
     end
    -
    # File 'lib/idl/ast.rb', line 70
    +      
    # File 'lib/idl/ast.rb', line 52
     
     def set_input_file(filename, starting_line = 0)
       @input_file = filename
    @@ -1166,6 +1097,87 @@ 

    +
    + +
    +

    + + #to_astSyntaxNode + + + + + +

    +
    + +
    + Note: +
    +

    This may alter the SyntaxTree. You shouldn’t use pointers within the tree from before a call to to_ast

    +
    +
    + + +

    convert SyntaxNode into an AstNode

    + +

    Mostly, there is a 1:1 correspondence between SyntaxNode and AstNode. A few exceptions:

    + +
    * Left recusrion needs fixed up, so BinaryExpreesions are converted
    +* If statements are converted to a more friendly format
    +
    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (SyntaxNode) + + + + — +
      +

      A fixed syntax tree

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +
    +
    # File 'lib/idl/ast.rb', line 40
    +
    +def to_ast
    +  elements.nil? || elements.length.times do |i|
    +    elements[i] = elements[i].to_ast
    +    elements[i].parent = self
    +  end
    +  self
    +end
    +
    @@ -1173,7 +1185,7 @@

    diff --git a/docs/ruby/Validator.html b/docs/ruby/Validator.html index 4f6873123..6d3d348d7 100644 --- a/docs/ruby/Validator.html +++ b/docs/ruby/Validator.html @@ -655,7 +655,7 @@

    diff --git a/docs/ruby/Validator/SchemaError.html b/docs/ruby/Validator/SchemaError.html index ae7b30392..1dc80af7d 100644 --- a/docs/ruby/Validator/SchemaError.html +++ b/docs/ruby/Validator/SchemaError.html @@ -299,7 +299,7 @@

    diff --git a/docs/ruby/Validator/ValidationError.html b/docs/ruby/Validator/ValidationError.html index 7ad3deeaf..b250ee573 100644 --- a/docs/ruby/Validator/ValidationError.html +++ b/docs/ruby/Validator/ValidationError.html @@ -369,7 +369,7 @@

    diff --git a/docs/ruby/_index.html b/docs/ruby/_index.html index da2c6fcac..51e34c8b3 100644 --- a/docs/ruby/_index.html +++ b/docs/ruby/_index.html @@ -110,7 +110,7 @@

    Namespace Listing A-Z

  • - AryAccess + AryAccessSyntaxNode (Idl) @@ -181,7 +181,7 @@

    Namespace Listing A-Z

  • - BinaryExpressionRightAst + BinaryExpressionRightSyntaxNode (Idl) @@ -279,6 +279,13 @@

    Namespace Listing A-Z

  • +
  • + ConditionalStatementSyntaxNode + + (Idl) + +
  • +
  • Csr @@ -339,6 +346,13 @@

    Namespace Listing A-Z

  • D
  • + +
    • U
      • @@ -813,9 +892,6 @@

        Namespace Listing A-Z

      -
    - - diff --git a/docs/ruby/index.html b/docs/ruby/index.html index 3f8bc7a60..acba22041 100644 --- a/docs/ruby/index.html +++ b/docs/ruby/index.html @@ -57,7 +57,41 @@
    -
    +
    +
    +
    +

    The RISC-V Unified Database is intended to hold all the information needed to describe RISC-V, +including a list of extensions, instruction specifications, CSR specifications, and documentation prose. The vision is that anything one would need for RISC-V can be generated from the information in this repository.

    +
    +
    +

    This repository contains:

    +
    +
    +
      +
    • +

      A (eventually complete) description of the RISC-V specification in a machine-readable format.

      +
    • +
    • +

      A tool to generate multiple views of that spec, including:

      +
      +
        +
      • +

        A configuration-specific, human-readable documentation webpage

        +
      • +
      • +

        [COMING SOON] A configuration-specific Instruction Set Simulator

        +
      • +
      • +

        More backends are planned

        +
      • +
      +
      +
    • +
    +
    +
    +
    +

    Prerequisites

    @@ -105,6 +139,20 @@

    Setup

    # DEVELOPMENT=1 ./bin/setup
    +
    + + + + + +
    +
    Note
    +
    +If you forget, don’t worry. Setup will be invoked by any program in bin/ if necessary. +
    +
    +
    +

    VSCode

    If using Visual Studio Code and want to use development tools, you will need to restart the editor after setup.

    @@ -128,6 +176,11 @@

    Setup

    +
    +

    The .vscode/settings.json file in the repo will ensure that Solargraph works without any additional +configuration (assuming you’ve already run ./bin/setup).

    +
    +
    diff --git a/docs/ruby/method_list.html b/docs/ruby/method_list.html index 8ebbff803..f032dbe58 100644 --- a/docs/ruby/method_list.html +++ b/docs/ruby/method_list.html @@ -117,6 +117,62 @@

    Method List

  • +
    + #add_symbol + Idl::Declaration +
    +
  • + + +
  • +
    + #add_symbol + Idl::EnumDefinitionAst +
    +
  • + + +
  • +
    + #add_symbol + Idl::BitfieldDefinitionAst +
    +
  • + + +
  • +
    + #add_symbol + Idl::MultiVariableDeclarationAst +
    +
  • + + +
  • +
    + #add_symbol + Idl::VariableDeclarationAst +
    +
  • + + +
  • +
    + #add_symbol + Idl::VariableDeclarationWithInitializationAst +
    +
  • + + +
  • +
    + #add_symbol + Idl::FunctionDefAst +
    +
  • + + +
  • #alias DecodeVariable @@ -124,7 +180,7 @@

    Method List

  • -
  • +
  • #alias CsrField @@ -132,7 +188,7 @@

    Method List

  • -
  • +
  • #all_known_csr_names ArchDef @@ -140,7 +196,7 @@

    Method List

  • -
  • +
  • #all_known_exts ArchGen @@ -148,7 +204,7 @@

    Method List

  • -
  • +
  • #apply_arguments Idl::FunctionType @@ -156,7 +212,7 @@

    Method List

  • -
  • +
  • #apply_template_values Idl::FunctionType @@ -164,7 +220,7 @@

    Method List

  • -
  • +
  • #arch_def CsrField @@ -172,7 +228,7 @@

    Method List

  • -
  • +
  • #arch_def Csr @@ -180,7 +236,7 @@

    Method List

  • -
  • +
  • #arch_def Instruction @@ -188,7 +244,7 @@

    Method List

  • -
  • +
  • #arch_def Extension @@ -196,7 +252,7 @@

    Method List

  • -
  • +
  • #arch_def ExtensionVersion @@ -204,7 +260,7 @@

    Method List

  • -
  • +
  • #archdef Idl::SymbolTable @@ -212,7 +268,7 @@

    Method List

  • -
  • +
  • #arg_nodes Idl::FunctionCallExpressionAst @@ -220,7 +276,7 @@

    Method List

  • -
  • +
  • #argument_name Idl::FunctionType @@ -228,7 +284,7 @@

    Method List

  • -
  • +
  • #argument_type Idl::FunctionType @@ -236,7 +292,7 @@

    Method List

  • -
  • +
  • #arguments Idl::FunctionDefAst @@ -244,7 +300,7 @@

    Method List

  • -
  • +
  • #arguments Idl::Type @@ -252,7 +308,7 @@

    Method List

  • -
  • +
  • #arguments_list_str Idl::FunctionDefAst @@ -260,7 +316,7 @@

    Method List

  • -
  • +
  • #ary? Idl::Type @@ -268,7 +324,7 @@

    Method List

  • -
  • +
  • #ary_type Idl::Type @@ -276,14 +332,6 @@

    Method List

  • -
  • -
    - #ast - Idl::TemplateFunctionType -
    -
  • - -
  • #base32_only? @@ -341,6 +389,14 @@

    Method List

  • +
    + #body + Idl::ElseIfAst +
    +
  • + + +
  • #body Idl::FunctionType @@ -348,7 +404,7 @@

    Method List

  • -
  • +
  • #bt Idl::AstNode::TypeError @@ -356,7 +412,7 @@

    Method List

  • -
  • +
  • #bt Idl::AstNode::InternalError @@ -364,7 +420,7 @@

    Method List

  • -
  • +
  • #builtin? Idl::FunctionDefAst @@ -372,7 +428,7 @@

    Method List

  • -
  • +
  • #builtin? Idl::FunctionType @@ -380,7 +436,7 @@

    Method List

  • -
  • +
  • #check_extension_dependencies ArchGen @@ -388,7 +444,7 @@

    Method List

  • -
  • +
  • #children Idl::AstNodeFuncs @@ -396,7 +452,7 @@

    Method List

  • -
  • +
  • #children Idl::IsaAst @@ -404,7 +460,7 @@

    Method List

  • -
  • +
  • #clone Treetop::Runtime::SyntaxNode @@ -412,7 +468,7 @@

    Method List

  • -
  • +
  • #clone Idl::Type @@ -420,7 +476,7 @@

    Method List

  • -
  • +
  • #clone Idl::EnumerationType @@ -428,7 +484,7 @@

    Method List

  • -
  • +
  • #clone Idl::BitfieldType @@ -436,7 +492,7 @@

    Method List

  • -
  • +
  • #clone Idl::FunctionType @@ -444,7 +500,7 @@

    Method List

  • -
  • +
  • #clone Idl::Var @@ -452,7 +508,7 @@

    Method List

  • -
  • +
  • #comparable_to? Idl::Type @@ -460,6 +516,14 @@

    Method List

  • +
  • +
    + #compile_expression + Idl::Compiler +
    +
  • + +
  • #compile_file @@ -485,6 +549,14 @@

    Method List

  • +
    + #cond + Idl::ElseIfAst +
    +
  • + + +
  • #condition Idl::TernaryOperatorExpressionAst @@ -492,7 +564,7 @@

    Method List

  • -
  • +
  • #condition Idl::ConditionalStatementAst @@ -500,7 +572,7 @@

    Method List

  • -
  • +
  • #condition Idl::ConditionalReturnStatementAst @@ -508,7 +580,7 @@

    Method List

  • -
  • +
  • #config_params ArchDef @@ -516,6 +588,14 @@

    Method List

  • +
  • +
    + #config_params + TestExpressions::MockArchDef +
    +
  • + +
  • #const? @@ -717,6 +797,14 @@

    Method List

  • +
    + #default + Idl::Type +
    +
  • + + +
  • #defined_in_all_bases? CsrField @@ -724,7 +812,7 @@

    Method List

  • -
  • +
  • #description Idl::FunctionDefAst @@ -732,7 +820,7 @@

    Method List

  • -
  • +
  • #description_html Csr @@ -740,7 +828,7 @@

    Method List

  • -
  • +
  • #dynamic_length? Csr @@ -748,7 +836,7 @@

    Method List

  • -
  • +
  • #dynamic_location? CsrField @@ -756,7 +844,7 @@

    Method List

  • -
  • +
  • #element_names Idl::EnumDefinitionAst @@ -764,7 +852,7 @@

    Method List

  • -
  • +
  • #element_names Idl::BitfieldDefinitionAst @@ -772,7 +860,7 @@

    Method List

  • -
  • +
  • #element_names Idl::EnumerationType @@ -780,7 +868,7 @@

    Method List

  • -
  • +
  • #element_nodes Idl::ArrayLiteralAst @@ -788,7 +876,7 @@

    Method List

  • -
  • +
  • #element_ranges Idl::BitfieldDefinitionAst @@ -796,7 +884,7 @@

    Method List

  • -
  • +
  • #element_values Idl::EnumDefinitionAst @@ -804,7 +892,7 @@

    Method List

  • -
  • +
  • #element_values Idl::EnumerationType @@ -812,6 +900,14 @@

    Method List

  • +
  • +
    + #elseifs + Idl::IfAst +
    +
  • + +
  • #enclosing_function @@ -934,77 +1030,85 @@

    Method List

  • - #execute - Idl::MultiVariableDeclarationAst + #execute + Idl::VariableDeclarationWithInitializationAst
  • - #execute - Idl::VariableDeclarationAst + #execute + Idl::PostDecrementExpressionAst
  • - #execute - Idl::VariableDeclarationWithInitializationAst + #execute + Idl::PostIncrementExpressionAst
  • - #execute - Idl::PostDecrementExpressionAst + #execute + Idl::NoopAst
  • - #execute - Idl::PostIncrementExpressionAst + #execute + Idl::StatementAst
  • - #execute - Idl::StatementAst + #execute + Idl::ConditionalStatementAst
  • - #execute - Idl::ConditionalStatementAst + #execute + Idl::FunctionStatementAst
  • - #execute - Idl::FunctionStatementAst + #execute + Idl::InstructionOperationAst
  • - #execute - Idl::InstructionOperationAst + #execute + Idl::IfBodyAst
  • +
    + #execute + Idl::CsrSoftwareWriteAst +
    +
  • + + +
  • #execute Idl::CsrWriteAst @@ -1012,7 +1116,7 @@

    Method List

  • -
  • +
  • #exp Idl::UnaryOperatorExpressionAst @@ -1020,7 +1124,7 @@

    Method List

  • -
  • +
  • #expected_return_type Idl::ReturnStatementAst @@ -1028,7 +1132,7 @@

    Method List

  • -
  • +
  • #ext? ArchDef @@ -1036,7 +1140,7 @@

    Method List

  • -
  • +
  • #extension Instruction @@ -1044,7 +1148,7 @@

    Method List

  • -
  • +
  • #extension ExtensionVersion @@ -1052,7 +1156,7 @@

    Method List

  • -
  • +
  • #extension ArchDef @@ -1060,7 +1164,7 @@

    Method List

  • -
  • +
  • #extension_hash ArchDef @@ -1068,7 +1172,7 @@

    Method List

  • -
  • +
  • #extensions ArchDef @@ -1076,6 +1180,14 @@

    Method List

  • +
  • +
    + #extensions + TestExpressions::MockArchDef +
    +
  • + +
  • #extract @@ -1198,24 +1310,40 @@

    Method List

  • - #find_ancestor - Treetop::Runtime::SyntaxNode + #final_else_body + Idl::IfAst
  • - #find_replace_links - ArchDef + #find_all + Idl::SymbolTable
  • - #format - Instruction::Encoding + #find_ancestor + Treetop::Runtime::SyntaxNode +
    +
  • + + +
  • +
    + #find_replace_links + ArchDef +
    +
  • + + +
  • +
    + #format + Instruction::Encoding
  • @@ -1252,6 +1380,54 @@

    Method List

    +
  • +
    + #gen_adoc + Idl::AryElementAccessAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::BinaryExpressionAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::VariableAssignmentAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::StatementAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::ReturnStatementAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::ConditionalStatementAst +
    +
  • + +
  • #gen_adoc @@ -1260,6 +1436,38 @@

    Method List

  • +
  • +
    + #gen_adoc + Idl::FunctionBodyAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::CsrFieldReadExpressionAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::CsrReadExpressionAst +
    +
  • + + +
  • +
    + #gen_adoc + Idl::IfAst +
    +
  • + +
  • #gen_dir @@ -1285,6 +1493,30 @@

    Method List

  • +
    + #get_from + Idl::SymbolTable +
    +
  • + + +
  • +
    + #get_global + Idl::SymbolTable +
    +
  • + + +
  • +
    + #global_ast + ArchDef +
    +
  • + + +
  • #globals Idl::IsaAst @@ -1292,7 +1524,7 @@

    Method List

  • -
  • +
  • #grouped_encoding_fields DecodeVariable @@ -1300,7 +1532,7 @@

    Method List

  • -
  • +
  • #grouped_encoding_fields DecodeField @@ -1308,7 +1540,7 @@

    Method List

  • -
  • +
  • #has_custom_sw_read? Csr @@ -1316,7 +1548,7 @@

    Method List

  • -
  • +
  • #has_custom_write? CsrField @@ -1324,7 +1556,7 @@

    Method List

  • -
  • +
  • #has_template_ancestor? Treetop::Runtime::SyntaxNode @@ -1332,7 +1564,7 @@

    Method List

  • -
  • +
  • #hash EncodingField @@ -1340,7 +1572,7 @@

    Method List

  • -
  • +
  • #hash DecodeVariable @@ -1348,7 +1580,7 @@

    Method List

  • -
  • +
  • #hash DecodeField @@ -1356,7 +1588,7 @@

    Method List

  • -
  • +
  • #idl_compiler ArchDef @@ -1364,7 +1596,23 @@

    Method List

  • +
  • +
    + #if_body + Idl::IfAst +
    +
  • + +
  • +
    + #if_cond + Idl::IfAst +
    +
  • + + +
  • #implemented_csr ArchDef @@ -1372,7 +1620,7 @@

    Method List

  • -
  • +
  • #implemented_csr_hash ArchDef @@ -1380,7 +1628,7 @@

    Method List

  • -
  • +
  • #implemented_csrs ArchDef @@ -1388,7 +1636,7 @@

    Method List

  • -
  • +
  • #implemented_csrs ArchGen @@ -1396,7 +1644,7 @@

    Method List

  • -
  • +
  • #implemented_extensions ArchDef @@ -1404,7 +1652,7 @@

    Method List

  • -
  • +
  • #implemented_extensions ArchGen @@ -1412,7 +1660,7 @@

    Method List

  • -
  • +
  • #implemented_fields Csr @@ -1420,7 +1668,7 @@

    Method List

  • -
  • +
  • #implemented_fields_for Csr @@ -1428,7 +1676,7 @@

    Method List

  • -
  • +
  • #implemented_instructions ArchDef @@ -1436,7 +1684,7 @@

    Method List

  • -
  • +
  • #implemented_instructions ArchGen @@ -1444,7 +1692,7 @@

    Method List

  • -
  • +
  • #implies Extension @@ -1452,7 +1700,7 @@

    Method List

  • -
  • +
  • #index Idl::AryElementAccessAst @@ -1460,7 +1708,7 @@

    Method List

  • -
  • +
  • #initialize Idl::Compiler @@ -1468,7 +1716,7 @@

    Method List

  • -
  • +
  • #initialize Idl::AstNode::TypeError @@ -1476,7 +1724,7 @@

    Method List

  • -
  • +
  • #initialize Idl::AstNode::InternalError @@ -1484,7 +1732,7 @@

    Method List

  • -
  • +
  • #initialize Idl::AstNode::ValueError @@ -1492,7 +1740,7 @@

    Method List

  • -
  • +
  • #initialize Idl::AryElementAccessAst @@ -1500,7 +1748,7 @@

    Method List

  • -
  • +
  • #initialize Idl::AryRangeAccessAst @@ -1508,7 +1756,7 @@

    Method List

  • -
  • +
  • #initialize Idl::BinaryExpressionAst @@ -1516,6 +1764,62 @@

    Method List

  • +
  • +
    + #initialize + Idl::NoopAst +
    +
  • + + +
  • +
    + #initialize + Idl::StatementAst +
    +
  • + + +
  • +
    + #initialize + Idl::ConditionalStatementAst +
    +
  • + + +
  • +
    + #initialize + Idl::FunctionBodyAst +
    +
  • + + +
  • +
    + #initialize + Idl::IfBodyAst +
    +
  • + + +
  • +
    + #initialize + Idl::ElseIfAst +
    +
  • + + +
  • +
    + #initialize + Idl::IfAst +
    +
  • + +
  • #initialize @@ -1661,14 +1965,6 @@

    Method List

  • -
    - #initialize - Idl::TemplateFunctionType -
    -
  • - - -
  • #initialize Idl::XregType @@ -1676,7 +1972,7 @@

    Method List

  • -
  • +
  • #initialize Validator::SchemaError @@ -1684,7 +1980,7 @@

    Method List

  • -
  • +
  • #initialize Validator::ValidationError @@ -1692,7 +1988,7 @@

    Method List

  • -
  • +
  • #initialize Validator @@ -1700,7 +1996,7 @@

    Method List

  • -
  • +
  • #initialize Idl::Var @@ -1708,7 +2004,7 @@

    Method List

  • -
  • +
  • #initialize Idl::SymbolTable @@ -1716,6 +2012,14 @@

    Method List

  • +
  • +
    + #initialize + TestExpressions::MockExtension +
    +
  • + +
  • #input_file @@ -1861,6 +2165,14 @@

    Method List

  • +
    + #keys_pretty + Idl::SymbolTable +
    +
  • + + +
  • #kind Idl::FieldAssignmentAst @@ -1868,7 +2180,7 @@

    Method List

  • -
  • +
  • #kind Idl::BitfieldAccessExpressionAst @@ -1876,7 +2188,7 @@

    Method List

  • -
  • +
  • #kind Idl::Type @@ -1884,7 +2196,7 @@

    Method List

  • -
  • +
  • #left_shift DecodeVariable @@ -1892,7 +2204,7 @@

    Method List

  • -
  • +
  • #length Csr @@ -1900,7 +2212,7 @@

    Method List

  • -
  • +
  • #length_cond32 Csr @@ -1908,7 +2220,7 @@

    Method List

  • -
  • +
  • #length_cond64 Csr @@ -1916,7 +2228,7 @@

    Method List

  • -
  • +
  • #length_pretty Csr @@ -1924,7 +2236,7 @@

    Method List

  • -
  • +
  • #levels Idl::SymbolTable @@ -1932,7 +2244,7 @@

    Method List

  • -
  • +
  • #lhs Idl::AssignmentAst @@ -1940,7 +2252,7 @@

    Method List

  • -
  • +
  • #lhs Idl::VariableAssignmentAst @@ -1948,7 +2260,7 @@

    Method List

  • -
  • +
  • #lhs Idl::AryElementAssignmentAst @@ -1956,7 +2268,7 @@

    Method List

  • -
  • +
  • #lhs Idl::AryRangeAssignmentAst @@ -1964,7 +2276,7 @@

    Method List

  • -
  • +
  • #lhs Idl::VariableDeclarationWithInitializationAst @@ -1972,7 +2284,7 @@

    Method List

  • -
  • +
  • #lhs Idl::BinaryExpressionAst @@ -1980,7 +2292,7 @@

    Method List

  • -
  • +
  • #lhs_type Idl::VariableDeclarationWithInitializationAst @@ -1988,7 +2300,7 @@

    Method List

  • -
  • +
  • #lineno Treetop::Runtime::SyntaxNode @@ -1996,7 +2308,7 @@

    Method List

  • -
  • +
  • #lineno Idl::AstNode::ValueError @@ -2004,7 +2316,7 @@

    Method List

  • -
  • +
  • #location CsrField @@ -2012,7 +2324,7 @@

    Method List

  • -
  • +
  • #location_pretty CsrField @@ -2020,7 +2332,7 @@

    Method List

  • -
  • +
  • #lsb Idl::AryRangeAccessAst @@ -2028,7 +2340,7 @@

    Method List

  • -
  • +
  • #make_const Idl::Type @@ -2036,30 +2348,6 @@

    Method List

  • -
  • -
    - #make_left - Treetop::Runtime::SyntaxNode -
    -
  • - - -
  • -
    - #make_left - Idl::AryAccess -
    -
  • - - -
  • -
    - #make_left - Idl::BinaryExpressionRightAst -
    -
  • - -
  • #make_signed @@ -2229,6 +2517,14 @@

    Method List

  • +
    + #name + TestExpressions::MockExtension +
    +
  • + + +
  • #nodes Idl::AstNodeFuncs @@ -2236,7 +2532,7 @@

    Method List

  • -
  • +
  • #num_args Idl::FunctionDefAst @@ -2244,7 +2540,7 @@

    Method List

  • -
  • +
  • #num_args Idl::FunctionType @@ -2252,7 +2548,7 @@

    Method List

  • -
  • +
  • #op Idl::BinaryExpressionAst @@ -2260,7 +2556,7 @@

    Method List

  • -
  • +
  • #op Idl::UnaryOperatorExpressionAst @@ -2268,7 +2564,7 @@

    Method List

  • -
  • +
  • #opcode? EncodingField @@ -2276,7 +2572,7 @@

    Method List

  • -
  • +
  • #opcode? Instruction::Encoding::Field @@ -2284,7 +2580,7 @@

    Method List

  • -
  • +
  • #opcode_fields Instruction::Encoding @@ -2292,7 +2588,7 @@

    Method List

  • -
  • +
  • #operation_ast Instruction @@ -2300,7 +2596,7 @@

    Method List

  • -
  • +
  • #operation_source Instruction @@ -2308,7 +2604,7 @@

    Method List

  • -
  • +
  • #orig_instantiate_node Treetop::Runtime::CompiledParser @@ -2316,7 +2612,7 @@

    Method List

  • -
  • +
  • #params ArchGen @@ -2324,7 +2620,7 @@

    Method List

  • -
  • +
  • #parent CsrField @@ -2332,14 +2628,6 @@

    Method List

  • -
  • -
    - #parsing_in_template? - Treetop::Runtime::SyntaxNode -
    -
  • - -
  • #pass_find_return_values @@ -2405,6 +2693,94 @@

    Method List

  • +
    + #prune + Treetop::Runtime::SyntaxNode +
    +
  • + + +
  • +
    + #prune + Idl::FunctionBodyAst +
    +
  • + + +
  • +
    + #prune + Idl::StatementAst +
    +
  • + + +
  • +
    + #prune + Idl::AryElementAccessAst +
    +
  • + + +
  • +
    + #prune + Idl::AryRangeAccessAst +
    +
  • + + +
  • +
    + #prune + Idl::BinaryExpressionAst +
    +
  • + + +
  • +
    + #prune + Idl::IfBodyAst +
    +
  • + + +
  • +
    + #prune + Idl::ElseIfAst +
    +
  • + + +
  • +
    + #prune + Idl::IfAst +
    +
  • + + +
  • +
    + #prune + Idl::ConditionalStatementAst +
    +
  • + + +
  • +
    + #pruned_operation_ast + Instruction +
    +
  • + + +
  • #push Idl::SymbolTable @@ -2412,7 +2788,7 @@

    Method List

  • -
  • +
  • #qualifiers Idl::Type @@ -2420,7 +2796,7 @@

    Method List

  • -
  • +
  • #qualify Idl::Type @@ -2428,7 +2804,7 @@

    Method List

  • -
  • +
  • #range EncodingField @@ -2436,7 +2812,7 @@

    Method List

  • -
  • +
  • #range CsrField::Alias @@ -2444,7 +2820,7 @@

    Method List

  • -
  • +
  • #range Instruction::Encoding::Field @@ -2452,7 +2828,7 @@

    Method List

  • -
  • +
  • #range Idl::BitfieldType @@ -2460,7 +2836,7 @@

    Method List

  • -
  • +
  • #reset_value CsrField @@ -2468,7 +2844,7 @@

    Method List

  • -
  • +
  • #reset_value_func CsrField @@ -2476,7 +2852,7 @@

    Method List

  • -
  • +
  • #respond_to_missing? ArchDefObject @@ -2484,7 +2860,7 @@

    Method List

  • -
  • +
  • #result Validator::SchemaError @@ -2492,7 +2868,7 @@

    Method List

  • -
  • +
  • #result Validator::ValidationError @@ -2500,7 +2876,7 @@

    Method List

  • -
  • +
  • #return_type Idl::ReturnStatementAst @@ -2508,7 +2884,7 @@

    Method List

  • -
  • +
  • #return_type Idl::FunctionDefAst @@ -2516,7 +2892,7 @@

    Method List

  • -
  • +
  • #return_type Idl::Type @@ -2524,7 +2900,7 @@

    Method List

  • -
  • +
  • #return_type Idl::FunctionType @@ -2532,7 +2908,7 @@

    Method List

  • -
  • +
  • #return_type_list_str Idl::FunctionDefAst @@ -2540,7 +2916,7 @@

    Method List

  • -
  • +
  • #return_types Idl::ReturnStatementAst @@ -2548,14 +2924,6 @@

    Method List

  • -
  • -
    - #return_types - Idl::FunctionDefAst -
    -
  • - -
  • #return_types @@ -2605,6 +2973,14 @@

    Method List

  • +
    + #return_value + Idl::IfBodyAst +
    +
  • + + +
  • #return_value Idl::IfAst @@ -2612,6 +2988,14 @@

    Method List

  • +
  • +
    + #return_value + Idl::FunctionType +
    +
  • + +
  • #return_value_nodes @@ -2621,6 +3005,30 @@

    Method List

  • +
    + #return_values + Idl::Returns +
    +
  • + + +
  • +
    + #return_values + Idl::ReturnStatementAst +
    +
  • + + +
  • +
    + #return_values + Idl::ConditionalReturnStatementAst +
    +
  • + + +
  • #return_values Idl::FunctionBodyAst @@ -2628,6 +3036,30 @@

    Method List

  • +
  • +
    + #return_values + Idl::ForLoopAst +
    +
  • + + +
  • +
    + #return_values + Idl::IfBodyAst +
    +
  • + + +
  • +
    + #return_values + Idl::ElseIfAst +
    +
  • + +
  • #return_values @@ -2725,6 +3157,14 @@

    Method List

  • +
    + #setup + TestExpressions +
    +
  • + + +
  • #sext? DecodeVariable @@ -2732,7 +3172,7 @@

    Method List

  • -
  • +
  • #sext? DecodeField @@ -2740,7 +3180,7 @@

    Method List

  • -
  • +
  • #signed? Idl::Type @@ -2748,7 +3188,7 @@

    Method List

  • -
  • +
  • #size EncodingField @@ -2756,7 +3196,7 @@

    Method List

  • -
  • +
  • #size DecodeVariable @@ -2764,7 +3204,7 @@

    Method List

  • -
  • +
  • #size DecodeField @@ -2772,7 +3212,7 @@

    Method List

  • -
  • +
  • #size Instruction::Encoding @@ -2780,7 +3220,7 @@

    Method List

  • -
  • +
  • #size_in_encoding DecodeVariable @@ -2788,7 +3228,7 @@

    Method List

  • -
  • +
  • #size_in_encoding DecodeField @@ -2796,7 +3236,7 @@

    Method List

  • -
  • +
  • #split? DecodeVariable @@ -2804,7 +3244,7 @@

    Method List

  • -
  • +
  • #split? DecodeField @@ -2812,7 +3252,7 @@

    Method List

  • -
  • +
  • #statements Idl::FunctionBodyAst @@ -2820,6 +3260,14 @@

    Method List

  • +
  • +
    + #stmts + Idl::IfBodyAst +
    +
  • + +
  • #sub_type @@ -2869,6 +3317,14 @@

    Method List

  • +
    + #template_index + Idl::Var +
    +
  • + + +
  • #template_names Idl::FunctionDefAst @@ -2876,7 +3332,7 @@

    Method List

  • -
  • +
  • #template_names Idl::FunctionType @@ -2884,7 +3340,7 @@

    Method List

  • -
  • +
  • #template_types Idl::FunctionDefAst @@ -2892,7 +3348,7 @@

    Method List

  • -
  • +
  • #template_types Idl::FunctionType @@ -2900,10 +3356,18 @@

    Method List

  • +
  • +
    + #template_val? + Idl::Var +
    +
  • + +
  • - #template_types - Idl::TemplateFunctionType + #template_value_for? + Idl::Var
  • @@ -2932,6 +3396,86 @@

    Method List

    +
  • + +
  • + + +
  • + +
  • + + +
  • +
    + #test_that_values_are_tuncated + TestExpressions +
    +
  • + + +
  • +
    + #to_ast + Treetop::Runtime::SyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::AryAccessSyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::BinaryExpressionRightSyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::StatementSyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::ConditionalStatementSyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::FunctionBodySyntaxNode +
    +
  • + + +
  • +
    + #to_ast + Idl::IfSyntaxNode +
    +
  • + +
  • #to_cxx @@ -3014,8 +3558,24 @@

    Method List

  • - #to_idl - Idl::AryAccess + #to_idl + Idl::AryAccessSyntaxNode +
    +
  • + + +
  • +
    + #to_idl + Idl::AryElementAccessAst +
    +
  • + + +
  • +
    + #to_idl + Idl::AryRangeAccessAst
  • @@ -3077,6 +3637,14 @@

    Method List

  • +
    + #to_idl + Idl::VariableDeclarationWithInitializationAst +
    +
  • + + +
  • #to_idl Idl::SignCastAst @@ -3084,7 +3652,7 @@

    Method List

  • -
  • +
  • #to_idl Idl::BitsCastAst @@ -3092,175 +3660,287 @@

    Method List

  • +
  • +
    + #to_idl + Idl::BinaryExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::ParenExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::ArrayLiteralAst +
    +
  • + + +
  • +
    + #to_idl + Idl::ConcatenationExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::ReplicationExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::PostDecrementExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::PostIncrementExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::BitfieldAccessExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::EnumRefAst +
    +
  • + + +
  • +
    + #to_idl + Idl::UnaryOperatorExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::TernaryOperatorExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::VarReadExpressionAst +
    +
  • + + +
  • +
    + #to_idl + Idl::NoopAst +
    +
  • + +
  • - #to_idl - Idl::BinaryExpressionAst + #to_idl + Idl::StatementAst
  • - #to_idl - Idl::ParenExpressionAst + #to_idl + Idl::ConditionalStatementAst
  • - #to_idl - Idl::ArrayLiteralAst + #to_idl + Idl::DontCareReturnAst
  • - #to_idl - Idl::ConcatenationExpressionAst + #to_idl + Idl::DontCareLvalueAst
  • - #to_idl - Idl::ReplicationExpressionAst + #to_idl + Idl::ReturnStatementAst
  • - #to_idl - Idl::PostDecrementExpressionAst + #to_idl + Idl::BitsTypeAst
  • - #to_idl - Idl::PostIncrementExpressionAst + #to_idl + Idl::BuiltinTypeNameAst
  • - #to_idl - Idl::BitfieldAccessExpressionAst + #to_idl + Idl::IntAst
  • - #to_idl - Idl::EnumRefAst + #to_idl + Idl::FunctionCallExpressionAst
  • - #to_idl - Idl::UnaryOperatorExpressionAst + #to_idl + Idl::UserTypeNameAst
  • - #to_idl - Idl::TernaryOperatorExpressionAst + #to_idl + Idl::FieldNameAst
  • - #to_idl - Idl::VarReadExpressionAst + #to_idl + Idl::InstructionOperationAst
  • - #to_idl - Idl::StatementAst + #to_idl + Idl::FunctionBodyAst
  • - #to_idl - Idl::DontCareReturnAst + #to_idl + Idl::ForLoopAst
  • - #to_idl - Idl::DontCareLvalueAst + #to_idl + Idl::IfBodyAst
  • - #to_idl - Idl::ReturnStatementAst + #to_idl + Idl::ElseIfAst
  • - #to_idl - Idl::IntAst + #to_idl + Idl::IfAst
  • - #to_idl - Idl::UserTypeNameAst + #to_idl + Idl::CsrFieldReadExpressionAst
  • - #to_idl - Idl::FunctionBodyAst + #to_idl + Idl::CsrReadExpressionAst
  • - #to_idl - Idl::IfAst + #to_idl + Idl::CsrSoftwareWriteAst
  • - #to_idl - Idl::CsrFieldReadExpressionAst + #to_idl + Idl::CsrSoftwareReadAst
  • +
    + #to_idl + Idl::CsrWriteAst +
    +
  • + + +
  • #to_s Idl::Type @@ -3268,7 +3948,7 @@

    Method List

  • -
  • +
  • #to_s Idl::XregType @@ -3276,7 +3956,7 @@

    Method List

  • -
  • +
  • #true_expression Idl::TernaryOperatorExpressionAst @@ -3284,7 +3964,7 @@

    Method List

  • -
  • +
  • #tuple_types Idl::Type @@ -3292,7 +3972,7 @@

    Method List

  • -
  • +
  • #type Idl::Rvalue @@ -3300,7 +3980,7 @@

    Method List

  • -
  • +
  • #type Idl::IdAst @@ -3308,7 +3988,7 @@

    Method List

  • -
  • +
  • #type Idl::GlobalWithInitializationAst @@ -3316,7 +3996,7 @@

    Method List

  • -
  • +
  • #type Idl::GlobalAst @@ -3324,7 +4004,7 @@

    Method List

  • -
  • +
  • #type Idl::EnumDefinitionAst @@ -3332,7 +4012,7 @@

    Method List

  • -
  • +
  • #type Idl::BuiltinEnumDefinitionAst @@ -3340,7 +4020,7 @@

    Method List

  • -
  • +
  • #type Idl::BitfieldDefinitionAst @@ -3348,7 +4028,7 @@

    Method List

  • -
  • +
  • #type Idl::AryElementAccessAst @@ -3356,7 +4036,7 @@

    Method List

  • -
  • +
  • #type Idl::AryRangeAccessAst @@ -3364,7 +4044,7 @@

    Method List

  • -
  • +
  • #type Idl::FieldAssignmentAst @@ -3372,7 +4052,7 @@

    Method List

  • -
  • +
  • #type Idl::SignCastAst @@ -3380,7 +4060,7 @@

    Method List

  • -
  • +
  • #type Idl::BitsCastAst @@ -3388,7 +4068,7 @@

    Method List

  • -
  • +
  • #type Idl::BinaryExpressionAst @@ -3396,7 +4076,7 @@

    Method List

  • -
  • +
  • #type Idl::ParenExpressionAst @@ -3404,7 +4084,7 @@

    Method List

  • -
  • +
  • #type Idl::ArrayLiteralAst @@ -3412,7 +4092,7 @@

    Method List

  • -
  • +
  • #type Idl::ConcatenationExpressionAst @@ -3420,7 +4100,7 @@

    Method List

  • -
  • +
  • #type Idl::ReplicationExpressionAst @@ -3428,7 +4108,7 @@

    Method List

  • -
  • +
  • #type Idl::PostDecrementExpressionAst @@ -3436,7 +4116,7 @@

    Method List

  • -
  • +
  • #type Idl::PostIncrementExpressionAst @@ -3444,7 +4124,7 @@

    Method List

  • -
  • +
  • #type Idl::BitfieldAccessExpressionAst @@ -3452,7 +4132,7 @@

    Method List

  • -
  • +
  • #type Idl::EnumRefAst @@ -3460,7 +4140,7 @@

    Method List

  • -
  • +
  • #type Idl::UnaryOperatorExpressionAst @@ -3468,7 +4148,7 @@

    Method List

  • -
  • +
  • #type Idl::TernaryOperatorExpressionAst @@ -3476,7 +4156,7 @@

    Method List

  • -
  • +
  • #type Idl::VarReadExpressionAst @@ -3484,7 +4164,7 @@

    Method List

  • -
  • +
  • #type Idl::DontCareReturnAst @@ -3492,7 +4172,7 @@

    Method List

  • -
  • +
  • #type Idl::DontCareLvalueAst @@ -3500,7 +4180,7 @@

    Method List

  • -
  • +
  • #type Idl::BitsTypeAst @@ -3508,7 +4188,7 @@

    Method List

  • -
  • +
  • #type Idl::BuiltinTypeNameAst @@ -3516,7 +4196,7 @@

    Method List

  • -
  • +
  • #type Idl::IntAst @@ -3524,7 +4204,7 @@

    Method List

  • -
  • +
  • #type Idl::FunctionCallExpressionAst @@ -3532,7 +4212,7 @@

    Method List

  • -
  • +
  • #type Idl::UserTypeNameAst @@ -3540,7 +4220,7 @@

    Method List

  • -
  • +
  • #type Idl::CsrFieldReadExpressionAst @@ -3548,7 +4228,7 @@

    Method List

  • -
  • +
  • #type Idl::CsrReadExpressionAst @@ -3556,7 +4236,7 @@

    Method List

  • -
  • +
  • #type Idl::CsrSoftwareReadAst @@ -3564,7 +4244,7 @@

    Method List

  • -
  • +
  • #type Idl::CsrWriteAst @@ -3572,7 +4252,7 @@

    Method List

  • -
  • +
  • #type CsrField @@ -3580,7 +4260,7 @@

    Method List

  • -
  • +
  • #type Idl::Var @@ -3588,7 +4268,7 @@

    Method List

  • -
  • +
  • #type_check Idl::AstNodeFuncs @@ -3596,7 +4276,7 @@

    Method List

  • -
  • +
  • #type_check Idl::IdAst @@ -3604,7 +4284,7 @@

    Method List

  • -
  • +
  • #type_check Idl::GlobalWithInitializationAst @@ -3612,7 +4292,7 @@

    Method List

  • -
  • +
  • #type_check Idl::GlobalAst @@ -3620,7 +4300,7 @@

    Method List

  • -
  • +
  • #type_check Idl::IsaAst @@ -3628,7 +4308,7 @@

    Method List

  • -
  • +
  • #type_check Idl::EnumDefinitionAst @@ -3636,7 +4316,7 @@

    Method List

  • -
  • +
  • #type_check Idl::BuiltinEnumDefinitionAst @@ -3644,7 +4324,7 @@

    Method List

  • -
  • +
  • #type_check Idl::BitfieldDefinitionAst @@ -3652,7 +4332,7 @@

    Method List

  • -
  • +
  • #type_check Idl::AryElementAccessAst @@ -3660,7 +4340,7 @@

    Method List

  • -
  • +
  • #type_check Idl::AryRangeAccessAst @@ -3668,7 +4348,7 @@

    Method List

  • -
  • +
  • #type_check Idl::VariableAssignmentAst @@ -3676,7 +4356,7 @@

    Method List

  • -
  • +
  • #type_check Idl::AryElementAssignmentAst @@ -3684,7 +4364,7 @@

    Method List

  • -
  • +
  • #type_check Idl::AryRangeAssignmentAst @@ -3692,7 +4372,7 @@

    Method List

  • -
  • +
  • #type_check Idl::FieldAssignmentAst @@ -3700,7 +4380,7 @@

    Method List

  • -
  • +
  • #type_check Idl::MultiVariableAssignmentAst @@ -3708,7 +4388,7 @@

    Method List

  • -
  • +
  • #type_check Idl::MultiVariableDeclarationAst @@ -3716,7 +4396,7 @@

    Method List

  • -
  • +
  • #type_check Idl::VariableDeclarationAst @@ -3724,7 +4404,7 @@

    Method List

  • -
  • +
  • #type_check Idl::VariableDeclarationWithInitializationAst @@ -3732,15 +4412,15 @@

    Method List

  • -
  • +
  • - #type_check - Idl::BinaryExpressionRightAst + #type_check + Idl::BinaryExpressionRightSyntaxNode
  • -
  • +
  • #type_check Idl::SignCastAst @@ -3748,7 +4428,7 @@

    Method List

  • -
  • +
  • #type_check Idl::BitsCastAst @@ -3756,7 +4436,7 @@

    Method List

  • -
  • +
  • #type_check Idl::BinaryExpressionAst @@ -3764,7 +4444,7 @@

    Method List

  • -
  • +
  • #type_check Idl::ParenExpressionAst @@ -3772,7 +4452,7 @@

    Method List

  • -
  • +
  • #type_check Idl::ArrayLiteralAst @@ -3780,7 +4460,7 @@

    Method List

  • -
  • +
  • #type_check Idl::ConcatenationExpressionAst @@ -3788,7 +4468,7 @@

    Method List

  • -
  • +
  • #type_check Idl::ReplicationExpressionAst @@ -3796,7 +4476,7 @@

    Method List

  • -
  • +
  • #type_check Idl::PostDecrementExpressionAst @@ -3804,7 +4484,7 @@

    Method List

  • -
  • +
  • #type_check Idl::PostIncrementExpressionAst @@ -3812,7 +4492,7 @@

    Method List

  • -
  • +
  • #type_check Idl::BitfieldAccessExpressionAst @@ -3820,7 +4500,7 @@

    Method List

  • -
  • +
  • #type_check Idl::EnumRefAst @@ -3828,7 +4508,7 @@

    Method List

  • -
  • +
  • #type_check Idl::UnaryOperatorExpressionAst @@ -3836,7 +4516,7 @@

    Method List

  • -
  • +
  • #type_check Idl::TernaryOperatorExpressionAst @@ -3844,7 +4524,7 @@

    Method List

  • -
  • +
  • #type_check Idl::VarReadExpressionAst @@ -3852,6 +4532,14 @@

    Method List

  • +
  • +
    + #type_check + Idl::NoopAst +
    +
  • + +
  • #type_check @@ -3980,6 +4668,22 @@

    Method List

  • +
  • +
    + #type_check + Idl::IfBodyAst +
    +
  • + + +
  • +
    + #type_check + Idl::ElseIfAst +
    +
  • + +
  • #type_check @@ -4372,6 +5076,22 @@

    Method List

  • +
  • +
    + #values + Idl::Rvalue +
    +
  • + + +
  • +
    + #values + Idl::TernaryOperatorExpressionAst +
    +
  • + +
  • #var diff --git a/docs/ruby/top-level-namespace.html b/docs/ruby/top-level-namespace.html index 73b4ebc40..a460931e3 100644 --- a/docs/ruby/top-level-namespace.html +++ b/docs/ruby/top-level-namespace.html @@ -86,7 +86,7 @@

    Defined Under Namespace

    - Classes: ArchDef, ArchDefObject, ArchGen, Csr, CsrField, DecodeField, DecodeVariable, EncodingField, Extension, ExtensionVersion, Instruction, Validator + Classes: ArchDef, ArchDefObject, ArchGen, Csr, CsrField, DecodeField, DecodeVariable, EncodingField, Extension, ExtensionVersion, Instruction, TestExpressions, Validator

    @@ -102,7 +102,7 @@

    Defined Under Namespace

    diff --git a/lib/arch_def.rb b/lib/arch_def.rb index 4c002f698..5a60fa018 100644 --- a/lib/arch_def.rb +++ b/lib/arch_def.rb @@ -1,16 +1,13 @@ # frozen_string_literal: true require "forwardable" -# require "treetop" -require_relative "opcodes" + require_relative "validate" require_relative "idl" require_relative "idl/passes/find_return_values" require_relative "idl/passes/gen_adoc" -# require_relative "ast/ast" -# require_relative "ast/gen_adoc" +require_relative "idl/passes/prune" -# Treetop.load("arch/isa/isa") # base for any object representation of the Architecture Definition # does two things: @@ -862,11 +859,44 @@ module RiscvOpcodes # model of a specific instruction in a specific base (RV32/RV64) class Instruction < ArchDefObject - # @return [Idl::AstNode] Abstract syntax tree of the instruction operation() - def operation_ast - parse_operation(@sym_table) if @operation_ast.nil? + def fill_symtab(global_symtab) + symtab = global_symtab.deep_clone(clone_values: true) + symtab.push + symtab.add( + "__instruction_encoding_size", + Idl::Var.new("__instruction_encoding_size", Idl::Type.new(:bits, width:encoding_width.bit_length), encoding_width) + ) + @encodings[symtab.archdef.config_params["XLEN"]].decode_variables.each do |d| + qualifiers = [] + qualifiers << :signed if d.sext? + width = d.size - @operation_ast + var = Idl::Var.new(d.name, Idl::Type.new(:bits, qualifiers:, width:), decode_var: true) + symtab.add(d.name, var) + end + + symtab + end + private :fill_symtab + + # type check the instruction operation in the context of symtab + # + # @param global_symtab [Idl::SymbolTable] A symbol table with global scope populated + # @raise Idl::AstNode::TypeError if there is a type problem + def type_check_operation(global_symtab) + global_symtab.archdef.idl_compiler.type_check( + operation_ast(global_symtab.archdef.idl_compiler), + fill_symtab(global_symtab), + "#{name}.operation()" + ) + end + + # @param global_symtab [Idl::SymbolTable] Symbol table with global scope populated and a configuration loaded + # @return [Idl::FunctionBodyAst] A pruned abstract syntax tree + def pruned_operation_ast(global_symtab) + type_check_operation(global_symtab) + puts "PRUNING #{name}" + operation_ast(global_symtab.archdef.idl_compiler).prune(fill_symtab(global_symtab)) end # @return [ArchDef] The architecture definition @@ -929,7 +959,7 @@ def initialize(format, decode_vars) end @decode_variables = [] - decode_vars.each do |var| + decode_vars&.each do |var| @decode_variables << DecodeVariable.new(self, var) end end @@ -944,158 +974,57 @@ def load_encoding @encodings = {} if @data["encoding"].key?("RV32") # there are different encodings for RV32/RV64 - @encodings[32] = Encoding.new(@data["encoding"]["RV32"]["mask"], @data["encoding"]["RV32"]["fields"]) - @encodings[64] = Encoding.new(@data["encoding"]["RV64"]["mask"], @data["encoding"]["RV64"]["fields"]) + @encodings[32] = Encoding.new(@data["encoding"]["RV32"]["match"], @data["encoding"]["RV32"]["variables"]) + @encodings[64] = Encoding.new(@data["encoding"]["RV64"]["match"], @data["encoding"]["RV64"]["variables"]) elsif @data.key("base") - @encodings[@data["base"]] = Encoding.new(@data["encoding"]["mask"], @data["encoding"]["fields"]) + @encodings[@data["base"]] = Encoding.new(@data["encoding"]["match"], @data["encoding"]["variables"]) else - @encodings[32] = Encoding.new(@data["encoding"]["mask"], @data["encoding"]["fields"]) - @encodings[64] = Encoding.new(@data["encoding"]["mask"], @data["encoding"]["fields"]) + @encodings[32] = Encoding.new(@data["encoding"]["match"], @data["encoding"]["variables"]) + @encodings[64] = Encoding.new(@data["encoding"]["match"], @data["encoding"]["variables"]) end end private :load_encoding - # @params inst_data [Hash] Instruction data from the architecture spec - # @params full_opcode_data [Hash] Opcode data to interpret riscv-opcodes -- this will be deprecated - # @params sym_table [Idl::SymbolTable] Symbol table with global names - # @params arch_def [ArchDef] The architecture definition - def initialize(inst_data, full_opcode_data, sym_table, arch_def) - @arch_def = arch_def - @sym_table = sym_table.deep_clone - - super(inst_data) - - if inst_data.key?("encoding") - load_encoding - else - opcode_data_key = name.downcase.gsub(".", "_") - raise "opcode data not found for #{name}" unless full_opcode_data.key?(opcode_data_key) - - opcode_data = full_opcode_data[opcode_data_key] - encoding_mask = opcode_data["encoding"] - - opcode_fields = [] - msb = encoding_mask.size - encoding_mask.split("-").each do |e| - if e.empty? - msb -= 1 - else - opcode_fields << Encoding::Field.new(e, (msb - e.size + 1)..msb) - msb -= e.size - end - end - - - decode_variables = [] - opcode_data["variable_fields"].to_a.each do |f| - decode_field_data = RiscvOpcodes::VARIABLE_FIELDS.to_a.select do |d| - d[0] == f || (d[0].is_a?(Array) && d[0].any?(f)) - end - raise "didn't find '#{f}' in DECODER_RING" if decode_field_data.empty? - - raise "Found multiple matches for '#{f}' in DECODER_RING" if decode_field_data.size > 1 - - data = decode_field_data[0][1] - names = [] - if data.key?(:decode_variable) - if data[:decode_variable].is_a?(String) - names << data[:decode_variable] - else - raise "unexpected" unless data[:decode_variable].is_a?(Array) - - names = data[:decode_variable] - end - else - raise "?" unless decode_field_data[0][0].is_a?(String) - - names = [decode_field_data[0][0]] - end - - names.each do |name| - decode_variables << DecodeField.new(self, name, decode_field_data[0][0], decode_field_data[0][1]) - end - end - decode_variables.uniq! - - @encodings ||= {} - klass = Struct.new(:opcode_fields, :decode_variables) - @encodings[32] = klass.new(opcode_fields, decode_variables) - @encodings[64] = klass.new(opcode_fields, decode_variables) - end - end - # @return [Boolean] whether or not this instruction has different encodings depending on XLEN def multi_encoding? @data.key?("encoding") && @data["encoding"].key?("RV32") end - # @return [String] The operation() IDL code - def operation_source - return "" if @data["operation()"].nil? - - operation_ast.gen_adoc.gsub("{{", '\((') - # @data['operation'] - end + # @return [FunctionBodyAst] The abstract syntax tree of the instruction operation + def operation_ast(idl_compiler) + return @operation_ast unless @operation_ast.nil? + return nil if @data["operation()"].nil? - def parse_operation(sym_table) # now, parse the operation - return if @data["operation()"].nil? || !@operation_ast.nil? - - cloned_symtab = sym_table.deep_clone - - cloned_symtab.push - @encodings[@arch_def.config_params["XLEN"]].decode_variables.each do |d| - qualifiers = [] - qualifiers << :signed if d.sext? - width = d.size - var = Idl::Var.new(d.name, Idl::Type.new(:bits, qualifiers:, width:), decode_var: true) - cloned_symtab.add(d.name, var) - end - - m = arch_def.idl_compiler.compile_inst_operation( - @data["operation()"], - symtab: cloned_symtab, - name:, - parent: nil, + @operation_ast = idl_compiler.compile_inst_operation( + self, input_file: "Instruction #{name}" ) - cloned_symtab.pop + raise "unexpected #{@operation_ast.class}" unless @operation_ast.is_a?(Idl::FunctionBodyAst) - raise "unexpected #{m.class}" unless m.is_a?(Idl::InstructionOperationAst) + @operation_ast + end - m.make_left # fix up right recursion + # @param base [Integer] 32 or 64 + # @return [Encoding] the encoding + def encoding(base) + load_encoding if @encodings.nil? - @operation_ast = m + @encodings[base] end - private :parse_operation - # @return [String] the encoding as, e.g.,: - # 0000101----------001-----0110011 - def encoding(base) - @encodings[base].format + # @return [Integer] the width of the encoding + def encoding_width + raise "unexpected: encodings are different sizes" unless encoding(32).size == encoding(64).size + + encoding(64).size end # @return [Array] The decode variables def decode_variables(base) - @encodings[base].decode_variables - end - - # def encoding_variable_fields - # @decode_variables.map(&:decode_variable).flatten - # end - - # @return [String] the extension that defines this instruction - # @return [Array] the extensions that define this instruction - def extension - @data["definedBy"] - # parts = @data["extension"][0].split("_") - # if @data["definedBy"].is_a?(String) - # parts[1].capitalize - # else - # parts[1..].map(&:capitalize) - # end + encoding(base).decode_variables end # @return [Boolean] true if the instruction has an 'access_detail' field @@ -1112,8 +1041,8 @@ def wavedrom_desc(base) "reg" => [] } - display_fields = @encodings[base].opcode_fields - display_fields += @encodings[base].decode_variables.map(&:grouped_encoding_fields).flatten + display_fields = encoding(base).opcode_fields + display_fields += encoding(base).decode_variables.map(&:grouped_encoding_fields).flatten display_fields.sort { |a, b| b.range.last <=> a.range.last }.reverse.each do |e| desc["reg"] << { "bits" => e.range.size, "name" => e.name, "type" => (e.opcode? ? 2 : 4) } @@ -1121,6 +1050,136 @@ def wavedrom_desc(base) desc end + + # @return [Boolean] whether or not this instruction is defined for RV32 + def rv32? + !@data.key?("base") || base == 32 + end + + # @return [Boolean] whether or not this instruction is defined for RV64 + def rv64? + !@data.key?("base") || base == 64 + end + + def extension_requirement?(obj) + obj.is_a?(String) && obj =~ /^([A-WY])|([SXZ][a-z]+)$/ || + obj.is_a?(Array) && obj[0] =~ /^([A-WY])|([SXZ][a-z]+)$/ + end + private :extension_requirement? + + def to_extension_requirement(obj) + if obj.is_a?(String) + ExtensionRequirement.new(obj, ">= 0") + else + ExtensionRequirement.new(*obj) + end + end + private :to_extension_requirement + + # @return [Array] Extension requirements for the instruction. If *any* requirement is met, the instruction is defined + def extension_requirements + return @extension_requirements unless @extension_requirements.nil? + + @extension_requirements = [] + if @data["definedBy"].is_a?(Array) + # could be either a single extension with requirement, or a list of requirements + if extension_requirement?(@data["definedBy"][0]) + @extension_requirements << to_extension_requirement(@data["definedBy"][0]) + else + # this is a list + @data["definedBy"].each do |r| + @extension_requirements << to_extension_requirement(r) + end + end + else + @extension_requirements << to_extension_requirement(@data["definedBy"]) + end + + raise "empty requirements" if @extension_requirements.empty? + + @extension_requirements + end + + # @return [Array] Extension exclusions for the instruction. If *any* exclusion is met, the instruction is not defined + def extension_exclusions + return @extension_exclusions unless @extension_excludions.nil? + + @extension_exclusions = [] + if @data.key?("excludedBy") + if @data["exludedBy"].is_a?(Array) + # could be either a single extension with exclusion, or a list of exclusions + if extension_exclusion?(@data["definedBy"][0]) + @extension_exclusions << to_extension_requirement(@data["excludedBy"][0]) + else + # this is a list + @data["excludeddBy"].each do |r| + @extension_exclusions << to_extension_exclusion(r) + end + end + else + @extension_exclusions << to_extension_requirement(@data["excludedBy"]) + end + end + + @extension_exclusions + end + + # @overload defined_by?(ext_name, ext_version) + # @param ext_name [#to_s] An extension name + # @param ext_version [#to_s] A specific extension version + # @return [Boolean] Whether or not the instruction is defined by extesion `ext`, version `version` + # @overload defined_by?(ext_version) + # @param ext_version [ExtensionVersion] An extension version + # @return [Boolean] Whether or not the instruction is defined by ext_version + def defined_by?(*args) + if args.size == 1 + raise ArgumentError, "Parameter must be an ExtensionVersion" unless args[0].is_a?(ExtensionVersion) + + extension_requirements.any? do |r| + r.satisfied_by?(args[0]) + end + elsif args.size == 2 + raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) + raise ArgumentError, "Second parameter must be an extension version" unless args[0].respond_to?(:to_s) + + extension_requirements.any? do |r| + r.satisfied_by?(args[0].to_s, args[1].to_s) + end + end + end + + # @overload excluded_by?(ext_name, ext_version) + # @param ext_name [#to_s] An extension name + # @param ext_version [#to_s] A specific extension version + # @return [Boolean] Whether or not the instruction is excluded by extesion `ext`, version `version` + # @overload excluded_by?(ext_version) + # @param ext_version [ExtensionVersion] An extension version + # @return [Boolean] Whether or not the instruction is excluded by ext_version + def excluded_by?(*args) + if args.size == 1 + raise ArgumentError, "Parameter must be an ExtensionVersion" unless args[0].is_a?(ExtensionVersion) + + extension_exclusions.any? do |r| + r.satisfied_by?(args[0]) + end + elsif args.size == 2 + raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) + raise ArgumentError, "Second parameter must be an extension version" unless args[0].respond_to?(:to_s) + + extension_exclusions.any? do |r| + r.satisfied_by?(args[0].to_s, args[1].to_s) + end + end + end + + # @param possible_xlens [Array] List of xlens that be used in any implemented mode + # @param extensions [Array] List of extensions implemented + # @return [Boolean] whether or not the instruction is implemented given the supplies config options + def exists_in_cfg?(possible_xlens, extensions) + (@data["base"].nil? || (possible_xlens.include?(@data["base"]))) && + extensions.any? { |e| defined_by?(e) } && + extensions.none? { |e| excluded_by?(e) } + end end # Extension definition @@ -1135,16 +1194,30 @@ def initialize(ext_data, arch_def) @arch_def = arch_def end - # @return [Array] Array of extensions implied by this one - def implies - case @data["implies"] - when nil - [] - when Array - @data["implies"] - else - [@data["implies"]] + # @param version_requirement [String] Version requirement + # @return [Array] Array of extensions implied by any version of this extension meeting version_requirement + def implies(version_requirement = ">= 0") + implications = [] + @data["versions"].each do |v| + next unless Gem::Requirement.new(version_requirement).satisfied_by?(Gem::Version.new(v["version"])) + + case v["implies"] + when nil + next + when Array + if v["implies"][0].is_a?(Array) + implications += v["implies"].map { |e| ExtensionVersion.new(e[0], e[1])} + else + implications << ExtensionVersion.new(v["implies"][0], v["implies"][1]) + end + end end + implications + end + + # returns the list of instructions implemented by this extension + def instructions + arch_def.instructions.select { |i| i.definedBy == name || (i.definedBy.is_a?(Array) && i.definedBy.include?(name)) } end end @@ -1156,20 +1229,13 @@ class ExtensionVersion # @return [Gem::Version] Version of the extension attr_reader :version - # @return [ArchDef] Owning ArchDef - attr_reader :arch_def - - # @return [Extension] The full definition of the extension (all versions) - attr_reader :extension # @param name [#to_s] The extension name # @param version [Integer,String] The version specifier # @param arch_def [ArchDef] The architecture definition - def initialize(name, version, arch_def) + def initialize(name, version) @name = name.to_s @version = Gem::Version.new(version) - @arch_def = arch_def - @extension = @arch_def.extension(@name) end # @override ==(other) @@ -1209,6 +1275,52 @@ def <=>(other) end end +# represents an extension requirement, that is an extension name paired with version requirement(s) +class ExtensionRequirement + # @return [String] Extension name + attr_reader :name + + # @return [Gem::Requirement] Version requirement + def version_requirement + @requirement + end + + def initialize(name, *requirements) + @name = name + requirements = + if requirements.empty? + [">= 0"] + else + requirements + end + @requirement = Gem::Requirement.new(requirements) + end + + # @overload + # @param extension_version [ExtensionVersion] A specific extension version + # @return [Boolean] whether or not the extension_version meets 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)) + 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) + + args[0] == @name && + @requirement.satisfied_by?(Gem::Version.new(args[1])) + else + raise ArgumentError, "Wrong number of args (expecting 1 or 2)" + end + end +end + # Object model for a configured architecture definition class ArchDef # @return [String] Name of the architecture configuration @@ -1268,8 +1380,8 @@ def implemented_extensions @implemented_extensions = [] @arch_def["implemented_extensions"].each do |e| - @implemented_extensions << ExtensionVersion.new(e["name"], e["version"], self) - end + @implemented_extensions << ExtensionVersion.new(e["name"], e["version"]) +2 end @implemented_extensions end @@ -1395,10 +1507,8 @@ def csr(csr_name) def instructions return @instructions unless @instructions.nil? - opcode_data = YAML.load_file("#{$root}/ext/riscv-opcodes/instr_dict.yaml") - @instructions = @arch_def["instructions"].map do |_inst_name, inst_data| - Instruction.new(inst_data, opcode_data, @sym_table, self) + Instruction.new(inst_data) end @instructions @@ -1445,13 +1555,13 @@ def find_replace_links(adoc) csr_name, field_name = name.split(".") csr = csr(csr_name) if !field_name.nil? && !csr.nil? && csr.field?(field_name) - "%%LINK[csr_field;#{csr_name}.#{field_name};#{csr_name}.#{field_name}]%%" + "%%LINK%csr_field;#{csr_name}.#{field_name};#{csr_name}.#{field_name}%%" elsif !csr.nil? - "%%LINK[csr;#{csr_name};#{csr_name}]%%" + "%%LINK%csr;#{csr_name};#{csr_name}%%" elsif inst(name.downcase) - "%%LINK[inst;#{name};#{name}]%%" + "%%LINK%inst;#{name};#{name}%%" elsif extension(name) - "%%LINK[ext;#{name};#{name}]%%" + "%%LINK%ext;#{name};#{name}%%" else match end diff --git a/lib/arch_gen.rb b/lib/arch_gen.rb index 91367cb09..5e61b9be2 100644 --- a/lib/arch_gen.rb +++ b/lib/arch_gen.rb @@ -9,6 +9,7 @@ require "yaml" require_relative "validate" +require_relative "arch_def" $root = Pathname.new(__FILE__).dirname.dirname.realpath if $root.nil? @@ -281,7 +282,7 @@ def ext?(ext_name, ext_version = nil) # @params type [Symbol] Type (:section, :csr, :inst, :ext) # @params name [#to_s] Name of the object def link_to(type, name) - "%%LINK[#{type};#{name}]%%" + "%%LINK%#{type};#{name}%%" end # info on interrupt and exception codes @@ -717,48 +718,47 @@ def maybe_add_inst(inst_name, extra_env = {}) merged_path = gen_merged_def(:inst, arch_path, arch_overlay_path) # get the inst data (not including the name key), which is redundant at this point - inst_obj = YAML.load_file(merged_path)[inst_name] - inst_obj["name"] = inst_name + inst_data = YAML.load_file(merged_path)[inst_name] + inst_data["name"] = inst_name - defined_in = inst_obj["definedBy"] - defined_in = [defined_in] unless defined_in.is_a?(Array) - - excluded_by = inst_obj.key?("excluded_by") ? inst_obj["excluded_by"] : [] - excluded_by = [excluded_by] unless excluded_by.is_a?(Array) - - - unless inst_obj.key?("encoding") - raise "no riscv-opcode data for #{inst_obj['name']}" unless @opcode_data.key?(inst_obj["name"].tr(".", "_")) - - opcode_str = @opcode_data[inst_obj["name"].tr(".", "_")]["extension"][0] - - raise "Bad opcode string" unless opcode_str =~ /rv((32)|(64))?_([a-zA-Z0-9]+)/ - - base = ::Regexp.last_match(1) - riscv_opcodes_extension = ::Regexp.last_match(4) - warn "Found #{inst_obj['name']} in unexpected extension (#{riscv_opcodes_extension})" unless defined_in.include?(riscv_opcodes_extension.capitalize) + inst_yaml = YAML.dump({ inst_name => inst_data}) + begin + inst_data = @validator.validate_str(inst_yaml, type: :inst) + rescue Validator::ValidationError => e + warn "Instruction definition in #{gen_inst_path} did not validate" + raise e end - inst_obj["base"] = base.to_i unless base.nil? - - # add the instruction, unless it is from an extension not supported in this config + inst_obj = Instruction.new(inst_data[inst_name]) + possible_xlens = [@params["XLEN"]] + if @cfg["extensions"].any? { |e| e[0] == "S" } + possible_xlens << 32 if [32, 3264].include?(@params["SXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["SXLEN"]) + end + if @cfg["extensions"].any? { |e| e[0] == "U" } + possible_xlens << 32 if [32, 3264].include?(@params["UXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["UXLEN"]) + end + if @cfg["extensions"].any? { |e| e[0] == "H" } + possible_xlens << 32 if [32, 3264].include?(@params["VSXLEN"]) + possible_xlens << 32 if [32, 3264].include?(@params["VUXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["VSXLEN"]) + possible_xlens << 64 if [64, 3264].include?(@params["VUXLEN"]) + end belongs = - (base.nil? || (base.to_i == @params["XLEN"])) && - @cfg["extensions"].any? { |e| defined_in.map(&:downcase).include?(e[0].downcase) } && - @cfg["extensions"].none? { |e| excluded_by.map(&:downcase).include?(e[0].downcase) } + inst_obj.exists_in_cfg?( + possible_xlens.uniq, + @cfg["extensions"].map { |e| ExtensionVersion.new(e[0], e[1]) } + ) + @implemented_instructions ||= [] @implemented_instructions << inst_name if belongs - gen_inst_path = @gen_dir / "arch" / "inst" / defined_in[0] / "#{inst_name}.yaml" + raise "?" if inst_obj.extension_requirements[0].name.nil? + gen_inst_path = @gen_dir / "arch" / "inst" / inst_obj.extension_requirements[0].name / "#{inst_name}.yaml" FileUtils.mkdir_p gen_inst_path.dirname - gen_inst_path.write YAML.dump({ inst_name => inst_obj }) + gen_inst_path.write inst_yaml - begin - @validator.validate_str(File.read(gen_inst_path), type: :inst) - rescue Validator::ValidationError => e - warn "Instruction definition in #{gen_inst_path} did not validate" - raise e - end # @instructions << inst_def # @inst_hash ||= {} diff --git a/lib/idl.rb b/lib/idl.rb index b41beb414..c8e28bb41 100644 --- a/lib/idl.rb +++ b/lib/idl.rb @@ -56,17 +56,17 @@ def compile_file(path, symtab) raise "unexpected type #{m.class.name}" unless m.is_a?(IsaAst) - m.make_left + ast = m.to_ast - m.set_input_file(path.to_s) + ast.set_input_file(path.to_s) begin - m.type_check(symtab) + ast.type_check(symtab) rescue AstNode::TypeError, AstNode::InternalError => e warn e.what warn e.bt exit 1 end - m + ast end # compile a function body, and return the abstract syntax tree @@ -88,8 +88,8 @@ def compile_func_body(body, return_type: nil, symtab: SymbolTable.new, name: nil cloned_symtab.pop end - ast = @parser.parse(body, root: :function_body) - if ast.nil? + m = @parser.parse(body, root: :function_body) + if m.nil? raise SyntaxError, <<~MSG While parsing #{parent}::#{name} #{@parser.failure_line}:#{@parser.failure_column} @@ -98,15 +98,15 @@ def compile_func_body(body, return_type: nil, symtab: SymbolTable.new, name: nil end # fix up left recursion - ast.make_left + ast = m.to_ast # type check cloned_symtab.push cloned_symtab.add("__expected_return_type", return_type) unless return_type.nil? begin - ast.func_stmt_list.elements.each do |e| - e.choice.type_check(cloned_symtab) + ast.statements.each do |s| + s.type_check(cloned_symtab) end rescue AstNode::TypeError => e raise e if no_rescue @@ -138,18 +138,17 @@ def compile_func_body(body, return_type: nil, symtab: SymbolTable.new, name: nil # compile an instruction operation, and return the abstract syntax tree # - # @param operation [String] Instruction operation source code + # @param inst [Instruction] Instruction object # @param symtab [SymbolTable] Symbol table to use for type checking - # @param name [String] Function name, used for error messages - # @param parent [String] Parent class of the function, used for error messages # @param input_file [Pathname] Path to the input file this source comes from # @param input_line [Integer] Starting line in the input file that this source comes from # @return [Ast] The root of the abstract syntax tree - def compile_inst_operation(operation, symtab: SymbolTable.new, name: nil, parent: nil, input_file: nil, input_line: 0) + def compile_inst_operation(inst, input_file: nil, input_line: 0) + operation = inst["operation()"] @parser.set_input_file(input_file, input_line) - ast = @parser.parse(operation, root: :instruction_operation) - if ast.nil? + m = @parser.parse(operation, root: :instruction_operation) + if m.nil? raise SyntaxError, <<~MSG While parsing #{input_file}:#{@parser.failure_line}:#{@parser.failure_column} @@ -158,33 +157,63 @@ def compile_inst_operation(operation, symtab: SymbolTable.new, name: nil, parent end # fix up left recursion - ast.make_left + ast = m.to_ast + ast.set_input_file("Inst #{inst.name} (#{input_file})", input_line) + ast + end + # Type check an abstract syntax tree + # + # @param ast [AstNode] An abstract syntax tree + # @param symtab [SymbolTable] The compilation context + # @param what [String] A description of what you are type checking (for error messages) + # @raise AstNode::TypeError if a type error is found + def type_check(ast, symtab, what) # type check - symtab.push + begin + ast.type_check(symtab) + rescue AstNode::TypeError => e + warn "While type checking #{what}:" + warn e.what + exit 1 + rescue AstNode::InternalError => e + warn "While type checking #{what}:" + warn e.what + warn e.backtrace + exit 1 + end + ast + end + + def compile_expression(expression, symtab, pass_error: false) + m = @parser.parse(expression, root: :expression) + if m.nil? + raise SyntaxError, <<~MSG + While parsing #{expression}:#{@parser.failure_line}:#{@parser.failure_column} + + #{@parser.failure_reason} + MSG + end + + ast = m.to_ast begin ast.type_check(symtab) rescue AstNode::TypeError => e - if name && parent - warn "In function #{name} of #{parent}:" - elsif name && parent.nil? - warn "In function #{name}:" - end + raise e if pass_error + + warn "Compiling #{expression}" warn e.what warn e.backtrace exit 1 rescue AstNode::InternalError => e - if name && parent - warn "In function #{name} of #{parent}:" - elsif name && parent.nil? - warn "In function #{name}:" - end + raise e if pass_error + + warn "Compiling #{expression}" warn e.what warn e.backtrace exit 1 end - symtab.pop ast end diff --git a/lib/idl/ast.rb b/lib/idl/ast.rb index f8f1cec91..321105eed 100644 --- a/lib/idl/ast.rb +++ b/lib/idl/ast.rb @@ -27,18 +27,20 @@ def has_template_ancestor? # @return [Boolean] whether or not this SyntaxNode represents a function name (overriden in the parser) def is_function_name? = false - # Fix up left recursion for the PEG + # convert SyntaxNode into an AstNode # - # This is the default for anything that isn't a left-recursive binary op + # Mostly, there is a 1:1 correspondence between SyntaxNode and AstNode. A few exceptions: # - # Only left-recursive binary ops need to override this + # * Left recusrion needs fixed up, so BinaryExpreesions are converted + # * If statements are converted to a more friendly format # # @note This may alter the SyntaxTree. You shouldn't use pointers within the - # tree from before a call to make_left + # tree from before a call to to_ast # @return [SyntaxNode] A fixed syntax tree - def make_left + def to_ast elements.nil? || elements.length.times do |i| - elements[i] = elements[i].make_left + elements[i] = elements[i].to_ast + elements[i].parent = self end self end @@ -50,6 +52,9 @@ def make_left def set_input_file(filename, starting_line = 0) @input_file = filename @starting_line = starting_line + elements.nil? || elements.length.times do |i| + elements[i].set_input_file(filename, starting_line) + end raise "?" if @starting_line.nil? end @@ -283,7 +288,7 @@ def print_ast(indent = 0, indent_size: 2, io: $stdout) # @!macro type_check # @abstract - def type_check(symtab) = raise NotImplementedError, "Subclass of AstNode must implement type_check" + def type_check(symtab) = raise NotImplementedError, "#{self.class.name} must implement type_check" # @!macro [new] to_idl # Return valid IDL representation of the node (and its subtree) @@ -310,22 +315,37 @@ module Executable # @return [void] # @!macro execute - def execute(symtab) = raise NotImplementedError, "#{self.class.name} must implement update_value" + def execute(symtab) = raise NotImplementedError, "#{self.class.name} must implement execute" end # interface for nodes that *might* return a value in a function body module Returns # @!macro [new] retrun_value # Evaluate the compile-time return value of this node, or, if the node does not return - # (e.g., because it is an IfAst and the return in the not-taken path), execute the node + # (e.g., because it is an IfAst but there is no return on the taken path), execute the node # and update the symtab # # @param symtab [SymbolTable] The symbol table for the context # @raise ValueError if, during evaulation, a node without a compile-time value is found - # @return [Integer, nil] The return value, or nil if the node doesn't return + # @return [Integer] The return value, if it is integral + # @return [Boolean] The return value, if it is boolean + # @return [nil] if the return value is not compile-time-known # @!macro return_value def return_value(symtab) = raise NotImplementedError, "#{self.class.name} must implement return_value" + + # @!macro [new] retrun_values + # Evaluate all possible compile-time return values of this node, or, if the node does not return + # (e.g., because it is an IfAst but there is no return on a possible path), execute the node + # and update the symtab + # + # @param symtab [SymbolTable] The symbol table for the context + # @raise ValueError if, during evaulation, a node without a compile-time value is found + # @return [Array] The possible return values. Will be an empty array if there are no return values + # @return [Array] The possible return values. Will be an empty array if there are no return values + + # @!macro return_values + def return_values(symtab) = raise NotImplementedError, "#{self.class.name} must implement return_values" end # interface for R-values (e.g., expressions that have a value) @@ -355,7 +375,7 @@ def type(symtab) = raise NotImplementedError, "#{self.class.name} has no type" # Should not be called until {#type_check} is called with the same arguments # # @param symtab [SymbolTable] Symbol table for lookup - # @return [Integer] if the compile-time-known value is an integer + # @return [Integer] if the compile-time-known value is integral # @return [Boolean] if the compile-time-known value is a boolean # @raise [AstNode::ValueError] if the value is not knowable at compile time # @raise [AstNode::InternalError] if the value is dependent on symtab, and type_check was not called first @@ -371,6 +391,33 @@ def type(symtab) = raise NotImplementedError, "#{self.class.name} has no type" # @!macro value # @abstract def value(symtab) = raise NotImplementedError, "#{self.class.name} must implement value(symtab)" + + # @!macro [new] values + # Return a complete list of possible compile-time-known values of the node, or raise a ValueError if + # the full list cannot be determined + # + # For most AstNodes, this will just be a single-entry array + # + # @param symtab [SymbolTable] The context for the evaulation + # @return [Array] The complete list of compile-time-known values, when they are integral + # @return [Array] The complete list of compile-time-known values, when they are booleans + # @return [AstNode::ValueError] if the list of values is not knowable at compile time + + # @!macro values + def values(symtab) = [value(symtab)] + end + + # interface for any AstNode that introduces a new symbol into scope + module Declaration + # @!macro [new] add_symbol + # Add symbol(s) at the outermost scope of the symbol table + # + # @param symtab [SymbolTable] Symbol table at the scope that the symbol(s) will be inserted + def add_symbol(symtab) = raise NotImplementedError, "#{self.class.name} must implment add_symbol" + end + + class IdSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast = IdAst.new(input, interval, text_value) end # an identifier @@ -379,34 +426,39 @@ def value(symtab) = raise NotImplementedError, "#{self.class.name} must implemen class IdAst < AstNode include Rvalue + def initialize(input, interval, id_name) + super(input, interval, []) + @name = id_name + end + # @!macro type_check def type_check(symtab) - type_error "no symbol named '#{text_value}' on line #{lineno}" if symtab.get(text_value).nil? + type_error "no symbol named '#{@name}' on line #{lineno}" if symtab.get(@name).nil? end # @return [String] The ID name - def name = text_value + def name = @name # @!macro type_no_archdef def type(symtab) - internal_error "Symbol not found (should have called type_check)" if symtab.get(text_value).nil? + internal_error "Symbol '#{@name}' not found (should have called type_check)" if symtab.get(@name).nil? - symtab.get(text_value).type + symtab.get(@name).type end # @!macro value_no_archdef def value(symtab) - var = symtab.get(text_value) + var = symtab.get(@name) - internal_error "Var was not found, call type_check first!" if var.nil? + type_error "Variable '#{@name}' was not found" if var.nil? - value_error "Value of '#{text_value}' not known" if var.value.nil? + value_error "Value of '#{@name}' not known" if var.value.nil? var.value end # @!macro to_idl - def to_idl = text_value + def to_idl = @name end # global variable declared with an initializer, @@ -569,6 +621,11 @@ def type_check(symtab) end end + add_symbol(symtab) + end + + # @!macro add_symbol + def add_symbol(symtab) et = EnumerationType.new(user_type_name.text_value, element_names, element_values) symtab.add!(et.name, et) end @@ -673,6 +730,11 @@ def type_check(symtab) type_error "Field position (#{b}) is larger than the bitfield width (#{bf_size})" if b >= bf_size end + add_symbol(symtab) + end + + # @!macro add_symbol + def add_symbol(symtab) t = type(symtab) symtab.add!(name, t) end @@ -723,19 +785,19 @@ def to_idl # # For example, it helps us represent # X[rs1][31:0] - class AryAccess < Treetop::Runtime::SyntaxNode + class AryAccessSyntaxNode < Treetop::Runtime::SyntaxNode # fix up left recursion # # @return [AstNode] New tree rooted at the array access - def make_left - var = a.make_left + def to_ast + var = a.to_ast interval_start = interval.begin brackets.elements.each do |bracket| var = if bracket.msb.empty? - AryElementAccessAst.new(input, interval_start...bracket.interval.end, var, bracket.lsb.make_left) + AryElementAccessAst.new(input, interval_start...bracket.interval.end, var, bracket.lsb.to_ast) else AryRangeAccessAst.new(input, interval_start...bracket.interval.end, var, - bracket.msb.expression.make_left, bracket.lsb.make_left) + bracket.msb.expression.to_ast, bracket.lsb.to_ast) end interval_start = bracket.interval.end end @@ -824,6 +886,9 @@ def value(symtab) ary.value[idx].value end end + + # @!macro to_idl + def to_idl = "#{@var.to_idl}[#{@index.to_idl}]" end class AryRangeAccessAst < AstNode @@ -838,6 +903,7 @@ def initialize(input, interval, var, msb, lsb) @lsb = lsb end + # @!macro type_check def type_check(symtab) @var.type_check(symtab) @msb.type_check(symtab) @@ -863,6 +929,7 @@ def type_check(symtab) end end + # @!macro type def type(symtab) begin msb_value = @msb.value(symtab) @@ -875,10 +942,15 @@ def type(symtab) end end + # @!macro value def value(symtab) mask = (1 << (@msb.value(symtab) - @lsb.value(symtab) + 1)) - 1 (@var.value(symtab) >> @lsb.value(symtab)) & mask end + + # @!macro to_idl + def to_idl = "#{@var.to_idl}[#{@msb.to_idl}:#{@lsb.to_idl}]" + end # base class for all nodes representing an assignment @@ -897,76 +969,99 @@ def rhs end end + class VariableAssignmentSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + VariableAssignmentAst.new(input, interval, var.to_ast, rval.to_ast) + end + end + # represents a variable assignment statement # # for example, these will result in a VariableAssignmentAst # X[rs1] = XLEN'b0 # CSR[mepc] = PC + 4 - class VariableAssignmentAst < AssignmentAst - # @!macro type_check - def type_check(symtab) - var.type_check(symtab) - rval.type_check(symtab) - unless rval.type(symtab).convertable_to?(var.type(symtab)) - type_error "Incompatible type in assignment (#{var.type(symtab)}, #{rval.type(symtab)}) on line #{lineno}" - end - end + class VariableAssignmentAst < AstNode + attr_reader :lhs, :rhs - def lhs - var + def initialize(input, interval, lhs_ast, rhs_ast) + super(input, interval, [lhs_ast, rhs_ast]) + @lhs = lhs_ast + @rhs = rhs_ast end - def rhs - rval + # @!macro type_check + def type_check(symtab) + @lhs.type_check(symtab) + @rhs.type_check(symtab) + unless @rhs.type(symtab).convertable_to?(@lhs.type(symtab)) + type_error "Incompatible type in assignment (#{@lhs.type(symtab)}, #{@rhs.type(symtab)})" + end end def execute(symtab) - if var.is_a?(CsrWriteAst) + if @lhs.is_a?(CsrWriteAst) value_error "CSR writes are never compile-time-known" else - variable = symtab.get(var.text_value) + variable = symtab.get(@lhs.text_value) - internal_error "No variable #{var.text_value}" if variable.nil? + internal_error "No variable #{@lhs.text_value}" if variable.nil? - variable.value = rval.value(symtab) + variable.value = @rhs.value(symtab) end end # @!macro to_idl - def to_idl = "#{var.to_idl} = #{rval.to_idl}" + def to_idl = "#{@lhs.to_idl} = #{@rhs.to_idl}" + end + + class AryElementAssignmentSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + AryElementAssignmentAst.new(input, interval, var.to_ast, idx.to_ast, rval.to_ast) + end end # represents an array element assignement # # for example: # X[rs1] = XLEN'd0 - class AryElementAssignmentAst < AssignmentAst - # @!macro type_check + class AryElementAssignmentAst < AstNode + attr_reader :lhs, :idx, :rhs + + def initialize(input, interval, lhs, idx, rhs) + super(input, interval, [lhs, idx, rhs]) + @lhs = lhs + @idx = idx + @rhs = rhs + end + + # @!macro type_check def type_check(symtab) - var.type_check(symtab) - type_error "#{var.text_value} must be an array or an integral type" unless [:array, :bits].include?(var.type(symtab).kind) - type_errpr "Assigning to a constant" if var.type(symtab).const? + @lhs.type_check(symtab) + unless [:array, :bits].include?(@lhs.type(symtab).kind) + type_error "#{@lhs.text_value} must be an array or an integral type" + end + type_errpr "Assigning to a constant" if @lhs.type(symtab).const? - idx.type_check(symtab) + @idx.type_check(symtab) - type_error "Index must be integral" unless idx.type(symtab).integral? + type_error "Index must be integral" unless @idx.type(symtab).integral? begin - idx_value = idx.value(symtab) - type_error "Array index out of range" if idx_value(symtab) >= var.type(symtab).width + idx_value = @idx.value(symtab) + type_error "Array index (#{@idx.text_value} = #{idx_value}) out of range (< #{var.type(symtab).width})" if idx_value >= @lhs.type(symtab).width rescue ValueError # OK, doesn't need to be known end - rval.type_check(symtab) + @rhs.type_check(symtab) - case var.type(symtab).kind + case @lhs.type(symtab).kind when :array - unless rval.type(symtab).convertable_to?(var.type(symtab).sub_type) + unless @rhs.type(symtab).convertable_to?(@lhs.type(symtab).sub_type) type_error "Incompatible type in array assignment" end when :bits - unless rval.type(symtab).convertable_to?(Type.new(:bits, width: 1)) + unless @rhs.type(symtab).convertable_to?(Type.new(:bits, width: 1)) type_error "Incompatible type in integer slice assignement" end else @@ -974,30 +1069,21 @@ def type_check(symtab) end end - def lhs - internal_error "What's this used for?" - end - - def rhs - rval - end - def execute(symtab) - case var.type(symtab).kind + case @lhs.type(symtab).kind when :array - value_error "TODO: array element assignement execution" + @lhs.value(symtab)[@idx.value(symtab)] = @rhs.value(symtab) when :bits - v = rhs.value(symtab) - var = symtab.get(var.text_value) - mask = 1 << idx.value(symtab) - var.value = (var.value & ~0) | ((v & 1) << idx.value(symtab)) + v = @rhs.value(symtab) + var = symtab.get(@lhs.text_value) + var.value = (@lhs.value & ~0) | ((v & 1) << @idx.value(symtab)) else internal_error "unexpected type for array element assignment" end end # @!macro to_idl - def to_idl = "#{var.to_idl}[#{idx.to_idl}] = #{rval.to_idl}" + def to_idl = "#{@lhs.to_idl}[#{@idx.to_idl}] = #{@rhs.to_idl}" end # represents an array range assignement @@ -1048,7 +1134,7 @@ def execute(symtab) msb_val = msb.value(symtab) lsb_val = lsb.value(symtab) - type_error "MSB is <= LSB" if msb_val <= lsb_val + type_error "MSB (#{msb_val}) is <= LSB (#{lsb_val})" if msb_val <= lsb_val rval_val = rval.value(symtab) @@ -1233,7 +1319,9 @@ def to_idl = "(#{vars.map(&:to_idl).join(', ')}) = #{function_call.to_idl}" # for example: # Bits<64> a, b; # Bits<64> a, b, c, d; - class MultiVariableDeclarationAst < AssignmentAst + class MultiVariableDeclarationAst < AstNode + include Declaration + # @return [Array] Variables being declared def var_names return @var_names unless @var_names.nil? @@ -1252,14 +1340,13 @@ def type_check(symtab) type_error "Attempt to write read-only/constant variable #{text_value}" if type.const? - var_names.each do |vname| - symtab.add(vname, Var.new(vname, type.clone)) - end + add_symbol(symtab) end - def execute(symtab) - var_names.each do |name| - symtab.add(name, Var.new(name, type.clone)) + # @!macro add_symbol + def add_symbol(symtab) + var_names.each do |vname| + symtab.add(vname, Var.new(vname, type.clone, type.default)) end end @@ -1273,19 +1360,26 @@ def to_idl = "#{type.to_idl} #{var_names.map(&:to_idl).join(', ')}" # Bits<64> doubleword # Boolean has_property class VariableDeclarationAst < AstNode - include Executable + include Declaration def decl_type(symtab) dtype = type_name.type(symtab) return nil if dtype.nil? - dtype = Type.new(:enum_ref, enum_class: dtype) if dtype.kind == :enum + qualifiers = + if var_write.text_value[0].upcase == var_write.text_value[0] + [:const] + else + [] + end + + dtype = Type.new(:enum_ref, enum_class: dtype, qualifiers:) if dtype.kind == :enum dtype = dtype.clone.qualify(q.text_value.to_sym) unless q.empty? unless ary_size.empty? - dtype = Type.new(:array, width: ary_size.expression.value(symtab), sub_type: dtype.clone) + dtype = Type.new(:array, width: ary_size.expression.value(symtab), sub_type: dtype.clone, qualifiers:) end dtype @@ -1303,39 +1397,64 @@ def type_check(symtab) unless ary_size.empty? ary_size.expression.type_check(symtab) begin - ary_size_value = ary_size.expression.value(symtab) + ary_size.expression.value(symtab) rescue ValueError type_error "Array size must be known at compile time" end end - symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab))) + add_symbol(symtab) var_write.type_check(symtab) end - def execute(symtab) - value_error "TODO: array declration execution" unless ary_size.empty? - symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab))) + # @!macro add_symbol + def add_symbol(symtab) + symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type(symtab), decl_type(symtab).default)) end # @!macro to_idl def to_idl if ary_size.empty? - "#{type.to_idl} #{var_write.to_idl}" + "#{type_name.to_idl} #{var_write.to_idl}" else - "#{type.to_idl} #{var_write.to_idl}[#{ary_size.expression.to_idl}]" + "#{type_name.to_idl} #{var_write.to_idl}[#{ary_size.expression.to_idl}]" end end end + class VariableDeclarationWithInitializationSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + ary_size_ast = ary_size.empty? ? nil : ary_size.expression.to_ast + VariableDeclarationWithInitializationAst.new( + input, interval, + type_name.to_ast, var_write.to_ast, ary_size_ast, rval.to_ast + ) + end + end + # reprents a single variable declaration with initialization # # for example: # Bits<64> doubleword = 64'hdeadbeef # Boolean has_property = true - class VariableDeclarationWithInitializationAst < AssignmentAst + class VariableDeclarationWithInitializationAst < AstNode include Executable + include Declaration + + attr_reader :type_name, :lhs, :rhs + + def initialize(input, interval, type_name_ast, var_write_ast, ary_size, rval_ast) + if ary_size.nil? + super(input, interval, [type_name_ast, var_write_ast, rval_ast]) + else + super(input, interval, [type_name_ast, var_write_ast, ary_size, rval_ast]) + end + @type_name = type_name_ast + @lhs = var_write_ast + @ary_size = ary_size + @rhs = rval_ast + end def lhs_type(symtab) decl_type = type_name.type(symtab).clone @@ -1343,97 +1462,121 @@ def lhs_type(symtab) decl_type = Type.new(:enum_ref, enum_class: decl_type) if decl_type.kind == :enum - decl_type = decl_type.clone.qualify(q.text_value.to_sym) unless q.empty? + # decl_type = decl_type.clone.qualify(q.text_value.to_sym) unless q.empty? + + if @lhs.text_value[0].upcase == @lhs.text_value[0] + decl_type.make_const + end + + unless @ary_size.nil? + begin + decl_type = Type.new(:array, sub_type: decl_type, width: @ary_size.value(symtab)) + rescue ValueError + type_error "Array size must be known at compile time" + end + if @lhs.text_value[0].upcase == @lhs.text_value[0] + decl_type.make_const + end + end decl_type end + # @!macro type_check def type_check(symtab) - rval.type_check(symtab) + @rhs.type_check(symtab) - type_name.type_check(symtab) + @type_name.type_check(symtab) - decl_type = lhs_type(symtab) + @ary_size&.type_check(symtab) - unless ary_size.empty? - ary_size.expression.type_check(symtab) - begin - ary_size_value = ary_size.expression.value(symtab) - rescue ValueError - type_error "Array size must be known at compile time" - end + decl_type = lhs_type(symtab) - decl_type = Type.new(:array, width: ary_size_value, sub_type: decl_type) - end - if (var_write.text_value == var_write.text_value.upcase) && ary_size.empty? + if decl_type.const? # this is a constant; ensure we are assigning a constant value begin - symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type.clone.make_const, rval.value(symtab))) + symtab.add(@lhs.text_value, Var.new(@lhs.text_value, decl_type.clone, @rhs.value(symtab))) rescue ValueError => e type_error "Declaring constant with a non-constant value (#{e})" end else - symtab.add(var_write.text_value, Var.new(var_write.text_value, decl_type.clone)) + symtab.add(@lhs.text_value, Var.new(@lhs.text_value, decl_type.clone)) end - var_write.type_check(symtab) + @lhs.type_check(symtab) # now check that the assignment is compatible - return if rval.type(symtab).convertable_to?(decl_type) - - type_error "Incompatible type (#{decl_type}, #{rval.type(symtab)}) in assignment" - end + return if @rhs.type(symtab).convertable_to?(decl_type) - def lhs - var_write + type_error "Incompatible type (#{decl_type}, #{@rhs.type(symtab)}) in assignment" end - def rhs - # if rhs is nil, this is the non-initializing variant - return nil unless respond_to?(:rval) - - return rval if rval.is_a?(Rvalue) - - internal_error "unexpected #{rval.inspect}" unless rval.is_a?(MemoryRValAst) - - rval + # @!macro add_symbol + def add_symbol(symtab) + symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs.value(symtab))) + rescue ValueError + symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab))) end + # @!macro execute def execute(symtab) - value_error "TODO: Array declaration" unless ary_size.empty? + value_error "TODO: Array declaration" unless @ary_size.nil? symtab.add(lhs.text_value, Var.new(lhs.text_value, lhs_type(symtab), rhs.value(symtab))) end + + # @!macro to_idl + def to_idl + if @ary_size.nil? + "#{type_name.to_idl} #{lhs.to_idl} = #{rhs.to_idl}" + else + "#{type_name.to_idl} #{lhs.to_idl}[#{@ary_size.to_idl}] = #{rhs.to_idl}" + end + end end - class BinaryExpressionRightAst < AstNode + class BinaryExpressionRightSyntaxNode < Treetop::Runtime::SyntaxNode - def make_left + # fix up left recursion + # i.e., xlen() - 1 - i => (xlen() - 1) - i + def to_ast first = BinaryExpressionAst.new( input, (interval.begin...r.elements[0].r.interval.end), - l.make_left, r.elements[0].op, r.elements[0].r.make_left + l.to_ast, r.elements[0].op.text_value, r.elements[0].r.to_ast ) if r.elements.size == 1 first else - r.elements[1, -1].inject(first) do |lhs, r| - BinaryExpressionAst.new(input, (r.interval.begin...r.r.interval.end), - lhs, r.op, r.r.make_left) + r.elements[1..].inject(first) do |lhs, el| + BinaryExpressionAst.new(input, (lhs.interval.begin...el.r.interval.end), + lhs, el.op.text_value, el.r.to_ast) end end - first end - def type_check(_symtab, _archdef) - raise "you must have forgotten the make_left pass" + def type_check(_symtab) + raise "you must have forgotten the to_ast pass" + end + end + + class SignCastSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + SignCastAst.new(input, interval, expression.to_ast) end end class SignCastAst < AstNode include Rvalue + attr_reader :expression + + def initialize(input, interval, expression) + super(input, interval, [expression]) + @expression = expression + end + # @!macro type_check def type_check(symtab) expression.type_check(symtab) @@ -1523,9 +1666,9 @@ class BinaryExpressionAst < AstNode # create a new, left-recursion-fixed, binary expression def initialize(input, interval, lhs, op, rhs) - super(input, interval, [lhs, op, rhs]) + super(input, interval, [lhs, rhs]) @lhs = lhs - @op = op.text_value + @op = op.to_s type_error "Bad op '#{@op}'" unless OPS.include?(@op) @rhs = rhs end @@ -1560,7 +1703,7 @@ def invert(symtab) # @!macro to_idl def to_idl - "#{lhs.to_idl} #{op} #{rhs.to_idl}" + "(#{lhs.to_idl} #{op} #{rhs.to_idl})" end # @!macro type @@ -1670,8 +1813,87 @@ def value(symtab) else eval "lhs_value #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ end + elsif op == "==" + begin + @lhs.value(symtab) == @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that == is false if the possible values of each do not overlap + if @lhs.values(symtab).intersection(@rhs.value(symtab)).empty? + false + else + value_error "There is overlap in the lhs/rhs return values" + end + end + elsif op == "!=" + begin + @lhs.value(symtab) != @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of each do not overlap + if @lhs.values(symtab).intersection(@rhs.value(symtab)).empty? + true + else + value_error "There is overlap in the lhs/rhs return values" + end + end + elsif op == "<=" + begin + @lhs.value(symtab) <= @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all <= the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value <= rhs_value} } + true + else + value_error "Some value of lhs is not <= some value of rhs" + end + end + elsif op == ">=" + begin + @lhs.value(symtab) >= @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all >= the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value >= rhs_value} } + true + else + value_error "Some value of lhs is not >= some value of rhs" + end + end + elsif op == "<" + begin + @lhs.value(symtab) < @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all < the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value < rhs_value} } + true + else + value_error "Some value of lhs is not < some value of rhs" + end + end + elsif op == ">" + begin + @lhs.value(symtab) > @rhs.value(symtab) + rescue ValueError + # even if we don't know the exact value of @lhs and @rhs, we can still + # know that != is true if the possible values of lhs are all > the possible values of rhs + rhs_values = @rhs.values(symtab) + if @lhs.values(symtab).all? { |lhs_value| rhs_values.all? { |rhs_value| lhs_value > rhs_value} } + true + else + value_error "Some value of lhs is not > some value of rhs" + end + end else - eval "lhs.value(symtab) #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ + v = eval "lhs.value(symtab) #{op} rhs.value(symtab)", binding, __FILE__, __LINE__ + v_trunc = v & ((1 << type(symtab).width) - 1) + warn "WARNING: The value of '#{text_value}' is truncated from #{v} to #{v_trunc} because the result is only #{type(symtab).width} bits" if v != v_trunc + v_trunc end end @@ -1685,6 +1907,12 @@ def value(symtab) attr_reader :op end + class ParenExpressionSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + ParenExpressionAst.new(input, interval, e.to_ast) + end + end + # represents a parenthesized expression # # for example: @@ -1692,16 +1920,23 @@ def value(symtab) class ParenExpressionAst < AstNode include Rvalue - def invert(symtab) = e.invert(symtab) + attr_reader :expression + + def initialize(input, interval, expression) + super(input, interval, [expression]) + @expression = expression + end + + def invert(symtab) = expression.invert(symtab) # @!macro type_check - def type_check(symtab) = e.type_check(symtab) + def type_check(symtab) = expression.type_check(symtab) # @!macro type - def type(symtab) = e.type(symtab) + def type(symtab) = expression.type(symtab) # @!macro value - def value(symtab) = e.value(symtab) + def value(symtab) = expression.value(symtab) # @!macro to_idl def to_idl = "(#{e.to_idl})" @@ -1771,12 +2006,13 @@ def type(symtab) # @!macro value def value(symtab) - result = first.value(symtab) - total_width = first.type(symtab).width - rest.elements.each do |e| + result = 0 + total_width = 0 + rest.elements.reverse_each do |e| result |= (e.expression.value(symtab) << total_width) total_width += e.expression.type(symtab).width end + result |= first.value(symtab) << total_width result end @@ -1784,6 +2020,12 @@ def value(symtab) def to_idl = "{#{first.to_idl},#{rest.elements.map { |e| e.expression.to_idl }.join(',')}}" end + class ReplicationExpressionSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + ReplicationExpressionAst.new(input, interval, n.to_ast, v.to_ast) + end + end + # represents a replication expression # # for example: @@ -1791,6 +2033,14 @@ def to_idl = "{#{first.to_idl},#{rest.elements.map { |e| e.expression.to_idl }.j class ReplicationExpressionAst < AstNode include Rvalue + attr_reader :n, :v + + def initialize(input, interval, n, v) + super(input, interval, [n, v]) + @n = n + @v = v + end + # @!macro type_check def type_check(symtab) n.type_check(symtab) @@ -1844,12 +2094,48 @@ def execute(symtab) var = symtab.get(rval.text_value) internal_error "No symbol #{rval.text_value}" if var.nil? + value_error "value of variable '#{rval.text_value}' not know" if var.value.nil? + var.value = var.value - 1 end def to_idl = "#{rval.to_idl}--" end + class BuiltinVariableSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + BuiltinVariableAst.new(input, interval, text_value) + end + end + + class BuiltinVariableAst < AstNode + attr_reader :name + + def initialize(input, interval, name) + super(input, interval, []) + @name = name + end + + def type_check(symtab) + type_error "Not a builtin variable" unless ["$pc", "$encoding"].include?(@name) + end + + def type(symtab) + case @name + when "$encoding" + sz = symtab.get("__instruction_encoding_size") + internal_error "Forgot to set __instruction_encoding_size" if sz.nil? + Type.new(:bits, width: sz.value, qualifiers: [:const]) + when "$pc" + Type.new(:bits, width: symtab.archdef.config_params["XLEN"]) + end + end + + def value(symtab) + value_error "Cannot know the value of pc or encoding" + end + end + # represents a post-increment expression # # for example: @@ -1861,6 +2147,7 @@ class PostIncrementExpressionAst < AstNode def type_check(symtab) rval.type_check(symtab) var = symtab.get(rval.text_value) + type_error "Post increment variable must be integral" unless var.type.integral? end # @!macro type @@ -1870,8 +2157,8 @@ def type(symtab) # @!macro execute def execute(symtab) - var = symtab.get(rval) - internal_error "Call type check first" if var.nil? + var = symtab.get(rval.text_value) + internal_error "No symbol named '#{rval.text_value}'" if var.nil? var.value = var.value + 1 end @@ -1951,6 +2238,12 @@ def value(symtab) def to_idl = "#{rval.to_idl}.#{field_name.to_idl}" end + class EnumRefSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + EnumRefAst.new(input, interval, enum_class.text_value, member.text_value) + end + end + # represents an enum reference # # for example: @@ -1959,30 +2252,41 @@ def to_idl = "#{rval.to_idl}.#{field_name.to_idl}" class EnumRefAst < AstNode include Rvalue + def class_name = @enum_class_name + def member_name = @member_name + + def initialize(input, interval, class_name, member_name) + super(input, interval, []) + + @enum_class_name = class_name + @member_name = member_name + end + # @!macro type_check def type_check(symtab) - enum_def_type = symtab.get(enum_class.text_value) - type_error "No symbol #{enum_class.text_value} has been defined" if enum_def_type.nil? + enum_def_type = symtab.get(@enum_class_name) + type_error "No symbol #{@enum_class_name} has been defined" if enum_def_type.nil? - type_error "#{enum_class.text_value} is not an enum type" unless enum_def_type.is_a?(EnumerationType) + type_error "#{@enum_class_name} is not an enum type" unless enum_def_type.is_a?(EnumerationType) + type_error "#{@enum_class_name} has no member '#{@member_name}'" if enum_def_type.value(@member_name).nil? end # @!macro type_no_archdef def type(symtab) - internal_error "Must call type_check first" if symtab.get(enum_class.text_value).nil? + internal_error "Must call type_check first" if symtab.get(@enum_class_name).nil? - Type.new(:enum_ref, enum_class: symtab.get(enum_class.text_value)) + Type.new(:enum_ref, enum_class: symtab.get(@enum_class_name)) end # @!macro value_no_archdef def value(symtab) - internal_error "Must call type_check first" if symtab.get(enum_class.text_value).nil? + internal_error "Must call type_check first" if symtab.get(@enum_class_name).nil? - symtab.get(enum_class.text_value).value(member.text_value) + symtab.get(@enum_class_name).value(@member_name) end # @!macro to_idl - def to_idl = "#{enum_class.to_idl}::#{member.to_idl}" + def to_idl = "#{@enum_class_name}::#{@member_name}" end # represents a unary operator @@ -2016,7 +2320,7 @@ def type_check(symtab) type_error "#{exp.type(symtab)} does not support unary #{op} operator" end - type_error "Unary minus only works on signed values" unless exp.type(symtab).signed? + # type_error "Unary minus only works on signed values" unless exp.type(symtab).signed? when "~" unless [:bits, :bitfield].include?(exp.type(symtab).kind) type_error "#{exp.type(symtab)} does not support unary #{op} operator" @@ -2032,18 +2336,19 @@ def type_check(symtab) # @!macro value def value(symtab) - val = eval("#{op}#{exp.value(symtab)}", binding, __FILE__, __LINE__) - if type(symtab).integral? && type(symtab).width > val.bit_length - # need to truncate - val &= ((1 << type(symtab).width) - 1) - if type(symtab).signed? && ((((val >> (type(symtab).width - 1))) & 1) == 1) + val = val_trunc = eval("#{op}#{exp.value(symtab)}", binding, __FILE__, __LINE__) + if type(symtab).integral? && val != val_trunc + val_trunc = val & ((1 << type(symtab).width) - 1) + if type(symtab).signed? && ((((val_trunc >> (type(symtab).width - 1))) & 1) == 1) # need to make this negative! # take the twos compliment - val = -((1 << type(symtab).width) - val) + val_trunc = -((1 << type(symtab).width) - val_trunc) end end - val + warn "#{text_value} is truncated due to insufficient bit width (from #{val} to #{val_trunc})" if val_trunc != val + + val_trunc end # return the operated-on expression @@ -2060,6 +2365,12 @@ def op def to_idl = "#{op}#{e.to_idl}" end + class TernaryOperatorExpressionSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + TernaryOperatorExpressionAst.new(input, interval, p9_binary_expression.to_ast, t.to_ast, f.to_ast) + end + end + # Represents a ternary operator # # for example: @@ -2068,157 +2379,214 @@ def to_idl = "#{op}#{e.to_idl}" class TernaryOperatorExpressionAst < AstNode include Rvalue + attr_reader :condition, :true_expression, :false_expression + + def initialize(input, interval, condition, true_expression, false_expression) + super(input, interval, [condition, true_expression, false_expression]) + + @condition = condition + @true_expression = true_expression + @false_expression = false_expression + end + # @!macro type_check def type_check(symtab) - p9_binary_expression.type_check(symtab) + @condition.type_check(symtab) + type_error "ternary selector must be bool" unless @condition.type(symtab).kind == :boolean + begin - cond = p9_binary_expression.value(symtab) + cond = @condition.value(symtab) # if the condition is compile-time-known, only check the used field if (cond) - t.type_check(symtab) + @true_expression.type_check(symtab) else - f.type_check(symtab) + @false_expression.type_check(symtab) end rescue ValueError - t.type_check(symtab) - f.type_check(symtab) + @true_expression.type_check(symtab) + @false_expression.type_check(symtab) - unless t.type(symtab).equal_to?(f.type(symtab)) + unless @true_expression.type(symtab).equal_to?(@false_expression.type(symtab)) # we'll allow dissimilar if they are both bits type - unless t.type(symtab).kind == :bits && f.type(symtab).kind == :bits - type_error "True and false options must be same type (have #{t.type(symtab)} and #{f.type(symtab)})" + unless @true_expression.type(symtab).kind == :bits && @false_expression.type(symtab).kind == :bits + type_error "True and false options must be same type (have #{@true_expression.type(symtab)} and #{@false_expression.type(symtab)})" end end end - - type_error "ternary selector must be bool" unless p9_binary_expression.type(symtab).kind == :boolean - - end # @!macro type def type(symtab) - p9_binary_expression.type_check(symtab) + @condition.type_check(symtab) begin - cond = p9_binary_expression.value(symtab) + cond = @condition.value(symtab) # if the condition is compile-time-known, only check the used field if (cond) - t.type(symtab) + @true_expression.type(symtab) else - f.type(symtab) + @false_expression.type(symtab) end rescue ValueError - if t.type(symtab).kind == :bits && f.type(symtab).kind == :bits - Type.new(:bits, width: [t.type(symtab).width, f.type(symtab).width].max) + if @true_expression.type(symtab).kind == :bits && @false_expression.type(symtab).kind == :bits + Type.new(:bits, width: [@true_expression.type(symtab).width, @false_expression.type(symtab).width].max) else - t.type(symtab) + @true_expression.type(symtab) end end end - def condition - p9_binary_expression - end - - def true_expression - t - end - - def false_expression - f - end - # @!macro value def value(symtab) - condition.value(symtab) ? t.value(symtab) : f.value(symtab) + @condition.value(symtab) ? @true_expression.value(symtab) : @false_expression.value(symtab) + end + + # @!macro values + def values(symtab) + @condition.value(symtab) ? @true_expression.values(symtab) : @false_expression.values(symtab) + rescue ValueError + (@true_expression.values(symtab) + @false_expression.values(symtab)).uniq end # @!macro to_idl - def to_idl = "#{condition.to_idl} ? #{true_expression.to_idl} : #{false_expression.to_idl}" + def to_idl = "#{@condition.to_idl} ? #{@true_expression.to_idl} : #{@false_expression.to_idl}" end - module VarReadExpressionAst - include Rvalue + # module VarReadExpressionAst + # include Rvalue - # @!macro type_check - def type_check(symtab) - var = symtab.get(text_value) + # # @!macro type_check + # def type_check(symtab) + # var = symtab.get(text_value) - type_error "No symbol named '#{text_value}'" if var.nil? + # type_error "No symbol named '#{text_value}'" if var.nil? - type_error "'#{text_value}' is not a variable" unless var.is_a?(Var) - end + # type_error "'#{text_value}' is not a variable" unless var.is_a?(Var) + # end - # @!macro type_no_archdef - def type(symtab) - internal_error "While checking VarRead type, no symbol '#{text_value}' found" if symtab.get(text_value).nil? + # # @!macro type_no_archdef + # def type(symtab) + # internal_error "While checking VarRead type, no symbol '#{text_value}' found" if symtab.get(text_value).nil? - symtab.get(text_value).type - end + # symtab.get(text_value).type + # end - # @!macro value_no_archdef - def value(symtab) - var = symtab.get(text_value) + # # @!macro value_no_archdef + # def value(symtab) + # var = symtab.get(text_value) - internal_error "Call type_check first" if var.nil? + # internal_error "Cannot find variable #{text_value}" if var.nil? - value_error "The value of '#{text_value}' is not known" if var.value.nil? + # value_error "The value of '#{text_value}' is not known" if var.value.nil? - var.value - end + # var.value + # end - # @!macro to_idl - def to_idl = text_value + # # @!macro to_idl + # def to_idl = text_value + # end + + + class StatementSyntaxNode < AstNode + def to_ast + StatementAst.new(a.to_ast) + end end - # represents a simple, one-line statement - # - # for example: - # Bits<64> new_variable; - # new_variable = 4; + class NoopAst < AstNode + def initialize + super("", 0...0, []) + end + + # @!macro type_check + def type_check(symtab); end + + # @!macro execute + def execute(symtab); end + + # @1macro to_idl + def to_idl = "" + end + + # represents a simple, one-line statement + # + # for example: + # Bits<64> new_variable; + # new_variable = 4; # func(); class StatementAst < AstNode include Executable - def action = a + attr_reader :action + + def initialize(action) + super(action.input, action.interval, [action]) + @action = action + end # @!macro type_check def type_check(symtab) - a.type_check(symtab) + @action.type_check(symtab) end + # @!macro execute def execute(symtab) - a.execute(symtab) + if @action.is_a?(Declaration) + @action.add_symbol(symtab) + end + if @action.is_a?(Executable) + @action.execute(symtab) + end end - def to_idl = "#{action.to_idl};" + # @!macro to_idl + def to_idl = "#{@action.to_idl};" + end + + class ConditionalStatementSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + ConditionalStatementAst.new(a.to_ast, expression.to_ast) + end end # represents a predicated simple statement # # for example: # a = 2 if condition; - class ConditionalStatementAst < StatementAst - # @!macro type_check - def type_check(symtab) - action.type_check(symtab) - condition.type_check(symtab) - type_error "condition is not boolean" unless condition.type(symtab).convertable_to?(:boolean) - end + class ConditionalStatementAst < AstNode + attr_reader :action, :condition - def action = a + def initialize(action, condition) + super(action.input, action.interval.first..action.interval.end, [action, condition]) + @action = action + @condition = condition + end - def condition - expression + # @!macro type_check + def type_check(symtab) + @action.type_check(symtab) + @condition.type_check(symtab) + type_error "condition is not boolean" unless @condition.type(symtab).convertable_to?(:boolean) end + # @!macro execute def execute(symtab) - cond = condition.value(symtab) + cond = @condition.value(symtab) if (cond) - action.execute(symtab) + @action.execute(symtab) end end + + # @!macro to_idl + def to_idl + "#{@action.to_idl} if (#{@condition.to_idl});" + end + end + + class DontCareReturnSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + DontCareReturnAst.new(input, interval) + end end # represents a don't care return value @@ -2228,6 +2596,10 @@ def execute(symtab) class DontCareReturnAst < AstNode include Rvalue + def initialize(input, interval) + super(input, interval, []) + end + # @!macro type_check_no_args def type_check(_symtab) # nothing to do! @@ -2347,7 +2719,6 @@ def type_check(symtab) types = [] if first.type(symtab).kind == :tuple type_error("Can't combine tuple types in return") unless rest.elements.empty? - num_values = first.type(symtab).tuple_types.size types = first.type(symtab).tuple_types else types = [first.type(symtab)] @@ -2362,7 +2733,7 @@ def type_check(symtab) end end - # list of return value nodes + # @return [Array] List of return value nodes def return_value_nodes v = [first] unless rest.empty? @@ -2377,6 +2748,7 @@ def enclosing_function find_ancestor(FunctionDefAst) end + # @!macro return_value def return_value(symtab) if return_value_nodes.size == 1 return_value_nodes[0].value(symtab) @@ -2385,6 +2757,15 @@ def return_value(symtab) end end + # @!macro return_values + def return_values(symtab) + if return_value_nodes.size == 1 + return_value_nodes[0].values(symtab) + else + return_value_nodes.map { |v| v.values(symtab) }.flatten.uniq + end + end + def to_idl = "return #{return_value_nodes.map(&:to_idl).join(',')};" end @@ -2395,6 +2776,7 @@ def condition expression end + # @!macro return_value def return_value(symtab) cond = condition.value(symtab) @@ -2406,42 +2788,60 @@ def return_value(symtab) nil end end + + # @!macro return_values + def return_values(symtab) + cond = condition.value(symtab) + + cond ? return_value_nodes.map { |n| n.values(symtab) }.flatten.uniq : [] + + rescue ValueError + # condition isn't known, so the return value is always possible + return_value_nodes.map { |n| n.values(symtab) }.flatten + end end class ExecutionCommentAst < AstNode def type_check(_symtab, _global); end end - class BitsTypeAst < AstNode - # @!macro type_check - def type_check(symtab) - i.type_check(symtab) - - begin - i.value(symtab) - rescue ValueError - type_error "Bit width is not compile-time known" + class BuiltinTypeNameSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + if !respond_to?(:i) + BuiltinTypeNameAst.new(input, interval, elements[0].text_value, nil) + else + BuiltinTypeNameAst.new(input, interval, elements[0].text_value, i.to_ast) end - type_error "Bit widht must be integral" unless i.type(symtab).integral? - end - - # @!macro type - def type(symtab) - Type.new(:bits, width: i.value(symtab).to_i) end - end class BuiltinTypeNameAst < AstNode + + def initialize(input, interval, type_name, bits_expression) + if bits_expression.nil? + super(input, interval, []) + else + super(input, interval, [bits_expression]) + end + @type_name = type_name + @bits_expression = bits_expression + end + # @!macro type_check def type_check(symtab) - type_error "Unimplemented builtin type #{text_value}" unless ["XReg", "Boolean", "U32", "U64"].include?(text_value) + if @type_name == "Bits" + @bits_expression.type_check(symtab) + type_error "Bits width (#{@bits_expression.value(symtab)}) must be positive" unless @bits_expression.value(symtab).positive? + end + unless ["Bits", "XReg", "Boolean", "U32", "U64"].include?(@type_name) + type_error "Unimplemented builtin type #{text_value}" + end end # @!macro type def type(symtab) archdef = symtab.archdef - case text_value + case @type_name when "XReg" Type.new(:bits, width: archdef.config_params["XLEN"]) when "Boolean" @@ -2450,116 +2850,249 @@ def type(symtab) Type.new(:bits, width: 32) when "U64" Type.new(:bits, width: 64) + when "Bits" + Type.new(:bits, width: @bits_expression.value(symtab)) else internal_error "TODO: #{text_value}" end end + + # @!macro to_idl + def to_idl + if @type_name == "Bits" + "Bits<#{@bits_expression.to_idl}>" + else + @type_name + end + end end - module IntAst + module IntLiteralSyntaxNode + def to_ast + IntLiteralAst.new(input, interval) + end + end + + class IntLiteralAst < AstNode include AstNodeFuncs include Rvalue + def initialize(input, interval) + super(input, interval, []) + end + # @!macro type_check def type_check(symtab) - archdef = symtab.archdef - text_value_no_underscores = text_value.delete("_") - if text_value_no_underscores =~ /([0-9]+)?'(s?)([bodh]?)(.*)/ + if text_value.delete("_") =~ /([0-9]+)?'(s?)([bodh]?)(.*)/ + # verilog-style literal width = ::Regexp.last_match(1) - signed = ::Regexp.last_match(2) - radix_id = ::Regexp.last_match(3) - value = ::Regexp.last_match(4) + value_text = ::Regexp.last_match(4) - width = archdef.config_params["XLEN"] if width.nil? - radix_id = "d" if radix_id.empty? + if width.nil? + width = symtab.archdef.config_params["XLEN"] + memoize = false + end # ensure we actually have enough bits to represent the value - case radix_id - when "b" - @value = value.to_i(2) - type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i - when "o" - @value = value.to_i(8) - type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i - when "d" - @value = value.to_i(10) - type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i - when "h" - @value = value.to_i(16) - type_error("#{value} cannot be represented in #{width} bits") if @value.bit_length > width.to_i - end + type_error("#{value_text} cannot be represented in #{width} bits") if unsigned_value.bit_length > width.to_i + end + end - qualifiers = signed == "s" ? [:signed, :const] : [:const] - @type = Type.new(:bits, width: width.to_i, qualifiers:) - elsif text_value_no_underscores =~ /0([bdx]?)([0-9a-fA-F]*)(s?)/ - radix_id = ::Regexp.last_match(1) - value = ::Regexp.last_match(2) - signed = ::Regexp.last_match(3) + # @!macro type + def type(symtab) + return @type unless @type.nil? - radix_id = "o" if radix_id.empty? + case text_value.delete("_") + when /([0-9]+)?'(s?)([bodh]?)(.*)/ + # verilog-style literal + width = ::Regexp.last_match(1) + signed = ::Regexp.last_match(2) - case radix_id - when "b" - @value = value.to_i(2) - when "o" - @value = value.to_i(8) - when "d" - @value = value.to_i(10) - when "x" - @value = value.to_i(16) + memoize = true + if width.nil? + width = symtab.archdef.config_params["XLEN"] + memoize = false end qualifiers = signed == "s" ? [:signed, :const] : [:const] - width = signed == "s" ? @value.bit_length + 1 : @value.bit_length - width = 1 if width.zero? # happens when the literal is '0' - @type = Type.new(:bits, width:, qualifiers:) - elsif text_value_no_underscores =~ /([0-9]*)(s?)/ - value = ::Regexp.last_match(1) - signed = ::Regexp.last_match(2) + t = Type.new(:bits, width: width.to_i, qualifiers:) + @type = t if memoize + t + when /0([bdx]?)([0-9a-fA-F]*)(s?)/ + # C++-style literal + signed = ::Regexp.last_match(3) - @value = value.to_i(10) + qualifiers = signed == "s" ? [:signed, :const] : [:const] + @type = Type.new(:bits, width: width(symtab), qualifiers:) + when /([0-9]*)(s?)/ + # basic decimal + signed = ::Regexp.last_match(2) qualifiers = signed == "s" ? [:signed, :const] : [:const] - width = signed == "s" ? @value.bit_length + 1 : @value.bit_length - width = 1 if width.zero? # happens when the literal is '0' - @type = Type.new(:bits, width:, qualifiers:) + @type = Type.new(:bits, width: width(symtab), qualifiers:) else internal_error "Unhandled int value" end - type_error(text_value) if @value.nil? end - # @!macro type - def type(symtab) - @type + def width(symtab) + return @width unless @width.nil? + + text_value_no_underscores = text_value.delete("_") + + case text_value_no_underscores + when /([0-9]+)?'(s?)([bodh]?)(.*)/ + # verilog-style literal + width = ::Regexp.last_match(1) + memoize = true + if width.nil? + width = archdef.config_params["XLEN"] + memoize = false + end + @width = width if memoize + width + when /0([bdx]?)([0-9a-fA-F]*)(s?)/ + signed = ::Regexp.last_match(3) + + @width = signed == "s" ? value(symtab).bit_length + 1 : value(symtab).bit_length + @width = 1 if @width.zero? # happens when the literal is '0' + + @width + when /([0-9]*)(s?)/ + signed = ::Regexp.last_match(3) + + @width = signed == "s" ? value(symtab).bit_length + 1 : value(symtab).bit_length + @width = 1 if @width.zero? # happens when the literal is '0' + + @width + else + internal_error "No match on int literal" + end end # @!macro value def value(symtab) - internal_error("Did not type check #{text_value}") if @value.nil? + return @value unless @value.nil? + + if text_value.delete("_") =~ /([0-9]+)?'(s?)([bodh]?)(.*)/ + # verilog-style literal + width = ::Regexp.last_match(1) + signed = ::Regexp.last_match(2) - @value + memoize = true + if width.nil? + width = archdef.config_params["XLEN"] + memoize = false + end + + v = + if !signed.empty? && ((unsigned_value >> (width.to_i - 1)) == 1) + -(2**width.to_i - unsigned_value) + else + unsigned_value + end + + @value = v if memoize + v + else + @value = unsigned_value + end + end + + + # @return [Integer] the unsigned value of this literal (i.e., treating it as unsigned even if the signed specifier is present) + def unsigned_value + return @unsigned_value unless @unsigned_value.nil? + + case text_value.delete("_") + when /([0-9]+)?'(s?)([bodh]?)(.*)/ + # verilog-style literal + signed = ::Regexp.last_match(2) + radix_id = ::Regexp.last_match(3) + value = ::Regexp.last_match(4) + + radix_id = "d" if radix_id.empty? + + # ensure we actually have enough bits to represent the value + @unsigned_value = + case radix_id + when "b" + value.to_i(2) + when "o" + value.to_i(8) + when "d" + value.to_i(10) + when "h" + value.to_i(16) + end + when /0([bdx]?)([0-9a-fA-F]*)(s?)/ + # C++-style literal + radix_id = ::Regexp.last_match(1) + value = ::Regexp.last_match(2) + signed = ::Regexp.last_match(3) + + radix_id = "o" if radix_id.empty? + + @unsigned_value = + case radix_id + when "b" + value.to_i(2) + when "o" + value.to_i(8) + when "d" + value.to_i(10) + when "x" + value.to_i(16) + end + when /([0-9]*)(s?)/ + # basic decimal + value = ::Regexp.last_match(1) + signed = ::Regexp.last_match(2) + + @unsigned_value = value.to_i(10) + else + internal_error "Unhandled int value" + end end # @!macro to_idl def to_idl = text_value end + class FunctionCallExpressionSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + targs = t.empty? ? [] : [t.targs.first.to_ast] + t.targs.rest.elements.map { |e| e.arg.to_ast } + args = [] + args << function_arg_list.first.to_ast unless function_arg_list.first.empty? + args += function_arg_list.rest.elements.map { |e| e.expression.to_ast } + FunctionCallExpressionAst.new(input, interval, function_name.text_value, targs, args) + end + end + class FunctionCallExpressionAst < AstNode # a function call can be both Lvalue (when void or return is ignored) and Rvalue include Rvalue include Executable + def initialize(input, interval, function_name, targs, args) + raise ArgumentError, "targs shoudl be an array" unless targs.is_a?(Array) + raise ArgumentError, "args shoudl be an array" unless args.is_a?(Array) + + super(input, interval, targs + args) + + @name = function_name + @targs = targs + @args = args + end + # @return [Boolean] whether or not the function call has a template argument def template? - !t.empty? + !@targs.empty? end # @return [Array] Template argument nodes def template_arg_nodes - return [] unless template? - - [t.targs.first] + t.targs.rest.elements.map(&:arg) + @targs end def template_values(symtab) @@ -2570,25 +3103,23 @@ def template_values(symtab) # @return [Array] Function argument nodes def arg_nodes - nodes = [] - nodes << function_arg_list.first unless function_arg_list.first.empty? - nodes + function_arg_list.rest.elements.map(&:expression) + @args end # @!macro type_check def type_check(symtab) level = symtab.levels - func_def_type = symtab.get(name) - type_error "No symbol #{name}" if func_def_type.nil? + func_def_type = symtab.get(@name) + type_error "No symbol #{@name}" if func_def_type.nil? unless func_def_type.is_a?(FunctionType) - type_error "#{name} is not a function (it's a #{func_def_type.class.name})" + type_error "#{@name} is not a function (it's a #{func_def_type.class.name})" end - type_error "Missing template arguments in call to #{name}" if template? && func_def_type.template_names.empty? + type_error "Missing template arguments in call to #{@name}" if template? && func_def_type.template_names.empty? - type_error "Template arguments provided in call to non-template function #{name}" if !template? && !func_def_type.template_names.empty? + type_error "Template arguments provided in call to non-template function #{@name}" if !template? && !func_def_type.template_names.empty? if template? num_targs = template_arg_nodes.size @@ -2598,7 +3129,7 @@ def type_check(symtab) template_arg_nodes.each_with_index do |t, idx| t.type_check(symtab) - unless t.type(symtab).convertable_to?(func_def_type.template_types[idx]) + unless t.type(symtab).convertable_to?(func_def_type.template_types(symtab)[idx]) type_error "Template argument #{idx + 1} has wrong type" end end @@ -2612,7 +3143,7 @@ def type_check(symtab) if func_def_type.num_args != num_args type_error "Wrong number of arguments to '#{name}' function call. Expecting #{func_def_type.num_args}, got #{num_args}" end - arg_nodes.each_with_index do |a, idx| + arg_nodes.each do |a| a.type_check(symtab) end arg_nodes.each_with_index do |a, idx| @@ -2640,17 +3171,17 @@ def value(symtab) type_error "not a function" unless func_def_type.is_a?(FunctionType) if func_def_type.builtin? if name == "implemented?" - extname = arg_nodes[0].text_value - return symtab.archdef.ext?(extname) + extname_ref = arg_nodes[0] + type_error "First argument should be a ExtensionName" unless extname_ref.type(symtab).kind == :enum_ref && extname_ref.class_name == "ExtensionName" + + return symtab.archdef.ext?(arg_nodes[0].member_name) else value_error "value of builtin function cannot be known" end end template_values = [] - template_arg_nodes.each_with_index do |targ, idx| - # targ_name = func_def_type.template_names[idx] - # targ_type = func_def_type.template_types[idx] + template_arg_nodes.each do |targ| template_values << targ.value(symtab) end @@ -2659,7 +3190,16 @@ def value(symtab) alias execute value def name - function_name.text_value + @name + end + + # @!macro to_idl + def to_idl + if template? + "#{name}<#{template_arg_nodes.map(&:to_idl).join(',')}>(#{arg_nodes.map(&:to_idl).join(',')})" + else + "#{name}(#{arg_nodes.map(&:to_idl).join(',')})" + end end end @@ -2691,14 +3231,24 @@ class FieldNameAst < AstNode def type_check(_symtab, _archdef) # nothing to do end + + + # @!macro to_idl + def to_idl = text_value end - module FunctionStatementAst - include Executable - include AstNodeFuncs + # module FunctionStatementAst + # include Executable + # include AstNodeFuncs - def execute(symtab) - raise "WHere is this AST?" + # def execute(symtab) + # raise "WHere is this AST?" + # end + # end + + class InstructionOperationSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + FunctionBodyAst.new(input, interval, op_stmt_list.elements.map(&:choice).map(&:to_ast) ) end end @@ -2717,23 +3267,37 @@ def execute(symtab) e.choice.execute(symtab) end end + + def to_idl = op_stmt_list.elements.map { |e| e.choice.to_idl }.join("") + end + + class FunctionBodySyntaxNode < Treetop::Runtime::SyntaxNode + # @!macro to_ast + def to_ast + FunctionBodyAst.new(input, interval, func_stmt_list.elements.map(&:choice).map(&:to_ast)) + end end class FunctionBodyAst < AstNode include Executable include Returns + def initialize(input, interval, stmts) + super(input, interval, stmts) + @stmts = stmts + end + def statements - func_stmt_list.elements.map(&:choice) + @stmts end # @!macro type_check def type_check(symtab) - internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2 + internal_error "Function bodies should be at global + 1 scope (at #{symtab.levels})" unless symtab.levels == 2 return_value_might_be_known = true - statements.each do |s| + @stmts.each do |s| s.type_check(symtab) next unless return_value_might_be_known @@ -2741,7 +3305,7 @@ def type_check(symtab) if s.is_a?(Returns) s.return_value(symtab) # if we reach here, the return value is known, so we don't have to go futher - return + break else s.execute(symtab) end @@ -2758,7 +3322,7 @@ def return_value(symtab) internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2 # go through the statements, and return the first one that has a return value - statements.each do |s| + @stmts.each do |s| if s.is_a?(Returns) v = s.return_value(symtab) return v unless v.nil? @@ -2771,10 +3335,38 @@ def return_value(symtab) end alias execute return_value + # @!macro return_values + def return_values(symtab) + internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2 + + values = [] + begin + # if there is a definate return value, then just return that + return [return_value(symtab)] + rescue ValueError + # go through the statements, and collect return values + # we can stop if we encounter a statement with a known return value + @stmts.each do |s| + if s.is_a?(Returns) + begin + v = s.return_value(symtab) + return values.push(v).uniq unless v.nil? + rescue ValueError + values += s.return_values(symtab) + end + else + s.execute(symtab) + end + end + end + + values.uniq + end + def to_idl result = "" # go through the statements, and return the first one that has a return value - statements.each do |s| + @stmts.each do |s| result << s.to_idl end result @@ -2796,7 +3388,7 @@ def num_args 1 + args.rest.elements.size end - # @return [Array] containing the argument types, in order + # @return [Array] containing the argument types, in order def arguments(symtab) if templated? template_names.each do |tname| @@ -2925,19 +3517,50 @@ def type_check(symtab) type_check_targs(symtab) + # recursion isn't supported (doesn't map well to hardware), so we can add the function after type checking the body + add_symbol(symtab) + end + + # @!macro add_symbol + def add_symbol(symtab) # now add the function in global scope def_type = FunctionType.new( - name, - self, - symtab - ) + name, + self, + symtab + ) - # recursion isn't supported (doesn't map well to hardware), so we can add the function after type checking the body symtab.add!(name, def_type) end - attr_reader :template_names - attr_reader :template_types + # @return [Array] Template arugment names, in order + def template_names + return [] unless templated? + + tnames = [targs.first.id.text_value] + targs.rest.elements.each do |a| + tnames << a.function_argument_definition.id.text_value + end + tnames + end + + # @param symtab [SymbolTable] The context for evaluation + # @return [Array] Template argument types, in order + def template_types(symtab) + return [] unless templated? + + ttype = targs.first.type_name.type(symtab) + ttype = Type.new(:enum_ref, enum_class: ttype) if ttype.kind == :enum + + ttypes = [ttype.clone] + targs.rest.elements.each do |a| + ttype = a.function_argument_definition.type_name.type(symtab) + ttype = Type.new(:enum_ref, enum_class: ttype) if ttype.kind == :enum + ttypes << ttype + end + ttypes + end + def type_check_targs(symtab) @template_names = [] @template_types = [] @@ -3039,42 +3662,66 @@ def builtin? end + class ForLoopSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + ForLoopAst.new( + input, interval, + single_declaration_with_initialization.to_ast, + condition.to_ast, + action.to_ast, + stmts.elements.map(&:s).map(&:to_ast) + ) + end + end + class ForLoopAst < AstNode include Executable include Returns # a return statement in a for loop can make it return a value + attr_reader :init, :condition, :update, :stmts + + def initialize(input, interval, init, condition, update, stmts) + super(input, interval, [init, condition] + stmts) + + @init = init + @condition = condition + @update = update + @stmts = stmts + end + # @!macro type_check def type_check(symtab) symtab.push - single_declaration_with_initialization.type_check(symtab) - condition.type_check(symtab) - action.type_check(symtab) + @init.type_check(symtab) + @condition.type_check(symtab) + @update.type_check(symtab) - stmts.elements.each do |s| - s.s.type_check(symtab) + @stmts.each do |s| + s.type_check(symtab) end symtab.pop end + # @!macro return_value def return_value(symtab) symtab.push begin - single_declaration_with_initialization.execute(symtab) + @init.execute(symtab) - while condition.value(symtab) - stmts.elements.each do |s| - if s.s.is_a?(Returns) - v = s.s.return_value(symtab) + while @condition.value(symtab) + @stmts.each do |s| + if s.is_a?(Returns) + v = s.return_value(symtab) unless v.nil? symtab.pop return v end else - s.s.execute(symtab) + s.execute(symtab) end end - action.execute(symtab) + @update.execute(symtab) end rescue ValueError => e symtab.pop @@ -3084,150 +3731,365 @@ def return_value(symtab) symtab.pop nil end + + # @!macro return_values + def return_values(symtab) + # if there is a known return value, then we are done + [return_value(symtab)] + rescue ValueError + # see if we can collect a list + values = [] + symtab.push + + begin + @init.execute(symtab) + + while @condition.value(symtab) + @stmts.each do |s| + if s.is_a?(Returns) + begin + v = s.return_value(symtab) + return values.push(v).uniq unless v.nil? + rescue ValueError + values += s.return_values(symtab) + end + else + s.execute(symtab) + end + end + @update.execute(symtab) + end + ensure + symtab.pop + end + + values.uniq + end + + # @!macro execute alias execute return_value + + # @!macro to_idl + def to_idl + idl = "for (#{@init.to_idl}; #{@condition.to_idl}; #{@update.to_idl}) {" + @stmts.each do |s| + idl << s.to_idl + end + idl << "}" + idl + end end - class IfAst < AstNode + class IfBodyAst < AstNode include Executable include Returns + attr_reader :stmts + + def initialize(body_stmts) + if body_stmts.empty? + super("", 0...0, []) + else + super(body_stmts[0].input, body_stmts.first.interval.first..body_stmts.last.interval.end, body_stmts) + end + @stmts = body_stmts + end + # @!macro type_check def type_check(symtab) - level = symtab.levels - if_cond.type_check(symtab) + symtab.push - type_error "'#{if_cond.text_value}' is not boolean" unless if_cond.type(symtab).convertable_to?(:boolean) + @stmts.each do |s| + s.type_check(symtab) + end - symtab.push + symtab.pop + end + # @!macro return_value + def return_value(symtab) + symtab.push begin - # only type check the body if it is reachable - if if_cond.value(symtab) == true - if_body.elements.each do |e| - e.e.type_check(symtab) + @stmts.each do |s| + if s.is_a?(Returns) + v = s.return_value(symtab) + unless v.nil? + return v + end + else + s.execute(symtab) end - return # don't bother with the rest - end - rescue ValueError - # we don't know if the body is reachable; type check it - if_body.elements.each do |e| - e.e.type_check(symtab) end ensure symtab.pop end - internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels - - unless elseifs.empty? - elseifs.elements.each do |eif| - eif.expression.type_check(symtab) - unless eif.expression.type(symtab).convertable_to?(:boolean) - type_error "'#{eif.expression.text_value}' is not boolean" - end + nil + end - symtab.push - begin - # only type check the body if it is reachable - if eif.expression.value(symtab) == true - eif.body.elements.each do |e| - e.e.type_check(symtab) - end - return # don't bother with the rest - end - rescue ValueError - # condition isn't compile-time-known; have to check the body - eif.body.elements.each do |e| - e.e.type_check(symtab) + # @!macro return_values + def return_values(symtab) + values = [] + symtab.push + begin + @stmts.each do |s| + if s.is_a?(Returns) + begin + v = s.return_value(symtab) + return values.push(v).uniq unless v.nil? + rescue ValueError + values += s.return_values(symtab) end - ensure - symtab.pop + else + s.execute(symtab) end end + ensure + symtab.pop end - return if final_else.empty? + values.uniq + end - internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels + # @!macro execute + def execute(symtab) + stmts.each do |s| + s.execute(symtab) + end + end - symtab.push - final_else.body.elements.each do |e| - e.e.type_check(symtab) + # @!macro to_idl + def to_idl + stmts.map(&:to_idl).join("") + end + + end + + class ElseIfAst < AstNode + include Returns + + attr_reader :cond, :body + + def initialize(cond, body_stmts) + @body = IfBodyAst.new(body_stmts) + super(cond.input, cond.interval.first..body_stmts.last.interval.end, [cond, @body]) + @cond = cond + end + + def type_check(symtab) + @cond.type_check(symtab) + unless @cond.type(symtab).convertable_to?(:boolean) + type_error "'#{@cond.text_value}' is not boolean" end - symtab.pop - internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels + begin + # only type check the body if it is reachable + if @cond.value(symtab) == true + @body.type_check(symtab) + return # don't bother with the rest + end + rescue ValueError + # condition isn't compile-time-known; have to check the body + @body.type_check(symtab) + end end - # @return [Boolean] true if the taken path is knowable at compile-time - # @raise ValueError if the take path is not known at compile time - def taken_body(symtab) - return if_body if if_cond.value(symtab) + # @!macro return_values + def return_values(symtab) + if @cond.value(symtab) + @body.return_values(symtab) + else + [] + end + rescue ValueError + # might be taken, so add the possible return values + @body.return_values(symtab) + end + # @!macro to_idl + def to_idl + " else if (#{@cond.to_idl}) { #{@body.to_idl} }" + end + end + + class IfSyntaxNode < Treetop::Runtime::SyntaxNode + def to_ast + if_body_stmts = [] + if_body.elements.each do |e| + if_body_stmts << e.e.to_ast + end + eifs = [] unless elseifs.empty? elseifs.elements.each do |eif| - return eif.body if eif.expression.value(symtab) + stmts = [] + eif.body.elements.each do |e| + stmts << e.e.to_ast + end + eifs << ElseIfAst.new(eif.expression.to_ast, stmts) end end - - final_else.empty? ? nil : final_else.body + final_else_stmts = [] + unless final_else.empty? + final_else.body.elements.each do |e| + final_else_stmts << e.e.to_ast + end + end + if_body_ast = IfBodyAst.new(if_body_stmts) + final_else_ast = IfBodyAst.new(final_else_stmts) + ast = IfAst.new(if_cond.to_ast, if_body_ast, eifs, final_else_ast) + ast.parent = parent + if_body_ast.parent = ast + eifs.each { |eif| eif.parent = ast } + final_else_ast.parent = ast + ast end + end - def return_values(symtab) - begin - # the if condition is known - if if_cond.value(symtab) + class IfAst < AstNode + include Executable + include Returns + + attr_reader :if_cond, :if_body, :elseifs, :final_else_body + + def initialize(if_cond, if_body, elseifs, final_else_body) + children_nodes = [if_cond, if_body] + children_nodes += elseifs + children_nodes << final_else_body + interval_end = + if !final_else_body.stmts.empty? + final_else_body.stmts.last.interval.end + elsif !elseifs.empty? + elseifs.last.body.stmts.last.interval.end else + if_body.stmts.last.interval.end + end + + super(if_cond.input, if_cond.interval.first..interval_end, children_nodes) + + @if_cond = if_cond + @if_body = if_body + @elseifs = elseifs + @final_else_body = final_else_body + end + + # @!macro type_check + def type_check(symtab) + level = symtab.levels + if_cond.type_check(symtab) + + type_error "'#{if_cond.text_value}' is not boolean" unless if_cond.type(symtab).convertable_to?(:boolean) + + begin + # only type check the body if it is reachable + if @if_cond.value(symtab) == true + @if_body.type_check(symtab) + return # don't bother with the rest end rescue ValueError + # we don't know if the body is reachable; type check it + @if_body.type_check(symtab) + end + + internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels + + unless @elseifs.empty? + @elseifs.each do |eif| + eif.type_check(symtab) + end end + + internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels + + @final_else_body.type_check(symtab) + + internal_error "not at same level #{level} #{symtab.levels}" unless level == symtab.levels end + # @return [Boolean] true if the taken path is knowable at compile-time + # @raise ValueError if the take path is not known at compile time + def taken_body(symtab) + return @if_body if @if_cond.value(symtab) + + unless @elseifs.empty? + @elseifs.each do |eif| + return eif.body if eif.cond.value(symtab) + end + end + + @final_else_body.stmts.empty? ? nil : @final_else_body + end + + # @!macro return_value def return_value(symtab) body = taken_body(symtab) return nil if body.nil? - symtab.push - begin - body.elements.each do |e| - if e.e.is_a?(Returns) - v = e.e.return_value(symtab) - unless v.nil? - return v + body.return_value(symtab) + end + alias execute return_value + + # return values starting at the first else if + def return_values_after_if(symtab) + values = [] + + unless @elsifs.empty? + @elsifs.each do |eif| + values += eif.return_values(symtab) + begin + elseif_cond_value = eif.value(symtab) + if elseif_cond_value + # this else if is defintately taken, so we are done + return (values + eif.return_values(symtab)).uniq + else + next # we know the else if isn't taken, so we can just go to the next end - else - e.e.execute(symtab) + rescue ValueError + # else if path not known; body return paths are possible + values += eif.return_values(symtab) end end - ensure - symtab.pop end - nil + # now add the returns from the final else + (values + @final_else_body.return_values(symtab)).uniq end + private :return_values_after_if - def to_idl - result = "if (#{if_cond.to_idl}) { " - if_body.elements.each do |e| - result << e.e.to_idl + # Returns a list of all possible return values, if known. Otherwise, raises a ValueError + # + # @param symtab [SymbolTable] Context for the evaluation + # @return [Array] List of all possible return values + # @raise ValueError if it is not possible to determine all return values at compile time + def return_values(symtab) + if_cond_value = @if_cond.value(symtab) + if if_cond_value + # if is taken, so the only possible return values are those in the if body + @if_body.return_values(symtab) + else + # if cond not taken; check else ifs and possibly final else + return_values_after_if(symtab) end + rescue ValueError + # if condition not known; both paths are possible + (@if_body.return_values(symtab) + return_values_after_if(symtab)).uniq + end + + # @!macro to_idl + def to_idl + result = "if (#{@if_cond.to_idl}) { " + result << @if_body.to_idl result << "} " - elseifs.elements.each do |eif| - result << " else if (#{eif.expression.to_idl}) { " - eif.body.elements.each do |e| - result << e.e.to_idl - end - result << "} " + @elseifs.each do |eif| + result << eif.to_idl end - unless final_else.empty? + unless @final_else_body.stmts.empty? result << " else { " - final_else.body.elements.each do |e| - result << e.e.to_idl - end + result << @final_else_body.to_idl result << "} " end + result end end @@ -3236,11 +4098,7 @@ class CsrFieldReadExpressionAst < AstNode # @!macro type_check def type_check(symtab) - archdef = symtab.archdef - - - - if idx.is_a?(IntAst) + if idx.is_a?(IntLiteralAst) type_error "No CSR at address #{idx.text_value}" if csr_def(symtab).nil? else # idx is a csr name @@ -3253,7 +4111,7 @@ def type_check(symtab) def csr_def(symtab) archdef = symtab.archdef - if idx.is_a?(IntAst) + if idx.is_a?(IntLiteralAst) archdef.implemented_csrs.find { |c| c.address == idx.value(symtab) } else archdef.implemented_csrs.find { |c| c.name == idx.text_value } @@ -3274,7 +4132,7 @@ def field_name(symtab) # @!macro to_idl def to_idl - if idx.is_a?(IntAst) + if idx.is_a?(IntLiteralAst) "CSR[#{idx.to_idl}].#{csr_field_name.text_value}" else "CSR[#{idx.text_value}].#{csr_field_name.text_value}" @@ -3373,6 +4231,7 @@ def csr_name(symtab) csr_def(symtab).name end + # @!macro value def value(symtab) cd = csr_def(symtab) value_error "CSR number not knowable" if cd.nil? @@ -3381,6 +4240,9 @@ def value(symtab) csr_def(symtab).fields.reduce(0) { |val, f| val | (f.value << f.location.begin) } end + + # @!macro to_idl + def to_idl = "CSR[#{idx.text_value}]" end class CsrSoftwareWriteAst < AstNode @@ -3405,10 +4267,16 @@ def csr_name(symtab) csr.csr_name(symtab) end + # @!macro value def value(_symtab) value_error "CSR writes are global" end + # @!macro execute + def execute(_symtab) = value_error "CSR writes are global" + + # @!macro to_idl + def to_idl = "CSR[#{csr.to_idl}].sw_write(#{expression.to_idl})" end class CsrSoftwareReadAst < AstNode @@ -3442,19 +4310,23 @@ def csr_def(symtab) # @todo check the sw_read function body def value(symtab) - value_error "CSR not knowable" unless csr_known? + value_error "CSR not knowable" unless csr_known?(symtab) cd = csr_def(symtab) cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" } value_error "TODO: CSRs with sw_read function" end + + # @!macro to_idl + def to_idl = "CSR[#{csr.to_idl}].sw_read()" end class CsrWriteAst < AstNode include Executable + # @!macro type_check def type_check(symtab) - if idx.is_a?(IntAst) + if idx.is_a?(IntLiteralAst) # make sure this value is a defined CSR index = symtab.archdef.csrs.index { |csr| csr.address == idx.value(symtab) } type_error "No csr number '#{idx.value(symtab)}' was found" if index.nil? @@ -3468,7 +4340,7 @@ def type_check(symtab) def csr_def(symtab) index = - if idx.is_a?(IntAst) + if idx.is_a?(IntLiteralAst) # make sure this value is a defined CSR symtab.archdef.csrs.index { |csr| csr.address == idx.text_value.to_i } else @@ -3478,6 +4350,7 @@ def csr_def(symtab) symtab.archdef.csrs[index] end + # @!macro type def type(symtab) CsrType.new(csr_def(symtab)) end @@ -3486,8 +4359,12 @@ def name(symtab) csr_def(symtab).name end + # @!macro execute def execute(symtab) value_error "CSR write" end + + # @!macro to_idl + def to_idl = "CSR[#{idx.text_value}]" end end diff --git a/lib/idl/idl.treetop b/lib/idl/idl.treetop index 4fcbf87ae..2c495fff8 100644 --- a/lib/idl/idl.treetop +++ b/lib/idl/idl.treetop @@ -32,7 +32,7 @@ grammar Idl end rule enum_ref - enum_class:user_type_name space* '::' space* member:user_type_name + enum_class:user_type_name space* '::' space* member:user_type_name end rule bitfield_definition @@ -47,31 +47,31 @@ grammar Idl rule int # verilog style: explicit bit width - ([0-9]+)? "'" 'b' [0-1] [0-1_]* / - ([0-9]+)? "'" 'o' [0-7] [0-7_]* / - ([0-9]+)? "'" 'd'? [0-9] [0-9]* / - ([0-9]+)? "'" 'h' [0-9a-fA-F] [0-9a-fA-F]* / + ([0-9]+)? "'" 'b' [0-1] [0-1_]* / + ([0-9]+)? "'" 'o' [0-7] [0-7_]* / + ([0-9]+)? "'" 'd'? [0-9] [0-9_]* / + ([0-9]+)? "'" 'h' [0-9a-fA-F] [0-9a-fA-F_]* / # verilog style: explicit bit width, signed - ([0-9]+)? "'" 'sb' [0-1] [0-1_]* / - ([0-9]+)? "'" 'so' [0-7] [0-7_]* / - ([0-9]+)? "'" 'sd' [0-9] [0-9]* / - ([0-9]+)? "'" 'sh' [0-9a-fA-F] [0-9a-fA-F]* / + ([0-9]+)? "'" 'sb' [0-1] [0-1_]* / + ([0-9]+)? "'" 'so' [0-7] [0-7_]* / + ([0-9]+)? "'" 's' 'd'? [0-9] [0-9_]* / + ([0-9]+)? "'" 'sh' [0-9a-fA-F] [0-9a-fA-F_]* / # c++ style: signed - '0b' [0-1] [0-1_]* 's' / - '0' [0-7] [0-7_]* 's' / - [1-9] [0-9]* 's' / - '0x' [0-9a-fA-F] [0-9a-fA-F]* 's' / + '0b' [0-1] [0-1_]* 's' / + '0' [0-7] [0-7_]* 's' / + [1-9] [0-9]* 's' / + '0x' [0-9a-fA-F] [0-9a-fA-F]* 's' / # c++ style: unsigned - '0b' [0-1] [0-1_]* / - '0' [0-7] [0-7_]* / - [1-9] [0-9]* / - '0x' [0-9a-fA-F] [0-9a-fA-F]* / + '0b' [0-1] [0-1_]* / + '0' [0-7] [0-7_]* / + [1-9] [0-9]* / + '0x' [0-9a-fA-F] [0-9a-fA-F]* / # special case: just a single 0 - '0' 's'? + '0' 's'? end rule bits @@ -140,114 +140,114 @@ grammar Idl end rule p0_binary_expression - l:unary_expression r:(space* op:p0_binary_operator space* r:p0_binary_expression)+ + l:unary_expression r:(space* op:p0_binary_operator space* r:unary_expression)+ / unary_expression end rule p1_binary_expression - l:p0_binary_expression r:(space* op:p1_binary_operator space* r:p1_binary_expression)+ + l:p0_binary_expression r:(space* op:p1_binary_operator space* r:p0_binary_expression)+ / p0_binary_expression end rule p2_binary_expression - l:p1_binary_expression r:(space* op:p2_binary_operator space* r:p2_binary_expression)+ + l:p1_binary_expression r:(space* op:p2_binary_operator space* r:p1_binary_expression)+ / p1_binary_expression end rule p3_binary_expression - l:p2_binary_expression r:(space* op:p3_binary_operator space* r:p3_binary_expression)+ + l:p2_binary_expression r:(space* op:p3_binary_operator space* r:p2_binary_expression)+ / p2_binary_expression end rule template_safe_p3_binary_expression - l:p2_binary_expression r:(space* op:p3_template_binary_operator space* r:p3_binary_expression)+ + l:p2_binary_expression r:(space* op:p3_template_binary_operator space* r:p2_binary_expression)+ / p2_binary_expression end rule p4_binary_expression - l:p3_binary_expression r:(space* op:p4_binary_operator space* r:p4_binary_expression)+ + l:p3_binary_expression r:(space* op:p4_binary_operator space* r:p3_binary_expression)+ / p3_binary_expression end rule template_safe_p4_binary_expression - l:template_safe_p3_binary_expression r:(space* op:p4_binary_operator space* r:p4_binary_expression)+ + l:template_safe_p3_binary_expression r:(space* op:p4_binary_operator space* r:p3_binary_expression)+ / template_safe_p3_binary_expression end rule p5_binary_expression - l:p4_binary_expression r:(space* op:p5_binary_operator space* r:p5_binary_expression)+ + l:p4_binary_expression r:(space* op:p5_binary_operator space* r:p4_binary_expression)+ / p4_binary_expression end rule template_safe_p5_binary_expression - l:template_safe_p4_binary_expression r:(space* op:p5_binary_operator space* r:p5_binary_expression)+ + l:template_safe_p4_binary_expression r:(space* op:p5_binary_operator space* r:p4_binary_expression)+ / template_safe_p4_binary_expression end rule p6_binary_expression - l:p5_binary_expression r:(space* op:p6_binary_operator space* r:p6_binary_expression)+ + l:p5_binary_expression r:(space* op:p6_binary_operator space* r:p5_binary_expression)+ / p5_binary_expression end rule template_safe_p6_binary_expression - l:template_safe_p5_binary_expression r:(space* op:p6_binary_operator space* r:p6_binary_expression)+ + l:template_safe_p5_binary_expression r:(space* op:p6_binary_operator space* r:p5_binary_expression)+ / template_safe_p5_binary_expression end rule p7_binary_expression - l:p6_binary_expression r:(space* op:p7_binary_operator space* r:p7_binary_expression)+ + l:p6_binary_expression r:(space* op:p7_binary_operator space* r:p6_binary_expression)+ / p6_binary_expression end rule template_safe_p7_binary_expression - l:template_safe_p6_binary_expression r:(space* op:p7_binary_operator space* r:p7_binary_expression)+ + l:template_safe_p6_binary_expression r:(space* op:p7_binary_operator space* r:p6_binary_expression)+ / template_safe_p6_binary_expression end rule p8_binary_expression - l:p7_binary_expression r:(space* op:p8_binary_operator space* r:p8_binary_expression)+ + l:p7_binary_expression r:(space* op:p8_binary_operator space* r:p7_binary_expression)+ / p7_binary_expression end rule template_safe_p8_binary_expression - l:template_safe_p7_binary_expression r:(space* op:p8_binary_operator space* r:p8_binary_expression)+ + l:template_safe_p7_binary_expression r:(space* op:p8_binary_operator space* r:p7_binary_expression)+ / template_safe_p7_binary_expression end rule p9_binary_expression - l:p8_binary_expression r:(space* op:p9_binary_operator space* r:p9_binary_expression)+ + l:p8_binary_expression r:(space* op:p9_binary_operator space* r:p8_binary_expression)+ / p8_binary_expression end rule template_safe_p9_binary_expression - l:template_safe_p8_binary_expression r:(space* op:p9_binary_operator space* r:p9_binary_expression)+ + l:template_safe_p8_binary_expression r:(space* op:p9_binary_operator space* r:p8_binary_expression)+ / template_safe_p8_binary_expression end rule paren_expression - '(' space* e:expression space* ')' + '(' space* e:expression space* ')' end rule replication_expression # verilog-style replication - '{' space* n:expression space* '{' space* v:expression space* '}' space* '}' + '{' space* n:expression space* '{' space* v:expression space* '}' space* '}' end rule concatenation_expression @@ -288,7 +288,7 @@ grammar Idl end rule ary_access - a:ary_eligible_expression space* brackets:('[' space* msb:(expression space* ':' space*)? lsb:expression space* ']' space*)+ + a:ary_eligible_expression space* brackets:('[' space* msb:(expression space* ':' space*)? lsb:expression space* ']' space*)+ end rule post_dec @@ -304,7 +304,7 @@ grammar Idl / ary_access / - '$signed' space* '(' space* expression space* ')' + '$signed' space* '(' space* expression space* ')' / '$bits' space* '(' space* expression space* ')' / @@ -334,7 +334,7 @@ grammar Idl end rule ternary_expression - p9_binary_expression space* '?' space* t:expression space* ':' space* f:expression + p9_binary_expression space* '?' space* t:expression space* ':' space* f:expression end rule template_safe_ternary_expression @@ -367,7 +367,7 @@ grammar Idl / csr:csr_register_access_expression space* '.' space* 'sw_read' space* '(' space* ')' / - function_name t:(space* '<' space* targs:function_call_template_arguments space* '>')? space* '(' space* function_arg_list space* ')' + function_name t:(space* '<' space* targs:function_call_template_arguments space* '>')? space* '(' space* function_arg_list space* ')' end rule function_name @@ -425,21 +425,17 @@ grammar Idl type_name space+ id end - rule exception_name - 'AddressMisalignedException' - end - rule rval - (var_read / int) + (id / int / builtin_read_only_var / builtin_read_write_var) end rule assignment '(' first:(var_write / dontcare_lvalue) space* rest:(',' space* var:(var_write / dontcare_lvalue) space*)+ ')' space* '=' space* function_call / single_declaration_with_initialization / - var:var_write space* '=' space* rval:expression / + var:var_write space* '=' space* rval:expression / var:var_write '.' field_name space* '=' space* rval:expression / var:var_write space* '[' space* msb:expression space* ':' space* lsb:expression space* ']' space* '=' space* rval:expression / - var:var_write space* '[' space* idx:expression space* ']' space* '=' space* rval:expression + var:var_write space* '[' space* idx:expression space* ']' space* '=' space* rval:expression end rule ary_size_decl @@ -447,7 +443,7 @@ grammar Idl end rule single_declaration_with_initialization - q:type_qualifier? space* type_name space+ var_write space* ary_size:ary_size_decl? space* '=' space* rval:expression + q:type_qualifier? space* type_name space+ var_write space* ary_size:ary_size_decl? space* '=' space* rval:expression end rule declaration @@ -461,9 +457,9 @@ grammar Idl end rule statement - a:(function_call / assignment) space* 'if' space* expression space* ';' + a:(function_call / assignment) space* 'if' space* expression space* ';' / - a:(function_call / assignment / declaration) space* ';' + a:(function_call / assignment / declaration) space* ';' end rule dontcare_lvalue @@ -471,7 +467,7 @@ grammar Idl end rule dontcare_return - '-' + '-' end rule return_statement @@ -493,7 +489,7 @@ grammar Idl space* 'else' space* '{' space* body:(e:(statement / return_statement / function_if_block / for_loop) space*)+ '}' - )? + )? end rule execute_if_block @@ -509,13 +505,13 @@ grammar Idl space* 'else' space* '{' space* body:(e:(statement / execute_if_block / for_loop) space*)+ '}' - )? + )? end rule for_loop 'for' space* '(' space* single_declaration_with_initialization space* ';' space* condition:expression space* ';' space* action:(assignment / post_inc / post_dec) space* ')' space* '{' space* stmts:(s:(statement / return_statement / function_if_block / for_loop) space*)+ - '}' + '}' end rule type_qualifier @@ -524,17 +520,17 @@ grammar Idl rule builtin_type_name # alias for Bits - 'XReg' ![A-Za-z0-9] / + 'XReg' ![A-Za-z0-9] / - 'Bits' space* '<' space* i:template_safe_expression space* '>' ![A-Za-z0-9] / + 'Bits' space* '<' space* i:template_safe_expression space* '>' ![A-Za-z0-9] / - 'Boolean' ![A-Za-z0-9] / + 'Boolean' ![A-Za-z0-9] / # 64-bit unsigned integer - 'U64' ![A-Za-z0-9] / + 'U64' ![A-Za-z0-9] / # 32-bit unsigned integer - 'U32' ![A-Za-z0-9] + 'U32' ![A-Za-z0-9] end rule keyword @@ -577,17 +573,25 @@ grammar Idl end rule function_body - space* func_stmt_list:(choice:function_statement space*)* + space* func_stmt_list:(choice:function_statement space*)* end rule instruction_operation - space* op_stmt_list:(choice:(statement/execute_if_block/for_loop) space*)* + space* op_stmt_list:(choice:(statement/execute_if_block/for_loop) space*)* end rule id # we purposely omit _ from the starting character so that tools can safely use such names # without worrying about name collisions - !reserved [A-Za-z] [A-Za-z_0-9]* + !reserved [A-Za-z] [A-Za-z_0-9]* + end + + rule builtin_read_only_var + "$encoding" + end + + rule builtin_read_write_var + "$pc" end rule csr_name @@ -598,10 +602,6 @@ grammar Idl [a-zA-Z] ([a-zA-Z0-9])* end - rule var_read - id - end - rule var_write 'CSR' space* '[' space* idx:(csr_name / int) space* ']' / diff --git a/lib/idl/passes/gen_adoc.rb b/lib/idl/passes/gen_adoc.rb index ef5355c6a..3145a4b8e 100644 --- a/lib/idl/passes/gen_adoc.rb +++ b/lib/idl/passes/gen_adoc.rb @@ -1,51 +1,237 @@ require_relative "../ast" -class Treetop::Runtime::SyntaxNode +class Idl::AstNode def gen_adoc(indent = 0, indent_spaces: 2) - if terminal? - text_value - else - adoc = '' - next_pos = interval.begin - elements.each do |e| - if e.interval.size > 0 && e.interval.begin != next_pos - adoc << input[next_pos..(e.interval.begin - 1)] - end - adoc << e.gen_adoc(indent+2, indent_spaces: 2) - next_pos = e.interval.exclude_end? ? e.interval.end : (e.interval.end + 1) - end - if next_pos != (interval.exclude_end? ? interval.end : (interval.end + 1)) - end_pos = interval.exclude_end? ? interval.end - 1 : interval.end - adoc << input[next_pos..end_pos] - end - if adoc != text_value && !text_value.index('xref').nil? - raise - end - adoc + adoc = [] + puts self.class.name if elements.nil? + elements.each do |e| + next unless e.is_a?(Idl::AstNode) + + adoc << e.gen_adoc(indent, indent_spaces:) end + adoc.map{ |a| "#{' '*indent}#{a}" }.join('') end + # def gen_adoc(indent = 0, indent_spaces: 2) + # if terminal? + # text_value + # else + # adoc = '' + # next_pos = interval.begin + # elements.each do |e| + # if e.interval.size > 0 && e.interval.begin != next_pos + # adoc << input[next_pos..(e.interval.begin - 1)] + # end + # adoc << e.gen_adoc(indent+2, indent_spaces: 2) + # next_pos = e.interval.exclude_end? ? e.interval.end : (e.interval.end + 1) + # end + # if next_pos != (interval.exclude_end? ? interval.end : (interval.end + 1)) + # end_pos = interval.exclude_end? ? interval.end - 1 : interval.end + # adoc << input[next_pos..end_pos] + # end + # if adoc != text_value && !text_value.index('xref').nil? + # raise + # end + # adoc + # end + # end end module Idl + class EnumRefAst + def gen_adoc(indent, indent_spaces: 2) + "#{class_name}::#{member_name}" + end + end + class ParenExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + "(#{expression.gen_adoc(indent, indent_spaces:)})" + end + end + class IntLiteralAst + def gen_adoc(indent = 0, indent_spaces: 2) + raise "?" if text_value.empty? + text_value + end + end + class IdAst + def gen_adoc(indent = 0, indent_spaces: 2) + text_value + end + end + class SignCastAst + def gen_adoc(indent = 0, indent_spaces: 2) + "$signed(#{expression.gen_adoc(0, indent_spaces:)})" + end + end class AryRangeAccessAst def gen_adoc(indent = 0, indent_spaces: 2) - adoc = '' - unless var.is_a?(AryRangeAccessAst) || var.is_a?(AryElementAccessAst) - adoc << input[interval.begin...var.interval.begin] - adoc << var.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces) + "#{var.gen_adoc(indent, indent_spaces:)}[#{msb.gen_adoc(0, indent_spaces:)}:#{lsb.gen_adoc(0, indent_spaces:)}]" + end + end + + class VariableDeclarationAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{var_write.gen_adoc(0, indent_spaces:)};" + end + end + + class TernaryOperatorExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{' ' * indent}#{condition.gen_adoc(0, indent_spaces:)} ? #{true_expression.gen_adoc(0, indent_spaces:)} : #{false_expression.gen_adoc(0, indent_spaces:)}" + end + end + + class BuiltinTypeNameAst + def gen_adoc(indent = 0, indent_spaces: 2) + if @type_name == "Bits" + "Bits<#{@bits_expression.gen_adoc(0, indent_spaces:)}>" + else + to_idl end - adoc << input[var.interval.end...msb.interval.begin] - adoc << msb.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces) - adoc << input[msb.interval.end...lsb.interval.begin] - adoc << lsb.gen_adoc(indent + indent_spaces, indent_spaces: indent_spaces) - adoc << input[lsb.interval.end...interval.end] - adoc + end + end + + class ForLoopAst + def gen_adoc(indent = 0, indent_spaces: 2) + lines = ["#{' '*indent}for (#{init.gen_adoc(0, indent_spaces:)}; #{condition.gen_adoc(0, indent_spaces:)}; #{update.gen_adoc(0, indent_spaces:)}) {"] + stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + lines << "#{' '*indent}}" + lines.join("\n") + end + end + + class BuiltinVariableAst + def gen_adoc(indent = 0, indent_spaces: 2) + name + end + end + + class VariableDeclarationWithInitializationAst + def gen_adoc(indent = 0, indent_spaces: 2) + if @ary_size.nil? + "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{lhs.gen_adoc(0, indent_spaces:)} = #{rhs.gen_adoc(0, indent_spaces:)};" + else + "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{lhs.gen_adoc(0, indent_spaces:)}[#{@ary_size.gen_adoc(0, indent_spaces:)}] = #{rhs.gen_adoc(0, indent_spaces:)};" + end + end + end + + class AryElementAccessAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{var.gen_adoc(indent, indent_spaces:)}[#{index.gen_adoc(0, indent_spaces:)}]" + end + end + + class BinaryExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{lhs.gen_adoc(0, indent_spaces:)} #{op} #{rhs.gen_adoc(0, indent_spaces:)}" + end + end + + class VariableAssignmentAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{lhs.gen_adoc(0, indent_spaces:)} = #{rhs.gen_adoc(0, indent_spaces:)}" + end + end + + class AryElementAssignmentAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{lhs.gen_adoc(0, indent_spaces:)}[#{@idx.gen_adoc(0, indent_spaces:)}] = #{@rhs.gen_adoc(0, indent_spaces:)}" + end + end + + class StatementAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{' ' * indent}#{action.gen_adoc(0, indent_spaces:)};" + end + end + + class UnaryOperatorExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{op}#{exp.gen_adoc(0, indent_spaces:)}" + end + end + + class ReturnStatementAst + def gen_adoc(indent = 0, indent_spaces: 2) + values = [first.gen_adoc(0, indent_spaces:)] + rest.elements.each { |e| e.e.gen_adoc(0, indent_spaces: )} + "#{' ' * indent}return #{values.join(', ')};" + end + end + + class ReplicationExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + puts v.class.name + "{#{n.gen_adoc(indent, indent_spaces:)}{#{v.gen_adoc(indent, indent_spaces:)}}}" + end + end + + class ConditionalStatementAst + def gen_adoc(indent = 0, indent_spaces: 2) + "#{action.gen_adoc(indent, indent_spaces:)} if (#{condition.gen_adoc(0, indent_spaces:)});" end end class FunctionCallExpressionAst def gen_adoc(indent = 0, indent_spaces: 2) - "xref:funcs:funcs.adoc##{name}-func-def[#{name}]" << t.gen_adoc << "(#{function_arg_list.gen_adoc})" + after_name = [] + after_name << "<#{template_arg_nodes.map { |t| t.gen_adoc(0, indent_spaces:)}.join(', ')}>" unless template_arg_nodes.empty? + after_name << "(#{arg_nodes.map { |a| a.gen_adoc(0, indent_spaces: ) }.join(', ')})" + "%%LINK%func;#{name};#{name}%%#{after_name.join ''}" + end + end + + class FunctionBodyAst + def gen_adoc(indent = 0, indent_spaces: 2) + statements.map{ |s| "#{' ' * indent}#{s.gen_adoc(indent, indent_spaces:)}" }.join("\n") + end + end + + class CsrFieldReadExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + csr_text = "CSR[#{idx.text_value}].#{csr_field_name.text_value}" + if idx.text_value =~ /[0-9]+/ + csr_text + else + "%%LINK%csr_field;#{idx.text_value}.#{csr_field_name.text_value};#{csr_text}%%" + end + end + end + + class CsrReadExpressionAst + def gen_adoc(indent = 0, indent_spaces: 2) + csr_text = "CSR[#{idx.text_value}]" + if idx.text_value =~ /[0-9]+/ + csr_text + else + "%%LINK%csr;#{idx.text_value};#{csr_text}%%" + end + end + end + + class IfAst + def gen_adoc(indent = 0, indent_spaces: 2) + lines = ["if (#{if_cond.gen_adoc(0, indent_spaces:)}) {"] + if_body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + elseifs.each do |eif| + lines << "} else if (#{eif.cond.gen_adoc(0, indent_spaces:)}) {" + eif.body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + end + unless final_else_body.stmts.empty? + lines << "} else {" + final_else_body.stmts.each do |s| + lines << s.gen_adoc(indent + indent_spaces, indent_spaces:) + end + end + lines << "}" + + lines.map { |l| "#{' ' * indent}#{l}"}.join("\n") end end end diff --git a/lib/idl/passes/prune.rb b/lib/idl/passes/prune.rb new file mode 100644 index 000000000..5b0f9fb46 --- /dev/null +++ b/lib/idl/passes/prune.rb @@ -0,0 +1,223 @@ +# frozen_string_literal: true + +require_relative "../ast" + +module Treetop + module Runtime + class SyntaxNode + # @!macro [new] prune + # @param symtab [Idl::SymbolTable] Context of the compilation + # @return [AstNode] A new abstract syntax tree with all dead/unreachable code removed + def prune(symtab) + new_elements = elements.nil? ? [] : elements.map { |e| e.prune(symtab) } + new_node = clone # self.class.new(input, interval, new_elements) + new_node.elements.clear + new_node.elements.concat(new_elements) + + # extension_modules.each do |m| + # new_node.extend m + # end + + if is_a?(Idl::AstNode) + begin + if new_node.is_a?(Idl::Declaration) + new_node.add_symbol(symtab) + end + if new_node.is_a?(Idl::Executable) + new_node.execute(symtab) # to update values + end + rescue Idl::AstNode::ValueError + # new_node.type_check(symtab) + end + end + + new_node + end + end + end +end + +module Idl + # set up a default + class AstNode + def prune(_symtab) + clone + end + end + class FunctionCallExpressionAst + def prune(symtab) + FunctionCallExpressionAst.new(input, interval, name, @targs.map { |t| t.prune(symtab) }, @args.map { |a| a.prune(symtab)} ) + end + end + class FunctionBodyAst + def prune(symtab) + symtab.push + raise "?" if symtab.get("current_mode").nil? + func_def = find_ancestor(FunctionDefAst) + unless func_def.nil? + return FunctionBodyAst.new(input, interval, statements) if func_def.templated? # can't prune a template because we don't have all types + + # push template values + func_def.template_names.each_with_index do |tname, idx| + symtab.add(tname, Var.new(tname, func_def.template_types(symtab)[idx])) + end + + # push args + func_def.arguments(symtab).each do |arg_type, arg_name| + symtab.add(arg_name, Var.new(arg_name, arg_type)) + end + end + begin + # go through the statements, and stop if we find one that retuns + statements.each_with_index do |s, idx| + if s.is_a?(Returns) + v = s.return_value(symtab) + return FunctionBodyAst.new(input, interval, statements[0..idx].map { |s| s.prune(symtab) }) unless v.nil? + else + s.execute(symtab) + end + end + + FunctionBodyAst.new(input, interval, statements.map { |s| s.prune(symtab) }) + rescue ValueError + FunctionBodyAst.new(input, interval, statements.map { |s| s.prune(symtab) }) + ensure + symtab.pop + end + end + end + class StatementAst + def prune(symtab) + pruned_action = action.prune(symtab) + if pruned_action.is_a?(Declaration) + pruned_action.add_symbol(symtab) + end + if pruned_action.is_a?(Executable) + begin + pruned_action.execute(symtab) + rescue ValueError + # ok + end + end + StatementAst.new(pruned_action) + end + end + class AryElementAccessAst + def prune(symtab) + AryElementAccessAst.new(input, interval, @var.prune(symtab), @index.prune(symtab)) + end + end + class AryRangeAccessAst + def prune(symtab) + AryRangeAccessAst.new(input, interval, @var.prune(symtab), @msb.prune(symtab), @lsb.prune(symtab)) + end + end + class BinaryExpressionAst + # @!macro prune + def prune(symtab) + if op == "&&" + begin + if @lhs.value(symtab) == false + @rhs.prune(symtab) + else + BinaryExpressionAst.new(input, interval, @lhs.prune(symtab), @op, @rhs.prune(symtab)) + end + rescue ValueError + BinaryExpressionAst.new(input, interval, @lhs.prune(symtab), @op, @rhs.prune(symtab)) + end + elsif op == "||" + begin + if @lhs.value(symtab) == true + @rhs.prune(symtab) + else + BinaryExpressionAst.new(input, interval, @lhs.prune(symtab), @op, @rhs.prune(symtab)) + end + rescue ValueError + BinaryExpressionAst.new(input, interval, @lhs.prune(symtab), @op, @rhs.prune(symtab)) + end + else + BinaryExpressionAst.new(input, interval, @lhs.prune(symtab), @op, @rhs.prune(symtab)) + end + end + end + + class IfBodyAst + def prune(symtab) + pruned_stmts = [] + stmts.each do |s| + pruned_stmts << s.prune(symtab) + end + IfBodyAst.new(pruned_stmts) + end + end + + class ElseIfAst + def prune(symtab) + ElseIfAst.new(cond.prune(symtab), body.prune(symtab).stmts) + end + end + + class IfAst + # @!macro prune + def prune(symtab) + if if_cond.value(symtab) + if_body.prune(symtab) + elsif !elseifs.empty? + # we know that the if condition is false, so now we treat the else if + # as the starting point and try again + IfAst.new( + elseifs[0].cond.prune(symtab), + elseifs[0].body.prune(symtab), + elseifs[1..].map { |e| e.prune(symtab) }, + final_else_body.prune(symtab)) + elsif !final_else_body.stmts.empty? + # the if is false, and there are no else ifs, so the result of the prune is just the pruned else body + final_else_body.prune(symtab) + else + # the if is false, and there are no else ifs or elses. This is just a no-op + NoopAst.new + end + rescue ValueError + # we don't know the value of the if condition + # we still might know the value of an else if + unknown_elsifs = [] + elseifs.each do |eif| + begin + if eif.cond.value(symtab) + # this elseif is true, so turn it into an else and then we are done + return IfAst.new(if_cond.prune(symtab), if_body.prune(symtab), unknown_elsifs.map { |u| u.prune(symtab)}, eif.body.prune(symtab)) + else + # this elseif is false, so we can remove it + next + end + rescue ValueError + unknown_elsifs << eif + end + end + # we get here, then we don't know the value of anything. just return this if with everything pruned + IfAst.new(if_cond.prune(symtab), if_body.prune(symtab), elseifs.map { |eif| eif.prune(symtab)}, final_else_body.prune(symtab)) + end + end + + class ConditionalStatementAst + def prune(symtab) + if condition.value(symtab) + StatementAst.new(action.prune(symtab)) + else + NoopAst.new() + end + rescue ValueError + # condition not known + ConditionalStatementAst.new(action.prune(symtab), condition.prune(symtab)) + end + end + + # class TernaryOperatorExpressionAst + # def prune(symtab) + # begin + # rescue ValueError + # TernaryOperatorExpressionAst.new() + # end + # end + # end +end diff --git a/lib/idl/symbol_table.rb b/lib/idl/symbol_table.rb index 1f6cc03e2..f91bdddce 100644 --- a/lib/idl/symbol_table.rb +++ b/lib/idl/symbol_table.rb @@ -9,7 +9,7 @@ class Var def initialize(name, type, value = nil, decode_var: false, template_index: nil, function_name: nil) @name = name - raise 'unexpected' unless type.is_a?(Type) + raise ArgumentError, "Expecting a Type, got #{type.class.name}" unless type.is_a?(Type) @type = type @value = value diff --git a/lib/idl/tests/helpers.rb b/lib/idl/tests/helpers.rb new file mode 100644 index 000000000..5393332d1 --- /dev/null +++ b/lib/idl/tests/helpers.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Extension mock that returns an extension name +class MockExtension + attr_reader :name + def initialize(name) + @name = name + end +end + +# ArchDef mock that knows about XLEN and extensions +class MockArchDef + def config_params = { "XLEN" => 32 } + def extensions = [MockExtension.new("I")] +end + +module TestMixin + def setup + @archdef = MockArchDef.new + @symtab = Idl::SymbolTable.new(@archdef) + @compiler = Idl::Compiler.new(@archdef) + end +end \ No newline at end of file diff --git a/lib/idl/tests/test_expressions.rb b/lib/idl/tests/test_expressions.rb new file mode 100644 index 000000000..01523317d --- /dev/null +++ b/lib/idl/tests/test_expressions.rb @@ -0,0 +1,129 @@ +require "minitest/autorun" + +$root ||= (Pathname.new(__FILE__) / ".." / ".." / ".." / "..").realpath + +require_relative "../../idl" +require_relative "helpers" + +# Test IDL expressions +class TestExpressions < Minitest::Test + include TestMixin + + def test_that_operators_are_left_recusrive + idl = <<~IDL.strip + 4 - 3 - 1 + IDL + + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 0, ast.value(@symtab) + assert_equal "((4 - 3) - 1)", ast.to_idl + end + + def test_that_values_are_tuncated + idl = <<~IDL.strip + 4'hf + 4'h1 + IDL + + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 0, ast.value(@symtab) + + idl = <<~IDL.strip + 4'hf + 5'h1 + IDL + + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 16, ast.value(@symtab) + end + + def test_that_multplication_is_higher_precedence_than_addition + idl = <<~IDL.strip + 4 + 5'd3 * 2 + IDL + + ast = @compiler.compile_expression(idl, @symtab) + refute_equal 14, ast.value(@symtab) + assert_equal 10, ast.value(@symtab) + end + + def test_that_integer_literals_give_correct_values + idl = "8'd13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + idl = "16'hd" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + idl = "12'o15" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + idl = "4'b1101" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + idl = "-8'sd13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal(-13, ast.value(@symtab)) + + idl = "-16'shd" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal(-13, ast.value(@symtab)) + + idl = "-12'so15" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal(-13, ast.value(@symtab)) + + idl = "-4'sb1101" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 3, ast.value(@symtab) + + idl = "4'sb1101" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal(-3, ast.value(@symtab)) + + idl = "32'h80000000" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 0x80000000, ast.value(@symtab) + + idl = "32'h8000_0000" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 0x80000000, ast.value(@symtab) + + idl = "8'13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + # 13 decimal, unsigned XLEN-bit wide + idl = "'13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + # 13 decimal, signed XLEN-bit wide + idl = "'s13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 13, ast.value(@symtab) + + # compilation error: 300 does not fit in 8 bits + idl = "'h1_0000_0000" + assert_raises(Idl::AstNode::TypeError) { @compiler.compile_expression(idl, @symtab, pass_error: true) } + + # 3 decimal: the literal is 13, unsigned, in 4-bits. when negated, the sign bit is lost + idl = "-4'd13" + ast = @compiler.compile_expression(idl, @symtab) + assert_equal 3, ast.value(@symtab) + + # compilation error: 300 does not fit in 8 bits + idl = "8'sd300" + assert_raises(Idl::AstNode::TypeError) { @compiler.compile_expression(idl, @symtab, pass_error: true) } + + # compilation error: bit width must be positive + idl = "0'15" + assert_raises(Idl::AstNode::TypeError) { @compiler.compile_expression(idl, @symtab, pass_error: true) } + + # compilation error: value does not fit in four bita + idl = "4'hff" + assert_raises(Idl::AstNode::TypeError) { @compiler.compile_expression(idl, @symtab, pass_error: true) } + end + +end diff --git a/lib/idl/tests/test_variables.rb b/lib/idl/tests/test_variables.rb new file mode 100644 index 000000000..61ad9117f --- /dev/null +++ b/lib/idl/tests/test_variables.rb @@ -0,0 +1,22 @@ +require "minitest/autorun" + +$root ||= (Pathname.new(__FILE__) / ".." / ".." / ".." / "..").realpath + +require_relative "../../idl" +require_relative "helpers" + +# test IDL variables +class TestVariables < Minitest::Test + include TestMixin + + def test_that_constants_are_read_only + idl = <<~IDL.strip + XReg MyConstant = 15; + MyContant = 0; + IDL + + assert_raises(Idl::AstNode::TypeError) do + @compiler.compile_func_body(idl, symtab: @symtab, no_rescue: true) + end + end +end diff --git a/lib/idl/type.rb b/lib/idl/type.rb index 136d65fa2..87d7dce7f 100644 --- a/lib/idl/type.rb +++ b/lib/idl/type.rb @@ -27,6 +27,17 @@ def integral? @kind == :bits end + def default + case @kind + when :bits, :enum_ref, :bitfield + 0 + when :boolean + false + else + raise "No default for #{@kind}" + end + end + attr_reader :kind, :qualifiers, :width, :sub_type, :tuple_types, :return_type, :arguments, :enum_class def qualify(qualifier) @@ -366,9 +377,9 @@ def clone def value(element_name) i = @element_names.index(element_name) - raise "Could not find #{element_name} in enumeration #{@name}" if i.nil? + return nil if i.nil? - return @element_values[i] + @element_values[i] end end @@ -453,7 +464,7 @@ def type_check_call(template_values = []) def template_names = @func_def_ast.template_names - def template_types = @func_def_ast.template_types + def template_types(symtab) = @func_def_ast.template_types(symtab) def templated? = @func_def_ast.templated? @@ -472,7 +483,7 @@ def apply_template_values(template_values = []) template_values.each_with_index do |value, idx| raise "template value should be an Integer" unless value.is_a?(Integer) - symtab.add!(template_names[idx], Var.new(template_names[idx], template_types[idx], value, template_index: idx, function_name: @func_def_ast.name)) + symtab.add!(template_names[idx], Var.new(template_names[idx], template_types(symtab)[idx], value, template_index: idx, function_name: @func_def_ast.name)) end symtab end @@ -540,17 +551,17 @@ def argument_name(index, template_values = []) def body = @func_def_ast.body end - # a function that is templated, and hasn't been fully typed checked yet - # because it needs to have template arguments resolved - class TemplateFunctionType < Type - attr_reader :template_types, :ast - - def initialize(func_name, template_types, ast) - super(:template_function, name: func_name, arguments: arguments) - @template_types = template_types - @ast = ast - end - end + # # a function that is templated, and hasn't been fully typed checked yet + # # because it needs to have template arguments resolved + # class TemplateFunctionType < Type + # attr_reader :template_types, :ast + + # def initialize(func_name, template_types, ast) + # super(:template_function, name: func_name, arguments: arguments) + # @template_types = template_types + # @ast = ast + # end + # end # XReg is really a Bits<> type, so we override it just to get # prettier prints diff --git a/lib/opcodes.rb b/lib/opcodes.rb index 6490c1dee..29938e715 100644 --- a/lib/opcodes.rb +++ b/lib/opcodes.rb @@ -55,9 +55,16 @@ class DecodeVariable # For example, if the field is offset[5:3], left_shift is 3 attr_reader :left_shift - def extract_location(location_string) - parts = location_string.split("|") + def extract_location(location) @encoding_fields = [] + + if location.is_a?(Integer) + @encoding_fields << EncodingField.new("", location..location) + return + end + + location_string = location + parts = location_string.split("|") parts.each do |part| if part =~ /^([0-9]+)$/ bit = ::Regexp.last_match(1) diff --git a/schemas/config_schema.json b/schemas/config_schema.json index 4460c9fc5..9374a40dd 100644 --- a/schemas/config_schema.json +++ b/schemas/config_schema.json @@ -14,8 +14,18 @@ "IMP_ID", "MISALIGNED_LDST", "NUM_HPM_COUNTERS", + "REPORT_VA_IN_MTVAL_ON_BREAKPOINT", + "REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED", + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED", + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED", + "REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT", + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT", + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT", + "REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT", + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT", + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT", + "REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION", "TRAP_ON_ILLEGAL_WLRL", - "REPORT_EBREAK_PC_IN_TVAL", "CONFIG_PTR_ADDRESS", "PHYS_ADDR_WIDTH", "CACHE_BLOCK_SIZE" @@ -152,10 +162,202 @@ "default": true, "description": "When true, writing an illegal value to a WLRL CSR field raises an Illegal Instruction exception.\nWhen false, writing an illegal value to a WLRL CSR field is ignored." }, - "REPORT_EBREAK_PC_IN_TVAL": { + + "REPORT_VA_IN_MTVAL_ON_BREAKPOINT": { "type": "boolean", - "description": "When true, *tval is written with the virtual PC of the EBREAK instruction (same information as *epc).\nWhen false, *tval is written with 0 on an EBREAK instruction\n\nregardless, *tval is always written with a virtual PC when an external breakpoint is generated." + "default": false, + "description": "When true, mtval is written with the virtual PC of the EBREAK instruction (same information as mepc).\nWhen false, mtval is written with 0 on an EBREAK instruction\n\nregardless, mtval is always written with a virtual PC when an external breakpoint is generated." + }, + "REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a misaligned load causes a LoadAddressMisaligned exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a load causes a LoadAccessFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_LOAD_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a load causes a LoadPageFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_STORE_AMO_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_VA_IN_MTVAL_ON_INSTRUCTION_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, mtval is written with 0" + }, + "REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the faulting instruciton encoding when a IllegalInstruction exception occurs.\nWhen false, mtval is written with 0" + }, + "REPORT_CAUSE_IN_MTVAL_ON_SOFTWARE_CHECK": { + "type": "boolean", + "default": false, + "description": "When true, mtval is written with the casue when a SoftwareCheck exception occurs.\nWhen false, mtval is written with 0" + }, + "MTVAL_WIDTH": { + "type": "integer", + "maximum": 64, + "description": "Number of implemented bits in MTVAL. Must be >= largest virtual address size if a VA is ever written to mtval by hardware or if Sdext is implemented. Must also be able to hold the minimum of MXLEN or ILEN if encodings are reported on IllegalInstruction exceptions" + }, + + "REPORT_VA_IN_STVAL_ON_BREAKPOINT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual PC of the EBREAK instruction (same information as mepc).\nWhen false, stval is written with 0 on an EBREAK instruction\n\nregardless, stval is always written with a virtual PC when an external breakpoint is generated." + }, + "REPORT_VA_IN_STVAL_ON_LOAD_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a misaligned load causes a LoadAddressMisaligned exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_STORE_AMO_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_INSTRUCTION_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_LOAD_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a load causes a LoadAccessFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_STORE_AMO_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_INSTRUCTION_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_LOAD_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a load causes a LoadPageFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_STORE_AMO_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_VA_IN_STVAL_ON_INSTRUCTION_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, stval is written with 0" + }, + "REPORT_ENCODING_IN_STVAL_ON_ILLEGAL_INSTRUCTION": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the faulting instruciton encoding when a IllegalInstruction exception occurs.\nWhen false, stval is written with 0" + }, + "REPORT_CAUSE_IN_STVAL_ON_SOFTWARE_CHECK": { + "type": "boolean", + "default": false, + "description": "When true, stval is written with the casue when a SoftwareCheck exception occurs.\nWhen false, stval is written with 0" + }, + "STVAL_WIDTH": { + "type": "integer", + "maximum": 64, + "description": "Number of implemented bits in STVAL. Must be >= largest virtual address size if a VA is ever written to stval by hardware or if Sdext is implemented. Must also be able to hold the minimum of SXLEN or ILEN if encodings are reported on IllegalInstruction exceptions" + }, + + "REPORT_VA_IN_VSTVAL_ON_BREAKPOINT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual PC of the EBREAK instruction (same information as mepc).\nWhen false, vstval is written with 0 on an EBREAK instruction\n\nregardless, vstval is always written with a virtual PC when an external breakpoint is generated." + }, + "REPORT_VA_IN_VSTVAL_ON_LOAD_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a misaligned load causes a LoadAddressMisaligned exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_STORE_AMO_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_MISALIGNED": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a misaligned store or atomic causes a StoreAmoAddressMisaligned exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_LOAD_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a load causes a LoadAccessFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_STORE_AMO_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_ACCESS_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a store or atomic causes a StoreAmoAccessFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_LOAD_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a load causes a LoadPageFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_STORE_AMO_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_VA_IN_VSTVAL_ON_INSTRUCTION_PAGE_FAULT": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the virtual address when a store or atomic causes a StoreAmoPageFault exception.\nWhen false, vstval is written with 0" + }, + "REPORT_ENCODING_IN_VSTVAL_ON_ILLEGAL_INSTRUCTION": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the faulting instruciton encoding when a IllegalInstruction exception occurs.\nWhen false, vstval is written with 0" + }, + "REPORT_CAUSE_IN_VSTVAL_ON_SOFTWARE_CHECK": { + "type": "boolean", + "default": false, + "description": "When true, vstval is written with the casue when a SoftwareCheck exception occurs.\nWhen false, vstval is written with 0" }, + + + "CONFIG_PTR_ADDRESS": { "type": "integer", "minimum": 0, diff --git a/schemas/ext_schema.json b/schemas/ext_schema.json index 7f2d1c0c9..53a0dc680 100644 --- a/schemas/ext_schema.json +++ b/schemas/ext_schema.json @@ -7,17 +7,83 @@ "required": ["description", "versions"], "properties": { "name": { "$ref": "schema_defs.json#/$defs/extension_name" }, - "description": { "type": "string" }, + "long_name": { + "type": "string", + "description": "One line description for the extension" + }, + "description": { + "type": "string", + "description": "Full documentation of the extension" + }, + "company": { + "description": "The company that developed this extension", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the company that developed this extension. Should be \"RISC-V International\" for standard extensions" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Website of the company that developed this extension. Should be \"https://riscv.org\" for standard extensions" + } + } + }, + "doc_license": { + "description": "License that applies to the textual documantation for this extension", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "License name" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Link to license text" + } + }, + "additionalProperties": false + }, "type": { "enum": ["unprivileged", "privileged"] }, "versions": { "type": "array", "items": { "type": "object", - "required": ["version", "ratification_date"], + "required": ["version", "state"], "properties": { "version": { "$ref": "schema_defs.json#/$defs/extension_version" }, + "state": { + "description": "Current state of this version", + "enum": [ + "development", + "frozen", + "public-review", + "ratified", + "nonstandard-released" + ] + }, + "repositories": { + "description": "Repositories associated with this extension", + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri" + }, + "branch": { + "type": "string", + "description": "Branch/tag where the work is done" + } + }, + "additionalProperties": false + } + }, "ratification_date": { "oneOf": [ {"type": "string", "pattern": "^20[0-9][0-9]-[0-9][0-9]$", "$comment": "When ratification date is known" }, @@ -40,6 +106,28 @@ { "$ref": "schema_defs.json#/$defs/extension_requirement" }, { "type": "array", "items": { "$ref": "schema_defs.json#/$defs/extension_requirement" }} ] + }, + "contributors": { + "description": "List of contributors to this version of the extension", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Contributor name, in 'GIVEN_NAME SURNAME' format" + }, + "company": { + "type": "string", + "description": "Company the contributor worked for, or 'Individual'" + }, + "email": { + "type": "string", + "format": "email", + "description": "E-mail address for the contributor" + } + } + } } }, "additionalProperties": false diff --git a/schemas/inst_schema.json b/schemas/inst_schema.json index 8e8ec4c57..8673cc64c 100644 --- a/schemas/inst_schema.json +++ b/schemas/inst_schema.json @@ -2,15 +2,19 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$defs": { - "extension": { - "type": "string", - "pattern": "^[A-W,Y]|([XZ][a-z]+)$", - "description": "RISC-V Extension" - }, "field_location": { "description": "Location specifier for a field", - "type": "string", - "pattern": "^(([0-9]+)|([0-9]+-[0-9]+))(\\|(([0-9]+)|([0-9]+-[0-9]+)))*$" + "oneOf": [ + { + "type": "string", + "pattern": "^(([0-9]+)|([0-9]+-[0-9]+))(\\|(([0-9]+)|([0-9]+-[0-9]+)))*$" + }, + { + "type": "integer", + "minimum": 0, + "maximum": 31 + } + ] }, "field": { "description": "Decode field", @@ -42,7 +46,7 @@ "encoding": { "type": "object", "properties": { - "mask": { + "match": { "oneOf": [ { "type": "string", @@ -56,7 +60,7 @@ } ] }, - "not_mask": { + "not_match": { "description": "Bit values that cannot match for the instruction. Used to exclude encodings where all but one value are valid (e.g., common with the C encodings)", "oneOf": [ { @@ -71,7 +75,7 @@ } ] }, - "fields": { + "variables": { "type": "array", "items": { "$ref": "#/$defs/field" @@ -102,12 +106,12 @@ "definedBy": { "oneOf": [ { - "$ref": "#/$defs/extension" + "$ref": "schema_defs.json#/$defs/extension_requirement" }, { "type": "array", "items": { - "$ref": "#/$defs/extension" + "$ref": "schema_defs.json#/$defs/extension_requirement" } } ], @@ -116,12 +120,12 @@ "excludedBy": { "oneOf": [ { - "$ref": "#/$defs/extension" + "$ref": "schema_defs.json#/$defs/extension_requirement" }, { "type": "array", "items": { - "$ref": "#/$defs/extension" + "$ref": "schema_defs.json#/$defs/extension_requirement" } } ], @@ -189,6 +193,21 @@ "assembly": { "type": "string", "description": "Assembly format of the instruction. Can use decode variables" + }, + "pseudoinstructions": { + "description": "Variations of this instruction that form a pseudoinstruction", + "type": "object", + "properties": { + "when": { + "type": "string", + "description": "Condition when the instruction has an alias" + }, + "to": { + "type": "string", + "description": "pseduoinstruction format" + } + }, + "additionalProperties": false } } } diff --git a/schemas/schema_defs.json b/schemas/schema_defs.json index dec4d76de..27a5e2106 100644 --- a/schemas/schema_defs.json +++ b/schemas/schema_defs.json @@ -19,14 +19,21 @@ } ] }, - "extension_version_requirement": { + "requirement_string": { + "type": "string", + "pattern": "^((>=)|(>)|(~>)|(<)|(<=)|(=))?\\s*[0-9]+(\\.[0-9]+(\\.[0-9]+(-[a-fA-F0-9]+)?)?)?$" + }, + "version_requirements": { + "description": "A (set of) version requirments", "oneOf": [ { - "type": "number" + "$ref": "#/$defs/requirement_string" }, { - "type": "string", - "pattern": "^((>=)|(>)|(~>)|(<)|(<=)|(==))?\\s*[0-9]+(\\.[0-9]+(\\.[0-9]+(-[a-fA-F0-9]+)?)?)?$" + "type": "array", + "items": { + "$ref": "#/$defs/requirement_string" + } } ] }, @@ -43,16 +50,25 @@ "additionalItems": false }, "extension_requirement": { - "type": "array", - "items": [ + "description": "A requirement on an extension. Can either specify just an extension name, in which case version '>= 0' is implied, or both a name and a requirement", + "oneOf": [ { "$ref": "#/$defs/extension_name" }, { - "$ref": "#/$defs/extension_version_requirement" + "type": "array", + "items": [ + { + "$ref": "#/$defs/extension_name" + }, + { + "$ref": "#/$defs/version_requirements" + } + ], + "additionalItems": false } - ], - "additionalItems": false + ] + } } } \ No newline at end of file diff --git a/tasks/adoc_gen.rake b/tasks/adoc_gen.rake index 4ad6a52f2..0a4ae25d1 100644 --- a/tasks/adoc_gen.rake +++ b/tasks/adoc_gen.rake @@ -9,6 +9,7 @@ require_relative "../lib/arch_def" "#{$root}/.stamps/arch-gen-#{config_name}.stamp", ($root / "views" / "adoc" / "#{type}.adoc.erb").to_s, "lib/arch_def.rb", + "lib/idl/passes/gen_adoc.rb", "tasks/adoc_gen.rake", "#{$root}/.stamps" ] @@ -43,6 +44,7 @@ require_relative "../lib/arch_def" end when "func" isa_def = arch_def.global_ast + global_symtab = arch_def.sym_table path = dir_path / "funcs.adoc" File.write(path, erb.result(binding)) else diff --git a/tasks/ext_pdf_gen.rake b/tasks/ext_pdf_gen.rake new file mode 100644 index 000000000..7210aa26f --- /dev/null +++ b/tasks/ext_pdf_gen.rake @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require "pathname" + +require "asciidoctor-pdf" +require "asciidoctor-diagram" + +require_relative "../lib/idl/passes/gen_adoc" + +# Utilities for generating an Antora site out of an architecture def +module AsciidocUtils + class << self + def resolve_links(path_or_str) + str = + if path_or_str.is_a?(Pathname) + path_or_str.read + else + path_or_str + end + str.gsub(/%%LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do + type = Regexp.last_match[1] + name = Regexp.last_match[2] + link_text = Regexp.last_match[3] + + case type + when "inst" + "xref:insns-#{name.gsub(',', '_')}[#{link_text.gsub(']', '\]')}]" + when "csr" + # "xref:csrs:#{name}.adoc##{name}-def[#{link_text.gsub(']', '\]')}]" + link_text + when "csr_field" + csr_name, field_name = name.split('.') + # "xref:csrs:#{csr_name}.adoc##{csr_name}-#{field_name}-def[#{link_text.gsub(']', '\]')}]" + link_text + when "ext" + # "xref:exts:#{name}.adoc##{name}-def[#{link_text.gsub(']', '\]')}]" + link_text + when "func" + # "xref:funcs:funcs.adoc##{name}-func-def[#{link_text.gsub(']', '\]')}]" + link_text + else + raise "Unhandled link type '#{type}' for '#{name}' #{match.captures}" + end + end + end + end +end + +rule %r{#{$root}/gen/.*/pdf/.*_extension\.pdf} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from($root / "gen").to_s.split("/")[0] + ext_name = Pathname.new(tname).basename(".pdf").to_s.split("_")[0..-2].join("_") + [ + "#{$root}/gen/#{config_name}/adoc/#{ext_name}_extension.adoc" + ] +} do |t| + config_name = Pathname.new(t.name).relative_path_from($root / "gen").to_s.split("/")[0] + ext_name = Pathname.new(t.name).basename(".pdf").to_s.split("_")[0..-2].join("_") + adoc_file = "#{$root}/gen/#{config_name}/adoc/#{ext_name}_extension.adoc" + + FileUtils.mkdir_p File.dirname(t.name) + File.write t.name, Asciidoctor.convert_file(adoc_file, backend: "pdf", safe: :safe) +end + +rule %r{#{$root}/gen/.*/adoc/.*_extension\.adoc} => proc { |tname| + config_name = Pathname.new(tname).relative_path_from($root / "gen").to_s.split("/")[0] + [ + "#{$root}/.stamps/arch-gen-#{config_name}.stamp", + ($root / "views" / "adoc" / "ext_pdf.adoc.erb").to_s, + __FILE__ + ] +} do |t| + config_name = Pathname.new(t.name).relative_path_from("#{$root}/gen").to_s.split("/")[0] + ext_name = Pathname.new(t.name).basename(".pdf").to_s.split("_")[0..-2].join("_") + + template_path = $root / "views" / "adoc" / "ext_pdf.adoc.erb" + erb = ERB.new(template_path.read, trim_mode: "-") + erb.filename = template_path.to_s + + arch_def = ArchDef.new(config_name) + ext = arch_def.extension(ext_name) + FileUtils.mkdir_p File.dirname(t.name) + File.write t.name, AsciidocUtils.resolve_links(erb.result(binding)) +end + +namespace :gen do + desc <<~DESC + Generate PDF documentation for :extension using configuration :config_name + DESC + task :ext_pdf, [:extension, :config_name] do |_t, args| + config = args[:config_name] + extension = args[:extension] + + Rake::Task[$root / "gen" / config.to_s / "pdf" / "#{extension}_extension.pdf"].invoke + end +end diff --git a/tasks/html_gen.rake b/tasks/html_gen.rake index 1a6414f4b..e12d1413c 100644 --- a/tasks/html_gen.rake +++ b/tasks/html_gen.rake @@ -10,22 +10,23 @@ module AntoraUtils else path_or_str end - str.gsub(/%%LINK\[([^;\]%]+)\s*;\s*([^;\]%]+)\s*;\s*([^\]%]+)\]%%/) do + str.gsub(/%%LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do type = Regexp.last_match[1] name = Regexp.last_match[2] link_text = Regexp.last_match[3] - case type when "inst" - "xref:insts:#{name}.adoc##{name}-def[#{link_text}]" + "xref:insts:#{name}.adoc##{name}-def[#{link_text.gsub(']', '\]')}]" when "csr" - "xref:csrs:#{name}.adoc##{name}-def[#{link_text}]" + "xref:csrs:#{name}.adoc##{name}-def[#{link_text.gsub(']', '\]')}]" when "csr_field" - csr_name, field_name = name.split(".") - "xref:csrs:#{csr_name}.adoc##{csr_name}-#{field_name}-def[#{link_text}]" + csr_name, field_name = name.split('.') + "xref:csrs:#{csr_name}.adoc##{csr_name}-#{field_name}-def[#{link_text.gsub(']', '\]')}]" when "ext" - "xref:exts:#{name}.adoc##{name}-def[#{link_text}]" + "xref:exts:#{name}.adoc##{name}-def[#{link_text.gsub(']', '\]')}]" + when "func" + "xref:funcs:funcs.adoc##{name}-func-def[#{link_text.gsub(']', '\]')}]" else raise "Unhandled link type '#{type}' for '#{name}' #{match.captures}" end @@ -39,7 +40,6 @@ end config_name = Pathname.new(tname).relative_path_from("#{$root}/gen").to_s.split("/")[0] [ "#{$root}/\.stamps/adoc-gen-#{type}s-#{config_name}\.stamp", - # "#{$root}/gen/#{config_name}/adoc/#{type}s/#{rest}", __FILE__ ] } do |t| diff --git a/tasks/top.rake b/tasks/top.rake index 4327eeae1..f206f8f3c 100644 --- a/tasks/top.rake +++ b/tasks/top.rake @@ -4,6 +4,7 @@ $root = Pathname.new(__FILE__).dirname.dirname.realpath $lib = $root / "lib" require "yard" +require "minitest/test_task" require_relative $root / "lib" / "validate" @@ -12,6 +13,7 @@ directory "#{$root}/.stamps" load "#{$root}/tasks/arch_gen.rake" load "#{$root}/tasks/adoc_gen.rake" load "#{$root}/tasks/html_gen.rake" +load "#{$root}/tasks/ext_pdf_gen.rake" namespace :gen do task :html @@ -61,3 +63,7 @@ namespace :serve do sh "yard server -p #{args[:port]} --reload" end end + +Minitest::TestTask.create :idl_test do |t| + t.test_globs = ["#{$root}/lib/idl/tests/test_*.rb"] +end diff --git a/views/adoc/csr.adoc.erb b/views/adoc/csr.adoc.erb index 7896b7219..b6a17f509 100644 --- a/views/adoc/csr.adoc.erb +++ b/views/adoc/csr.adoc.erb @@ -73,7 +73,7 @@ a| <%= arch_def.find_replace_links(field.description) %> This CSR may store a value that is different from what software attempts to write. -When a software write occurs (_e.g._, through %%LINK[inst;cssrw;csrrw]%%), the following determines the +When a software write occurs (_e.g._, through %%LINK%inst;cssrw;csrrw%%), the following determines the written value: [idl] diff --git a/views/adoc/ext.adoc.erb b/views/adoc/ext.adoc.erb index 69f329bd4..52a59d839 100644 --- a/views/adoc/ext.adoc.erb +++ b/views/adoc/ext.adoc.erb @@ -6,16 +6,16 @@ This extension not implemented by the <%= ext.arch_def.name %> configuration. <%- end -%> -<%- if ext.respond_to?(:implies) && !ext.implies.empty? -%> +<%- if !ext.implies.empty? -%> This extension implies the following extension(s): -`<%= ext.name %>` => <%= ext.implies.map { |e| arch_def.find_replace_links "`#{e}`" }.join(", ") %> +`<%= ext.name %>` => <%= ext.implies.map { |e| arch_def.find_replace_links "`#{e.name}`, version #{e.version}" }.join(", ") %> <%- end -%> == Versions <%- ext.versions.each do |v| -%> -<%- implemented = ext.arch_def.implemented_extensions.include?(ExtensionVersion.new(ext.name, v["version"], ext.arch_def)) -%> +<%- implemented = arch_def.implemented_extensions.include?(ExtensionVersion.new(ext.name, v["version"])) -%> <%= v["version"] %>:: Ratification date::: <%= v["ratification_date"] %> diff --git a/views/adoc/ext_pdf.adoc.erb b/views/adoc/ext_pdf.adoc.erb new file mode 100644 index 000000000..7a4686773 --- /dev/null +++ b/views/adoc/ext_pdf.adoc.erb @@ -0,0 +1,193 @@ += <%= ext.long_name %> + +:description: <%= ext.long_name %> +:company: <%= ext.company %> +:url-riscv: https://riscv.org +:doctype: book +:preface-title: Licensing and Acknowledgements +:colophon: +:appendix-caption: Appendix +:title-logo-image: image:RISC-V-logo.svg[pdfwidth=3.25in,align=center] +:back-cover-image: image:circuit.png[opacity=25%] +// Settings +:experimental: +:reproducible: +:wavedrom: <%= $root %>/node_modules/.bin/wavedrom-cli +// needs to be changed +:imagesoutdir: images +:icons: font +:lang: en +:listing-caption: Listing +:sectnums: +:toc: left +:toclevels: 4 +:source-highlighter: pygments +ifdef::backend-pdf[] +:source-highlighter: coderay +endif::[] +:data-uri: +:hide-uri-scheme: +:stem: +:footnote: +:xrefstyle: short + + + +<<< +[colophon] +== Colophon + +This document is released under the <%= ext.doc_license["url"] %>[<%= ext.doc_license["name"] %>]. + +<<< +[acknowledgements] +== Acknowledgements + +<%- ext.versions.each do |version| -%> +Contributors to version <%= version["version"] %> of the specification (in alphabetical order) include: + + +<%- version["contributors"].sort { |a, b| a["name"].split(" ").last <=> b["name"].split(" ").last }.each do |c| -%> + * <%= c["name"] %> <<%= c["email"] %>> (<%= c["company"] %>) +<%- end -%> +<%- end -%> + +We express our gratitude to everyone that contributed to, reviewed or +improved this specification through their comments and questions. + +<<< +== Versions + +The following versions have been defined: + +<%- ext.versions.each do |version| -%> +-- +Version:: <%= version["version"] %> +State:: <%= version["state"] %> +<%- if version.key?("ratification_date") -%> +Ratification Date:: <%= version["ratification_date"] %> +<%- end -%> +<%- if version.key?("url") -%> +Design document:: <%= version["url"] %> +<%- end -%> +<%- if version.key?("change") -%> +Changes:: +<%= version["changes"] %> +<%- end -%> +-- +<%- end -%> + +<<< +== Extension description + +<%= ext.description %> + +<%- unless ext.implies.nil? -%> +<%- ext.implies.each do |e| -%> +<%- end -%> +<%- end -%> + +<<< +== Instruction summary + +The following instructions are added by this extension: + +[%autowidth] +|=== +| RV32 | RV64 | Mnemonic | Instruction | <%= ext.versions.map { |v| "v#{v["version"]}" }.join(" | ") %> + +<%- ext.instructions.each do |i| -%> +| <%= i.rv32? ? "X" : "" %> +| <%= i.rv64? ? "X" : "" %> +| `<%= i.name %> <%= i.assembly.gsub("x", "r") %>` +| xref:insns-<%= i.name.gsub('.', '_') %>[<%= i.long_name %>] +| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "X" : "" }.join(" | ") %> +<%- end -%> +|=== + +<<< +[#insns,reftext="Instructions (in alphabetical order)"] +== Instructions (in alphabetical order) + +<%- ext.instructions.each do |i| -%> +[#insns-<%= i.name.gsub('.', '_') %>,reftext=<%= i.long_name %>] +=== <%= i.name %> + +Synopsis:: +<%= i.long_name %> + +Mnemoic:: +---- +<%= i.name %><%= i.assembly.gsub('x', 'r') %> +---- + +Encoding:: +<%- if arch_def.multi_xlen? && i.multi_encoding? -%> +[NOTE] +This instruction has different encodings in RV32 and RV64 + +RV32:: +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump i.wavedrom_desc(32) %> +.... + +RV64:: +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump i.wavedrom_desc(64) %> +.... +<%- else -%> +[wavedrom, ,svg,subs='attributes',width="100%"] +.... +<%= JSON.dump i.wavedrom_desc(arch_def.config_params["XLEN"]) %> +.... +<%- end -%> + +Description:: +<%= i.description %> + +Decode Variables:: + +<%- if i.arch_def.multi_xlen? && i.multi_encoding? -%> +RV32:: ++ +---- +<%- i.decode_variables(32).each do |d| -%> +<%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>; +<%- end -%> +---- + +RV64:: ++ +---- +<%- i.decode_variables(64).each do |d| -%> +<%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>; +<%- end -%> +---- +<%- else -%> +---- +<%- i.decode_variables(i.arch_def.config_params["XLEN"]).each do |d| -%> +<%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>; +<%- end -%> +---- +<%- end -%> + +Operation:: +[souce,idl] +---- +<%= i.operation_ast.gen_adoc %> +---- + +Included in:: +[%header,cols="4,2,2"] +|=== +|Extension +|Minimum version +|Lifecycle state + +|Zba (<<#zba>>) +|0.93 +|Frozen +|=== +<<< +<%- end -%> \ No newline at end of file diff --git a/views/adoc/func.adoc.erb b/views/adoc/func.adoc.erb index 3b2cd0ae0..d36676563 100644 --- a/views/adoc/func.adoc.erb +++ b/views/adoc/func.adoc.erb @@ -1,3 +1,5 @@ +:tabs-sync-option: + // defintions and helper functions for ISA definitions = Functions @@ -13,11 +15,24 @@ h| Return Type l| <%= f.return_type_list_str.join(', ') %> h| Arguments l| <%= f.arguments_list_str.join (', ') %> |=== -<%- if f.respond_to?(:body_block) -%> +<%- unless f.builtin? -%> +<%- body_ast = f.body_block.function_body -%> +[tabs] +==== +Original:: ++ +[subs="specialchars,macros"] +---- +<%= body_ast.gen_adoc.gsub('(', 'pass:[(]') %> +---- + +Pruned:: ++ [subs="specialchars,macros"] ---- -<%= f.unindent(f.body_block.function_body.gen_adoc.gsub('(', 'pass:[(]')) %> +<%= body_ast.prune(global_symtab.deep_clone).gen_adoc.gsub('(', 'pass:[(]') %> ---- +==== <%- end -%> <%- end -%> \ No newline at end of file diff --git a/views/adoc/inst.adoc.erb b/views/adoc/inst.adoc.erb index 8d97afc7d..62b7001d6 100644 --- a/views/adoc/inst.adoc.erb +++ b/views/adoc/inst.adoc.erb @@ -7,7 +7,7 @@ == Encoding -<%- if inst.arch_def.multi_xlen? && inst.multi_encoding? -%> +<%- if arch_def.multi_xlen? && inst.multi_encoding? -%> [NOTE] This instruction has different encodings in RV32 and RV64. @@ -30,7 +30,7 @@ RV64:: <%- else -%> [wavedrom, ,svg,subs='attributes',width="100%"] .... -<%= JSON.dump inst.wavedrom_desc(inst.arch_def.config_params["XLEN"]) %> +<%= JSON.dump inst.wavedrom_desc(arch_def.config_params["XLEN"]) %> .... <%- end -%> @@ -62,7 +62,7 @@ RV64:: == Decode Variables -<%- if inst.arch_def.multi_xlen? && inst.multi_encoding? -%> +<%- if arch_def.multi_xlen? && inst.multi_encoding? -%> [tabs] ==== RV32:: @@ -83,7 +83,7 @@ RV64:: ==== <%- else -%> ---- -<%- inst.decode_variables(inst.arch_def.config_params["XLEN"]).each do |d| -%> +<%- inst.decode_variables(arch_def.config_params["XLEN"]).each do |d| -%> <%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>; <%- end -%> ---- @@ -91,7 +91,23 @@ RV64:: == Execution +<%- if inst.operation_ast(arch_def.idl_compiler).nil? -%> + +<%- else -%> +[tabs] +==== +Pruned:: ++ [subs="specialchars,macros"] ---- -<%= inst.operation_source %> +<%= inst.pruned_operation_ast(arch_def.sym_table).gen_adoc %> ---- + +Original:: ++ +[subs="specialchars,macros"] +---- +<%= inst.operation_ast(arch_def.idl_compiler).gen_adoc %> +---- +==== +<%- end -%> \ No newline at end of file diff --git a/views/adoc/toc.adoc.erb b/views/adoc/toc.adoc.erb index dd14331f4..0282723d5 100644 --- a/views/adoc/toc.adoc.erb +++ b/views/adoc/toc.adoc.erb @@ -2,17 +2,17 @@ .Extensions <%- arch_def.implemented_extensions.sort { |a, b| a.name <=> b.name }.each do |ext| -%> -* %%LINK[ext;<%= ext.name %>;<%= ext.name %>]%% +* %%LINK%ext;<%= ext.name %>;<%= ext.name %>%% <%- end -%> .Control and Status Registers <%- arch_def.implemented_csrs.sort { |a, b| a.name <=> b.name }.each do |csr| -%> -* %%LINK[csr;<%= csr.name %>;<%= csr.name %>]%% +* %%LINK%csr;<%= csr.name %>;<%= csr.name %>%% <%- end -%> .Instructions <%- arch_def.implemented_instructions.sort { |a, b| a.name <=> b.name }.each do |inst| -%> -* %%LINK[inst;<%= inst.name %>;<%= inst.name %>]%% +* %%LINK%inst;<%= inst.name %>;<%= inst.name %>%% <%- end -%> .IDL functions