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; | ... | ... |