~ubuntu-branches/ubuntu/utopic/libav/utopic-proposed

« back to all changes in this revision

Viewing changes to libavcodec/ppc/dsputil_ppc.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler, Reinhard Tartler, Rico Tzschichholz
  • Date: 2014-08-30 11:02:45 UTC
  • mfrom: (1.3.47 sid)
  • Revision ID: package-import@ubuntu.com-20140830110245-io3dg7q85wfr7125
Tags: 6:11~beta1-2
[ Reinhard Tartler ]
* Make libavcodec-dev depend on libavresample-dev

[ Rico Tzschichholz ]
* Some fixes and leftovers from soname bumps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2002 Brian Foley
3
 
 * Copyright (c) 2002 Dieter Shirley
4
 
 * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
5
 
 *
6
 
 * This file is part of Libav.
7
 
 *
8
 
 * Libav is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public
10
 
 * License as published by the Free Software Foundation; either
11
 
 * version 2.1 of the License, or (at your option) any later version.
12
 
 *
13
 
 * Libav is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with Libav; if not, write to the Free Software
20
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 
 */
22
 
 
23
 
#include <string.h>
24
 
 
25
 
#include "libavutil/attributes.h"
26
 
#include "libavutil/cpu.h"
27
 
#include "libavutil/mem.h"
28
 
#include "libavutil/ppc/cpu.h"
29
 
#include "dsputil_altivec.h"
30
 
 
31
 
/* ***** WARNING ***** WARNING ***** WARNING ***** */
32
 
/*
33
 
clear_blocks_dcbz32_ppc will not work properly on PowerPC processors with a
34
 
cache line size not equal to 32 bytes.
35
 
Fortunately all processor used by Apple up to at least the 7450 (aka second
36
 
generation G4) use 32 bytes cache line.
37
 
This is due to the use of the 'dcbz' instruction. It simply clear to zero a
38
 
single cache line, so you need to know the cache line size to use it !
39
 
It's absurd, but it's fast...
40
 
 
41
 
update 24/06/2003 : Apple released yesterday the G5, with a PPC970. cache line
42
 
size: 128 bytes. Oups.
43
 
The semantic of dcbz was changed, it always clear 32 bytes. so the function
44
 
below will work, but will be slow. So I fixed check_dcbz_effect to use dcbzl,
45
 
which is defined to clear a cache line (as dcbz before). So we still can
46
 
distinguish, and use dcbz (32 bytes) or dcbzl (one cache line) as required.
47
 
 
48
 
see <http://developer.apple.com/technotes/tn/tn2087.html>
49
 
and <http://developer.apple.com/technotes/tn/tn2086.html>
50
 
*/
51
 
static void clear_blocks_dcbz32_ppc(int16_t *blocks)
52
 
{
53
 
    register int misal = ((unsigned long)blocks & 0x00000010);
54
 
    register int i = 0;
55
 
    if (misal) {
56
 
        ((unsigned long*)blocks)[0] = 0L;
57
 
        ((unsigned long*)blocks)[1] = 0L;
58
 
        ((unsigned long*)blocks)[2] = 0L;
59
 
        ((unsigned long*)blocks)[3] = 0L;
60
 
        i += 16;
61
 
    }
62
 
    for ( ; i < sizeof(int16_t)*6*64-31 ; i += 32) {
63
 
        __asm__ volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory");
64
 
    }
65
 
    if (misal) {
66
 
        ((unsigned long*)blocks)[188] = 0L;
67
 
        ((unsigned long*)blocks)[189] = 0L;
68
 
        ((unsigned long*)blocks)[190] = 0L;
69
 
        ((unsigned long*)blocks)[191] = 0L;
70
 
        i += 16;
71
 
    }
72
 
}
73
 
 
74
 
/* same as above, when dcbzl clear a whole 128B cache line
75
 
   i.e. the PPC970 aka G5 */
76
 
#if HAVE_DCBZL
77
 
static void clear_blocks_dcbz128_ppc(int16_t *blocks)
78
 
