Blame src/libmpg123/dct64_altivec.c

Packit c32a2d
/*
Packit c32a2d
	dct64_altivec.c: Discrete Cosine Tansform (DCT) for Altivec
Packit c32a2d
Packit c32a2d
	copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
Packit c32a2d
	see COPYING and AUTHORS files in distribution or http://mpg123.org
Packit c32a2d
	initially written by Michael Hipp
Packit c32a2d
	altivec optimization by tmkk
Packit c32a2d
*/
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
 * Discrete Cosine Tansform (DCT) for subband synthesis
Packit c32a2d
 *
Packit c32a2d
 * -funroll-loops (for gcc) will remove the loops for better performance
Packit c32a2d
 * using loops in the source-code enhances readabillity
Packit c32a2d
 *
Packit c32a2d
 *
Packit c32a2d
 * TODO: write an optimized version for the down-sampling modes
Packit c32a2d
 *       (in these modes the bands 16-31 (2:1) or 8-31 (4:1) are zero 
Packit c32a2d
 */
Packit c32a2d
Packit c32a2d
#include "mpg123lib_intern.h"
Packit c32a2d
Packit c32a2d
#ifndef __APPLE__
Packit c32a2d
#include <altivec.h>
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
void dct64_altivec(real *out0,real *out1,real *samples)
Packit c32a2d
{
Packit c32a2d
  ALIGNED(16) real bufs[32];
Packit c32a2d
Packit c32a2d
	{
Packit c32a2d
		register real *b1,*costab;
Packit c32a2d
		
Packit c32a2d
		vector unsigned char vinvert,vperm1,vperm2,vperm3,vperm4;
Packit c32a2d
		vector float v1,v2,v3,v4,v5,v6,v7,v8;
Packit c32a2d
		vector float vbs1,vbs2,vbs3,vbs4,vbs5,vbs6,vbs7,vbs8;
Packit c32a2d
		vector float vbs9,vbs10,vbs11,vbs12,vbs13,vbs14,vbs15,vbs16;
Packit c32a2d
		vector float vzero;
Packit c32a2d
		b1 = samples;
Packit c32a2d
		costab = pnts[0];
Packit c32a2d
		
Packit c32a2d
		vzero = vec_xor(vzero,vzero);
Packit c32a2d
#ifdef __APPLE__
Packit c32a2d
		vinvert = (vector unsigned char)(12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3);
Packit c32a2d
#else
Packit c32a2d
		vinvert = (vector unsigned char){12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3};
Packit c32a2d
#endif
Packit c32a2d
		vperm1 = vec_lvsl(0,b1);
Packit c32a2d
		vperm2 = vec_perm(vperm1,vperm1,vinvert);
Packit c32a2d
		
Packit c32a2d
		v1 = vec_ld(0,b1);
Packit c32a2d
		v2 = vec_ld(16,b1);
Packit c32a2d
		v3 = vec_ld(112,b1);
Packit c32a2d
		v4 = vec_ld(127,b1);
Packit c32a2d
		v5 = vec_perm(v1,v2,vperm1); /* b1[0,1,2,3] */
Packit c32a2d
		v6 = vec_perm(v3,v4,vperm2); /* b1[31,30,29,28] */
Packit c32a2d
		
Packit c32a2d
		vbs1 = vec_add(v5,v6);
Packit c32a2d
		vbs8 = vec_sub(v5,v6);
Packit c32a2d
		
Packit c32a2d
		v1 = vec_ld(32,b1);
Packit c32a2d
		v4 = vec_ld(96,b1);
Packit c32a2d
		v5 = vec_perm(v2,v1,vperm1); /* b1[4,5,6,7] */
Packit c32a2d
		v6 = vec_perm(v4,v3,vperm2); /* b1[27,26,25,24] */
Packit c32a2d
		
Packit c32a2d
		vbs2 = vec_add(v5,v6);
Packit c32a2d
		vbs7 = vec_sub(v5,v6);
Packit c32a2d
		
Packit c32a2d
		v2 = vec_ld(48,b1);
Packit c32a2d
		v3 = vec_ld(80,b1);
Packit c32a2d
		v5 = vec_perm(v1,v2,vperm1); /* b1[8,9,10,11] */
Packit c32a2d
		v6 = vec_perm(v3,v4,vperm2); /* b1[23,22,21,20] */
Packit c32a2d
		
Packit c32a2d
		vbs3 = vec_add(v5,v6);
Packit c32a2d
		vbs6 = vec_sub(v5,v6);
Packit c32a2d
		
Packit c32a2d
		v1 = vec_ld(64,b1);
Packit c32a2d
		v5 = vec_perm(v2,v1,vperm1); /* b1[12,13,14,15] */
Packit c32a2d
		v6 = vec_perm(v1,v3,vperm2); /* b1[19,18,17,16] */
Packit c32a2d
		
Packit c32a2d
		vbs4 = vec_add(v5,v6);
Packit c32a2d
		vbs5 = vec_sub(v5,v6);
Packit c32a2d
		
Packit c32a2d
		v1 = vec_ld(0,costab);
Packit c32a2d
		vbs8 = vec_madd(vbs8,v1,vzero);
Packit c32a2d
		v2 = vec_ld(16,costab);
Packit c32a2d
		vbs7 = vec_madd(vbs7,v2,vzero);
Packit c32a2d
		v3 = vec_ld(32,costab);
Packit c32a2d
		vbs6 = vec_madd(vbs6,v3,vzero);
Packit c32a2d
		v4 = vec_ld(48,costab);
Packit c32a2d
		vbs5 = vec_madd(vbs5,v4,vzero);
Packit c32a2d
		vbs6 = vec_perm(vbs6,vbs6,vinvert);
Packit c32a2d
		vbs5 = vec_perm(vbs5,vbs5,vinvert);
Packit c32a2d
		
Packit c32a2d
		
Packit c32a2d
		costab = pnts[1];
Packit c32a2d
		
Packit c32a2d
		v1 = vec_perm(vbs4,vbs4,vinvert);
Packit c32a2d
		vbs9 = vec_add(vbs1,v1);
Packit c32a2d
		v3 = vec_sub(vbs1,v1);
Packit c32a2d
		v5 = vec_ld(0,costab);
Packit c32a2d
		v2 = vec_perm(vbs3,vbs3,vinvert);
Packit c32a2d
		vbs10 = vec_add(vbs2,v2);
Packit c32a2d
		v4 = vec_sub(vbs2,v2);
Packit c32a2d
		v6 = vec_ld(16,costab);
Packit c32a2d
		vbs12 = vec_madd(v3,v5,vzero);
Packit c32a2d
		vbs11 = vec_madd(v4,v6,vzero);
Packit c32a2d
		
Packit c32a2d
		v7 = vec_sub(vbs7,vbs6);
Packit c32a2d
		v8 = vec_sub(vbs8,vbs5);
Packit c32a2d
		vbs13 = vec_add(vbs5,vbs8);
Packit c32a2d
		vbs14 = vec_add(vbs6,vbs7);
Packit c32a2d
		vbs15 = vec_madd(v7,v6,vzero);
Packit c32a2d
		vbs16 = vec_madd(v8,v5,vzero);
Packit c32a2d
		
Packit c32a2d
		
Packit c32a2d
		costab = pnts[2];
Packit c32a2d
		
Packit c32a2d
		v1 = vec_perm(vbs10,vbs10,vinvert);
Packit c32a2d
		v5 = vec_perm(vbs14,vbs14,vinvert);
Packit c32a2d
		vbs1 = vec_add(v1,vbs9);
Packit c32a2d
		vbs5 = vec_add(v5,vbs13);
Packit c32a2d
		v2 = vec_sub(vbs9,v1);
Packit c32a2d
		v6 = vec_sub(vbs13,v5);
Packit c32a2d
		v3 = vec_ld(0,costab);
Packit c32a2d
		vbs11 = vec_perm(vbs11,vbs11,vinvert);
Packit c32a2d
		vbs15 = vec_perm(vbs15,vbs15,vinvert);
Packit c32a2d
		vbs3 = vec_add(vbs11,vbs12);
Packit c32a2d
		vbs7 = vec_add(vbs15,vbs16);
Packit c32a2d
		v4 = vec_sub(vbs12,vbs11);
Packit c32a2d
		v7 = vec_sub(vbs16,vbs15);
Packit c32a2d
		vbs2 = vec_madd(v2,v3,vzero);
Packit c32a2d
		vbs4 = vec_madd(v4,v3,vzero);
Packit c32a2d
		vbs6 = vec_madd(v6,v3,vzero);
Packit c32a2d
		vbs8 = vec_madd(v7,v3,vzero);
Packit c32a2d
		
Packit c32a2d
		vbs2 = vec_perm(vbs2,vbs2,vinvert);
Packit c32a2d
		vbs4 = vec_perm(vbs4,vbs4,vinvert);
Packit c32a2d
		vbs6 = vec_perm(vbs6,vbs6,vinvert);
Packit c32a2d
		vbs8 = vec_perm(vbs8,vbs8,vinvert);
Packit c32a2d
		
Packit c32a2d
		
Packit c32a2d
		costab = pnts[3];
Packit c32a2d
		
Packit c32a2d
#ifdef __APPLE__
Packit c32a2d
		vperm1 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23);
Packit c32a2d
		vperm2 = (vector unsigned char)(12,13,14,15,8,9,10,11,28,29,30,31,24,25,26,27);
Packit c32a2d
		vperm3 = (vector unsigned char)(0,1,2,3,4,5,6,7,20,21,22,23,16,17,18,19);
Packit c32a2d
#else
Packit c32a2d
		vperm1 = (vector unsigned char){0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23};
Packit c32a2d
		vperm2 = (vector unsigned char){12,13,14,15,8,9,10,11,28,29,30,31,24,25,26,27};
Packit c32a2d
		vperm3 = (vector unsigned char){0,1,2,3,4,5,6,7,20,21,22,23,16,17,18,19};
Packit c32a2d
#endif
Packit c32a2d
		vperm4 = vec_add(vperm3,vec_splat_u8(8));
Packit c32a2d
		
Packit c32a2d
		v1 = vec_ld(0,costab);
Packit c32a2d
		v2 = vec_splat(v1,0);
Packit c32a2d
		v3 = vec_splat(v1,1);
Packit c32a2d
		v1 = vec_mergeh(v2,v3);
Packit c32a2d
		
Packit c32a2d
		v2 = vec_perm(vbs1,vbs3,vperm1);
Packit c32a2d
		v3 = vec_perm(vbs2,vbs4,vperm1);
Packit c32a2d
		v4 = vec_perm(vbs1,vbs3,vperm2);
Packit c32a2d
		v5 = vec_perm(vbs2,vbs4,vperm2);
Packit c32a2d
		v6 = vec_sub(v2,v4);
Packit c32a2d
		v7 = vec_sub(v3,v5);
Packit c32a2d
		v2 = vec_add(v2,v4);
Packit c32a2d
		v3 = vec_add(v3,v5);
Packit c32a2d
		v4 = vec_madd(v6,v1,vzero);
Packit c32a2d
		v5 = vec_nmsub(v7,v1,vzero);
Packit c32a2d
		vbs9 = vec_perm(v2,v4,vperm3);
Packit c32a2d
		vbs11 = vec_perm(v2,v4,vperm4);
Packit c32a2d
		vbs10 = vec_perm(v3,v5,vperm3);
Packit c32a2d
		vbs12 = vec_perm(v3,v5,vperm4);
Packit c32a2d
		
Packit c32a2d
		v2 = vec_perm(vbs5,vbs7,vperm1);
Packit c32a2d
		v3 = vec_perm(vbs6,vbs8,vperm1);
Packit c32a2d
		v4 = vec_perm(vbs5,vbs7,vperm2);
Packit c32a2d
		v5 = vec_perm(vbs6,vbs8,vperm2);
Packit c32a2d
		v6 = vec_sub(v2,v4);
Packit c32a2d
		v7 = vec_sub(v3,v5);
Packit c32a2d
		v2 = vec_add(v2,v4);
Packit c32a2d
		v3 = vec_add(v3,v5);
Packit c32a2d
		v4 = vec_madd(v6,v1,vzero);
Packit c32a2d
		v5 = vec_nmsub(v7,v1,vzero);
Packit c32a2d
		vbs13 = vec_perm(v2,v4,vperm3);
Packit c32a2d
		vbs15 = vec_perm(v2,v4,vperm4);
Packit c32a2d
		vbs14 = vec_perm(v3,v5,vperm3);
Packit c32a2d
		vbs16 = vec_perm(v3,v5,vperm4);
Packit c32a2d
		
Packit c32a2d
		
Packit c32a2d
		costab = pnts[4];
Packit c32a2d
		
Packit c32a2d
		v1 = vec_lde(0,costab);
Packit c32a2d
#ifdef __APPLE__
Packit c32a2d
		v2 = (vector float)(1.0f,-1.0f,1.0f,-1.0f);
Packit c32a2d
#else
Packit c32a2d
		v2 = (vector float){1.0f,-1.0f,1.0f,-1.0f};
Packit c32a2d
#endif
Packit c32a2d
		v3 = vec_splat(v1,0);
Packit c32a2d
		v1 = vec_madd(v2,v3,vzero);
Packit c32a2d
		
Packit c32a2d
		v2 = vec_mergeh(vbs9,vbs10);
Packit c32a2d
		v3 = vec_mergel(vbs9,vbs10);
Packit c32a2d
		v4 = vec_mergeh(vbs11,vbs12);
Packit c32a2d
		v5 = vec_mergel(vbs11,vbs12);
Packit c32a2d
		v6 = vec_mergeh(v2,v3);
Packit c32a2d
		v7 = vec_mergel(v2,v3);
Packit c32a2d
		v2 = vec_mergeh(v4,v5);
Packit c32a2d
		v3 = vec_mergel(v4,v5); 
Packit c32a2d
		v4 = vec_sub(v6,v7);
Packit c32a2d
		v5 = vec_sub(v2,v3);
Packit c32a2d
		v6 = vec_add(v6,v7);
Packit c32a2d
		v7 = vec_add(v2,v3);
Packit c32a2d
		v2 = vec_madd(v4,v1,vzero);
Packit c32a2d
		v3 = vec_madd(v5,v1,vzero);
Packit c32a2d
		vbs1 = vec_mergeh(v6,v2);
Packit c32a2d
		vbs2 = vec_mergel(v6,v2);
Packit c32a2d
		vbs3 = vec_mergeh(v7,v3);
Packit c32a2d
		vbs4 = vec_mergel(v7,v3);
Packit c32a2d
		
Packit c32a2d
		v2 = vec_mergeh(vbs13,vbs14);
Packit c32a2d
		v3 = vec_mergel(vbs13,vbs14);
Packit c32a2d
		v4 = vec_mergeh(vbs15,vbs16);
Packit c32a2d
		v5 = vec_mergel(vbs15,vbs16);
Packit c32a2d
		v6 = vec_mergeh(v2,v3);
Packit c32a2d
		v7 = vec_mergel(v2,v3);
Packit c32a2d
		v2 = vec_mergeh(v4,v5);
Packit c32a2d
		v3 = vec_mergel(v4,v5); 
Packit c32a2d
		v4 = vec_sub(v6,v7);
Packit c32a2d
		v5 = vec_sub(v2,v3);
Packit c32a2d
		v6 = vec_add(v6,v7);
Packit c32a2d
		v7 = vec_add(v2,v3);
Packit c32a2d
		v2 = vec_madd(v4,v1,vzero);
Packit c32a2d
		v3 = vec_madd(v5,v1,vzero);
Packit c32a2d
		vbs5 = vec_mergeh(v6,v2);
Packit c32a2d
		vbs6 = vec_mergel(v6,v2);
Packit c32a2d
		vbs7 = vec_mergeh(v7,v3);
Packit c32a2d
		vbs8 = vec_mergel(v7,v3);
Packit c32a2d
		
Packit c32a2d
		vec_st(vbs1,0,bufs);
Packit c32a2d
		vec_st(vbs2,16,bufs);
Packit c32a2d
		vec_st(vbs3,32,bufs);
Packit c32a2d
		vec_st(vbs4,48,bufs);
Packit c32a2d
		vec_st(vbs5,64,bufs);
Packit c32a2d
		vec_st(vbs6,80,bufs);
Packit c32a2d
		vec_st(vbs7,96,bufs);
Packit c32a2d
		vec_st(vbs8,112,bufs);
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
 {
Packit c32a2d
  register real *b1;
Packit c32a2d
  register int i;
Packit c32a2d
Packit c32a2d
  for(b1=bufs,i=8;i;i--,b1+=4)
Packit c32a2d
    b1[2] += b1[3];
Packit c32a2d
Packit c32a2d
  for(b1=bufs,i=4;i;i--,b1+=8)
Packit c32a2d
  {
Packit c32a2d
    b1[4] += b1[6];
Packit c32a2d
    b1[6] += b1[5];
Packit c32a2d
    b1[5] += b1[7];
Packit c32a2d
  }
Packit c32a2d
Packit c32a2d
  for(b1=bufs,i=2;i;i--,b1+=16)
Packit c32a2d
  {
Packit c32a2d
    b1[8]  += b1[12];
Packit c32a2d
    b1[12] += b1[10];
Packit c32a2d
    b1[10] += b1[14];
Packit c32a2d
    b1[14] += b1[9];
Packit c32a2d
    b1[9]  += b1[13];
Packit c32a2d
    b1[13] += b1[11];
Packit c32a2d
    b1[11] += b1[15];
Packit c32a2d
  }
Packit c32a2d
 }
Packit c32a2d
Packit c32a2d
Packit c32a2d
  out0[0x10*16] = bufs[0];
Packit c32a2d
  out0[0x10*15] = bufs[16+0]  + bufs[16+8];
Packit c32a2d
  out0[0x10*14] = bufs[8];
Packit c32a2d
  out0[0x10*13] = bufs[16+8]  + bufs[16+4];
Packit c32a2d
  out0[0x10*12] = bufs[4];
Packit c32a2d
  out0[0x10*11] = bufs[16+4]  + bufs[16+12];
Packit c32a2d
  out0[0x10*10] = bufs[12];
Packit c32a2d
  out0[0x10* 9] = bufs[16+12] + bufs[16+2];
Packit c32a2d
  out0[0x10* 8] = bufs[2];
Packit c32a2d
  out0[0x10* 7] = bufs[16+2]  + bufs[16+10];
Packit c32a2d
  out0[0x10* 6] = bufs[10];
Packit c32a2d
  out0[0x10* 5] = bufs[16+10] + bufs[16+6];
Packit c32a2d
  out0[0x10* 4] = bufs[6];
Packit c32a2d
  out0[0x10* 3] = bufs[16+6]  + bufs[16+14];
Packit c32a2d
  out0[0x10* 2] = bufs[14];
Packit c32a2d
  out0[0x10* 1] = bufs[16+14] + bufs[16+1];
Packit c32a2d
  out0[0x10* 0] = bufs[1];
Packit c32a2d
Packit c32a2d
  out1[0x10* 0] = bufs[1];
Packit c32a2d
  out1[0x10* 1] = bufs[16+1]  + bufs[16+9];
Packit c32a2d
  out1[0x10* 2] = bufs[9];
Packit c32a2d
  out1[0x10* 3] = bufs[16+9]  + bufs[16+5];
Packit c32a2d
  out1[0x10* 4] = bufs[5];
Packit c32a2d
  out1[0x10* 5] = bufs[16+5]  + bufs[16+13];
Packit c32a2d
  out1[0x10* 6] = bufs[13];
Packit c32a2d
  out1[0x10* 7] = bufs[16+13] + bufs[16+3];
Packit c32a2d
  out1[0x10* 8] = bufs[3];
Packit c32a2d
  out1[0x10* 9] = bufs[16+3]  + bufs[16+11];
Packit c32a2d
  out1[0x10*10] = bufs[11];
Packit c32a2d
  out1[0x10*11] = bufs[16+11] + bufs[16+7];
Packit c32a2d
  out1[0x10*12] = bufs[7];
Packit c32a2d
  out1[0x10*13] = bufs[16+7]  + bufs[16+15];
Packit c32a2d
  out1[0x10*14] = bufs[15];
Packit c32a2d
  out1[0x10*15] = bufs[16+15];
Packit c32a2d
Packit c32a2d
}
Packit c32a2d
Packit c32a2d