Preprocesses an operandinfo, changing an outer bitselect or partselect
into a
(vl-operandinfo-to-svex-preproc x indices) → (mv err new-x new-indices)
This is just a code-simplifying step so that we don't have to deal with so many separate cases later.
Note: This function's correctness depends on the ordering in which indices are listed by vl-operandinfo->indices, so keep these two functions in sync.
The result is an operandinfo with the following characteristics:
Function:
(defun vl-operandinfo-to-svex-preproc (x indices) (declare (xargs :guard (and (vl-operandinfo-p x) (sv::svexlist-p indices)))) (declare (xargs :guard (and (vl-operandinfo-usertypes-ok x) (equal (len indices) (vl-operandinfo-index-count x))))) (let ((__function__ 'vl-operandinfo-to-svex-preproc)) (declare (ignorable __function__)) (b* ((indices (sv::svexlist-fix indices)) ((vl-operandinfo x) (vl-operandinfo-fix x))) (vl-partselect-case x.part :none (b* (((when (atom x.seltrace)) (mv nil x indices)) ((vl-selstep sel1) (car x.seltrace)) ((unless (vl-select-case sel1.select :index)) (mv nil x indices)) (type (vl-seltrace-type (cdr x.seltrace) x.hidtype)) ((unless (vl-datatype-index-is-bitselect type)) (mv nil x indices)) ((vl-select-index idx) sel1.select) ((cons bitselect-index rest-indices) indices)) (mv nil (change-vl-operandinfo x :seltrace (cdr x.seltrace) :part (vl-plusminus->partselect (make-vl-plusminus :width (vl-make-index 1) :base idx.val))) (list* (sv::svex-fix bitselect-index) (svex-int 1) rest-indices))) :range (b* (((list* ?msb-index ?lsb-index rest-indices) indices) ((unless (and (vl-expr-resolved-p x.part.msb) (vl-expr-resolved-p x.part.lsb))) (mv (vmsg "Unresolved partselect range") x indices)) (msb (vl-resolved->val x.part.msb)) (lsb (vl-resolved->val x.part.lsb)) (minusp (< msb lsb)) (width (+ 1 (abs (- msb lsb)))) (new-part (vl-plusminus->partselect (make-vl-plusminus :base x.part.lsb :width (vl-make-index width) :minusp minusp)))) (mv nil (change-vl-operandinfo x :part new-part) (list* (svex-int lsb) (svex-int width) rest-indices))) :plusminus (b* (((unless (b* ((width (cadr indices))) (sv::svex-case width :quote (and (sv::2vec-p width.val) (natp (sv::2vec->val width.val))) :otherwise nil))) (mv (vmsg "Unresolved plusminus select width") x indices))) (mv nil x indices))))))
Theorem:
(defthm return-type-of-vl-operandinfo-to-svex-preproc.err (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (iff (vl-msg-p err) err)) :rule-classes :rewrite)
Theorem:
(defthm vl-operandinfo-p-of-vl-operandinfo-to-svex-preproc.new-x (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (vl-operandinfo-p new-x)) :rule-classes :rewrite)
Theorem:
(defthm svexlist-p-of-vl-operandinfo-to-svex-preproc.new-indices (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (sv::svexlist-p new-indices)) :rule-classes :rewrite)
Theorem:
(defthm vl-operandinfo-usertypes-ok-of-vl-operandinfo-to-svex-preproc (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (implies (vl-operandinfo-usertypes-ok x) (vl-operandinfo-usertypes-ok new-x))))
Theorem:
(defthm len-indices-of-vl-operandinfo-to-svex-preproc (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (implies (equal (len indices) (vl-operandinfo-index-count x)) (equal (len new-indices) (vl-operandinfo-index-count new-x)))))
Theorem:
(defthm partselect-kind-of-vl-operandinfo-to-svex-preproc (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (implies (not err) (or (equal (vl-partselect-kind (vl-operandinfo->part new-x)) :none) (equal (vl-partselect-kind (vl-operandinfo->part new-x)) :plusminus)))) :rule-classes ((:forward-chaining :trigger-terms ((vl-partselect-kind (vl-operandinfo->part (mv-nth 1 (vl-operandinfo-to-svex-preproc x indices))))))))
Theorem:
(defthm vars-of-vl-operandinfo-to-svex-preproc (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (implies (not (member v (sv::svexlist-vars indices))) (not (member v (sv::svexlist-vars new-indices))))))
Theorem:
(defthm constant-width-of-vl-operandinfo-to-svex-preproc-width (b* (((mv ?err ?new-x ?new-indices) (vl-operandinfo-to-svex-preproc x indices))) (implies (and (not err) (not (equal (vl-partselect-kind (vl-operandinfo->part new-x)) :none))) (b* ((sv::width (cadr new-indices))) (and (equal (sv::svex-kind sv::width) :quote) (equal (sv::4vec->lower (sv::svex-quote->val sv::width)) (sv::4vec->upper (sv::svex-quote->val sv::width))) (natp (sv::4vec->upper (sv::svex-quote->val sv::width))))))))
Theorem:
(defthm vl-operandinfo-to-svex-preproc-of-vl-operandinfo-fix-x (equal (vl-operandinfo-to-svex-preproc (vl-operandinfo-fix x) indices) (vl-operandinfo-to-svex-preproc x indices)))
Theorem:
(defthm vl-operandinfo-to-svex-preproc-vl-operandinfo-equiv-congruence-on-x (implies (vl-operandinfo-equiv x x-equiv) (equal (vl-operandinfo-to-svex-preproc x indices) (vl-operandinfo-to-svex-preproc x-equiv indices))) :rule-classes :congruence)
Theorem:
(defthm vl-operandinfo-to-svex-preproc-of-svexlist-fix-indices (equal (vl-operandinfo-to-svex-preproc x (sv::svexlist-fix indices)) (vl-operandinfo-to-svex-preproc x indices)))
Theorem:
(defthm vl-operandinfo-to-svex-preproc-svexlist-equiv-congruence-on-indices (implies (sv::svexlist-equiv indices indices-equiv) (equal (vl-operandinfo-to-svex-preproc x indices) (vl-operandinfo-to-svex-preproc x indices-equiv))) :rule-classes :congruence)