{
79
 
    register int misal = ((unsigned long)blocks & 0x0000007f);
80
 
    register int i = 0;
81
 
    if (misal) {
82
 
        // we could probably also optimize this case,
83
 
        // but there's not much point as the machines
84
 
        // aren't available yet (2003-06-26)
85
 
        memset(blocks, 0, sizeof(int16_t)*6*64);
86
 
    }
87
 
    else
88
 
        for ( ; i < sizeof(int16_t)*6*64 ; i += 128) {
89
 
            __asm__ volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory");
90
 
        }
91
 
}
92
 
#else
93
 
static void clear_blocks_dcbz128_ppc(int16_t *blocks)
94
 
{
95
 
    memset(blocks, 0, sizeof(int16_t)*6*64);
96
 
}
97
 
#endif
98
 
 
99
 
#if HAVE_DCBZL
100
 
/* check dcbz report how many bytes are set to 0 by dcbz */
101
 
/* update 24/06/2003 : replace dcbz by dcbzl to get
102
 
   the intended effect (Apple "fixed" dcbz)
103
 
   unfortunately this cannot be used unless the assembler
104
 
   knows about dcbzl ... */
105
 
static long check_dcbzl_effect(void)
106
 
{
107
 
    register char *fakedata = av_malloc(1024);
108
 
    register char *fakedata_middle;
109
 
    register long zero = 0;
110
 
    register long i = 0;
111
 
    long count = 0;
112
 
 
113
 
    if (!fakedata) {
114
 
        return 0L;
115
 
    }
116
 
 
117
 
    fakedata_middle = (fakedata + 512);
118
 
 
119
 
    memset(fakedata, 0xFF, 1024);
120
 
 
121
 
    /* below the constraint "b" seems to mean "Address base register"
122
 
       in gcc-3.3 / RS/6000 speaks. seems to avoid using r0, so.... */
123
 
    __asm__ volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero));
124
 
 
125
 
    for (i = 0; i < 1024 ; i ++) {
126
 
        if (fakedata[i] == (char)0)
127
 
            count++;
128
 
    }
129
 
 
130
 
    av_free(fakedata);
131
 
 
132
 
    return count;
133
 
}
134
 
#else
135
 
static long check_dcbzl_effect(void)
136
 
{
137
 
  return 0;
138
 
}
139
 
#endif
140
 
 
141
 
av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx)
142
 
{
143
 
    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
144
 
 
145
 
    // Common optimizations whether AltiVec is available or not
146
 
    if (!high_bit_depth) {
147
 
    switch (check_dcbzl_effect()) {
148
 
        case 32:
149
 
            c->clear_blocks = clear_blocks_dcbz32_ppc;
150
 
            break;
151
 
        case 128:
152
 
            c->clear_blocks = clear_blocks_dcbz128_ppc;
153
 
            break;
154
 
        default:
155
 
            break;
156
 
    }
157
 
    }
158
 
 
159
 
    if (PPC_ALTIVEC(av_get_cpu_flags())) {
160
 
        ff_dsputil_init_altivec(c, avctx);
161
 
        ff_int_init_altivec(c, avctx);
162
 
        c->gmc1 = ff_gmc1_altivec;
163
 
 
164
 
#if CONFIG_ENCODERS
165
 
        if (avctx->bits_per_raw_sample <= 8 &&
166
 
            (avctx->dct_algo == FF_DCT_AUTO ||
167
 
             avctx->dct_algo == FF_DCT_ALTIVEC)) {
168
 
            c->fdct = ff_fdct_altivec;
169
 
        }
170
 
#endif //CONFIG_ENCODERS
171
 
 
172
 
        if (avctx->bits_per_raw_sample <= 8) {
173
 
            if ((avctx->idct_algo == FF_IDCT_AUTO) ||
174
 
                (avctx->idct_algo == FF_IDCT_ALTIVEC)) {
175
 
                c->idct_put = ff_idct_put_altivec;
176
 
                c->idct_add = ff_idct_add_altivec;
177
 
                c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
178
 
            }
179
 
        }
180
 
 
181
 
    }
182
 
}