1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2 2018-04-28 : Igor Pavlov : Public domain */
11 #define kTopValue ((UInt32)1 << 24)
12 #define kNumModelBits 11
13 #define kBitModelTotal (1 << kNumModelBits)
14 #define kNumMoveBits 5
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));
20 void Bcj2Dec_Init(CBcj2Dec
*p
)
24 p
->state
= BCJ2_DEC_STATE_OK
;
29 for (i
= 0; i
< sizeof(p
->probs
) / sizeof(p
->probs
[0]); i
++)
30 p
->probs
[i
] = kBitModelTotal
>> 1;
33 SRes
Bcj2Dec_Decode(CBcj2Dec
*p
)
37 p
->state
= BCJ2_DEC_STATE_OK
;
38 for (; p
->range
!= 5; p
->range
++)
40 if (p
->range
== 1 && p
->code
!= 0)
43 if (p
->bufs
[BCJ2_STREAM_RC
] == p
->lims
[BCJ2_STREAM_RC
])
45 p
->state
= BCJ2_STREAM_RC
;
49 p
->code
= (p
->code
<< 8) | *(p
->bufs
[BCJ2_STREAM_RC
])++;
52 if (p
->code
== 0xFFFFFFFF)
55 p
->range
= 0xFFFFFFFF;
57 else if (p
->state
>= BCJ2_DEC_STATE_ORIG_0
)
59 while (p
->state
<= BCJ2_DEC_STATE_ORIG_3
)
62 if (dest
== p
->destLim
)
64 *dest
= p
->temp
[(size_t)p
->state
- BCJ2_DEC_STATE_ORIG_0
];
71 if (BCJ2_IS_32BIT_STREAM(p->state))
73 const Byte *cur = p->bufs[p->state];
74 if (cur == p->lims[p->state])
76 p->bufs[p->state] = cur + 4;
84 val = GetBe32(cur) - p->ip;
86 rem = p->destLim - dest;
90 SetUi32(p->temp, val);
91 for (i = 0; i < rem; i++)
94 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
98 p->temp[3] = (Byte)(val >> 24);
100 p->state = BCJ2_DEC_STATE_OK;
107 if (BCJ2_IS_32BIT_STREAM(p
->state
))
108 p
->state
= BCJ2_DEC_STATE_OK
;
111 if (p
->range
< kTopValue
)
113 if (p
->bufs
[BCJ2_STREAM_RC
] == p
->lims
[BCJ2_STREAM_RC
])
115 p
->state
= BCJ2_STREAM_RC
;
119 p
->code
= (p
->code
<< 8) | *(p
->bufs
[BCJ2_STREAM_RC
])++;
123 const Byte
*src
= p
->bufs
[BCJ2_STREAM_MAIN
];
126 SizeT num
= p
->lims
[BCJ2_STREAM_MAIN
] - src
;
130 p
->state
= BCJ2_STREAM_MAIN
;
135 if (num
> (SizeT
)(p
->destLim
- dest
))
137 num
= p
->destLim
- dest
;
140 p
->state
= BCJ2_DEC_STATE_ORIG
;
147 if (p
->temp
[3] == 0x0F && (src
[0] & 0xF0) == 0x80)
155 if ((b
& 0xFE) == 0xE8)
165 if ((*src
& 0xF0) != 0x80)
171 num
= src
- p
->bufs
[BCJ2_STREAM_MAIN
];
175 p
->temp
[3] = src
[-1];
176 p
->bufs
[BCJ2_STREAM_MAIN
] = src
;
177 p
->ip
+= (UInt32
)num
;
180 p
->bufs
[BCJ2_STREAM_MAIN
] ==
181 p
->lims
[BCJ2_STREAM_MAIN
] ?
182 (unsigned)BCJ2_STREAM_MAIN
:
183 (unsigned)BCJ2_DEC_STATE_ORIG
;
191 Byte prev
= (Byte
)(num
== 0 ? p
->temp
[3] : src
[-1]);
194 p
->bufs
[BCJ2_STREAM_MAIN
] = src
+ 1;
196 p
->ip
+= (UInt32
)num
;
199 prob
= p
->probs
+ (unsigned)(b
== 0xE8 ? 2 + (unsigned)prev
: (b
== 0xE9 ? 1 : 0));
214 unsigned cj
= (p
->temp
[3] == 0xE8) ? BCJ2_STREAM_CALL
: BCJ2_STREAM_JUMP
;
215 const Byte
*cur
= p
->bufs
[cj
];
219 if (cur
== p
->lims
[cj
])
226 p
->bufs
[cj
] = cur
+ 4;
231 rem
= p
->destLim
- dest
;
235 p
->temp
[0] = (Byte
)val
; if (rem
> 0) dest
[0] = (Byte
)val
; val
>>= 8;
236 p
->temp
[1] = (Byte
)val
; if (rem
> 1) dest
[1] = (Byte
)val
; val
>>= 8;
237 p
->temp
[2] = (Byte
)val
; if (rem
> 2) dest
[2] = (Byte
)val
; val
>>= 8;
238 p
->temp
[3] = (Byte
)val
;
239 p
->dest
= dest
+ rem
;
240 p
->state
= BCJ2_DEC_STATE_ORIG_0
+ (unsigned)rem
;
245 p
->temp
[3] = (Byte
)(val
>> 24);
250 if (p
->range
< kTopValue
&& p
->bufs
[BCJ2_STREAM_RC
] != p
->lims
[BCJ2_STREAM_RC
])
253 p
->code
= (p
->code
<< 8) | *(p
->bufs
[BCJ2_STREAM_RC
])++;