You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

762 lines
19KB

  1. ;*****************************************************************************
  2. ;* MMX/SSE2-optimized H.264 deblocking code
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*
  8. ;* This file is part of FFmpeg.
  9. ;*
  10. ;* FFmpeg is free software; you can redistribute it and/or
  11. ;* modify it under the terms of the GNU Lesser General Public
  12. ;* License as published by the Free Software Foundation; either
  13. ;* version 2.1 of the License, or (at your option) any later version.
  14. ;*
  15. ;* FFmpeg is distributed in the hope that it will be useful,
  16. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. ;* Lesser General Public License for more details.
  19. ;*
  20. ;* You should have received a copy of the GNU Lesser General Public
  21. ;* License along with FFmpeg; if not, write to the Free Software
  22. ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. ;******************************************************************************
  24. %include "x86inc.asm"
  25. SECTION_RODATA
  26. pb_00: times 16 db 0x00
  27. pb_01: times 16 db 0x01
  28. pb_03: times 16 db 0x03
  29. pb_a1: times 16 db 0xa1
  30. SECTION .text
  31. ; expands to [base],...,[base+7*stride]
  32. %define PASS8ROWS(base, base3, stride, stride3) \
  33. [base], [base+stride], [base+stride*2], [base3], \
  34. [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
  35. ; in: 8 rows of 4 bytes in %1..%8
  36. ; out: 4 rows of 8 bytes in m0..m3
  37. %macro TRANSPOSE4x8_LOAD 8
  38. movd m0, %1
  39. movd m2, %2
  40. movd m1, %3
  41. movd m3, %4
  42. punpcklbw m0, m2
  43. punpcklbw m1, m3
  44. movq m2, m0
  45. punpcklwd m0, m1
  46. punpckhwd m2, m1
  47. movd m4, %5
  48. movd m6, %6
  49. movd m5, %7
  50. movd m7, %8
  51. punpcklbw m4, m6
  52. punpcklbw m5, m7
  53. movq m6, m4
  54. punpcklwd m4, m5
  55. punpckhwd m6, m5
  56. movq m1, m0
  57. movq m3, m2
  58. punpckldq m0, m4
  59. punpckhdq m1, m4
  60. punpckldq m2, m6
  61. punpckhdq m3, m6
  62. %endmacro
  63. ; in: 4 rows of 8 bytes in m0..m3
  64. ; out: 8 rows of 4 bytes in %1..%8
  65. %macro TRANSPOSE8x4_STORE 8
  66. movq m4, m0
  67. movq m5, m1
  68. movq m6, m2
  69. punpckhdq m4, m4
  70. punpckhdq m5, m5
  71. punpckhdq m6, m6
  72. punpcklbw m0, m1
  73. punpcklbw m2, m3
  74. movq m1, m0
  75. punpcklwd m0, m2
  76. punpckhwd m1, m2
  77. movd %1, m0
  78. punpckhdq m0, m0
  79. movd %2, m0
  80. movd %3, m1
  81. punpckhdq m1, m1
  82. movd %4, m1
  83. punpckhdq m3, m3
  84. punpcklbw m4, m5
  85. punpcklbw m6, m3
  86. movq m5, m4
  87. punpcklwd m4, m6
  88. punpckhwd m5, m6
  89. movd %5, m4
  90. punpckhdq m4, m4
  91. movd %6, m4
  92. movd %7, m5
  93. punpckhdq m5, m5
  94. movd %8, m5
  95. %endmacro
  96. %macro SBUTTERFLY 4
  97. movq %4, %2
  98. punpckl%1 %2, %3
  99. punpckh%1 %4, %3
  100. %endmacro
  101. ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
  102. ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
  103. %macro TRANSPOSE6x8_MEM 9
  104. movq m0, %1
  105. movq m1, %2
  106. movq m2, %3
  107. movq m3, %4
  108. movq m4, %5
  109. movq m5, %6
  110. movq m6, %7
  111. SBUTTERFLY bw, m0, m1, m7
  112. SBUTTERFLY bw, m2, m3, m1
  113. SBUTTERFLY bw, m4, m5, m3
  114. movq [%9+0x10], m1
  115. SBUTTERFLY bw, m6, %8, m5
  116. SBUTTERFLY wd, m0, m2, m1
  117. SBUTTERFLY wd, m4, m6, m2
  118. punpckhdq m0, m4
  119. movq [%9+0x00], m0
  120. SBUTTERFLY wd, m7, [%9+0x10], m6
  121. SBUTTERFLY wd, m3, m5, m4
  122. SBUTTERFLY dq, m7, m3, m0
  123. SBUTTERFLY dq, m1, m2, m5
  124. punpckldq m6, m4
  125. movq [%9+0x10], m1
  126. movq [%9+0x20], m5
  127. movq [%9+0x30], m7
  128. movq [%9+0x40], m0
  129. movq [%9+0x50], m6
  130. %endmacro
  131. ; in: 8 rows of 8 in %1..%8
  132. ; out: 8 rows of 8 in %9..%16
  133. %macro TRANSPOSE8x8_MEM 16
  134. movq m0, %1
  135. movq m1, %2
  136. movq m2, %3
  137. movq m3, %4
  138. movq m4, %5
  139. movq m5, %6
  140. movq m6, %7
  141. SBUTTERFLY bw, m0, m1, m7
  142. SBUTTERFLY bw, m2, m3, m1
  143. SBUTTERFLY bw, m4, m5, m3
  144. SBUTTERFLY bw, m6, %8, m5
  145. movq %9, m3
  146. SBUTTERFLY wd, m0, m2, m3
  147. SBUTTERFLY wd, m4, m6, m2
  148. SBUTTERFLY wd, m7, m1, m6
  149. movq %11, m2
  150. movq m2, %9
  151. SBUTTERFLY wd, m2, m5, m1
  152. SBUTTERFLY dq, m0, m4, m5
  153. SBUTTERFLY dq, m7, m2, m4
  154. movq %9, m0
  155. movq %10, m5
  156. movq %13, m7
  157. movq %14, m4
  158. SBUTTERFLY dq, m3, %11, m0
  159. SBUTTERFLY dq, m6, m1, m5
  160. movq %11, m3
  161. movq %12, m0
  162. movq %15, m6
  163. movq %16, m5
  164. %endmacro
  165. ; out: %4 = |%1-%2|>%3
  166. ; clobbers: %5
  167. %macro DIFF_GT 5
  168. mova %5, %2
  169. mova %4, %1
  170. psubusb %5, %1
  171. psubusb %4, %2
  172. por %4, %5
  173. psubusb %4, %3
  174. %endmacro
  175. ; out: %4 = |%1-%2|>%3
  176. ; clobbers: %5
  177. %macro DIFF_GT2 5
  178. mova %5, %2
  179. mova %4, %1
  180. psubusb %5, %1
  181. psubusb %4, %2
  182. psubusb %5, %3
  183. psubusb %4, %3
  184. pcmpeqb %4, %5
  185. %endmacro
  186. %macro SPLATW 1
  187. %ifidn m0, xmm0
  188. pshuflw %1, %1, 0
  189. punpcklqdq %1, %1
  190. %else
  191. pshufw %1, %1, 0
  192. %endif
  193. %endmacro
  194. ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
  195. ; out: m5=beta-1, m7=mask, %3=alpha-1
  196. ; clobbers: m4,m6
  197. %macro LOAD_MASK 2-3
  198. movd m4, %1
  199. movd m5, %2
  200. SPLATW m4
  201. SPLATW m5
  202. packuswb m4, m4 ; 16x alpha-1
  203. packuswb m5, m5 ; 16x beta-1
  204. %if %0>2
  205. mova %3, m4
  206. %endif
  207. DIFF_GT m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
  208. DIFF_GT m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
  209. por m7, m4
  210. DIFF_GT m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
  211. por m7, m4
  212. pxor m6, m6
  213. pcmpeqb m7, m6
  214. %endmacro
  215. ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
  216. ; out: m1=p0' m2=q0'
  217. ; clobbers: m0,3-6
  218. %macro DEBLOCK_P0_Q0 0
  219. mova m5, m1
  220. pxor m5, m2 ; p0^q0
  221. pand m5, [pb_01] ; (p0^q0)&1
  222. pcmpeqb m4, m4
  223. pxor m3, m4
  224. pavgb m3, m0 ; (p1 - q1 + 256)>>1
  225. pavgb m3, [pb_03] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
  226. pxor m4, m1
  227. pavgb m4, m2 ; (q0 - p0 + 256)>>1
  228. pavgb m3, m5
  229. paddusb m3, m4 ; d+128+33
  230. mova m6, [pb_a1]
  231. psubusb m6, m3
  232. psubusb m3, [pb_a1]
  233. pminub m6, m7
  234. pminub m3, m7
  235. psubusb m1, m6
  236. psubusb m2, m3
  237. paddusb m1, m3
  238. paddusb m2, m6
  239. %endmacro
  240. ; in: m1=p0 m2=q0
  241. ; %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
  242. ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
  243. ; clobbers: q2, tmp, tc0
  244. %macro LUMA_Q1 6
  245. mova %6, m1
  246. pavgb %6, m2
  247. pavgb %2, %6 ; avg(p2,avg(p0,q0))
  248. pxor %6, %3
  249. pand %6, [pb_01] ; (p2^avg(p0,q0))&1
  250. psubusb %2, %6 ; (p2+((p0+q0+1)>>1))>>1
  251. mova %6, %1
  252. psubusb %6, %5
  253. paddusb %5, %1
  254. pmaxub %2, %6
  255. pminub %2, %5
  256. mova %4, %2
  257. %endmacro
  258. %ifdef ARCH_X86_64
  259. ;-----------------------------------------------------------------------------
  260. ; void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  261. ;-----------------------------------------------------------------------------
  262. INIT_XMM
  263. cglobal x264_deblock_v_luma_sse2, 5,5,10
  264. movd m8, [r4] ; tc0
  265. lea r4, [r1*3]
  266. dec r2d ; alpha-1
  267. neg r4
  268. dec r3d ; beta-1
  269. add r4, r0 ; pix-3*stride
  270. mova m0, [r4+r1] ; p1
  271. mova m1, [r4+2*r1] ; p0
  272. mova m2, [r0] ; q0
  273. mova m3, [r0+r1] ; q1
  274. LOAD_MASK r2d, r3d
  275. punpcklbw m8, m8
  276. punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
  277. pcmpeqb m9, m9
  278. pcmpeqb m9, m8
  279. pandn m9, m7
  280. pand m8, m9
  281. movdqa m3, [r4] ; p2
  282. DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
  283. pand m6, m9
  284. mova m7, m8
  285. psubb m7, m6
  286. pand m6, m8
  287. LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
  288. movdqa m4, [r0+2*r1] ; q2
  289. DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
  290. pand m6, m9
  291. pand m8, m6
  292. psubb m7, m6
  293. mova m3, [r0+r1]
  294. LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
  295. DEBLOCK_P0_Q0
  296. mova [r4+2*r1], m1
  297. mova [r0], m2
  298. RET
  299. ;-----------------------------------------------------------------------------
  300. ; void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  301. ;-----------------------------------------------------------------------------
  302. INIT_MMX
  303. cglobal x264_deblock_h_luma_sse2, 5,7
  304. movsxd r10, r1d
  305. lea r11, [r10+r10*2]
  306. lea r6, [r0-4]
  307. lea r5, [r0-4+r11]
  308. %ifdef WIN64
  309. sub rsp, 0x98
  310. %define pix_tmp rsp+0x30
  311. %else
  312. sub rsp, 0x68
  313. %define pix_tmp rsp
  314. %endif
  315. ; transpose 6x16 -> tmp space
  316. TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp
  317. lea r6, [r6+r10*8]
  318. lea r5, [r5+r10*8]
  319. TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
  320. ; vertical filter
  321. ; alpha, beta, tc0 are still in r2d, r3d, r4
  322. ; don't backup r6, r5, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
  323. lea r0, [pix_tmp+0x30]
  324. mov r1d, 0x10
  325. %ifdef WIN64
  326. mov [rsp+0x20], r4
  327. %endif
  328. call x264_deblock_v_luma_sse2
  329. ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter)
  330. add r6, 2
  331. add r5, 2
  332. movq m0, [pix_tmp+0x18]
  333. movq m1, [pix_tmp+0x28]
  334. movq m2, [pix_tmp+0x38]
  335. movq m3, [pix_tmp+0x48]
  336. TRANSPOSE8x4_STORE PASS8ROWS(r6, r5, r10, r11)
  337. shl r10, 3
  338. sub r6, r10
  339. sub r5, r10
  340. shr r10, 3
  341. movq m0, [pix_tmp+0x10]
  342. movq m1, [pix_tmp+0x20]
  343. movq m2, [pix_tmp+0x30]
  344. movq m3, [pix_tmp+0x40]
  345. TRANSPOSE8x4_STORE PASS8ROWS(r6, r5, r10, r11)
  346. %ifdef WIN64
  347. add rsp, 0x98
  348. %else
  349. add rsp, 0x68
  350. %endif
  351. RET
  352. %else
  353. %macro DEBLOCK_LUMA 3
  354. ;-----------------------------------------------------------------------------
  355. ; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  356. ;-----------------------------------------------------------------------------
  357. cglobal x264_deblock_%2_luma_%1, 5,5
  358. lea r4, [r1*3]
  359. dec r2 ; alpha-1
  360. neg r4
  361. dec r3 ; beta-1
  362. add r4, r0 ; pix-3*stride
  363. %assign pad 2*%3+12-(stack_offset&15)
  364. SUB esp, pad
  365. mova m0, [r4+r1] ; p1
  366. mova m1, [r4+2*r1] ; p0
  367. mova m2, [r0] ; q0
  368. mova m3, [r0+r1] ; q1
  369. LOAD_MASK r2, r3
  370. mov r3, r4mp
  371. movd m4, [r3] ; tc0
  372. punpcklbw m4, m4
  373. punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
  374. mova [esp+%3], m4 ; tc
  375. pcmpeqb m3, m3
  376. pcmpgtb m4, m3
  377. pand m4, m7
  378. mova [esp], m4 ; mask
  379. mova m3, [r4] ; p2
  380. DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
  381. pand m6, m4
  382. pand m4, [esp+%3] ; tc
  383. mova m7, m4
  384. psubb m7, m6
  385. pand m6, m4
  386. LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
  387. mova m4, [r0+2*r1] ; q2
  388. DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
  389. mova m5, [esp] ; mask
  390. pand m6, m5
  391. mova m5, [esp+%3] ; tc
  392. pand m5, m6
  393. psubb m7, m6
  394. mova m3, [r0+r1]
  395. LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
  396. DEBLOCK_P0_Q0
  397. mova [r4+2*r1], m1
  398. mova [r0], m2
  399. ADD esp, pad
  400. RET
  401. ;-----------------------------------------------------------------------------
  402. ; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  403. ;-----------------------------------------------------------------------------
  404. INIT_MMX
  405. cglobal x264_deblock_h_luma_%1, 0,5
  406. mov r0, r0mp
  407. mov r3, r1m
  408. lea r4, [r3*3]
  409. sub r0, 4
  410. lea r1, [r0+r4]
  411. %assign pad 0x78-(stack_offset&15)
  412. SUB esp, pad
  413. %define pix_tmp esp+12
  414. ; transpose 6x16 -> tmp space
  415. TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp
  416. lea r0, [r0+r3*8]
  417. lea r1, [r1+r3*8]
  418. TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
  419. ; vertical filter
  420. lea r0, [pix_tmp+0x30]
  421. PUSH dword r4m
  422. PUSH dword r3m
  423. PUSH dword r2m
  424. PUSH dword 16
  425. PUSH dword r0
  426. call x264_deblock_%2_luma_%1
  427. %ifidn %2, v8
  428. add dword [esp ], 8 ; pix_tmp+0x38
  429. add dword [esp+16], 2 ; tc0+2
  430. call x264_deblock_%2_luma_%1
  431. %endif
  432. ADD esp, 20
  433. ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter)
  434. mov r0, r0mp
  435. sub r0, 2
  436. lea r1, [r0+r4]
  437. movq m0, [pix_tmp+0x10]
  438. movq m1, [pix_tmp+0x20]
  439. movq m2, [pix_tmp+0x30]
  440. movq m3, [pix_tmp+0x40]
  441. TRANSPOSE8x4_STORE PASS8ROWS(r0, r1, r3, r4)
  442. lea r0, [r0+r3*8]
  443. lea r1, [r1+r3*8]
  444. movq m0, [pix_tmp+0x18]
  445. movq m1, [pix_tmp+0x28]
  446. movq m2, [pix_tmp+0x38]
  447. movq m3, [pix_tmp+0x48]
  448. TRANSPOSE8x4_STORE PASS8ROWS(r0, r1, r3, r4)
  449. ADD esp, pad
  450. RET
  451. %endmacro ; DEBLOCK_LUMA
  452. INIT_XMM
  453. DEBLOCK_LUMA sse2, v, 16
  454. %endif ; ARCH
  455. %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
  456. mova t0, p2
  457. mova t1, p0
  458. pavgb t0, p1
  459. pavgb t1, q0
  460. pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
  461. mova t5, t1
  462. mova t2, p2
  463. mova t3, p0
  464. paddb t2, p1
  465. paddb t3, q0
  466. paddb t2, t3
  467. mova t3, t2
  468. mova t4, t2
  469. psrlw t2, 1
  470. pavgb t2, mpb_00
  471. pxor t2, t0
  472. pand t2, mpb_01
  473. psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
  474. mova t1, p2
  475. mova t2, p2
  476. pavgb t1, q1
  477. psubb t2, q1
  478. paddb t3, t3
  479. psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
  480. pand t2, mpb_01
  481. psubb t1, t2
  482. pavgb t1, p1
  483. pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
  484. psrlw t3, 2
  485. pavgb t3, mpb_00
  486. pxor t3, t1
  487. pand t3, mpb_01
  488. psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
  489. mova t3, p0
  490. mova t2, p0
  491. pxor t3, q1
  492. pavgb t2, q1
  493. pand t3, mpb_01
  494. psubb t2, t3
  495. pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
  496. pxor t1, t2
  497. pxor t2, p0
  498. pand t1, mask1p
  499. pand t2, mask0
  500. pxor t1, t2
  501. pxor t1, p0
  502. mova %1, t1 ; store p0
  503. mova t1, %4 ; p3
  504. mova t2, t1
  505. pavgb t1, p2
  506. paddb t2, p2
  507. pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
  508. paddb t2, t2
  509. paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
  510. psrlw t2, 2
  511. pavgb t2, mpb_00
  512. pxor t2, t1
  513. pand t2, mpb_01
  514. psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
  515. pxor t0, p1
  516. pxor t1, p2
  517. pand t0, mask1p
  518. pand t1, mask1p
  519. pxor t0, p1
  520. pxor t1, p2
  521. mova %2, t0 ; store p1
  522. mova %3, t1 ; store p2
  523. %endmacro
  524. %macro LUMA_INTRA_SWAP_PQ 0
  525. %define q1 m0
  526. %define q0 m1
  527. %define p0 m2
  528. %define p1 m3
  529. %define p2 q2
  530. %define mask1p mask1q
  531. %endmacro
  532. %macro DEBLOCK_LUMA_INTRA 2
  533. %define p1 m0
  534. %define p0 m1
  535. %define q0 m2
  536. %define q1 m3
  537. %define t0 m4
  538. %define t1 m5
  539. %define t2 m6
  540. %define t3 m7
  541. %ifdef ARCH_X86_64
  542. %define p2 m8
  543. %define q2 m9
  544. %define t4 m10
  545. %define t5 m11
  546. %define mask0 m12
  547. %define mask1p m13
  548. %define mask1q [rsp-24]
  549. %define mpb_00 m14
  550. %define mpb_01 m15
  551. %else
  552. %define spill(x) [esp+16*x+((stack_offset+4)&15)]
  553. %define p2 [r4+r1]
  554. %define q2 [r0+2*r1]
  555. %define t4 spill(0)
  556. %define t5 spill(1)
  557. %define mask0 spill(2)
  558. %define mask1p spill(3)
  559. %define mask1q spill(4)
  560. %define mpb_00 [pb_00]
  561. %define mpb_01 [pb_01]
  562. %endif
  563. ;-----------------------------------------------------------------------------
  564. ; void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
  565. ;-----------------------------------------------------------------------------
  566. cglobal x264_deblock_%2_luma_intra_%1, 4,6,16
  567. %ifndef ARCH_X86_64
  568. sub esp, 0x60
  569. %endif
  570. lea r4, [r1*4]
  571. lea r5, [r1*3] ; 3*stride
  572. dec r2d ; alpha-1
  573. jl .end
  574. neg r4
  575. dec r3d ; beta-1
  576. jl .end
  577. add r4, r0 ; pix-4*stride
  578. mova p1, [r4+2*r1]
  579. mova p0, [r4+r5]
  580. mova q0, [r0]
  581. mova q1, [r0+r1]
  582. %ifdef ARCH_X86_64
  583. pxor mpb_00, mpb_00
  584. mova mpb_01, [pb_01]
  585. LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
  586. SWAP 7, 12 ; m12=mask0
  587. pavgb t5, mpb_00
  588. pavgb t5, mpb_01 ; alpha/4+1
  589. movdqa p2, [r4+r1]
  590. movdqa q2, [r0+2*r1]
  591. DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
  592. DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
  593. DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
  594. pand t0, mask0
  595. pand t4, t0
  596. pand t2, t0
  597. mova mask1q, t4
  598. mova mask1p, t2
  599. %else
  600. LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
  601. mova m4, t5
  602. mova mask0, m7
  603. pavgb m4, [pb_00]
  604. pavgb m4, [pb_01] ; alpha/4+1
  605. DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
  606. pand m6, mask0
  607. DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
  608. pand m4, m6
  609. mova mask1p, m4
  610. DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
  611. pand m4, m6
  612. mova mask1q, m4
  613. %endif
  614. LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
  615. LUMA_INTRA_SWAP_PQ
  616. LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
  617. .end:
  618. %ifndef ARCH_X86_64
  619. add esp, 0x60
  620. %endif
  621. RET
  622. INIT_MMX
  623. %ifdef ARCH_X86_64
  624. ;-----------------------------------------------------------------------------
  625. ; void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
  626. ;-----------------------------------------------------------------------------
  627. cglobal x264_deblock_h_luma_intra_%1, 4,7
  628. movsxd r10, r1d
  629. lea r11, [r10*3]
  630. lea r6, [r0-4]
  631. lea r5, [r0-4+r11]
  632. sub rsp, 0x88
  633. %define pix_tmp rsp
  634. ; transpose 8x16 -> tmp space
  635. TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
  636. lea r6, [r6+r10*8]
  637. lea r5, [r5+r10*8]
  638. TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
  639. lea r0, [pix_tmp+0x40]
  640. mov r1, 0x10
  641. call x264_deblock_v_luma_intra_%1
  642. ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
  643. lea r5, [r6+r11]
  644. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
  645. shl r10, 3
  646. sub r6, r10
  647. sub r5, r10
  648. shr r10, 3
  649. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
  650. add rsp, 0x88
  651. RET
  652. %else
  653. cglobal x264_deblock_h_luma_intra_%1, 2,4
  654. lea r3, [r1*3]
  655. sub r0, 4
  656. lea r2, [r0+r3]
  657. %assign pad 0x8c-(stack_offset&15)
  658. SUB rsp, pad
  659. %define pix_tmp rsp
  660. ; transpose 8x16 -> tmp space
  661. TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
  662. lea r0, [r0+r1*8]
  663. lea r2, [r2+r1*8]
  664. TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
  665. lea r0, [pix_tmp+0x40]
  666. PUSH dword r3m
  667. PUSH dword r2m
  668. PUSH dword 16
  669. PUSH r0
  670. call x264_deblock_%2_luma_intra_%1
  671. %ifidn %2, v8
  672. add dword [rsp], 8 ; pix_tmp+8
  673. call x264_deblock_%2_luma_intra_%1
  674. %endif
  675. ADD esp, 16
  676. mov r1, r1m
  677. mov r0, r0mp
  678. lea r3, [r1*3]
  679. sub r0, 4
  680. lea r2, [r0+r3]
  681. ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
  682. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
  683. lea r0, [r0+r1*8]
  684. lea r2, [r2+r1*8]
  685. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
  686. ADD rsp, pad
  687. RET
  688. %endif ; ARCH_X86_64
  689. %endmacro ; DEBLOCK_LUMA_INTRA
  690. INIT_XMM
  691. DEBLOCK_LUMA_INTRA sse2, v
  692. %ifndef ARCH_X86_64
  693. INIT_MMX
  694. DEBLOCK_LUMA_INTRA mmxext, v8
  695. %endif