ax-cpu 0.10.0

Privileged instruction and structure abstractions for various CPU architectures
Documentation
# Shared VMX/SVM extended-state window. R8 owns the descriptor; RDI and RSI
# retain the entry context and SVM guest address. Only saved scratch GPRs change.
.macro XS_READ_MSR index, slot
    mov ecx, \index
    rdmsr
    shl rdx, 32
    or rax, rdx
    mov [r8 + \slot], rax
.endm
.macro XS_WRITE_MSR index, slot
    mov ecx, \index
    mov rax, [r8 + \slot]
    mov rdx, rax
    shr rdx, 32
    wrmsr
.endm
.macro XS_SET_XCR0 slot
    xor ecx, ecx
    mov rax, [r8 + \slot]
    mov rdx, rax
    shr rdx, 32
    xsetbv
.endm
.macro XS_READ_BANKS xcr0, xss, xfd, error
    xor ecx, ecx
    xgetbv
    shl rdx, 32
    or rax, rdx
    mov [r8 + \xcr0], rax
    cmp qword ptr [r8 + {xs_mode}], 2
    jne .Lxs_no_xss_\@
    XS_READ_MSR 0xda0, \xss
.Lxs_no_xss_\@:
    cmp qword ptr [r8 + {xs_has_xfd}], 0
    je .Lxs_no_xfd_\@
    XS_READ_MSR 0x1c4, \xfd
    XS_READ_MSR 0x1c5, \error
    # Retain dormant components as well as those enabled by the current bank.
    mov ecx, 0x1c4
    xor eax, eax
    xor edx, edx
    wrmsr
.Lxs_no_xfd_\@:
.endm
.macro XS_SET_BANKS xcr0, xss, xfd, error
    XS_SET_XCR0 \xcr0
    cmp qword ptr [r8 + {xs_mode}], 2
    jne .Lxs_set_no_xss_\@
    XS_WRITE_MSR 0xda0, \xss
.Lxs_set_no_xss_\@:
    cmp qword ptr [r8 + {xs_has_xfd}], 0
    je .Lxs_set_no_xfd_\@
    XS_WRITE_MSR 0x1c4, \xfd
    XS_WRITE_MSR 0x1c5, \error
.Lxs_set_no_xfd_\@:
.endm
.macro XS_FULL_BANKS
    XS_SET_XCR0 {xs_full_xcr0}
    cmp qword ptr [r8 + {xs_mode}], 2
    jne .Lxs_full_no_xss_\@
    XS_WRITE_MSR 0xda0, {xs_full_xss}
.Lxs_full_no_xss_\@:
.endm
.macro XS_IMAGE save, restore
    mov rax, [r8 + {xs_full_xcr0}]
    or rax, [r8 + {xs_full_xss}]
    mov rdx, rax
    shr rdx, 32
    mov r9, [r8 + \save]
    cmp qword ptr [r8 + {xs_mode}], 2
    je .Lxs_compact_\@
    xsave64 [r9]
    mov r9, [r8 + \restore]
    xrstor64 [r9]
    jmp .Lxs_image_done_\@
.Lxs_compact_\@:
    xsaves64 [r9]
    mov r9, [r8 + \restore]
    xrstors64 [r9]
.Lxs_image_done_\@:
.endm
.macro XSTATE_ENTER pointer
    mov r8, [rdi + \pointer]
    cmp qword ptr [r8 + {xs_mode}], 0
    je .Lxs_enter_fx_\@
    XS_READ_BANKS {xs_host_xcr0}, {xs_host_xss}, {xs_host_xfd}, {xs_host_xfd_err}
    XS_FULL_BANKS
    XS_IMAGE {xs_host}, {xs_guest}
    XS_SET_BANKS {xs_guest_xcr0}, {xs_guest_xss}, {xs_guest_xfd}, {xs_guest_xfd_err}
    jmp .Lxs_enter_done_\@
.Lxs_enter_fx_\@:
    mov r9, [r8 + {xs_host}]
    fxsave64 [r9]
    mov r9, [r8 + {xs_guest}]
    fxrstor64 [r9]
.Lxs_enter_done_\@:
.endm
.macro XSTATE_EXIT pointer
    mov r8, [rdi + \pointer]
    cmp qword ptr [r8 + {xs_mode}], 0
    je .Lxs_exit_fx_\@
    XS_READ_BANKS {xs_guest_xcr0}, {xs_guest_xss}, {xs_guest_xfd}, {xs_guest_xfd_err}
    XS_FULL_BANKS
    XS_IMAGE {xs_guest}, {xs_host}
    XS_SET_BANKS {xs_host_xcr0}, {xs_host_xss}, {xs_host_xfd}, {xs_host_xfd_err}
    jmp .Lxs_exit_done_\@
.Lxs_exit_fx_\@:
    mov r9, [r8 + {xs_guest}]
    fxsave64 [r9]
    mov r9, [r8 + {xs_host}]
    fxrstor64 [r9]
.Lxs_exit_done_\@:
.endm