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