PPC fixes & clean-up patch by (Romain Dolbeau <dolbeau at irisa dot fr>)
[libav.git] / libavcodec / ppc / dsputil_ppc.h
1 /*
2 * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifndef _DSPUTIL_PPC_
20 #define _DSPUTIL_PPC_
21
22 #ifdef CONFIG_DARWIN
23 /* The Apple assembler shipped w/ gcc-3.3 knows about DCBZL, previous assemblers don't
24 We assume here that the Darwin GCC is from Apple.... */
25 #if (__GNUC__ * 100 + __GNUC_MINOR__ < 303)
26 #define NO_DCBZL
27 #endif
28 #else /* CONFIG_DARWIN */
29 /* I don't think any non-Apple assembler knows about DCBZL */
30 #define NO_DCBZL
31 #endif /* CONFIG_DARWIN */
32
33 #ifdef POWERPC_TBL_PERFORMANCE_REPORT
34 void powerpc_display_perf_report(void);
35 /* if you add to the enum below, also add to the perfname array
36 in dsputil_ppc.c */
37 enum powerpc_perf_index {
38 altivec_fft_num = 0,
39 altivec_gmc1_num,
40 altivec_dct_unquantize_h263_num,
41 altivec_idct_add_num,
42 altivec_idct_put_num,
43 altivec_put_pixels16_num,
44 altivec_avg_pixels16_num,
45 altivec_avg_pixels8_num,
46 altivec_put_pixels8_xy2_num,
47 altivec_put_no_rnd_pixels8_xy2_num,
48 altivec_put_pixels16_xy2_num,
49 altivec_put_no_rnd_pixels16_xy2_num,
50 powerpc_clear_blocks_dcbz32,
51 powerpc_clear_blocks_dcbz128,
52 powerpc_perf_total
53 };
54 enum powerpc_data_index {
55 powerpc_data_min = 0,
56 powerpc_data_max,
57 powerpc_data_sum,
58 powerpc_data_num,
59 powerpc_data_total
60 };
61 extern unsigned long long perfdata[powerpc_perf_total][powerpc_data_total];
62 #ifdef POWERPC_PERF_USE_PMC
63 extern unsigned long long perfdata_pmc2[powerpc_perf_total][powerpc_data_total];
64 extern unsigned long long perfdata_pmc3[powerpc_perf_total][powerpc_data_total];
65 #endif
66
67 #ifndef POWERPC_PERF_USE_PMC
68 #define POWERPC_GET_CYCLES(a) asm volatile("mftb %0" : "=r" (a))
69 #define POWERPC_TBL_DECLARE(a, cond) register unsigned long tbl_start, tbl_stop
70 #define POWERPC_TBL_START_COUNT(a, cond) do { POWERPC_GET_CYCLES(tbl_start); } while (0)
71 #define POWERPC_TBL_STOP_COUNT(a, cond) do { \
72 POWERPC_GET_CYCLES(tbl_stop); \
73 if (tbl_stop > tbl_start) \
74 { \
75 unsigned long diff = tbl_stop - tbl_start; \
76 if (cond) \
77 { \
78 if (diff < perfdata[a][powerpc_data_min]) \
79 perfdata[a][powerpc_data_min] = diff; \
80 if (diff > perfdata[a][powerpc_data_max]) \
81 perfdata[a][powerpc_data_max] = diff; \
82 perfdata[a][powerpc_data_sum] += diff; \
83 perfdata[a][powerpc_data_num] ++; \
84 } \
85 } \
86 } while (0)
87
88 #else /* POWERPC_PERF_USE_PMC */
89 #define POWERPC_GET_CYCLES(a) asm volatile("mfspr %0, 937" : "=r" (a))
90 #define POWERPC_GET_PMC2(a) asm volatile("mfspr %0, 938" : "=r" (a))
91 #define POWERPC_GET_PMC3(a) asm volatile("mfspr %0, 941" : "=r" (a))
92 #define POWERPC_TBL_DECLARE(a, cond) register unsigned long cycles_start, cycles_stop, pmc2_start, pmc2_stop, pmc3_start, pmc3_stop
93 #define POWERPC_TBL_START_COUNT(a, cond) do { \
94 POWERPC_GET_PMC3(pmc3_start); \
95 POWERPC_GET_PMC2(pmc2_start); \
96 POWERPC_GET_CYCLES(cycles_start); } while (0)
97 #define POWERPC_TBL_STOP_COUNT(a, cond) do { \
98 POWERPC_GET_CYCLES(cycles_stop); \
99 POWERPC_GET_PMC2(pmc2_stop); \
100 POWERPC_GET_PMC3(pmc3_stop); \
101 if (cycles_stop >= cycles_start) \
102 { \
103 unsigned long diff = \
104 cycles_stop - cycles_start; \
105 if (cond) \
106 { \
107 if (diff < perfdata[a][powerpc_data_min]) \
108 perfdata[a][powerpc_data_min] = diff; \
109 if (diff > perfdata[a][powerpc_data_max]) \
110 perfdata[a][powerpc_data_max] = diff; \
111 perfdata[a][powerpc_data_sum] += diff; \
112 perfdata[a][powerpc_data_num] ++; \
113 } \
114 } \
115 if (pmc2_stop >= pmc2_start) \
116 { \
117 unsigned long diff = \
118 pmc2_stop - pmc2_start; \
119 if (cond) \
120 { \
121 if (diff < perfdata_pmc2[a][powerpc_data_min]) \
122 perfdata_pmc2[a][powerpc_data_min] = diff; \
123 if (diff > perfdata_pmc2[a][powerpc_data_max]) \
124 perfdata_pmc2[a][powerpc_data_max] = diff; \
125 perfdata_pmc2[a][powerpc_data_sum] += diff; \
126 perfdata_pmc2[a][powerpc_data_num] ++; \
127 } \
128 } \
129 if (pmc3_stop >= pmc3_start) \
130 { \
131 unsigned long diff = \
132 pmc3_stop - pmc3_start; \
133 if (cond) \
134 { \
135 if (diff < perfdata_pmc3[a][powerpc_data_min]) \
136 perfdata_pmc3[a][powerpc_data_min] = diff; \
137 if (diff > perfdata_pmc3[a][powerpc_data_max]) \
138 perfdata_pmc3[a][powerpc_data_max] = diff; \
139 perfdata_pmc3[a][powerpc_data_sum] += diff; \
140 perfdata_pmc3[a][powerpc_data_num] ++; \
141 } \
142 } \
143 } while (0)
144
145 #endif /* POWERPC_PERF_USE_PMC */
146
147
148 #else /* POWERPC_TBL_PERFORMANCE_REPORT */
149 // those are needed to avoid empty statements.
150 #define POWERPC_TBL_DECLARE(a, cond) int altivec_placeholder __attribute__ ((unused))
151 #define POWERPC_TBL_START_COUNT(a, cond) do {} while (0)
152 #define POWERPC_TBL_STOP_COUNT(a, cond) do {} while (0)
153 #endif /* POWERPC_TBL_PERFORMANCE_REPORT */
154
155 #endif /* _DSPUTIL_PPC_ */