MCODEC - 感恩的心,感谢生命中的每一个人

(本站所有文章都是原创,转载请注明出处)
  首页  :: 联系 :: 订阅 订阅  :: 管理

tm1500 部分汇编指令的C实现

Posted on 2009-10-23 19:29  mcodec  阅读(319)  评论(0编辑  收藏  举报

很早以前的代码,当时公司里面的仿真器总是被别人霸占,就只好用PC C语言来模拟TM1500汇编指令,进行开发调试,于是就有下面这些代码。

#define DSPIMUL(X, Y) (X*Y)
#define DSPIABS(X) abs(X)

static int ADDSUB(int a, int b)
{
 if(a>0)
  return a+b;
 else
  return a-b;
}

static int DUALICLIPI(int a, int b)
{
 int c=-1-b;
 if(a>b)
  return b;
 else if(a<c)
  return c;
 else
  return a;
}

static __inline uint32_t FUNSHIFT3(uint32_t src1, uint32_t src2)
{
 return ((src1 & 0xFF) << 24 ) + ((src2 >> 8) & 0xFFFFFF);
}

static __inline uint32_t FUNSHIFT2(uint32_t src1, uint32_t src2)
{
 return ((src1 & 0xFFFF) << 16 ) + ((src2 >> 16) & 0xFFFF);
}

static __inline uint32_t FUNSHIFT1(uint32_t src1, uint32_t src2)
{
 return ((src1 & 0xFFFFFF) << 8 ) + ((src2 >> 24) & 0xFF);
}

static __inline uint32_t QUADAVG0(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ( (src1 & 0xFF) + (src2 & 0xFF) ) / 2 ;

 temp += (( ((src1>>8) & 0xFF) + ((src2>>8) & 0xFF) ) / 2 ) << 8;

 temp += (( ((src1>>16) & 0xFF) + ((src2>>16) & 0xFF) ) / 2) << 16 ;

 temp += (( ((src1>>24) & 0xFF) + ((src2>>24) & 0xFF) ) / 2) << 24 ;

 return temp;
}

static __inline uint32_t QUADAVG(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ( (src1 & 0xFF) + (src2 & 0xFF) + 1 ) / 2 ;

 temp += (( ((src1>>8) & 0xFF) + ((src2>>8) & 0xFF) + 1) / 2 ) << 8;

 temp += (( ((src1>>16) & 0xFF) + ((src2>>16) & 0xFF) + 1) / 2) << 16 ;

 temp += (( ((src1>>24) & 0xFF) + ((src2>>24) & 0xFF) + 1) / 2) << 24 ;

 return temp;
}

static __inline uint32_t BILINEAR1(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ((src1 & 0xFF) + (src2 & 0xFF) + ((src1 >> 8) & 0xFF) +(( src2 >> 8) & 0xFF) + 1) / 4;

 temp += ( ( ((src1>>16) & 0xFF) + ((src2>>16) & 0xFF) + ((src1 >> 24) & 0xFF) +((src2 >> 24) & 0xFF) + 1) / 4)<<16;

 return temp;
}

static __inline uint32_t BILINEAR2(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ((src1 & 0xFF) + (src2 & 0xFF) + ((src1 >> 8) & 0xFF) +(( src2 >> 8) & 0xFF) + 2) / 4;

 temp += ( ( ((src1>>16) & 0xFF) + ((src2>>16) & 0xFF) + ((src1 >> 24) & 0xFF) +((src2 >> 24) & 0xFF) + 2) / 4)<<16;

 return temp;
}

static __inline uint32_t MERGEODD(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = (src2 & 0xFF00FF) + ((src1 & 0xFF00FF) << 8);

 return temp;
}

static __inline uint32_t MERGEDUAL16LSB(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ((src1 & 0xFF) << 16) + ((src1 & 0xFF0000) << 8) + (src2 & 0xFF) +((src2 & 0xFF0000) >> 8);

 return temp;
}

static __inline uint32_t PACKBYTES(int8_t src1, int8_t src2)
{
 uint32_t temp=0;

 temp = ((src1 & 0xFF) << 8) + (src2 & 0xFF);

 return temp;
}

static __inline uint32_t PACK16LSB(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = ((src1 & 0xFFFFFF) << 16) + (src2 & 0xFFFF);

 return temp;
}

static __inline uint32_t MERGELSB(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = (src1 & 0xFF00)<<16;
 temp |= (src1 & 0xFF)<<8;
 temp |= (src2 & 0xFF00)<<8;
 temp |= (src2 & 0xFF);

 return temp;
}

static __inline uint32_t MERGEMSB(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 temp = src1 & 0xFF000000;
 temp |= (src1 & 0xFF0000)>>8;
 temp |= (src2 & 0xFF000000)>>8;
 temp |= (src2 & 0xFF0000)>>16;

 return temp;
}

static __inline uint32_t DSPIDUALSUB(uint32_t src1, uint32_t src2)
{
 uint32_t temp;

 int32_t temp1 = (src1 & 0xFFFF0000) - (src2 & 0xFFFF0000);
 int32_t temp2 = (src1 & 0xFFFF) - (src2 & 0xFFFF);

 temp = (temp1 & 0xFFFF0000) + (temp2 & 0xFFFF);

 return temp;
}

//-------------------------------------------------------------------

static __inline uint32_t SEX16(uint32_t src1)
{
 uint32_t temp=src1 & 0xFFFF;

 if(temp & 0x8000)
  temp |= 0xFFFF0000;

 return temp;
}

static __inline uint32_t ASRI(uint32_t src1, uint32_t src2)
{
 int32_t temp=src2;

 if((src1 < 32) && (src1 >= 0))
 {
  temp = temp >> src1;
 }

 return temp;
}

static __inline uint32_t ASLI(uint32_t src1, uint32_t src2)
{
 int32_t temp=src2;
 if((src1 < 32) && (src1 >= 0))
 {
  temp = temp << src1;
 }

 return temp;
}

#define LOW16BIT(a)  SEX16(a)
#define HIGH16BIT(a) ASRI(16, (a))

static __inline uint32_t DUALASR(uint32_t src1, uint32_t src2)
{
 uint32_t temp=src1;

 if( (src2<16) && (src2>=0))
 {
  int tmp1 = SEX16(src1);
  int tmp2 = SEX16(src1 >> 16);

  tmp1 >>= src2;
  tmp1 &= 0xFFFF;

  tmp2 >>= src2;
  tmp2 &= 0xFFFF;

  temp = (tmp2<<16) | tmp1;
 }

 return temp;
}

static __inline uint32_t DSPIDUALABS(uint32_t src1)
{
 uint32_t temp=0;

 int tmp1 = SEX16(src1);
 int tmp2 = SEX16(src1>>16);

 if(tmp1 == 0xFFFF8000)
  tmp1 = 0x7FFF;
 if(tmp2 == 0xFFFF8000)
  tmp2 = 0x7FFF;

 if(tmp1 <0)
  tmp1 = -tmp1;
 if(tmp2<0)
  tmp2 = -tmp2;

 temp = (tmp1 & 0xFFFF) + (tmp2<<16);

 return temp;
}

static __inline uint32_t DUALIMULM(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 int tmp1 = SEX16(src1);
 int tmp2 = SEX16(src1>>16);

 int tmp3 = SEX16(src2);
 int tmp4 = SEX16(src2>>16);

 int tmp5 = tmp1 * tmp3;
 int tmp6 = tmp2 * tmp4;

 temp = (tmp6 & 0xFFFF0000) + ((tmp5 >>16) & 0xFFFF);

 return temp;
}

static __inline uint32_t DSPIDUALADD(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 int tmp1 = SEX16(src1);
 int tmp2 = SEX16(src1>>16);

 int tmp3 = SEX16(src2);
 int tmp4 = SEX16(src2>>16);

 int tmp5 = tmp1 + tmp3;
 int tmp6 = tmp2 + tmp4;

 if(tmp5>32767)
  tmp5 = 32767;
 else if(tmp5<-32768)
  tmp5 = -32768;

 if(tmp6>32767)
  tmp6 = 32767;
 else if(tmp6<-32768)
  tmp6 = -32768;
 
 temp = (tmp6<<16) + (tmp5 & 0xFFFF);

 return temp;
}

static __inline uint32_t UME8UU(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;
 int tmp1 = (src1 & 0xFF);
 int tmp2 = (src1>>8) & 0xFF;
 int tmp3 = (src1>>16) & 0xFF;
 int tmp4 = (src1>>24) & 0xFF;

 int tmp5 = (src2 & 0xFF);
 int tmp6 = (src2>>8) & 0xFF;
 int tmp7 = (src2>>16) & 0xFF;
 int tmp8 = (src2>>24) & 0xFF;

 temp = abs(tmp1 - tmp5) + abs(tmp2 - tmp6) + abs(tmp3 - tmp7) + abs(tmp4 - tmp8);

 return temp;
}

static __inline uint32_t DUALUCLIPI(uint32_t src1, uint32_t src2)
{
 uint32_t temp=0;

 int tmp1 = SEX16(src1);
 int tmp2 = SEX16(src1>>16);

 if(tmp1<0)
  tmp1=0;
 else if(tmp1>src2)
  tmp1=src2;

 if(tmp2<0)
  tmp2=0;
 else if(tmp2>src2)
  tmp2=src2;

 temp = tmp1 + (tmp2<<16);

 return temp;
}