summaryrefslogtreecommitdiff
path: root/arch/x86/il.cpp
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-06-03 21:25:55 -0700
committerMark Rowe <mark@vector35.com>2026-06-04 17:33:53 -0700
commitcb972a3d4fe468bf1d51af2ce756e99d9e6dbfe4 (patch)
tree4e43ddc523c30817f4e3580825c5763bf6401eed /arch/x86/il.cpp
parent144cd0aa1f13baebac43d5c877dc7cec8e07b389 (diff)
[x86] Emit bswap, popcnt, clz, and ctz instructions during lifting
Diffstat (limited to 'arch/x86/il.cpp')
-rw-r--r--arch/x86/il.cpp80
1 files changed, 13 insertions, 67 deletions
diff --git a/arch/x86/il.cpp b/arch/x86/il.cpp
index 692ee04e..fbc8a6b5 100644
--- a/arch/x86/il.cpp
+++ b/arch/x86/il.cpp
@@ -4870,81 +4870,27 @@ bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLev
il.AddInstruction(il.SetRegister(2, REG_X87_TOP, il.Add(2, il.Register(2, REG_X87_TOP), il.Const(2, 1))));
break;
- case XED_ICLASS_TZCNT:
- {
- if (opOneLen == 8)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_TZCNT_GPR64_GPRMEM64,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
- else if (opOneLen == 4)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_TZCNT_GPR32_GPRMEM32,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
- else
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_TZCNT_GPR16_GPRMEM16,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
+ case XED_ICLASS_BSWAP:
+ // BSWAP reverses the bytes of its single register operand in place. x86 leaves the flags
+ // unaffected, matching the native operation.
+ il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0,
+ il.ByteSwap(opOneLen, ReadILOperand(il, xedd, addr, 0, 0))));
+ break;
+ case XED_ICLASS_TZCNT:
+ il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0,
+ il.CountTrailingZeros(opOneLen, ReadILOperand(il, xedd, addr, 1, 1), IL_FLAGWRITE_LZTZCNT)));
break;
- }
case XED_ICLASS_LZCNT:
- {
- if (opOneLen == 8)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_LZCNT_GPR64_GPRMEM64,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) }
- )
- );
- else if (opOneLen == 4)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_LZCNT_GPR32_GPRMEM32,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
- else
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_LZCNT_GPR16_GPRMEM16,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
-
+ il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0,
+ il.CountLeadingZeros(opOneLen, ReadILOperand(il, xedd, addr, 1, 1), IL_FLAGWRITE_LZTZCNT)));
break;
- }
case XED_ICLASS_POPCNT:
- {
- if (opOneLen == 8)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_POPCNT_GPR64_GPRMEM64,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) }
- )
- );
- else if (opOneLen == 4)
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_POPCNT_GPR32_GPRMEM32,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
- else
- il.AddInstruction(
- il.Intrinsic(
- vector<RegisterOrFlag> { RegisterOrFlag::Register(regOne) },
- INTRINSIC_XED_IFORM_POPCNT_GPR16_GPRMEM16,
- vector<ExprId> { ReadILOperand(il, xedd, addr, 1, 1) } ));
-
+ il.AddInstruction(WriteILOperand(il, xedd, addr, 0, 0,
+ il.PopulationCount(opOneLen, ReadILOperand(il, xedd, addr, 1, 1), IL_FLAGWRITE_POPCNT)));
break;
- }
default:
LiftAsIntrinsic();