Skip to content

Commit c17d48a

Browse files
authored
Merge pull request #34 from vxcall/main
lift_idiv2 integration, and separate lift_inc_dec
2 parents 9189d71 + 990e5f4 commit c17d48a

File tree

3 files changed

+130
-52
lines changed

3 files changed

+130
-52
lines changed

lifter/Semantics.cpp

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,35 +2442,6 @@ void lift_rcr(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
24422442
printvalue(splitResult) printvalue(of) printvalue(cf)
24432443
}
24442444

2445-
void lift_idiv2(IRBuilder<>& builder,
2446-
ZydisDisassembledInstruction& instruction) {
2447-
LLVMContext& context = builder.getContext();
2448-
auto src = instruction.operands[0];
2449-
auto dividend = GetRegisterValue(builder, ZYDIS_REGISTER_AX);
2450-
2451-
Value* divisor = GetOperandValue(builder, src, src.size);
2452-
divisor =
2453-
builder.CreateSExt(divisor, Type::getIntNTy(context, src.size * 2));
2454-
dividend = builder.CreateSExtOrTrunc(dividend, divisor->getType());
2455-
Value* remainder = builder.CreateSRem(dividend, divisor);
2456-
Value* quotient = builder.CreateSDiv(dividend, divisor);
2457-
2458-
SetRegisterValue(
2459-
builder, ZYDIS_REGISTER_AL,
2460-
createZExtOrTruncFolder(builder, quotient,
2461-
Type::getIntNTy(context, src.size)));
2462-
2463-
SetRegisterValue(
2464-
builder, ZYDIS_REGISTER_AH,
2465-
createZExtOrTruncFolder(builder, remainder,
2466-
Type::getIntNTy(context, src.size)));
2467-
2468-
printvalue(remainder);
2469-
printvalue(quotient);
2470-
printvalue(divisor);
2471-
printvalue(dividend);
2472-
}
2473-
24742445
void lift_div(IRBuilder<>& builder,
24752446
ZydisDisassembledInstruction& instruction) {
24762447

@@ -2563,7 +2534,29 @@ void lift_rcr(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
25632534
LLVMContext& context = builder.getContext();
25642535
auto src = instruction.operands[0];
25652536
if (src.size == 8) {
2566-
lift_idiv2(builder, instruction);
2537+
auto dividend = GetRegisterValue(builder, ZYDIS_REGISTER_AX);
2538+
2539+
Value* divisor = GetOperandValue(builder, src, src.size);
2540+
divisor =
2541+
builder.CreateSExt(divisor, Type::getIntNTy(context, src.size * 2));
2542+
dividend = builder.CreateSExtOrTrunc(dividend, divisor->getType());
2543+
Value* remainder = builder.CreateSRem(dividend, divisor);
2544+
Value* quotient = builder.CreateSDiv(dividend, divisor);
2545+
2546+
SetRegisterValue(
2547+
builder, ZYDIS_REGISTER_AL,
2548+
createZExtOrTruncFolder(builder, quotient,
2549+
Type::getIntNTy(context, src.size)));
2550+
2551+
SetRegisterValue(
2552+
builder, ZYDIS_REGISTER_AH,
2553+
createZExtOrTruncFolder(builder, remainder,
2554+
Type::getIntNTy(context, src.size)));
2555+
2556+
printvalue(remainder);
2557+
printvalue(quotient);
2558+
printvalue(divisor);
2559+
printvalue(dividend);
25672560
return;
25682561
}
25692562
auto dividendLowop = instruction.operands[1]; // eax
@@ -2872,7 +2865,7 @@ void lift_rcr(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
28722865
SetOperandValue(builder, dest, result);
28732866
}
28742867

2875-
void lift_inc_dec(IRBuilder<>& builder,
2868+
void lift_inc(IRBuilder<>& builder,
28762869
ZydisDisassembledInstruction& instruction) {
28772870
auto operand = instruction.operands[0];
28782871

@@ -2883,30 +2876,55 @@ void lift_rcr(IRBuilder<>& builder, ZydisDisassembledInstruction& instruction) {
28832876
Value* of;
28842877
// The CF flag is not affected. The OF, SF, ZF, AF, and PF flags are set
28852878
// according to the result.
2886-
if (instruction.info.mnemonic == ZYDIS_MNEMONIC_INC) {
2887-
// treat it as add r, 1 for flags
2888-
result = createAddFolder(builder, Lvalue, one,
2889-
"inc-" + to_string(instruction.runtime_address) +
2890-
"-");
2891-
of = computeOverflowFlagAdd(builder, Lvalue, one, result);
2879+
// treat it as add r, 1 for flags
2880+
result = createAddFolder(builder, Lvalue, one,
2881+
"inc-" + to_string(instruction.runtime_address) +
2882+
"-");
2883+
of = computeOverflowFlagAdd(builder, Lvalue, one, result);
28922884

2893-
} else {
2894-
// treat it as sub r, 1 for flags
2895-
result = createSubFolder(builder, Lvalue, one,
2896-
"dec-" + to_string(instruction.runtime_address) +
2897-
"-");
2898-
of = computeOverflowFlagSub(builder, Lvalue, one, result);
2899-
}
29002885

2901-
printvalue(Lvalue) printvalue(result)
2886+
printvalue(Lvalue) printvalue(result);
2887+
2888+
Value* sf = computeSignFlag(builder, result);
2889+
Value* zf = computeZeroFlag(builder, result);
2890+
Value* pf = computeParityFlag(builder, result);
2891+
2892+
printvalue(sf);
2893+
2894+
setFlag(builder, FLAG_OF, of);
2895+
setFlag(builder, FLAG_SF, sf);
2896+
setFlag(builder, FLAG_ZF, zf);
2897+
setFlag(builder, FLAG_PF, pf);
2898+
SetOperandValue(builder, operand, result);
2899+
}
2900+
2901+
2902+
void lift_dec(IRBuilder<>& builder,
2903+
ZydisDisassembledInstruction& instruction) {
2904+
auto operand = instruction.operands[0];
2905+
2906+
Value* Lvalue = GetOperandValue(builder, operand, operand.size);
2907+
2908+
Value* one = ConstantInt::get(Lvalue->getType(), 1, true);
2909+
Value* result;
2910+
Value* of;
2911+
// The CF flag is not affected. The OF, SF, ZF, AF, and PF flags are set
2912+
// according to the result.
2913+
// treat it as sub r, 1 for flags
2914+
result = createSubFolder(builder, Lvalue, one,
2915+
"dec-" + to_string(instruction.runtime_address) +
2916+
"-");
2917+
of = computeOverflowFlagSub(builder, Lvalue, one, result);
2918+
2919+
printvalue(Lvalue) printvalue(result);
29022920

2903-
Value* sf = computeSignFlag(builder, result);
2921+
Value* sf = computeSignFlag(builder, result);
29042922
Value* zf = computeZeroFlag(builder, result);
29052923
Value* pf = computeParityFlag(builder, result);
29062924

2907-
printvalue(sf)
2925+
printvalue(sf);
29082926

2909-
setFlag(builder, FLAG_OF, of);
2927+
setFlag(builder, FLAG_OF, of);
29102928
setFlag(builder, FLAG_SF, sf);
29112929
setFlag(builder, FLAG_ZF, zf);
29122930
setFlag(builder, FLAG_PF, pf);
@@ -4259,9 +4277,13 @@ void liftInstructionSemantics(IRBuilder<>& builder,
42594277
arithmeticsAndLogical::lift_lea(builder, instruction);
42604278
break;
42614279
}
4262-
case ZYDIS_MNEMONIC_INC:
4280+
case ZYDIS_MNEMONIC_INC: {
4281+
arithmeticsAndLogical::lift_inc(builder, instruction);
4282+
break;
4283+
}
4284+
42634285
case ZYDIS_MNEMONIC_DEC: {
4264-
arithmeticsAndLogical::lift_inc_dec(builder, instruction);
4286+
arithmeticsAndLogical::lift_dec(builder, instruction);
42654287
break;
42664288
}
42674289

testcases/test_div.asm

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
section .text
2+
3+
global test_div_64
4+
test_div_64:
5+
mov rdx, 0xbf01
6+
mov rax, 0x800000007F65B9DD
7+
mov rcx, rax
8+
mov rax, 0x11
9+
div rcx
10+
ret
11+
12+
global test_div_32
13+
test_div_32:
14+
mov edx, 0x12345678
15+
mov ecx, 0x1000
16+
mov eax, 0x87654321
17+
div ecx
18+
ret
19+
20+
global test_div_16
21+
test_div_16:
22+
mov dx, 0x1234
23+
mov ax, 0x5678
24+
mov cx, 0x100
25+
div cx
26+
ret
27+
28+
global test_div_8
29+
test_div_8:
30+
mov ax, 0x1278
31+
mov cl, 0x10
32+
div cl
33+
ret

testcases/test_idiv.asm

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
section .text
22

3-
global main
4-
main:
3+
global test_idiv_64
4+
test_idiv_64:
55
mov rdx, 0xbf01
66
mov rax, 0x800000007F65B9DD
77
mov rcx, rax
88
mov rax, 0x11
99
idiv rcx
10+
ret
11+
12+
global test_idiv_32
13+
test_idiv_32:
14+
mov edx, 0x12345678
15+
mov ecx, 0x1000
16+
mov eax, 0x87654321
17+
idiv ecx
18+
ret
19+
20+
global test_idiv_16
21+
test_idiv_16:
22+
mov dx, 0x1234
23+
mov ax, 0x5678
24+
mov cx, 0x100
25+
idiv cx
26+
ret
27+
28+
global test_idiv_8
29+
test_idiv_8:
30+
mov ax, 0x1278
31+
mov cl, 0x10
32+
idiv cl
1033
ret

0 commit comments

Comments
 (0)