-static s32
-lzms_maybe_do_x86_translation(u8 data[restrict], s32 i, s32 num_op_bytes,
- s32 * restrict closest_target_usage_p,
- s32 last_target_usages[restrict],
- s32 max_trans_offset, bool undo)
-{
- u16 pos;
-
- if (undo) {
- if (i - *closest_target_usage_p <= max_trans_offset) {
- LZMS_DEBUG("Undid x86 translation at position %d "
- "(opcode 0x%02x)", i, data[i]);
- void *p32 = &data[i + num_op_bytes];
- u32 n = get_unaligned_u32_le(p32);
- put_unaligned_u32_le(n - i, p32);
- }
- pos = i + get_unaligned_u16_le(&data[i + num_op_bytes]);
- } else {
- pos = i + get_unaligned_u16_le(&data[i + num_op_bytes]);
-
- if (i - *closest_target_usage_p <= max_trans_offset) {
- LZMS_DEBUG("Did x86 translation at position %d "
- "(opcode 0x%02x)", i, data[i]);
- void *p32 = &data[i + num_op_bytes];
- u32 n = get_unaligned_u32_le(p32);
- put_unaligned_u32_le(n + i, p32);
- }
- }
-
- i += num_op_bytes + sizeof(le32) - 1;
-
- if (i - last_target_usages[pos] <= LZMS_X86_MAX_GOOD_TARGET_OFFSET)
- *closest_target_usage_p = i;
-
- last_target_usages[pos] = i;
-
- return i + 1;
-}
-
-static inline s32
-lzms_may_x86_translate(const u8 p[restrict], s32 *restrict max_offset_ret)
-{
- /* Switch on first byte of the opcode, assuming it is really an x86
- * instruction. */
- *max_offset_ret = LZMS_X86_MAX_TRANSLATION_OFFSET;
- switch (p[0]) {
- case 0x48:
- if (p[1] == 0x8b) {
- if (p[2] == 0x5 || p[2] == 0xd) {
- /* Load relative (x86_64) */
- return 3;
- }
- } else if (p[1] == 0x8d) {
- if ((p[2] & 0x7) == 0x5) {
- /* Load effective address relative (x86_64) */
- return 3;
- }
- }
- break;
-
- case 0x4c:
- if (p[1] == 0x8d) {
- if ((p[2] & 0x7) == 0x5) {
- /* Load effective address relative (x86_64) */
- return 3;
- }
- }
- break;
-
- case 0xe8:
- /* Call relative */
- *max_offset_ret = LZMS_X86_MAX_TRANSLATION_OFFSET / 2;
- return 1;
-
- case 0xe9:
- /* Jump relative */
- *max_offset_ret = 0;
- return 5;
-
- case 0xf0:
- if (p[1] == 0x83 && p[2] == 0x05) {
- /* Lock add relative */
- return 3;
- }
- break;
-
- case 0xff:
- if (p[1] == 0x15) {
- /* Call indirect */
- return 2;
- }
- break;
- }
- *max_offset_ret = 0;
- return 1;
-}
-