Rev 5728 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5728 | serge | 1 | /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) |
2 | 2015-08-01 : Igor Pavlov : Public domain */ |
||
3 | |||
4 | #include "Precomp.h" |
||
5 | |||
6 | #include "Bcj2.h" |
||
7 | #include "CpuArch.h" |
||
8 | |||
9 | #define CProb UInt16 |
||
10 | |||
11 | #define kTopValue ((UInt32)1 << 24) |
||
12 | #define kNumModelBits 11 |
||
13 | #define kBitModelTotal (1 << kNumModelBits) |
||
14 | #define kNumMoveBits 5 |
||
15 | |||
16 | #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) |
||
17 | #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
||
18 | #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); |
||
19 | |||
20 | void Bcj2Dec_Init(CBcj2Dec *p) |
||
21 | { |
||
22 | unsigned i; |
||
23 | |||
24 | p->state = BCJ2_DEC_STATE_OK; |
||
25 | p->ip = 0; |
||
26 | p->temp[3] = 0; |
||
27 | p->range = 0; |
||
28 | p->code = 0; |
||
29 | for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) |
||
30 | p->probs[i] = kBitModelTotal >> 1; |
||
31 | } |
||
32 | |||
33 | SRes Bcj2Dec_Decode(CBcj2Dec *p) |
||
34 | { |
||
35 | if (p->range <= 5) |
||
36 | { |
||
37 | p->state = BCJ2_DEC_STATE_OK; |
||
38 | for (; p->range != 5; p->range++) |
||
39 | { |
||
40 | if (p->range == 1 && p->code != 0) |
||
41 | return SZ_ERROR_DATA; |
||
5809 | serge | 42 | |
5728 | serge | 43 | if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
44 | { |
||
45 | p->state = BCJ2_STREAM_RC; |
||
46 | return SZ_OK; |
||
47 | } |
||
48 | |||
49 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
||
50 | } |
||
51 | |||
52 | if (p->code == 0xFFFFFFFF) |
||
53 | return SZ_ERROR_DATA; |
||
54 | |||
55 | p->range = 0xFFFFFFFF; |
||
56 | } |
||
57 | else if (p->state >= BCJ2_DEC_STATE_ORIG_0) |
||
58 | { |
||
59 | while (p->state <= BCJ2_DEC_STATE_ORIG_3) |
||
60 | { |
||
61 | Byte *dest = p->dest; |
||
62 | if (dest == p->destLim) |
||
63 | return SZ_OK; |
||
64 | *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; |
||
65 | p->dest = dest + 1; |
||
66 | } |
||
67 | } |
||
68 | |||
69 | /* |
||
70 | if (BCJ2_IS_32BIT_STREAM(p->state)) |
||
71 | { |
||
72 | const Byte *cur = p->bufs[p->state]; |
||
73 | if (cur == p->lims[p->state]) |
||
5809 | serge | 74 | return SZ_OK; |
5728 | serge | 75 | p->bufs[p->state] = cur + 4; |
76 | |||
77 | { |
||
78 | UInt32 val; |
||
79 | Byte *dest; |
||
80 | SizeT rem; |
||
81 | |||
82 | p->ip += 4; |
||
83 | val = GetBe32(cur) - p->ip; |
||
84 | dest = p->dest; |
||
85 | rem = p->destLim - dest; |
||
86 | if (rem < 4) |
||
87 | { |
||
88 | SizeT i; |
||
89 | SetUi32(p->temp, val); |
||
90 | for (i = 0; i < rem; i++) |
||
91 | dest[i] = p->temp[i]; |
||
92 | p->dest = dest + rem; |
||
93 | p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; |
||
94 | return SZ_OK; |
||
95 | } |
||
96 | SetUi32(dest, val); |
||
97 | p->temp[3] = (Byte)(val >> 24); |
||
98 | p->dest = dest + 4; |
||
99 | p->state = BCJ2_DEC_STATE_OK; |
||
100 | } |
||
101 | } |
||
102 | */ |
||
103 | |||
104 | for (;;) |
||
105 | { |
||
106 | if (BCJ2_IS_32BIT_STREAM(p->state)) |
||
107 | p->state = BCJ2_DEC_STATE_OK; |
||
108 | else |
||
109 | { |
||
110 | if (p->range < kTopValue) |
||
111 | { |
||
112 | if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
||
113 | { |
||
114 | p->state = BCJ2_STREAM_RC; |
||
115 | return SZ_OK; |
||
116 | } |
||
117 | p->range <<= 8; |
||
118 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
||
119 | } |
||
120 | |||
121 | { |
||
122 | const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; |
||
123 | const Byte *srcLim; |
||
124 | Byte *dest; |
||
125 | SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; |
||
126 | |||
127 | if (num == 0) |
||
128 | { |
||
129 | p->state = BCJ2_STREAM_MAIN; |
||
130 | return SZ_OK; |
||
131 | } |
||
132 | |||
133 | dest = p->dest; |
||
134 | if (num > (SizeT)(p->destLim - dest)) |
||
135 | { |
||
136 | num = p->destLim - dest; |
||
137 | if (num == 0) |
||
138 | { |
||
139 | p->state = BCJ2_DEC_STATE_ORIG; |
||
140 | return SZ_OK; |
||
141 | } |
||
142 | } |
||
143 | |||
144 | srcLim = src + num; |
||
145 | |||
146 | if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) |
||
147 | *dest = src[0]; |
||
148 | else for (;;) |
||
149 | { |
||
150 | Byte b = *src; |
||
151 | *dest = b; |
||
152 | if (b != 0x0F) |
||
5809 | serge | 153 | { |
5728 | serge | 154 | if ((b & 0xFE) == 0xE8) |
5809 | serge | 155 | break; |
5728 | serge | 156 | dest++; |
157 | if (++src != srcLim) |
||
158 | continue; |
||
159 | break; |
||
160 | } |
||
161 | dest++; |
||
162 | if (++src == srcLim) |
||
163 | break; |
||
164 | if ((*src & 0xF0) != 0x80) |
||
165 | continue; |
||
166 | *dest = *src; |
||
167 | break; |
||
168 | } |
||
169 | |||
170 | num = src - p->bufs[BCJ2_STREAM_MAIN]; |
||
171 | |||
172 | if (src == srcLim) |
||
173 | { |
||
174 | p->temp[3] = src[-1]; |
||
175 | p->bufs[BCJ2_STREAM_MAIN] = src; |
||
176 | p->ip += (UInt32)num; |
||
177 | p->dest += num; |
||
178 | p->state = |
||
179 | p->bufs[BCJ2_STREAM_MAIN] == |
||
180 | p->lims[BCJ2_STREAM_MAIN] ? |
||
181 | (unsigned)BCJ2_STREAM_MAIN : |
||
182 | (unsigned)BCJ2_DEC_STATE_ORIG; |
||
183 | return SZ_OK; |
||
5809 | serge | 184 | } |
185 | |||
5728 | serge | 186 | { |
187 | UInt32 bound, ttt; |
||
188 | CProb *prob; |
||
189 | Byte b = src[0]; |
||
190 | Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); |
||
191 | |||
192 | p->temp[3] = b; |
||
193 | p->bufs[BCJ2_STREAM_MAIN] = src + 1; |
||
194 | num++; |
||
195 | p->ip += (UInt32)num; |
||
196 | p->dest += num; |
||
5809 | serge | 197 | |
5728 | serge | 198 | prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); |
5809 | serge | 199 | |
5728 | serge | 200 | _IF_BIT_0 |
201 | { |
||
202 | _UPDATE_0 |
||
203 | continue; |
||
204 | } |
||
205 | _UPDATE_1 |
||
5809 | serge | 206 | |
207 | } |
||
5728 | serge | 208 | } |
209 | } |
||
210 | |||
211 | { |
||
212 | UInt32 val; |
||
213 | unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; |
||
214 | const Byte *cur = p->bufs[cj]; |
||
215 | Byte *dest; |
||
216 | SizeT rem; |
||
217 | |||
218 | if (cur == p->lims[cj]) |
||
219 | { |
||
220 | p->state = cj; |
||
221 | break; |
||
222 | } |
||
223 | |||
224 | val = GetBe32(cur); |
||
225 | p->bufs[cj] = cur + 4; |
||
226 | |||
227 | p->ip += 4; |
||
228 | val -= p->ip; |
||
229 | dest = p->dest; |
||
230 | rem = p->destLim - dest; |
||
231 | |||
232 | if (rem < 4) |
||
233 | { |
||
234 | SizeT i; |
||
235 | SetUi32(p->temp, val); |
||
236 | for (i = 0; i < rem; i++) |
||
237 | dest[i] = p->temp[i]; |
||
238 | p->dest = dest + rem; |
||
239 | p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; |
||
240 | break; |
||
241 | } |
||
242 | |||
243 | SetUi32(dest, val); |
||
244 | p->temp[3] = (Byte)(val >> 24); |
||
245 | p->dest = dest + 4; |
||
5809 | serge | 246 | } |
5728 | serge | 247 | } |
248 | |||
249 | if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) |
||
250 | { |
||
251 | p->range <<= 8; |
||
252 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
||
253 | } |
||
254 | |||
255 | return SZ_OK; |
||
256 | }><>=><=>>>>><>=><=>>>>=>><>=>>>><>><> |