mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-25 03:30:53 +00:00
718112a8fe
Currently none of these is being used, but eventually they will, once more code gets ported over. So it's better to have them right away and avoid editing the project file too much, only to revert that later.
82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
/* Bra86.c -- Converter for x86 code (BCJ)
|
|
2017-04-03 : Igor Pavlov : Public domain */
|
|
|
|
#include "Precomp.h"
|
|
|
|
#include "Bra.h"
|
|
|
|
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
|
|
|
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
|
{
|
|
SizeT pos = 0;
|
|
UInt32 mask = *state & 7;
|
|
if (size < 5)
|
|
return 0;
|
|
size -= 4;
|
|
ip += 5;
|
|
|
|
for (;;)
|
|
{
|
|
Byte *p = data + pos;
|
|
const Byte *limit = data + size;
|
|
for (; p < limit; p++)
|
|
if ((*p & 0xFE) == 0xE8)
|
|
break;
|
|
|
|
{
|
|
SizeT d = (SizeT)(p - data - pos);
|
|
pos = (SizeT)(p - data);
|
|
if (p >= limit)
|
|
{
|
|
*state = (d > 2 ? 0 : mask >> (unsigned)d);
|
|
return pos;
|
|
}
|
|
if (d > 2)
|
|
mask = 0;
|
|
else
|
|
{
|
|
mask >>= (unsigned)d;
|
|
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
|
|
{
|
|
mask = (mask >> 1) | 4;
|
|
pos++;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Test86MSByte(p[4]))
|
|
{
|
|
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
|
UInt32 cur = ip + (UInt32)pos;
|
|
pos += 5;
|
|
if (encoding)
|
|
v += cur;
|
|
else
|
|
v -= cur;
|
|
if (mask != 0)
|
|
{
|
|
unsigned sh = (mask & 6) << 2;
|
|
if (Test86MSByte((Byte)(v >> sh)))
|
|
{
|
|
v ^= (((UInt32)0x100 << sh) - 1);
|
|
if (encoding)
|
|
v += cur;
|
|
else
|
|
v -= cur;
|
|
}
|
|
mask = 0;
|
|
}
|
|
p[1] = (Byte)v;
|
|
p[2] = (Byte)(v >> 8);
|
|
p[3] = (Byte)(v >> 16);
|
|
p[4] = (Byte)(0 - ((v >> 24) & 1));
|
|
}
|
|
else
|
|
{
|
|
mask = (mask >> 1) | 4;
|
|
pos++;
|
|
}
|
|
}
|
|
}
|