Skip to content

Commit a413562

Browse files
committed
ANDN, BEXTR, BLSI, BLSMSK, BLSR, LZCNT, TZCNT Instructions
1 parent 1b3d266 commit a413562

File tree

8 files changed

+230
-0
lines changed

8 files changed

+230
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,4 @@ _Pvt_Extensions
234234

235235
# FAKE - F# Make
236236
.fake/
237+
/UDEmulator.VC.db

ANDN.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,33 @@ int __stdcall ANDNInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src1 = getRegValue(instruction.src1, context);
12+
unsigned int src2;
13+
if (instruction.src2 == MEM_32)
14+
{
15+
src2 = *(unsigned int*)getEffectiveVA(instruction.mem, context);
16+
}
17+
else
18+
{
19+
src2 = getRegValue(instruction.src2, context);
20+
}
21+
22+
unsigned int dest = (~src1) & src2;
23+
unsigned int SF = dest >> 31;
24+
25+
// Set flags
26+
context->flags &= (~FLAG_SF) & (~FLAG_ZF) & (~FLAG_OF) & (~FLAG_CF);
27+
if (SF)
28+
{
29+
context->flags |= FLAG_SF;
30+
}
31+
32+
if (dest == 0)
33+
{
34+
context->flags |= FLAG_ZF;
35+
}
36+
37+
setRegValue(instruction.dest, dest, context);
38+
1139
return TRUE;
1240
}

BEXTR.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,32 @@ int __stdcall BEXTRInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src1;
12+
if (instruction.src1 == MEM_32)
13+
{
14+
src1 = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src1 = getRegValue(instruction.src1, context);
19+
}
20+
unsigned int src2 = getRegValue(instruction.src2, context);
21+
22+
23+
unsigned int start = src2 & 0xFF;
24+
unsigned int len = (src2 & 0xFF00) >> 8;
25+
26+
unsigned int dest = (src1 >> start) & ((1 << len) - 1);
27+
28+
// Set flags
29+
context->flags &= (~FLAG_ZF) & (~FLAG_CF) & (~FLAG_OF);
30+
31+
if (dest == 0)
32+
{
33+
context->flags |= FLAG_ZF;
34+
}
35+
36+
setRegValue(instruction.dest, dest, context);
37+
1138
return TRUE;
1239
}

BLSI.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,38 @@ int __stdcall BLSIInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src;
12+
if (instruction.src1 == MEM_32)
13+
{
14+
src = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src = getRegValue(instruction.src1, context);
19+
}
20+
21+
unsigned int operand_size = 32;
22+
23+
unsigned int dest = (-src) & src;
24+
25+
// Set flags
26+
context->flags &= (~FLAG_ZF) & (~FLAG_SF) & (~FLAG_CF) & (~FLAG_OF);
27+
if (src == 0)
28+
{
29+
context->flags |= FLAG_CF;
30+
}
31+
32+
if (dest == 0)
33+
{
34+
context->flags |= FLAG_ZF;
35+
}
36+
37+
if (dest >> (operand_size - 1))
38+
{
39+
context->flags |= FLAG_SF;
40+
}
41+
42+
setRegValue(instruction.dest, dest, context);
43+
1144
return TRUE;
1245
}

BLSMSK.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,33 @@ int __stdcall BLSMSKInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src;
12+
if (instruction.src1 == MEM_32)
13+
{
14+
src = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src = getRegValue(instruction.src1, context);
19+
}
20+
21+
unsigned int operand_size = 32;
22+
23+
unsigned int dest = (src-1) ^ src;
24+
25+
// Set flags
26+
context->flags &= (~FLAG_ZF) & (~FLAG_SF) & (~FLAG_CF) & (~FLAG_OF);
27+
if (src == 0)
28+
{
29+
context->flags |= FLAG_CF;
30+
}
31+
32+
if (dest >> (operand_size - 1))
33+
{
34+
context->flags |= FLAG_SF;
35+
}
36+
37+
setRegValue(instruction.dest, dest, context);
38+
1139
return TRUE;
1240
}

BLSR.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,38 @@ int __stdcall BLSRInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src;
12+
if (instruction.src1 == MEM_32)
13+
{
14+
src = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src = getRegValue(instruction.src1, context);
19+
}
20+
21+
unsigned int operand_size = 32;
22+
23+
unsigned int dest = (src-1) & src;
24+
25+
// Set flags
26+
context->flags &= (~FLAG_ZF) & (~FLAG_SF) & (~FLAG_CF) & (~FLAG_OF);
27+
if (src == 0)
28+
{
29+
context->flags |= FLAG_CF;
30+
}
31+
32+
if (dest == 0)
33+
{
34+
context->flags |= FLAG_ZF;
35+
}
36+
37+
if (dest >> (operand_size - 1))
38+
{
39+
context->flags |= FLAG_SF;
40+
}
41+
42+
setRegValue(instruction.dest, dest, context);
43+
1144
return TRUE;
1245
}

LZCNT.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,45 @@ int __stdcall LZCNTInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src;
12+
if (instruction.src1 == MEM_32 || instruction.src1 == MEM_16 )
13+
{
14+
src = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src = getRegValue(instruction.src1, context);
19+
}
20+
21+
unsigned int operand_size = 32;
22+
23+
if (instruction.dest & 0x10) // 16-bit instruction
24+
{
25+
operand_size = 16;
26+
}
27+
28+
unsigned int temp = operand_size - 1;
29+
unsigned int dest = 0;
30+
31+
while ((temp >= 0) && (src >> temp == 0))
32+
{
33+
--temp;
34+
++dest;
35+
}
36+
37+
// Set flags
38+
context->flags &= (~FLAG_ZF) & (~FLAG_CF);
39+
if (dest == operand_size)
40+
{
41+
context->flags |= FLAG_CF;
42+
}
43+
44+
if (dest == 0)
45+
{
46+
context->flags |= FLAG_ZF;
47+
}
48+
49+
setRegValue(instruction.dest, dest, context);
50+
1151
return TRUE;
1252
}

TZCNT.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,45 @@ int __stdcall TZCNTInstructionEmulator(
88
UNREFERENCED_PARAMETER(instruction);
99
UNREFERENCED_PARAMETER(context);
1010

11+
unsigned int src;
12+
if (instruction.src1 == MEM_32 || instruction.src1 == MEM_16)
13+
{
14+
src = *(unsigned int*)getEffectiveVA(instruction.mem, context);
15+
}
16+
else
17+
{
18+
src = getRegValue(instruction.src1, context);
19+
}
20+
21+
unsigned int operand_size = 32;
22+
23+
if (instruction.dest & 0x10) // 16-bit instruction
24+
{
25+
operand_size = 16;
26+
}
27+
28+
unsigned int temp = 0;
29+
unsigned int dest = 0;
30+
31+
while ((temp < operand_size) && (((src >> temp) & 0x1) == 0))
32+
{
33+
--temp;
34+
++dest;
35+
}
36+
37+
// Set flags
38+
context->flags &= (~FLAG_ZF) & (~FLAG_CF);
39+
if (dest == operand_size)
40+
{
41+
context->flags |= FLAG_CF;
42+
}
43+
44+
if (dest == 0)
45+
{
46+
context->flags |= FLAG_ZF;
47+
}
48+
49+
setRegValue(instruction.dest, dest, context);
50+
1151
return TRUE;
1252
}

0 commit comments

Comments
 (0)