2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/amd64/interlck.S
5 * PURPOSE: Rtl Interlocked Functions for amd64
6 * PROGRAMMERS: Timo Kreuzer
10 #include <ksamd64.inc>
12 EXTERN RtlpUse16ByteSLists:BYTE
15 typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER
26 ULONGLONG NextEntry:39;
27 ULONGLONG HeaderType:1;
29 ULONGLONG Reserved:59;
35 ULONGLONG Sequence:48;
36 ULONGLONG HeaderType:1;
39 ULONGLONG NextEntry:60;
44 ULONGLONG Sequence:48;
45 ULONGLONG HeaderType:1;
47 ULONGLONG NextEntry:60;
49 } SLIST_HEADER, *PSLIST_HEADER;
52 #define SLIST8A_DEPTH_MASK HEX(000000000000FFFF)
53 #define SLIST8A_DEPTH_INC HEX(0000000000000001)
54 #define SLIST8A_SEQUENCE_MASK HEX(0000000001FF0000)
55 #define SLIST8A_SEQUENCE_INC HEX(0000000000010000)
56 #define SLIST8A_NEXTENTRY_MASK HEX(FFFFFFFFFE000000)
57 #define SLIST8A_NEXTENTRY_SHIFT 21
58 #define SLIST8B_HEADERTYPE_MASK HEX(0000000000000001)
59 #define SLIST8B_INIT_MASK HEX(0000000000000002)
60 #define SLIST8B_REGION_MASK HEX(E000000000000000)
61 #define SLIST8_POINTER_MASK HEX(000007FFFFFFFFFF)
63 #define SLIST16A_DEPTH_MASK HEX(000000000000FFFF)
64 #define SLIST16A_DEPTH_INC HEX(0000000000000001)
65 #define SLIST16A_SEQUENCE_MASK HEX(FFFFFFFFFFFF0000)
66 #define SLIST16A_SEQUENCE_INC HEX(0000000000010000)
67 #define SLIST16B_HEADERTYPE_MASK HEX(0000000000000001)
68 #define SLIST16B_INIT_MASK HEX(0000000000000002)
69 #define SLIST16B_NEXTENTRY_MASK HEX(FFFFFFFFFFFFFFF0)
72 /* FUNCTIONS ****************************************************************/
76 PUBLIC ExpInterlockedPopEntrySList
77 PUBLIC ExpInterlockedPopEntrySListResume
78 PUBLIC ExpInterlockedPopEntrySListFault
79 PUBLIC ExpInterlockedPopEntrySListEnd
80 PUBLIC ExpInterlockedPopEntrySListResume16
81 PUBLIC ExpInterlockedPopEntrySListFault16
82 PUBLIC ExpInterlockedPopEntrySListEnd16
83 PUBLIC ExpInterlockedPushEntrySList
84 PUBLIC ExpInterlockedFlushSList
86 PUBLIC RtlInterlockedFlushSList
87 PUBLIC RtlInterlockedPopEntrySList
88 PUBLIC RtlInterlockedPushEntrySList
92 * RtlInterlockedPopEntrySList(
93 * IN PSLIST_HEADER ListHead);
95 RtlInterlockedPopEntrySList:
96 ExpInterlockedPopEntrySList:
98 /* Load ListHead->Region into rdx */
101 /* Load ListHead->Alignment into rax */
104 /* Check for 16 byte SList support */
105 cmp byte ptr [RtlpUse16ByteSLists], 0
106 jne RtlInterlockedPopEntrySList16
108 /* Use the 8 byte header */
110 ExpInterlockedPopEntrySListResume:
112 /* Check if ListHead->NextEntry is NULL */
114 and r9, SLIST8A_NEXTENTRY_MASK
115 jz RtlInterlockedPopEntrySListEmpty
117 /* Copy Depth and Sequence number and adjust Depth */
118 lea r8, [rax - SLIST8A_DEPTH_INC]
119 and r8, (SLIST8A_SEQUENCE_MASK OR SLIST8A_DEPTH_MASK)
121 /* Create a pointer template from rcx in rdx */
122 mov rdx, (NOT SLIST8_POINTER_MASK)
125 /* Shift the NextEntry pointer */
126 shr r9, SLIST8A_NEXTENTRY_SHIFT
128 /* Combine to new pointer in rdx */
131 ExpInterlockedPopEntrySListFault:
133 /* Load the next NextEntry pointer to r9 */
136 /* Shift bits in place */
137 shl r9, SLIST8A_NEXTENTRY_SHIFT
139 /* Combine into r8 */
142 ExpInterlockedPopEntrySListEnd:
144 /* If [rcx] equals rax, exchange it with r8 */
145 lock cmpxchg [rcx], r8
147 /* If not equal, retry with rax, being the content of [rcx] now */
148 jne ExpInterlockedPopEntrySListResume
150 /* Shift the pointer bits in place */
151 and rax, SLIST8A_NEXTENTRY_MASK
152 shr rax, SLIST8A_NEXTENTRY_SHIFT
154 /* Use rcx as pointer template */
155 mov rdx, (NOT SLIST8_POINTER_MASK)
158 /* Combine result and return */
162 RtlInterlockedPopEntrySListEmpty:
166 RtlInterlockedPopEntrySList16:
167 /* This is a 16 byte header
169 rdx == ListHead->Region
170 rax == ListHead->Alignment */
175 /* Copy rcx to r8, as we need rcx for the exchange */
178 ExpInterlockedPopEntrySListResume16:
180 /* Set r9 = ListHead->NextEntry and check if it is NULL */
182 and r9, SLIST16B_NEXTENTRY_MASK
183 jz RtlInterlockedPopEntrySListEmpty16
185 ExpInterlockedPopEntrySListFault16:
187 /* Set NewListHead.Next = ListHead->NextEntry->Next */
190 /* Set NewListHead.HeaderType = 1 and NewListHead.Init = 1 */
191 or rcx, (SLIST16B_HEADERTYPE_MASK or SLIST16B_INIT_MASK)
193 /* Copy Depth and Sequence number and adjust Depth */
194 lea rbx, [rax - SLIST16A_DEPTH_INC]
196 ExpInterlockedPopEntrySListEnd16:
198 /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
201 /* If not equal, retry with rdx:rax, being the content of [r8] now */
202 jne ExpInterlockedPopEntrySListResume16
204 /* Copy the old NextEntry pointer to rax */
206 and rax, SLIST16B_NEXTENTRY_MASK
212 RtlInterlockedPopEntrySListEmpty16:
220 * RtlInterlockedPushEntrySList(
221 * IN PSLIST_HEADER ListHead,
222 * IN PSLIST_ENTRY ListEntry);
224 RtlInterlockedPushEntrySList:
225 ExpInterlockedPushEntrySList:
228 /* Make sure the ListEntry is 16 bytes aligned */
230 jz ExpInterlockedPushEntrySListChecked
231 /* Not aligned, raise an assertion */
233 ExpInterlockedPushEntrySListChecked:
235 /* Make sure RtlpUse16ByteSLists is initialized */
236 cmp byte ptr [RtlpUse16ByteSLists], HEX(FF)
237 jne ExpInterlockedPushEntrySListChecked2
238 /* Not initialized, raise an assertion */
240 ExpInterlockedPushEntrySListChecked2:
243 /* Load ListHead->Alignment into rax */
246 /* Load ListHead->Region into r9 */
249 /* Check for 16 byte SList support */
250 cmp byte ptr [RtlpUse16ByteSLists], 0
251 jne RtlInterlockedPushEntrySList16
253 /* Use the 8 byte header */
255 RtlInterlockedPushEntrySListLoop:
257 /* Get ListHead->NextEntry */
259 and r8, SLIST8A_NEXTENTRY_MASK
260 jz RtlInterlockedPushEntrySListEmpty
262 /* Shift the NextEntry pointer */
263 shr r8, SLIST8A_NEXTENTRY_SHIFT
265 /* Create a pointer template from rcx in rdx */
266 mov r9, (NOT SLIST8_POINTER_MASK)
269 /* Combine to new pointer and save as ListEntry->NextEntry */
272 RtlInterlockedPushEntrySListEmpty:
273 /* Store the NextEntry pointer in the new ListEntry */
276 /* Shift and mask the new ListEntry pointer */
278 shl r8, SLIST8A_NEXTENTRY_SHIFT
279 and r8, SLIST8A_NEXTENTRY_MASK
281 /* Copy and adjust depth and sequence number */
282 lea r9, [rax + SLIST8A_DEPTH_INC + SLIST8A_SEQUENCE_INC]
283 and r9, SLIST8A_SEQUENCE_MASK OR SLIST8A_DEPTH_MASK
285 /* Combine to exchange value in r8 */
288 /* Save the NextEntry in r9 */
291 /* If [rcx] equals rax, exchange it with r8 */
292 lock cmpxchg [rcx], r8
294 /* If not equal, retry with rax, being the content of [rcx] now */
295 jne RtlInterlockedPushEntrySListLoop
297 /* Return the old NextEntry pointer */
301 RtlInterlockedPushEntrySList16:
302 /* This is a 16 byte header
305 rax = ListHead->Alignment
306 r9 = ListHead->Region */
311 /* Copy rcx/rdx to r8/r9, as we need rcx/rdx for the exchange */
315 /* Set NewListHead.NextEntry = ListEntry */
318 /* Set NewListHead.HeaderType = 1 and NewListHead.Init = 1 */
319 or rcx, (SLIST16B_HEADERTYPE_MASK or SLIST16B_INIT_MASK)
321 /* Set rdx = ListHead->Region */
324 RtlInterlockedPushEntrySListLoop16:
327 rax = ListHead->Alignment
328 rdx = ListHead->Region
331 /* Move ListHead->NextEntry to rbx */
333 and rbx, SLIST16B_NEXTENTRY_MASK
335 /* Store next pointer in ListEntry->Next */
338 /* Copy and increment Depth and Sequence number to rbx */
339 lea rbx, [rax + SLIST16A_DEPTH_INC + SLIST16A_SEQUENCE_INC]
341 /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
344 /* If not equal, retry with rdx:rax, being the content of [r8] now */
345 jne RtlInterlockedPushEntrySListLoop16
347 /* Copy the old NextEntry pointer to rax */
349 and rax, SLIST16B_NEXTENTRY_MASK
358 * RtlInterlockedFlushSList(
359 * IN PSLIST_HEADER ListHead);
361 RtlInterlockedFlushSList:
362 ExpInterlockedFlushSList:
364 /* Load ListHead->Region into rdx */
367 /* Load ListHead->Alignment into rax */
370 /* Check for 16 byte SList support */
371 cmp byte ptr [RtlpUse16ByteSLists], 0
372 jne RtlInterlockedFlushSList16
374 /* Use the 8 byte header */
376 RtlInterlockedFlushSListLoop:
378 /* Zero NewListHead.Alignment */
381 /* If [rcx] equals rax, exchange it with r8 */
382 lock cmpxchg [rcx], r8
384 /* If not equal, retry with rax, being the content of [rcx] now */
385 jne RtlInterlockedFlushSListLoop
387 /* Create a pointer template from rcx in rdx */
388 mov rdx, (NOT SLIST8_POINTER_MASK)
391 /* Load the old NextEntry pointer into rax */
392 and rax, SLIST8A_NEXTENTRY_MASK
393 shr rax, SLIST8A_NEXTENTRY_SHIFT
395 /* Combine result and return */
399 RtlInterlockedFlushSList16:
400 /* We have a 16 byte header
402 rax = ListHead->Alignment
403 rdx = ListHead->Region
409 /* Load ListHead into r8, as we need rcx for the exchange */
412 /* Initialize an ampty NewListHead in rcx:rbx */
414 mov rcx, (SLIST16B_HEADERTYPE_MASK or SLIST16B_INIT_MASK)
416 RtlInterlockedFlushSListLoop16:
418 /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
421 /* If not equal, retry with rdx:rax, being the content of [r8] now */
422 jne RtlInterlockedFlushSListLoop16
424 /* Copy the old NextEntry pointer to rax */
426 and rax, SLIST16B_NEXTENTRY_MASK