udb 0.1.9 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.data/cfgs/example_rv64_with_overlay.yaml +5 -2
- data/.data/cfgs/mc100-32-full-example.yaml +1 -0
- data/.data/cfgs/profile/README.adoc +10 -0
- data/.data/cfgs/profile/RVA20S64.yaml +26 -6
- data/.data/cfgs/profile/RVA20U64.yaml +18 -4
- data/.data/cfgs/profile/RVA22S64.yaml +27 -7
- data/.data/cfgs/profile/RVA22U64.yaml +18 -4
- data/.data/cfgs/profile/RVA23S64.yaml +61 -7
- data/.data/cfgs/profile/RVA23U64.yaml +36 -4
- data/.data/cfgs/profile/RVB23S64.yaml +27 -7
- data/.data/cfgs/profile/RVB23U64.yaml +18 -4
- data/.data/cfgs/profile/RVI20U32.yaml +10 -4
- data/.data/cfgs/profile/RVI20U64.yaml +10 -4
- data/.data/cfgs/qc_iu.yaml +4 -1
- data/.data/cfgs/rv32-riscv-tests.yaml +2 -1
- data/.data/cfgs/rv32-vector.yaml +2 -1
- data/.data/cfgs/rv64-riscv-tests.yaml +2 -1
- data/.data/cfgs/rv64-vector.yaml +2 -1
- data/.data/spec/custom/isa/qc_iu/csr/Smrnmi/mnepc.yaml +17 -0
- data/.data/spec/custom/isa/qc_iu/csr/Xqccmi/qc.itba.yaml +45 -0
- data/.data/spec/custom/isa/qc_iu/csr/Xqccmi/qc.itdec.yaml +39 -0
- data/.data/spec/custom/isa/qc_iu/csr/jvt.yaml +11 -0
- data/.data/spec/custom/isa/qc_iu/csr/mepc.yaml +16 -0
- data/.data/spec/custom/isa/qc_iu/ext/Xqccmi.yaml +219 -0
- data/.data/spec/custom/isa/qc_iu/ext/Xqccmt.yaml +127 -0
- data/.data/spec/custom/isa/qc_iu/inst/Xqccmi/qc.cm.ilut.yaml +153 -0
- data/.data/spec/custom/isa/qc_iu/inst/Xqccmt/qc.cm.jalt.yaml +84 -0
- data/.data/spec/custom/isa/qc_iu/inst/Xqccmt/qc.cm.jt.yaml +60 -0
- data/.data/spec/custom/isa/qc_iu/isa/globals.isa +112 -0
- data/.data/spec/schemas/config_schema.json +219 -26
- data/.data/spec/schemas/csr_schema.json +0 -6
- data/.data/spec/schemas/ext_schema.json +80 -24
- data/.data/spec/schemas/inst_schema.json +0 -3
- data/.data/spec/schemas/profile_release_schema.json +1 -1
- data/.data/spec/schemas/profile_schema.json +0 -3
- data/.data/spec/schemas/register_file_schema.json +8 -3
- data/.data/spec/schemas/schema_defs.json +8 -27
- data/.data/spec/std/isa/csr/I/pmpcfg0.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg1.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg10.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg11.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg12.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg13.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg14.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg15.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg2.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg3.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg4.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg5.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg6.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg7.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfg8.yaml +8 -8
- data/.data/spec/std/isa/csr/I/pmpcfg9.yaml +4 -4
- data/.data/spec/std/isa/csr/I/pmpcfgN.layout +1 -1
- data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.layout +6 -2
- data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.yaml +6 -2
- data/.data/spec/std/isa/csr/hstatus.yaml +16 -0
- data/.data/spec/std/isa/csr/mcycleh.yaml +1 -1
- data/.data/spec/std/isa/csr/misa.yaml +0 -12
- data/.data/spec/std/isa/csr/mstatus.yaml +38 -0
- data/.data/spec/std/isa/csr/mstatush.yaml +17 -15
- data/.data/spec/std/isa/csr/senvcfg.yaml +16 -0
- data/.data/spec/std/isa/csr/sstatus.yaml +12 -0
- data/.data/spec/std/isa/csr/vsstatus.yaml +24 -0
- data/.data/spec/std/isa/ext/A.yaml +5 -7
- data/.data/spec/std/isa/ext/S.yaml +12 -0
- data/.data/spec/std/isa/ext/Smpmpmt.yaml +52 -0
- data/.data/spec/std/isa/ext/Sv32.yaml +7 -19
- data/.data/spec/std/isa/ext/Sv39.yaml +7 -19
- data/.data/spec/std/isa/ext/Sv48.yaml +4 -20
- data/.data/spec/std/isa/ext/Sv57.yaml +4 -20
- data/.data/spec/std/isa/ext/Svukte.yaml +71 -0
- data/.data/spec/std/isa/ext/Zawrs.yaml +1 -1
- data/.data/spec/std/isa/ext/Zihpm.yaml +0 -12
- data/.data/spec/std/isa/inst/C/c.addi.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.addi16sp.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.addiw.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.andi.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.ldsp.yaml +1 -1
- data/.data/spec/std/isa/inst/C/c.li.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.lui.yaml +1 -0
- data/.data/spec/std/isa/inst/C/c.mv.yaml +1 -1
- data/.data/spec/std/isa/inst/C/c.sdsp.yaml +1 -1
- data/.data/spec/std/isa/inst/D/fsgnj.d.yaml +3 -0
- data/.data/spec/std/isa/inst/D/fsgnjn.d.yaml +3 -0
- data/.data/spec/std/isa/inst/D/fsgnjx.d.yaml +3 -0
- data/.data/spec/std/isa/inst/F/fadd.s.yaml +5 -5
- data/.data/spec/std/isa/inst/F/fclass.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fcvt.l.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.lu.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.s.l.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.s.lu.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.s.w.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.s.wu.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.w.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fcvt.wu.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fdiv.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/feq.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fle.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fleq.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/flt.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fltq.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/flw.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fmadd.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fmax.s.yaml +6 -6
- data/.data/spec/std/isa/inst/F/fmin.s.yaml +6 -6
- data/.data/spec/std/isa/inst/F/fmsub.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fmul.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fmv.w.x.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fmv.x.w.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fnmadd.s.yaml +2 -2
- data/.data/spec/std/isa/inst/F/fnmsub.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fsgnj.s.yaml +4 -4
- data/.data/spec/std/isa/inst/F/fsgnjn.s.yaml +3 -3
- data/.data/spec/std/isa/inst/F/fsgnjx.s.yaml +4 -4
- data/.data/spec/std/isa/inst/F/fsqrt.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fsub.s.yaml +1 -1
- data/.data/spec/std/isa/inst/F/fsw.yaml +1 -1
- data/.data/spec/std/isa/inst/I/addi.yaml +1 -1
- data/.data/spec/std/isa/inst/I/addiw.yaml +1 -1
- data/.data/spec/std/isa/inst/I/andi.yaml +1 -1
- data/.data/spec/std/isa/inst/I/beq.yaml +1 -1
- data/.data/spec/std/isa/inst/I/bge.yaml +4 -2
- data/.data/spec/std/isa/inst/I/bgeu.yaml +3 -0
- data/.data/spec/std/isa/inst/I/blt.yaml +4 -2
- data/.data/spec/std/isa/inst/I/bltu.yaml +3 -0
- data/.data/spec/std/isa/inst/I/bne.yaml +1 -1
- data/.data/spec/std/isa/inst/I/slt.yaml +2 -2
- data/.data/spec/std/isa/inst/I/sltiu.yaml +1 -1
- data/.data/spec/std/isa/inst/I/sltu.yaml +1 -1
- data/.data/spec/std/isa/inst/I/sub.yaml +1 -1
- data/.data/spec/std/isa/inst/I/subw.yaml +1 -1
- data/.data/spec/std/isa/inst/I/xori.yaml +1 -1
- data/.data/spec/std/isa/inst/M/mul.yaml +0 -19
- data/.data/spec/std/isa/inst/Q/fsgnj.q.yaml +1 -1
- data/.data/spec/std/isa/inst/S/sret.yaml +3 -1
- data/.data/spec/std/isa/inst/V/vadd.vv.yaml +1 -5
- data/.data/spec/std/isa/inst/V/vfsgnjn.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vfsgnjx.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vl1re8.v.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vl2re8.v.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vl4re8.v.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vl8re8.v.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vle8.v.yaml +3 -8
- data/.data/spec/std/isa/inst/V/vmand.mm.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmfle.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmflt.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmnand.mm.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsgt.vi.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsgtu.vi.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsle.vi.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsle.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsleu.vi.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsleu.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmslt.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmsltu.vv.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmv.v.i.yaml +2 -13
- data/.data/spec/std/isa/inst/V/vmv.x.s.yaml +1 -1
- data/.data/spec/std/isa/inst/V/vmxnor.mm.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vmxor.mm.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vnsrl.wx.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vrsub.vx.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vse8.v.yaml +3 -4
- data/.data/spec/std/isa/inst/V/vwadd.vx.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vwaddu.vx.yaml +3 -0
- data/.data/spec/std/isa/inst/V/vxor.vi.yaml +4 -0
- data/.data/spec/std/isa/inst/Zalasr/lSIZE.AQRL.layout +40 -5
- data/.data/spec/std/isa/inst/Zalasr/lb.aq.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/lb.aqrl.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/ld.aq.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/ld.aqrl.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/lh.aq.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/lh.aqrl.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/lw.aq.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/lw.aqrl.yaml +17 -1
- data/.data/spec/std/isa/inst/Zalasr/sSIZE.AQRL.layout +46 -5
- data/.data/spec/std/isa/inst/Zalasr/sb.aqrl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sb.rl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sd.aqrl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sd.rl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sh.aqrl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sh.rl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sw.aqrl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zalasr/sw.rl.yaml +16 -1
- data/.data/spec/std/isa/inst/Zbkb/packw.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcd/c.fld.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcd/c.fldsp.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcd/c.fsdsp.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcf/c.flwsp.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcf/c.fswsp.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcmp/cm.pop.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcmp/cm.popret.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcmp/cm.popretz.yaml +1 -1
- data/.data/spec/std/isa/inst/Zcmp/cm.push.yaml +2 -3
- data/.data/spec/std/isa/inst/Zfa/fround.s.yaml +1 -1
- data/.data/spec/std/isa/inst/Zfh/fcvt.h.s.yaml +6 -6
- data/.data/spec/std/isa/inst/Zfh/fcvt.s.h.yaml +5 -5
- data/.data/spec/std/isa/inst/Zfh/flh.yaml +1 -1
- data/.data/spec/std/isa/inst/Zfh/fmv.h.x.yaml +1 -1
- data/.data/spec/std/isa/inst/Zfh/fmv.x.h.yaml +1 -1
- data/.data/spec/std/isa/inst/Zfh/fsh.yaml +1 -1
- data/.data/spec/std/isa/inst/Zicsr/csrrc.yaml +1 -1
- data/.data/spec/std/isa/inst/Zicsr/csrrci.yaml +1 -1
- data/.data/spec/std/isa/inst/Zicsr/csrrs.yaml +2 -2
- data/.data/spec/std/isa/inst/Zicsr/csrrsi.yaml +1 -1
- data/.data/spec/std/isa/inst/Zicsr/csrrw.yaml +1 -1
- data/.data/spec/std/isa/inst/Zicsr/csrrwi.yaml +1 -1
- data/.data/spec/std/isa/isa/builtin_functions.idl +17 -0
- data/.data/spec/std/isa/isa/fp.idl +1 -5
- data/.data/spec/std/isa/isa/globals.isa +45 -14
- data/.data/spec/std/isa/isa/vec.idl +1 -2
- data/.data/spec/std/isa/manual_version/isa/20240411/isa_20240411.yaml +5 -5
- data/.data/spec/std/isa/param/COUNTINHIBIT_EN.yaml +8 -2
- data/.data/spec/std/isa/param/JVT_BASE_MASK.yaml +1 -1
- data/.data/spec/std/isa/param/MCOUNTINHIBIT_IMPLEMENTED.yaml +25 -0
- data/.data/spec/std/isa/param/MTVEC_MODES.yaml +10 -3
- data/.data/spec/std/isa/param/VLEN.yaml +2 -0
- data/.data/spec/std/isa/profile/RVA20S64.yaml +11 -4
- data/.data/spec/std/isa/profile/RVA20U64.yaml +14 -5
- data/.data/spec/std/isa/profile/RVA22S64.yaml +14 -3
- data/.data/spec/std/isa/profile/RVA22U64.yaml +8 -1
- data/.data/spec/std/isa/profile/RVA23S64.yaml +13 -0
- data/.data/spec/std/isa/profile/RVA23U64.yaml +15 -1
- data/.data/spec/std/isa/profile/RVB23S64.yaml +15 -3
- data/.data/spec/std/isa/profile/RVB23U64.yaml +8 -1
- data/.data/spec/std/isa/profile/RVI20U32.yaml +8 -1
- data/.data/spec/std/isa/profile/RVI20U64.yaml +7 -0
- data/.data/spec/std/isa/register_file/F.yaml +3 -2
- data/.data/spec/std/isa/register_file/V.yaml +2 -2
- data/.data/spec/std/isa/register_file/X.yaml +2 -1
- data/lib/udb/architecture.rb +4 -25
- data/lib/udb/cfg_arch.rb +171 -59
- data/lib/udb/cli.rb +10 -1
- data/lib/udb/condition.rb +38 -37
- data/lib/udb/config.rb +72 -6
- data/lib/udb/logic.rb +29 -56
- data/lib/udb/obj/csr.rb +23 -5
- data/lib/udb/obj/csr_field.rb +36 -21
- data/lib/udb/obj/database_obj.rb +2 -5
- data/lib/udb/obj/extension.rb +0 -3
- data/lib/udb/obj/instruction.rb +1 -4
- data/lib/udb/obj/portfolio.rb +75 -20
- data/lib/udb/obj/profile.rb +0 -4
- data/lib/udb/obj/register_file.rb +63 -2
- data/lib/udb/portfolio_design.rb +3 -6
- data/lib/udb/resolver.rb +84 -23
- data/lib/udb/version.rb +1 -1
- data/lib/udb/version_spec.rb +8 -0
- data/lib/udb/z3.rb +23 -0
- data/lib/udb.rb +0 -3
- metadata +25 -37
- data/.data/cfgs/profile/RVA23M64.yaml +0 -159
- data/.data/cfgs/profile/RVB23M64.yaml +0 -149
- data/.data/spec/schemas/proc_cert_class_schema.json +0 -35
- data/.data/spec/schemas/proc_cert_model_schema.json +0 -336
- data/.data/spec/std/isa/proc_cert_class/AC.yaml +0 -13
- data/.data/spec/std/isa/proc_cert_class/MC.yaml +0 -13
- data/.data/spec/std/isa/proc_cert_class/RVI.yaml +0 -16
- data/.data/spec/std/isa/proc_cert_model/AC100.yaml +0 -72
- data/.data/spec/std/isa/proc_cert_model/AC200.yaml +0 -58
- data/.data/spec/std/isa/proc_cert_model/MC100-32.yaml +0 -155
- data/.data/spec/std/isa/proc_cert_model/MC100-64.yaml +0 -21
- data/.data/spec/std/isa/proc_cert_model/MC200-32.yaml +0 -60
- data/.data/spec/std/isa/proc_cert_model/MC200-64.yaml +0 -21
- data/.data/spec/std/isa/proc_cert_model/MC300-32.yaml +0 -40
- data/.data/spec/std/isa/proc_cert_model/MC300-64.yaml +0 -21
- data/.data/spec/std/isa/proc_cert_model/RVI20-32.yaml +0 -39
- data/.data/spec/std/isa/proc_cert_model/RVI20-64.yaml +0 -19
- data/.data/spec/std/isa/profile/RVA23M64.yaml +0 -24
- data/.data/spec/std/isa/profile/RVB23M64.yaml +0 -86
- data/lib/udb/cert_normative_rule.rb +0 -41
- data/lib/udb/obj/certifiable_obj.rb +0 -21
- data/lib/udb/obj/certificate.rb +0 -230
- data/lib/udb/proc_cert_design.rb +0 -77
data/lib/udb/cfg_arch.rb
CHANGED
|
@@ -204,7 +204,19 @@ module Udb
|
|
|
204
204
|
begin
|
|
205
205
|
@symtab = create_symtab
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
# Guard against re-entrant solver calls from within add_global_symbols.
|
|
208
|
+
# Global initializers (e.g. FLEN) may call implemented?(), which triggers
|
|
209
|
+
# prohibited_ext?() and the Z3 solver chain. If those calls see @symtab is
|
|
210
|
+
# already set (partial), they'd use an incomplete symtab and fail.
|
|
211
|
+
# A depth counter (rather than a boolean) is used so that if this block
|
|
212
|
+
# ever nests (e.g. create_symtab is called recursively in the future),
|
|
213
|
+
# the inner ensure does not prematurely clear the guard for the outer block.
|
|
214
|
+
@constructing_symtab_depth = (@constructing_symtab_depth || 0) + 1
|
|
215
|
+
begin
|
|
216
|
+
global_ast.add_global_symbols(@symtab)
|
|
217
|
+
ensure
|
|
218
|
+
@constructing_symtab_depth -= 1
|
|
219
|
+
end
|
|
208
220
|
|
|
209
221
|
@symtab.deep_freeze
|
|
210
222
|
raise if @symtab.name.nil?
|
|
@@ -213,6 +225,11 @@ module Udb
|
|
|
213
225
|
end
|
|
214
226
|
end
|
|
215
227
|
|
|
228
|
+
# @return [Boolean] true while add_global_symbols is running inside symtab construction
|
|
229
|
+
# Used by implemented? callback to avoid triggering the Z3 solver on a partial symtab.
|
|
230
|
+
sig { returns(T::Boolean) }
|
|
231
|
+
def constructing_symtab? = (@constructing_symtab_depth || 0) > 0
|
|
232
|
+
|
|
216
233
|
sig { returns(Idl::IsaAst) }
|
|
217
234
|
def global_ast
|
|
218
235
|
@global_ast ||=
|
|
@@ -277,7 +294,7 @@ module Udb
|
|
|
277
294
|
reasons << "#{h.fetch("name")} is not a known extension"
|
|
278
295
|
end
|
|
279
296
|
if extensions.any? { |e| e.name == h.fetch("name") } && !T.must(extension(h.fetch("name"))).versions.any? { |v| v.version_spec == h.fetch("version") }
|
|
280
|
-
reasons << "#{h.fetch("version")} is not a known extension"
|
|
297
|
+
reasons << "#{h.fetch("version")} is not a known version of extension #{h.fetch("name")}"
|
|
281
298
|
end
|
|
282
299
|
end
|
|
283
300
|
|
|
@@ -336,6 +353,8 @@ module Udb
|
|
|
336
353
|
reasons += missing_params.map { |p| "Parameter is required but missing: '#{p.name}'" }
|
|
337
354
|
end
|
|
338
355
|
|
|
356
|
+
validate_compatible(reasons)
|
|
357
|
+
|
|
339
358
|
if reasons.empty?
|
|
340
359
|
raise "bad validity check" unless to_condition.satisfiable?
|
|
341
360
|
ValidationResult.new(valid: true, reasons:)
|
|
@@ -466,6 +485,8 @@ module Udb
|
|
|
466
485
|
end
|
|
467
486
|
end
|
|
468
487
|
|
|
488
|
+
validate_compatible(reasons)
|
|
489
|
+
|
|
469
490
|
if reasons.empty?
|
|
470
491
|
raise "Bad validation" unless to_condition.satisfiable?
|
|
471
492
|
return ValidationResult.new(valid: true, reasons: [])
|
|
@@ -488,6 +509,11 @@ module Udb
|
|
|
488
509
|
# we can know if it is implemented, but not if it's not implemented for a partially configured
|
|
489
510
|
if ext?(ext_name)
|
|
490
511
|
true
|
|
512
|
+
elsif constructing_symtab?
|
|
513
|
+
# During symtab construction (add_global_symbols), the Z3 solver is not
|
|
514
|
+
# available because the symtab is partial. Return nil (unknown) so that
|
|
515
|
+
# value_try falls back to storing the global with nil (no compile-time value).
|
|
516
|
+
nil
|
|
491
517
|
elsif prohibited_ext?(ext_name)
|
|
492
518
|
false
|
|
493
519
|
else
|
|
@@ -504,6 +530,9 @@ module Udb
|
|
|
504
530
|
# we can know if it is implemented, but not if it's not implemented for a partially configured
|
|
505
531
|
if ext?(ext_name, [version])
|
|
506
532
|
true
|
|
533
|
+
elsif constructing_symtab?
|
|
534
|
+
# Same guard as for implemented? above.
|
|
535
|
+
nil
|
|
507
536
|
elsif prohibited_ext?(ext_name)
|
|
508
537
|
false
|
|
509
538
|
else
|
|
@@ -583,6 +612,33 @@ module Udb
|
|
|
583
612
|
end
|
|
584
613
|
pb.finish
|
|
585
614
|
|
|
615
|
+
# Build a bootstrap symtab and compute RF max widths before constructing the real
|
|
616
|
+
# symtab. The bootstrap needs add_global_symbols so that implemented?() is a known
|
|
617
|
+
# function (required for type_check to pass). Running it under @constructing_symtab=true
|
|
618
|
+
# ensures implemented?() returns nil → value_error during value evaluation, which
|
|
619
|
+
# causes TernaryOperatorExpressionAst#max_value to explore both branches.
|
|
620
|
+
bootstrap_st = Idl::SymbolTable.new(
|
|
621
|
+
mxlen:,
|
|
622
|
+
builtin_global_vars: final_param_vars,
|
|
623
|
+
builtin_enums: symtab_enums,
|
|
624
|
+
builtin_funcs: symtab_callbacks,
|
|
625
|
+
params: all_params,
|
|
626
|
+
name: "#{@name}/bootstrap",
|
|
627
|
+
register_files: []
|
|
628
|
+
)
|
|
629
|
+
rf_max_widths = begin
|
|
630
|
+
@constructing_symtab_depth = (@constructing_symtab_depth || 0) + 1
|
|
631
|
+
global_ast.add_global_symbols(bootstrap_st)
|
|
632
|
+
register_files.each_with_object({}) do |rf, h|
|
|
633
|
+
node = @idl_compiler.compile_expression(rf.register_length_expr, bootstrap_st, pass_error: true)
|
|
634
|
+
max = node.max_value(bootstrap_st)
|
|
635
|
+
raise "Cannot determine max width for register file '#{rf.name}'" if max == :unknown
|
|
636
|
+
h[rf.name] = Integer(max)
|
|
637
|
+
end
|
|
638
|
+
ensure
|
|
639
|
+
@constructing_symtab_depth -= 1
|
|
640
|
+
end
|
|
641
|
+
|
|
586
642
|
Idl::SymbolTable.new(
|
|
587
643
|
mxlen:,
|
|
588
644
|
possible_xlens_cb: proc { possible_xlens },
|
|
@@ -591,7 +647,9 @@ module Udb
|
|
|
591
647
|
builtin_enums: symtab_enums,
|
|
592
648
|
name: @name,
|
|
593
649
|
csrs:,
|
|
594
|
-
params: all_params
|
|
650
|
+
params: all_params,
|
|
651
|
+
register_files: register_files,
|
|
652
|
+
register_file_max_widths: rf_max_widths
|
|
595
653
|
)
|
|
596
654
|
end
|
|
597
655
|
private :create_symtab
|
|
@@ -665,6 +723,12 @@ module Udb
|
|
|
665
723
|
# @param name [String] The $1 name
|
|
666
724
|
# @return [$3] The $1
|
|
667
725
|
# @return [nil] if there is no $1 named +name+
|
|
726
|
+
# Class-level cache of raw YAML file contents keyed by "#{resolved_spec_path}/#{obj_type_dir}".
|
|
727
|
+
# Maps each directory to an array of [content, original_path, realpath] triples so that a
|
|
728
|
+
# second ConfiguredArchitecture sharing the same spec path skips disk I/O and file locking.
|
|
729
|
+
# Benign race: two threads both missing the cache produce identical entries.
|
|
730
|
+
@@yaml_data_cache = Concurrent::Hash.new
|
|
731
|
+
|
|
668
732
|
sig { params(fn_name: String, arch_dir: String, obj_class: T.class_of(TopLevelDatabaseObject)).void }
|
|
669
733
|
def self.generate_obj_methods(fn_name, arch_dir, obj_class)
|
|
670
734
|
|
|
@@ -675,12 +739,25 @@ module Udb
|
|
|
675
739
|
|
|
676
740
|
@objects[arch_dir] = Concurrent::Array.new
|
|
677
741
|
@object_hashes[arch_dir] = Concurrent::Hash.new
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
@
|
|
742
|
+
|
|
743
|
+
yaml_cache_key = "#{@arch_dir}/#{arch_dir}"
|
|
744
|
+
cached_files = @@yaml_data_cache[yaml_cache_key]
|
|
745
|
+
if cached_files.nil?
|
|
746
|
+
entries = []
|
|
747
|
+
Dir.glob(@arch_dir / arch_dir / "**" / "*.yaml") do |obj_path|
|
|
748
|
+
File.open(obj_path) do |f|
|
|
749
|
+
f.flock(File::LOCK_EX)
|
|
750
|
+
content = f.read
|
|
751
|
+
f.flock(File::LOCK_UN)
|
|
752
|
+
entries << [content, obj_path, Pathname.new(obj_path).realpath]
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
cached_files = @@yaml_data_cache[yaml_cache_key] = entries
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
cached_files.each do |content, obj_path, realpath|
|
|
759
|
+
obj_yaml = YAML.load(content, filename: obj_path, permitted_classes: [Date])
|
|
760
|
+
@objects[arch_dir] << obj_class.new(obj_yaml, realpath, T.cast(self, ConfiguredArchitecture))
|
|
684
761
|
@object_hashes[arch_dir][@objects[arch_dir].last.name] = @objects[arch_dir].last
|
|
685
762
|
end
|
|
686
763
|
@objects[arch_dir]
|
|
@@ -714,43 +791,28 @@ module Udb
|
|
|
714
791
|
# @param io where to write progress bars
|
|
715
792
|
# @return [void]
|
|
716
793
|
sig { params(show_progress: T::Boolean, io: IO).void }
|
|
717
|
-
def type_check(show_progress: true, io: $
|
|
794
|
+
def type_check(show_progress: true, io: $stderr)
|
|
718
795
|
io.puts "Type checking IDL code for #{@config.name}..." if show_progress
|
|
719
796
|
insts = @config.unconfigured? ? instructions : possible_instructions(show_progress:)
|
|
720
797
|
xlens = @config.unconfigured? ? [32, 64] : possible_xlens
|
|
721
798
|
|
|
722
799
|
progressbar =
|
|
723
800
|
if show_progress
|
|
724
|
-
TTY::ProgressBar.new("type checking possible instructions [:bar] :current/:total", total: insts.size, output:
|
|
801
|
+
TTY::ProgressBar.new("type checking possible instructions [:bar] :current/:total", total: insts.size, output: io)
|
|
725
802
|
end
|
|
726
803
|
|
|
727
804
|
insts.each do |inst|
|
|
728
805
|
progressbar.advance if show_progress
|
|
729
806
|
if @mxlen == 32
|
|
730
807
|
if inst.rv32?
|
|
731
|
-
|
|
732
|
-
unless op_ast.nil?
|
|
733
|
-
s = inst.fill_symtab(32, op_ast)
|
|
734
|
-
op_ast.prune(s).type_check(s, strict: true)
|
|
735
|
-
s.release
|
|
736
|
-
end
|
|
808
|
+
inst.pruned_operation_ast(32)
|
|
737
809
|
end
|
|
738
810
|
else
|
|
739
811
|
if inst.rv64?
|
|
740
|
-
|
|
741
|
-
unless op_ast.nil?
|
|
742
|
-
s = inst.fill_symtab(64, op_ast)
|
|
743
|
-
op_ast.prune(s).type_check(s, strict: true)
|
|
744
|
-
s.release
|
|
745
|
-
end
|
|
812
|
+
inst.pruned_operation_ast(64)
|
|
746
813
|
end
|
|
747
814
|
if xlens.include?(32) && inst.rv32?
|
|
748
|
-
|
|
749
|
-
unless op_ast.nil?
|
|
750
|
-
s = inst.fill_symtab(32, op_ast)
|
|
751
|
-
op_ast.prune(s).type_check(s, strict: true)
|
|
752
|
-
s.release
|
|
753
|
-
end
|
|
815
|
+
inst.pruned_operation_ast(32)
|
|
754
816
|
end
|
|
755
817
|
end
|
|
756
818
|
end
|
|
@@ -758,7 +820,7 @@ module Udb
|
|
|
758
820
|
csr_list = @config.unconfigured? ? csrs : possible_csrs
|
|
759
821
|
progressbar =
|
|
760
822
|
if show_progress
|
|
761
|
-
TTY::ProgressBar.new("type checking CSRs [:bar]", total: csr_list.size, output:
|
|
823
|
+
TTY::ProgressBar.new("type checking CSRs [:bar] :current/:total", total: csr_list.size, output: io)
|
|
762
824
|
end
|
|
763
825
|
|
|
764
826
|
csr_list.each do |csr|
|
|
@@ -769,53 +831,35 @@ module Udb
|
|
|
769
831
|
|
|
770
832
|
if csr.has_custom_sw_read?
|
|
771
833
|
if (xlens.include?(32) && csr_in_base32)
|
|
772
|
-
|
|
773
|
-
csr.sw_read_ast(s).prune(s).type_check(s, strict: true)
|
|
774
|
-
s.release
|
|
834
|
+
csr.type_checked_pruned_sw_read_ast(32)
|
|
775
835
|
end
|
|
776
836
|
if (xlens.include?(64) && csr_in_base64)
|
|
777
|
-
|
|
778
|
-
csr.sw_read_ast(s).prune(s).type_check(s, strict: true)
|
|
779
|
-
s.release
|
|
837
|
+
csr.type_checked_pruned_sw_read_ast(64)
|
|
780
838
|
end
|
|
781
839
|
end
|
|
782
840
|
csr.possible_fields.each do |field|
|
|
783
|
-
|
|
784
|
-
unless reset_ast.nil?
|
|
841
|
+
if field.reset_value_ast
|
|
785
842
|
if xlens.include?(32) && csr_in_base32 && field.defined_in_base32?
|
|
786
|
-
|
|
787
|
-
reset_ast.prune(s).type_check(s, strict: true)
|
|
788
|
-
s.release
|
|
843
|
+
field.pruned_reset_value_ast
|
|
789
844
|
end
|
|
790
845
|
if xlens.include?(64) && csr_in_base64 && field.defined_in_base64?
|
|
791
|
-
|
|
792
|
-
reset_ast.prune(s).type_check(s, strict: true)
|
|
793
|
-
s.release
|
|
846
|
+
field.pruned_reset_value_ast
|
|
794
847
|
end
|
|
795
848
|
end
|
|
796
849
|
if field.has_custom_sw_write?
|
|
797
850
|
if xlens.include?(32) && csr_in_base32 && field.defined_in_base32?
|
|
798
|
-
|
|
799
|
-
field.sw_write_ast(s).prune(s).type_check(s, strict: true)
|
|
800
|
-
s.release
|
|
851
|
+
field.pruned_sw_write_ast(32)
|
|
801
852
|
end
|
|
802
853
|
if xlens.include?(64) && csr_in_base64 && field.defined_in_base64?
|
|
803
|
-
|
|
804
|
-
field.sw_write_ast(s).prune(s).type_check(s, strict: true)
|
|
805
|
-
s.release
|
|
854
|
+
field.pruned_sw_write_ast(64)
|
|
806
855
|
end
|
|
807
856
|
end
|
|
808
|
-
|
|
809
|
-
unless type_ast.nil?
|
|
857
|
+
if field.type_ast
|
|
810
858
|
if xlens.include?(32) && csr_in_base32 && field.defined_in_base32?
|
|
811
|
-
|
|
812
|
-
type_ast.prune(s).type_check(s, strict: true)
|
|
813
|
-
s.release
|
|
859
|
+
field.pruned_type_ast(32)
|
|
814
860
|
end
|
|
815
861
|
if xlens.include?(64) && csr_in_base64 && field.defined_in_base64?
|
|
816
|
-
|
|
817
|
-
type_ast.prune(s).type_check(s, strict: true)
|
|
818
|
-
s.release
|
|
862
|
+
field.pruned_type_ast(64)
|
|
819
863
|
end
|
|
820
864
|
end
|
|
821
865
|
end
|
|
@@ -824,7 +868,7 @@ module Udb
|
|
|
824
868
|
func_list = @config.unconfigured? ? functions : reachable_functions(show_progress:)
|
|
825
869
|
progressbar =
|
|
826
870
|
if show_progress
|
|
827
|
-
TTY::ProgressBar.new("type checking functions [:bar]", total: func_list.size, output:
|
|
871
|
+
TTY::ProgressBar.new("type checking functions [:bar] :current/:total", total: func_list.size, output: io)
|
|
828
872
|
end
|
|
829
873
|
func_list.each do |func|
|
|
830
874
|
progressbar.advance if show_progress
|
|
@@ -1080,6 +1124,21 @@ module Udb
|
|
|
1080
1124
|
end
|
|
1081
1125
|
end
|
|
1082
1126
|
|
|
1127
|
+
# @return [Hash<String, Array<ExtensionVersion>>] possible_extension_versions grouped by name
|
|
1128
|
+
def possible_extension_versions_by_name
|
|
1129
|
+
@possible_extension_versions_by_name ||=
|
|
1130
|
+
possible_extension_versions.group_by(&:name)
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
# Memoized Z3 satisfiability result for a ParameterTerm against this cfg_arch.
|
|
1134
|
+
# Keyed by ParameterTerm (uses hash/eql? based on yaml_no_reason), so identical
|
|
1135
|
+
# terms across different Condition objects share the same Z3 result.
|
|
1136
|
+
#
|
|
1137
|
+
# @return [Hash<ParameterTerm, SatisfiedResult>]
|
|
1138
|
+
def param_term_satisfied_memo
|
|
1139
|
+
@param_term_satisfied_memo ||= {}
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1083
1142
|
# @overload prohibited_ext?(ext)
|
|
1084
1143
|
# Returns true if the ExtensionVersion +ext+ is prohibited
|
|
1085
1144
|
# @param ext [ExtensionVersion] An extension version
|
|
@@ -1740,5 +1799,58 @@ module Udb
|
|
|
1740
1799
|
end
|
|
1741
1800
|
end
|
|
1742
1801
|
|
|
1802
|
+
sig { params(pointer: String).returns(ConfiguredArchitecture) }
|
|
1803
|
+
def resolve_compatible_pointer(pointer)
|
|
1804
|
+
@config.info.resolver.cfg_arch_for_pointer(
|
|
1805
|
+
pointer,
|
|
1806
|
+
relative_dir: Pathname.new(@config.info.path).dirname
|
|
1807
|
+
)
|
|
1808
|
+
end
|
|
1809
|
+
private :resolve_compatible_pointer
|
|
1810
|
+
|
|
1811
|
+
sig { params(other: ConfiguredArchitecture, reasons: T::Array[String], visited: T::Set[String]).void }
|
|
1812
|
+
def check_compatible_with(other, reasons, visited)
|
|
1813
|
+
return if visited.include?(other.name)
|
|
1814
|
+
visited.add(other.name)
|
|
1815
|
+
|
|
1816
|
+
combined = to_condition & other.to_condition
|
|
1817
|
+
unless combined.satisfiable_by_cfg_arch?(self)
|
|
1818
|
+
combined.to_logic_tree(expand: true).minimal_unsat_subsets.each do |min|
|
|
1819
|
+
reasons << "Config '#{name}' is not compatible with '#{other.name}': not satisfiable: #{min.to_s(format: LogicNode::LogicSymbolFormat::C)}"
|
|
1820
|
+
end
|
|
1821
|
+
end
|
|
1822
|
+
|
|
1823
|
+
# Resolve transitive pointers relative to `other`'s directory, not self's.
|
|
1824
|
+
Array(other.config.compatible).each do |pointer|
|
|
1825
|
+
begin
|
|
1826
|
+
trans = other.send(:resolve_compatible_pointer, pointer)
|
|
1827
|
+
check_compatible_with(trans, reasons, visited)
|
|
1828
|
+
rescue => e
|
|
1829
|
+
reasons << "Cannot resolve transitive compatible pointer '#{pointer}': #{e.message}"
|
|
1830
|
+
end
|
|
1831
|
+
end
|
|
1832
|
+
end
|
|
1833
|
+
private :check_compatible_with
|
|
1834
|
+
|
|
1835
|
+
sig { params(reasons: T::Array[String]).void }
|
|
1836
|
+
def validate_compatible(reasons)
|
|
1837
|
+
return if @config.compatible.nil?
|
|
1838
|
+
|
|
1839
|
+
# Use dup per top-level pointer so sibling pointers each get a fresh visited set —
|
|
1840
|
+
# each branch independently validates against any shared transitive targets. Cycle
|
|
1841
|
+
# detection within a single chain is still enforced because visited mutates in-place
|
|
1842
|
+
# during the recursive descent.
|
|
1843
|
+
visited = T.let(Set.new([name]), T::Set[String])
|
|
1844
|
+
Array(@config.compatible).each do |pointer|
|
|
1845
|
+
begin
|
|
1846
|
+
other = resolve_compatible_pointer(pointer)
|
|
1847
|
+
check_compatible_with(other, reasons, visited.dup)
|
|
1848
|
+
rescue => e
|
|
1849
|
+
reasons << "Cannot resolve compatible pointer '#{pointer}': #{e.message}"
|
|
1850
|
+
end
|
|
1851
|
+
end
|
|
1852
|
+
end
|
|
1853
|
+
private :validate_compatible
|
|
1854
|
+
|
|
1743
1855
|
end
|
|
1744
1856
|
end
|
data/lib/udb/cli.rb
CHANGED
|
@@ -82,17 +82,21 @@ module Udb
|
|
|
82
82
|
method_option :custom, type: :string, desc: "Path to custom specification directory, if needed", default: Udb.default_custom_isa_path.to_s
|
|
83
83
|
method_option :config_dir, type: :string, desc: "Path to directory with config files", default: Udb.default_cfgs_path.to_s
|
|
84
84
|
method_option :gen, type: :string, desc: "Path to folder used for generation", default: Udb.default_gen_path.to_s
|
|
85
|
+
method_option :strict_partial, type: :boolean, desc: "Whether or not to check if a partial config is fully specified -- that is, all requirements of a mandatory extension are also listed in mandatory extensions and/or parameters", default: false
|
|
85
86
|
method_option :z3parallel, type: :boolean, desc: "Use parallel.enable for Z3", default: true
|
|
86
87
|
def cfg(name_or_path)
|
|
87
88
|
raise ArgumentError, "Spec directory does not exist: #{options[:std]}" unless File.directory?(options[:std])
|
|
88
89
|
|
|
89
90
|
Udb.global_options.parallel_z3 = options[:z3parallel]
|
|
90
91
|
|
|
92
|
+
|
|
91
93
|
cfg_file =
|
|
92
94
|
if File.file?(name_or_path)
|
|
93
95
|
Pathname.new(name_or_path)
|
|
94
96
|
elsif File.file?("#{options[:config_dir]}/#{name_or_path}.yaml")
|
|
95
97
|
Pathname.new("#{options[:config_dir]}/#{name_or_path}.yaml")
|
|
98
|
+
elsif File.file?("#{options[:config_dir]}/profile/#{name_or_path}.yaml")
|
|
99
|
+
Pathname.new("#{options[:config_dir]}/profile/#{name_or_path}.yaml")
|
|
96
100
|
else
|
|
97
101
|
raise ArgumentError, "Cannot find config: #{name_or_path}"
|
|
98
102
|
end
|
|
@@ -108,7 +112,12 @@ module Udb
|
|
|
108
112
|
say "Config is #{pastel.red.bold("invalid")}"
|
|
109
113
|
exit 1
|
|
110
114
|
end
|
|
111
|
-
result =
|
|
115
|
+
result =
|
|
116
|
+
if options[:strict_partial]
|
|
117
|
+
cfg_arch.partial_config_strictly_specified?
|
|
118
|
+
else
|
|
119
|
+
cfg_arch.valid?
|
|
120
|
+
end
|
|
112
121
|
|
|
113
122
|
if result.valid
|
|
114
123
|
say "Config #{pastel.bold(cfg_arch.name)} is #{pastel.green.bold("valid")}"
|
data/lib/udb/condition.rb
CHANGED
|
@@ -432,10 +432,6 @@ module Udb
|
|
|
432
432
|
end
|
|
433
433
|
end
|
|
434
434
|
|
|
435
|
-
class MemoizedState < T::Struct
|
|
436
|
-
prop :satisfied_by_cfg_arch, T::Hash[ConfiguredArchitecture, SatisfiedResult]
|
|
437
|
-
end
|
|
438
|
-
|
|
439
435
|
sig {
|
|
440
436
|
params(
|
|
441
437
|
yaml: T.any(T::Hash[String, T.untyped], T::Boolean),
|
|
@@ -450,7 +446,7 @@ module Udb
|
|
|
450
446
|
@cfg_arch = cfg_arch
|
|
451
447
|
@input_file = input_file
|
|
452
448
|
@input_line = input_line
|
|
453
|
-
@
|
|
449
|
+
@satisfied_by_cfg_arch_memo = T.let({}, T::Hash[ConfiguredArchitecture, SatisfiedResult])
|
|
454
450
|
end
|
|
455
451
|
|
|
456
452
|
sig { override.returns(T::Boolean) }
|
|
@@ -1103,7 +1099,7 @@ module Udb
|
|
|
1103
1099
|
|
|
1104
1100
|
sig { override.params(cfg_arch: ConfiguredArchitecture).returns(SatisfiedResult) }
|
|
1105
1101
|
def satisfied_by_cfg_arch?(cfg_arch)
|
|
1106
|
-
@
|
|
1102
|
+
@satisfied_by_cfg_arch_memo[cfg_arch] ||=
|
|
1107
1103
|
if cfg_arch.fully_configured?
|
|
1108
1104
|
implemented_ext_cb = make_cb_proc do |term|
|
|
1109
1105
|
if term.is_a?(ExtensionTerm)
|
|
@@ -1115,18 +1111,7 @@ module Udb
|
|
|
1115
1111
|
elsif term.is_a?(ParameterTerm)
|
|
1116
1112
|
if cfg_arch.param_values.key?(term.name)
|
|
1117
1113
|
result = term.eval(cfg_arch)
|
|
1118
|
-
if result == SatisfiedResult::Maybe
|
|
1119
|
-
# this might just mean we don't know the value.
|
|
1120
|
-
# however, given the parameter schema and constraints, we could know that term is
|
|
1121
|
-
# always false
|
|
1122
|
-
if (Condition.new({ "param" => term.to_h }, cfg_arch) & cfg_arch.to_condition).unsatisfiable?
|
|
1123
|
-
result = SatisfiedResult::No
|
|
1124
|
-
|
|
1125
|
-
# or always true
|
|
1126
|
-
elsif (-Condition.new({ "param" => term.to_h }, cfg_arch) & cfg_arch.to_condition).unsatisfiable?
|
|
1127
|
-
result = SatisfiedResult::Yes
|
|
1128
|
-
end
|
|
1129
|
-
end
|
|
1114
|
+
result = resolve_param_term_from_maybe(term, cfg_arch) if result == SatisfiedResult::Maybe
|
|
1130
1115
|
result
|
|
1131
1116
|
else
|
|
1132
1117
|
SatisfiedResult::No
|
|
@@ -1155,27 +1140,17 @@ module Udb
|
|
|
1155
1140
|
elsif cfg_arch.partially_configured?
|
|
1156
1141
|
cb = make_cb_proc do |term|
|
|
1157
1142
|
if term.is_a?(ExtensionTerm)
|
|
1158
|
-
|
|
1143
|
+
ext_req = term.to_ext_req(cfg_arch)
|
|
1144
|
+
if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| ext_req.satisfied_by?(cfg_ext_req) }
|
|
1159
1145
|
SatisfiedResult::Yes
|
|
1160
|
-
elsif cfg_arch.
|
|
1146
|
+
elsif (cfg_arch.possible_extension_versions_by_name[term.name] || []).any? { |cfg_ext_ver| ext_req.satisfied_by?(cfg_ext_ver) }
|
|
1161
1147
|
SatisfiedResult::Maybe
|
|
1162
1148
|
else
|
|
1163
1149
|
SatisfiedResult::No
|
|
1164
1150
|
end
|
|
1165
1151
|
elsif term.is_a?(ParameterTerm)
|
|
1166
1152
|
result = term.eval(cfg_arch)
|
|
1167
|
-
if result == SatisfiedResult::Maybe
|
|
1168
|
-
# this might just mean we don't know the value.
|
|
1169
|
-
# however, given the parameter schema and constraints, we could know that term is
|
|
1170
|
-
# always false
|
|
1171
|
-
if (Condition.new({ "param" => term.to_h }, cfg_arch) & cfg_arch.to_condition).unsatisfiable?
|
|
1172
|
-
result = SatisfiedResult::No
|
|
1173
|
-
|
|
1174
|
-
# or always true
|
|
1175
|
-
elsif (-Condition.new({ "param" => term.to_h }, cfg_arch) & cfg_arch.to_condition).unsatisfiable?
|
|
1176
|
-
result = SatisfiedResult::Yes
|
|
1177
|
-
end
|
|
1178
|
-
end
|
|
1153
|
+
result = resolve_param_term_from_maybe(term, cfg_arch) if result == SatisfiedResult::Maybe
|
|
1179
1154
|
result
|
|
1180
1155
|
elsif term.is_a?(FreeTerm)
|
|
1181
1156
|
raise "unreachable"
|
|
@@ -1232,7 +1207,8 @@ module Udb
|
|
|
1232
1207
|
if node.type == LogicNodeType::Term
|
|
1233
1208
|
term = node.children.fetch(0)
|
|
1234
1209
|
if term.is_a?(ExtensionTerm)
|
|
1235
|
-
|
|
1210
|
+
term_ext_req = term.to_ext_req(@cfg_arch)
|
|
1211
|
+
if ext_reqs.any? { |ext_req| term_ext_req.satisfied_by?(ext_req) }
|
|
1236
1212
|
next LogicNode::True
|
|
1237
1213
|
end
|
|
1238
1214
|
end
|
|
@@ -1277,9 +1253,10 @@ module Udb
|
|
|
1277
1253
|
SatisfiedResult::Yes
|
|
1278
1254
|
end
|
|
1279
1255
|
elsif cfg_arch.partially_configured?
|
|
1280
|
-
|
|
1256
|
+
ext_req = term.to_ext_req(cfg_arch)
|
|
1257
|
+
if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| ext_req.satisfied_by?(cfg_ext_req) }
|
|
1281
1258
|
SatisfiedResult::Yes
|
|
1282
|
-
elsif cfg_arch.
|
|
1259
|
+
elsif (cfg_arch.possible_extension_versions_by_name[term.name] || []).any? { |cfg_ext_ver| ext_req.satisfied_by?(cfg_ext_ver) }
|
|
1283
1260
|
SatisfiedResult::Maybe
|
|
1284
1261
|
else
|
|
1285
1262
|
SatisfiedResult::No
|
|
@@ -1329,9 +1306,10 @@ module Udb
|
|
|
1329
1306
|
SatisfiedResult::Yes
|
|
1330
1307
|
end
|
|
1331
1308
|
elsif cfg_arch.partially_configured?
|
|
1332
|
-
|
|
1309
|
+
ext_req = term.to_ext_req(cfg_arch)
|
|
1310
|
+
if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| ext_req.satisfied_by?(cfg_ext_req) }
|
|
1333
1311
|
SatisfiedResult::Yes
|
|
1334
|
-
elsif cfg_arch.
|
|
1312
|
+
elsif (cfg_arch.possible_extension_versions_by_name[term.name] || []).any? { |cfg_ext_ver| ext_req.satisfied_by?(cfg_ext_ver) }
|
|
1335
1313
|
SatisfiedResult::Maybe
|
|
1336
1314
|
else
|
|
1337
1315
|
SatisfiedResult::No
|
|
@@ -1645,6 +1623,27 @@ module Udb
|
|
|
1645
1623
|
def -@
|
|
1646
1624
|
Condition.not(self, @cfg_arch)
|
|
1647
1625
|
end
|
|
1626
|
+
|
|
1627
|
+
private
|
|
1628
|
+
|
|
1629
|
+
# When term.eval returns Maybe, check whether the parameter schema and constraints
|
|
1630
|
+
# imply the term is always false or always true, and cache the result per (term, cfg_arch).
|
|
1631
|
+
sig { params(term: ParameterTerm, cfg_arch: ConfiguredArchitecture).returns(SatisfiedResult) }
|
|
1632
|
+
def resolve_param_term_from_maybe(term, cfg_arch)
|
|
1633
|
+
memo = cfg_arch.param_term_satisfied_memo
|
|
1634
|
+
unless memo.key?(term)
|
|
1635
|
+
param_cond = Condition.new({ "param" => term.to_h }, cfg_arch)
|
|
1636
|
+
memo[term] =
|
|
1637
|
+
if param_cond.unsatisfiable_by_cfg_arch?(cfg_arch)
|
|
1638
|
+
SatisfiedResult::No
|
|
1639
|
+
elsif (-param_cond).unsatisfiable_by_cfg_arch?(cfg_arch)
|
|
1640
|
+
SatisfiedResult::Yes
|
|
1641
|
+
else
|
|
1642
|
+
SatisfiedResult::Maybe
|
|
1643
|
+
end
|
|
1644
|
+
end
|
|
1645
|
+
memo[term]
|
|
1646
|
+
end
|
|
1648
1647
|
end
|
|
1649
1648
|
|
|
1650
1649
|
class LogicCondition < Condition
|
|
@@ -1654,6 +1653,7 @@ module Udb
|
|
|
1654
1653
|
@logic_node = logic_node
|
|
1655
1654
|
@cfg_arch = cfg_arch
|
|
1656
1655
|
@yaml = logic_node.to_h
|
|
1656
|
+
@satisfied_by_cfg_arch_memo = T.let({}, T::Hash[ConfiguredArchitecture, SatisfiedResult])
|
|
1657
1657
|
end
|
|
1658
1658
|
|
|
1659
1659
|
sig { override.returns(T::Boolean) }
|
|
@@ -2040,6 +2040,7 @@ module Udb
|
|
|
2040
2040
|
sig { params(xlen: Integer).void }
|
|
2041
2041
|
def initialize(xlen)
|
|
2042
2042
|
@xlen = xlen
|
|
2043
|
+
@satisfied_by_cfg_arch_memo = T.let({}, T::Hash[ConfiguredArchitecture, SatisfiedResult])
|
|
2043
2044
|
end
|
|
2044
2045
|
|
|
2045
2046
|
sig { override.returns(LogicNode) }
|