re-import all libretro code from it's fork
[picodrive.git] / platform / linux / pprof.h
1 #ifndef __PPROF_H__
2 #define __PPROF_H__
3
4 enum pprof_points {
5   pp_main,
6   pp_frame,
7   pp_draw,
8   pp_sound,
9   pp_m68k,
10   pp_z80,
11   pp_msh2,
12   pp_ssh2,
13   pp_dummy,
14   pp_total_points
15 };
16
17 struct pp_counters
18 {
19         unsigned long long counter[pp_total_points];
20 };
21
22 extern struct pp_counters *pp_counters;
23
24 #ifdef __i386__
25 static __attribute__((always_inline)) inline unsigned int pprof_get_one(void)
26 {
27   unsigned long long ret;
28   __asm__ __volatile__ ("rdtsc" : "=A" (ret));
29   return (unsigned int)ret;
30 }
31 #define unglitch_timer(x)
32
33 #elif defined(__GP2X__)
34 // XXX: MMSP2 only, timer sometimes seems to return lower vals?
35 extern volatile unsigned long *gp2x_memregl;
36 #define pprof_get_one() (unsigned int)gp2x_memregl[0x0a00 >> 2]
37 #define unglitch_timer(di) \
38   if ((signed int)(di) < 0) di = 0
39
40 #else
41 #error no timer
42 #endif
43
44 #define pprof_start(point) { \
45     unsigned int pp_start_##point = pprof_get_one()
46
47 #define pprof_end(point) \
48     { \
49       unsigned int di = pprof_get_one() - pp_start_##point; \
50       unglitch_timer(di); \
51       pp_counters->counter[pp_##point] += di; \
52     } \
53   }
54
55 // subtract for recursive stuff
56 #define pprof_end_sub(point) \
57     { \
58       unsigned int di = pprof_get_one() - pp_start_##point; \
59       unglitch_timer(di); \
60       pp_counters->counter[pp_##point] -= di; \
61     } \
62   }
63
64 extern void pprof_init(void);
65 extern void pprof_finish(void);
66
67 #endif // __PPROF_H__