1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
\r
2 2015-08-01 : Igor Pavlov : Public domain */
\r
11 #define kTopValue ((UInt32)1 << 24)
\r
12 #define kNumModelBits 11
\r
13 #define kBitModelTotal (1 << kNumModelBits)
\r
14 #define kNumMoveBits 5
\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
20 void Bcj2Dec_Init(CBcj2Dec *p)
\r
24 p->state = BCJ2_DEC_STATE_OK;
\r
29 for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
\r
30 p->probs[i] = kBitModelTotal >> 1;
\r
33 SRes Bcj2Dec_Decode(CBcj2Dec *p)
\r
37 p->state = BCJ2_DEC_STATE_OK;
\r
38 for (; p->range != 5; p->range++)
\r
40 if (p->range == 1 && p->code != 0)
\r
41 return SZ_ERROR_DATA;
\r
43 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
\r
45 p->state = BCJ2_STREAM_RC;
\r
49 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
\r
52 if (p->code == 0xFFFFFFFF)
\r
53 return SZ_ERROR_DATA;
\r
55 p->range = 0xFFFFFFFF;
\r
57 else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
\r
59 while (p->state <= BCJ2_DEC_STATE_ORIG_3)
\r
61 Byte *dest = p->dest;
\r
62 if (dest == p->destLim)
\r
64 *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
\r
70 if (BCJ2_IS_32BIT_STREAM(p->state))
\r
72 const Byte *cur = p->bufs[p->state];
\r
73 if (cur == p->lims[p->state])
\r
75 p->bufs[p->state] = cur + 4;
\r
83 val = GetBe32(cur) - p->ip;
\r
85 rem = p->destLim - dest;
\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
97 p->temp[3] = (Byte)(val >> 24);
\r
99 p->state = BCJ2_DEC_STATE_OK;
\r
106 if (BCJ2_IS_32BIT_STREAM(p->state))
\r
107 p->state = BCJ2_DEC_STATE_OK;
\r
110 if (p->range < kTopValue)
\r
112 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
\r
114 p->state = BCJ2_STREAM_RC;
\r
118 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
\r
122 const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
\r
123 const Byte *srcLim;
\r
125 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
\r
129 p->state = BCJ2_STREAM_MAIN;
\r
134 if (num > (SizeT)(p->destLim - dest))
\r
136 num = p->destLim - dest;
\r
139 p->state = BCJ2_DEC_STATE_ORIG;
\r
144 srcLim = src + num;
\r
146 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
\r
154 if ((b & 0xFE) == 0xE8)
\r
157 if (++src != srcLim)
\r
162 if (++src == srcLim)
\r
164 if ((*src & 0xF0) != 0x80)
\r
170 num = src - p->bufs[BCJ2_STREAM_MAIN];
\r
174 p->temp[3] = src[-1];
\r
175 p->bufs[BCJ2_STREAM_MAIN] = src;
\r
176 p->ip += (UInt32)num;
\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
190 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
\r
193 p->bufs[BCJ2_STREAM_MAIN] = src + 1;
\r
195 p->ip += (UInt32)num;
\r
198 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
\r
213 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
\r
214 const Byte *cur = p->bufs[cj];
\r
218 if (cur == p->lims[cj])
\r
224 val = GetBe32(cur);
\r
225 p->bufs[cj] = cur + 4;
\r
230 rem = p->destLim - dest;
\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
243 SetUi32(dest, val);
\r
244 p->temp[3] = (Byte)(val >> 24);
\r
245 p->dest = dest + 4;
\r
249 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
\r
252 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
\r