Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
357 changes: 179 additions & 178 deletions lifter/Semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1374,186 +1374,171 @@ namespace arithmeticsAndLogical {
FI;
*/

void lift_rcl(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {
LLVMContext& context = builder.getContext();
auto dest = instruction.operands[0];
auto count = instruction.operands[1];

auto Lvalue = GetOperandValue(builder, dest, dest.size);
auto countValue = GetOperandValue(builder, count, dest.size);
auto carryFlag = getFlag(builder, FLAG_CF);

unsigned long bitWidth = Lvalue->getType()->getIntegerBitWidth();
unsigned maskC = bitWidth == 64 ? 0x3f : 0x1f;

auto actualCount = createAndFolder(
builder, countValue, ConstantInt::get(countValue->getType(), maskC),
"actualCount");

auto wideType = Type::getIntNTy(context, dest.size * 2);
auto wideLvalue = createZExtFolder(builder, Lvalue, wideType);
auto cf_extended = createZExtFolder(builder, carryFlag, wideType);
auto shiftedInCF =
createShlFolder(builder, cf_extended, dest.size, "shiftedincf");
wideLvalue = createOrFolder(builder, wideLvalue,
createZExtFolder(builder, shiftedInCF, wideType,
"shiftedInCFExtended"));

auto leftShifted = createShlFolder(
builder, wideLvalue,
createZExtFolder(builder, actualCount, wideType, "actualCountExtended"),
"leftshifted");
auto rightShiftAmount = createSubFolder(
builder, ConstantInt::get(actualCount->getType(), dest.size),
actualCount, "rightshiftamount");
auto rightShifted = createLShrFolder(
builder, wideLvalue,
createZExtFolder(builder, rightShiftAmount, wideType), "rightshifted");
auto rotated =
createOrFolder(builder, leftShifted,
createZExtFolder(builder, rightShifted, wideType,
"rightShiftedExtended"));

auto result = createZExtOrTruncFolder(builder, rotated, Lvalue->getType());

auto newCFBitPosition = ConstantInt::get(rotated->getType(), dest.size - 1);
auto newCF = createZExtOrTruncFolder(
builder, createLShrFolder(builder, rotated, newCFBitPosition),
Type::getInt1Ty(context), "rclnewcf");

auto msbAfterRotate = createZExtOrTruncFolder(
builder, createLShrFolder(builder, result, dest.size - 1),
Type::getInt1Ty(context), "rclmsbafterrotate");
auto isCountOne =
createICMPFolder(builder, CmpInst::ICMP_EQ, actualCount,
ConstantInt::get(actualCount->getType(), 1));
auto newOF = createZExtOrTruncFolder(
builder, createXorFolder(builder, newCF, msbAfterRotate),
Type::getInt1Ty(context));
newOF = createSelectFolder(builder, isCountOne, newOF,
getFlag(builder, FLAG_OF));

printvalue(Lvalue) printvalue(countValue) printvalue(carryFlag)
printvalue(cf_extended) printvalue(shiftedInCF) printvalue(actualCount)
printvalue(wideLvalue) printvalue(leftShifted)
printvalue(rightShifted) printvalue(rotated) printvalue(result)

SetOperandValue(builder, dest, result);
setFlag(builder, FLAG_CF, newCF);
setFlag(builder, FLAG_OF, newOF);
}

/*
(* RCL and RCR Instructions *)
SIZE := OperandSize;
CASE (determine count) OF
SIZE := 8: tempCOUNT := (COUNT AND 1FH) MOD 9;
SIZE := 16: tempCOUNT := (COUNT AND 1FH) MOD 17;
SIZE := 32: tempCOUNT := COUNT AND 1FH;
SIZE := 64: tempCOUNT := COUNT AND 3FH;
ESAC;
IF OperandSize = 64
THEN COUNTMASK = 3FH;
ELSE COUNTMASK = 1FH;
FI;
(* RCR Instruction Operation *)
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR CF;
ELSE OF is undefined;
FI;
WHILE (tempCOUNT ≠ 0)
DO
tempCF := LSB(SRC);
DEST := (DEST / 2) + (CF * 2SIZE);
CF := tempCF;
tempCOUNT := tempCOUNT – 1;
OD;
ELIHW;

*/
void lift_rcr(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {
LLVMContext& context = builder.getContext();
auto dest = instruction.operands[0];
auto count = instruction.operands[1];

auto Lvalue = GetOperandValue(builder, dest, dest.size);
auto countValue = GetOperandValue(builder, count, dest.size);
auto carryFlag = getFlag(builder, FLAG_CF);

unsigned long bitWidth = Lvalue->getType()->getIntegerBitWidth();
unsigned maskC = bitWidth == 64 ? 0x3f : 0x1f;

auto actualCount = createAndFolder(
builder, countValue, ConstantInt::get(countValue->getType(), maskC),
"actualCount");
auto wideType = Type::getIntNTy(context, dest.size * 2);
auto wideLvalue = createZExtFolder(builder, Lvalue, wideType);
auto shiftedInCF = createShlFolder(
builder, createZExtFolder(builder, carryFlag, wideType), dest.size);
wideLvalue = createOrFolder(builder, wideLvalue,
createZExtFolder(builder, shiftedInCF, wideType,
"shiftedInCFExtended"));

auto rightShifted = createLShrFolder(
builder, wideLvalue,
createZExtFolder(builder, actualCount, wideType, "actualCountExtended"),
"rightshifted");
auto leftShiftAmount = createSubFolder(
builder, ConstantInt::get(actualCount->getType(), dest.size),
actualCount);
auto leftShifted =
createShlFolder(builder, wideLvalue,
createZExtFolder(builder, leftShiftAmount, wideType,
"leftShiftAmountExtended"));
auto rotated = createOrFolder(builder, rightShifted, leftShifted);

auto result = createZExtOrTruncFolder(builder, rotated, Lvalue->getType());

auto newCFBitPosition = ConstantInt::get(rotated->getType(), dest.size - 1);
auto newCF = createZExtOrTruncFolder(
builder, createLShrFolder(builder, rotated, newCFBitPosition),
Type::getInt1Ty(context), "rcrcf");

auto msbAfterRotate = createZExtOrTruncFolder(
builder, createLShrFolder(builder, result, dest.size - 1),
Type::getInt1Ty(context), "rcrmsb");
auto newOF = createSelectFolder(
builder,
createICMPFolder(builder, CmpInst::ICMP_EQ, actualCount,
ConstantInt::get(actualCount->getType(), 1)),
createXorFolder(builder, newCF, msbAfterRotate),
getFlag(builder, FLAG_OF));

Value* isCountOne =
createICMPFolder(builder, CmpInst::ICMP_EQ, actualCount,
ConstantInt::get(actualCount->getType(), 1));

newCF = createSelectFolder(builder, isCountOne, newOF,
getFlag(builder, FLAG_OF));
result = createSelectFolder(builder, isCountOne, result, Lvalue);

SetOperandValue(builder, dest, result);
setFlag(builder, FLAG_CF, newCF);
setFlag(builder, FLAG_OF, newOF);
}

void lift_not(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {

auto dest = instruction.operands[0];
void lift_rcl(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
LLVMContext& context = builder.getContext();
auto dest = instruction.operands[0];
auto count = instruction.operands[1];

Value* Lvalue = GetOperandValue(builder, dest, dest.size);
Value* countValue = GetOperandValue(builder, count, dest.size);
Value* carryFlag = getFlag(builder, FLAG_CF);

unsigned long bitWidth = Lvalue->getType()->getIntegerBitWidth();
unsigned maskC = bitWidth == 64 ? 0x3f : 0x1f;

// Calculate actual count
Value* countMask = ConstantInt::get(countValue->getType(), maskC);
Value* actualCount = createAndFolder(builder, countValue, countMask, "actualCount");

// Extend Lvalue to double width
Type* wideType = Type::getIntNTy(context, dest.size * 2);
Value* wideLvalue = createZExtFolder(builder, Lvalue, wideType);

// Shift the carry flag into the LSB
Value* cf_extended = createZExtFolder(builder, carryFlag, wideType);
Value* shiftedInCF = createOrFolder(builder, wideLvalue, cf_extended, "shiftedincf");

// Perform the rotation
Value* shiftAmount = createZExtFolder(builder, actualCount, wideType);
Value* bitWidthPlusOne = ConstantInt::get(wideType, bitWidth + 1);
Value* inverseShiftAmount = createSubFolder(builder, bitWidthPlusOne, shiftAmount);

Value* leftShifted = createShlFolder(builder, shiftedInCF, shiftAmount, "leftshifted");
Value* rightShifted = createLShrFolder(builder, shiftedInCF, inverseShiftAmount, "rightshifted");
Value* rotated = createOrFolder(builder, leftShifted, rightShifted);

// Extract the result and new carry flag
Value* result = createTruncFolder(builder, rotated, Lvalue->getType());
Value* newCFShifted = createLShrFolder(builder, rotated, ConstantInt::get(wideType, bitWidth));
Value* newCF = createTruncFolder(builder, newCFShifted, Type::getInt1Ty(context), "rclnewcf");

// Calculate OF (only valid when count == 1)
Value* resultMSB = createLShrFolder(builder, result, ConstantInt::get(result->getType(), bitWidth - 1));
Value* msbAfterRotate = createTruncFolder(builder, resultMSB, Type::getInt1Ty(context), "rclmsbafterrotate");

Value* one = ConstantInt::get(actualCount->getType(), 1);
Value* isCountOne = createICMPFolder(builder, CmpInst::ICMP_EQ, actualCount, one);

Value* newOF = createXorFolder(builder, newCF, msbAfterRotate);
Value* currentOF = getFlag(builder, FLAG_OF);
newOF = createSelectFolder(builder, isCountOne, newOF, currentOF);

// Set the result and flags
SetOperandValue(builder, dest, result);
setFlag(builder, FLAG_CF, newCF);
setFlag(builder, FLAG_OF, newOF);

// Debug output
printvalue(Lvalue);
printvalue(countValue);
printvalue(carryFlag);
printvalue(actualCount);
printvalue(shiftedInCF);
printvalue(rotated);
printvalue(result);
printvalue(newCF);
printvalue(newOF);
}

auto Rvalue = GetOperandValue(builder, dest, dest.size);
Rvalue = builder.CreateNot(
Rvalue, "realnot-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(builder, dest, Rvalue,
to_string(instruction.runtime_address));
/*
(* RCL and RCR Instructions *)
SIZE := OperandSize;
CASE (determine count) OF
SIZE := 8: tempCOUNT := (COUNT AND 1FH) MOD 9;
SIZE := 16: tempCOUNT := (COUNT AND 1FH) MOD 17;
SIZE := 32: tempCOUNT := COUNT AND 1FH;
SIZE := 64: tempCOUNT := COUNT AND 3FH;
ESAC;
IF OperandSize = 64
THEN COUNTMASK = 3FH;
ELSE COUNTMASK = 1FH;
FI;
(* RCR Instruction Operation *)
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR CF;
ELSE OF is undefined;
FI;
WHILE (tempCOUNT ≠ 0)
DO
tempCF := LSB(SRC);
DEST := (DEST / 2) + (CF * 2SIZE);
CF := tempCF;
tempCOUNT := tempCOUNT – 1;
OD;
ELIHW;

printvalue(Rvalue);
// Flags Affected
// None
}
*/
void lift_rcr(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
LLVMContext& context = builder.getContext();
auto dest = instruction.operands[0];
auto count = instruction.operands[1];

Value* Lvalue = GetOperandValue(builder, dest, dest.size);
Value* countValue = GetOperandValue(builder, count, dest.size);
Value* carryFlag = getFlag(builder, FLAG_CF);

unsigned long bitWidth = Lvalue->getType()->getIntegerBitWidth();
unsigned maskC = bitWidth == 64 ? 0x3f : 0x1f;

// Calculate actual count
Value* countMask = ConstantInt::get(countValue->getType(), maskC);
Value* actualCount = createAndFolder(builder, countValue, countMask, "actualCount");

// Extend Lvalue to double width and shift left by 1 to make room for CF
Type* wideType = Type::getIntNTy(context, dest.size * 2);
Value* wideLvalue = createZExtFolder(builder, Lvalue, wideType);
Value* shiftedLvalue =
createShlFolder(builder, wideLvalue, ConstantInt::get(wideType, 1));

// Insert the carry flag into the MSB
Value* cf_extended = createZExtFolder(builder, carryFlag, wideType);
Value* shiftedCF = createShlFolder(builder, cf_extended, ConstantInt::get(wideType, bitWidth));
Value* shiftedInCF = createOrFolder(builder, shiftedLvalue, shiftedCF, "shiftedincf");

// Perform the rotation
Value* shiftAmount = createZExtFolder(builder, actualCount, wideType);
Value* bitWidthPlusOne = ConstantInt::get(wideType, bitWidth + 1);
Value* inverseShiftAmount = createSubFolder(builder, bitWidthPlusOne, shiftAmount);

Value* rightShifted = createLShrFolder(builder, shiftedInCF, shiftAmount, "rightshifted");
Value* leftShifted = createShlFolder(builder, shiftedInCF, inverseShiftAmount, "leftshifted");
Value* rotated = createOrFolder(builder, rightShifted, leftShifted);

// Extract the result and new carry flag
Value* shiftedResult = createLShrFolder(builder, rotated, ConstantInt::get(wideType, 1));
Value* result = createTruncFolder(builder, shiftedResult, Lvalue->getType());
Value* newCF = createTruncFolder(builder, rotated, Type::getInt1Ty(context), "rcrnewcf");

// Calculate OF (only valid when count == 1)
Value* resultMSB = createLShrFolder(builder, result, ConstantInt::get(result->getType(), bitWidth - 1));
Value* msbAfterRotate = createTruncFolder(builder, resultMSB, Type::getInt1Ty(context), "rcrmsbafterrotate");

Value* LvalueMSB = createLShrFolder(builder, Lvalue, ConstantInt::get(Lvalue->getType(), bitWidth - 1));
Value* msbBeforeRotate = createTruncFolder(builder, LvalueMSB, Type::getInt1Ty(context), "rcrmsbbeforerotate");

Value* one = ConstantInt::get(actualCount->getType(), 1);
Value* isCountOne = createICMPFolder(builder, CmpInst::ICMP_EQ, actualCount, one);

Value* newOF = createXorFolder(builder, msbBeforeRotate, msbAfterRotate);
Value* currentOF = getFlag(builder, FLAG_OF);
newOF = createSelectFolder(builder, isCountOne, newOF, currentOF);

// Set the result and flags
SetOperandValue(builder, dest, result);
setFlag(builder, FLAG_CF, newCF);
setFlag(builder, FLAG_OF, newOF);

// Debug output
printvalue(Lvalue);
printvalue(countValue);
printvalue(carryFlag);
printvalue(actualCount);
printvalue(shiftedInCF);
printvalue(rotated);
printvalue(result);
printvalue(newCF);
printvalue(newOF);
}

void lift_neg(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {
Expand Down Expand Up @@ -1978,6 +1963,22 @@ namespace arithmeticsAndLogical {
setFlag(builder, FLAG_SF, sf);
setFlag(builder, FLAG_ZF, zf);
}

void lift_not(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {

auto dest = instruction.operands[0];

auto Rvalue = GetOperandValue(builder, dest, dest.size);
Rvalue = builder.CreateNot(
Rvalue, "realnot-" + to_string(instruction.runtime_address) + "-");
SetOperandValue(builder, dest, Rvalue,
to_string(instruction.runtime_address));

printvalue(Rvalue);
// Flags Affected
// None
}

void lift_xchg(IRBuilder<>& builder,
ZydisDisassembledInstruction& instruction) {
Expand Down