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

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_arm_fix.c 543 2006-01-07 22:06:24Z 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(ARM) 
  27. typedef struct stack
  28. {
  29. int EndOfLine;
  30. int EndOfRect;
  31. int DstPitch; 
  32. int DstNext;
  33. int YNext;
  34. int UVNext;
  35. int StackFrame[STACKFRAME];
  36. //void* this   R0
  37. //char* Dst    R1
  38. //char* Src    R2
  39. //int DstPitch R3 can be signed
  40. int SrcPitch; //can be signed
  41. int Width; 
  42. int Height;
  43. int Src2SrcLast;
  44. } stack;
  45. static NOINLINE void Fix_RGB_UV_LoadUV(blit_soft* p)
  46. {
  47. //set R4 =           RVMul*v + RAdd
  48. //set R5 = GUMul*u + GVMul*v + GAdd
  49. //set R6 = BUMul*u +           BAdd
  50. if (p->Dither)
  51. {
  52. //R0,R4,R8 for temporary
  53. //R5(DiffMask),R6(Src2SrcLast),R7(EndOfLine)
  54. if (p->OnlyDiff)
  55. {
  56. Half(); I3(LDR,R8,R12,R6);
  57. Half(); I2C(LDR_POST,R0,R12,2);
  58. Half(); I3(LDR,R4,R14,R6);
  59. //xscale stall
  60. I3(EOR,R8,R8,R0);
  61. Half(); I2C(LDR_POST,R0,R14,2);
  62. S(); I3(TST,NONE,R8,R5);
  63. C(EQ); Byte(); I3(LDR,R8,R10,R6);
  64. C(EQ); I3(EOR,R4,R4,R0);
  65. Byte(); I2C(LDR_POST,R0,R10,1); //u
  66. C(EQ); S(); I3(TST,NONE,R4,R5);
  67. C(EQ); Byte(); I3(LDR,R4,R11,R6);
  68. C(EQ); I3(EOR,R8,R8,R0);
  69. Byte(); I2C(LDR_POST,R0,R11,1); //v
  70. C(EQ); S(); I3(TST,NONE,R8,R5);
  71. //xscale stall
  72. C(EQ); I3(EOR,R4,R4,R0);
  73. C(EQ); S(); I3(TST,NONE,R4,R5);
  74. if (p->SwapXY)
  75. {
  76. MB(); I2C(LDR,R8,SP,OFS(stack,DstPitch));
  77. C(EQ); I3S(ADD,R9,R9,R8,LSL,1+p->DstDoubleY);
  78. }
  79. else
  80. {
  81. C(EQ); I2C(ADD,R9,R9,p->DstStepX);
  82. }
  83. I0P(B,EQ,p->Skip);
  84. // R0=v
  85. if (p->ColorLookup)
  86. {
  87. Byte(); I2C(LDR,R5,R10,-1);   //u
  88. I1P(MOV,R8,p->LookUp,0);
  89. }
  90. }
  91. else
  92. {
  93. Byte(); I2C(LDR_POST,R0,R11,1); //v
  94. if (p->ColorLookup)
  95. {
  96. Byte(); I2C(LDR_POST,R5,R10,1); //u
  97. }
  98. }
  99. if (!p->ColorLookup)
  100. {
  101. I1P(LDR,R5,p->GAdd,0);
  102. I1P(LDR,R8,p->GVMul,0);
  103. I1P(LDR,R4,p->RAdd,0);
  104. I1P(LDR,R6,p->RVMul,0);
  105. I4(MLA,R5,R8,R0,R5);
  106. Byte(); 
  107. if (p->OnlyDiff) //already incremented
  108. I2C(LDR,R8,R10,-1);   //u
  109. else
  110. I2C(LDR_POST,R8,R10,1); //u
  111. I4(MLA,R4,R6,R0,R4);
  112. I1P(LDR,R7,p->GUMul,0);
  113. I1P(LDR,R6,p->BAdd,0);
  114. I1P(LDR,R0,p->BUMul,0);
  115. I4(MLA,R5,R7,R8,R5);
  116. //R7 Y read will moveback here (this will prevent stall by R0)
  117. I4(MLA,R6,R0,R8,R6);
  118. I1P(LDR,R8,p->YMul,0); //restore R8
  119. }
  120. else
  121. {
  122. I2C(ADD,R0,R0,p->LookUp_V);
  123. I3S(LDR,R4,R8,R0,LSL,2); // RVMul+RAdd | GVMul+GAdd
  124. I2C(ADD,R5,R5,p->LookUp_U);
  125. I3S(LDR,R6,R8,R5,LSL,2); // BUMul | GUMul
  126. I3S(MOV,R5,NONE,R4,LSL,16); 
  127. I3S(ADD,R5,R5,R6,LSL,16); // GUMul+GVMul+GAdd | 0000
  128. }
  129. }
  130. else
  131. {
  132. //R0,R1,R2,R3,R4 for temporary
  133. //R5(DiffMask),R6(Src2SrcLast),R7(EndOfLine)
  134. if (p->OnlyDiff)
  135. {
  136. Half(); I3(LDR,R0,R12,R6);
  137. Half(); I2C(LDR_POST,R1,R12,2);
  138. Half(); I3(LDR,R4,R14,R6);
  139. Half(); I2C(LDR_POST,R2,R14,2);
  140. I3(EOR,R0,R0,R1);
  141. S(); I3(TST,NONE,R0,R5);
  142. I3(EOR,R4,R4,R2);
  143. C(EQ); S(); I3(TST,NONE,R4,R5);
  144. C(EQ); Byte(); I3(LDR,R0,R10,R6);
  145. Byte(); I2C(LDR_POST,R1,R10,1); //u
  146. C(EQ); Byte(); I3(LDR,R4,R11,R6);
  147. Byte(); I2C(LDR_POST,R2,R11,1); //v
  148. C(EQ); I3(EOR,R0,R0,R1);
  149. C(EQ); S(); I3(TST,NONE,R0,R5);
  150. C(EQ); I3(EOR,R4,R4,R2);
  151. C(EQ); S(); I3(TST,NONE,R4,R5);
  152. if (p->SwapXY)
  153. {
  154. MB(); I2C(LDR,R3,SP,OFS(stack,DstPitch));
  155. C(EQ); I3S(ADD,R9,R9,R3,LSL,1+p->DstDoubleY);
  156. }
  157. else
  158. {
  159. C(EQ); I2C(ADD,R9,R9,p->DstStepX);
  160. }
  161. I0P(B,EQ,p->Skip);
  162. }
  163. else
  164. {
  165. Byte(); I2C(LDR_POST,R1,R10,1); //u
  166. Byte(); I2C(LDR_POST,R2,R11,1); //v
  167. }
  168. if (!p->ColorLookup)
  169. {
  170. I1P(LDR,R5,p->GAdd,0);
  171. I1P(LDR,R0,p->GVMul,0);
  172. I1P(LDR,R4,p->RAdd,0);
  173. I1P(LDR,R7,p->RVMul,0);
  174. I1P(LDR,R6,p->BAdd,0);
  175. I4(MLA,R5,R0,R2,R5); 
  176. I1P(LDR,R0,p->BUMul,0);
  177. I1P(LDR,R3,p->GUMul,0);
  178. I4(MLA,R4,R7,R2,R4); 
  179. I4(MLA,R6,R0,R1,R6); 
  180. I4(MLA,R5,R3,R1,R5); 
  181. }
  182. else
  183. {
  184. I2C(ADD,R1,R1,p->LookUp_U);
  185. I2C(ADD,R2,R2,p->LookUp_V);
  186. I3S(LDR,R6,R8,R1,LSL,2); // BUMul+BAdd | GUMul
  187. I3S(LDR,R4,R8,R2,LSL,2); // RVMul+RAdd | GVMul+GAdd
  188. //double xscale stall
  189. I3S(MOV,R5,NONE,R6,LSL,16); 
  190. I3S(ADD,R5,R5,R4,LSL,16); // GUMul+GVMul+GAdd | 0000
  191. }
  192. }
  193. }
  194. void Fix_RGB_UV_Pixel(blit_soft* p, int Col, int Row)
  195. {
  196. int SatBitR = p->QAdd ? 32 : 24;
  197. int SatBitG = SatBitR;
  198. int SatBitB = SatBitR;
  199. int RPos = p->DstPos[0];
  200. int GPos = p->DstPos[1];
  201. int BPos = p->DstPos[2];
  202. p->Upper = (p->DirX<0) ^ (Col>0);
  203. if (p->Upper && p->DstBPP==8 && p->DstDoubleX)
  204. {
  205. RPos += 16;
  206. GPos += 16;
  207. BPos += 16;
  208. }
  209. else
  210. if (p->Upper && p->DstBPP<=16)
  211. {
  212. RPos += p->DstBPP;
  213. GPos += p->DstBPP;
  214. BPos += p->DstBPP;
  215. }
  216. //load Y
  217. MB();
  218. Byte(); 
  219. if (p->OnlyDiff) //is R12,R14 already incremented?
  220. {
  221. if (p->SwapXY)
  222. I2C(LDR,R7,(reg)(Col==0?R12:R14),-2+Row);
  223. else
  224. I2C(LDR,R7,(reg)(Row==0?R14:R12),-2+Col);
  225. }
  226. else
  227. if (p->SwapXY)
  228. I2C(LDR_POST,R7,(reg)(Col==0?R12:R14),1);
  229. else
  230. I2C(LDR_POST,R7,(reg)(Row==0?R14:R12),1);
  231. if (p->Dither)
  232. {
  233. if (!p->ColorLookup)
  234. {
  235. I3S(ADD,R1,R4,R1,LSR,32-SatBitR+p->DstSize[0]);
  236. I3S(ADD,R2,R5,R2,LSR,32-SatBitG+p->DstSize[1]);
  237. I3S(ADD,R3,R6,R3,LSR,32-SatBitB+p->DstSize[2]);
  238. I4(MLA,R1,R8,R7,R1);
  239. I4(MLA,R2,R8,R7,R2);
  240. I4(MLA,R3,R8,R7,R3);
  241. }
  242. else
  243. {
  244. I3S(ADD,R1,R4,R1,LSL,16+LOOKUP_FIX-p->DstSize[0]);
  245. I3S(LDR,R7,R8,R7,LSL,2); // YMul * y
  246. I3S(ADD,R2,R5,R2,LSL,16+LOOKUP_FIX-p->DstSize[1]);
  247. I3S(ADD,R3,R6,R3,LSL,16+LOOKUP_FIX-p->DstSize[2]);
  248. I3(ADD,R1,R7,R1);
  249. I3(ADD,R2,R7,R2);
  250. I3(ADD,R3,R7,R3);
  251. Byte(); I3S(LDR,R1,R8,R1,LSR,16+LOOKUP_FIX); //sat and 8bit ror (8-RSize)
  252. Byte(); I3S(LDR,R2,R8,R2,LSR,16+LOOKUP_FIX); //sat and 8bit ror (8-GSize)
  253. Byte(); I3S(LDR,R3,R8,R3,LSR,16+LOOKUP_FIX); //sat and 8bit ror (8-BSize)
  254. // R1 = Dither[8-RSize] | Value[RSize]
  255. // R2 = Dither[8-GSize] | Value[GSize]
  256. // R3 = Dither[8-BSize] | Value[BSize]
  257. RPos += p->DstSize[0]; // LSB part -> MSB part
  258. GPos += p->DstSize[1]; // LSB part -> MSB part
  259. BPos += p->DstSize[2]; // LSB part -> MSB part
  260. SatBitR = 2*p->DstSize[0] - 32;
  261. SatBitG = 2*p->DstSize[1] - 32;
  262. SatBitB = 2*p->DstSize[2] - 32;
  263. }
  264. }
  265. else
  266. {
  267. if (!p->ColorLookup)
  268. {
  269. I4(MLA,R1,R8,R7,R4);
  270. I4(MLA,R2,R8,R7,R5);
  271. I4(MLA,R3,R8,R7,R6);
  272. }
  273. else
  274. {
  275. I3S(LDR,R7,R8,R7,LSL,2); // YMul * y
  276. I3(ADD,R1,R7,R4);
  277. I3(ADD,R2,R7,R5);
  278. I3(ADD,R3,R7,R6);
  279. Byte(); I3S(LDR,R1,R8,R1,LSR,16+LOOKUP_FIX); // sat to 8bit
  280. Byte(); I3S(LDR,R2,R8,R2,LSR,16+LOOKUP_FIX); // sat to 8bit
  281. Byte(); I3S(LDR,R3,R8,R3,LSR,16+LOOKUP_FIX); // sat to 8bit
  282. SatBitR = SatBitB = SatBitG = 8;
  283. }
  284. }
  285. if (!p->ColorLookup)
  286. {
  287. if (p->QAdd)
  288. {
  289. I3(QDADD,R1,R1,R1);
  290. I3(QDADD,R2,R2,R2);
  291. I3(QDADD,R3,R3,R3);
  292. }
  293. else
  294. {
  295. I2C(TST,NONE,R1,0xFF000000);
  296. C(NE);I2C(MVN,R1,NONE,0xFF000000);
  297. C(MI);I2C(MOV,R1,NONE,0x00000000);
  298. I2C(TST,NONE,R2,0xFF000000);
  299. C(NE);I2C(MVN,R2,NONE,0xFF000000);
  300. C(MI);I2C(MOV,R2,NONE,0x00000000);
  301. I2C(TST,NONE,R3,0xFF000000);
  302. C(NE);I2C(MVN,R3,NONE,0xFF000000);
  303. C(MI);I2C(MOV,R3,NONE,0x00000000);
  304. }
  305. }
  306. if (p->InvertMask && p->Pos<0)
  307. {
  308. p->Pos = RPos;
  309. MB(); I1P(LDR,R0,p->InvertMask,0);
  310. }
  311. if (p->Pos!=RPos && p->Pos>=0) I3S(MOV,R0,NONE,R0,ROR,RPos-p->Pos);
  312. I3S(p->Pos<0?MOV:EOR,R0,(reg)(p->Pos<0?NONE:R0),R1,LSR,SatBitR-p->DstSize[0]);
  313. I3S(MOV,R7,NONE,R2,LSR,SatBitG-p->DstSize[1]);
  314. I3S(MOV,R0,NONE,R0,ROR,BPos-RPos);
  315. I3S(EOR,R0,R0,R7,ROR,BPos-GPos);
  316. I3S(EOR,R0,R0,R3,LSR,SatBitB-p->DstSize[2]);
  317. p->Pos = BPos;
  318. if (p->Dither && !p->ColorLookup)
  319. {
  320. MB(); I3S(MOV,R1,NONE,R1,LSL,32-SatBitR+p->DstSize[0]);
  321. MB(); I3S(MOV,R2,NONE,R2,LSL,32-SatBitG+p->DstSize[1]);
  322. MB(); I3S(MOV,R3,NONE,R3,LSL,32-SatBitB+p->DstSize[2]);
  323. }
  324. }
  325. void Fix_RGB_UV(blit_soft* p)
  326. {
  327. dyninst* LoopY;
  328. dyninst* LoopX;
  329. int Invert = 0;
  330. int Mask = 0;
  331. p->DstAlignSize = 4;
  332. p->Dither = (boolmem_t)((p->FX.Flags & BLITFX_DITHER)!=0);
  333. if (p->DstDoubleX || p->DstDoubleY || p->DstBPP>16)
  334. p->Dither = 0;
  335. p->DstStepX = p->DirX * ((p->DstBPP*2) >> 3) << p->DstDoubleX;
  336. p->LookUp = NULL;
  337. p->PalPtr = NULL;
  338. p->DiffMask = NULL;
  339. p->InvertMask = NULL;
  340. if (p->Dst.Flags & PF_INVERTED)
  341. Invert = -1;
  342. if (p->ColorLookup)
  343. {
  344. CalcLookUp(p,p->Dither);
  345. p->LookUp = InstCreate(p->LookUp_Data,p->LookUp_Size,NONE,NONE,NONE,0,0);
  346. free(p->LookUp_Data);
  347. p->LookUp_Data = NULL;
  348. }
  349. if (p->QAdd)
  350. {
  351. int Mask2;
  352. int i,Shift;
  353. for (i=0;i<3;++i)
  354. Mask |= 1 << (p->DstPos[i] + p->DstSize[i] -1);
  355. Mask2 = Mask;
  356. Shift = 0;
  357. if (p->DstBPP==8 && p->DstDoubleX)
  358. Mask2 |= Mask << 16;
  359. else
  360. if (p->DstBPP <= 16)
  361. {
  362. if (p->DirX<0) Shift = p->DstBPP;
  363. Mask2 |= Mask << p->DstBPP;
  364. }
  365. Invert ^= RotateRight(Mask2,Shift+p->DstPos[0]);
  366. }
  367. p->YMul = InstCreate32(p->_YMul,NONE,NONE,NONE,0,0);
  368. p->RVMul = InstCreate32(p->_RVMul,NONE,NONE,NONE,0,0);
  369. p->RAdd = InstCreate32(p->_RAdd,NONE,NONE,NONE,0,0);
  370. p->GUMul = InstCreate32(p->_GUMul,NONE,NONE,NONE,0,0);
  371. p->GVMul = InstCreate32(p->_GVMul,NONE,NONE,NONE,0,0);
  372. p->GAdd = InstCreate32(p->_GAdd,NONE,NONE,NONE,0,0);
  373. p->BUMul = InstCreate32(p->_BUMul,NONE,NONE,NONE,0,0);
  374. p->BAdd = InstCreate32(p->_BAdd,NONE,NONE,NONE,0,0);
  375. if (Invert)
  376. p->InvertMask = InstCreate32(Invert,NONE,NONE,NONE,0,0);
  377. if (p->OnlyDiff)
  378. p->DiffMask = InstCreate32(0xFCFCFCFC,NONE,NONE,NONE,0,0);
  379. CodeBegin();
  380. I2C(SUB,SP,SP,OFS(stack,StackFrame));
  381. I2C(LDR,R9,R1,0); //Dst[0] RGB
  382. I2C(LDR,R10,R2,4); //Src[1] U
  383. I2C(LDR,R11,R2,8); //Src[2] V
  384. I2C(LDR,R12,R2,0); //Src[0] Y
  385. I2C(STR,R3,SP,OFS(stack,DstPitch));
  386. I3(MOV,R6,NONE,R3); //DstPitch
  387. I2C(LDR,R7,SP,OFS(stack,SrcPitch));
  388. I2C(LDR,R0,SP,OFS(stack,Height));
  389. I2C(LDR,R4,SP,OFS(stack,Width));
  390. if (!p->ColorLookup)
  391. I1P(LDR,R8,p->YMul,0);
  392. else
  393. I1P(MOV,R8,p->LookUp,0);
  394. //YNext = 2*Src->Pitch - (Width >> SrcDoubleX)
  395. I3S(MOV,R1,NONE,R7,LSL,1);
  396. I3S(SUB,R1,R1,R4,LSR,p->SrcDoubleX); 
  397. I2C(STR,R1,SP,OFS(stack,YNext));
  398. //UVNext = (Src->Pitch >> 1) - (Width >> SrcDoubleX >> 1);
  399. I3S(MOV,R2,NONE,R7,ASR,1);
  400. I3S(SUB,R2,R2,R4,LSR,p->SrcDoubleX+1); 
  401. I2C(STR,R2,SP,OFS(stack,UVNext));
  402. if (p->DirX<0 && p->DstBPP==16) //adjust reversed destination for block size
  403. I2C(SUB,R9,R9,-p->DstStepX-(p->DstBPP >> 3));
  404. if (p->DstBPP==32)
  405. I2C(ADD,R9,R9,p->DstStepX/2);
  406. if (p->SwapXY)
  407. {
  408. // EndOfRect = Dst + ((Height * DstBPP * DirX) >> 3) - (DstPitch << DstDoubleY)
  409. I3S(SUB,R9,R9,R6,LSL,p->DstDoubleY);
  410. I2C(MOV,R1,NONE,p->DstBPP * p->DirX);
  411. I3(MUL,R0,R1,R0);
  412. I3S(ADD,R0,R9,R0,ASR,3);
  413. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  414. //DstNext = DstStepX - Width*DstPitch;
  415. MB(); I3(MUL,R2,R6,R4);
  416. I2C(MOV,R0,NONE,p->DstStepX); 
  417. I3(SUB,R0,R0,R2); 
  418. I2C(STR,R0,SP,OFS(stack,DstNext));
  419. }
  420. else
  421. {
  422. // EndOfRect = Dst + DstPitch * Height
  423. I3(MUL,R0,R6,R0);
  424. I3(ADD,R0,R9,R0);
  425. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  426. //DstNext = ((DstPitch*2 << DstDoubleY) - DirX * Width << DstBPP2;
  427. I3S(MOV,R2,NONE,R6,LSL,p->DstDoubleY+1);
  428. I3S(p->DirX>0?SUB:ADD,R2,R2,R4,LSL,p->DstBPP2); 
  429. I2C(STR,R2,SP,OFS(stack,DstNext));
  430. }
  431. I3(ADD,R14,R12,R7);
  432. if (p->Dither)
  433. {
  434. if (!p->ColorLookup)
  435. {
  436. I2C(MVN,R1,NONE,0x80000000);
  437. I2C(MVN,R2,NONE,0x80000000);
  438. I2C(MVN,R3,NONE,0x80000000);
  439. }
  440. else
  441. {
  442. I2C(MOV,R1,NONE,0x80);
  443. I2C(MOV,R2,NONE,0x80);
  444. I2C(MOV,R3,NONE,0x80);
  445. }
  446. }
  447. LoopY = Label(1);
  448. if (p->SwapXY)
  449. {
  450. I3(MUL,R0,R6,R4); //R6=dstpitch
  451. I3(ADD,R7,R9,R0);
  452. }
  453. else
  454. {
  455. if (p->DirX > 0)
  456. I3S(ADD,R7,R9,R4,LSL,p->DstBPP2);
  457. else
  458. I3S(SUB,R7,R9,R4,LSL,p->DstBPP2);
  459. }
  460. I2C(STR,R7,SP,OFS(stack,EndOfLine));
  461. // preload
  462. if (p->ARM5) // not needed for non slices mode, but testing show it didn't help on ARM4
  463. {
  464. if (!p->Slices)
  465. {
  466. //R4 width
  467. //R0,R7,R5,R6 tmp
  468. dyninst* PreLoadEnd = Label(0);
  469. dyninst* PreLoad1;
  470. dyninst* PreLoad2;
  471. dyninst* PreLoad3;
  472. dyninst* PreLoad4;
  473. I3S(ADD,R0,R12,R4,ASR,(p->SrcDoubleX?1:0)-(p->SrcHalfX?1:0));
  474. I2C(ADD,R5,R12,32);
  475. I3(CMP,NONE,R5,R0);
  476. I0P(B,CS,PreLoadEnd);
  477. //y0
  478. PreLoad1 = Label(1);
  479. Byte(); I2C(LDR,R6,R5,-32);
  480. I2C(ADD,R5,R5,64);
  481. I3(CMP,NONE,R5,R0);
  482. Byte(); I2C(LDR,R7,R5,-64);
  483. I0P(B,CC,PreLoad1);
  484. I3S(ADD,R0,R14,R4,ASR,(p->SrcDoubleX?1:0)-(p->SrcHalfX?1:0));
  485. I2C(ADD,R5,R14,32);
  486. //y1
  487. PreLoad2 = Label(1);
  488. Byte(); I2C(LDR,R6,R5,-32);
  489. I2C(ADD,R5,R5,64);
  490. I3(CMP,NONE,R5,R0);
  491. Byte(); I2C(LDR,R7,R5,-64);
  492. I0P(B,CC,PreLoad2);
  493. I3S(ADD,R0,R10,R4,ASR,(p->SrcDoubleX?1:0)-(p->SrcHalfX?1:0)+p->SrcUVX2);
  494. I2C(ADD,R5,R10,32);
  495. I3(CMP,NONE,R5,R0);
  496. I0P(B,CS,PreLoadEnd);
  497. //u
  498. PreLoad3 = Label(1);
  499. Byte(); I2C(LDR,R6,R5,-32);
  500. I2C(ADD,R5,R5,64);
  501. I3(CMP,NONE,R5,R0);
  502. Byte(); I2C(LDR,R7,R5,-64);
  503. I0P(B,CC,PreLoad3);
  504. I3S(ADD,R0,R11,R4,ASR,(p->SrcDoubleX?1:0)-(p->SrcHalfX?1:0)+p->SrcUVX2);
  505. I2C(ADD,R5,R11,32);
  506. //v
  507. PreLoad4 = Label(1);
  508. Byte(); I2C(LDR,R6,R5,-32);
  509. I2C(ADD,R5,R5,64);
  510. I3(CMP,NONE,R5,R0);
  511. Byte(); I2C(LDR,R7,R5,-64);
  512. I0P(B,CC,PreLoad4);
  513. if (p->OnlyDiff) //restore R7
  514. I2C(LDR,R7,SP,OFS(stack,EndOfLine));
  515. InstPost(PreLoadEnd);
  516. }
  517. else
  518. {
  519. //preload next
  520. MB(); I2C(LDR,R6,SP,OFS(stack,SrcPitch));
  521. I3S(PLD,NONE,R12,R6,LSL,1);
  522. I3S(PLD,NONE,R14,R6,LSL,1);
  523. I3S(PLD,NONE,R10,R6,ASR,p->SrcUVPitch2);
  524. I3S(PLD,NONE,R11,R6,ASR,p->SrcUVPitch2);
  525. }
  526. }
  527.     if (p->OnlyDiff)
  528. {
  529. MB(); I1P(LDR,R5,p->DiffMask,0);
  530. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  531. p->Skip = Label(0);
  532. }
  533. LoopX = Label(1);
  534. {
  535. int PitchDouble;
  536. reg Pitch;
  537. Fix_RGB_UV_LoadUV(p);
  538. p->Pos = -1;
  539. Fix_RGB_UV_Pixel(p,0,0);
  540. if (p->DstBPP==32)
  541. {
  542. if (p->Pos)
  543. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  544. assert(!p->DstDoubleX && !p->DstDoubleY);
  545. MB(); I2C(LDR,R1,SP,OFS(stack,DstPitch));
  546. I2C(ADD,R1,R1,-p->DstStepX/2);
  547. I3(STR,R0,R9,R1);
  548. p->Pos = -1;
  549. }
  550. Fix_RGB_UV_Pixel(p,1,0);
  551. if (p->Pos) 
  552. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  553. Pitch = (reg)(p->Dither ? R7:R1);
  554. MB(); I2C(LDR,Pitch,SP,OFS(stack,DstPitch));
  555. if (p->DstBPP==8 && p->DstDoubleX) 
  556. I3S(ORR,R0,R0,R0,LSL,8);
  557. if (p->DstBPP==16 && p->DstDoubleX) 
  558. {
  559. I2C(ADD,R9,R9,4);
  560. I3S(MOV,R3,NONE,R0,LSR,16);
  561. I3S(MOV,R0,NONE,R0,LSL,16);
  562. I3S(ORR,R3,R3,R3,LSL,16);
  563. I3S(ORR,R0,R0,R0,LSR,16);
  564. if (p->DstDoubleY)
  565. {
  566. I3S(ADD,R2,Pitch,Pitch,LSL,1); //R2=3*DstPitch
  567. I3(STR,R3,R9,R2);
  568. }
  569. I3S(STR,R3,R9,Pitch,LSL,p->DstDoubleY);
  570. I2C(SUB,R9,R9,4);
  571. }
  572. if (p->DstDoubleY)
  573. {
  574. I3S(ADD,R2,Pitch,Pitch,LSL,1); //R2=3*DstPitch
  575. if (p->DstBPP==8 && !p->DstDoubleX) Half();
  576. I3(STR,R0,R9,R2);
  577. }
  578. PitchDouble = p->DstDoubleY;
  579. if (p->DstBPP==8 && !p->DstDoubleX) 
  580. {
  581. if (PitchDouble) // can't use STR with Half() and LSL,#1 at the same time
  582. {
  583. PitchDouble = 0;
  584. I3(ADD,Pitch,Pitch,Pitch);
  585. }
  586. Half();
  587. }
  588. I3S(STR,R0,R9,Pitch,LSL,PitchDouble);
  589. if (p->SwapXY)
  590. I3S(ADD,R9,R9,Pitch,LSL,1+PitchDouble);
  591. p->Pos = -1;
  592. Fix_RGB_UV_Pixel(p,0,1);
  593. if (p->DstBPP==32)
  594. {
  595. if (p->Pos)
  596. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  597. assert(!p->DstDoubleX && !p->DstDoubleY);
  598. I2C(STR,R0,R9,-p->DstStepX/2);
  599. p->Pos = -1;
  600. }
  601. Fix_RGB_UV_Pixel(p,1,1);
  602. if (p->Pos) 
  603. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  604. if (p->DstBPP==8 && p->DstDoubleX) 
  605. I3S(ORR,R0,R0,R0,LSL,8);
  606. if (p->DstDoubleY)
  607. {
  608. MB(); I2C(LDR,R1,SP,OFS(stack,DstPitch));
  609. }
  610. if (p->DstBPP==16 && p->DstDoubleX) 
  611. {
  612. I3S(MOV,R3,NONE,R0,LSR,16);
  613. I3S(MOV,R0,NONE,R0,LSL,16);
  614. I3S(ORR,R3,R3,R3,LSL,16);
  615. I3S(ORR,R0,R0,R0,LSR,16);
  616. if (p->DstDoubleY)
  617. {
  618. I2C(ADD,R2,R1,4); //DstPitch+4
  619. I3(STR,R3,R9,R2);
  620. }
  621. I2C(STR,R3,R9,4);
  622. }
  623. if (p->DstDoubleY)
  624. {
  625. if (p->DstBPP==8 && !p->DstDoubleX) Half();
  626. I3(STR,R0,R9,R1);
  627. }
  628. if (p->DstBPP==8 && !p->DstDoubleX) Half();
  629. if (p->SwapXY)
  630. I2(STR,R0,R9);
  631. else
  632. I2C(STR_POST,R0,R9,p->DstStepX);
  633. MB(); I2C(LDR,R7,SP,OFS(stack,EndOfLine));
  634. if (p->OnlyDiff)
  635. {
  636. MB(); I1P(LDR,R5,p->DiffMask,0);
  637. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  638. InstPost(p->Skip);
  639. }
  640. I3(CMP,NONE,R9,R7);
  641. I0P(B,NE,LoopX);
  642. }
  643. I2C(LDR,R0,SP,OFS(stack,YNext));
  644. I2C(LDR,R4,SP,OFS(stack,DstNext));
  645. I2C(LDR,R6,SP,OFS(stack,UVNext));
  646. I2C(LDR,R5,SP,OFS(stack,EndOfRect));
  647. //increment pointers
  648. I3(ADD,R12,R12,R0);
  649. I3(ADD,R14,R14,R0);
  650. I3(ADD,R9,R9,R4);
  651. I3(ADD,R10,R10,R6);
  652. I3(ADD,R11,R11,R6);
  653. //prepare registers for next row
  654. if (p->SwapXY) I2C(LDR,R6,SP,OFS(stack,DstPitch));
  655. I2C(LDR,R4,SP,OFS(stack,Width));
  656. I3(CMP,NONE,R9,R5);
  657. I0P(B,NE,LoopY);
  658. I2C(ADD,SP,SP,OFS(stack,StackFrame));
  659. CodeEnd();
  660. InstPost(p->YMul);
  661. InstPost(p->RVMul);
  662. InstPost(p->RAdd);
  663. InstPost(p->GUMul);
  664. InstPost(p->GVMul);
  665. InstPost(p->GAdd);
  666. InstPost(p->BUMul);
  667. InstPost(p->BAdd);
  668. if (p->InvertMask) InstPost(p->InvertMask);
  669. if (p->DiffMask) InstPost(p->DiffMask);
  670. if (p->PalPtr) InstPost(p->PalPtr);
  671. if (p->LookUp)
  672. {
  673. Align(16);
  674. InstPost(p->LookUp);
  675. }
  676. }
  677. #endif