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,15 +900,107 @@ void cpu_tlb_update_dirty(CPUState *env); | ||
| 900 | void dump_exec_info(FILE *f, | 900 | void dump_exec_info(FILE *f, |
| 901 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | 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 | int64_t val; | 938 | int64_t val; |
| 908 | asm volatile ("rdtsc" : "=A" (val)); | 939 | asm volatile ("rdtsc" : "=A" (val)); |
| 909 | return val; | 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 | extern int64_t kqemu_time, kqemu_time_start; | 1004 | extern int64_t kqemu_time, kqemu_time_start; |
| 913 | extern int64_t qemu_time, qemu_time_start; | 1005 | extern int64_t qemu_time, qemu_time_start; |
| 914 | extern int64_t tlb_flush_time; | 1006 | extern int64_t tlb_flush_time; |