blit_sh3_fix.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: blit_sh3_fix.c 271 2005-08-09 08:31:35Z 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 "blit_soft.h"
  26. #if defined(SH3) 
  27. typedef struct stack
  28. {
  29. int EndOfRect;
  30. int EndOfLine;
  31. int DstNext;
  32. int SrcNext;
  33. int UVNext;
  34. int EndOfLineInc;
  35. int StackFrame[7];
  36. void* This;   //R4
  37. char* Dst;    //R5
  38. char* Src;    //R6
  39. int DstPitch; //R7
  40. int SrcPitch;
  41. int Width; 
  42. int Height;
  43. int Src2SrcLast;
  44. } stack;
  45. // R0 lookup
  46. // R10 buffer_u
  47. // R11 buffer_v
  48. // R12 buffer_y1
  49. // R14 buffer_y2
  50. // R4  r / pal:dither acc
  51. // R5  g / pal:mask
  52. // R6  b / pal:mask
  53. // R8  y1
  54. // R9  y2
  55. // R2  tmp / pal:uv
  56. // R3  tmp 
  57. // R7  tmp / endofline 
  58. // R13 dest1
  59. // R1  pitch
  60. static NOINLINE void Fix_RGB_UV_LoadUV(blit_soft* p)
  61. {
  62. //set R4 =           RVMul*v + RAdd
  63. //set R5 = GUMul*u + GVMul*v + GAdd
  64. //set R6 = BUMul*u +           BAdd
  65. I2(MOVB_LDADD,R10,R2); //u
  66. I2(MOVB_LDADD,R11,R3); //v
  67. if (p->DstPalette)
  68. {
  69. I2(EXTUB,R2,R2);
  70. I2(EXTUB,R3,R3);
  71. I1(SHLR,R2);
  72. I1(SHLR,R3);
  73. I1(SHLL8,R2);
  74. I1(SHLL16,R3);
  75. I2(OR,R3,R2);
  76. }
  77. else
  78. {
  79. I1C(MOVI,R8,1);
  80. I1(SHLL8,R8);
  81. I2(ADD,R8,R2); //+=256
  82. I1(SHLL,R8);
  83. I2(ADD,R8,R3); //+=512
  84. I1(SHLL2,R2);
  85. I1(SHLL2,R3);
  86. I2(MOVW_LDR0,R2,R6);
  87. I2(MOVW_LDR0,R3,R4);
  88. I1C(ADDI,R2,2);
  89. I1C(ADDI,R3,2);
  90. I2(MOVW_LDR0,R2,R5);
  91. I2(MOVW_LDR0,R3,R9);
  92. I2(ADD,R9,R5);
  93. }
  94. }
  95. static NOINLINE void Fix_RGB_UV_Pixel(blit_soft* p, int Row)
  96. {
  97. //load Y
  98. if (p->SwapXY)
  99. {
  100. if (p->DirX>0)
  101. {
  102. I2(MOVB_LDADD,R14,R9); //y2
  103. I2(MOVB_LDADD,R12,R8); //y1
  104. }
  105. else
  106. {
  107. I2(MOVB_LDADD,R14,R8); //y1
  108. I2(MOVB_LDADD,R12,R9); //y2
  109. }
  110. }
  111. else
  112. {
  113. reg Y = (reg)(Row==0?R12:R14);
  114. if (p->DirX>0)
  115. {
  116. I2(MOVB_LDADD,Y,R8); //y1
  117. I2(MOVB_LDADD,Y,R9); //y2
  118. }
  119. else
  120. {
  121. I2(MOVB_LDADD,Y,R9); //y2
  122. I2(MOVB_LDADD,Y,R8); //y1
  123. }
  124. }
  125. if (p->DstPalette)
  126. {
  127. I2(EXTUB,R8,R8);
  128. I2(EXTUB,R9,R9);
  129. I1(SHLR,R8);
  130. I1(SHLR,R9);
  131. I1(SHLL16,R8);
  132. I1(SHLL16,R9);
  133. I1(SHLL8,R8);
  134. I1(SHLL8,R9);
  135. I2(OR,R2,R8);
  136. I2(OR,R2,R9);
  137. I2(ADD,R8,R4); //      yyvvuu00
  138. I2(MOV,R4,R3); 
  139. I2(MOV,R4,R7);
  140. I2(AND,R5,R3); // mask F0F00000
  141. I2(AND,R6,R7); // mask 0000F000
  142. I1(SHLR16,R3);
  143. I1(SHLR8,R7);
  144. I1(SHLR2,R3);
  145. I1(SHLL2,R7);
  146. I2(OR,R7,R3);
  147. I2(MOVL_LDR0,R3,R8);
  148. I2(SUB,R8,R4);
  149. I2(ADD,R9,R4); //      yyvvuu00
  150. I2(MOV,R4,R3); 
  151. I2(MOV,R4,R7);
  152. I2(AND,R5,R3); // mask F0F00000
  153. I2(AND,R6,R7); // mask 0000F000
  154. I1(SHLR16,R3);
  155. I1(SHLR8,R7);
  156. I1(SHLR2,R3);
  157. I1(SHLL2,R7);
  158. I2(OR,R7,R3);
  159. I2(MOVL_LDR0,R3,R9);
  160. I2(SUB,R9,R4);
  161. //Break();
  162. }
  163. else
  164. {
  165. I2(MOVB_LDR0,R8,R8);
  166. I2(MOVB_LDR0,R9,R9);
  167. I2(MOV,R4,R2);
  168. I2(ADD,R8,R2);
  169. I2(MOVB_LDR0,R2,R2);
  170. I2(MOV,R5,R3);
  171. I2(ADD,R8,R3);
  172. I2(MOVB_LDR0,R3,R3);
  173. I2(ADD,R6,R8);
  174. I2(MOVB_LDR0,R8,R8);
  175. IShift(R2,R7,p->DstPos[0]);
  176. IShift(R3,R7,p->DstPos[1]);
  177. IShift(R8,R7,p->DstPos[2]);
  178. I2(OR,R2,R8);
  179. I2(OR,R3,R8);
  180. I2(MOV,R4,R2);
  181. I2(ADD,R9,R2);
  182. I2(MOVB_LDR0,R2,R2);
  183. I2(MOV,R5,R3);
  184. I2(ADD,R9,R3);
  185. I2(MOVB_LDR0,R3,R3);
  186. I2(ADD,R6,R9);
  187. I2(MOVB_LDR0,R9,R9);
  188. IShift(R2,R7,p->DstPos[0]);
  189. IShift(R3,R7,p->DstPos[1]);
  190. IShift(R9,R7,p->DstPos[2]);
  191. I2(OR,R2,R9);
  192. I2(OR,R3,R9);
  193. if (!p->DstDoubleX && p->DstBPP <= 16)
  194. {
  195. I1(SHLL16,R9);
  196. I2(OR,R9,R8);
  197. }
  198. }
  199. }
  200. // R3,R2 for temp
  201. static NOINLINE void Write(blit_soft* p,reg Dst,reg A,reg B,bool_t Prepare)
  202. {
  203. switch (p->DstBPP)
  204. {
  205. case 8:
  206. if (p->DstDoubleX)
  207. {
  208. if (Prepare)
  209. {
  210. I2(EXTUB,B,B);
  211. I2(EXTUB,A,A);
  212. I1(SHLL16,B);
  213. I2(OR,B,A);
  214. I2(MOV,A,R3);
  215. I1(SHLL8,R3);
  216. I2(OR,R3,A);
  217. }
  218. I2(MOVL_ST,A,Dst);
  219. }
  220. else
  221. {
  222. if (Prepare)
  223. {
  224. I2(EXTUB,A,A);
  225. I1(SHLL8,B);
  226. I2(OR,B,A);
  227. }
  228. I2(MOVW_ST,A,Dst);
  229. }
  230. break;
  231. case 16:
  232. if (p->DstDoubleX)
  233. {
  234. if (Prepare)
  235. {
  236. I2(MOV,A,R3);
  237. I2(MOV,B,R2);
  238. I1(SHLL16,R3);
  239. I1(SHLL16,R2);
  240. I2(OR,R3,A);
  241. I2(OR,R2,B);
  242. }
  243. I2C(MOVL_STOFS,B,Dst,4);
  244. }
  245. I2C(MOVL_STOFS,A,Dst,0);
  246. break;
  247. }
  248. }
  249. void Fix_RGB_UV(blit_soft* p)
  250. {
  251. dyninst* Quit;
  252. dyninst* LoopYAddr;
  253. dyninst* Mask1;
  254. dyninst* Mask2;
  255. dyninst* LoopY;
  256. dyninst* LoopX;
  257. if (p->RScaleX == 8 || p->RScaleY == 8)
  258. p->DstAlignSize = 4;
  259. p->DstStepX = p->DirX * ((p->DstBPP*2) >> 3) << p->DstDoubleX;
  260. CodeBegin(7,OFS(stack,StackFrame));
  261. I2C(MOVL_LDOFS,R4,R0,OFS(blit_soft,LookUp_Data));
  262. if (!p->DstPalette)
  263. {
  264. CalcLookUp(p,0);
  265. I1C(ADDI,R0,64);
  266. I1C(ADDI,R0,64);
  267. }
  268. I2C(MOVL_LDOFS,R5,R13,0); //dst
  269. I2C(MOVL_LDOFS,R6,R10,4); //U
  270. I2C(MOVL_LDOFS,R6,R11,8); //V
  271. I2C(MOVL_LDOFS,R6,R12,0); //Y
  272. I2(MOV,R7,R1); //dstpitch
  273. I1C(MOVI,R2,OFS(stack,This));
  274. I2(ADD,SP,R2);
  275. I2C(MOVL_LDOFS,R2,R7,OFS(stack,SrcPitch)-OFS(stack,This));
  276. I2C(MOVL_LDOFS,R2,R5,OFS(stack,Height)-OFS(stack,This));
  277. I2C(MOVL_LDOFS,R2,R4,OFS(stack,Width)-OFS(stack,This));
  278. //SrcNext = 2*Src->Pitch - (Width >> SrcDoubleX)
  279. I2(MOV,R7,R2);
  280. I1(SHLL,R2);
  281. I2(MOV,R4,R3);
  282. IShift(R3,NONE,-p->SrcDoubleX);
  283. I2(SUB,R3,R2);
  284. I2C(MOVL_STOFS,R2,SP,OFS(stack,SrcNext));
  285. //UVNext = (Src->Pitch >> 1) - (Width >> SrcDoubleX >> 1);
  286. I2(MOV,R7,R2);
  287. I1(SHAR,R2);
  288. I2(MOV,R4,R3);
  289. IShift(R3,NONE,-p->SrcDoubleX-1);
  290. I2(SUB,R3,R2);
  291. I2C(MOVL_STOFS,R2,SP,OFS(stack,UVNext));
  292. if (p->DirX<0) //adjust reversed destination for block size
  293. I1C(ADDI,R13,p->DstStepX+(p->DstBPP >> 3));
  294. if (p->SwapXY)
  295. {
  296. I1C(MOVI,R3,p->DstBPP * p->DirX);
  297. I2(MULL,R3,R5); // p->DstBPP * p->DirX * Height
  298. I1C(MOVI,R2,-3);
  299. I1(STS_MACL,R3);
  300. I2(SHAD,R2,R3);
  301. I2(ADD,R13,R3);
  302. I2C(MOVL_STOFS,R3,SP,OFS(stack,EndOfRect));
  303. //DstNext = DstStepX - Width * DstPitch;
  304. I2(MULL,R1,R4);
  305. I1C(MOVI,R2,p->DstStepX);
  306. I1(STS_MACL,R3);
  307. I2(SUB,R3,R2);
  308. I2C(MOVL_STOFS,R2,SP,OFS(stack,DstNext));
  309. }
  310. else
  311. {
  312. I2(MULL,R1,R5); //Height * DstPitch
  313. I1(STS_MACL,R3);
  314. I2(ADD,R13,R3);
  315. I2C(MOVL_STOFS,R3,SP,OFS(stack,EndOfRect));
  316. //DstNext = ((DstPitch*2 << DstDoubleY) - DirX * Width << DstBPP2;
  317. I2(MOV,R1,R2);
  318. IShift(R2,NONE,p->DstDoubleY+1);
  319. I2(MOV,R4,R3);
  320. IShift(R3,NONE,p->DstBPP2);
  321. I2(p->DirX>0?SUB:ADD,R3,R2);
  322. I2C(MOVL_STOFS,R2,SP,OFS(stack,DstNext));
  323. }
  324. if (p->SwapXY)
  325. {
  326. I2(MULL,R1,R4); //width*dstpitch
  327. I1(STS_MACL,R3);
  328. I2(SUB,R1,R3); // - DstPitch
  329. }
  330. else
  331. {
  332. I2(MOV,R4,R3);
  333. IShift(R3,NONE,p->DstBPP2);
  334. if (p->DirX < 0)
  335. I2(NEG,R3,R3);
  336. I1C(ADDI,R3,-p->DstStepX); // -p->DstStepX
  337. }
  338. I2C(MOVL_STOFS,R3,SP,OFS(stack,EndOfLineInc));
  339. I2(MOV,R12,R14);
  340. I2(ADD,R7,R14);
  341. Quit = Label(0);
  342. LoopY = Label(1);
  343. LoopYAddr = ICode(LoopY,0);
  344. if (p->DstPalette)
  345. {
  346. Mask1 = InstCreate32(0xF0F00000,NONE,NONE,NONE,0,0);
  347. Mask2 = InstCreate32(0x0000F000,NONE,NONE,NONE,0,0);
  348. I1P(MOVL_PC,R5,Mask1,0);
  349. I1P(MOVL_PC,R6,Mask2,0);
  350. I1C(MOVI,R4,0);
  351. }
  352. // R3 = EndOfLineInc
  353. I2(MOV,R13,R7);
  354. I2(ADD,R3,R7);
  355. I2C(MOVL_STOFS,R7,SP,OFS(stack,EndOfLine));
  356. LoopX = Label(1);
  357. {
  358. Fix_RGB_UV_LoadUV(p);
  359. Fix_RGB_UV_Pixel(p,0);
  360. Write(p,R13,R8,R9,1);
  361. I2(ADD,R1,R13);
  362. if (p->DstDoubleY)
  363. {
  364. Write(p,R13,R8,R9,0);
  365. I2(ADD,R1,R13);
  366. }
  367. Fix_RGB_UV_Pixel(p,1);
  368. I2C(MOVL_LDOFS,SP,R7,OFS(stack,EndOfLine));
  369. Write(p,R13,R8,R9,1);
  370. if (p->DstDoubleY)
  371. {
  372. I2(ADD,R1,R13);
  373. Write(p,R13,R8,R9,0);
  374. }
  375. if (p->SwapXY)
  376. {
  377. I2(CMPEQ,R13,R7);
  378. I2(ADD,R1,R13);
  379. }
  380. else
  381. {
  382. I2(SUB,R1,R13);
  383. if (p->DstDoubleY)
  384. {
  385. I2(SUB,R1,R13);
  386. I2(SUB,R1,R13);
  387. }
  388. I2(CMPEQ,R13,R7);
  389. I1C(ADDI,R13,p->DstStepX);
  390. }
  391. DS(); I0P(BFS,LoopX);
  392. }
  393. I2C(MOVL_LDOFS,SP,R2,OFS(stack,SrcNext));
  394. I2C(MOVL_LDOFS,SP,R3,OFS(stack,DstNext));
  395. I2C(MOVL_LDOFS,SP,R9,OFS(stack,UVNext));
  396. I2C(MOVL_LDOFS,SP,R8,OFS(stack,EndOfRect));
  397. //increment pointers
  398. I2(ADD,R2,R12);
  399. I2(ADD,R2,R14);
  400. I2(ADD,R3,R13);
  401. I1P(MOVL_PC,R2,LoopYAddr,0);
  402. I2(ADD,R9,R10);
  403. I2(ADD,R9,R11);
  404. MB(); I2(CMPEQ,R13,R8);
  405. DS(); I0P(BTS,Quit);
  406. I2C(MOVL_LDOFS,SP,R3,OFS(stack,EndOfLineInc)); //prepare registers for next row
  407. DS(); I1(JMP,R2);
  408. InstPost(Quit);
  409. CodeEnd(7,OFS(stack,StackFrame));
  410. Align(4);
  411. InstPost(LoopYAddr);
  412. if (p->DstPalette)
  413. {
  414. InstPost(Mask1);
  415. InstPost(Mask2);
  416. }
  417. }
  418. #endif