1 | /* |
2 | Copyright 2005-2013 Intel Corporation. All Rights Reserved. |
3 | |
4 | This file is part of Threading Building Blocks. |
5 | |
6 | Threading Building Blocks is free software; you can redistribute it |
7 | and/or modify it under the terms of the GNU General Public License |
8 | version 2 as published by the Free Software Foundation. |
9 | |
10 | Threading Building Blocks is distributed in the hope that it will be |
11 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU General Public License |
16 | along with Threading Building Blocks; if not, write to the Free Software |
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | |
19 | As a special exception, you may use this file as part of a free software |
20 | library without restriction. Specifically, if other files instantiate |
21 | templates or use macros or inline functions from this file, or you compile |
22 | this file and link it with other files to produce an executable, this |
23 | file does not by itself cause the resulting executable to be covered by |
24 | the GNU General Public License. This exception does not however |
25 | invalidate any other reasons why the executable file might be covered by |
26 | the GNU General Public License. |
27 | */ |
28 | |
29 | #ifndef __TBB_machine_gcc_ia32_common_H |
30 | #define __TBB_machine_gcc_ia32_common_H |
31 | |
32 | //TODO: Add a higher-level function, e.g. tbb::interal::log2(), into tbb_stddef.h, which |
33 | //uses __TBB_Log2 and contains the assert and remove the assert from here and all other |
34 | //platform-specific headers. |
35 | //TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations |
36 | static inline intptr_t __TBB_machine_lg( uintptr_t x ) { |
37 | __TBB_ASSERT(x, "__TBB_Log2(0) undefined" ); |
38 | uintptr_t j; |
39 | __asm__ ("bsr %1,%0" : "=r" (j) : "r" (x)); |
40 | return j; |
41 | } |
42 | #define __TBB_Log2(V) __TBB_machine_lg(V) |
43 | |
44 | #ifndef __TBB_Pause |
45 | //TODO: check if raising a ratio of pause instructions to loop control instructions |
46 | //(via e.g. loop unrolling) gives any benefit for HT. E.g, the current implementation |
47 | //does about 2 CPU-consuming instructions for every pause instruction. Perhaps for |
48 | //high pause counts it should use an unrolled loop to raise the ratio, and thus free |
49 | //up more integer cycles for the other hyperthread. On the other hand, if the loop is |
50 | //unrolled too far, it won't fit in the core's loop cache, and thus take away |
51 | //instruction decode slots from the other hyperthread. |
52 | |
53 | //TODO: check if use of gcc __builtin_ia32_pause intrinsic gives a "some how" better performing code |
54 | static inline void __TBB_machine_pause( int32_t delay ) { |
55 | for (int32_t i = 0; i < delay; i++) { |
56 | __asm__ __volatile__("pause;" ); |
57 | } |
58 | return; |
59 | } |
60 | #define __TBB_Pause(V) __TBB_machine_pause(V) |
61 | #endif /* !__TBB_Pause */ |
62 | |
63 | // API to retrieve/update FPU control setting |
64 | #ifndef __TBB_CPU_CTL_ENV_PRESENT |
65 | #define __TBB_CPU_CTL_ENV_PRESENT 1 |
66 | |
67 | struct __TBB_cpu_ctl_env_t { |
68 | int mxcsr; |
69 | short x87cw; |
70 | }; |
71 | inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) { |
72 | #if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN |
73 | __TBB_cpu_ctl_env_t loc_ctl; |
74 | __asm__ __volatile__ ( |
75 | "stmxcsr %0\n\t" |
76 | "fstcw %1" |
77 | : "=m" (loc_ctl.mxcsr), "=m" (loc_ctl.x87cw) |
78 | ); |
79 | *ctl = loc_ctl; |
80 | #else |
81 | __asm__ __volatile__ ( |
82 | "stmxcsr %0\n\t" |
83 | "fstcw %1" |
84 | : "=m" (ctl->mxcsr), "=m" (ctl->x87cw) |
85 | ); |
86 | #endif |
87 | } |
88 | inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) { |
89 | __asm__ __volatile__ ( |
90 | "ldmxcsr %0\n\t" |
91 | "fldcw %1" |
92 | : : "m" (ctl->mxcsr), "m" (ctl->x87cw) |
93 | ); |
94 | } |
95 | #endif /* !__TBB_CPU_CTL_ENV_PRESENT */ |
96 | |
97 | #include "gcc_itsx.h" |
98 | |
99 | #endif /* __TBB_machine_gcc_ia32_common_H */ |
100 | |