Commit b46cec4f authored by David Conrad's avatar David Conrad Committed by Fiona Glaser

ARM NEON versions of weightp functions

parent 40d72156
......@@ -432,6 +432,311 @@ avg2_w20_loop:
.endfunc
.macro weight_prologue type
push {r4-r5,lr}
ldr r4, [sp, #4*3] // weight_t
ldr ip, [sp, #4*3+4] // h
.ifc \type, full
ldr lr, [r4, #32] // denom
.endif
ldrd r4, [r4, #32+4] // scale, offset
vdup.16 q0, r4
vdup.16 q1, r5
.ifc \type, full
rsb lr, lr, #0
vdup.16 q2, lr
.endif
.endm
// void mc_weight( uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
// const x264_weight_t *weight, int height )
function x264_mc_weight_w20_neon
weight_prologue full
sub r1, #16
weight20_loop:
subs ip, #2
vld1.8 {d17-d19}, [r2], r3
vmovl.u8 q10, d17
vmovl.u8 q11, d18
vmovl.u8 q14, d19
vld1.8 {d16-d18}, [r2], r3
vmovl.u8 q12, d16
vmovl.u8 q13, d17
vmovl.u8 q15, d18
vmul.s16 q10, q10, q0
vmul.s16 q11, q11, q0
vmul.s16 q12, q12, q0
vmul.s16 q13, q13, q0
vmul.s16 d28, d28, d0
vmul.s16 d29, d30, d0
vrshl.s16 q10, q10, q2
vrshl.s16 q11, q11, q2
vrshl.s16 q12, q12, q2
vrshl.s16 q13, q13, q2
vrshl.s16 q14, q14, q2
vadd.s16 q10, q10, q1
vadd.s16 q11, q11, q1
vadd.s16 q12, q12, q1
vadd.s16 q13, q13, q1
vadd.s16 q14, q14, q1
vqmovun.s16 d16, q10
vqmovun.s16 d17, q11
vqmovun.s16 d18, q12
vqmovun.s16 d19, q13
vqmovun.s16 d20, q14
vst1.8 {d16-d17}, [r0,:128]!
vst1.32 {d20[0]}, [r0,:32], r1
vst1.8 {d18-d19}, [r0,:128]!
vst1.32 {d20[1]}, [r0,:32], r1
bgt weight20_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w16_neon
weight_prologue full
weight16_loop:
subs ip, #2
vld1.8 {d16-d17}, [r2], r3
vld1.8 {d18-d19}, [r2], r3
vmovl.u8 q10, d16
vmovl.u8 q11, d17
vmovl.u8 q12, d18
vmovl.u8 q13, d19
vmul.s16 q10, q10, q0
vmul.s16 q11, q11, q0
vmul.s16 q12, q12, q0
vmul.s16 q13, q13, q0
vrshl.s16 q10, q10, q2
vrshl.s16 q11, q11, q2
vrshl.s16 q12, q12, q2
vrshl.s16 q13, q13, q2
vadd.s16 q10, q10, q1
vadd.s16 q11, q11, q1
vadd.s16 q12, q12, q1
vadd.s16 q13, q13, q1
vqmovun.s16 d16, q10
vqmovun.s16 d17, q11
vqmovun.s16 d18, q12
vqmovun.s16 d19, q13
vst1.8 {d16-d17}, [r0,:128], r1
vst1.8 {d18-d19}, [r0,:128], r1
bgt weight16_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w8_neon
weight_prologue full
weight8_loop:
subs ip, #2
vld1.8 {d16}, [r2], r3
vld1.8 {d18}, [r2], r3
vmovl.u8 q8, d16
vmovl.u8 q9, d18
vmul.s16 q8, q8, q0
vmul.s16 q9, q9, q0
vrshl.s16 q8, q8, q2
vrshl.s16 q9, q9, q2
vadd.s16 q8, q8, q1
vadd.s16 q9, q9, q1
vqmovun.s16 d16, q8
vqmovun.s16 d18, q9
vst1.8 {d16}, [r0,:64], r1
vst1.8 {d18}, [r0,:64], r1
bgt weight8_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w4_neon
weight_prologue full
weight4_loop:
subs ip, #2
vld1.32 {d16[]}, [r2], r3
vld1.32 {d18[]}, [r2], r3
vmovl.u8 q8, d16
vmovl.u8 q9, d18
vmul.s16 d16, d16, d0
vmul.s16 d17, d18, d0
vrshl.s16 q8, q8, q2
vadd.s16 q8, q8, q1
vqmovun.s16 d16, q8
vst1.32 {d16[0]}, [r0,:32], r1
vst1.32 {d16[1]}, [r0,:32], r1
bgt weight4_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w20_nodenom_neon
weight_prologue nodenom
sub r1, #16
weight20_nodenom_loop:
subs ip, #2
vld1.8 {d17-d19}, [r2], r3
vmovl.u8 q10, d17
vmovl.u8 q11, d18
vmovl.u8 q14, d19
vld1.8 {d16-d18}, [r2], r3
vmovl.u8 q12, d16
vmovl.u8 q13, d17
vmovl.u8 q15, d18
vmov q8, q1
vmov q9, q1
vmla.s16 q8, q10, q0
vmla.s16 q9, q11, q0
vmov q10, q1
vmov q11, q1
vmla.s16 q10, q12, q0
vmla.s16 q11, q13, q0
vmov q12, q1
vmla.s16 d24, d28, d0
vmla.s16 d25, d30, d0
vqmovun.s16 d16, q8
vqmovun.s16 d17, q9
vqmovun.s16 d18, q10
vqmovun.s16 d19, q11
vqmovun.s16 d20, q12
vst1.8 {d16-d17}, [r0,:128]!
vst1.32 {d20[0]}, [r0,:32], r1
vst1.8 {d18-d19}, [r0,:128]!
vst1.32 {d20[1]}, [r0,:32], r1
bgt weight20_nodenom_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w16_nodenom_neon
weight_prologue nodenom
weight16_nodenom_loop:
subs ip, #2
vld1.8 {d16-d17}, [r2], r3
vld1.8 {d18-d19}, [r2], r3
vmovl.u8 q12, d16
vmovl.u8 q13, d17
vmovl.u8 q14, d18
vmovl.u8 q15, d19
vmov q8, q1
vmov q9, q1
vmov q10, q1
vmov q11, q1
vmla.s16 q8, q12, q0
vmla.s16 q9, q13, q0
vmla.s16 q10, q14, q0
vmla.s16 q11, q15, q0
vqmovun.s16 d16, q8
vqmovun.s16 d17, q9
vqmovun.s16 d18, q10
vqmovun.s16 d19, q11
vst1.8 {d16-d17}, [r0,:128], r1
vst1.8 {d18-d19}, [r0,:128], r1
bgt weight16_nodenom_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w8_nodenom_neon
weight_prologue nodenom
weight8_nodenom_loop:
subs ip, #2
vld1.8 {d16}, [r2], r3
vld1.8 {d18}, [r2], r3
vmovl.u8 q8, d16
vmovl.u8 q9, d18
vmov q10, q1
vmov q11, q1
vmla.s16 q10, q8, q0
vmla.s16 q11, q9, q0
vqmovun.s16 d16, q10
vqmovun.s16 d17, q11
vst1.8 {d16}, [r0,:64], r1
vst1.8 {d17}, [r0,:64], r1
bgt weight8_nodenom_loop
pop {r4-r5,pc}
.endfunc
function x264_mc_weight_w4_nodenom_neon
weight_prologue nodenom
weight4_nodenom_loop:
subs ip, #2
vld1.32 {d16[]}, [r2], r3
vld1.32 {d18[]}, [r2], r3
vmovl.u8 q8, d16
vmovl.u8 q9, d18
vmov q10, q1
vmla.s16 d20, d16, d0
vmla.s16 d21, d18, d0
vqmovun.s16 d16, q10
vst1.32 {d16[0]}, [r0,:32], r1
vst1.32 {d16[1]}, [r0,:32], r1
bgt weight4_nodenom_loop
pop {r4-r5,pc}
.endfunc
.macro weight_simple_prologue
push {lr}
ldr lr, [sp, #4] // weight_t
ldr ip, [sp, #8] // h
ldr lr, [lr] // offset
vdup.8 q1, lr
.endm
.macro weight_simple name op
function x264_mc_weight_w20_\name\()_neon
weight_simple_prologue
weight20_\name\()_loop:
subs ip, #2
vld1.8 {d16-d18}, [r2], r3
vld1.8 {d19-d21}, [r2], r3
\op q8, q8, q1
\op q9, q9, q1
\op q10, q10, q1
vst1.8 {d16-d18}, [r0,:64], r1
vst1.8 {d19-d21}, [r0,:64], r1
bgt weight20_\name\()_loop
pop {pc}
.endfunc
function x264_mc_weight_w16_\name\()_neon
weight_simple_prologue
weight16_\name\()_loop:
subs ip, #2
vld1.8 {d16-d17}, [r2], r3
vld1.8 {d18-d19}, [r2], r3
\op q8, q8, q1
\op q9, q9, q1
vst1.8 {d16-d17}, [r0,:128], r1
vst1.8 {d18-d19}, [r0,:128], r1
bgt weight16_\name\()_loop
pop {pc}
.endfunc
function x264_mc_weight_w8_\name\()_neon
weight_simple_prologue
weight8_\name\()_loop:
subs ip, #2
vld1.8 {d16}, [r2], r3
vld1.8 {d17}, [r2], r3
\op q8, q8, q1
vst1.8 {d16}, [r0,:64], r1
vst1.8 {d17}, [r0,:64], r1
bgt weight8_\name\()_loop
pop {pc}
.endfunc
function x264_mc_weight_w4_\name\()_neon
weight_simple_prologue
weight4_\name\()_loop:
subs ip, #2
vld1.32 {d16[]}, [r2], r3
vld1.32 {d17[]}, [r2], r3
\op q8, q8, q1
vst1.32 {d16[0]}, [r0,:32], r1
vst1.32 {d17[0]}, [r0,:32], r1
bgt weight4_\name\()_loop
pop {pc}
.endfunc
.endm
weight_simple offsetadd, vqadd.u8
weight_simple offsetsub, vqsub.u8
// void mc_copy( uint8_t *dst, int dst_stride, uint8_t *src, int src_stride, int height )
function x264_mc_copy_w4_neon
ldr ip, [sp]
......
......@@ -43,6 +43,48 @@ void x264_pixel_avg2_w8_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
void x264_pixel_avg2_w16_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
void x264_pixel_avg2_w20_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
#define MC_WEIGHT(func)\
void x264_mc_weight_w20##func##_neon( uint8_t *, int, uint8_t *, int, const x264_weight_t *, int );\
void x264_mc_weight_w16##func##_neon( uint8_t *, int, uint8_t *, int, const x264_weight_t *, int );\
void x264_mc_weight_w8##func##_neon( uint8_t *, int, uint8_t *, int, const x264_weight_t *, int );\
void x264_mc_weight_w4##func##_neon( uint8_t *, int, uint8_t *, int, const x264_weight_t *, int );\
\
static void (* const x264_mc##func##_wtab_neon[6])( uint8_t *, int, uint8_t *, int, const x264_weight_t *, int ) =\
{\
x264_mc_weight_w4##func##_neon,\
x264_mc_weight_w4##func##_neon,\
x264_mc_weight_w8##func##_neon,\
x264_mc_weight_w16##func##_neon,\
x264_mc_weight_w16##func##_neon,\
x264_mc_weight_w20##func##_neon,\
};
MC_WEIGHT()
MC_WEIGHT(_nodenom)
MC_WEIGHT(_offsetadd)
MC_WEIGHT(_offsetsub)
static void x264_weight_cache_neon( x264_t *h, x264_weight_t *w )
{
if( w->i_scale == 1<<w->i_denom )
{
if( w->i_offset < 0 )
{
w->weightfn = x264_mc_offsetsub_wtab_neon;
w->cachea[0] = -w->i_offset;
}
else
{
w->weightfn = x264_mc_offsetadd_wtab_neon;
w->cachea[0] = w->i_offset;
}
}
else if( !w->i_denom )
w->weightfn = x264_mc_nodenom_wtab_neon;
else
w->weightfn = x264_mc_wtab_neon;
}
void x264_mc_copy_w4_neon( uint8_t *, int, uint8_t *, int, int );
void x264_mc_copy_w8_neon( uint8_t *, int, uint8_t *, int, int );
void x264_mc_copy_w16_neon( uint8_t *, int, uint8_t *, int, int );
......@@ -182,6 +224,11 @@ void x264_mc_init_arm( int cpu, x264_mc_functions_t *pf )
pf->avg[PIXEL_4x4] = x264_pixel_avg_4x4_neon;
pf->avg[PIXEL_4x2] = x264_pixel_avg_4x2_neon;
pf->weight = x264_mc_wtab_neon;
pf->offsetadd = x264_mc_offsetadd_wtab_neon;
pf->offsetsub = x264_mc_offsetsub_wtab_neon;
pf->weight_cache = x264_weight_cache_neon;
// Apple's gcc stupidly cannot align stack variables, and ALIGNED_ARRAY can't work on structs
#ifndef SYS_MACOSX
pf->memcpy_aligned = x264_memcpy_aligned_neon;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment