Commit effedbc915c51bf2f65818960671fef2bf8c54cf
1 parent
9f909fef
export cpu_get_real_ticks()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2048 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
95 additions
and
3 deletions
cpu-all.h
| ... | ... | @@ -900,15 +900,107 @@ void cpu_tlb_update_dirty(CPUState *env); |
| 900 | 900 | void dump_exec_info(FILE *f, |
| 901 | 901 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
| 902 | 902 | |
| 903 | -/* profiling */ | |
| 904 | -#ifdef CONFIG_PROFILER | |
| 905 | -static inline int64_t profile_getclock(void) | |
| 903 | +/*******************************************/ | |
| 904 | +/* host CPU ticks (if available) */ | |
| 905 | + | |
| 906 | +#if defined(__powerpc__) | |
| 907 | + | |
| 908 | +static inline uint32_t get_tbl(void) | |
| 909 | +{ | |
| 910 | + uint32_t tbl; | |
| 911 | + asm volatile("mftb %0" : "=r" (tbl)); | |
| 912 | + return tbl; | |
| 913 | +} | |
| 914 | + | |
| 915 | +static inline uint32_t get_tbu(void) | |
| 916 | +{ | |
| 917 | + uint32_t tbl; | |
| 918 | + asm volatile("mftbu %0" : "=r" (tbl)); | |
| 919 | + return tbl; | |
| 920 | +} | |
| 921 | + | |
| 922 | +static inline int64_t cpu_get_real_ticks(void) | |
| 923 | +{ | |
| 924 | + uint32_t l, h, h1; | |
| 925 | + /* NOTE: we test if wrapping has occurred */ | |
| 926 | + do { | |
| 927 | + h = get_tbu(); | |
| 928 | + l = get_tbl(); | |
| 929 | + h1 = get_tbu(); | |
| 930 | + } while (h != h1); | |
| 931 | + return ((int64_t)h << 32) | l; | |
| 932 | +} | |
| 933 | + | |
| 934 | +#elif defined(__i386__) | |
| 935 | + | |
| 936 | +static inline int64_t cpu_get_real_ticks(void) | |
| 906 | 937 | { |
| 907 | 938 | int64_t val; |
| 908 | 939 | asm volatile ("rdtsc" : "=A" (val)); |
| 909 | 940 | return val; |
| 910 | 941 | } |
| 911 | 942 | |
| 943 | +#elif defined(__x86_64__) | |
| 944 | + | |
| 945 | +static inline int64_t cpu_get_real_ticks(void) | |
| 946 | +{ | |
| 947 | + uint32_t low,high; | |
| 948 | + int64_t val; | |
| 949 | + asm volatile("rdtsc" : "=a" (low), "=d" (high)); | |
| 950 | + val = high; | |
| 951 | + val <<= 32; | |
| 952 | + val |= low; | |
| 953 | + return val; | |
| 954 | +} | |
| 955 | + | |
| 956 | +#elif defined(__ia64) | |
| 957 | + | |
| 958 | +static inline int64_t cpu_get_real_ticks(void) | |
| 959 | +{ | |
| 960 | + int64_t val; | |
| 961 | + asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory"); | |
| 962 | + return val; | |
| 963 | +} | |
| 964 | + | |
| 965 | +#elif defined(__s390__) | |
| 966 | + | |
| 967 | +static inline int64_t cpu_get_real_ticks(void) | |
| 968 | +{ | |
| 969 | + int64_t val; | |
| 970 | + asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc"); | |
| 971 | + return val; | |
| 972 | +} | |
| 973 | + | |
| 974 | +#elif defined(__sparc__) && defined(HOST_SOLARIS) | |
| 975 | + | |
| 976 | +static inline int64_t cpu_get_real_ticks (void) | |
| 977 | +{ | |
| 978 | +#if defined(_LP64) | |
| 979 | + uint64_t rval; | |
| 980 | + asm volatile("rd %%tick,%0" : "=r"(rval)); | |
| 981 | + return rval; | |
| 982 | +#else | |
| 983 | + union { | |
| 984 | + uint64_t i64; | |
| 985 | + struct { | |
| 986 | + uint32_t high; | |
| 987 | + uint32_t low; | |
| 988 | + } i32; | |
| 989 | + } rval; | |
| 990 | + asm volatile("rd %%tick,%1; srlx %1,32,%0" | |
| 991 | + : "=r"(rval.i32.high), "=r"(rval.i32.low)); | |
| 992 | + return rval.i64; | |
| 993 | +#endif | |
| 994 | +} | |
| 995 | +#endif | |
| 996 | + | |
| 997 | +/* profiling */ | |
| 998 | +#ifdef CONFIG_PROFILER | |
| 999 | +static inline int64_t profile_getclock(void) | |
| 1000 | +{ | |
| 1001 | + return cpu_get_real_ticks(); | |
| 1002 | +} | |
| 1003 | + | |
| 912 | 1004 | extern int64_t kqemu_time, kqemu_time_start; |
| 913 | 1005 | extern int64_t qemu_time, qemu_time_start; |
| 914 | 1006 | extern int64_t tlb_flush_time; | ... | ... |