Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
26 | pmbaty | 1 | /* ACC -- Automatic Compiler Configuration |
2 | |||
3 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer |
||
4 | All Rights Reserved. |
||
5 | |||
6 | This software is a copyrighted work licensed under the terms of |
||
7 | the GNU General Public License. Please consult the file "ACC_LICENSE" |
||
8 | for details. |
||
9 | |||
10 | Markus F.X.J. Oberhumer |
||
11 | <markus@oberhumer.com> |
||
12 | http://www.oberhumer.com/ |
||
13 | */ |
||
14 | |||
15 | |||
16 | #define __ACCLIB_RDTSC_CH_INCLUDED 1 |
||
17 | #if !defined(ACCLIB_PUBLIC) |
||
18 | # define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f) |
||
19 | #endif |
||
20 | |||
21 | #if defined(acc_int32e_t) |
||
22 | |||
23 | |||
24 | #if ((ACC_ARCH_AMD64 || ACC_ARCH_IA32) && ACC_CC_GNUC) |
||
25 | # if (ACC_CC_GNUC >= 0x020000ul) |
||
26 | # define __ACCLIB_RDTSC_REGS : : "r" (t) : "cc", "memory", "eax", "edx" |
||
27 | # else |
||
28 | # define __ACCLIB_RDTSC_REGS : : "r" (t) : "ax", "dx" |
||
29 | # endif |
||
30 | #elif (ACC_ARCH_IA32 && ACC_CC_INTELC) && defined(__linux__) |
||
31 | # define __ACCLIB_RDTSC_REGS : : "r" (t) : "memory", "eax", "edx" |
||
32 | #endif |
||
33 | |||
34 | |||
35 | /************************************************************************* |
||
36 | // read TSC |
||
37 | **************************************************************************/ |
||
38 | |||
39 | ACCLIB_PUBLIC(int, acc_tsc_read) (acc_uint32e_t* t) |
||
40 | { |
||
41 | #if (ACC_ARCH_AMD64 || ACC_ARCH_IA32) && defined(__ACCLIB_RDTSC_REGS) |
||
42 | __asm__ __volatile__( |
||
43 | "clc \n" ".byte 0x0f, 0x31\n" |
||
44 | "movl %%eax,(%0)\n" "movl %%edx,4(%0)\n" |
||
45 | __ACCLIB_RDTSC_REGS |
||
46 | ); |
||
47 | return 0; |
||
48 | #elif (ACC_ARCH_IA32 && (ACC_OS_DOS32 || ACC_OS_WIN32) && (ACC_CC_DMC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_PELLESC)) |
||
49 | ACC_UNUSED(t); |
||
50 | __asm { |
||
51 | mov ecx, t |
||
52 | clc |
||
53 | # if (ACC_CC_MSC && (_MSC_VER < 1200)) |
||
54 | _emit 0x0f |
||
55 | _emit 0x31 |
||
56 | # else |
||
57 | rdtsc |
||
58 | # endif |
||
59 | mov [ecx], eax |
||
60 | mov [ecx+4], edx |
||
61 | } |
||
62 | return 0; |
||
63 | #else |
||
64 | t[0] = t[1] = 0; |
||
65 | return -1; |
||
66 | #endif |
||
67 | } |
||
68 | |||
69 | |||
70 | /************************************************************************* |
||
71 | // read and add TSC |
||
72 | **************************************************************************/ |
||
73 | |||
74 | ACCLIB_PUBLIC(int, acc_tsc_read_add) (acc_uint32e_t* t) |
||
75 | { |
||
76 | #if (ACC_ARCH_AMD64 || ACC_ARCH_IA32) && defined(__ACCLIB_RDTSC_REGS) |
||
77 | __asm__ __volatile__( |
||
78 | "clc \n" ".byte 0x0f, 0x31\n" |
||
79 | "addl %%eax,(%0)\n" "adcl $0,%%edx\n" "addl %%edx,4(%0)\n" |
||
80 | __ACCLIB_RDTSC_REGS |
||
81 | ); |
||
82 | return 0; |
||
83 | #elif (ACC_ARCH_IA32 && (ACC_OS_DOS32 || ACC_OS_WIN32) && (ACC_CC_DMC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_PELLESC)) |
||
84 | ACC_UNUSED(t); |
||
85 | __asm { |
||
86 | mov ecx, t |
||
87 | clc |
||
88 | # if (ACC_CC_MSC && (_MSC_VER < 1200)) |
||
89 | _emit 0x0f |
||
90 | _emit 0x31 |
||
91 | # else |
||
92 | rdtsc |
||
93 | # endif |
||
94 | add [ecx], eax |
||
95 | adc edx, 0 |
||
96 | add [ecx+4], edx |
||
97 | } |
||
98 | return 0; |
||
99 | #else |
||
100 | acc_uint32e_t v[2]; |
||
101 | int r; |
||
102 | r = acc_tsc_read(v); |
||
103 | t[0] += v[0]; |
||
104 | if (t[0] < v[0]) t[1] += 1; |
||
105 | t[1] += v[1]; |
||
106 | return r; |
||
107 | #endif |
||
108 | } |
||
109 | |||
110 | |||
111 | #endif /* defined(acc_int32e_t) */ |
||
112 | |||
113 | |||
114 | /* |
||
115 | vi:ts=4:et |
||
116 | */ |