Commit made by Daniel, including the implementation of the daemon.
[vdi_driver.git] / src / asm.h
blob2b0c29570bf9db2bcc6f253d815d4a34cc94e3b3
1 #ifndef ASM_H
2 #define ASM_H
4 #include "config.h"
5 #include "types.h"
6 #include "func_defines.h"
8 /**
9 * Finds the first set bit in a bitmap.
11 * @returns Index of the first set bit.
12 * @returns -1 if no clear bit was found.
13 * @param pvBitmap Pointer to the bitmap.
14 * @param cBits The number of bits in the bitmap. Multiple of 32.
16 DECLINLINE(int) ASMBitFirstSet(volatile void *pvBitmap, uint32_t cBits)
18 if (cBits)
20 int32_t iBit;
21 # ifdef RT_INLINE_ASM_GNU_STYLE
22 RTCCUINTREG uEAX, uECX, uEDI;
23 cBits = RT_ALIGN_32(cBits, 32);
24 __asm__ __volatile__("repe; scasl\n\t"
25 "je 1f\n\t"
26 # ifdef RT_ARCH_AMD64
27 "lea -4(%%rdi), %%rdi\n\t"
28 "movl (%%rdi), %%eax\n\t"
29 "subq %5, %%rdi\n\t"
30 # else
31 "lea -4(%%edi), %%edi\n\t"
32 "movl (%%edi), %%eax\n\t"
33 "subl %5, %%edi\n\t"
34 # endif
35 "shll $3, %%edi\n\t"
36 "bsfl %%eax, %%edx\n\t"
37 "addl %%edi, %%edx\n\t"
38 "1:\t\n"
39 : "=d" (iBit),
40 "=&c" (uECX),
41 "=&D" (uEDI),
42 "=&a" (uEAX)
43 : "0" (0xffffffff),
44 "mr" (pvBitmap),
45 "1" (cBits >> 5),
46 "2" (pvBitmap),
47 "3" (0));
48 # else
49 cBits = RT_ALIGN_32(cBits, 32);
50 __asm
52 # ifdef RT_ARCH_AMD64
53 mov rdi, [pvBitmap]
54 mov rbx, rdi
55 # else
56 mov edi, [pvBitmap]
57 mov ebx, edi
58 # endif
59 mov edx, 0ffffffffh
60 xor eax, eax
61 mov ecx, [cBits]
62 shr ecx, 5
63 repe scasd
64 je done
65 # ifdef RT_ARCH_AMD64
66 lea rdi, [rdi - 4]
67 mov eax, [rdi]
68 sub rdi, rbx
69 # else
70 lea edi, [edi - 4]
71 mov eax, [edi]
72 sub edi, ebx
73 # endif
74 shl edi, 3
75 bsf edx, eax
76 add edx, edi
77 done:
78 mov [iBit], edx
80 # endif
81 return iBit;
83 return -1;
86 /**
87 * Gets the content of the CPU timestamp counter register.
89 * @returns TSC.
91 DECLINLINE(uint64_t) ASMReadTSC(void)
93 RTUINT64U u;
94 # ifdef RT_INLINE_ASM_GNU_STYLE
95 __asm__ __volatile__ ("rdtsc\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi));
96 # else
97 # if RT_INLINE_ASM_USES_INTRIN
98 u.u = __rdtsc();
99 # else
100 __asm
102 rdtsc
103 mov [u.s.Lo], eax
104 mov [u.s.Hi], edx
106 # endif
107 # endif
108 return u.u;
111 #endif