source: josm/trunk/src/org/tukaani/xz/simple/X86.java@ 13431

Last change on this file since 13431 was 13350, checked in by stoecker, 7 years ago

see #15816 - add XZ support

File size: 2.9 KB
Line 
1/*
2 * BCJ filter for x86 instructions
3 *
4 * Authors: Lasse Collin <lasse.collin@tukaani.org>
5 * Igor Pavlov <http://7-zip.org/>
6 *
7 * This file has been put into the public domain.
8 * You can do whatever you want with this file.
9 */
10
11package org.tukaani.xz.simple;
12
13public final class X86 implements SimpleFilter {
14 private static final boolean[] MASK_TO_ALLOWED_STATUS
15 = {true, true, true, false, true, false, false, false};
16
17 private static final int[] MASK_TO_BIT_NUMBER = {0, 1, 2, 2, 3, 3, 3, 3};
18
19 private final boolean isEncoder;
20 private int pos;
21 private int prevMask = 0;
22
23 private static boolean test86MSByte(byte b) {
24 int i = b & 0xFF;
25 return i == 0x00 || i == 0xFF;
26 }
27
28 public X86(boolean isEncoder, int startPos) {
29 this.isEncoder = isEncoder;
30 pos = startPos + 5;
31 }
32
33 public int code(byte[] buf, int off, int len) {
34 int prevPos = off - 1;
35 int end = off + len - 5;
36 int i;
37
38 for (i = off; i <= end; ++i) {
39 if ((buf[i] & 0xFE) != 0xE8)
40 continue;
41
42 prevPos = i - prevPos;
43 if ((prevPos & ~3) != 0) { // (unsigned)prevPos > 3
44 prevMask = 0;
45 } else {
46 prevMask = (prevMask << (prevPos - 1)) & 7;
47 if (prevMask != 0) {
48 if (!MASK_TO_ALLOWED_STATUS[prevMask] || test86MSByte(
49 buf[i + 4 - MASK_TO_BIT_NUMBER[prevMask]])) {
50 prevPos = i;
51 prevMask = (prevMask << 1) | 1;
52 continue;
53 }
54 }
55 }
56
57 prevPos = i;
58
59 if (test86MSByte(buf[i + 4])) {
60 int src = (buf[i + 1] & 0xFF)
61 | ((buf[i + 2] & 0xFF) << 8)
62 | ((buf[i + 3] & 0xFF) << 16)
63 | ((buf[i + 4] & 0xFF) << 24);
64 int dest;
65 while (true) {
66 if (isEncoder)
67 dest = src + (pos + i - off);
68 else
69 dest = src - (pos + i - off);
70
71 if (prevMask == 0)
72 break;
73
74 int index = MASK_TO_BIT_NUMBER[prevMask] * 8;
75 if (!test86MSByte((byte)(dest >>> (24 - index))))
76 break;
77
78 src = dest ^ ((1 << (32 - index)) - 1);
79 }
80
81 buf[i + 1] = (byte)dest;
82 buf[i + 2] = (byte)(dest >>> 8);
83 buf[i + 3] = (byte)(dest >>> 16);
84 buf[i + 4] = (byte)(~(((dest >>> 24) & 1) - 1));
85 i += 4;
86 } else {
87 prevMask = (prevMask << 1) | 1;
88 }
89 }
90
91 prevPos = i - prevPos;
92 prevMask = ((prevPos & ~3) != 0) ? 0 : prevMask << (prevPos - 1);
93
94 i -= off;
95 pos += i;
96 return i;
97 }
98}
Note: See TracBrowser for help on using the repository browser.