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