Replaced some c includes with their c++ wrappers
[ardour.git] / libs / pbd / fpu.cc
1 #define _XOPEN_SOURCE 600
2 #include <cstdlib>
3 #include <stdint.h>
4
5 #include <pbd/fpu.h>
6 #include <pbd/error.h>
7
8 #include "i18n.h"
9
10 using namespace PBD;
11 using namespace std;
12
13 FPU::FPU ()
14 {
15         unsigned long cpuflags = 0;
16
17         _flags = Flags (0);
18
19 #ifndef ARCH_X86
20         return;
21
22 #else
23         
24 #ifndef USE_X86_64_ASM
25         asm volatile (
26                 "mov $1, %%eax\n"
27                 "pushl %%ebx\n"
28                 "cpuid\n"
29                 "movl %%edx, %0\n"
30                 "popl %%ebx\n"
31                 : "=r" (cpuflags)
32                 : 
33                 : "%eax", "%ecx", "%edx", "memory"
34                 );
35         
36 #else
37         
38         asm volatile (
39                 "pushq %%rbx\n"
40                 "movq $1, %%rax\n"
41                 "cpuid\n"
42                 "movq %%rdx, %0\n"
43                 "popq %%rbx\n"
44                 : "=r" (cpuflags)
45                 : 
46                 : "%rax", "%rcx", "%rdx", "memory"
47                 );
48
49 #endif /* USE_X86_64_ASM */
50         
51         if (cpuflags & (1<<25)) {
52                 _flags = Flags (_flags | (HasSSE|HasFlushToZero));
53         }
54
55         if (cpuflags & (1<<26)) {
56                 _flags = Flags (_flags | HasSSE2);
57         }
58
59         if (cpuflags & (1 << 24)) {
60                 
61                 char* fxbuf = 0;
62                 
63 #ifdef NO_POSIX_MEMALIGN
64                 if ((fxbuf = (char *) malloc(512)) == 0)
65 #else
66                 if (posix_memalign ((void**)&fxbuf, 16, 512)) 
67 #endif                  
68                 {
69                         error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg;
70                 } else {
71                         
72                         asm volatile (
73                                 "fxsave (%0)"
74                                 :
75                                 : "r" (fxbuf)
76                                 : "memory"
77                                 );
78                         
79                         uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]);
80                         
81                         /* if the mask is zero, set its default value (from intel specs) */
82                         
83                         if (mxcsr_mask == 0) {
84                                 mxcsr_mask = 0xffbf;
85                         }
86                         
87                         if (mxcsr_mask & (1<<6)) {
88                                 _flags = Flags (_flags | HasDenormalsAreZero);
89                         } 
90
91                         free (fxbuf);
92                 }
93         }
94 #endif  // ARCH_X86
95 }                       
96
97 FPU::~FPU ()
98 {
99 }