• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
      • Kestrel-books
      • X86isa
        • Program-execution
        • Sdm-instruction-set-summary
        • Tlb
        • Running-linux
        • Introduction
        • Asmtest
        • X86isa-build-instructions
        • Publications
        • Contributors
        • Machine
          • X86isa-state
          • Syscalls
          • Cpuid
          • Linear-memory
          • Rflag-specifications
          • Characterizing-undefined-behavior
          • Top-level-memory
            • Rme32
            • Rime32
            • Gen-read-function
            • Rme256
            • Rme128
            • Rime64
            • Rime16
            • Rme80
            • Rme64
            • Rme48
            • Rme16
            • Gen-write-function
            • Rme-size
            • Rme08
            • Rime08
            • Rime-size
            • Wme-size
            • Wime-size
            • Wme32
            • Wime32
            • Wme80
            • Wme64
            • Wme48
            • Wme256
            • Wme16
            • Wme128
              • Wime64
              • Wime16
              • Address-aligned-p
              • Wme08
              • Wime08
            • App-view
            • X86-decoder
            • Physical-memory
            • Decoding-and-spec-utils
            • Instructions
            • Register-readers-and-writers
            • X86-modes
            • Segmentation
            • Other-non-deterministic-computations
            • Environment
            • Paging
          • Implemented-opcodes
          • To-do
          • Proof-utilities
          • Peripherals
          • Model-validation
          • Modelcalls
          • Concrete-simulation-examples
          • Utils
          • Debugging-code-proofs
        • Axe
        • Execloader
      • Math
      • Testing-utilities
    • Top-level-memory

    Wme128

    Write an unsigned 128-bit value to memory via an effective address.

    Signature
    (wme128 proc-mode eff-addr seg-reg val check-alignment? x86) 
      → 
    (mv flg x86-new)
    Arguments
    check-alignment? — Guard (booleanp check-alignment?).
    Returns
    x86-new — Type (x86p x86-new), given (x86p x86).

    The effective address eff-addr is translated to a canonical linear address. If this translation is successful and no other error occurs (like alignment errors), then wml128 is called.

    Prior to the effective address translation, we check whether write access is allowed. In 32-bit mode, write access is allowed in data segments (DS, ES, FS, GS, and SS) if the W bit in the segment descriptor is 1; write access is disallowed in code segments (this is not explicitly mentioned in Intel manual, May'18, Volume 3, Section 3.4.5.1, but it seems reasonable). In 64-bit mode, the W bit is ignored (see Atmel manual, Dec'17, Volume 2, Section 4.8.1); by analogy, we allow write access to the code segment as well. These checks may be slightly optimized using the invariant that SS.W must be 1 when SS is loaded.

    Definitions and Theorems

    Function: wme128$inline

    (defun wme128$inline (proc-mode eff-addr
                                    seg-reg val check-alignment? x86)
     (declare (xargs :stobjs (x86)))
     (declare (type (integer 0 4) proc-mode)
              (type (signed-byte 64) eff-addr)
              (type (integer 0 5) seg-reg)
              (type (unsigned-byte 128) val))
     (declare (xargs :guard (booleanp check-alignment?)))
     (b*
      (((when
         (and
          (/= proc-mode 0)
          (or (= seg-reg 1)
              (b* ((attr (loghead 16 (seg-hidden-attri seg-reg x86)))
                   (w (data-segment-descriptor-attributesbits->w attr)))
                (= w 0)))))
        (mv (list :non-writable-segment eff-addr seg-reg)
            x86))
       ((mv flg lin-addr)
        (ea-to-la proc-mode eff-addr seg-reg 16 x86))
       ((when flg) (mv flg x86))
       ((unless (or (not check-alignment?)
                    (address-aligned-p lin-addr 16 nil)))
        (mv (list :unaligned-linear-address lin-addr)
            x86)))
      (wml128 lin-addr val x86)))

    Theorem: x86p-of-wme128.x86-new

    (defthm x86p-of-wme128.x86-new
      (implies (x86p x86)
               (b* (((mv ?flg ?x86-new)
                     (wme128$inline proc-mode eff-addr
                                    seg-reg val check-alignment? x86)))
                 (x86p x86-new)))
      :rule-classes :rewrite)

    Theorem: wme128-when-64-bit-modep-and-not-fs/gs

    (defthm wme128-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 16 nil)))
               (equal (wme128 0 eff-addr
                              seg-reg val check-alignment? x86)
                      (wml128 eff-addr val x86))))

    Theorem: wme128-unaligned-when-64-bit-modep-and-not-fs/gs

    (defthm wme128-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 16 nil)))
                    (canonical-address-p eff-addr))
               (equal (wme128 0 eff-addr
                              seg-reg val check-alignment? x86)
                      (list (list :unaligned-linear-address eff-addr)
                            x86))))

    Theorem: wme128-when-64-bit-modep-and-fs/gs

    (defthm wme128-when-64-bit-modep-and-fs/gs
     (implies
          (or (equal seg-reg 4) (equal seg-reg 5))
          (equal (wme128 0 eff-addr
                         seg-reg val check-alignment? x86)
                 (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 x86))
                      ((unless (or (not check-alignment?)
                                   (address-aligned-p lin-addr 16 nil)))
                       (mv (list :unaligned-linear-address lin-addr)
                           x86)))
                   (wml128 lin-addr val x86)))))