SaveRestoreSseAvxNasm.inc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. ;------------------------------------------------------------------------------
  2. ;
  3. ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
  4. ; SPDX-License-Identifier: BSD-2-Clause-Patent
  5. ;
  6. ; Abstract:
  7. ;
  8. ; Provide macro for register save/restore using SSE registers
  9. ;
  10. ;------------------------------------------------------------------------------
  11. ;
  12. ; Define SSE and AVX instruction set
  13. ;
  14. ;
  15. ; Define SSE macros using SSE 4.1 instructions
  16. ; args 1:XMM, 2:IDX, 3:REG
  17. ;
  18. %macro SXMMN 3
  19. pinsrq %1, %3, (%2 & 3)
  20. %endmacro
  21. ;
  22. ; args 1:XMM, 2:REG, 3:IDX
  23. ;
  24. %macro LXMMN 3
  25. pextrq %2, %1, (%3 & 3)
  26. %endmacro
  27. ;
  28. ; Define AVX macros using AVX instructions
  29. ; Save XMM to YMM
  30. ; args 1:YMM, 2:IDX (0 - lower 128bits, 1 - upper 128bits), 3:XMM
  31. ;
  32. %macro SYMMN 3
  33. vinsertf128 %1, %1, %3, %2
  34. %endmacro
  35. ;
  36. ; Restore XMM from YMM
  37. ; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)
  38. ;
  39. %macro LYMMN 3
  40. vextractf128 %2, %1, %3
  41. %endmacro
  42. ;
  43. ; Upper half of YMM7 to save RBP and RBX. Upper half of YMM8 to save RSI and RDI.
  44. ; Modified: XMM5, YMM6, YMM7 and YMM8
  45. ;
  46. %macro SAVE_REGS 0
  47. SXMMN xmm5, 0, rbp
  48. SXMMN xmm5, 1, rbx
  49. SYMMN ymm7, 1, xmm5
  50. SXMMN xmm5, 0, rsi
  51. SXMMN xmm5, 1, rdi
  52. SYMMN ymm8, 1, xmm5
  53. SAVE_RSP
  54. %endmacro
  55. ;
  56. ; Upper half of YMM7 to restore RBP and RBX. Upper half of YMM8 to restore RSI and RDI.
  57. ; Modified: XMM5, RBP, RBX, RSI, RDI and RSP
  58. ;
  59. %macro LOAD_REGS 0
  60. LYMMN ymm7, xmm5, 1
  61. LXMMN xmm5, rbp, 0
  62. LXMMN xmm5, rbx, 1
  63. LYMMN ymm8, xmm5, 1
  64. LXMMN xmm5, rsi, 0
  65. LXMMN xmm5, rdi, 1
  66. LOAD_RSP
  67. %endmacro
  68. ;
  69. ; Restore RBP from YMM7[128:191]
  70. ; Modified: XMM5 and RBP
  71. ;
  72. %macro LOAD_RBP 0
  73. LYMMN ymm7, xmm5, 1
  74. movq rbp, xmm5
  75. %endmacro
  76. ;
  77. ; Restore RBX from YMM7[192:255]
  78. ; Modified: XMM5 and RBX
  79. ;
  80. %macro LOAD_RBX 0
  81. LYMMN ymm7, xmm5, 1
  82. LXMMN xmm5, rbx, 1
  83. %endmacro
  84. ;
  85. ; Upper half of YMM6 to save/restore Time Stamp, RSP
  86. ;
  87. ;
  88. ; Save Time Stamp to YMM6[192:255]
  89. ; arg 1:general purpose register which holds time stamp
  90. ; Modified: XMM5 and YMM6
  91. ;
  92. %macro SAVE_TS 1
  93. LYMMN ymm6, xmm5, 1
  94. SXMMN xmm5, 1, %1
  95. SYMMN ymm6, 1, xmm5
  96. %endmacro
  97. ;
  98. ; Restore Time Stamp from YMM6[192:255]
  99. ; arg 1:general purpose register where to save time stamp
  100. ; Modified: XMM5 and %1
  101. ;
  102. %macro LOAD_TS 1
  103. LYMMN ymm6, xmm5, 1
  104. LXMMN xmm5, %1, 1
  105. %endmacro
  106. ;
  107. ; Save RSP to YMM6[128:191]
  108. ; Modified: XMM5 and YMM6
  109. ;
  110. %macro SAVE_RSP 0
  111. LYMMN ymm6, xmm5, 1
  112. SXMMN xmm5, 0, rsp
  113. SYMMN ymm6, 1, xmm5
  114. %endmacro
  115. ;
  116. ; Restore RSP from YMM6[128:191]
  117. ; Modified: XMM5 and RSP
  118. ;
  119. %macro LOAD_RSP 0
  120. LYMMN ymm6, xmm5, 1
  121. movq rsp, xmm5
  122. %endmacro
  123. ;
  124. ; Upper half of YMM9 to save/restore UCODE status, BFV address
  125. ;
  126. ;
  127. ; Save uCode status to YMM9[192:255]
  128. ; arg 1:general purpose register which holds uCode status
  129. ; Modified: XMM5 and YMM9
  130. ;
  131. %macro SAVE_UCODE_STATUS 1
  132. LYMMN ymm9, xmm5, 1
  133. SXMMN xmm5, 0, %1
  134. SYMMN ymm9, 1, xmm5
  135. %endmacro
  136. ;
  137. ; Restore uCode status from YMM9[192:255]
  138. ; arg 1:general purpose register where to save uCode status
  139. ; Modified: XMM5 and %1
  140. ;
  141. %macro LOAD_UCODE_STATUS 1
  142. LYMMN ymm9, xmm5, 1
  143. movq %1, xmm5
  144. %endmacro
  145. ;
  146. ; Save BFV address to YMM9[128:191]
  147. ; arg 1:general purpose register which holds BFV address
  148. ; Modified: XMM5 and YMM9
  149. ;
  150. %macro SAVE_BFV 1
  151. LYMMN ymm9, xmm5, 1
  152. SXMMN xmm5, 1, %1
  153. SYMMN ymm9, 1, xmm5
  154. %endmacro
  155. ;
  156. ; Restore BFV address from YMM9[128:191]
  157. ; arg 1:general purpose register where to save BFV address
  158. ; Modified: XMM5 and %1
  159. ;
  160. %macro LOAD_BFV 1
  161. LYMMN ymm9, xmm5, 1
  162. LXMMN xmm5, %1, 1
  163. %endmacro
  164. ;
  165. ; Upper half of YMM10 to save/restore RCX
  166. ;
  167. ;
  168. ; Save RCX to YMM10[128:191]
  169. ; Modified: XMM5 and YMM10
  170. ;
  171. %macro SAVE_RCX 0
  172. LYMMN ymm10, xmm5, 1
  173. SXMMN xmm5, 0, rcx
  174. SYMMN ymm10, 1, xmm5
  175. %endmacro
  176. ;
  177. ; Restore RCX from YMM10[128:191]
  178. ; Modified: XMM5 and RCX
  179. ;
  180. %macro LOAD_RCX 0
  181. LYMMN ymm10, xmm5, 1
  182. movq rcx, xmm5
  183. %endmacro
  184. ;
  185. ; YMM7[128:191] for calling stack
  186. ; arg 1:Entry
  187. ; Modified: RSI, XMM5, YMM7
  188. ;
  189. %macro CALL_YMM 1
  190. mov rsi, %%ReturnAddress
  191. LYMMN ymm7, xmm5, 1
  192. SXMMN xmm5, 0, rsi
  193. SYMMN ymm7, 1, xmm5
  194. mov rsi, %1
  195. jmp rsi
  196. %%ReturnAddress:
  197. %endmacro
  198. ;
  199. ; Restore RIP from YMM7[128:191]
  200. ; Modified: RSI, XMM5
  201. ;
  202. %macro RET_YMM 0
  203. LYMMN ymm7, xmm5, 1
  204. movq rsi, xmm5
  205. jmp rsi
  206. %endmacro
  207. %macro ENABLE_SSE 0
  208. ;
  209. ; Initialize floating point units
  210. ;
  211. jmp NextAddress
  212. align 4
  213. ;
  214. ; Float control word initial value:
  215. ; all exceptions masked, double-precision, round-to-nearest
  216. ;
  217. FpuControlWord DW 027Fh
  218. ;
  219. ; Multimedia-extensions control word:
  220. ; all exceptions masked, round-to-nearest, flush to zero for masked underflow
  221. ;
  222. MmxControlWord DQ 01F80h
  223. SseError:
  224. ;
  225. ; Processor has to support SSE
  226. ;
  227. jmp SseError
  228. NextAddress:
  229. finit
  230. mov rax, FpuControlWord
  231. fldcw [rax]
  232. ;
  233. ; Use CpuId instruction (CPUID.01H:EDX.SSE[bit 25] = 1) to test
  234. ; whether the processor supports SSE instruction.
  235. ;
  236. mov r10, rcx
  237. mov rax, 1
  238. cpuid
  239. bt rdx, 25
  240. jnc SseError
  241. ;
  242. ; SSE 4.1 support
  243. ;
  244. bt ecx, 19
  245. jnc SseError
  246. mov rcx, r10
  247. ;
  248. ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
  249. ;
  250. mov rax, cr4
  251. or rax, 00000600h
  252. mov cr4, rax
  253. ;
  254. ; The processor should support SSE instruction and we can use
  255. ; ldmxcsr instruction
  256. ;
  257. mov rax, MmxControlWord
  258. ldmxcsr [rax]
  259. %endmacro
  260. %macro ENABLE_AVX 0
  261. mov r10, rcx
  262. mov eax, 1
  263. cpuid
  264. and ecx, 10000000h
  265. cmp ecx, 10000000h ; check AVX feature flag
  266. je EnableAvx
  267. AvxError:
  268. ;
  269. ; Processor has to support AVX
  270. ;
  271. jmp AvxError
  272. EnableAvx:
  273. ;
  274. ; Set OSXSAVE bit (bit #18) to enable xgetbv/xsetbv instruction
  275. ;
  276. mov rax, cr4
  277. or rax, 00040000h
  278. mov cr4, rax
  279. mov rcx, 0 ; index 0
  280. xgetbv ; result in edx:eax
  281. or eax, 00000006h ; Set XCR0 bit #1 and bit #2 to enable SSE state and AVX state
  282. xsetbv
  283. mov rcx, r10
  284. %endmacro