pcm_mips.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:7k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: pcm_mips.c 304 2005-10-20 11:02:59Z picard $
  18.  *
  19.  ****************************************************************************/
  20. #include "../common.h"
  21. #include "../dyncode/dyncode.h"
  22. #include "pcm_soft.h"
  23. #if defined(MIPS)
  24. typedef struct stack
  25. {
  26. void* this;   // R4
  27. char* Dst;   // R5
  28. char* Src;   // R6
  29. int DstLength;// R7
  30. pcmstate* State;
  31. int Volume;
  32. } stack;
  33. // R13 tmp
  34. // R24,R25 dither 
  35. // R2,R3 value
  36. // R4 Min
  37. // R5 Max
  38. // R7 Step
  39. // R8 Pos
  40. // R9 SrcLeft
  41. // R10 SrcRight
  42. // R11 DstLeft-1
  43. // R12 DstRight-1
  44. // R14 DstLeftEnd-1
  45. void PCMLoop(pcm_soft* p,bool_t Speed)
  46. {
  47. bool_t DstPacked = !(p->Dst.Flags & PCM_PLANES) && p->Dst.Channels==2 && (p->Dst.Bits<=16);
  48. dyninst* Loop;
  49. reg Left;
  50. reg Right;
  51. Loop = Label(1);
  52. Left = R2;
  53. if (p->UseLeft)
  54. Right = R3;
  55. else
  56. Right = R2;
  57. if (Speed)
  58. {
  59. I2C(SRL,R3,R8,8);
  60. if (p->SrcShift) I2C(SLL,R3,R3,p->SrcShift);
  61. if (p->UseLeft)
  62. I3(ADDU,R2,R3,R9);
  63. if (p->UseRight)
  64. I3(ADDU,R3,R3,R10);
  65. switch (p->Src.Bits)
  66. {
  67. case 8:
  68. if (p->UseLeft)
  69. I2C(p->SrcUnsigned ? LBU:LB,R2,R2,0);
  70. if (p->UseRight)
  71. I2C(p->SrcUnsigned ? LBU:LB,R3,R3,0);
  72. break;
  73. case 16:
  74. if (p->UseLeft)
  75. I2C(p->SrcUnsigned ? LHU:LH,R2,R2,0);
  76. if (p->UseRight)
  77. I2C(p->SrcUnsigned ? LHU:LH,R3,R3,0);
  78. break;
  79. case 32:
  80. if (p->UseLeft)
  81. I2C(LW,R2,R2,0);
  82. if (p->UseRight)
  83. I2C(LW,R3,R3,0);
  84. break;
  85. }
  86. I3(ADDU,R8,R8,R7);
  87. }
  88. else
  89. {
  90. switch (p->Src.Bits)
  91. {
  92. case 8:
  93. if (p->UseLeft)
  94. I2C(p->SrcUnsigned ? LBU:LB,R2,R9,0);
  95. if (p->UseRight)
  96. I2C(p->SrcUnsigned ? LBU:LB,R3,R10,0);
  97. break;
  98. case 16:
  99. if (p->UseLeft)
  100. I2C(p->SrcUnsigned ? LHU:LH,R2,R9,0);
  101. if (p->UseRight)
  102. I2C(p->SrcUnsigned ? LHU:LH,R3,R10,0);
  103. break;
  104. case 32:
  105. if (p->UseLeft)
  106. I2C(LW,R2,R9,0);
  107. if (p->UseRight)
  108. I2C(LW,R3,R10,0);
  109. break;
  110. }
  111. if (p->UseLeft)
  112. I2C(ADDIU,R9,R9,1<<p->SrcShift);
  113. if (p->UseRight)
  114. I2C(ADDIU,R10,R10,1<<p->SrcShift);
  115. }
  116. if (p->SrcUnsigned && p->SrcUnsigned <= 0x8000) 
  117. {
  118. I2C(ADDIU,R2,R2,-p->SrcUnsigned);
  119. if (p->SrcChannels>1)
  120. I2C(ADDIU,R3,R3,-p->SrcUnsigned);
  121. }
  122. if (p->Stereo)
  123. {
  124. if ((p->Src.Flags ^ p->Dst.Flags) & PCM_SWAPPEDSTEREO)
  125. {
  126. Left = R3;
  127. Right = R2;
  128. }
  129. else
  130. {
  131. Left = R2;
  132. Right = R3;
  133. }
  134. }
  135. else
  136. {
  137. if (p->Join)
  138. I3(ADDU,R2,R2,R3);
  139. Right = Left = R2;
  140. }
  141. if (p->ActualDither)
  142. {
  143. I3(ADDU,R2,R2,R24);
  144. I3(ADDU,R24,R2,ZERO);
  145. if (p->Stereo) 
  146. {
  147. I3(ADDU,R3,R3,R25);
  148. I3(ADDU,R25,R3,ZERO);
  149. }
  150. }
  151. if (p->UseVolume)
  152. {
  153. if (p->Src.Bits >= 23)
  154. I2C(SRA,R2,R2,8); 
  155. I2(MULT,R2,R24);
  156. I1(MFLO,R2);
  157. if (p->Stereo)
  158. {
  159. if (p->Src.Bits >= 23)
  160. I2C(SRA,R3,R3,8);
  161. else
  162. NOP();
  163. NOP(); // MULT and MFLO too close
  164. I2(MULT,R3,R24);
  165. I1(MFLO,R3);
  166. }
  167. }
  168. if (p->Clip>0)
  169. {
  170. dyninst* ClipMin = Label(0);
  171. dyninst* ClipMax = Label(0);
  172. I3(SUBU,R13,R2,R4);
  173. I1P(BGEZ,R13,ClipMin,0);
  174. I3(SUBU,R13,R5,R2); // delay slot
  175. I3(ADDU,R2,R4,ZERO);
  176. InstPost(ClipMin);
  177. I1P(BGEZ,R13,ClipMax,0);
  178. I2C(ADDIU,R11,R11,1<<p->DstShift); // delay slot
  179. I3(ADDU,R2,R5,ZERO);
  180. InstPost(ClipMax);
  181. if (p->Stereo)
  182. {
  183. dyninst* ClipMin = Label(0);
  184. dyninst* ClipMax = Label(0);
  185. I3(SUBU,R13,R3,R4);
  186. I1P(BGEZ,R13,ClipMin,0);
  187. I3(SUBU,R13,R5,R3); // delay slot
  188. I3(ADDU,R3,R4,ZERO);
  189. InstPost(ClipMin);
  190. I1P(BGEZ,R13,ClipMax,0);
  191. I2C(ADDIU,R12,R12,1<<p->DstShift); // delay slot
  192. I3(ADDU,R3,R5,ZERO);
  193. InstPost(ClipMax);
  194. }
  195. else
  196. if (p->Dst.Channels>1 && !DstPacked)
  197. I2C(ADDIU,R12,R12,1<<p->DstShift); // delay slot
  198. }
  199. else
  200. {
  201. I2C(ADDIU,R11,R11,1<<p->DstShift);
  202. if (p->Dst.Channels>1 && !DstPacked)
  203. I2C(ADDIU,R12,R12,1<<p->DstShift);
  204. }
  205. if (p->Shift)
  206. {
  207. I2C(SRA,R2,R2,-p->Shift);
  208. if (p->Stereo) I2C(SRA,R3,R3,-p->Shift);
  209. }
  210. if (p->ActualDither)
  211. {
  212. I2C(SRA,R13,R2,p->Shift);
  213. I3(SUBU,R24,R24,R13);
  214. if (p->Stereo)
  215. {
  216. I2C(SRA,R13,R3,p->Shift);
  217. I3(SUBU,R25,R25,R13);
  218. }
  219. }
  220. if (p->DstUnsigned && p->DstUnsigned < 0x8000) 
  221. {
  222. I2C(ADDIU,Left,Left,p->DstUnsigned);
  223. if (Left != Right)
  224. I2C(ADDIU,Right,Right,p->DstUnsigned);
  225. }
  226. switch (p->Dst.Bits)
  227. {
  228. case 8:
  229. if (DstPacked)
  230. {
  231. I2C(SLL,Right,Right,8);
  232. I2C(ANDI,Left,Left,0xFF);
  233. I3(OR,Left,Left,Right);
  234. I2C(SH,Left,R11,0);
  235. }
  236. else
  237. {
  238. I2C(SB,Left,R11,0);
  239. if (p->Dst.Channels>1)
  240. I2C(SB,Right,R12,0);
  241. }
  242. break;
  243. case 16:
  244. if (DstPacked)
  245. {
  246. I2C(SLL,Right,Right,16);
  247. I2C(ANDI,Left,Left,0xFFFF);
  248. I3(OR,Left,Left,Right);
  249. I2C(SW,Left,R11,0);
  250. }
  251. else
  252. {
  253. I2C(SH,Left,R11,0);
  254. if (p->Dst.Channels>1)
  255. I2C(SH,Right,R12,0);
  256. }
  257. break;
  258. case 32:
  259. I2C(SW,Left,R11,0);
  260. if (p->Dst.Channels>1)
  261. I2C(SW,Right,R12,0);
  262. break;
  263. }
  264. DS(); I2P(BNE,R11,R14,Loop);
  265. if (p->ActualDither)
  266. {
  267. I2C(LW,R4,SP,OFS(stack,State));
  268. I2C(SW,R24,R4,OFS(pcmstate,Dither[0]));
  269. I2C(SW,R25,R4,OFS(pcmstate,Dither[1]));
  270. }
  271. else
  272. I3(ADDU,R4,ZERO,ZERO); // for the delay slot
  273. CodeEnd(0,0,0);
  274. }
  275. void PCMCompile(pcm_soft* p)
  276. {
  277. dyninst* Speed;
  278. CodeBegin(0,0,0);
  279. // dst pointers
  280. I2C(LW,R11,R5,0);
  281. if (p->Dst.Channels > 1)
  282. {
  283. if (p->Dst.Flags & PCM_PLANES)
  284. {
  285. I2C(LW,R12,R5,4);
  286. }
  287. else
  288. I2C(ADDIU,R12,R11,1<<(p->DstShift-1));
  289. }
  290. I2C(ADDIU,R11,R11,-(1<<p->DstShift)); // back one step
  291. if (p->Dst.Channels > 1)
  292. I2C(ADDIU,R12,R12,-(1<<p->DstShift)); // back one step
  293. I3(ADDU,R14,R11,R7); // dstend-1
  294. // src pointers
  295. I2C(LW,R9,R6,0);
  296. if (p->Src.Channels > 1)
  297. {
  298. if (p->Src.Flags & PCM_PLANES)
  299. I2C(LW,R10,R6,4);
  300. else
  301. I2C(ADDIU,R10,R9,p->Src.Bits>>3);
  302. }
  303. I2C(LW,R4,SP,OFS(stack,State));
  304. I2C(LW,R7,R4,OFS(pcmstate,Step));
  305. I2C(LW,R8,R4,OFS(pcmstate,Pos));
  306. if (p->UseVolume)
  307. I2C(LW,R24,SP,OFS(stack,Volume));
  308. if (p->ActualDither)
  309. {
  310. I2C(LW,R24,R4,OFS(pcmstate,Dither[0]));
  311. I2C(LW,R25,R4,OFS(pcmstate,Dither[1]));
  312. }
  313. if (p->Clip>0)
  314. {
  315. IConst(R4,p->MinLimit);
  316. IConst(R5,p->MaxLimit);
  317. }
  318. Speed = Label(0);
  319. I2C(ADDIU,R13,ZERO,256);
  320. I2P(BNE,R13,R7,Speed);
  321. PCMLoop(p,0);
  322. InstPost(Speed);
  323. PCMLoop(p,1);
  324. }
  325. #endif