| /* Bra.c -- Converters for RISC code |
| 2017-04-04 : Igor Pavlov : Public domain */ |
| |
| #include "Precomp.h" |
| |
| #include "CpuArch.h" |
| #include "Bra.h" |
| |
| SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
| { |
| Byte *p; |
| const Byte *lim; |
| size &= ~(size_t)3; |
| ip += 4; |
| p = data; |
| lim = data + size; |
| |
| if (encoding) |
| |
| for (;;) |
| { |
| for (;;) |
| { |
| if (p >= lim) |
| return p - data; |
| p += 4; |
| if (p[-1] == 0xEB) |
| break; |
| } |
| { |
| UInt32 v = GetUi32(p - 4); |
| v <<= 2; |
| v += ip + (UInt32)(p - data); |
| v >>= 2; |
| v &= 0x00FFFFFF; |
| v |= 0xEB000000; |
| SetUi32(p - 4, v); |
| } |
| } |
| |
| for (;;) |
| { |
| for (;;) |
| { |
| if (p >= lim) |
| return p - data; |
| p += 4; |
| if (p[-1] == 0xEB) |
| break; |
| } |
| { |
| UInt32 v = GetUi32(p - 4); |
| v <<= 2; |
| v -= ip + (UInt32)(p - data); |
| v >>= 2; |
| v &= 0x00FFFFFF; |
| v |= 0xEB000000; |
| SetUi32(p - 4, v); |
| } |
| } |
| } |
| |
| |
| SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
| { |
| Byte *p; |
| const Byte *lim; |
| size &= ~(size_t)1; |
| p = data; |
| lim = data + size - 4; |
| |
| if (encoding) |
| |
| for (;;) |
| { |
| UInt32 b1; |
| for (;;) |
| { |
| UInt32 b3; |
| if (p > lim) |
| return p - data; |
| b1 = p[1]; |
| b3 = p[3]; |
| p += 2; |
| b1 ^= 8; |
| if ((b3 & b1) >= 0xF8) |
| break; |
| } |
| { |
| UInt32 v = |
| ((UInt32)b1 << 19) |
| + (((UInt32)p[1] & 0x7) << 8) |
| + (((UInt32)p[-2] << 11)) |
| + (p[0]); |
| |
| p += 2; |
| { |
| UInt32 cur = (ip + (UInt32)(p - data)) >> 1; |
| v += cur; |
| } |
| |
| p[-4] = (Byte)(v >> 11); |
| p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); |
| p[-2] = (Byte)v; |
| p[-1] = (Byte)(0xF8 | (v >> 8)); |
| } |
| } |
| |
| for (;;) |
| { |
| UInt32 b1; |
| for (;;) |
| { |
| UInt32 b3; |
| if (p > lim) |
| return p - data; |
| b1 = p[1]; |
| b3 = p[3]; |
| p += 2; |
| b1 ^= 8; |
| if ((b3 & b1) >= 0xF8) |
| break; |
| } |
| { |
| UInt32 v = |
| ((UInt32)b1 << 19) |
| + (((UInt32)p[1] & 0x7) << 8) |
| + (((UInt32)p[-2] << 11)) |
| + (p[0]); |
| |
| p += 2; |
| { |
| UInt32 cur = (ip + (UInt32)(p - data)) >> 1; |
| v -= cur; |
| } |
| |
| /* |
| SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); |
| SetUi16(p - 2, (UInt16)(v | 0xF800)); |
| */ |
| |
| p[-4] = (Byte)(v >> 11); |
| p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); |
| p[-2] = (Byte)v; |
| p[-1] = (Byte)(0xF8 | (v >> 8)); |
| } |
| } |
| } |
| |
| |
| SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
| { |
| Byte *p; |
| const Byte *lim; |
| size &= ~(size_t)3; |
| ip -= 4; |
| p = data; |
| lim = data + size; |
| |
| for (;;) |
| { |
| for (;;) |
| { |
| if (p >= lim) |
| return p - data; |
| p += 4; |
| /* if ((v & 0xFC000003) == 0x48000001) */ |
| if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) |
| break; |
| } |
| { |
| UInt32 v = GetBe32(p - 4); |
| if (encoding) |
| v += ip + (UInt32)(p - data); |
| else |
| v -= ip + (UInt32)(p - data); |
| v &= 0x03FFFFFF; |
| v |= 0x48000000; |
| SetBe32(p - 4, v); |
| } |
| } |
| } |
| |
| |
| SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) |
| { |
| Byte *p; |
| const Byte *lim; |
| size &= ~(size_t)3; |
| ip -= 4; |
| p = data; |
| lim = data + size; |
| |
| for (;;) |
| { |
| for (;;) |
| { |
| if (p >= lim) |
| return p - data; |
| /* |
| v = GetBe32(p); |
| p += 4; |
| m = v + ((UInt32)5 << 29); |
| m ^= (UInt32)7 << 29; |
| m += (UInt32)1 << 22; |
| if ((m & ((UInt32)0x1FF << 23)) == 0) |
| break; |
| */ |
| p += 4; |
| if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || |
| (p[-4] == 0x7F && (p[-3] >= 0xC0))) |
| break; |
| } |
| { |
| UInt32 v = GetBe32(p - 4); |
| v <<= 2; |
| if (encoding) |
| v += ip + (UInt32)(p - data); |
| else |
| v -= ip + (UInt32)(p - data); |
| |
| v &= 0x01FFFFFF; |
| v -= (UInt32)1 << 24; |
| v ^= 0xFF000000; |
| v >>= 2; |
| v |= 0x40000000; |
| SetBe32(p - 4, v); |
| } |
| } |
| } |