PPC fixes & clean-up patch by (Romain Dolbeau <dolbeau at irisa dot fr>)
[libav.git] / libavcodec / ppc / dsputil_ppc.h
CommitLineData
35e5fb06
RD
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
3efd4952
RD
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
35e5fb06
RD
33#ifdef POWERPC_TBL_PERFORMANCE_REPORT
34void powerpc_display_perf_report(void);
35/* if you add to the enum below, also add to the perfname array
36 in dsputil_ppc.c */
37enum 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,
35e5fb06
RD
43 altivec_put_pixels16_num,
44 altivec_avg_pixels16_num,
45 altivec_avg_pixels8_num,
46 altivec_put_pixels8_xy2_num,
fe50f385
RD
47 altivec_put_no_rnd_pixels8_xy2_num,
48 altivec_put_pixels16_xy2_num,
49 altivec_put_no_rnd_pixels16_xy2_num,
35e5fb06 50 powerpc_clear_blocks_dcbz32,
a4adb608 51 powerpc_clear_blocks_dcbz128,
35e5fb06
RD
52 powerpc_perf_total
53};
54enum 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};
61extern unsigned long long perfdata[powerpc_perf_total][powerpc_data_total];
62#ifdef POWERPC_PERF_USE_PMC
3efd4952
RD
63extern unsigned long long perfdata_pmc2[powerpc_perf_total][powerpc_data_total];
64extern unsigned long long perfdata_pmc3[powerpc_perf_total][powerpc_data_total];
35e5fb06
RD
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))
3efd4952
RD
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)
35e5fb06
RD
97#define POWERPC_TBL_STOP_COUNT(a, cond) do { \
98 POWERPC_GET_CYCLES(cycles_stop); \
3efd4952
RD
99 POWERPC_GET_PMC2(pmc2_stop); \
100 POWERPC_GET_PMC3(pmc3_stop); \
35e5fb06
RD
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 } \
3efd4952
RD
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) \
35e5fb06
RD
130 { \
131 unsigned long diff = \
3efd4952 132 pmc3_stop - pmc3_start; \
35e5fb06
RD
133 if (cond) \
134 { \
3efd4952
RD
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] ++; \
35e5fb06
RD
141 } \
142 } \
143} while (0)
144
145#endif /* POWERPC_PERF_USE_PMC */
146
147
148#else /* POWERPC_TBL_PERFORMANCE_REPORT */
475b46da
MN
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)
35e5fb06
RD
153#endif /* POWERPC_TBL_PERFORMANCE_REPORT */
154
155#endif /* _DSPUTIL_PPC_ */