]> git.sesse.net Git - x264/blob - common/x86/cabac-a.asm
Update file headers throughout x264
[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 %macro DEF_TMP 16
35     %rep 8
36         %define t%1d r%9d
37         %define t%1b r%9b
38         %define t%1  r%9
39         %rotate 1
40     %endrep
41 %endmacro
42
43 ; t3 must be ecx, since it's used for shift.
44 %ifdef ARCH_X86_64
45     DEF_TMP 0,1,2,3,4,5,6,7, 0,1,2,3,4,5,6,10
46     %define pointer resq
47 %else
48     DEF_TMP 0,1,2,3,4,5,6,7, 0,3,2,1,4,5,6,3
49     %define pointer resd
50 %endif
51
52 struc cb
53     .low: resd 1
54     .range: resd 1
55     .queue: resd 1
56     .bytes_outstanding: resd 1
57     .start: pointer 1
58     .p: pointer 1
59     .end: pointer 1
60     align 16, resb 1
61     .bits_encoded: resd 1
62     .state: resb 460
63 endstruc
64
65 %macro LOAD_GLOBAL 4
66 %ifdef PIC64
67     ; this would be faster if the arrays were declared in asm, so that I didn't have to duplicate the lea
68     lea   r11, [%2 GLOBAL]
69     %ifnidn %3, 0
70     add   r11, %3
71     %endif
72     movzx %1, byte [r11+%4]
73 %elifdef PIC32
74     %ifnidn %3, 0
75     lea   %1, [%3+%4]
76     movzx %1, byte [%2+%1 GLOBAL]
77     %else
78     movzx %1, byte [%2+%3+%4 GLOBAL]
79     %endif
80 %else
81     movzx %1, byte [%2+%3+%4]
82 %endif
83 %endmacro
84
85 cglobal x264_cabac_encode_decision_asm, 0,7
86     movifnidn t0d, r0m
87     movifnidn t1d, r1m
88     picgetgot t2
89     mov   t5d, [r0+cb.range]
90     movzx t3d, byte [r0+cb.state+t1]
91     mov   t4d, t5d
92     shr   t5d, 6
93     and   t5d, 3
94     LOAD_GLOBAL t5d, x264_cabac_range_lps, t5, t3*4
95     sub   t4d, t5d
96     mov   t6d, t3d
97     shr   t6d, 6
98 %ifdef PIC32
99     cmp   t6d, r2m
100 %else
101     movifnidn t2d, r2m
102     cmp   t6d, t2d
103 %endif
104     mov   t6d, [r0+cb.low]
105     lea   t7,  [t6+t4]
106     cmovne t4d, t5d
107     cmovne t6d, t7d
108 %ifdef PIC32
109     mov   t1,  r2m
110     LOAD_GLOBAL t3d, x264_cabac_transition, t1, t3*2
111 %else
112     LOAD_GLOBAL t3d, x264_cabac_transition, t2, t3*2
113 %endif
114     movifnidn t1d, r1m
115     mov   [r0+cb.state+t1], t3b
116 .renorm:
117     mov   t3d, t4d
118     shr   t3d, 3
119     LOAD_GLOBAL t3d, x264_cabac_renorm_shift, 0, t3
120     shl   t4d, t3b
121     shl   t6d, t3b
122     add   t3d, [r0+cb.queue]
123     mov   [r0+cb.range], t4d
124     mov   [r0+cb.low], t6d
125     mov   [r0+cb.queue], t3d
126     cmp   t3d, 8
127     jge .putbyte
128     REP_RET
129 .putbyte:
130     ; alive: t0=cb t3=queue t6=low
131     add   t3d, 2
132     mov   t1d, 1
133     mov   t2d, t6d
134     shl   t1d, t3b
135     shr   t2d, t3b ; out
136     dec   t1d
137     sub   t3d, 10
138     and   t6d, t1d
139     cmp   t2b, 0xff ; FIXME is a 32bit op faster?
140     mov   [r0+cb.queue], t3d
141     mov   [r0+cb.low], t6d
142     mov   t1d, t2d
143     mov   t4,  [r0+cb.p]
144     je .postpone
145     mov   t5d, [r0+cb.bytes_outstanding]
146     shr   t1d, 8 ; carry
147     add   [t4-1], t1b
148     test  t5d, t5d
149     jz .no_outstanding
150     dec   t1d
151 .loop_outstanding:
152     mov   [t4], t1b
153     inc   t4
154     dec   t5d
155     jg .loop_outstanding
156 .no_outstanding:
157     mov   [t4], t2b
158     inc   t4
159     mov   [r0+cb.bytes_outstanding], t5d ; is zero, but a reg has smaller opcode than an immediate
160     mov   [r0+cb.p], t4
161     RET
162 .postpone:
163     inc   dword [r0+cb.bytes_outstanding]
164     RET
165