Check if an instruction is valid with respect to given features.
Certain instructions are only valid in RV32I/RV32E or RV64I/RV64E.
In RV32E/RV64E, register indices are only 4 bits.
Certain instructions are only valid with the M extension.
Function:
(defun instr-validp (instr feat) (declare (xargs :guard (and (instrp instr) (featp feat)))) (let ((__function__ 'instr-validp)) (declare (ignorable __function__)) (b* (((feat feat) feat)) (instr-case instr :op-imm (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1))) :op-imms32 (and (feat-32p feat) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1)))) :op-imms64 (and (feat-64p feat) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1)))) :op-imm-32 (and (feat-64p feat) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1)))) :op-imms-32 (and (feat-64p feat) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1)))) :lui (implies (feat-embedp feat) (ubyte4p instr.rd)) :auipc (implies (feat-embedp feat) (ubyte4p instr.rd)) :op (and (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1) (ubyte4p instr.rs2))) (implies (member-eq (op-funct-kind instr.funct) '(:mul :mulh :mulhu :mulhsu :div :divu :rem :remu)) (feat-mp feat))) :op-32 (and (feat-64p feat) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1) (ubyte4p instr.rs2))) (implies (member-eq (op-32-funct-kind instr.funct) '(:mulw :divw :divuw :remw :remuw)) (feat-mp feat))) :jal (implies (feat-embedp feat) (ubyte4p instr.rd)) :jalr (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1))) :branch (implies (feat-embedp feat) (and (ubyte4p instr.rs1) (ubyte4p instr.rs2))) :load (and (load-funct-case instr.funct :lb t :lbu t :lh t :lhu t :lw t :lwu (feat-64p feat) :ld (feat-64p feat)) (implies (feat-embedp feat) (and (ubyte4p instr.rd) (ubyte4p instr.rs1)))) :store (and (store-funct-case instr.funct :sb t :sh t :sw t :sd (feat-64p feat)) (implies (feat-embedp feat) (and (ubyte4p instr.rs1) (ubyte4p instr.rs2))))))))
Theorem:
(defthm booleanp-of-instr-validp (b* ((yes/no (instr-validp instr feat))) (booleanp yes/no)) :rule-classes :rewrite)
Theorem:
(defthm instr-validp-of-instr-fix-instr (equal (instr-validp (instr-fix instr) feat) (instr-validp instr feat)))
Theorem:
(defthm instr-validp-instr-equiv-congruence-on-instr (implies (instr-equiv instr instr-equiv) (equal (instr-validp instr feat) (instr-validp instr-equiv feat))) :rule-classes :congruence)
Theorem:
(defthm instr-validp-of-feat-fix-feat (equal (instr-validp instr (feat-fix feat)) (instr-validp instr feat)))
Theorem:
(defthm instr-validp-feat-equiv-congruence-on-feat (implies (feat-equiv feat feat-equiv) (equal (instr-validp instr feat) (instr-validp instr feat-equiv))) :rule-classes :congruence)