HLE: Merge HLE BIOS improvements from upstream
[pcsx_rearmed.git] / include / pcnt.h
1
2 enum pcounters {
3         PCNT_ALL,
4         PCNT_GPU,
5         PCNT_SPU,
6         PCNT_BLIT,
7         PCNT_GTE,
8         PCNT_TEST,
9         PCNT_CNT
10 };
11
12 #ifdef PCNT
13
14 #if defined(__ARM_ARCH_7A__) || defined(ARM1176)
15 #define PCNT_DIV 1000
16 #else
17 #include <sys/time.h>
18 #define PCNT_DIV 1
19 #endif
20
21 static const char *pcnt_names[PCNT_CNT] = { "", "gpu", "spu", "blit", "gte", "test" };
22
23 #define PCNT_FRAMES 10
24
25 extern unsigned int pcounters[PCNT_CNT];
26 extern unsigned int pcounter_starts[PCNT_CNT];
27
28 #define pcnt_start(id) \
29         pcounter_starts[id] = pcnt_get()
30
31 #define pcnt_end(id) \
32         pcounters[id] += pcnt_get() - pcounter_starts[id]
33
34 void pcnt_hook_plugins(void);
35
36 static inline void pcnt_print(float fps)
37 {
38         static int print_counter;
39         unsigned int total, rem;
40         int i;
41
42         for (i = 0; i < PCNT_CNT; i++)
43                 pcounters[i] /= PCNT_DIV * PCNT_FRAMES;
44
45         rem = total = pcounters[PCNT_ALL];
46         for (i = 1; i < PCNT_CNT; i++)
47                 rem -= pcounters[i];
48         if (!total)
49                 total++;
50
51         if (--print_counter < 0) {
52                 printf("     ");
53                 for (i = 1; i < PCNT_CNT; i++)
54                         printf("%5s ", pcnt_names[i]);
55                 printf("%5s\n", "rem");
56                 print_counter = 30;
57         }
58
59         printf("%4.1f ", fps);
60 #if 0
61         static float pcounters_all[PCNT_CNT+1];
62         static int pcounter_samples;
63         pcounter_samples++;
64
65         for (i = 1; i < PCNT_CNT; i++) {
66                 pcounters_all[i] += pcounters[i];
67                 printf("%5.0f ", pcounters_all[i] / pcounter_samples);
68         }
69         pcounters_all[i] += rem;
70         printf("%5.0f\n", pcounters_all[i] / pcounter_samples);
71 #else
72         for (i = 1; i < PCNT_CNT; i++)
73                 printf("%5u ", pcounters[i]);
74         printf("%5u (", rem);
75         for (i = 1; i < PCNT_CNT; i++)
76                 printf("%2u ", pcounters[i] * 100 / total);
77         printf("%2u) %u\n", rem * 100 / total, total);
78 #endif
79         memset(pcounters, 0, sizeof(pcounters));
80 }
81
82 static inline unsigned int pcnt_get(void)
83 {
84         unsigned int val;
85 #ifdef __ARM_ARCH_7A__
86         __asm__ volatile("mrc p15, 0, %0, c9, c13, 0"
87                          : "=r"(val));
88 #elif defined(ARM1176)
89         __asm__ volatile("mrc p15, 0, %0, c15, c12, 1"
90                          : "=r"(val));
91 #else
92         // all slow on ARM :(
93         //struct timespec tv;
94         //clock_gettime(CLOCK_MONOTONIC_RAW, &tv);
95         //val = tv.tv_sec * 1000000000 + tv.tv_nsec;
96         struct timeval tv;
97         gettimeofday(&tv, NULL);
98         val = tv.tv_sec * 1000000 + tv.tv_usec;
99 #endif
100         return val;
101 }
102
103 static inline void pcnt_init(void)
104 {
105 #ifdef __ARM_ARCH_7A__
106         int v;
107         asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(v));
108         v |= 5; // master enable, ccnt reset
109         v &= ~8; // ccnt divider 0
110         asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(v));
111         // enable cycle counter
112         asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(1<<31));
113 #elif defined(ARM1176)
114         int v;
115         asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(v));
116         v |= 5; // master enable, ccnt reset
117         v &= ~8; // ccnt divider 0
118         asm volatile("mcr p15, 0, %0, c15, c12, 0" :: "r"(v));
119 #endif
120 }
121
122 void pcnt_gte_start(int op);
123 void pcnt_gte_end(int op);
124
125 #else
126
127 #define pcnt_start(id)
128 #define pcnt_end(id)
129 #define pcnt_hook_plugins()
130 #define pcnt_print(fps)
131
132 #endif