diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /C/Bra86.c | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.tar.gz 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.tar.bz2 7zip-f19f813537c7aea1c20749c914e756b54a9c3cf5.zip |
'21.07'21.07
Diffstat (limited to 'C/Bra86.c')
-rw-r--r-- | C/Bra86.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/C/Bra86.c b/C/Bra86.c new file mode 100644 index 0000000..10a0fbd --- /dev/null +++ b/C/Bra86.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* Bra86.c -- Converter for x86 code (BCJ) | ||
2 | 2021-02-09 : Igor Pavlov : Public domain */ | ||
3 | |||
4 | #include "Precomp.h" | ||
5 | |||
6 | #include "Bra.h" | ||
7 | |||
8 | #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) | ||
9 | |||
10 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) | ||
11 | { | ||
12 | SizeT pos = 0; | ||
13 | UInt32 mask = *state & 7; | ||
14 | if (size < 5) | ||
15 | return 0; | ||
16 | size -= 4; | ||
17 | ip += 5; | ||
18 | |||
19 | for (;;) | ||
20 | { | ||
21 | Byte *p = data + pos; | ||
22 | const Byte *limit = data + size; | ||
23 | for (; p < limit; p++) | ||
24 | if ((*p & 0xFE) == 0xE8) | ||
25 | break; | ||
26 | |||
27 | { | ||
28 | SizeT d = (SizeT)(p - data) - pos; | ||
29 | pos = (SizeT)(p - data); | ||
30 | if (p >= limit) | ||
31 | { | ||
32 | *state = (d > 2 ? 0 : mask >> (unsigned)d); | ||
33 | return pos; | ||
34 | } | ||
35 | if (d > 2) | ||
36 | mask = 0; | ||
37 | else | ||
38 | { | ||
39 | mask >>= (unsigned)d; | ||
40 | if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) | ||
41 | { | ||
42 | mask = (mask >> 1) | 4; | ||
43 | pos++; | ||
44 | continue; | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | if (Test86MSByte(p[4])) | ||
50 | { | ||
51 | UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); | ||
52 | UInt32 cur = ip + (UInt32)pos; | ||
53 | pos += 5; | ||
54 | if (encoding) | ||
55 | v += cur; | ||
56 | else | ||
57 | v -= cur; | ||
58 | if (mask != 0) | ||
59 | { | ||
60 | unsigned sh = (mask & 6) << 2; | ||
61 | if (Test86MSByte((Byte)(v >> sh))) | ||
62 | { | ||
63 | v ^= (((UInt32)0x100 << sh) - 1); | ||
64 | if (encoding) | ||
65 | v += cur; | ||
66 | else | ||
67 | v -= cur; | ||
68 | } | ||
69 | mask = 0; | ||
70 | } | ||
71 | p[1] = (Byte)v; | ||
72 | p[2] = (Byte)(v >> 8); | ||
73 | p[3] = (Byte)(v >> 16); | ||
74 | p[4] = (Byte)(0 - ((v >> 24) & 1)); | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | mask = (mask >> 1) | 4; | ||
79 | pos++; | ||
80 | } | ||
81 | } | ||
82 | } | ||