.section .rodata
.align 4
p16weight: .short 1,2,3,4,5,6,7,8
.text
.macro ldcol.8 rd, rs, rt, n=8, hi=0
.if \n == 8 || \hi == 0
vld1.8 {\rd[0]}, [\rs], \rt
vld1.8 {\rd[1]}, [\rs], \rt
vld1.8 {\rd[2]}, [\rs], \rt
vld1.8 {\rd[3]}, [\rs], \rt
.endif
.if \n == 8 || \hi == 1
vld1.8 {\rd[4]}, [\rs], \rt
vld1.8 {\rd[5]}, [\rs], \rt
vld1.8 {\rd[6]}, [\rs], \rt
vld1.8 {\rd[7]}, [\rs], \rt
.endif
.endm
.macro ldcol.16 rd1, rd2, rs, rt, ru
add \ru, \rs, \rt, lsl
vld1.8 {\rd1[0]}, [\rs], \rt
vld1.8 {\rd2[0]}, [\ru], \rt
vld1.8 {\rd1[1]}, [\rs], \rt
vld1.8 {\rd2[1]}, [\ru], \rt
vld1.8 {\rd1[2]}, [\rs], \rt
vld1.8 {\rd2[2]}, [\ru], \rt
vld1.8 {\rd1[3]}, [\rs], \rt
vld1.8 {\rd2[3]}, [\ru], \rt
vld1.8 {\rd1[4]}, [\rs], \rt
vld1.8 {\rd2[4]}, [\ru], \rt
vld1.8 {\rd1[5]}, [\rs], \rt
vld1.8 {\rd2[5]}, [\ru], \rt
vld1.8 {\rd1[6]}, [\rs], \rt
vld1.8 {\rd2[6]}, [\ru], \rt
vld1.8 {\rd1[7]}, [\rs], \rt
vld1.8 {\rd2[7]}, [\ru], \rt
.endm
.macro add16x8 dq, dl, dh, rl, rh
vaddl.u8 \dq, \rl, \rh
vadd.u16 \dl, \dl, \dh
vpadd.u16 \dl, \dl, \dl
vpadd.u16 \dl, \dl, \dl
.endm
// because gcc doesn't believe in using the free shift in add
function x264_predict_4x4_h_armv6
ldrb r1, [r0,
ldrb r2, [r0,
ldrb r3, [r0,
ldrb ip, [r0,
add r1, r1, r1, lsl
add r2, r2, r2, lsl
add r3, r3, r3, lsl
add ip, ip, ip, lsl
add r1, r1, r1, lsl
str r1, [r0,
add r2, r2, r2, lsl
str r2, [r0,
add r3, r3, r3, lsl
str r3, [r0,
add ip, ip, ip, lsl
str ip, [r0,
bx lr
endfunc
function x264_predict_4x4_v_armv6
ldr r1, [r0,
str r1, [r0,
str r1, [r0,
str r1, [r0,
str r1, [r0,
bx lr
endfunc
function x264_predict_4x4_dc_armv6
mov ip,
ldr r1, [r0,
ldrb r2, [r0,
ldrb r3, [r0,
usad8 r1, r1, ip
add r2, r2,
ldrb ip, [r0,
add r2, r2, r3
ldrb r3, [r0,
add r2, r2, ip
add r2, r2, r3
add r1, r1, r2
lsr r1, r1,
add r1, r1, r1, lsl
add r1, r1, r1, lsl
str r1, [r0,
str r1, [r0,
str r1, [r0,
str r1, [r0,
bx lr
endfunc
function x264_predict_4x4_dc_top_neon
mov r12,
sub r1, r0,
vld1.32 d1[], [r1,:32]
vpaddl.u8 d1, d1
vpadd.u16 d1, d1, d1
vrshr.u16 d1, d1,
vdup.8 d1, d1[0]
vst1.32 d1[0], [r0,:32], r12
vst1.32 d1[0], [r0,:32], r12
vst1.32 d1[0], [r0,:32], r12
vst1.32 d1[0], [r0,:32], r12
bx lr
endfunc
// return a1 = (a1+2*b1+c1+2)>>2 a2 = (a2+2*b2+c2+2)>>2
.macro PRED4x4_LOWPASS a1 b1 c1 a2 b2 c2 pb_1
uhadd8 \a1, \a1, \c1
uhadd8 \a2, \a2, \c2
uhadd8 \c1, \a1, \b1
uhadd8 \c2, \a2, \b2
eor \a1, \a1, \b1
eor \a2, \a2, \b2
and \a1, \a1, \pb_1
and \a2, \a2, \pb_1
uadd8 \a1, \a1, \c1
uadd8 \a2, \a2, \c2
.endm
function x264_predict_4x4_ddr_armv6
ldr r1, [r0,
ldrb r2, [r0,
ldrb r3, [r0,
push {r4-r6,lr}
add r2, r2, r1, lsl
ldrb r4, [r0,
add r3, r3, r2, lsl
ldrb r5, [r0,
ldrb r6, [r0,
add r4, r4, r3, lsl
add r5, r5, r4, lsl
add r6, r6, r5, lsl
ldr ip, =0x01010101
PRED4x4_LOWPASS r1, r2, r3, r4, r5, r6, ip
str r1, [r0,
lsl r2, r1,
lsl r3, r1,
lsl r4, r4,
lsl r5, r1,
add r2, r2, r4, lsr
str r2, [r0,
add r3, r3, r4, lsr
str r3, [r0,
add r5, r5, r4, lsr
str r5, [r0,
pop {r4-r6,pc}
endfunc
function x264_predict_4x4_ddl_neon
sub r0,
mov ip,
vld1.64 {d0}, [r0], ip
vdup.8 d3, d0[7]
vext.8 d1, d0, d0,
vext.8 d2, d0, d3,
vhadd.u8 d0, d0, d2
vrhadd.u8 d0, d0, d1
vst1.32 {d0[0]}, [r0,:32], ip
vext.8 d1, d0, d0,
vext.8 d2, d0, d0,
vst1.32 {d1[0]}, [r0,:32], ip
vext.8 d3, d0, d0,
vst1.32 {d2[0]}, [r0,:32], ip
vst1.32 {d3[0]}, [r0,:32], ip
bx lr
endfunc
function x264_predict_8x8_dc_neon
mov ip,
ldrd r2, r3, [r1,
push {r4-r5,lr}
ldrd r4, r5, [r1,
lsl r3, r3,
ldrb lr, [r1,
usad8 r2, r2, ip
usad8 r3, r3, ip
usada8 r2, r4, ip, r2
add lr, lr,
usada8 r3, r5, ip, r3
add r2, r2, lr
mov ip,
add r2, r2, r3
lsr r2, r2,
vdup.8 d0, r2
.rept 8
vst1.64 {d0}, [r0,:64], ip
.endr
pop {r4-r5,pc}
endfunc
function x264_predict_8x8_h_neon
add r1, r1,
mov ip,
vld1.64 {d16}, [r1]
vdup.8 d0, d16[7]
vdup.8 d1, d16[6]
vst1.64 {d0}, [r0,:64], ip
vdup.8 d2, d16[5]
vst1.64 {d1}, [r0,:64], ip
vdup.8 d3, d16[4]
vst1.64 {d2}, [r0,:64], ip
vdup.8 d4, d16[3]
vst1.64 {d3}, [r0,:64], ip
vdup.8 d5, d16[2]
vst1.64 {d4}, [r0,:64], ip
vdup.8 d6, d16[1]
vst1.64 {d5}, [r0,:64], ip
vdup.8 d7, d16[0]
vst1.64 {d6}, [r0,:64], ip
vst1.64 {d7}, [r0,:64], ip
bx lr
endfunc
function x264_predict_8x8_v_neon
add r1, r1,
mov r12,
vld1.8 {d0}, [r1,:64]
.rept 8
vst1.8 {d0}, [r0,:64], r12
.endr
bx lr
endfunc
function x264_predict_8x8_ddl_neon
add r1,
vld1.8 {d0, d1}, [r1,:128]
vmov.i8 q3,
vrev64.8 d2, d1
vext.8 q8, q3, q0,
vext.8 q2, q0, q1,
vhadd.u8 q8, q2
mov r12,
vrhadd.u8 q0, q8
vext.8 d2, d0, d1,
vext.8 d3, d0, d1,
vst1.8 d2, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 d3, [r0,:64], r12
vext.8 d3, d0, d1,
vst1.8 d2, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 d3, [r0,:64], r12
vext.8 d3, d0, d1,
vst1.8 d2, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 d3, [r0,:64], r12
vst1.8 d2, [r0,:64], r12
vst1.8 d1, [r0,:64], r12
bx lr
endfunc
function x264_predict_8x8_ddr_neon
vld1.8 {d0-d3}, [r1,:128]
vext.8 q2, q0, q1,
vext.8 q3, q0, q1,
vhadd.u8 q2, q2, q3
vrhadd.u8 d0, d1, d4
vrhadd.u8 d1, d2, d5
add r0,
mov r12,
vext.8 d2, d0, d1,
vst1.8 {d0}, [r0,:64], r12
vext.8 d4, d0, d1,
vst1.8 {d2}, [r0,:64], r12
vext.8 d5, d0, d1,
vst1.8 {d4}, [r0,:64], r12
vext.8 d4, d0, d1,
vst1.8 {d5}, [r0,:64], r12
vext.8 d5, d0, d1,
vst1.8 {d4}, [r0,:64], r12
vext.8 d4, d0, d1,
vst1.8 {d5}, [r0,:64], r12
vext.8 d5, d0, d1,
vst1.8 {d4}, [r0,:64], r12
vst1.8 {d5}, [r0,:64], r12
bx lr
endfunc
function x264_predict_8x8_vl_neon
add r1,
mov r12,
vld1.8 {d0, d1}, [r1,:128]
vext.8 q1, q1, q0,
vext.8 q2, q0, q2,
vrhadd.u8 q3, q0, q2
vhadd.u8 q1, q1, q2
vrhadd.u8 q0, q0, q1
vext.8 d2, d0, d1,
vst1.8 {d6}, [r0,:64], r12
vext.8 d3, d6, d7,
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 {d3}, [r0,:64], r12
vext.8 d3, d6, d7,
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 {d3}, [r0,:64], r12
vext.8 d3, d6, d7,
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 {d3}, [r0,:64], r12
vst1.8 {d2}, [r0,:64], r12
bx lr
endfunc
function x264_predict_8x8_vr_neon
add r1,
mov r12,
vld1.8 {d4,d5}, [r1,:64]
vext.8 q1, q2, q2,
vext.8 q0, q2, q2,
vhadd.u8 q3, q2, q1
vrhadd.u8 q2, q2, q0
vrhadd.u8 q0, q0, q3
vmov d2, d0
vst1.8 {d5}, [r0,:64], r12
vuzp.8 d2, d0
vst1.8 {d1}, [r0,:64], r12
vext.8 d6, d0, d5,
vext.8 d3, d2, d1,
vst1.8 {d6}, [r0,:64], r12
vst1.8 {d3}, [r0,:64], r12
vext.8 d6, d0, d5,
vext.8 d3, d2, d1,
vst1.8 {d6}, [r0,:64], r12
vst1.8 {d3}, [r0,:64], r12
vext.8 d6, d0, d5,
vext.8 d3, d2, d1,
vst1.8 {d6}, [r0,:64], r12
vst1.8 {d3}, [r0,:64], r12
bx lr
endfunc
function x264_predict_8x8_hd_neon
mov r12,
add r1,
vld1.8 {d2,d3}, [r1]
vext.8 q3, q1, q1,
vext.8 q2, q1, q1,
vrhadd.u8 q8, q1, q3
vhadd.u8 q1, q2
vrhadd.u8 q0, q1, q3
vzip.8 d16, d0
vext.8 d2, d0, d1,
vext.8 d3, d0, d1,
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d0, d1,
vst1.8 {d3}, [r0,:64], r12
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d16, d0,
vst1.8 {d0}, [r0,:64], r12
vext.8 d3, d16, d0,
vst1.8 {d2}, [r0,:64], r12
vext.8 d2, d16, d0,
vst1.8 {d3}, [r0,:64], r12
vst1.8 {d2}, [r0,:64], r12
vst1.8 {d16}, [r0,:64], r12
bx lr
endfunc
function x264_predict_8x8_hu_neon
mov r12,
add r1,
vld1.8 {d7}, [r1]
vdup.8 d6, d7[0]
vrev64.8 d7, d7
vext.8 d4, d7, d6,
vext.8 d2, d7, d6,
vhadd.u8 d16, d7, d4
vrhadd.u8 d0, d2, d7
vrhadd.u8 d1, d16, d2
vzip.8 d0, d1
vdup.16 q1, d1[3]
vext.8 q2, q0, q1,
vext.8 q3, q0, q1,
vext.8 q8, q0, q1,
vst1.8 {d0}, [r0,:64], r12
vst1.8 {d4}, [r0,:64], r12
vst1.8 {d6}, [r0,:64], r12
vst1.8 {d16}, [r0,:64], r12
vst1.8 {d1}, [r0,:64], r12
vst1.8 {d5}, [r0,:64], r12
vst1.8 {d7}, [r0,:64], r12
vst1.8 {d17}, [r0,:64]
bx lr
endfunc
function x264_predict_8x8c_dc_top_neon
sub r2, r0,
mov r1,
vld1.8 {d0}, [r2,:64]
vpaddl.u8 d0, d0
vpadd.u16 d0, d0, d0
vrshrn.u16 d0, q0,
vdup.8 d1, d0[1]
vdup.8 d0, d0[0]
vtrn.32 d0, d1
b pred8x8_dc_end
endfunc
function x264_predict_8x8c_dc_left_neon
mov r1,
sub r2, r0,
ldcol.8 d0, r2, r1
vpaddl.u8 d0, d0
vpadd.u16 d0, d0, d0
vrshrn.u16 d0, q0,
vdup.8 d1, d0[1]
vdup.8 d0, d0[0]
b pred8x8_dc_end
endfunc
function x264_predict_8x8c_dc_neon
sub r2, r0,
mov r1,
vld1.8 {d0}, [r2,:64]
sub r2, r0,
ldcol.8 d1, r2, r1
vtrn.32 d0, d1
vpaddl.u8 q0, q0
vpadd.u16 d0, d0, d1
vpadd.u16 d1, d0, d0
vrshrn.u16 d2, q0,
vrshrn.u16 d3, q0,
vdup.8 d0, d2[4]
vdup.8 d1, d3[3]
vdup.8 d4, d3[2]
vdup.8 d5, d2[5]
vtrn.32 q0, q2
pred8x8_dc_end:
add r2, r0, r1, lsl
.rept 4
vst1.8 {d0}, [r0,:64], r1
vst1.8 {d1}, [r2,:64], r1
.endr
bx lr
endfunc
function x264_predict_8x8c_h_neon
sub r1, r0,
mov ip,
.rept 4
vld1.8 {d0[]}, [r1], ip
vld1.8 {d2[]}, [r1], ip
vst1.64 {d0}, [r0,:64], ip
vst1.64 {d2}, [r0,:64], ip
.endr
bx lr
endfunc
function x264_predict_8x8c_v_neon
sub r0, r0,
mov ip,
vld1.64 {d0}, [r0,:64], ip
.rept 8
vst1.64 {d0}, [r0,:64], ip
.endr
bx lr
endfunc
function x264_predict_8x8c_p_neon
sub r3, r0,
mov r1,
add r2, r3,
sub r3, r3,
vld1.32 {d0[0]}, [r3]
vld1.32 {d2[0]}, [r2,:32], r1
ldcol.8 d0, r3, r1, 4, hi=1
add r3, r3, r1
ldcol.8 d3, r3, r1, 4
vaddl.u8 q8, d2, d3
vrev32.8 d0, d0
vtrn.32 d2, d3
vsubl.u8 q2, d2, d0
movrel r3, p16weight
vld1.16 {q0}, [r3,:128]
vmul.s16 d4, d4, d0
vmul.s16 d5, d5, d0
vpadd.i16 d4, d4, d5
vpaddl.s16 d4, d4
vshl.i32 d5, d4,
vadd.s32 d4, d4, d5
vrshrn.s32 d4, q2,
mov r3,
vtrn.16 d4, d5
vadd.i16 d2, d4, d5
vshl.i16 d3, d2,
vrev64.16 d16, d16
vsub.i16 d3, d3, d2
vadd.i16 d16, d16, d0
vshl.i16 d2, d16,
vsub.i16 d2, d2, d3
vext.16 q0, q0, q0,
vmov.16 d0[0], r3
vmul.i16 q0, q0, d4[0]
vdup.16 q1, d2[0]
vdup.16 q3, d5[0]
vadd.i16 q1, q1, q0
mov r3,
1:
vqshrun.s16 d0, q1,
vadd.i16 q1, q1, q3
vst1.8 {d0}, [r0,:64], r1
subs r3, r3,
bne 1b
bx lr
endfunc
function x264_predict_8x16c_dc_top_neon
sub r2, r0,
mov r1,
vld1.8 {d0}, [r2,:64]
vpaddl.u8 d0, d0
vpadd.u16 d0, d0, d0
vrshrn.u16 d0, q0,
vdup.8 d1, d0[1]
vdup.8 d0, d0[0]
vtrn.32 d0, d1
add r2, r0, r1, lsl
.rept 4
vst1.8 {d0}, [r0,:64], r1
vst1.8 {d1}, [r2,:64], r1
.endr
add r2, r2, r1, lsl
add r0, r0, r1, lsl
.rept 4
vst1.8 {d0}, [r0,:64], r1
vst1.8 {d1}, [r2,:64], r1
.endr
bx lr
endfunc
function x264_predict_8x16c_h_neon
sub r1, r0,
mov ip,
.rept 8
vld1.8 {d0[]}, [r1], ip
vld1.8 {d2[]}, [r1], ip
vst1.64 {d0}, [r0,:64], ip
vst1.64 {d2}, [r0,:64], ip
.endr
bx lr
endfunc
function x264_predict_8x16c_p_neon
sub r3, r0,
mov r1,
add r2, r3,
sub r3, r3,
vld1.32 {d0[0]}, [r3]
vld1.32 {d2[0]}, [r2,:32], r1
ldcol.8 d1, r3, r1
add r3, r3, r1
ldcol.8 d3, r3, r1
vrev64.32 d16, d3
vaddl.u8 q8, d2, d16
vrev32.8 d0, d0
vsubl.u8 q2, d2, d0
vrev64.8 d1, d1
vsubl.u8 q3, d3, d1
movrel r3, p16weight
vld1.16 {q0}, [r3,:128]
vmul.s16 d4, d4, d0
vmul.s16 q3, q3, q0
vpadd.i16 d4, d4, d5
vpadd.i16 d6, d6, d7
vpaddl.s16 d4, d4 @ d4[0] = H
vpaddl.s16 d6, d6
vpadd.s32 d6, d6 @ d6[0] = V
vshl.i32 d5, d4,
vadd.s32 d4, d4, d5 @ d4[0] = 17*H
vshl.i32 d7, d6,
vrshrn.s32 d4, q2,
vadd.s32 d6, d6, d7 @ d6[0] = 5*V
vrshrn.s32 d6, q3,
mov r3,
vshl.i16 d3, d4,
vsub.i16 d3, d3, d4 @ d2[0] = 3 * b
vshl.i16 d2, d6,
vadd.i16 d3, d3, d2 @ d2[0] = 3 * b + 8 * c
vsub.i16 d3, d3, d6 @ d2[0] = 3 * b + 7 * c
vrev64.16 d16, d16
vadd.i16 d16, d16, d0 @ d16[0] = src[]+src[] + 1
vshl.i16 d2, d16,
vsub.i16 d2, d2, d3 @ i00
vext.16 q0, q0, q0,
vmov.16 d0[0], r3
vmul.i16 q0, q0, d4[0]
vdup.16 q1, d2[0]
vdup.16 q3, d6[0]
vadd.i16 q1, q1, q0
mov r3,
1:
vqshrun.s16 d0, q1,
vadd.i16 q1, q1, q3
vst1.8 {d0}, [r0,:64], r1
subs r3, r3,
bne 1b
bx lr
endfunc
function x264_predict_16x16_dc_top_neon
sub r2, r0,
mov r1,
vld1.8 {q0}, [r2,:128]
add16x8 q0, d0, d1, d0, d1
vrshrn.u16 d0, q0,
vdup.8 q0, d0[0]
b pred16x16_dc_end
endfunc
function x264_predict_16x16_dc_left_neon
mov r1,
sub r2, r0,
ldcol.8 d0, r2, r1
ldcol.8 d1, r2, r1
add16x8 q0, d0, d1, d0, d1
vrshrn.u16 d0, q0,
vdup.8 q0, d0[0]
b pred16x16_dc_end
endfunc
function x264_predict_16x16_dc_neon
sub r3, r0,
sub r0, r0,
vld1.64 {d0-d1}, [r3,:128]
ldrb ip, [r0],
vaddl.u8 q0, d0, d1
ldrb r1, [r0],
vadd.u16 d0, d0, d1
vpadd.u16 d0, d0, d0
vpadd.u16 d0, d0, d0
.rept 4
ldrb r2, [r0],
add ip, ip, r1
ldrb r3, [r0],
add ip, ip, r2
ldrb r1, [r0],
add ip, ip, r3
.endr
ldrb r2, [r0],
add ip, ip, r1
ldrb r3, [r0],
add ip, ip, r2
sub r0, r0,
add ip, ip, r3
vdup.16 d1, ip
vadd.u16 d0, d0, d1
mov r1,
add r0, r0,
vrshr.u16 d0, d0,
vdup.8 q0, d0[0]
pred16x16_dc_end:
.rept 16
vst1.64 {d0-d1}, [r0,:128], r1
.endr
bx lr
endfunc
function x264_predict_16x16_h_neon
sub r1, r0,
mov ip,
.rept 8
vld1.8 {d0[]}, [r1], ip
vmov d1, d0
vld1.8 {d2[]}, [r1], ip
vmov d3, d2
vst1.64 {d0-d1}, [r0,:128], ip
vst1.64 {d2-d3}, [r0,:128], ip
.endr
bx lr
endfunc
function x264_predict_16x16_v_neon
sub r0, r0,
mov ip,
vld1.64 {d0-d1}, [r0,:128], ip
.rept 16
vst1.64 {d0-d1}, [r0,:128], ip
.endr
bx lr
endfunc
function x264_predict_16x16_p_neon
sub r3, r0,
mov r1,
add r2, r3,
sub r3, r3,
vld1.8 {d0}, [r3]
vld1.8 {d2}, [r2,:64], r1
ldcol.8 d1, r3, r1
add r3, r3, r1
ldcol.8 d3, r3, r1
vrev64.8 q0, q0
vaddl.u8 q8, d2, d3
vsubl.u8 q2, d2, d0
vsubl.u8 q3, d3, d1
movrel r3, p16weight
vld1.8 {q0}, [r3,:128]
vmul.s16 q2, q2, q0
vmul.s16 q3, q3, q0
vadd.i16 d4, d4, d5
vadd.i16 d5, d6, d7
vpadd.i16 d4, d4, d5
vpadd.i16 d4, d4, d4
vshll.s16 q3, d4,
vaddw.s16 q2, q3, d4
vrshrn.s32 d4, q2,
mov r3,
vtrn.16 d4, d5
vadd.i16 d2, d4, d5
vshl.i16 d3, d2,
vrev64.16 d16, d17
vsub.i16 d3, d3, d2
vadd.i16 d16, d16, d0
vshl.i16 d2, d16,
vsub.i16 d2, d2, d3
vshl.i16 d3, d4,
vext.16 q0, q0, q0,
vsub.i16 d6, d5, d3
vmov.16 d0[0], r3
vmul.i16 q0, q0, d4[0]
vdup.16 q1, d2[0]
vdup.16 q2, d4[0]
vdup.16 q3, d6[0]
vshl.i16 q2, q2,
vadd.i16 q1, q1, q0
vadd.i16 q3, q3, q2
mov r3,
1:
vqshrun.s16 d0, q1,
vadd.i16 q1, q1, q2
vqshrun.s16 d1, q1,
vadd.i16 q1, q1, q3
vst1.8 {q0}, [r0,:128], r1
subs r3, r3,
bne 1b
bx lr
endfunc