123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- ;------------------------------------------------------------------------------
- ;
- ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- ; SPDX-License-Identifier: BSD-2-Clause-Patent
- ;
- ; Abstract:
- ;
- ; Provide macro for register save/restore using SSE registers
- ;
- ;------------------------------------------------------------------------------
- ;
- ; Define SSE and AVX instruction set
- ;
- ;
- ; Define SSE macros using SSE 4.1 instructions
- ; args 1:XMM, 2:IDX, 3:REG
- ;
- %macro SXMMN 3
- pinsrq %1, %3, (%2 & 3)
- %endmacro
- ;
- ; args 1:XMM, 2:REG, 3:IDX
- ;
- %macro LXMMN 3
- pextrq %2, %1, (%3 & 3)
- %endmacro
- ;
- ; Define AVX macros using AVX instructions
- ; Save XMM to YMM
- ; args 1:YMM, 2:IDX (0 - lower 128bits, 1 - upper 128bits), 3:XMM
- ;
- %macro SYMMN 3
- vinsertf128 %1, %1, %3, %2
- %endmacro
- ;
- ; Restore XMM from YMM
- ; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)
- ;
- %macro LYMMN 3
- vextractf128 %2, %1, %3
- %endmacro
- ;
- ; Upper half of YMM7 to save RBP and RBX. Upper half of YMM8 to save RSI and RDI.
- ; Modified: XMM5, YMM6, YMM7 and YMM8
- ;
- %macro SAVE_REGS 0
- SXMMN xmm5, 0, rbp
- SXMMN xmm5, 1, rbx
- SYMMN ymm7, 1, xmm5
- SXMMN xmm5, 0, rsi
- SXMMN xmm5, 1, rdi
- SYMMN ymm8, 1, xmm5
- SAVE_RSP
- %endmacro
- ;
- ; Upper half of YMM7 to restore RBP and RBX. Upper half of YMM8 to restore RSI and RDI.
- ; Modified: XMM5, RBP, RBX, RSI, RDI and RSP
- ;
- %macro LOAD_REGS 0
- LYMMN ymm7, xmm5, 1
- LXMMN xmm5, rbp, 0
- LXMMN xmm5, rbx, 1
- LYMMN ymm8, xmm5, 1
- LXMMN xmm5, rsi, 0
- LXMMN xmm5, rdi, 1
- LOAD_RSP
- %endmacro
- ;
- ; Restore RBP from YMM7[128:191]
- ; Modified: XMM5 and RBP
- ;
- %macro LOAD_RBP 0
- LYMMN ymm7, xmm5, 1
- movq rbp, xmm5
- %endmacro
- ;
- ; Restore RBX from YMM7[192:255]
- ; Modified: XMM5 and RBX
- ;
- %macro LOAD_RBX 0
- LYMMN ymm7, xmm5, 1
- LXMMN xmm5, rbx, 1
- %endmacro
- ;
- ; Upper half of YMM6 to save/restore Time Stamp, RSP
- ;
- ;
- ; Save Time Stamp to YMM6[192:255]
- ; arg 1:general purpose register which holds time stamp
- ; Modified: XMM5 and YMM6
- ;
- %macro SAVE_TS 1
- LYMMN ymm6, xmm5, 1
- SXMMN xmm5, 1, %1
- SYMMN ymm6, 1, xmm5
- %endmacro
- ;
- ; Restore Time Stamp from YMM6[192:255]
- ; arg 1:general purpose register where to save time stamp
- ; Modified: XMM5 and %1
- ;
- %macro LOAD_TS 1
- LYMMN ymm6, xmm5, 1
- LXMMN xmm5, %1, 1
- %endmacro
- ;
- ; Save RSP to YMM6[128:191]
- ; Modified: XMM5 and YMM6
- ;
- %macro SAVE_RSP 0
- LYMMN ymm6, xmm5, 1
- SXMMN xmm5, 0, rsp
- SYMMN ymm6, 1, xmm5
- %endmacro
- ;
- ; Restore RSP from YMM6[128:191]
- ; Modified: XMM5 and RSP
- ;
- %macro LOAD_RSP 0
- LYMMN ymm6, xmm5, 1
- movq rsp, xmm5
- %endmacro
- ;
- ; Upper half of YMM9 to save/restore UCODE status, BFV address
- ;
- ;
- ; Save uCode status to YMM9[192:255]
- ; arg 1:general purpose register which holds uCode status
- ; Modified: XMM5 and YMM9
- ;
- %macro SAVE_UCODE_STATUS 1
- LYMMN ymm9, xmm5, 1
- SXMMN xmm5, 0, %1
- SYMMN ymm9, 1, xmm5
- %endmacro
- ;
- ; Restore uCode status from YMM9[192:255]
- ; arg 1:general purpose register where to save uCode status
- ; Modified: XMM5 and %1
- ;
- %macro LOAD_UCODE_STATUS 1
- LYMMN ymm9, xmm5, 1
- movq %1, xmm5
- %endmacro
- ;
- ; Save BFV address to YMM9[128:191]
- ; arg 1:general purpose register which holds BFV address
- ; Modified: XMM5 and YMM9
- ;
- %macro SAVE_BFV 1
- LYMMN ymm9, xmm5, 1
- SXMMN xmm5, 1, %1
- SYMMN ymm9, 1, xmm5
- %endmacro
- ;
- ; Restore BFV address from YMM9[128:191]
- ; arg 1:general purpose register where to save BFV address
- ; Modified: XMM5 and %1
- ;
- %macro LOAD_BFV 1
- LYMMN ymm9, xmm5, 1
- LXMMN xmm5, %1, 1
- %endmacro
- ;
- ; Upper half of YMM10 to save/restore RCX
- ;
- ;
- ; Save RCX to YMM10[128:191]
- ; Modified: XMM5 and YMM10
- ;
- %macro SAVE_RCX 0
- LYMMN ymm10, xmm5, 1
- SXMMN xmm5, 0, rcx
- SYMMN ymm10, 1, xmm5
- %endmacro
- ;
- ; Restore RCX from YMM10[128:191]
- ; Modified: XMM5 and RCX
- ;
- %macro LOAD_RCX 0
- LYMMN ymm10, xmm5, 1
- movq rcx, xmm5
- %endmacro
- ;
- ; YMM7[128:191] for calling stack
- ; arg 1:Entry
- ; Modified: RSI, XMM5, YMM7
- ;
- %macro CALL_YMM 1
- mov rsi, %%ReturnAddress
- LYMMN ymm7, xmm5, 1
- SXMMN xmm5, 0, rsi
- SYMMN ymm7, 1, xmm5
- mov rsi, %1
- jmp rsi
- %%ReturnAddress:
- %endmacro
- ;
- ; Restore RIP from YMM7[128:191]
- ; Modified: RSI, XMM5
- ;
- %macro RET_YMM 0
- LYMMN ymm7, xmm5, 1
- movq rsi, xmm5
- jmp rsi
- %endmacro
- %macro ENABLE_SSE 0
- ;
- ; Initialize floating point units
- ;
- jmp NextAddress
- align 4
- ;
- ; Float control word initial value:
- ; all exceptions masked, double-precision, round-to-nearest
- ;
- FpuControlWord DW 027Fh
- ;
- ; Multimedia-extensions control word:
- ; all exceptions masked, round-to-nearest, flush to zero for masked underflow
- ;
- MmxControlWord DQ 01F80h
- SseError:
- ;
- ; Processor has to support SSE
- ;
- jmp SseError
- NextAddress:
- finit
- mov rax, FpuControlWord
- fldcw [rax]
- ;
- ; Use CpuId instruction (CPUID.01H:EDX.SSE[bit 25] = 1) to test
- ; whether the processor supports SSE instruction.
- ;
- mov r10, rcx
- mov rax, 1
- cpuid
- bt rdx, 25
- jnc SseError
- ;
- ; SSE 4.1 support
- ;
- bt ecx, 19
- jnc SseError
- mov rcx, r10
- ;
- ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
- ;
- mov rax, cr4
- or rax, 00000600h
- mov cr4, rax
- ;
- ; The processor should support SSE instruction and we can use
- ; ldmxcsr instruction
- ;
- mov rax, MmxControlWord
- ldmxcsr [rax]
- %endmacro
- %macro ENABLE_AVX 0
- mov r10, rcx
- mov eax, 1
- cpuid
- and ecx, 10000000h
- cmp ecx, 10000000h ; check AVX feature flag
- je EnableAvx
- AvxError:
- ;
- ; Processor has to support AVX
- ;
- jmp AvxError
- EnableAvx:
- ;
- ; Set OSXSAVE bit (bit #18) to enable xgetbv/xsetbv instruction
- ;
- mov rax, cr4
- or rax, 00040000h
- mov cr4, rax
- mov rcx, 0 ; index 0
- xgetbv ; result in edx:eax
- or eax, 00000006h ; Set XCR0 bit #1 and bit #2 to enable SSE state and AVX state
- xsetbv
- mov rcx, r10
- %endmacro
|