Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52868 views
1
/*****************************************************************************
2
* pixel.S: arm pixel metrics
3
*****************************************************************************
4
* Copyright (C) 2009-2016 x264 project
5
*
6
* Authors: David Conrad <[email protected]>
7
* Janne Grunau <[email protected]>
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
22
*
23
* This program is also available under a commercial proprietary license.
24
* For more information, contact us at [email protected].
25
*****************************************************************************/
26
27
#include "asm.S"
28
29
.section .rodata
30
.align 4
31
32
.rept 16
33
.byte 0xff
34
.endr
35
mask_ff:
36
.rept 16
37
.byte 0
38
.endr
39
40
mask_ac4:
41
.short 0, -1, -1, -1, 0, -1, -1, -1
42
mask_ac8:
43
.short 0, -1, -1, -1, -1, -1, -1, -1
44
45
.text
46
47
.macro SAD4_ARMV6 h
48
function x264_pixel_sad_4x\h\()_armv6
49
push {r4-r6,lr}
50
ldr r4, [r2], r3
51
ldr r5, [r0], r1
52
ldr r6, [r2], r3
53
ldr lr, [r0], r1
54
usad8 ip, r4, r5
55
.rept (\h - 2)/2
56
ldr r4, [r2], r3
57
ldr r5, [r0], r1
58
usada8 ip, r6, lr, ip
59
ldr r6, [r2], r3
60
ldr lr, [r0], r1
61
usada8 ip, r4, r5, ip
62
.endr
63
usada8 r0, r6, lr, ip
64
pop {r4-r6,pc}
65
endfunc
66
.endm
67
68
SAD4_ARMV6 4
69
SAD4_ARMV6 8
70
71
72
.macro SAD_START_4 align:vararg
73
vld1.32 {d1[]}, [r2\align], r3
74
vld1.32 {d0[]}, [r0,:32], r1
75
vabdl.u8 q8, d0, d1
76
.endm
77
78
.macro SAD_4 align:vararg
79
vld1.32 {d1[]}, [r2\align], r3
80
vld1.32 {d0[]}, [r0,:32], r1
81
vabal.u8 q8, d0, d1
82
.endm
83
84
.macro SAD_START_8 align:vararg
85
vld1.64 {d1}, [r2\align], r3
86
vld1.64 {d0}, [r0,:64], r1
87
vabdl.u8 q8, d0, d1
88
.endm
89
90
.macro SAD_8 align:vararg
91
vld1.64 {d1}, [r2\align], r3
92
vld1.64 {d0}, [r0,:64], r1
93
vabal.u8 q8, d0, d1
94
.endm
95
96
.macro SAD_START_16 align:vararg
97
vld1.64 {d2-d3}, [r2\align], r3
98
vld1.64 {d0-d1}, [r0,:128], r1
99
vabdl.u8 q8, d0, d2
100
vld1.64 {d6-d7}, [r2\align], r3
101
vabdl.u8 q9, d1, d3
102
vld1.64 {d4-d5}, [r0,:128], r1
103
.endm
104
105
.macro SAD_16 align:vararg
106
vabal.u8 q8, d4, d6
107
vld1.64 {d2-d3}, [r2\align], r3
108
vabal.u8 q9, d5, d7
109
vld1.64 {d0-d1}, [r0,:128], r1
110
vabal.u8 q8, d0, d2
111
vld1.64 {d6-d7}, [r2\align], r3
112
vabal.u8 q9, d1, d3
113
vld1.64 {d4-d5}, [r0,:128], r1
114
.endm
115
116
.macro SAD_FUNC w, h, name, align:vararg
117
function x264_pixel_sad\name\()_\w\()x\h\()_neon
118
SAD_START_\w \align
119
120
.if \w == 16
121
.rept \h / 2 - 1
122
SAD_\w \align
123
.endr
124
.else
125
.rept \h - 1
126
SAD_\w \align
127
.endr
128
.endif
129
130
.if \w > 8
131
vabal.u8 q8, d4, d6
132
vabal.u8 q9, d5, d7
133
vadd.u16 q8, q8, q9
134
.endif
135
.if \w > 4
136
vadd.u16 d16, d16, d17
137
.endif
138
vpadd.u16 d0, d16, d16
139
vpaddl.u16 d0, d0
140
vmov.u32 r0, d0[0]
141
bx lr
142
endfunc
143
.endm
144
145
SAD_FUNC 4, 4
146
SAD_FUNC 4, 8
147
SAD_FUNC 8, 4
148
SAD_FUNC 8, 8
149
SAD_FUNC 8, 16
150
SAD_FUNC 16, 8
151
SAD_FUNC 16, 16
152
153
SAD_FUNC 4, 4, _aligned, ,:32
154
SAD_FUNC 4, 8, _aligned, ,:32
155
SAD_FUNC 8, 4, _aligned, ,:64
156
SAD_FUNC 8, 8, _aligned, ,:64
157
SAD_FUNC 8, 16, _aligned, ,:64
158
SAD_FUNC 16, 8, _aligned, ,:128
159
SAD_FUNC 16, 16, _aligned, ,:128
160
161
// If dual issue is possible, use additional accumulators to avoid
162
// stalls from vadal's latency. This only matters for aligned.
163
.macro SAD_DUAL_START_8
164
SAD_START_8 ,:64
165
vld1.64 {d3}, [r2,:64], r3
166
vld1.64 {d2}, [r0,:64], r1
167
vabdl.u8 q9, d2, d3
168
.endm
169
170
.macro SAD_DUAL_8 align:vararg
171
vld1.64 {d1}, [r2,:64], r3
172
vld1.64 {d0}, [r0,:64], r1
173
vabal.u8 q8, d0, d1
174
vld1.64 {d3}, [r2,:64], r3
175
vld1.64 {d2}, [r0,:64], r1
176
vabal.u8 q9, d2, d3
177
.endm
178
179
.macro SAD_DUAL_START_16
180
SAD_START_16 ,:128
181
vabdl.u8 q10, d4, d6
182
vld1.64 {d2-d3}, [r2,:128], r3
183
vabdl.u8 q11, d5, d7
184
vld1.64 {d0-d1}, [r0,:128], r1
185
.endm
186
187
.macro SAD_DUAL_16
188
vabal.u8 q8, d0, d2
189
vld1.64 {d6-d7}, [r2,:128], r3
190
vabal.u8 q9, d1, d3
191
vld1.64 {d4-d5}, [r0,:128], r1
192
vabal.u8 q10, d4, d6
193
vld1.64 {d2-d3}, [r2,:128], r3
194
vabal.u8 q11, d5, d7
195
vld1.64 {d0-d1}, [r0,:128], r1
196
.endm
197
198
.macro SAD_DUAL_END_16
199
vabal.u8 q8, d0, d2
200
vld1.64 {d6-d7}, [r2,:128], r3
201
vabal.u8 q9, d1, d3
202
vld1.64 {d4-d5}, [r0,:128], r1
203
vabal.u8 q10, d4, d6
204
vabal.u8 q11, d5, d7
205
.endm
206
207
.macro SAD_FUNC_DUAL w, h
208
function x264_pixel_sad_aligned_\w\()x\h\()_neon_dual
209
SAD_DUAL_START_\w
210
.rept \h / 2 - \w / 8
211
SAD_DUAL_\w
212
.endr
213
214
.if \w > 8
215
SAD_DUAL_END_16
216
vadd.u16 q8, q8, q9
217
vadd.u16 q9, q10, q11
218
.endif
219
.if \w > 4
220
vadd.u16 q8, q8, q9
221
vadd.u16 d16, d16, d17
222
.endif
223
vpadd.u16 d0, d16, d16
224
vpaddl.u16 d0, d0
225
vmov.u32 r0, d0[0]
226
bx lr
227
endfunc
228
.endm
229
230
SAD_FUNC_DUAL 8, 4
231
SAD_FUNC_DUAL 8, 8
232
SAD_FUNC_DUAL 8, 16
233
SAD_FUNC_DUAL 16, 8
234
SAD_FUNC_DUAL 16, 16
235
236
237
.macro SAD_X_START_4 x
238
vld1.32 {d0[]}, [r0,:32], lr
239
vld1.32 {d1[]}, [r1], r6
240
vabdl.u8 q8, d1, d0
241
vld1.32 {d2[]}, [r2], r6
242
vabdl.u8 q9, d2, d0
243
vld1.32 {d3[]}, [r3], r6
244
vabdl.u8 q10, d3, d0
245
.if \x == 4
246
vld1.32 {d4[]}, [r12], r6
247
vabdl.u8 q11, d4, d0
248
.endif
249
.endm
250
251
.macro SAD_X_4 x
252
vld1.32 {d0[]}, [r0,:32], lr
253
vld1.32 {d1[]}, [r1], r6
254
vabal.u8 q8, d1, d0
255
vld1.32 {d2[]}, [r2], r6
256
vabal.u8 q9, d2, d0
257
vld1.32 {d3[]}, [r3], r6
258
vabal.u8 q10, d3, d0
259
.if \x == 4
260
vld1.32 {d4[]}, [r12], r6
261
vabal.u8 q11, d4, d0
262
.endif
263
.endm
264
265
.macro SAD_X_START_8 x
266
vld1.64 {d0}, [r0,:64], lr
267
vld1.64 {d1}, [r1], r6
268
vabdl.u8 q8, d1, d0
269
vld1.64 {d2}, [r2], r6
270
vabdl.u8 q9, d2, d0
271
vld1.64 {d3}, [r3], r6
272
vabdl.u8 q10, d3, d0
273
.if \x == 4
274
vld1.64 {d4}, [r12], r6
275
vabdl.u8 q11, d4, d0
276
.endif
277
.endm
278
279
.macro SAD_X_8 x
280
vld1.64 {d0}, [r0,:64], lr
281
vld1.64 {d1}, [r1], r6
282
vabal.u8 q8, d1, d0
283
vld1.64 {d2}, [r2], r6
284
vabal.u8 q9, d2, d0
285
vld1.64 {d3}, [r3], r6
286
vabal.u8 q10, d3, d0
287
.if \x == 4
288
vld1.64 {d4}, [r12], r6
289
vabal.u8 q11, d4, d0
290
.endif
291
.endm
292
293
.macro SAD_X_START_16 x
294
vld1.64 {d0-d1}, [r0,:128], lr
295
vld1.64 {d2-d3}, [r1], r6
296
vabdl.u8 q8, d2, d0
297
vabdl.u8 q12, d3, d1
298
vld1.64 {d4-d5}, [r2], r6
299
vabdl.u8 q9, d4, d0
300
vabdl.u8 q13, d5, d1
301
vld1.64 {d6-d7}, [r3], r6
302
vabdl.u8 q10, d6, d0
303
vabdl.u8 q14, d7, d1
304
.if \x == 4
305
vld1.64 {d2-d3}, [r12], r6
306
vabdl.u8 q11, d2, d0
307
vabdl.u8 q15, d3, d1
308
.endif
309
.endm
310
311
.macro SAD_X_16 x
312
vld1.64 {d0-d1}, [r0,:128], lr
313
vld1.64 {d2-d3}, [r1], r6
314
vabal.u8 q8, d2, d0
315
vabal.u8 q12, d3, d1
316
vld1.64 {d4-d5}, [r2], r6
317
vabal.u8 q9, d4, d0
318
vabal.u8 q13, d5, d1
319
vld1.64 {d6-d7}, [r3], r6
320
vabal.u8 q10, d6, d0
321
vabal.u8 q14, d7, d1
322
.if \x == 4
323
vld1.64 {d2-d3}, [r12], r6
324
vabal.u8 q11, d2, d0
325
vabal.u8 q15, d3, d1
326
.endif
327
.endm
328
329
.macro SAD_X_FUNC x, w, h
330
function x264_pixel_sad_x\x\()_\w\()x\h\()_neon
331
push {r6-r7,lr}
332
.if \x == 3
333
ldrd r6, r7, [sp, #12]
334
.else
335
ldrd r6, r7, [sp, #16]
336
ldr r12, [sp, #12]
337
.endif
338
mov lr, #FENC_STRIDE
339
340
SAD_X_START_\w \x
341
.rept \h - 1
342
SAD_X_\w \x
343
.endr
344
345
// add up the sads
346
.if \w > 8
347
vadd.u16 q8, q8, q12
348
vadd.u16 q9, q9, q13
349
vadd.u16 q10, q10, q14
350
.if \x == 4
351
vadd.u16 q11, q11, q15
352
.endif
353
.endif
354
.if \w > 4
355
vadd.u16 d16, d16, d17
356
vadd.u16 d18, d18, d19
357
vadd.u16 d20, d20, d21
358
.if \x == 4
359
vadd.u16 d22, d22, d23
360
.endif
361
.endif
362
vpadd.u16 d0, d16, d18
363
vpadd.u16 d1, d20, d22
364
vpaddl.u16 q0, q0
365
366
.if \x == 3
367
vst1.32 {d0}, [r7]!
368
vst1.32 {d1[0]}, [r7,:32]
369
.else
370
vst1.32 {d0-d1}, [r7]
371
.endif
372
pop {r6-r7,pc}
373
endfunc
374
.endm
375
376
SAD_X_FUNC 3, 4, 4
377
SAD_X_FUNC 3, 4, 8
378
SAD_X_FUNC 3, 8, 4
379
SAD_X_FUNC 3, 8, 8
380
SAD_X_FUNC 3, 8, 16
381
SAD_X_FUNC 3, 16, 8
382
SAD_X_FUNC 3, 16, 16
383
384
SAD_X_FUNC 4, 4, 4
385
SAD_X_FUNC 4, 4, 8
386
SAD_X_FUNC 4, 8, 4
387
SAD_X_FUNC 4, 8, 8
388
SAD_X_FUNC 4, 8, 16
389
SAD_X_FUNC 4, 16, 8
390
SAD_X_FUNC 4, 16, 16
391
392
function x264_pixel_vsad_neon
393
subs r2, r2, #2
394
vld1.8 {q0}, [r0], r1
395
vld1.8 {q1}, [r0], r1
396
vabdl.u8 q2, d0, d2
397
vabdl.u8 q3, d1, d3
398
ble 2f
399
1:
400
subs r2, r2, #2
401
vld1.8 {q0}, [r0], r1
402
vabal.u8 q2, d2, d0
403
vabal.u8 q3, d3, d1
404
vld1.8 {q1}, [r0], r1
405
blt 2f
406
vabal.u8 q2, d0, d2
407
vabal.u8 q3, d1, d3
408
bgt 1b
409
2:
410
vadd.u16 q0, q2, q3
411
HORIZ_ADD d0, d0, d1
412
vmov.32 r0, d0[0]
413
bx lr
414
endfunc
415
416
function x264_pixel_asd8_neon
417
ldr r12, [sp, #0]
418
sub r12, r12, #2
419
vld1.8 {d0}, [r0], r1
420
vld1.8 {d1}, [r2], r3
421
vld1.8 {d2}, [r0], r1
422
vld1.8 {d3}, [r2], r3
423
vsubl.u8 q8, d0, d1
424
1:
425
subs r12, r12, #2
426
vld1.8 {d4}, [r0], r1
427
vld1.8 {d5}, [r2], r3
428
vsubl.u8 q9, d2, d3
429
vsubl.u8 q10, d4, d5
430
vadd.s16 q8, q9
431
vld1.8 {d2}, [r0], r1
432
vld1.8 {d3}, [r2], r3
433
vadd.s16 q8, q10
434
bgt 1b
435
vsubl.u8 q9, d2, d3
436
vadd.s16 q8, q9
437
vpaddl.s16 q8, q8
438
vpadd.s32 d16, d16, d17
439
vpadd.s32 d16, d16, d17
440
vabs.s32 d16, d16
441
vmov.32 r0, d16[0]
442
bx lr
443
endfunc
444
445
446
.macro SSD_START_4
447
vld1.32 {d16[]}, [r0,:32], r1
448
vld1.32 {d17[]}, [r2,:32], r3
449
vsubl.u8 q2, d16, d17
450
vld1.32 {d16[]}, [r0,:32], r1
451
vmull.s16 q0, d4, d4
452
vld1.32 {d17[]}, [r2,:32], r3
453
.endm
454
455
.macro SSD_4
456
vsubl.u8 q2, d16, d17
457
vld1.32 {d16[]}, [r0,:32], r1
458
vmlal.s16 q0, d4, d4
459
vld1.32 {d17[]}, [r2,:32], r3
460
.endm
461
462
.macro SSD_END_4
463
vsubl.u8 q2, d16, d17
464
vmlal.s16 q0, d4, d4
465
.endm
466
467
.macro SSD_START_8
468
vld1.64 {d16}, [r0,:64], r1
469
vld1.64 {d17}, [r2,:64], r3
470
vsubl.u8 q2, d16, d17
471
vld1.64 {d16}, [r0,:64], r1
472
vmull.s16 q0, d4, d4
473
vmlal.s16 q0, d5, d5
474
vld1.64 {d17}, [r2,:64], r3
475
.endm
476
477
.macro SSD_8
478
vsubl.u8 q2, d16, d17
479
vld1.64 {d16}, [r0,:64], r1
480
vmlal.s16 q0, d4, d4
481
vmlal.s16 q0, d5, d5
482
vld1.64 {d17}, [r2,:64], r3
483
.endm
484
485
.macro SSD_END_8
486
vsubl.u8 q2, d16, d17
487
vmlal.s16 q0, d4, d4
488
vmlal.s16 q0, d5, d5
489
.endm
490
491
.macro SSD_START_16
492
vld1.64 {d16-d17}, [r0,:128], r1
493
vld1.64 {d18-d19}, [r2,:128], r3
494
vsubl.u8 q2, d16, d18
495
vsubl.u8 q3, d17, d19
496
vld1.64 {d16-d17}, [r0,:128], r1
497
vmull.s16 q0, d4, d4
498
vmlal.s16 q0, d5, d5
499
vld1.64 {d18-d19}, [r2,:128], r3
500
vmlal.s16 q0, d6, d6
501
vmlal.s16 q0, d7, d7
502
.endm
503
504
.macro SSD_16
505
vsubl.u8 q2, d16, d18
506
vsubl.u8 q3, d17, d19
507
vld1.64 {d16-d17}, [r0,:128], r1
508
vmlal.s16 q0, d4, d4
509
vmlal.s16 q0, d5, d5
510
vld1.64 {d18-d19}, [r2,:128], r3
511
vmlal.s16 q0, d6, d6
512
vmlal.s16 q0, d7, d7
513
.endm
514
515
.macro SSD_END_16
516
vsubl.u8 q2, d16, d18
517
vsubl.u8 q3, d17, d19
518
vmlal.s16 q0, d4, d4
519
vmlal.s16 q0, d5, d5
520
vmlal.s16 q0, d6, d6
521
vmlal.s16 q0, d7, d7
522
.endm
523
524
.macro SSD_FUNC w h
525
function x264_pixel_ssd_\w\()x\h\()_neon
526
SSD_START_\w
527
.rept \h-2
528
SSD_\w
529
.endr
530
SSD_END_\w
531
vadd.s32 d0, d0, d1
532
vpadd.s32 d0, d0, d0
533
vmov.32 r0, d0[0]
534
bx lr
535
endfunc
536
.endm
537
538
SSD_FUNC 4, 4
539
SSD_FUNC 4, 8
540
SSD_FUNC 8, 4
541
SSD_FUNC 8, 8
542
SSD_FUNC 8, 16
543
SSD_FUNC 16, 8
544
SSD_FUNC 16, 16
545
546
function x264_pixel_ssd_nv12_core_neon
547
push {r4-r5}
548
ldrd r4, r5, [sp, #8]
549
add r12, r4, #8
550
bic r12, r12, #15
551
vmov.u64 q8, #0
552
vmov.u64 q9, #0
553
sub r1, r1, r12, lsl #1
554
sub r3, r3, r12, lsl #1
555
1:
556
subs r12, r4, #16
557
vld2.8 {d0,d1}, [r0]!
558
vld2.8 {d2,d3}, [r2]!
559
vld2.8 {d4,d5}, [r0]!
560
vld2.8 {d6,d7}, [r2]!
561
562
vsubl.u8 q10, d0, d2
563
vsubl.u8 q11, d1, d3
564
vmull.s16 q14, d20, d20
565
vmull.s16 q15, d22, d22
566
vsubl.u8 q12, d4, d6
567
vsubl.u8 q13, d5, d7
568
vmlal.s16 q14, d21, d21
569
vmlal.s16 q15, d23, d23
570
571
blt 4f
572
beq 3f
573
2:
574
vmlal.s16 q14, d24, d24
575
vmlal.s16 q15, d26, d26
576
vld2.8 {d0,d1}, [r0]!
577
vld2.8 {d2,d3}, [r2]!
578
vmlal.s16 q14, d25, d25
579
vmlal.s16 q15, d27, d27
580
581
subs r12, r12, #16
582
vsubl.u8 q10, d0, d2
583
vsubl.u8 q11, d1, d3
584
vmlal.s16 q14, d20, d20
585
vmlal.s16 q15, d22, d22
586
vld2.8 {d4,d5}, [r0]!
587
vld2.8 {d6,d7}, [r2]!
588
vmlal.s16 q14, d21, d21
589
vmlal.s16 q15, d23, d23
590
blt 4f
591
592
vsubl.u8 q12, d4, d6
593
vsubl.u8 q13, d5, d7
594
bgt 2b
595
3:
596
vmlal.s16 q14, d24, d24
597
vmlal.s16 q15, d26, d26
598
vmlal.s16 q14, d25, d25
599
vmlal.s16 q15, d27, d27
600
4:
601
subs r5, r5, #1
602
vaddw.s32 q8, q8, d28
603
vaddw.s32 q9, q9, d30
604
add r0, r0, r1
605
add r2, r2, r3
606
vaddw.s32 q8, q8, d29
607
vaddw.s32 q9, q9, d31
608
bgt 1b
609
610
vadd.u64 d16, d16, d17
611
vadd.u64 d18, d18, d19
612
ldrd r4, r5, [sp, #16]
613
vst1.64 {d16}, [r4]
614
vst1.64 {d18}, [r5]
615
616
pop {r4-r5}
617
bx lr
618
endfunc
619
620
.macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
621
vmull.u8 \qsqr, \dsrc, \dsrc
622
vaddw.u8 q0, q0, \dsrc
623
\vpadal \qsqr_sum, \qsqr_last
624
.endm
625
626
function x264_pixel_var_8x8_neon
627
vld1.64 {d16}, [r0,:64], r1
628
vmull.u8 q1, d16, d16
629
vmovl.u8 q0, d16
630
vld1.64 {d18}, [r0,:64], r1
631
vmull.u8 q2, d18, d18
632
vaddw.u8 q0, q0, d18
633
634
vld1.64 {d20}, [r0,:64], r1
635
VAR_SQR_SUM q1, q1, q3, d20, vpaddl.u16
636
vld1.64 {d22}, [r0,:64], r1
637
VAR_SQR_SUM q2, q2, q8, d22, vpaddl.u16
638
639
vld1.64 {d24}, [r0,:64], r1
640
VAR_SQR_SUM q1, q3, q9, d24
641
vld1.64 {d26}, [r0,:64], r1
642
VAR_SQR_SUM q2, q8, q10, d26
643
vld1.64 {d24}, [r0,:64], r1
644
VAR_SQR_SUM q1, q9, q14, d24
645
vld1.64 {d26}, [r0,:64], r1
646
VAR_SQR_SUM q2, q10, q15, d26
647
b x264_var_end
648
endfunc
649
650
function x264_pixel_var_8x16_neon
651
vld1.64 {d16}, [r0,:64], r1
652
vld1.64 {d18}, [r0,:64], r1
653
vmull.u8 q1, d16, d16
654
vmovl.u8 q0, d16
655
vld1.64 {d20}, [r0,:64], r1
656
vmull.u8 q2, d18, d18
657
vaddw.u8 q0, q0, d18
658
659
mov ip, #12
660
661
vld1.64 {d22}, [r0,:64], r1
662
VAR_SQR_SUM q1, q1, q14, d20, vpaddl.u16
663
vld1.64 {d16}, [r0,:64], r1
664
VAR_SQR_SUM q2, q2, q15, d22, vpaddl.u16
665
666
1: subs ip, ip, #4
667
vld1.64 {d18}, [r0,:64], r1
668
VAR_SQR_SUM q1, q14, q12, d16
669
vld1.64 {d20}, [r0,:64], r1
670
VAR_SQR_SUM q2, q15, q13, d18
671
vld1.64 {d22}, [r0,:64], r1
672
VAR_SQR_SUM q1, q12, q14, d20
673
beq 2f
674
vld1.64 {d16}, [r0,:64], r1
675
VAR_SQR_SUM q2, q13, q15, d22
676
b 1b
677
2:
678
VAR_SQR_SUM q2, q13, q15, d22
679
b x264_var_end
680
endfunc
681
682
function x264_pixel_var_16x16_neon
683
vld1.64 {d16-d17}, [r0,:128], r1
684
vmull.u8 q12, d16, d16
685
vmovl.u8 q0, d16
686
vmull.u8 q13, d17, d17
687
vaddw.u8 q0, q0, d17
688
689
vld1.64 {d18-d19}, [r0,:128], r1
690
VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
691
VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
692
693
mov ip, #7
694
var16_loop:
695
subs ip, ip, #1
696
vld1.64 {d16-d17}, [r0,:128], r1
697
VAR_SQR_SUM q1, q14, q12, d16
698
VAR_SQR_SUM q2, q15, q13, d17
699
700
vld1.64 {d18-d19}, [r0,:128], r1
701
VAR_SQR_SUM q1, q12, q14, d18
702
VAR_SQR_SUM q2, q13, q15, d19
703
bgt var16_loop
704
endfunc
705
706
function x264_var_end, export=0
707
vpaddl.u16 q8, q14
708
vpaddl.u16 q9, q15
709
vadd.u32 q1, q1, q8
710
vadd.u16 d0, d0, d1
711
vadd.u32 q1, q1, q9
712
vadd.u32 q1, q1, q2
713
vpaddl.u16 d0, d0
714
vadd.u32 d2, d2, d3
715
vpadd.u32 d0, d0, d2
716
717
vmov r0, r1, d0
718
bx lr
719
endfunc
720
721
.macro DIFF_SUM diff da db lastdiff
722
vld1.64 {\da}, [r0,:64], r1
723
vld1.64 {\db}, [r2,:64], r3
724
.ifnb \lastdiff
725
vadd.s16 q0, q0, \lastdiff
726
.endif
727
vsubl.u8 \diff, \da, \db
728
.endm
729
730
.macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
731
\vmlal \acc, \d0, \d0
732
vmlal.s16 \acc, \d1, \d1
733
.endm
734
735
function x264_pixel_var2_8x8_neon
736
DIFF_SUM q0, d0, d1
737
DIFF_SUM q8, d16, d17
738
SQR_ACC q1, d0, d1, vmull.s16
739
DIFF_SUM q9, d18, d19, q8
740
SQR_ACC q2, d16, d17, vmull.s16
741
.rept 2
742
DIFF_SUM q8, d16, d17, q9
743
SQR_ACC q1, d18, d19
744
DIFF_SUM q9, d18, d19, q8
745
SQR_ACC q2, d16, d17
746
.endr
747
DIFF_SUM q8, d16, d17, q9
748
SQR_ACC q1, d18, d19
749
vadd.s16 q0, q0, q8
750
SQR_ACC q2, d16, d17
751
752
ldr ip, [sp]
753
vadd.s16 d0, d0, d1
754
vadd.s32 q1, q1, q2
755
vpaddl.s16 d0, d0
756
vadd.s32 d1, d2, d3
757
vpadd.s32 d0, d0, d1
758
759
vmov r0, r1, d0
760
vst1.32 {d0[1]}, [ip,:32]
761
mul r0, r0, r0
762
sub r0, r1, r0, lsr #6
763
bx lr
764
endfunc
765
766
function x264_pixel_var2_8x16_neon
767
vld1.64 {d16}, [r0,:64], r1
768
vld1.64 {d17}, [r2,:64], r3
769
vld1.64 {d18}, [r0,:64], r1
770
vld1.64 {d19}, [r2,:64], r3
771
vsubl.u8 q10, d16, d17
772
vsubl.u8 q11, d18, d19
773
SQR_ACC q1, d20, d21, vmull.s16
774
vld1.64 {d16}, [r0,:64], r1
775
vadd.s16 q0, q10, q11
776
vld1.64 {d17}, [r2,:64], r3
777
SQR_ACC q2, d22, d23, vmull.s16
778
mov ip, #14
779
1: subs ip, ip, #2
780
vld1.64 {d18}, [r0,:64], r1
781
vsubl.u8 q10, d16, d17
782
vld1.64 {d19}, [r2,:64], r3
783
vadd.s16 q0, q0, q10
784
SQR_ACC q1, d20, d21
785
vsubl.u8 q11, d18, d19
786
beq 2f
787
vld1.64 {d16}, [r0,:64], r1
788
vadd.s16 q0, q0, q11
789
vld1.64 {d17}, [r2,:64], r3
790
SQR_ACC q2, d22, d23
791
b 1b
792
2:
793
vadd.s16 q0, q0, q11
794
SQR_ACC q2, d22, d23
795
796
ldr ip, [sp]
797
vadd.s16 d0, d0, d1
798
vadd.s32 q1, q1, q2
799
vpaddl.s16 d0, d0
800
vadd.s32 d1, d2, d3
801
vpadd.s32 d0, d0, d1
802
803
vmov r0, r1, d0
804
vst1.32 {d0[1]}, [ip,:32]
805
mul r0, r0, r0
806
sub r0, r1, r0, lsr #7
807
bx lr
808
endfunc
809
810
.macro LOAD_DIFF_8x4 q0 q1 q2 q3
811
vld1.32 {d1}, [r2], r3
812
vld1.32 {d0}, [r0,:64], r1
813
vsubl.u8 \q0, d0, d1
814
vld1.32 {d3}, [r2], r3
815
vld1.32 {d2}, [r0,:64], r1
816
vsubl.u8 \q1, d2, d3
817
vld1.32 {d5}, [r2], r3
818
vld1.32 {d4}, [r0,:64], r1
819
vsubl.u8 \q2, d4, d5
820
vld1.32 {d7}, [r2], r3
821
vld1.32 {d6}, [r0,:64], r1
822
vsubl.u8 \q3, d6, d7
823
.endm
824
825
function x264_pixel_satd_4x4_neon
826
vld1.32 {d1[]}, [r2], r3
827
vld1.32 {d0[]}, [r0,:32], r1
828
vld1.32 {d3[]}, [r2], r3
829
vld1.32 {d2[]}, [r0,:32], r1
830
vld1.32 {d1[1]}, [r2], r3
831
vld1.32 {d0[1]}, [r0,:32], r1
832
vld1.32 {d3[1]}, [r2], r3
833
vld1.32 {d2[1]}, [r0,:32], r1
834
vsubl.u8 q0, d0, d1
835
vsubl.u8 q1, d2, d3
836
837
SUMSUB_AB q2, q3, q0, q1
838
SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
839
HADAMARD 1, sumsub, q2, q3, q0, q1
840
HADAMARD 2, amax, q0,, q2, q3
841
842
HORIZ_ADD d0, d0, d1
843
vmov.32 r0, d0[0]
844
bx lr
845
endfunc
846
847
function x264_pixel_satd_4x8_neon
848
vld1.32 {d1[]}, [r2], r3
849
vld1.32 {d0[]}, [r0,:32], r1
850
vld1.32 {d3[]}, [r2], r3
851
vld1.32 {d2[]}, [r0,:32], r1
852
vld1.32 {d5[]}, [r2], r3
853
vld1.32 {d4[]}, [r0,:32], r1
854
vld1.32 {d7[]}, [r2], r3
855
vld1.32 {d6[]}, [r0,:32], r1
856
857
vld1.32 {d1[1]}, [r2], r3
858
vld1.32 {d0[1]}, [r0,:32], r1
859
vsubl.u8 q0, d0, d1
860
vld1.32 {d3[1]}, [r2], r3
861
vld1.32 {d2[1]}, [r0,:32], r1
862
vsubl.u8 q1, d2, d3
863
vld1.32 {d5[1]}, [r2], r3
864
vld1.32 {d4[1]}, [r0,:32], r1
865
vsubl.u8 q2, d4, d5
866
vld1.32 {d7[1]}, [r2], r3
867
SUMSUB_AB q8, q9, q0, q1
868
vld1.32 {d6[1]}, [r0,:32], r1
869
vsubl.u8 q3, d6, d7
870
SUMSUB_AB q10, q11, q2, q3
871
b x264_satd_4x8_8x4_end_neon
872
endfunc
873
874
function x264_pixel_satd_8x4_neon
875
vld1.64 {d1}, [r2], r3
876
vld1.64 {d0}, [r0,:64], r1
877
vsubl.u8 q0, d0, d1
878
vld1.64 {d3}, [r2], r3
879
vld1.64 {d2}, [r0,:64], r1
880
vsubl.u8 q1, d2, d3
881
vld1.64 {d5}, [r2], r3
882
vld1.64 {d4}, [r0,:64], r1
883
vsubl.u8 q2, d4, d5
884
vld1.64 {d7}, [r2], r3
885
SUMSUB_AB q8, q9, q0, q1
886
vld1.64 {d6}, [r0,:64], r1
887
vsubl.u8 q3, d6, d7
888
SUMSUB_AB q10, q11, q2, q3
889
endfunc
890
891
function x264_satd_4x8_8x4_end_neon, export=0
892
vadd.s16 q0, q8, q10
893
vadd.s16 q1, q9, q11
894
vsub.s16 q2, q8, q10
895
vsub.s16 q3, q9, q11
896
897
vtrn.16 q0, q1
898
vadd.s16 q8, q0, q1
899
vtrn.16 q2, q3
900
vsub.s16 q9, q0, q1
901
vadd.s16 q10, q2, q3
902
vsub.s16 q11, q2, q3
903
vtrn.32 q8, q10
904
vabs.s16 q8, q8
905
vtrn.32 q9, q11
906
vabs.s16 q10, q10
907
vabs.s16 q9, q9
908
vabs.s16 q11, q11
909
vmax.u16 q0, q8, q10
910
vmax.u16 q1, q9, q11
911
912
vadd.u16 q0, q0, q1
913
HORIZ_ADD d0, d0, d1
914
vmov.32 r0, d0[0]
915
bx lr
916
endfunc
917
918
function x264_pixel_satd_8x8_neon
919
mov ip, lr
920
921
bl x264_satd_8x8_neon
922
vadd.u16 q0, q12, q13
923
vadd.u16 q1, q14, q15
924
925
vadd.u16 q0, q0, q1
926
HORIZ_ADD d0, d0, d1
927
mov lr, ip
928
vmov.32 r0, d0[0]
929
bx lr
930
endfunc
931
932
function x264_pixel_satd_8x16_neon
933
vpush {d8-d11}
934
mov ip, lr
935
936
bl x264_satd_8x8_neon
937
vadd.u16 q4, q12, q13
938
vadd.u16 q5, q14, q15
939
940
bl x264_satd_8x8_neon
941
vadd.u16 q4, q4, q12
942
vadd.u16 q5, q5, q13
943
vadd.u16 q4, q4, q14
944
vadd.u16 q5, q5, q15
945
946
vadd.u16 q0, q4, q5
947
HORIZ_ADD d0, d0, d1
948
vpop {d8-d11}
949
mov lr, ip
950
vmov.32 r0, d0[0]
951
bx lr
952
endfunc
953
954
function x264_satd_8x8_neon, export=0
955
LOAD_DIFF_8x4 q8, q9, q10, q11
956
vld1.64 {d7}, [r2], r3
957
SUMSUB_AB q0, q1, q8, q9
958
vld1.64 {d6}, [r0,:64], r1
959
vsubl.u8 q12, d6, d7
960
vld1.64 {d17}, [r2], r3
961
SUMSUB_AB q2, q3, q10, q11
962
vld1.64 {d16}, [r0,:64], r1
963
vsubl.u8 q13, d16, d17
964
vld1.64 {d19}, [r2], r3
965
SUMSUB_AB q8, q10, q0, q2
966
vld1.64 {d18}, [r0,:64], r1
967
vsubl.u8 q14, d18, d19
968
vld1.64 {d1}, [r2], r3
969
SUMSUB_AB q9, q11, q1, q3
970
vld1.64 {d0}, [r0,:64], r1
971
vsubl.u8 q15, d0, d1
972
endfunc
973
974
// one vertical hadamard pass and two horizontal
975
function x264_satd_8x4v_8x8h_neon, export=0
976
SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
977
vtrn.16 q8, q9
978
SUMSUB_AB q12, q14, q0, q2
979
vtrn.16 q10, q11
980
SUMSUB_AB q13, q15, q1, q3
981
SUMSUB_AB q0, q1, q8, q9
982
vtrn.16 q12, q13
983
SUMSUB_AB q2, q3, q10, q11
984
vtrn.16 q14, q15
985
SUMSUB_AB q8, q9, q12, q13
986
vtrn.32 q0, q2
987
SUMSUB_AB q10, q11, q14, q15
988
989
vtrn.32 q1, q3
990
ABS2 q0, q2
991
vtrn.32 q8, q10
992
ABS2 q1, q3
993
vtrn.32 q9, q11
994
ABS2 q8, q10
995
ABS2 q9, q11
996
vmax.s16 q12, q0, q2
997
vmax.s16 q13, q1, q3
998
vmax.s16 q14, q8, q10
999
vmax.s16 q15, q9, q11
1000
bx lr
1001
endfunc
1002
1003
function x264_pixel_satd_16x8_neon
1004
vpush {d8-d11}
1005
mov ip, lr
1006
1007
bl x264_satd_16x4_neon
1008
vadd.u16 q4, q12, q13
1009
vadd.u16 q5, q14, q15
1010
1011
bl x264_satd_16x4_neon
1012
vadd.u16 q4, q4, q12
1013
vadd.u16 q5, q5, q13
1014
vadd.u16 q4, q4, q14
1015
vadd.u16 q5, q5, q15
1016
1017
vadd.u16 q0, q4, q5
1018
HORIZ_ADD d0, d0, d1
1019
vpop {d8-d11}
1020
mov lr, ip
1021
vmov.32 r0, d0[0]
1022
bx lr
1023
endfunc
1024
1025
function x264_pixel_satd_16x16_neon
1026
vpush {d8-d11}
1027
mov ip, lr
1028
1029
bl x264_satd_16x4_neon
1030
vadd.u16 q4, q12, q13
1031
vadd.u16 q5, q14, q15
1032
1033
bl x264_satd_16x4_neon
1034
vadd.u16 q4, q4, q12
1035
vadd.u16 q5, q5, q13
1036
vadd.u16 q4, q4, q14
1037
vadd.u16 q5, q5, q15
1038
1039
bl x264_satd_16x4_neon
1040
vadd.u16 q4, q4, q12
1041
vadd.u16 q5, q5, q13
1042
vadd.u16 q4, q4, q14
1043
vadd.u16 q5, q5, q15
1044
1045
bl x264_satd_16x4_neon
1046
vadd.u16 q4, q4, q12
1047
vadd.u16 q5, q5, q13
1048
vadd.u16 q4, q4, q14
1049
vadd.u16 q5, q5, q15
1050
1051
vadd.u16 q0, q4, q5
1052
HORIZ_ADD d0, d0, d1
1053
vpop {d8-d11}
1054
mov lr, ip
1055
vmov.32 r0, d0[0]
1056
bx lr
1057
endfunc
1058
1059
function x264_satd_16x4_neon, export=0
1060
vld1.64 {d2-d3}, [r2], r3
1061
vld1.64 {d0-d1}, [r0,:128], r1
1062
vsubl.u8 q8, d0, d2
1063
vld1.64 {d6-d7}, [r2], r3
1064
vsubl.u8 q12, d1, d3
1065
vld1.64 {d4-d5}, [r0,:128], r1
1066
vsubl.u8 q9, d4, d6
1067
vld1.64 {d2-d3}, [r2], r3
1068
vsubl.u8 q13, d5, d7
1069
vld1.64 {d0-d1}, [r0,:128], r1
1070
vsubl.u8 q10, d0, d2
1071
vld1.64 {d6-d7}, [r2], r3
1072
vsubl.u8 q14, d1, d3
1073
vadd.s16 q0, q8, q9
1074
vld1.64 {d4-d5}, [r0,:128], r1
1075
vsub.s16 q1, q8, q9
1076
vsubl.u8 q11, d4, d6
1077
vsubl.u8 q15, d5, d7
1078
SUMSUB_AB q2, q3, q10, q11
1079
SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
1080
b x264_satd_8x4v_8x8h_neon
1081
endfunc
1082
1083
1084
function x264_pixel_sa8d_8x8_neon
1085
mov ip, lr
1086
bl x264_sa8d_8x8_neon
1087
vadd.u16 q0, q8, q9
1088
HORIZ_ADD d0, d0, d1
1089
mov lr, ip
1090
vmov.32 r0, d0[0]
1091
add r0, r0, #1
1092
lsr r0, r0, #1
1093
bx lr
1094
endfunc
1095
1096
function x264_pixel_sa8d_16x16_neon
1097
vpush {d8-d11}
1098
mov ip, lr
1099
bl x264_sa8d_8x8_neon
1100
vpaddl.u16 q4, q8
1101
vpaddl.u16 q5, q9
1102
bl x264_sa8d_8x8_neon
1103
vpadal.u16 q4, q8
1104
vpadal.u16 q5, q9
1105
sub r0, r0, r1, lsl #4
1106
sub r2, r2, r3, lsl #4
1107
add r0, r0, #8
1108
add r2, r2, #8
1109
bl x264_sa8d_8x8_neon
1110
vpadal.u16 q4, q8
1111
vpadal.u16 q5, q9
1112
bl x264_sa8d_8x8_neon
1113
vpaddl.u16 q8, q8
1114
vpaddl.u16 q9, q9
1115
vadd.u32 q0, q4, q8
1116
vadd.u32 q1, q5, q9
1117
vadd.u32 q0, q0, q1
1118
vadd.u32 d0, d0, d1
1119
vpadd.u32 d0, d0, d0
1120
vpop {d8-d11}
1121
mov lr, ip
1122
vmov.32 r0, d0[0]
1123
add r0, r0, #1
1124
lsr r0, r0, #1
1125
bx lr
1126
endfunc
1127
1128
.macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
1129
SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
1130
SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
1131
.endm
1132
1133
.macro integrated_satd dst, s0, s1, s2, s3
1134
vmov q0, \s0
1135
vmov q1, \s1
1136
vmov q2, \s2
1137
vmov q3, \s3
1138
1139
vtrn.16 q0, q1
1140
vtrn.16 q2, q3
1141
1142
SUMSUB_AB q6, q7, q0, q1
1143
SUMSUB_AB q0, q1, q2, q3
1144
1145
vtrn.32 q6, q0
1146
vtrn.32 q7, q1
1147
1148
vabs.s16 q6, q6
1149
vabs.s16 q0, q0
1150
vabs.s16 q7, q7
1151
vabs.s16 q1, q1
1152
1153
vmax.u16 q6, q6, q0
1154
vmax.u16 q7, q7, q1
1155
1156
vadd.i16 q6, q6, q7
1157
vpadal.u16 \dst, q6
1158
.endm
1159
1160
.macro sa8d_satd_8x8 satd=
1161
function x264_sa8d_\satd\()8x8_neon, export=0
1162
LOAD_DIFF_8x4 q8, q9, q10, q11
1163
vld1.64 {d7}, [r2], r3
1164
SUMSUB_AB q0, q1, q8, q9
1165
vld1.64 {d6}, [r0,:64], r1
1166
vsubl.u8 q12, d6, d7
1167
vld1.64 {d17}, [r2], r3
1168
SUMSUB_AB q2, q3, q10, q11
1169
vld1.64 {d16}, [r0,:64], r1
1170
vsubl.u8 q13, d16, d17
1171
vld1.64 {d19}, [r2], r3
1172
SUMSUB_AB q8, q10, q0, q2
1173
vld1.64 {d18}, [r0,:64], r1
1174
vsubl.u8 q14, d18, d19
1175
vld1.64 {d1}, [r2], r3
1176
SUMSUB_AB q9, q11, q1, q3
1177
vld1.64 {d0}, [r0,:64], r1
1178
vsubl.u8 q15, d0, d1
1179
1180
HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
1181
1182
.ifc \satd, satd_
1183
integrated_satd q4, q8, q9, q10, q11
1184
integrated_satd q4, q12, q13, q14, q15
1185
.endif
1186
1187
SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
1188
SUMSUB_AB q2, q10, q10, q14
1189
vtrn.16 q8, q9
1190
SUMSUB_AB q3, q11, q11, q15
1191
vtrn.16 q0, q1
1192
SUMSUB_AB q12, q13, q8, q9
1193
vtrn.16 q10, q11
1194
SUMSUB_AB q8, q9, q0, q1
1195
vtrn.16 q2, q3
1196
SUMSUB_AB q14, q15, q10, q11
1197
vadd.i16 q10, q2, q3
1198
vtrn.32 q12, q14
1199
vsub.i16 q11, q2, q3
1200
vtrn.32 q13, q15
1201
SUMSUB_AB q0, q2, q12, q14
1202
vtrn.32 q8, q10
1203
SUMSUB_AB q1, q3, q13, q15
1204
vtrn.32 q9, q11
1205
SUMSUB_AB q12, q14, q8, q10
1206
SUMSUB_AB q13, q15, q9, q11
1207
1208
vswp d1, d24
1209
ABS2 q0, q12
1210
vswp d3, d26
1211
ABS2 q1, q13
1212
vswp d5, d28
1213
ABS2 q2, q14
1214
vswp d7, d30
1215
ABS2 q3, q15
1216
vmax.s16 q8, q0, q12
1217
vmax.s16 q9, q1, q13
1218
vmax.s16 q10, q2, q14
1219
vmax.s16 q11, q3, q15
1220
vadd.i16 q8, q8, q9
1221
vadd.i16 q9, q10, q11
1222
.ifc \satd, satd_
1223
vpadal.u16 q5, q8
1224
vpadal.u16 q5, q9
1225
.endif
1226
bx lr
1227
endfunc
1228
.endm
1229
1230
sa8d_satd_8x8
1231
sa8d_satd_8x8 satd_
1232
1233
function x264_pixel_sa8d_satd_16x16_neon
1234
push {lr}
1235
vpush {q4-q7}
1236
vmov.u32 q4, #0
1237
vmov.u32 q5, #0
1238
bl x264_sa8d_satd_8x8_neon
1239
bl x264_sa8d_satd_8x8_neon
1240
sub r0, r0, r1, lsl #4
1241
sub r2, r2, r3, lsl #4
1242
add r0, r0, #8
1243
add r2, r2, #8
1244
bl x264_sa8d_satd_8x8_neon
1245
bl x264_sa8d_satd_8x8_neon
1246
vadd.u32 d1, d10, d11
1247
vadd.u32 d0, d8, d9
1248
vpadd.u32 d1, d1, d1
1249
vpadd.u32 d0, d0, d0
1250
vrshr.u32 d1, d1, #1
1251
vmov.32 r1, d0[0]
1252
vmov.32 r0, d1[0]
1253
vpop {q4-q7}
1254
pop {pc}
1255
endfunc
1256
1257
1258
.macro HADAMARD_AC w h
1259
function x264_pixel_hadamard_ac_\w\()x\h\()_neon
1260
vpush {d8-d15}
1261
movrel ip, mask_ac4
1262
vmov.i8 q4, #0
1263
// note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
1264
vld1.64 {d12-d15}, [ip,:128]
1265
vmov.i8 q5, #0
1266
1267
mov ip, lr
1268
bl x264_hadamard_ac_8x8_neon
1269
.if \h > 8
1270
bl x264_hadamard_ac_8x8_neon
1271
.endif
1272
.if \w > 8
1273
sub r0, r0, r1, lsl #3
1274
add r0, r0, #8
1275
bl x264_hadamard_ac_8x8_neon
1276
.endif
1277
.if \w * \h == 256
1278
sub r0, r0, r1, lsl #4
1279
bl x264_hadamard_ac_8x8_neon
1280
.endif
1281
1282
vadd.s32 d8, d8, d9
1283
vadd.s32 d10, d10, d11
1284
vpadd.s32 d0, d8, d10
1285
vpop {d8-d15}
1286
mov lr, ip
1287
vmov r0, r1, d0
1288
lsr r0, r0, #1
1289
lsr r1, r1, #2
1290
bx lr
1291
endfunc
1292
.endm
1293
1294
HADAMARD_AC 8, 8
1295
HADAMARD_AC 8, 16
1296
HADAMARD_AC 16, 8
1297
HADAMARD_AC 16, 16
1298
1299
// q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1300
function x264_hadamard_ac_8x8_neon, export=0
1301
vld1.64 {d2}, [r0,:64], r1
1302
vld1.64 {d3}, [r0,:64], r1
1303
vaddl.u8 q0, d2, d3
1304
vld1.64 {d6}, [r0,:64], r1
1305
vsubl.u8 q1, d2, d3
1306
vld1.64 {d7}, [r0,:64], r1
1307
vaddl.u8 q2, d6, d7
1308
vld1.64 {d18}, [r0,:64], r1
1309
vsubl.u8 q3, d6, d7
1310
vld1.64 {d19}, [r0,:64], r1
1311
vaddl.u8 q8, d18, d19
1312
vld1.64 {d22}, [r0,:64], r1
1313
vsubl.u8 q9, d18, d19
1314
vld1.64 {d23}, [r0,:64], r1
1315
1316
SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1317
vaddl.u8 q10, d22, d23
1318
vsubl.u8 q11, d22, d23
1319
vtrn.16 q12, q13
1320
SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1321
1322
vtrn.16 q14, q15
1323
SUMSUB_AB q8, q9, q12, q13
1324
vtrn.16 q0, q1
1325
SUMSUB_AB q10, q11, q14, q15
1326
vtrn.16 q2, q3
1327
SUMSUB_AB q12, q13, q0, q1
1328
vtrn.32 q8, q10
1329
SUMSUB_AB q14, q15, q2, q3
1330
vtrn.32 q9, q11
1331
SUMSUB_AB q0, q2, q8, q10
1332
vtrn.32 q12, q14
1333
SUMSUB_AB q1, q3, q9, q11
1334
vtrn.32 q13, q15
1335
SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1336
1337
vabs.s16 q12, q0
1338
vabs.s16 q13, q8
1339
vabs.s16 q15, q1
1340
vadd.s16 q12, q12, q13
1341
vabs.s16 q14, q2
1342
vand.s16 q12, q12, q6
1343
vabs.s16 q13, q3
1344
vadd.s16 q12, q12, q15
1345
vabs.s16 q15, q9
1346
vadd.s16 q12, q12, q14
1347
vabs.s16 q14, q10
1348
vadd.s16 q12, q12, q13
1349
vabs.s16 q13, q11
1350
vadd.s16 q12, q12, q15
1351
vsub.s16 q15, q11, q3
1352
vadd.s16 q12, q12, q14
1353
vadd.s16 q14, q11, q3
1354
vadd.s16 q12, q12, q13
1355
vsub.s16 q13, q10, q2
1356
vadd.s16 q2, q10, q2
1357
vpadal.u16 q4, q12
1358
1359
SUMSUB_AB q10, q11, q9, q1
1360
SUMSUB_AB q9, q8, q0, q8
1361
vswp d29, d30
1362
vabs.s16 q14, q14
1363
vabs.s16 q15, q15
1364
vswp d5, d26
1365
vabs.s16 q2, q2
1366
vabs.s16 q13, q13
1367
vswp d21, d22
1368
vabs.s16 q10, q10
1369
vabs.s16 q11, q11
1370
vmax.s16 q3, q14, q15
1371
vmax.s16 q2, q2, q13
1372
vmax.s16 q1, q10, q11
1373
vswp d19, d16
1374
SUMSUB_AB q14, q15, q9, q8
1375
1376
vadd.s16 q2, q2, q3
1377
vadd.s16 q2, q2, q1
1378
vand q14, q14, q7
1379
vadd.s16 q2, q2, q2
1380
vabs.s16 q15, q15
1381
vabs.s16 q14, q14
1382
vadd.s16 q2, q2, q15
1383
vadd.s16 q2, q2, q14
1384
vpadal.u16 q5, q2
1385
bx lr
1386
endfunc
1387
1388
1389
.macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1390
vld1.64 {\db}, [r2], r3
1391
vmull.u8 \ssa, \da, \da
1392
vmull.u8 \s12, \da, \db
1393
.if \n == 1
1394
vpaddl.u16 q2, \lastssa
1395
vpaddl.u16 q3, \lasts12
1396
vaddl.u8 q0, d0, \da
1397
.else
1398
vpadal.u16 q2, \lastssa
1399
vpadal.u16 q3, \lasts12
1400
vaddw.u8 q0, q0, \da
1401
.endif
1402
vpadal.u16 q2, \lastssb
1403
.if \n < 3
1404
vld1.64 {\dnext}, [r0], r1
1405
.endif
1406
.if \n == 1
1407
vaddl.u8 q1, d2, \db
1408
.else
1409
vaddw.u8 q1, q1, \db
1410
.endif
1411
vmull.u8 \ssb, \db, \db
1412
.endm
1413
1414
function x264_pixel_ssim_4x4x2_core_neon
1415
ldr ip, [sp]
1416
vld1.64 {d0}, [r0], r1
1417
vld1.64 {d2}, [r2], r3
1418
vmull.u8 q2, d0, d0
1419
vmull.u8 q3, d0, d2
1420
vld1.64 {d28}, [r0], r1
1421
vmull.u8 q15, d2, d2
1422
1423
SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1424
SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1425
SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1426
1427
vpadal.u16 q2, q8
1428
vpaddl.u16 q0, q0
1429
vpaddl.u16 q1, q1
1430
vpadal.u16 q2, q15
1431
vpadal.u16 q3, q9
1432
1433
vpadd.u32 d0, d0, d1
1434
vpadd.u32 d1, d2, d3
1435
vpadd.u32 d2, d4, d5
1436
vpadd.u32 d3, d6, d7
1437
1438
vst4.32 {d0-d3}, [ip]
1439
bx lr
1440
endfunc
1441
1442
// FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1443
function x264_pixel_ssim_end4_neon
1444
vld1.32 {d16-d19}, [r0,:128]!
1445
vld1.32 {d20-d23}, [r1,:128]!
1446
vadd.s32 q0, q8, q10
1447
vadd.s32 q1, q9, q11
1448
vld1.32 {d24-d27}, [r0,:128]!
1449
vadd.s32 q0, q0, q1
1450
vld1.32 {d28-d31}, [r1,:128]!
1451
vadd.s32 q2, q12, q14
1452
vadd.s32 q3, q13, q15
1453
vld1.32 {d16-d17}, [r0,:128]
1454
vadd.s32 q1, q1, q2
1455
vld1.32 {d18-d19}, [r1,:128]
1456
vadd.s32 q8, q8, q9
1457
vadd.s32 q2, q2, q3
1458
vadd.s32 q3, q3, q8
1459
1460
vtrn.32 q0, q1
1461
vtrn.32 q2, q3
1462
vswp d1, d4
1463
vswp d3, d6
1464
1465
// s1=q0, s2=q1, ss=q2, s12=q3
1466
vmul.s32 q8, q0, q1 // s1*s2
1467
vmul.s32 q0, q0, q0
1468
vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1469
1470
vshl.s32 q3, q3, #7
1471
vshl.s32 q2, q2, #6
1472
vadd.s32 q1, q8, q8
1473
1474
mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1475
movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1476
vdup.32 q14, r3
1477
vdup.32 q15, ip
1478
1479
vsub.s32 q2, q2, q0 // vars
1480
vsub.s32 q3, q3, q1 // covar*2
1481
vadd.s32 q0, q0, q14
1482
vadd.s32 q2, q2, q15
1483
vadd.s32 q1, q1, q14
1484
vadd.s32 q3, q3, q15
1485
1486
vcvt.f32.s32 q0, q0
1487
vcvt.f32.s32 q2, q2
1488
vcvt.f32.s32 q1, q1
1489
vcvt.f32.s32 q3, q3
1490
1491
vmul.f32 q0, q0, q2
1492
vmul.f32 q1, q1, q3
1493
1494
cmp r2, #4
1495
1496
vdiv.f32 s0, s4, s0
1497
vdiv.f32 s1, s5, s1
1498
vdiv.f32 s2, s6, s2
1499
vdiv.f32 s3, s7, s3
1500
1501
beq ssim_skip
1502
movrel r3, mask_ff
1503
sub r3, r3, r2, lsl #2
1504
vld1.64 {d6-d7}, [r3]
1505
vand q0, q0, q3
1506
ssim_skip:
1507
vadd.f32 d0, d0, d1
1508
vpadd.f32 d0, d0, d0
1509
vmov.32 r0, d0[0]
1510
bx lr
1511
endfunc
1512
1513