mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 848773 - Add x86 BCJ filter for szip. r=nfroyd,r=ted
This commit is contained in:
parent
43c6f59e2b
commit
fa35064473
@ -43,3 +43,6 @@ else
|
|||||||
HOST_CXXFLAGS += -DTARGET_ARM
|
HOST_CXXFLAGS += -DTARGET_ARM
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
ifeq (x86,$(CPU_ARCH))
|
||||||
|
HOST_CXXFLAGS += -DTARGET_X86
|
||||||
|
endif
|
||||||
|
@ -170,6 +170,88 @@ BCJ_ARM_filter(off_t offset, SeekableZStream::FilterDirection dir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Branch/Call/Jump conversion filter for x86, derived from xz-utils
|
||||||
|
* by Igor Pavlov and Lasse Collin, published in the public domain */
|
||||||
|
|
||||||
|
#define Test86MSByte(b) ((b) == 0 || (b) == 0xff)
|
||||||
|
|
||||||
|
static void
|
||||||
|
BCJ_X86_filter(off_t offset, SeekableZStream::FilterDirection dir,
|
||||||
|
unsigned char *buf, size_t size)
|
||||||
|
{
|
||||||
|
static const bool MASK_TO_ALLOWED_STATUS[8] =
|
||||||
|
{ true, true, true, false, true, false, false, false };
|
||||||
|
|
||||||
|
static const uint32_t MASK_TO_BIT_NUMBER[8] =
|
||||||
|
{ 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||||
|
|
||||||
|
uint32_t prev_mask = 0;
|
||||||
|
uint32_t prev_pos = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i <= size - 5;) {
|
||||||
|
uint8_t b = buf[i];
|
||||||
|
if (b != 0xe8 && b != 0xe9) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t off = offset + (uint32_t)(i) - prev_pos;
|
||||||
|
prev_pos = offset + (uint32_t)(i);
|
||||||
|
|
||||||
|
if (off > 5) {
|
||||||
|
prev_mask = 0;
|
||||||
|
} else {
|
||||||
|
for (uint32_t i = 0; i < off; ++i) {
|
||||||
|
prev_mask &= 0x77;
|
||||||
|
prev_mask <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b = buf[i + 4];
|
||||||
|
|
||||||
|
if (Test86MSByte(b) && MASK_TO_ALLOWED_STATUS[(prev_mask >> 1) & 0x7]
|
||||||
|
&& (prev_mask >> 1) < 0x10) {
|
||||||
|
|
||||||
|
uint32_t src = ((uint32_t)(b) << 24)
|
||||||
|
| ((uint32_t)(buf[i + 3]) << 16)
|
||||||
|
| ((uint32_t)(buf[i + 2]) << 8)
|
||||||
|
| (buf[i + 1]);
|
||||||
|
|
||||||
|
uint32_t dest;
|
||||||
|
while (true) {
|
||||||
|
if (dir == SeekableZStream::FILTER)
|
||||||
|
dest = src + (offset + (uint32_t)(i) + 5);
|
||||||
|
else
|
||||||
|
dest = src - (offset + (uint32_t)(i) + 5);
|
||||||
|
|
||||||
|
if (prev_mask == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const uint32_t i = MASK_TO_BIT_NUMBER[prev_mask >> 1];
|
||||||
|
|
||||||
|
b = (uint8_t)(dest >> (24 - i * 8));
|
||||||
|
|
||||||
|
if (!Test86MSByte(b))
|
||||||
|
break;
|
||||||
|
|
||||||
|
src = dest ^ ((1 << (32 - i * 8)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[i + 4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
|
||||||
|
buf[i + 3] = (uint8_t)(dest >> 16);
|
||||||
|
buf[i + 2] = (uint8_t)(dest >> 8);
|
||||||
|
buf[i + 1] = (uint8_t)(dest);
|
||||||
|
i += 5;
|
||||||
|
prev_mask = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
prev_mask |= 1;
|
||||||
|
if (Test86MSByte(b))
|
||||||
|
prev_mask |= 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SeekableZStream::ZStreamFilter
|
SeekableZStream::ZStreamFilter
|
||||||
SeekableZStream::GetFilter(SeekableZStream::FilterId id)
|
SeekableZStream::GetFilter(SeekableZStream::FilterId id)
|
||||||
@ -179,6 +261,8 @@ SeekableZStream::GetFilter(SeekableZStream::FilterId id)
|
|||||||
return BCJ_Thumb_filter;
|
return BCJ_Thumb_filter;
|
||||||
case BCJ_ARM:
|
case BCJ_ARM:
|
||||||
return BCJ_ARM_filter;
|
return BCJ_ARM_filter;
|
||||||
|
case BCJ_X86:
|
||||||
|
return BCJ_X86_filter;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,7 @@ public:
|
|||||||
NONE,
|
NONE,
|
||||||
BCJ_THUMB,
|
BCJ_THUMB,
|
||||||
BCJ_ARM,
|
BCJ_ARM,
|
||||||
|
BCJ_X86,
|
||||||
FILTER_MAX
|
FILTER_MAX
|
||||||
};
|
};
|
||||||
static ZStreamFilter GetFilter(FilterId id);
|
static ZStreamFilter GetFilter(FilterId id);
|
||||||
|
@ -144,6 +144,8 @@ private:
|
|||||||
SeekableZStream::BCJ_THUMB;
|
SeekableZStream::BCJ_THUMB;
|
||||||
#elif defined(TARGET_ARM)
|
#elif defined(TARGET_ARM)
|
||||||
SeekableZStream::BCJ_ARM;
|
SeekableZStream::BCJ_ARM;
|
||||||
|
#elif defined(TARGET_X86)
|
||||||
|
SeekableZStream::BCJ_X86;
|
||||||
#else
|
#else
|
||||||
SeekableZStream::NONE;
|
SeekableZStream::NONE;
|
||||||
#endif
|
#endif
|
||||||
@ -352,6 +354,8 @@ int main(int argc, char* argv[])
|
|||||||
filter = SeekableZStream::BCJ_ARM;
|
filter = SeekableZStream::BCJ_ARM;
|
||||||
else if (strcmp(firstArg[0], "thumb") == 0)
|
else if (strcmp(firstArg[0], "thumb") == 0)
|
||||||
filter = SeekableZStream::BCJ_THUMB;
|
filter = SeekableZStream::BCJ_THUMB;
|
||||||
|
else if (strcmp(firstArg[0], "x86") == 0)
|
||||||
|
filter = SeekableZStream::BCJ_X86;
|
||||||
else {
|
else {
|
||||||
log("Invalid filter");
|
log("Invalid filter");
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user