Read a signed 32-bit value from memory via an effective address.
(rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 &key (mem-ptr? 'nil)) → (mv flg value x86-new)
The effective address
Prior to the effective address translation, we check whether read access is allowed. The only case in which it is not allowed is when a read access is attempted on an execute-only code segment, in 32-bit mode. In 64-bit mode, the R bit of the code segment descriptor is ignored (see Atmel manual, Dec'17, Volume 2, Section 4.8.1).
Function:
(defun rime32$inline (proc-mode eff-addr seg-reg r-x check-alignment? x86 mem-ptr?) (declare (xargs :stobjs (x86))) (declare (type (integer 0 4) proc-mode) (type (signed-byte 64) eff-addr) (type (integer 0 5) seg-reg) (type (member :r :x) r-x)) (declare (xargs :guard (and (booleanp check-alignment?) (booleanp mem-ptr?)))) (b* (((when (and (/= proc-mode 0) (= seg-reg 1) (eq r-x :r) (b* ((attr (loghead 16 (seg-hidden-attri seg-reg x86))) (r (code-segment-descriptor-attributesbits->r attr))) (= r 0)))) (mv (list :execute-only-code-segment eff-addr) 0 x86)) ((mv flg lin-addr) (ea-to-la proc-mode eff-addr seg-reg 4 x86)) ((when flg) (mv flg 0 x86)) ((unless (or (not check-alignment?) (address-aligned-p lin-addr 4 mem-ptr?))) (mv (list :unaligned-linear-address lin-addr) 0 x86))) (riml32 lin-addr r-x x86)))
Theorem:
(defthm return-type-of-rime32.value (implies (x86p x86) (b* (((mv ?flg acl2::?value ?x86-new) (rime32$inline proc-mode eff-addr seg-reg r-x check-alignment? x86 mem-ptr?))) (signed-byte-p 32 value))) :rule-classes :rewrite)
Theorem:
(defthm x86p-of-rime32.x86-new (implies (x86p x86) (b* (((mv ?flg acl2::?value ?x86-new) (rime32$inline proc-mode eff-addr seg-reg r-x check-alignment? x86 mem-ptr?))) (x86p x86-new))) :rule-classes :rewrite)
Theorem:
(defthm i32p-of-mv-nth-1-rime32 (signed-byte-p 32 (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) :rule-classes (:rewrite (:type-prescription :corollary (integerp (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) :hints (("Goal" :in-theory '(signed-byte-p integer-range-p)))) (:linear :corollary (and (<= -2147483648 (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (< (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)) 2147483648)) :hints (("Goal" :in-theory '(signed-byte-p integer-range-p (:e expt)))))))
Theorem:
(defthm rime32-value-when-error (implies (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)) (equal (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)) 0)))
Theorem:
(defthm rime32-does-not-affect-state-in-app-view (implies (app-view x86) (equal (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)) x86)))
Theorem:
(defthm xr-rime32-state-app-view (implies (app-view x86) (equal (xr fld index (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (xr fld index x86))))
Theorem:
(defthm xr-rime32-state-sys-view (implies (and (not (app-view x86)) (not (equal fld :mem)) (not (equal fld :fault)) (not (equal fld :tlb)) (member-equal fld *x86-field-names-as-keywords*)) (equal (xr fld index (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (xr fld index x86))))
Theorem:
(defthm rime32-xw-app-view (implies (and (app-view x86) (not (equal fld :mem)) (not (equal fld :app-view)) (not (equal fld :seg-hidden-base)) (not (equal fld :seg-hidden-limit)) (not (equal fld :seg-hidden-attr)) (not (equal fld :seg-visible)) (not (equal fld :msr))) (and (equal (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86) :mem-ptr? mem-ptr?)) (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (equal (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86) :mem-ptr? mem-ptr?)) (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))))))
Theorem:
(defthm rime32-xw-sys-view (implies (and (not (app-view x86)) (not (equal fld :fault)) (not (equal fld :seg-visible)) (not (equal fld :seg-hidden-base)) (not (equal fld :seg-hidden-limit)) (not (equal fld :seg-hidden-attr)) (not (equal fld :mem)) (not (equal fld :ctr)) (not (equal fld :msr)) (not (equal fld :rflags)) (not (equal fld :app-view)) (not (equal fld :tlb)) (not (equal fld :marking-view)) (not (equal fld :implicit-supervisor-access)) (member-equal fld *x86-field-names-as-keywords*)) (and (equal (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86) :mem-ptr? mem-ptr?)) (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (equal (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86) :mem-ptr? mem-ptr?)) (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (equal (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86) :mem-ptr? mem-ptr?)) (xw fld index value (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)))))))
Theorem:
(defthm rime32-xw-sys-view-rflags-not-ac (implies (and (not (app-view x86)) (equal (rflagsbits->ac value) (rflagsbits->ac (rflags x86)))) (and (equal (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86) :mem-ptr? mem-ptr?)) (mv-nth 0 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (equal (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86) :mem-ptr? mem-ptr?)) (mv-nth 1 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?))) (equal (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86) :mem-ptr? mem-ptr?)) (xw :rflags nil value (mv-nth 2 (rime32 proc-mode eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?)))))))
Theorem:
(defthm rime32-when-64-bit-modep-and-not-fs/gs (implies (and (not (equal seg-reg 4)) (not (equal seg-reg 5)) (canonical-address-p eff-addr) (or (not check-alignment?) (address-aligned-p eff-addr 4 mem-ptr?))) (equal (rime32 0 eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?) (riml32 eff-addr r-x x86))))
Theorem:
(defthm rime32-unaligned-when-64-bit-modep-and-not-fs/gs (implies (and (not (equal seg-reg 4)) (not (equal seg-reg 5)) (not (or (not check-alignment?) (address-aligned-p eff-addr 4 mem-ptr?))) (canonical-address-p eff-addr)) (equal (rime32 0 eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?) (list (list :unaligned-linear-address eff-addr) 0 x86))))
Theorem:
(defthm rime32-when-64-bit-modep-and-fs/gs (implies (or (equal seg-reg 4) (equal seg-reg 5)) (equal (rime32 0 eff-addr seg-reg r-x check-alignment? x86 :mem-ptr? mem-ptr?) (b* (((mv flg lin-addr) (b* (((mv base & &) (segment-base-and-bounds 0 seg-reg x86)) (lin-addr (i64 (+ base (n64 eff-addr))))) (if (canonical-address-p lin-addr) (mv nil lin-addr) (mv (list :non-canonical-address lin-addr) 0)))) ((when flg) (mv flg 0 x86)) ((unless (or (not check-alignment?) (address-aligned-p lin-addr 4 mem-ptr?))) (mv (list :unaligned-linear-address lin-addr) 0 x86))) (riml32 lin-addr r-x x86)))))