diff options
author | Roland Scheidegger <rscheidegger_lists@hispeed.ch> | 2012-04-20 04:10:57 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-04-21 02:27:06 +0400 |
commit | a812b599b504b39a8021827da89d5e23fb361cc9 (patch) | |
tree | 34b3f8ce41b8cdca8df4f3b84682731b09c94f34 /libavcodec/x86/h264_i386.h | |
parent | 3194ab78a6c4ea0a4c60c91c4d0ea34028ca408f (diff) |
h264: assembly version of get_cabac for x86_64 with PIC (v4)
This adds a hand-optimized assembly version for get_cabac much like the
existing one, but it works if the table offsets are RIP-relative.
Compared to the non-RIP-relative version this adds 2 lea instructions
and it needs one extra register.
There is a surprisingly large performance improvement over the c version (more
so than the generated assembly seems to suggest) just in get_cabac, I measured
roughly 40% faster for get_cabac on a K8. However, overall the difference is
not that big, I measured roughly 5% on a test clip on a K8 and a Core2.
Hopefully it still compiles on x86 32bit...
v2: incorporated feedback from Loren Merritt to avoid rip-relative movs
for every table, and got rid of unnecessary @GOTPCREL.
v3: apply similar fixes to the the decode_significance functions, and use
same macro arguments for non-pic case.
v4: prettify inline asm arguments, add a non-fast-cmov version (as I expect
the c code to be faster otherwise since both cmov and sbb suck hard on a
Prescott, even can't construct the mask with a 64bit shift as that's just as
terrible - it's quite difficult to find usable instructions on that chip...).
This is tested to work but not on a P4, in theory it _should_ be fast there.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/x86/h264_i386.h')
-rw-r--r-- | libavcodec/x86/h264_i386.h | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index 6aa2d073e3..20ffa25f08 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -36,7 +36,7 @@ //FIXME use some macros to avoid duplicating get_cabac (cannot be done yet //as that would make optimization work hard) -#if HAVE_7REGS && !defined(BROKEN_RELOCATIONS) +#if HAVE_7REGS static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off){ @@ -45,20 +45,31 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; + +#ifdef BROKEN_RELOCATIONS + int *rip; + + __asm__ volatile( + "1: \n\t" + "lea 1b(%%rip), %0 \n\t" + : "=&r"(rip) + ); +#endif + __asm__ volatile( "3: \n\t" - BRANCHLESS_GET_CABAC("%4", "(%1)", "%3", "%w3", - "%5", "%k0", "%b0", - "%a11(%6)", "%a12(%6)") + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%a11(%6)", "%a12(%6)", "%13") "test $1, %4 \n\t" " jz 4f \n\t" "add %10, %1 \n\t" - BRANCHLESS_GET_CABAC("%4", "(%1)", "%3", "%w3", - "%5", "%k0", "%b0", - "%a11(%6)", "%a12(%6)") + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%a11(%6)", "%a12(%6)", "%13") "sub %10, %1 \n\t" "mov %2, %0 \n\t" @@ -86,7 +97,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "+&r"(c->low), "=&r"(bit), "+&r"(c->range) : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, bytestream)), - "i"(offsetof(CABACContext, bytestream_end)) + "i"(offsetof(CABACContext, bytestream_end)) RIP_ARG : "%"REG_c, "memory" ); return coeff_count; @@ -100,6 +111,17 @@ static int decode_significance_8x8_x86(CABACContext *c, x86_reg coeff_count; x86_reg last=0; x86_reg state; + +#ifdef BROKEN_RELOCATIONS + int *rip; + + __asm__ volatile( + "1: \n\t" + "lea 1b(%%rip), %0 \n\t" + : "=&r"(rip) + ); +#endif + __asm__ volatile( "mov %1, %6 \n\t" "3: \n\t" @@ -108,20 +130,24 @@ static int decode_significance_8x8_x86(CABACContext *c, "movzbl (%0, %6), %k6 \n\t" "add %9, %6 \n\t" - BRANCHLESS_GET_CABAC("%4", "(%6)", "%3", "%w3", - "%5", "%k0", "%b0", - "%a12(%7)", "%a13(%7)") + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%a12(%7)", "%a13(%7)", "%14") "mov %1, %k6 \n\t" "test $1, %4 \n\t" " jz 4f \n\t" - "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%k6), %k6\n\t" +#ifdef BROKEN_RELOCATIONS + "movzbl last_coeff_flag_offset_8x8-1b(%14, %q6), %k6\n\t" +#else + "movzbl last_coeff_flag_offset_8x8(%k6), %k6\n\t" +#endif "add %11, %6 \n\t" - BRANCHLESS_GET_CABAC("%4", "(%6)", "%3", "%w3", - "%5", "%k0", "%b0", - "%a12(%7)", "%a13(%7)") + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%a12(%7)", "%a13(%7)", "%14") "mov %2, %0 \n\t" "mov %1, %k6 \n\t" @@ -147,7 +173,7 @@ static int decode_significance_8x8_x86(CABACContext *c, : "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_coeff_ctx_base), "i"(offsetof(CABACContext, bytestream)), - "i"(offsetof(CABACContext, bytestream_end)) + "i"(offsetof(CABACContext, bytestream_end)) RIP_ARG : "%"REG_c, "memory" ); return coeff_count; |