1 /* Bra86.c -- Converter for x86 code (BCJ)
2 2008-10-04 : Igor Pavlov : Public domain */
6 #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
8 const Byte kMaskToAllowedStatus
[8] = {1, 1, 1, 0, 1, 0, 0, 0};
9 const Byte kMaskToBitNumber
[8] = {0, 1, 2, 2, 3, 3, 3, 3};
11 SizeT
x86_Convert(Byte
*data
, SizeT size
, UInt32 ip
, UInt32
*state
, int encoding
)
13 SizeT bufferPos
= 0, prevPosT
;
14 UInt32 prevMask
= *state
& 0x7;
18 prevPosT
= (SizeT
)0 - 1;
22 Byte
*p
= data
+ bufferPos
;
23 Byte
*limit
= data
+ size
- 4;
24 for (; p
< limit
; p
++)
25 if ((*p
& 0xFE) == 0xE8)
27 bufferPos
= (SizeT
)(p
- data
);
30 prevPosT
= bufferPos
- prevPosT
;
35 prevMask
= (prevMask
<< ((int)prevPosT
- 1)) & 0x7;
38 Byte b
= p
[4 - kMaskToBitNumber
[prevMask
]];
39 if (!kMaskToAllowedStatus
[prevMask
] || Test86MSByte(b
))
42 prevMask
= ((prevMask
<< 1) & 0x7) | 1;
50 if (Test86MSByte(p
[4]))
52 UInt32 src
= ((UInt32
)p
[4] << 24) | ((UInt32
)p
[3] << 16) | ((UInt32
)p
[2] << 8) | ((UInt32
)p
[1]);
59 dest
= (ip
+ (UInt32
)bufferPos
) + src
;
61 dest
= src
- (ip
+ (UInt32
)bufferPos
);
64 index
= kMaskToBitNumber
[prevMask
] * 8;
65 b
= (Byte
)(dest
>> (24 - index
));
68 src
= dest
^ ((1 << (32 - index
)) - 1);
70 p
[4] = (Byte
)(~(((dest
>> 24) & 1) - 1));
71 p
[3] = (Byte
)(dest
>> 16);
72 p
[2] = (Byte
)(dest
>> 8);
78 prevMask
= ((prevMask
<< 1) & 0x7) | 1;
82 prevPosT
= bufferPos
- prevPosT
;
83 *state
= ((prevPosT
> 3) ? 0 : ((prevMask
<< ((int)prevPosT
- 1)) & 0x7));