]>
Commit | Line | Data |
---|---|---|
11ff2c71 | 1 | /* Bra86.c -- Converter for x86 code (BCJ)\r |
f0737de8 | 2 | 2017-04-03 : Igor Pavlov : Public domain */\r |
11ff2c71 | 3 | \r |
1e230224 | 4 | #include "Precomp.h"\r |
11ff2c71 | 5 | \r |
1e230224 | 6 | #include "Bra.h"\r |
11ff2c71 | 7 | \r |
1436aea4 | 8 | #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)\r |
11ff2c71 | 9 | \r |
1436aea4 MK |
10 | SizeT\r |
11 | x86_Convert (\r | |
12 | Byte *data,\r | |
13 | SizeT size,\r | |
14 | UInt32 ip,\r | |
15 | UInt32 *state,\r | |
16 | int encoding\r | |
17 | )\r | |
11ff2c71 | 18 | {\r |
1436aea4 MK |
19 | SizeT pos = 0;\r |
20 | UInt32 mask = *state & 7;\r | |
21 | \r | |
22 | if (size < 5) {\r | |
11ff2c71 | 23 | return 0;\r |
1436aea4 MK |
24 | }\r |
25 | \r | |
1e230224 | 26 | size -= 4;\r |
1436aea4 | 27 | ip += 5;\r |
11ff2c71 | 28 | \r |
1436aea4 MK |
29 | for ( ; ;) {\r |
30 | Byte *p = data + pos;\r | |
31 | const Byte *limit = data + size;\r | |
32 | for ( ; p < limit; p++) {\r | |
33 | if ((*p & 0xFE) == 0xE8) {\r | |
11ff2c71 | 34 | break;\r |
1436aea4 MK |
35 | }\r |
36 | }\r | |
1e230224 | 37 | \r |
11ff2c71 | 38 | {\r |
1436aea4 | 39 | SizeT d = (SizeT)(p - data - pos);\r |
1e230224 | 40 | pos = (SizeT)(p - data);\r |
1436aea4 | 41 | if (p >= limit) {\r |
1e230224 LG |
42 | *state = (d > 2 ? 0 : mask >> (unsigned)d);\r |
43 | return pos;\r | |
44 | }\r | |
1436aea4 MK |
45 | \r |
46 | if (d > 2) {\r | |
1e230224 | 47 | mask = 0;\r |
1436aea4 | 48 | } else {\r |
1e230224 | 49 | mask >>= (unsigned)d;\r |
1436aea4 | 50 | if ((mask != 0) && ((mask > 4) || (mask == 3) || Test86MSByte (p[(size_t)(mask >> 1) + 1]))) {\r |
1e230224 LG |
51 | mask = (mask >> 1) | 4;\r |
52 | pos++;\r | |
11ff2c71 LG |
53 | continue;\r |
54 | }\r | |
55 | }\r | |
56 | }\r | |
11ff2c71 | 57 | \r |
1436aea4 MK |
58 | if (Test86MSByte (p[4])) {\r |
59 | UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);\r | |
60 | UInt32 cur = ip + (UInt32)pos;\r | |
1e230224 | 61 | pos += 5;\r |
1436aea4 | 62 | if (encoding) {\r |
1e230224 | 63 | v += cur;\r |
1436aea4 | 64 | } else {\r |
1e230224 | 65 | v -= cur;\r |
1436aea4 MK |
66 | }\r |
67 | \r | |
68 | if (mask != 0) {\r | |
69 | unsigned sh = (mask & 6) << 2;\r | |
70 | if (Test86MSByte ((Byte)(v >> sh))) {\r | |
1e230224 | 71 | v ^= (((UInt32)0x100 << sh) - 1);\r |
1436aea4 | 72 | if (encoding) {\r |
1e230224 | 73 | v += cur;\r |
1436aea4 | 74 | } else {\r |
1e230224 | 75 | v -= cur;\r |
1436aea4 | 76 | }\r |
1e230224 | 77 | }\r |
1436aea4 | 78 | \r |
1e230224 | 79 | mask = 0;\r |
11ff2c71 | 80 | }\r |
1436aea4 | 81 | \r |
1e230224 LG |
82 | p[1] = (Byte)v;\r |
83 | p[2] = (Byte)(v >> 8);\r | |
84 | p[3] = (Byte)(v >> 16);\r | |
85 | p[4] = (Byte)(0 - ((v >> 24) & 1));\r | |
1436aea4 | 86 | } else {\r |
1e230224 LG |
87 | mask = (mask >> 1) | 4;\r |
88 | pos++;\r | |
11ff2c71 LG |
89 | }\r |
90 | }\r | |
11ff2c71 | 91 | }\r |