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

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_sh3.c 304 2005-10-20 11:02:59Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "../dyncode/dyncode.h"
  25. #include "pcm_soft.h"
  26. #if defined(SH3)
  27. typedef struct stack
  28. {
  29. int Step; //backup
  30. int StackFrame[7];
  31. void* this;    //R4
  32. char* Dst;    //R5
  33. char* Src;     //R6
  34. int DstLength; //R7
  35. pcmstate* State;
  36. int Volume;
  37. } stack;
  38. // R0 temp index
  39. // R13,R1 dither (or R13=shift,-shift) (or R1=volume)
  40. // R2,R3 value
  41. // R4 Min
  42. // R5 Max
  43. // R7 Step
  44. // R8 Pos
  45. // R9 SrcLeft
  46. // R10 SrcRight
  47. // R11 DstLeft
  48. // R12 DstRight
  49. // R14 DstLeftEnd
  50. void PCMLoop(pcm_soft* p,bool_t Speed)
  51. {
  52. bool_t SrcPacked = !(p->Src.Flags & PCM_PLANES) && p->Src.Channels==2;
  53. dyninst* Loop;
  54. reg Left;
  55. reg Right;
  56. reg Shift;
  57. if (!p->ActualDither && p->Shift)
  58. I1C(MOVI,R13,p->Shift);
  59. if (p->ActualDither)
  60. if (Speed)
  61. I2C(MOVL_STOFS,R7,SP,OFS(stack,Step)); // save backup
  62. else
  63. I1C(MOVI,R7,-p->Shift);
  64. Loop = Label(1);
  65. Left = R2;
  66. if (p->UseLeft)
  67. Right = R3;
  68. else
  69. Right = R2;
  70. if (Speed)
  71. {
  72. I2(MOV,R8,R0);
  73. IShift(R0,NONE,-8);
  74. IShift(R0,NONE,p->SrcShift);
  75. switch (p->Src.Bits)
  76. {
  77. case 8:
  78. if (p->UseLeft)
  79. I2(MOVB_LDR0,R9,Left);
  80. if (p->UseRight)
  81. I2(MOVB_LDR0,R10,Right);
  82. if (p->SrcUnsigned)
  83. {
  84. I2(EXTUB,R2,R2);
  85. if (p->SrcChannels>1)
  86. I2(EXTUB,R3,R3);
  87. }
  88. break;
  89. case 16:
  90. if (p->UseLeft)
  91. I2(MOVW_LDR0,R9,Left);
  92. if (p->UseRight)
  93. I2(MOVW_LDR0,R10,Right);
  94. if (p->SrcUnsigned)
  95. {
  96. I2(EXTUW,R2,R2);
  97. if (p->SrcChannels>1)
  98. I2(EXTUW,R3,R3);
  99. }
  100. break;
  101. case 32:
  102. if (p->UseLeft)
  103. I2(MOVL_LDR0,R9,Left);
  104. if (p->UseRight)
  105. I2(MOVL_LDR0,R10,Right);
  106. break;
  107. }
  108. I2(ADD,R7,R8);
  109. }
  110. else
  111. {
  112. switch (p->Src.Bits)
  113. {
  114. case 8:
  115. if (p->UseLeft)
  116. {
  117. I2(MOVB_LDADD,R9,Left);
  118. if (SrcPacked && !p->UseRight) I1C(ADDI,R9,1);
  119. }
  120. if (p->UseRight)
  121. if (SrcPacked)
  122. {
  123. if (!p->UseLeft) I1C(ADDI,R9,1);
  124. I2(MOVB_LDADD,R9,Right);
  125. }
  126. else
  127. I2(MOVB_LDADD,R10,Right);
  128. if (p->SrcUnsigned)
  129. {
  130. I2(EXTUB,R2,R2);
  131. if (p->SrcChannels>1)
  132. I2(EXTUB,R3,R3);
  133. }
  134. break;
  135. case 16:
  136. if (p->UseLeft)
  137. {
  138. I2(MOVW_LDADD,R9,Left);
  139. if (SrcPacked && !p->UseRight) I1C(ADDI,R9,2);
  140. }
  141. if (p->UseRight)
  142. if (SrcPacked)
  143. {
  144. if (!p->UseLeft) I1C(ADDI,R9,2);
  145. I2(MOVW_LDADD,R9,Right);
  146. }
  147. else
  148. I2(MOVW_LDADD,R10,Right);
  149. if (p->SrcUnsigned)
  150. {
  151. I2(EXTUW,R2,R2);
  152. if (p->SrcChannels>1)
  153. I2(EXTUW,R3,R3);
  154. }
  155. break;
  156. case 32:
  157. if (p->UseLeft)
  158. {
  159. I2(MOVL_LDADD,R9,Left);
  160. if (SrcPacked && !p->UseRight) I1C(ADDI,R9,4);
  161. }
  162. if (p->UseRight)
  163. if (SrcPacked)
  164. {
  165. if (!p->UseLeft) I1C(ADDI,R9,4);
  166. I2(MOVL_LDADD,R9,Right);
  167. }
  168. else
  169. I2(MOVL_LDADD,R10,Right);
  170. break;
  171. }
  172. }
  173. if (p->InstSrcUnsigned)
  174. {
  175. MB(); I1P(MOVL_PC,R0,p->InstSrcUnsigned,0);
  176. I2(SUB,R0,R2);
  177. if (p->SrcChannels>1)
  178. I2(SUB,R0,R3);
  179. }
  180. else
  181. if (p->SrcUnsigned == 128) 
  182. {
  183. I1C(ADDI,R2,-128);
  184. if (p->SrcChannels>1)
  185. I1C(ADDI,R3,-128);
  186. }
  187. if (p->Stereo)
  188. {
  189. if ((p->Src.Flags ^ p->Dst.Flags) & PCM_SWAPPEDSTEREO)
  190. {
  191. Left = R3;
  192. Right = R2;
  193. }
  194. else
  195. {
  196. Left = R2;
  197. Right = R3;
  198. }
  199. }
  200. else
  201. {
  202. if (p->Join)
  203. I2(ADD,R3,R2);
  204. Right = Left = R2;
  205. }
  206. if (p->ActualDither)
  207. {
  208. I2(ADD,R13,R2);
  209. I2(MOV,R2,R13);
  210. if (p->Stereo) 
  211. {
  212. I2(ADD,R1,R3);
  213. I2(MOV,R3,R1);
  214. }
  215. }
  216. if (p->Clip>0)
  217. {
  218. dyninst* ClipMin = Label(0);
  219. dyninst* ClipMax = Label(0);
  220. I2(CMPGT,R2,R4);
  221. I0P(BFS,ClipMin);
  222. I2(CMPGT,R5,R2); // delay slot
  223. I2(MOV,R4,R2);
  224. InstPost(ClipMin);
  225. I0P(BFS,ClipMax);
  226. I1C(ADDI,R11,1<<p->DstShift); // delay slot
  227. I2(MOV,R5,R2);
  228. InstPost(ClipMax);
  229. if (p->Stereo)
  230. {
  231. ClipMin = Label(0);
  232. ClipMax = Label(0);
  233. I2(CMPGT,R3,R4);
  234. I0P(BFS,ClipMin);
  235. I2(CMPGT,R5,R3); // delay slot
  236. I2(MOV,R4,R3);
  237. InstPost(ClipMin);
  238. I0P(BFS,ClipMax);
  239. I1C(ADDI,R12,1<<p->DstShift); // delay slot
  240. I2(MOV,R5,R3);
  241. InstPost(ClipMax);
  242. }
  243. else
  244. if (p->Dst.Channels>1)
  245. I1C(ADDI,R12,1<<p->DstShift); // delay slot
  246. }
  247. else
  248. {
  249. I1C(ADDI,R11,1<<p->DstShift);
  250. if (p->Dst.Channels>1)
  251. I1C(ADDI,R12,1<<p->DstShift);
  252. }
  253. I2(CMPEQ,R11,R14);
  254. if (p->Shift)
  255. {
  256. if (p->ActualDither)
  257. {
  258. I1C(MOVI,R0,p->Shift);
  259. Shift = R0;
  260. }
  261. else
  262. Shift = R13;
  263. I2(SHAD,Shift,R2);
  264. if (p->Stereo) I2(SHAD,Shift,R3);
  265. }
  266. if (p->ActualDither)
  267. {
  268. if (Speed)
  269. I1C(MOVI,R7,-p->Shift);
  270. I2(MOV,R2,R0);
  271. I2(SHAD,R7,R0);
  272. I2(SUB,R0,R13);
  273. if (p->Stereo)
  274. {
  275. I2(MOV,R3,R0);
  276. I2(SHAD,R7,R0);
  277. I2(SUB,R0,R1);
  278. }
  279. if (Speed)
  280. I2C(MOVL_LDOFS,SP,R7,OFS(stack,Step));
  281. }
  282. if (p->InstDstUnsigned)
  283. {
  284. MB(); I1P(MOVL_PC,R0,p->InstDstUnsigned,0);
  285. I1C(ADD,R0,Left);
  286. if (Left != Right)
  287. I1C(ADD,R0,Right);
  288. }
  289. else
  290. if (p->DstUnsigned == 128) 
  291. {
  292. // p->Dst.Bits=8 so doesn't matter if it's add or sub
  293. I1C(ADDI,Left,-128); 
  294. if (Left != Right)
  295. I1C(ADDI,Right,-128);
  296. }
  297. switch (p->Dst.Bits)
  298. {
  299. case 8:
  300. I2(MOVB_ST,Left,R11);
  301. if (p->Dst.Channels>1)
  302. I2(MOVB_ST,Right,R12);
  303. break;
  304. case 16:
  305. I2(MOVW_ST,Left,R11);
  306. if (p->Dst.Channels>1)
  307. I2(MOVW_ST,Right,R12);
  308. break;
  309. case 32:
  310. I2(MOVL_ST,Left,R11);
  311. if (p->Dst.Channels>1)
  312. I2(MOVL_ST,Right,R12);
  313. break;
  314. }
  315. DS(); I0P(BFS,Loop);
  316. if (p->ActualDither)
  317. {
  318. I2(MOV,SP,R0);
  319. I1C(ADDI,R0,OFS(stack,State));
  320. I2(MOVL_LD,R0,R4);
  321. I2C(MOVL_STOFS,R13,R4,OFS(pcmstate,Dither[0]));
  322. I2C(MOVL_STOFS,R1,R4,OFS(pcmstate,Dither[1]));
  323. }
  324. CodeEnd(7,OFS(stack,StackFrame));
  325. }
  326. void PCMCompile(pcm_soft* p)
  327. {
  328. dyninst* Speed;
  329. dyninst* Min = NULL;
  330. dyninst* Max = NULL;
  331. CodeBegin(7,OFS(stack,StackFrame));
  332. p->InstSrcUnsigned = NULL;
  333. p->InstDstUnsigned = NULL;
  334. if (p->SrcUnsigned && p->SrcUnsigned != 128)
  335. p->InstSrcUnsigned = InstCreate32(p->SrcUnsigned,NONE,NONE,NONE,0,0);
  336. if (p->DstUnsigned && p->DstUnsigned != 128)
  337. p->InstDstUnsigned = InstCreate32(p->DstUnsigned,NONE,NONE,NONE,0,0);
  338. // dst pointers
  339. I2C(MOVL_LDOFS,R5,R11,0);
  340. I1C(ADDI,R11,-(1<<p->DstShift)); // back one step
  341. if (p->Dst.Channels > 1)
  342. {
  343. if (p->Dst.Flags & PCM_PLANES)
  344. {
  345. I2C(MOVL_LDOFS,R5,R12,4);
  346. I1C(ADDI,R12,-(1<<p->DstShift)); // back one step
  347. }
  348. else
  349. {
  350. I2(MOV,R11,R12);
  351. I1C(ADDI,R12,1<<(p->DstShift-1));
  352. }
  353. }
  354. I2(MOV,R7,R14);
  355. I2(ADD,R11,R14); // dstend
  356. // src pointers
  357. I2C(MOVL_LDOFS,R6,R9,0);
  358. if (p->Src.Channels > 1)
  359. {
  360. if (p->Src.Flags & PCM_PLANES)
  361. I2C(MOVL_LDOFS,R6,R10,4);
  362. else
  363. {
  364. I2(MOV,R9,R10);
  365. I1C(ADDI,R10,p->Src.Bits>>3);
  366. }
  367. }
  368. I2(MOV,SP,R0);
  369. I1C(ADDI,R0,OFS(stack,State));
  370. I2(MOVL_LD,R0,R4);
  371. I2C(MOVL_LDOFS,R4,R7,OFS(pcmstate,Step));
  372. I2C(MOVL_LDOFS,R4,R8,OFS(pcmstate,Pos));
  373. /*
  374. if (p->UseVolume)
  375. {
  376. I1C(ADDI,R0,OFS(stack,Volume)-OFS(stack,State));
  377. I2(MOVL_LD,R0,R1);
  378. }
  379. */
  380. if (p->ActualDither)
  381. {
  382. I2C(MOVL_LDOFS,R4,R13,OFS(pcmstate,Dither[0]));
  383. I2C(MOVL_LDOFS,R4,R1,OFS(pcmstate,Dither[1]));
  384. }
  385. if (p->Clip>0)
  386. {
  387. Min = InstCreate32(p->MinLimit,NONE,NONE,NONE,0,0);
  388. Max = InstCreate32(p->MaxLimit,NONE,NONE,NONE,0,0);
  389. I1P(MOVL_PC,R4,Min,0);
  390. I1P(MOVL_PC,R5,Max,0);
  391. }
  392. Speed = Label(0);
  393. I1C(MOVI,R2,64);
  394. I1(SHLL2,R2);
  395. I2(CMPEQ,R2,R7);
  396. I0P(BF,Speed);
  397. PCMLoop(p,0);
  398. InstPost(Speed);
  399. PCMLoop(p,1);
  400. Align(4);
  401. if (Min) InstPost(Min);
  402. if (Max) InstPost(Max);
  403. if (p->InstSrcUnsigned) InstPost(p->InstSrcUnsigned);
  404. if (p->InstDstUnsigned) InstPost(p->InstDstUnsigned);
  405. }
  406. #endif