]> git.sesse.net Git - x264/blob - common/x86/cabac-a.asm
Set correct filesystem permissions for various files
[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 ;*         Holger Lubitz <holger@lubitz.org>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION .text
28
29 cextern cabac_range_lps
30 cextern cabac_transition
31 cextern cabac_renorm_shift
32
33 ; t3 must be ecx, since it's used for shift.
34 %ifdef WIN64
35     DECLARE_REG_TMP 3,1,2,0,4,5,6,10,2
36     %define pointer resq
37 %elifdef ARCH_X86_64
38     DECLARE_REG_TMP 0,1,2,3,4,5,6,10,6
39     %define pointer resq
40 %else
41     DECLARE_REG_TMP 0,4,2,1,3,5,6,2,2
42     %define pointer resd
43 %endif
44
45 struc cb
46     .low: resd 1
47     .range: resd 1
48     .queue: resd 1
49     .bytes_outstanding: resd 1
50     .start: pointer 1
51     .p: pointer 1
52     .end: pointer 1
53     align 16, resb 1
54     .bits_encoded: resd 1
55     .state: resb 460
56 endstruc
57
58 %macro LOAD_GLOBAL 4
59 %ifdef PIC
60     ; this would be faster if the arrays were declared in asm, so that I didn't have to duplicate the lea
61     lea   r11, [%2]
62     %ifnidn %3, 0
63     add   r11, %3
64     %endif
65     movzx %1, byte [r11+%4]
66 %else
67     movzx %1, byte [%2+%3+%4]
68 %endif
69 %endmacro
70
71 cglobal cabac_encode_decision_asm, 0,7
72     movifnidn t0,  r0mp
73     movifnidn t1d, r1m
74     mov   t5d, [t0+cb.range]
75     movzx t4d, byte [t0+cb.state+t1]
76     mov   t3d, t5d
77     mov   t6d, t4d
78     shr   t5d, 6
79     shr   t4d, 1
80     movifnidn t2d, r2m
81     LOAD_GLOBAL t5d, cabac_range_lps-4, t5, t4*4
82     LOAD_GLOBAL t4d, cabac_transition, t2, t6*2
83     and   t6d, 1
84     sub   t3d, t5d
85     cmp   t6d, t2d
86     mov   t6d, [t0+cb.low]
87     lea   t7,  [t6+t3]
88     cmovne t3d, t5d
89     cmovne t6d, t7d
90     mov   [t0+cb.state+t1], t4b
91 ;cabac_encode_renorm
92     mov   t4d, t3d
93     shr   t3d, 3
94     LOAD_GLOBAL t3d, cabac_renorm_shift, 0, t3
95     shl   t4d, t3b
96     shl   t6d, t3b
97     add   t3d, [t0+cb.queue]
98     mov   [t0+cb.range], t4d
99     jge cabac_putbyte
100 .update_queue_low:
101     mov   [t0+cb.low], t6d
102     mov   [t0+cb.queue], t3d
103     RET
104
105 cglobal cabac_encode_bypass_asm, 0,3
106     movifnidn  t0, r0mp
107     movifnidn t3d, r1m
108     neg       t3d
109     mov       t8d, [t0+cb.low]
110     and       t3d, [t0+cb.range]
111     lea       t8d, [t8*2+t3]
112     mov       t3d, [t0+cb.queue]
113     inc       t3d
114 %ifdef UNIX64 ; .putbyte compiles to nothing but a jmp
115     jge cabac_putbyte
116 %else
117     jge .putbyte
118 %endif
119     mov   [t0+cb.low], t8d
120     mov   [t0+cb.queue], t3d
121     RET
122 .putbyte:
123     PROLOGUE 0,7
124     movifnidn t6d, t8d
125     jmp cabac_putbyte
126
127 cglobal cabac_encode_terminal_asm, 0,3
128     movifnidn  t0, r0mp
129     sub  dword [t0+cb.range], 2
130 ; shortcut: the renormalization shift in terminal
131 ; can only be 0 or 1 and is zero over 99% of the time.
132     test dword [t0+cb.range], 0x100
133     je .renorm
134     REP_RET
135 .renorm:
136     shl  dword [t0+cb.low], 1
137     shl  dword [t0+cb.range], 1
138     inc  dword [t0+cb.queue]
139     jge .putbyte
140     REP_RET
141 .putbyte:
142     PROLOGUE 0,7
143     mov t3d, [t0+cb.queue]
144     mov t6d, [t0+cb.low]
145     jmp cabac_putbyte
146
147 cabac_putbyte:
148     ; alive: t0=cb t3=queue t6=low
149 %ifdef WIN64
150     DECLARE_REG_TMP 3,4,1,0,2,5,6,10
151 %endif
152     mov   t1d, -1
153     add   t3d, 10
154     mov   t2d, t6d
155     shl   t1d, t3b
156     shr   t2d, t3b ; out
157     not   t1d
158     sub   t3d, 18
159     and   t6d, t1d
160     mov   t5d, [t0+cb.bytes_outstanding]
161     cmp   t2b, 0xff ; FIXME is a 32bit op faster?
162     jz    .postpone
163     mov   t1,  [t0+cb.p]
164     add   [t1-1], dh ; t2h
165     dec   dh
166 .loop_outstanding:
167     mov   [t1], dh
168     inc   t1
169     dec   t5d
170     jge .loop_outstanding
171     mov   [t1-1], t2b
172     mov   [t0+cb.p], t1
173 .postpone:
174     inc   t5d
175     mov   [t0+cb.bytes_outstanding], t5d
176     jmp mangle(x264_cabac_encode_decision_asm.update_queue_low)