]> git.sesse.net Git - x264/blob - common/x86/cabac-a.asm
Faster signed golomb coding
[x264] / common / x86 / cabac-a.asm
1 ;*****************************************************************************
2 ;* cabac-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2008 x264 project
5 ;*
6 ;* Author: Loren Merritt <lorenm@u.washington.edu>
7 ;*         Fiona Glaser <fiona@x264.com>
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
24 %include "x86inc.asm"
25
26 SECTION_RODATA
27
28 SECTION .text
29
30 cextern x264_cabac_range_lps
31 cextern x264_cabac_transition
32 cextern x264_cabac_renorm_shift
33
34 ; t3 must be ecx, since it's used for shift.
35 %ifdef WIN64
36     DECLARE_REG_TMP 3,1,2,0,4,5,6,10
37     %define pointer resq
38 %elifdef ARCH_X86_64
39     DECLARE_REG_TMP 0,1,2,3,4,5,6,10
40     %define pointer resq
41 %else
42     DECLARE_REG_TMP 0,3,2,1,4,5,6,3
43     %define pointer resd
44 %endif
45
46 struc cb
47     .low: resd 1
48     .range: resd 1
49     .queue: resd 1
50     .bytes_outstanding: resd 1
51     .start: pointer 1
52     .p: pointer 1
53     .end: pointer 1
54     align 16, resb 1
55     .bits_encoded: resd 1
56     .state: resb 460
57 endstruc
58
59 %macro LOAD_GLOBAL 4
60 %ifdef PIC
61     ; this would be faster if the arrays were declared in asm, so that I didn't have to duplicate the lea
62     lea   r11, [%2 GLOBAL]
63     %ifnidn %3, 0
64     add   r11, %3
65     %endif
66     movzx %1, byte [r11+%4]
67 %else
68     movzx %1, byte [%2+%3+%4]
69 %endif
70 %endmacro
71
72 cglobal x264_cabac_encode_decision_asm, 0,7
73     movifnidn t0,  r0mp
74     movifnidn t1d, r1m
75     mov   t5d, [t0+cb.range]
76     movzx t3d, byte [t0+cb.state+t1]
77     mov   t4d, t5d
78     shr   t5d, 6
79     LOAD_GLOBAL t5d, x264_cabac_range_lps-4, t5, t3*4
80     sub   t4d, t5d
81     mov   t6d, t3d
82     shr   t6d, 6
83     movifnidn t2d, r2m
84     cmp   t6d, t2d
85     mov   t6d, [t0+cb.low]
86     lea   t7,  [t6+t4]
87     cmovne t4d, t5d
88     cmovne t6d, t7d
89     LOAD_GLOBAL t3d, x264_cabac_transition, t2, t3*2
90     movifnidn t1d, r1m
91     mov   [t0+cb.state+t1], t3b
92 .renorm:
93     mov   t3d, t4d
94     shr   t3d, 3
95     LOAD_GLOBAL t3d, x264_cabac_renorm_shift, 0, t3
96     shl   t4d, t3b
97     shl   t6d, t3b
98     add   t3d, [t0+cb.queue]
99     mov   [t0+cb.range], t4d
100     mov   [t0+cb.low], t6d
101     mov   [t0+cb.queue], t3d
102     cmp   t3d, 8
103     jge .putbyte
104     REP_RET
105 .putbyte:
106     ; alive: t0=cb t3=queue t6=low
107     add   t3d, 2
108     mov   t1d, 1
109     mov   t2d, t6d
110     shl   t1d, t3b
111     shr   t2d, t3b ; out
112     dec   t1d
113     sub   t3d, 10
114     and   t6d, t1d
115     cmp   t2b, 0xff ; FIXME is a 32bit op faster?
116     mov   [t0+cb.queue], t3d
117     mov   [t0+cb.low], t6d
118     mov   t1d, t2d
119     mov   t4,  [t0+cb.p]
120     je .postpone
121     mov   t5d, [t0+cb.bytes_outstanding]
122     shr   t1d, 8 ; carry
123     add   [t4-1], t1b
124     test  t5d, t5d
125     jz .no_outstanding
126     dec   t1d
127 .loop_outstanding:
128     mov   [t4], t1b
129     inc   t4
130     dec   t5d
131     jg .loop_outstanding
132 .no_outstanding:
133     mov   [t4], t2b
134     inc   t4
135     mov   [t0+cb.bytes_outstanding], t5d ; is zero, but a reg has smaller opcode than an immediate
136     mov   [t0+cb.p], t4
137     RET
138 .postpone:
139     inc   dword [t0+cb.bytes_outstanding]
140     RET
141