Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
diff libavcodec/ppc/dsputil_altivec.c @ 2:897f711a7157
rearrange to work with autoconf
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 25 Sep 2012 15:55:33 +0200 |
| parents | |
| children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libavcodec/ppc/dsputil_altivec.c Tue Sep 25 15:55:33 2012 +0200 1.3 @@ -0,0 +1,619 @@ 1.4 +/* 1.5 + * Copyright (c) 2002 Brian Foley 1.6 + * Copyright (c) 2002 Dieter Shirley 1.7 + * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org> 1.8 + * 1.9 + * This file is part of FFmpeg. 1.10 + * 1.11 + * FFmpeg is free software; you can redistribute it and/or 1.12 + * modify it under the terms of the GNU Lesser General Public 1.13 + * License as published by the Free Software Foundation; either 1.14 + * version 2.1 of the License, or (at your option) any later version. 1.15 + * 1.16 + * FFmpeg is distributed in the hope that it will be useful, 1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.19 + * Lesser General Public License for more details. 1.20 + * 1.21 + * You should have received a copy of the GNU Lesser General Public 1.22 + * License along with FFmpeg; if not, write to the Free Software 1.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 1.24 + */ 1.25 + 1.26 +#include "config.h" 1.27 +#if HAVE_ALTIVEC_H 1.28 +#include <altivec.h> 1.29 +#endif 1.30 +#include "libavcodec/dsputil.h" 1.31 +#include "dsputil_ppc.h" 1.32 +#include "util_altivec.h" 1.33 +#include "types_altivec.h" 1.34 +#include "dsputil_altivec.h" 1.35 + 1.36 + 1.37 +static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size) 1.38 +{ 1.39 + int i; 1.40 + vector unsigned char perm, bytes, *pixv; 1.41 + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); 1.42 + vector signed short shorts; 1.43 + 1.44 + for (i = 0; i < 8; i++) { 1.45 + // Read potentially unaligned pixels. 1.46 + // We're reading 16 pixels, and actually only want 8, 1.47 + // but we simply ignore the extras. 1.48 + perm = vec_lvsl(0, pixels); 1.49 + pixv = (vector unsigned char *) pixels; 1.50 + bytes = vec_perm(pixv[0], pixv[1], perm); 1.51 + 1.52 + // convert the bytes into shorts 1.53 + shorts = (vector signed short)vec_mergeh(zero, bytes); 1.54 + 1.55 + // save the data to the block, we assume the block is 16-byte aligned 1.56 + vec_st(shorts, i*16, (vector signed short*)block); 1.57 + 1.58 + pixels += line_size; 1.59 + } 1.60 +} 1.61 + 1.62 +static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1, 1.63 + const uint8_t *s2, int stride) 1.64 +{ 1.65 + int i; 1.66 + vector unsigned char perm, bytes, *pixv; 1.67 + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); 1.68 + vector signed short shorts1, shorts2; 1.69 + 1.70 + for (i = 0; i < 4; i++) { 1.71 + // Read potentially unaligned pixels 1.72 + // We're reading 16 pixels, and actually only want 8, 1.73 + // but we simply ignore the extras. 1.74 + perm = vec_lvsl(0, s1); 1.75 + pixv = (vector unsigned char *) s1; 1.76 + bytes = vec_perm(pixv[0], pixv[1], perm); 1.77 + 1.78 + // convert the bytes into shorts 1.79 + shorts1 = (vector signed short)vec_mergeh(zero, bytes); 1.80 + 1.81 + // Do the same for the second block of pixels 1.82 + perm = vec_lvsl(0, s2); 1.83 + pixv = (vector unsigned char *) s2; 1.84 + bytes = vec_perm(pixv[0], pixv[1], perm); 1.85 + 1.86 + // convert the bytes into shorts 1.87 + shorts2 = (vector signed short)vec_mergeh(zero, bytes); 1.88 + 1.89 + // Do the subtraction 1.90 + shorts1 = vec_sub(shorts1, shorts2); 1.91 + 1.92 + // save the data to the block, we assume the block is 16-byte aligned 1.93 + vec_st(shorts1, 0, (vector signed short*)block); 1.94 + 1.95 + s1 += stride; 1.96 + s2 += stride; 1.97 + block += 8; 1.98 + 1.99 + 1.100 + // The code below is a copy of the code above... This is a manual 1.101 + // unroll. 1.102 + 1.103 + // Read potentially unaligned pixels 1.104 + // We're reading 16 pixels, and actually only want 8, 1.105 + // but we simply ignore the extras. 1.106 + perm = vec_lvsl(0, s1); 1.107 + pixv = (vector unsigned char *) s1; 1.108 + bytes = vec_perm(pixv[0], pixv[1], perm); 1.109 + 1.110 + // convert the bytes into shorts 1.111 + shorts1 = (vector signed short)vec_mergeh(zero, bytes); 1.112 + 1.113 + // Do the same for the second block of pixels 1.114 + perm = vec_lvsl(0, s2); 1.115 + pixv = (vector unsigned char *) s2; 1.116 + bytes = vec_perm(pixv[0], pixv[1], perm); 1.117 + 1.118 + // convert the bytes into shorts 1.119 + shorts2 = (vector signed short)vec_mergeh(zero, bytes); 1.120 + 1.121 + // Do the subtraction 1.122 + shorts1 = vec_sub(shorts1, shorts2); 1.123 + 1.124 + // save the data to the block, we assume the block is 16-byte aligned 1.125 + vec_st(shorts1, 0, (vector signed short*)block); 1.126 + 1.127 + s1 += stride; 1.128 + s2 += stride; 1.129 + block += 8; 1.130 + } 1.131 +} 1.132 + 1.133 + 1.134 +static void clear_block_altivec(DCTELEM *block) { 1.135 + LOAD_ZERO; 1.136 + vec_st(zero_s16v, 0, block); 1.137 + vec_st(zero_s16v, 16, block); 1.138 + vec_st(zero_s16v, 32, block); 1.139 + vec_st(zero_s16v, 48, block); 1.140 + vec_st(zero_s16v, 64, block); 1.141 + vec_st(zero_s16v, 80, block); 1.142 + vec_st(zero_s16v, 96, block); 1.143 + vec_st(zero_s16v, 112, block); 1.144 +} 1.145 + 1.146 + 1.147 + 1.148 +/* next one assumes that ((line_size % 16) == 0) */ 1.149 +void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) 1.150 +{ 1.151 +POWERPC_PERF_DECLARE(altivec_put_pixels16_num, 1); 1.152 + register vector unsigned char pixelsv1, pixelsv2; 1.153 + register vector unsigned char pixelsv1B, pixelsv2B; 1.154 + register vector unsigned char pixelsv1C, pixelsv2C; 1.155 + register vector unsigned char pixelsv1D, pixelsv2D; 1.156 + 1.157 + register vector unsigned char perm = vec_lvsl(0, pixels); 1.158 + int i; 1.159 + register int line_size_2 = line_size << 1; 1.160 + register int line_size_3 = line_size + line_size_2; 1.161 + register int line_size_4 = line_size << 2; 1.162 + 1.163 +POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1); 1.164 +// hand-unrolling the loop by 4 gains about 15% 1.165 +// mininum execution time goes from 74 to 60 cycles 1.166 +// it's faster than -funroll-loops, but using 1.167 +// -funroll-loops w/ this is bad - 74 cycles again. 1.168 +// all this is on a 7450, tuning for the 7450 1.169 +#if 0 1.170 + for (i = 0; i < h; i++) { 1.171 + pixelsv1 = vec_ld(0, pixels); 1.172 + pixelsv2 = vec_ld(16, pixels); 1.173 + vec_st(vec_perm(pixelsv1, pixelsv2, perm), 1.174 + 0, block); 1.175 + pixels+=line_size; 1.176 + block +=line_size; 1.177 + } 1.178 +#else 1.179 + for (i = 0; i < h; i += 4) { 1.180 + pixelsv1 = vec_ld( 0, pixels); 1.181 + pixelsv2 = vec_ld(15, pixels); 1.182 + pixelsv1B = vec_ld(line_size, pixels); 1.183 + pixelsv2B = vec_ld(15 + line_size, pixels); 1.184 + pixelsv1C = vec_ld(line_size_2, pixels); 1.185 + pixelsv2C = vec_ld(15 + line_size_2, pixels); 1.186 + pixelsv1D = vec_ld(line_size_3, pixels); 1.187 + pixelsv2D = vec_ld(15 + line_size_3, pixels); 1.188 + vec_st(vec_perm(pixelsv1, pixelsv2, perm), 1.189 + 0, (unsigned char*)block); 1.190 + vec_st(vec_perm(pixelsv1B, pixelsv2B, perm), 1.191 + line_size, (unsigned char*)block); 1.192 + vec_st(vec_perm(pixelsv1C, pixelsv2C, perm), 1.193 + line_size_2, (unsigned char*)block); 1.194 + vec_st(vec_perm(pixelsv1D, pixelsv2D, perm), 1.195 + line_size_3, (unsigned char*)block); 1.196 + pixels+=line_size_4; 1.197 + block +=line_size_4; 1.198 + } 1.199 +#endif 1.200 +POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1); 1.201 +} 1.202 + 1.203 +/* next one assumes that ((line_size % 16) == 0) */ 1.204 +#define op_avg(a,b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) ) 1.205 +void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) 1.206 +{ 1.207 +POWERPC_PERF_DECLARE(altivec_avg_pixels16_num, 1); 1.208 + register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv; 1.209 + register vector unsigned char perm = vec_lvsl(0, pixels); 1.210 + int i; 1.211 + 1.212 +POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1); 1.213 + 1.214 + for (i = 0; i < h; i++) { 1.215 + pixelsv1 = vec_ld( 0, pixels); 1.216 + pixelsv2 = vec_ld(16,pixels); 1.217 + blockv = vec_ld(0, block); 1.218 + pixelsv = vec_perm(pixelsv1, pixelsv2, perm); 1.219 + blockv = vec_avg(blockv,pixelsv); 1.220 + vec_st(blockv, 0, (unsigned char*)block); 1.221 + pixels+=line_size; 1.222 + block +=line_size; 1.223 + } 1.224 + 1.225 +POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1); 1.226 +} 1.227 + 1.228 +/* next one assumes that ((line_size % 8) == 0) */ 1.229 +static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) 1.230 +{ 1.231 +POWERPC_PERF_DECLARE(altivec_avg_pixels8_num, 1); 1.232 + register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv; 1.233 + int i; 1.234 + 1.235 +POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1); 1.236 + 1.237 + for (i = 0; i < h; i++) { 1.238 + /* block is 8 bytes-aligned, so we're either in the 1.239 + left block (16 bytes-aligned) or in the right block (not) */ 1.240 + int rightside = ((unsigned long)block & 0x0000000F); 1.241 + 1.242 + blockv = vec_ld(0, block); 1.243 + pixelsv1 = vec_ld( 0, pixels); 1.244 + pixelsv2 = vec_ld(16, pixels); 1.245 + pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels)); 1.246 + 1.247 + if (rightside) { 1.248 + pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1)); 1.249 + } else { 1.250 + pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3)); 1.251 + } 1.252 + 1.253 + blockv = vec_avg(blockv, pixelsv); 1.254 + 1.255 + vec_st(blockv, 0, block); 1.256 + 1.257 + pixels += line_size; 1.258 + block += line_size; 1.259 + } 1.260 + 1.261 +POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1); 1.262 +} 1.263 + 1.264 +/* next one assumes that ((line_size % 8) == 0) */ 1.265 +static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) 1.266 +{ 1.267 +POWERPC_PERF_DECLARE(altivec_put_pixels8_xy2_num, 1); 1.268 + register int i; 1.269 + register vector unsigned char pixelsv1, pixelsv2, pixelsavg; 1.270 + register vector unsigned char blockv, temp1, temp2; 1.271 + register vector unsigned short pixelssum1, pixelssum2, temp3; 1.272 + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); 1.273 + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); 1.274 + 1.275 + temp1 = vec_ld(0, pixels); 1.276 + temp2 = vec_ld(16, pixels); 1.277 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); 1.278 + if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { 1.279 + pixelsv2 = temp2; 1.280 + } else { 1.281 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); 1.282 + } 1.283 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.284 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.285 + pixelssum1 = vec_add((vector unsigned short)pixelsv1, 1.286 + (vector unsigned short)pixelsv2); 1.287 + pixelssum1 = vec_add(pixelssum1, vctwo); 1.288 + 1.289 +POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1); 1.290 + for (i = 0; i < h ; i++) { 1.291 + int rightside = ((unsigned long)block & 0x0000000F); 1.292 + blockv = vec_ld(0, block); 1.293 + 1.294 + temp1 = vec_ld(line_size, pixels); 1.295 + temp2 = vec_ld(line_size + 16, pixels); 1.296 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); 1.297 + if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { 1.298 + pixelsv2 = temp2; 1.299 + } else { 1.300 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); 1.301 + } 1.302 + 1.303 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.304 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.305 + pixelssum2 = vec_add((vector unsigned short)pixelsv1, 1.306 + (vector unsigned short)pixelsv2); 1.307 + temp3 = vec_add(pixelssum1, pixelssum2); 1.308 + temp3 = vec_sra(temp3, vctwo); 1.309 + pixelssum1 = vec_add(pixelssum2, vctwo); 1.310 + pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); 1.311 + 1.312 + if (rightside) { 1.313 + blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); 1.314 + } else { 1.315 + blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); 1.316 + } 1.317 + 1.318 + vec_st(blockv, 0, block); 1.319 + 1.320 + block += line_size; 1.321 + pixels += line_size; 1.322 + } 1.323 + 1.324 +POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1); 1.325 +} 1.326 + 1.327 +/* next one assumes that ((line_size % 8) == 0) */ 1.328 +static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) 1.329 +{ 1.330 +POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1); 1.331 + register int i; 1.332 + register vector unsigned char pixelsv1, pixelsv2, pixelsavg; 1.333 + register vector unsigned char blockv, temp1, temp2; 1.334 + register vector unsigned short pixelssum1, pixelssum2, temp3; 1.335 + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); 1.336 + register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); 1.337 + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); 1.338 + 1.339 + temp1 = vec_ld(0, pixels); 1.340 + temp2 = vec_ld(16, pixels); 1.341 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); 1.342 + if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { 1.343 + pixelsv2 = temp2; 1.344 + } else { 1.345 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); 1.346 + } 1.347 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.348 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.349 + pixelssum1 = vec_add((vector unsigned short)pixelsv1, 1.350 + (vector unsigned short)pixelsv2); 1.351 + pixelssum1 = vec_add(pixelssum1, vcone); 1.352 + 1.353 +POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); 1.354 + for (i = 0; i < h ; i++) { 1.355 + int rightside = ((unsigned long)block & 0x0000000F); 1.356 + blockv = vec_ld(0, block); 1.357 + 1.358 + temp1 = vec_ld(line_size, pixels); 1.359 + temp2 = vec_ld(line_size + 16, pixels); 1.360 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); 1.361 + if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { 1.362 + pixelsv2 = temp2; 1.363 + } else { 1.364 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); 1.365 + } 1.366 + 1.367 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.368 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.369 + pixelssum2 = vec_add((vector unsigned short)pixelsv1, 1.370 + (vector unsigned short)pixelsv2); 1.371 + temp3 = vec_add(pixelssum1, pixelssum2); 1.372 + temp3 = vec_sra(temp3, vctwo); 1.373 + pixelssum1 = vec_add(pixelssum2, vcone); 1.374 + pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); 1.375 + 1.376 + if (rightside) { 1.377 + blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); 1.378 + } else { 1.379 + blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); 1.380 + } 1.381 + 1.382 + vec_st(blockv, 0, block); 1.383 + 1.384 + block += line_size; 1.385 + pixels += line_size; 1.386 + } 1.387 + 1.388 +POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); 1.389 +} 1.390 + 1.391 +/* next one assumes that ((line_size % 16) == 0) */ 1.392 +static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) 1.393 +{ 1.394 +POWERPC_PERF_DECLARE(altivec_put_pixels16_xy2_num, 1); 1.395 + register int i; 1.396 + register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4; 1.397 + register vector unsigned char blockv, temp1, temp2; 1.398 + register vector unsigned short temp3, temp4, 1.399 + pixelssum1, pixelssum2, pixelssum3, pixelssum4; 1.400 + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); 1.401 + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); 1.402 + 1.403 +POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1); 1.404 + 1.405 + temp1 = vec_ld(0, pixels); 1.406 + temp2 = vec_ld(16, pixels); 1.407 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); 1.408 + if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { 1.409 + pixelsv2 = temp2; 1.410 + } else { 1.411 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); 1.412 + } 1.413 + pixelsv3 = vec_mergel(vczero, pixelsv1); 1.414 + pixelsv4 = vec_mergel(vczero, pixelsv2); 1.415 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.416 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.417 + pixelssum3 = vec_add((vector unsigned short)pixelsv3, 1.418 + (vector unsigned short)pixelsv4); 1.419 + pixelssum3 = vec_add(pixelssum3, vctwo); 1.420 + pixelssum1 = vec_add((vector unsigned short)pixelsv1, 1.421 + (vector unsigned short)pixelsv2); 1.422 + pixelssum1 = vec_add(pixelssum1, vctwo); 1.423 + 1.424 + for (i = 0; i < h ; i++) { 1.425 + blockv = vec_ld(0, block); 1.426 + 1.427 + temp1 = vec_ld(line_size, pixels); 1.428 + temp2 = vec_ld(line_size + 16, pixels); 1.429 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); 1.430 + if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { 1.431 + pixelsv2 = temp2; 1.432 + } else { 1.433 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); 1.434 + } 1.435 + 1.436 + pixelsv3 = vec_mergel(vczero, pixelsv1); 1.437 + pixelsv4 = vec_mergel(vczero, pixelsv2); 1.438 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.439 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.440 + 1.441 + pixelssum4 = vec_add((vector unsigned short)pixelsv3, 1.442 + (vector unsigned short)pixelsv4); 1.443 + pixelssum2 = vec_add((vector unsigned short)pixelsv1, 1.444 + (vector unsigned short)pixelsv2); 1.445 + temp4 = vec_add(pixelssum3, pixelssum4); 1.446 + temp4 = vec_sra(temp4, vctwo); 1.447 + temp3 = vec_add(pixelssum1, pixelssum2); 1.448 + temp3 = vec_sra(temp3, vctwo); 1.449 + 1.450 + pixelssum3 = vec_add(pixelssum4, vctwo); 1.451 + pixelssum1 = vec_add(pixelssum2, vctwo); 1.452 + 1.453 + blockv = vec_packsu(temp3, temp4); 1.454 + 1.455 + vec_st(blockv, 0, block); 1.456 + 1.457 + block += line_size; 1.458 + pixels += line_size; 1.459 + } 1.460 + 1.461 +POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1); 1.462 +} 1.463 + 1.464 +/* next one assumes that ((line_size % 16) == 0) */ 1.465 +static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) 1.466 +{ 1.467 +POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels16_xy2_num, 1); 1.468 + register int i; 1.469 + register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4; 1.470 + register vector unsigned char blockv, temp1, temp2; 1.471 + register vector unsigned short temp3, temp4, 1.472 + pixelssum1, pixelssum2, pixelssum3, pixelssum4; 1.473 + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); 1.474 + register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); 1.475 + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); 1.476 + 1.477 +POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); 1.478 + 1.479 + temp1 = vec_ld(0, pixels); 1.480 + temp2 = vec_ld(16, pixels); 1.481 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); 1.482 + if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { 1.483 + pixelsv2 = temp2; 1.484 + } else { 1.485 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); 1.486 + } 1.487 + pixelsv3 = vec_mergel(vczero, pixelsv1); 1.488 + pixelsv4 = vec_mergel(vczero, pixelsv2); 1.489 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.490 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.491 + pixelssum3 = vec_add((vector unsigned short)pixelsv3, 1.492 + (vector unsigned short)pixelsv4); 1.493 + pixelssum3 = vec_add(pixelssum3, vcone); 1.494 + pixelssum1 = vec_add((vector unsigned short)pixelsv1, 1.495 + (vector unsigned short)pixelsv2); 1.496 + pixelssum1 = vec_add(pixelssum1, vcone); 1.497 + 1.498 + for (i = 0; i < h ; i++) { 1.499 + blockv = vec_ld(0, block); 1.500 + 1.501 + temp1 = vec_ld(line_size, pixels); 1.502 + temp2 = vec_ld(line_size + 16, pixels); 1.503 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); 1.504 + if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { 1.505 + pixelsv2 = temp2; 1.506 + } else { 1.507 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); 1.508 + } 1.509 + 1.510 + pixelsv3 = vec_mergel(vczero, pixelsv1); 1.511 + pixelsv4 = vec_mergel(vczero, pixelsv2); 1.512 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.513 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.514 + 1.515 + pixelssum4 = vec_add((vector unsigned short)pixelsv3, 1.516 + (vector unsigned short)pixelsv4); 1.517 + pixelssum2 = vec_add((vector unsigned short)pixelsv1, 1.518 + (vector unsigned short)pixelsv2); 1.519 + temp4 = vec_add(pixelssum3, pixelssum4); 1.520 + temp4 = vec_sra(temp4, vctwo); 1.521 + temp3 = vec_add(pixelssum1, pixelssum2); 1.522 + temp3 = vec_sra(temp3, vctwo); 1.523 + 1.524 + pixelssum3 = vec_add(pixelssum4, vcone); 1.525 + pixelssum1 = vec_add(pixelssum2, vcone); 1.526 + 1.527 + blockv = vec_packsu(temp3, temp4); 1.528 + 1.529 + vec_st(blockv, 0, block); 1.530 + 1.531 + block += line_size; 1.532 + pixels += line_size; 1.533 + } 1.534 + 1.535 +POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); 1.536 +} 1.537 + 1.538 +/* next one assumes that ((line_size % 8) == 0) */ 1.539 +static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) 1.540 +{ 1.541 +POWERPC_PERF_DECLARE(altivec_avg_pixels8_xy2_num, 1); 1.542 + register int i; 1.543 + register vector unsigned char pixelsv1, pixelsv2, pixelsavg; 1.544 + register vector unsigned char blockv, temp1, temp2, blocktemp; 1.545 + register vector unsigned short pixelssum1, pixelssum2, temp3; 1.546 + 1.547 + register const vector unsigned char vczero = (const vector unsigned char) 1.548 + vec_splat_u8(0); 1.549 + register const vector unsigned short vctwo = (const vector unsigned short) 1.550 + vec_splat_u16(2); 1.551 + 1.552 + temp1 = vec_ld(0, pixels); 1.553 + temp2 = vec_ld(16, pixels); 1.554 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); 1.555 + if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { 1.556 + pixelsv2 = temp2; 1.557 + } else { 1.558 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); 1.559 + } 1.560 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.561 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.562 + pixelssum1 = vec_add((vector unsigned short)pixelsv1, 1.563 + (vector unsigned short)pixelsv2); 1.564 + pixelssum1 = vec_add(pixelssum1, vctwo); 1.565 + 1.566 +POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1); 1.567 + for (i = 0; i < h ; i++) { 1.568 + int rightside = ((unsigned long)block & 0x0000000F); 1.569 + blockv = vec_ld(0, block); 1.570 + 1.571 + temp1 = vec_ld(line_size, pixels); 1.572 + temp2 = vec_ld(line_size + 16, pixels); 1.573 + pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); 1.574 + if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { 1.575 + pixelsv2 = temp2; 1.576 + } else { 1.577 + pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); 1.578 + } 1.579 + 1.580 + pixelsv1 = vec_mergeh(vczero, pixelsv1); 1.581 + pixelsv2 = vec_mergeh(vczero, pixelsv2); 1.582 + pixelssum2 = vec_add((vector unsigned short)pixelsv1, 1.583 + (vector unsigned short)pixelsv2); 1.584 + temp3 = vec_add(pixelssum1, pixelssum2); 1.585 + temp3 = vec_sra(temp3, vctwo); 1.586 + pixelssum1 = vec_add(pixelssum2, vctwo); 1.587 + pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); 1.588 + 1.589 + if (rightside) { 1.590 + blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); 1.591 + } else { 1.592 + blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); 1.593 + } 1.594 + 1.595 + blockv = vec_avg(blocktemp, blockv); 1.596 + vec_st(blockv, 0, block); 1.597 + 1.598 + block += line_size; 1.599 + pixels += line_size; 1.600 + } 1.601 + 1.602 +POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_xy2_num, 1); 1.603 +} 1.604 + 1.605 +void dsputil_init_altivec(DSPContext* c) 1.606 +{ 1.607 + c->diff_pixels = diff_pixels_altivec; 1.608 + c->get_pixels = get_pixels_altivec; 1.609 + c->clear_block = clear_block_altivec; 1.610 + 1.611 + c->put_pixels_tab[0][0] = put_pixels16_altivec; 1.612 + /* the two functions do the same thing, so use the same code */ 1.613 + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_altivec; 1.614 + c->avg_pixels_tab[0][0] = avg_pixels16_altivec; 1.615 + c->avg_pixels_tab[1][0] = avg_pixels8_altivec; 1.616 + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec; 1.617 + c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec; 1.618 + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec; 1.619 + c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec; 1.620 + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec; 1.621 + 1.622 +}
