pcm_sh3.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:9k
源码类别:
Windows CE
开发平台:
C/C++
- /*****************************************************************************
- *
- * This program is free software ; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: pcm_sh3.c 304 2005-10-20 11:02:59Z picard $
- *
- * The Core Pocket Media Player
- * Copyright (c) 2004-2005 Gabor Kovacs
- *
- ****************************************************************************/
- #include "../common.h"
- #include "../dyncode/dyncode.h"
- #include "pcm_soft.h"
- #if defined(SH3)
- typedef struct stack
- {
- int Step; //backup
- int StackFrame[7];
- void* this; //R4
- char* Dst; //R5
- char* Src; //R6
- int DstLength; //R7
- pcmstate* State;
- int Volume;
- } stack;
- // R0 temp index
- // R13,R1 dither (or R13=shift,-shift) (or R1=volume)
- // R2,R3 value
- // R4 Min
- // R5 Max
- // R7 Step
- // R8 Pos
- // R9 SrcLeft
- // R10 SrcRight
- // R11 DstLeft
- // R12 DstRight
- // R14 DstLeftEnd
- void PCMLoop(pcm_soft* p,bool_t Speed)
- {
- bool_t SrcPacked = !(p->Src.Flags & PCM_PLANES) && p->Src.Channels==2;
- dyninst* Loop;
- reg Left;
- reg Right;
- reg Shift;
- if (!p->ActualDither && p->Shift)
- I1C(MOVI,R13,p->Shift);
- if (p->ActualDither)
- if (Speed)
- I2C(MOVL_STOFS,R7,SP,OFS(stack,Step)); // save backup
- else
- I1C(MOVI,R7,-p->Shift);
- Loop = Label(1);
- Left = R2;
- if (p->UseLeft)
- Right = R3;
- else
- Right = R2;
- if (Speed)
- {
- I2(MOV,R8,R0);
- IShift(R0,NONE,-8);
- IShift(R0,NONE,p->SrcShift);
- switch (p->Src.Bits)
- {
- case 8:
- if (p->UseLeft)
- I2(MOVB_LDR0,R9,Left);
- if (p->UseRight)
- I2(MOVB_LDR0,R10,Right);
- if (p->SrcUnsigned)
- {
- I2(EXTUB,R2,R2);
- if (p->SrcChannels>1)
- I2(EXTUB,R3,R3);
- }
- break;
- case 16:
- if (p->UseLeft)
- I2(MOVW_LDR0,R9,Left);
- if (p->UseRight)
- I2(MOVW_LDR0,R10,Right);
- if (p->SrcUnsigned)
- {
- I2(EXTUW,R2,R2);
- if (p->SrcChannels>1)
- I2(EXTUW,R3,R3);
- }
- break;
- case 32:
- if (p->UseLeft)
- I2(MOVL_LDR0,R9,Left);
- if (p->UseRight)
- I2(MOVL_LDR0,R10,Right);
- break;
- }
- I2(ADD,R7,R8);
- }
- else
- {
- switch (p->Src.Bits)
- {
- case 8:
- if (p->UseLeft)
- {
- I2(MOVB_LDADD,R9,Left);
- if (SrcPacked && !p->UseRight) I1C(ADDI,R9,1);
- }
- if (p->UseRight)
- if (SrcPacked)
- {
- if (!p->UseLeft) I1C(ADDI,R9,1);
- I2(MOVB_LDADD,R9,Right);
- }
- else
- I2(MOVB_LDADD,R10,Right);
- if (p->SrcUnsigned)
- {
- I2(EXTUB,R2,R2);
- if (p->SrcChannels>1)
- I2(EXTUB,R3,R3);
- }
- break;
- case 16:
- if (p->UseLeft)
- {
- I2(MOVW_LDADD,R9,Left);
- if (SrcPacked && !p->UseRight) I1C(ADDI,R9,2);
- }
- if (p->UseRight)
- if (SrcPacked)
- {
- if (!p->UseLeft) I1C(ADDI,R9,2);
- I2(MOVW_LDADD,R9,Right);
- }
- else
- I2(MOVW_LDADD,R10,Right);
- if (p->SrcUnsigned)
- {
- I2(EXTUW,R2,R2);
- if (p->SrcChannels>1)
- I2(EXTUW,R3,R3);
- }
- break;
- case 32:
- if (p->UseLeft)
- {
- I2(MOVL_LDADD,R9,Left);
- if (SrcPacked && !p->UseRight) I1C(ADDI,R9,4);
- }
- if (p->UseRight)
- if (SrcPacked)
- {
- if (!p->UseLeft) I1C(ADDI,R9,4);
- I2(MOVL_LDADD,R9,Right);
- }
- else
- I2(MOVL_LDADD,R10,Right);
- break;
- }
- }
- if (p->InstSrcUnsigned)
- {
- MB(); I1P(MOVL_PC,R0,p->InstSrcUnsigned,0);
- I2(SUB,R0,R2);
- if (p->SrcChannels>1)
- I2(SUB,R0,R3);
- }
- else
- if (p->SrcUnsigned == 128)
- {
- I1C(ADDI,R2,-128);
- if (p->SrcChannels>1)
- I1C(ADDI,R3,-128);
- }
- if (p->Stereo)
- {
- if ((p->Src.Flags ^ p->Dst.Flags) & PCM_SWAPPEDSTEREO)
- {
- Left = R3;
- Right = R2;
- }
- else
- {
- Left = R2;
- Right = R3;
- }
- }
- else
- {
- if (p->Join)
- I2(ADD,R3,R2);
- Right = Left = R2;
- }
- if (p->ActualDither)
- {
- I2(ADD,R13,R2);
- I2(MOV,R2,R13);
- if (p->Stereo)
- {
- I2(ADD,R1,R3);
- I2(MOV,R3,R1);
- }
- }
- if (p->Clip>0)
- {
- dyninst* ClipMin = Label(0);
- dyninst* ClipMax = Label(0);
- I2(CMPGT,R2,R4);
- I0P(BFS,ClipMin);
- I2(CMPGT,R5,R2); // delay slot
- I2(MOV,R4,R2);
- InstPost(ClipMin);
- I0P(BFS,ClipMax);
- I1C(ADDI,R11,1<<p->DstShift); // delay slot
- I2(MOV,R5,R2);
- InstPost(ClipMax);
- if (p->Stereo)
- {
- ClipMin = Label(0);
- ClipMax = Label(0);
- I2(CMPGT,R3,R4);
- I0P(BFS,ClipMin);
- I2(CMPGT,R5,R3); // delay slot
- I2(MOV,R4,R3);
- InstPost(ClipMin);
- I0P(BFS,ClipMax);
- I1C(ADDI,R12,1<<p->DstShift); // delay slot
- I2(MOV,R5,R3);
- InstPost(ClipMax);
- }
- else
- if (p->Dst.Channels>1)
- I1C(ADDI,R12,1<<p->DstShift); // delay slot
- }
- else
- {
- I1C(ADDI,R11,1<<p->DstShift);
- if (p->Dst.Channels>1)
- I1C(ADDI,R12,1<<p->DstShift);
- }
- I2(CMPEQ,R11,R14);
- if (p->Shift)
- {
- if (p->ActualDither)
- {
- I1C(MOVI,R0,p->Shift);
- Shift = R0;
- }
- else
- Shift = R13;
- I2(SHAD,Shift,R2);
- if (p->Stereo) I2(SHAD,Shift,R3);
- }
- if (p->ActualDither)
- {
- if (Speed)
- I1C(MOVI,R7,-p->Shift);
- I2(MOV,R2,R0);
- I2(SHAD,R7,R0);
- I2(SUB,R0,R13);
- if (p->Stereo)
- {
- I2(MOV,R3,R0);
- I2(SHAD,R7,R0);
- I2(SUB,R0,R1);
- }
- if (Speed)
- I2C(MOVL_LDOFS,SP,R7,OFS(stack,Step));
- }
- if (p->InstDstUnsigned)
- {
- MB(); I1P(MOVL_PC,R0,p->InstDstUnsigned,0);
- I1C(ADD,R0,Left);
- if (Left != Right)
- I1C(ADD,R0,Right);
- }
- else
- if (p->DstUnsigned == 128)
- {
- // p->Dst.Bits=8 so doesn't matter if it's add or sub
- I1C(ADDI,Left,-128);
- if (Left != Right)
- I1C(ADDI,Right,-128);
- }
- switch (p->Dst.Bits)
- {
- case 8:
- I2(MOVB_ST,Left,R11);
- if (p->Dst.Channels>1)
- I2(MOVB_ST,Right,R12);
- break;
- case 16:
- I2(MOVW_ST,Left,R11);
- if (p->Dst.Channels>1)
- I2(MOVW_ST,Right,R12);
- break;
- case 32:
- I2(MOVL_ST,Left,R11);
- if (p->Dst.Channels>1)
- I2(MOVL_ST,Right,R12);
- break;
- }
- DS(); I0P(BFS,Loop);
- if (p->ActualDither)
- {
- I2(MOV,SP,R0);
- I1C(ADDI,R0,OFS(stack,State));
- I2(MOVL_LD,R0,R4);
- I2C(MOVL_STOFS,R13,R4,OFS(pcmstate,Dither[0]));
- I2C(MOVL_STOFS,R1,R4,OFS(pcmstate,Dither[1]));
- }
- CodeEnd(7,OFS(stack,StackFrame));
- }
- void PCMCompile(pcm_soft* p)
- {
- dyninst* Speed;
- dyninst* Min = NULL;
- dyninst* Max = NULL;
- CodeBegin(7,OFS(stack,StackFrame));
- p->InstSrcUnsigned = NULL;
- p->InstDstUnsigned = NULL;
- if (p->SrcUnsigned && p->SrcUnsigned != 128)
- p->InstSrcUnsigned = InstCreate32(p->SrcUnsigned,NONE,NONE,NONE,0,0);
- if (p->DstUnsigned && p->DstUnsigned != 128)
- p->InstDstUnsigned = InstCreate32(p->DstUnsigned,NONE,NONE,NONE,0,0);
- // dst pointers
- I2C(MOVL_LDOFS,R5,R11,0);
- I1C(ADDI,R11,-(1<<p->DstShift)); // back one step
- if (p->Dst.Channels > 1)
- {
- if (p->Dst.Flags & PCM_PLANES)
- {
- I2C(MOVL_LDOFS,R5,R12,4);
- I1C(ADDI,R12,-(1<<p->DstShift)); // back one step
- }
- else
- {
- I2(MOV,R11,R12);
- I1C(ADDI,R12,1<<(p->DstShift-1));
- }
- }
- I2(MOV,R7,R14);
- I2(ADD,R11,R14); // dstend
- // src pointers
- I2C(MOVL_LDOFS,R6,R9,0);
- if (p->Src.Channels > 1)
- {
- if (p->Src.Flags & PCM_PLANES)
- I2C(MOVL_LDOFS,R6,R10,4);
- else
- {
- I2(MOV,R9,R10);
- I1C(ADDI,R10,p->Src.Bits>>3);
- }
- }
- I2(MOV,SP,R0);
- I1C(ADDI,R0,OFS(stack,State));
- I2(MOVL_LD,R0,R4);
- I2C(MOVL_LDOFS,R4,R7,OFS(pcmstate,Step));
- I2C(MOVL_LDOFS,R4,R8,OFS(pcmstate,Pos));
- /*
- if (p->UseVolume)
- {
- I1C(ADDI,R0,OFS(stack,Volume)-OFS(stack,State));
- I2(MOVL_LD,R0,R1);
- }
- */
- if (p->ActualDither)
- {
- I2C(MOVL_LDOFS,R4,R13,OFS(pcmstate,Dither[0]));
- I2C(MOVL_LDOFS,R4,R1,OFS(pcmstate,Dither[1]));
- }
- if (p->Clip>0)
- {
- Min = InstCreate32(p->MinLimit,NONE,NONE,NONE,0,0);
- Max = InstCreate32(p->MaxLimit,NONE,NONE,NONE,0,0);
- I1P(MOVL_PC,R4,Min,0);
- I1P(MOVL_PC,R5,Max,0);
- }
- Speed = Label(0);
- I1C(MOVI,R2,64);
- I1(SHLL2,R2);
- I2(CMPEQ,R2,R7);
- I0P(BF,Speed);
- PCMLoop(p,0);
- InstPost(Speed);
- PCMLoop(p,1);
- Align(4);
- if (Min) InstPost(Min);
- if (Max) InstPost(Max);
- if (p->InstSrcUnsigned) InstPost(p->InstSrcUnsigned);
- if (p->InstDstUnsigned) InstPost(p->InstDstUnsigned);
- }
- #endif