Skip to content

Commit

Permalink
fix vextractfxxx definition decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
BeaEngine committed Sep 27, 2020
1 parent 4d9c2f2 commit 93c728e
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 64 deletions.
4 changes: 2 additions & 2 deletions headers/BeaEnginePython.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ def reset(self):
self.pp = 0
self.R = 0
self.B = 0
self.R1 = 0
self.Rprime = 0
self.X = 0
self.vvvv = 0b1111
self.V = 0
Expand All @@ -486,7 +486,7 @@ def prefix(self):
return '62{:02x}{:02x}{:02x}'.format(self.p0(),self.p1(),self.p2())

def p0(self):
return self.mm + (self.R1 << 4) + (self.B << 5) + (self.X << 6)+ (self.R << 7)
return self.mm + (self.Rprime << 4) + (self.B << 5) + (self.X << 6)+ (self.R << 7)

def p1(self):
return self.pp + 0b100 + (self.vvvv << 3) + (self.W << 7)
Expand Down
39 changes: 23 additions & 16 deletions src/Includes/instr_set/instructions_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -12545,6 +12545,8 @@ void __bea_callspec__ cvttps2pi_(PDISASM pMyDisasm)
}
}
else {
/* EVEX.LIG.F2.0F.W0 2C /r */
/* VCVTTSD2SI r32, xmm1/m64{sae} */
(*pMyDisasm).Instruction.Category = (GV.EVEX.state == InUsePrefix) ? AVX512_INSTRUCTION : AVX_INSTRUCTION;
#ifndef BEA_LIGHT_DISASSEMBLY
(void) strcpy ((*pMyDisasm).Instruction.Mnemonic, "vcvttsd2si ");
Expand Down Expand Up @@ -12577,7 +12579,6 @@ void __bea_callspec__ cvttps2pi_(PDISASM pMyDisasm)
GV.OperandSize = 64;
Reg_Opcode(&(*pMyDisasm).Operand1, pMyDisasm);
GV.EIP_+= GV.DECALAGE_EIP+2;

}
}
}
Expand Down Expand Up @@ -14765,6 +14766,9 @@ void __bea_callspec__ palignr_(PDISASM pMyDisasm)
* ==================================================================== */
void __bea_callspec__ vextractf128(PDISASM pMyDisasm)
{
/* EVEX.256.66.0F3A.W0 19 /r ib */
/* VEXTRACTF32X4 xmm1/m128 {k1}{z}, ymm2, imm8 */

if (GV.EVEX.state == InUsePrefix) {
if (GV.VEX.pp == 1) {
if (GV.VEX.L == 0) GV.ERROR_OPCODE = UD_;
Expand All @@ -14781,7 +14785,7 @@ void __bea_callspec__ vextractf128(PDISASM pMyDisasm)
GV.EVEX.tupletype = TUPLE2;
}
(*pMyDisasm).Instruction.Category = AVX512_INSTRUCTION;
GV.MemDecoration = Arg3_m128_xmm;
GV.MemDecoration = Arg1_m128_xmm;
if (GV.VEX.L == 0) {
GV.Register_ = SSE_REG;
}
Expand All @@ -14791,12 +14795,12 @@ void __bea_callspec__ vextractf128(PDISASM pMyDisasm)
else if (GV.EVEX.LL == 0x2) {
GV.Register_ = AVX512_REG;
}
Reg_Opcode(&(*pMyDisasm).Operand1, pMyDisasm);
fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand2, pMyDisasm);
Reg_Opcode(&(*pMyDisasm).Operand2, pMyDisasm);
/*fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand2, pMyDisasm);*/
GV.Register_ = SSE_REG;
MOD_RM(&(*pMyDisasm).Operand3, pMyDisasm);
MOD_RM(&(*pMyDisasm).Operand1, pMyDisasm);
GV.EIP_ += GV.DECALAGE_EIP+2;
getImmediat8(&(*pMyDisasm).Operand4, pMyDisasm);
getImmediat8(&(*pMyDisasm).Operand3, pMyDisasm);
}
else {
FailDecode(pMyDisasm);
Expand All @@ -14810,19 +14814,19 @@ void __bea_callspec__ vextractf128(PDISASM pMyDisasm)
(void) strcpy ((*pMyDisasm).Instruction.Mnemonic, "vextractf128 ");
#endif
(*pMyDisasm).Instruction.Category = AVX_INSTRUCTION;
GV.MemDecoration = Arg3_m128_xmm;
GV.MemDecoration = Arg1_m128_xmm;
if (GV.VEX.L == 0) {
GV.Register_ = SSE_REG;
}
else {
GV.Register_ = AVX_REG;
}
Reg_Opcode(&(*pMyDisasm).Operand1, pMyDisasm);
fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand2, pMyDisasm);
Reg_Opcode(&(*pMyDisasm).Operand2, pMyDisasm);
/*fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand1, pMyDisasm);*/
GV.Register_ = SSE_REG;
MOD_RM(&(*pMyDisasm).Operand3, pMyDisasm);
MOD_RM(&(*pMyDisasm).Operand1, pMyDisasm);
GV.EIP_ += GV.DECALAGE_EIP+2;
getImmediat8(&(*pMyDisasm).Operand4, pMyDisasm);
getImmediat8(&(*pMyDisasm).Operand3, pMyDisasm);
}
else {
FailDecode(pMyDisasm);
Expand Down Expand Up @@ -14976,6 +14980,9 @@ void __bea_callspec__ vcvtps2ph(PDISASM pMyDisasm)
* ==================================================================== */
void __bea_callspec__ vextractf32x8(PDISASM pMyDisasm)
{
/* # EVEX.512.66.0F3A.W0 1B /r ib */
/* VEXTRACTF32X8 ymm1/m256 {k1}{z}, zmm2, imm8 */

if (GV.EVEX.state == InUsePrefix) {
if (GV.VEX.pp == 1) {
if (GV.VEX.L == 0) GV.ERROR_OPCODE = UD_;
Expand All @@ -14992,7 +14999,7 @@ void __bea_callspec__ vextractf32x8(PDISASM pMyDisasm)
GV.EVEX.tupletype = TUPLE4;
}
(*pMyDisasm).Instruction.Category = AVX512_INSTRUCTION;
GV.MemDecoration = Arg3_m256_ymm;
GV.MemDecoration = Arg1_m256_ymm;
if (GV.VEX.L == 0) {
GV.Register_ = SSE_REG;
}
Expand All @@ -15002,12 +15009,12 @@ void __bea_callspec__ vextractf32x8(PDISASM pMyDisasm)
else if (GV.EVEX.LL == 0x2) {
GV.Register_ = AVX512_REG;
}
Reg_Opcode(&(*pMyDisasm).Operand1, pMyDisasm);
fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand2, pMyDisasm);
Reg_Opcode(&(*pMyDisasm).Operand2, pMyDisasm);
/*fillRegister((~GV.VEX.vvvv & 0xF) + 16 * GV.EVEX.V, &(*pMyDisasm).Operand2, pMyDisasm);*/
GV.Register_ = AVX_REG;
MOD_RM(&(*pMyDisasm).Operand3, pMyDisasm);
MOD_RM(&(*pMyDisasm).Operand1, pMyDisasm);
GV.EIP_ += GV.DECALAGE_EIP+2;
getImmediat8(&(*pMyDisasm).Operand4, pMyDisasm);
getImmediat8(&(*pMyDisasm).Operand3, pMyDisasm);
}
else {
FailDecode(pMyDisasm);
Expand Down
32 changes: 28 additions & 4 deletions tests/0f2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,43 @@ def test(self):
# VCVTTSD2SI r32, xmm1/m64{sae}

myEVEX = EVEX('EVEX.LIG.F2.0F.W0')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2c16'.format(myEVEX.prefix()).decode('hex')
#Buffer = '62017f002c16'.decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()

assert_equal(myEVEX.p0(), 17)
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2c)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvttsd2si ')
assert_equal(myDisasm.infos.repr, 'vcvttsd2si r10w, qword ptr [r14]')
assert_equal(myDisasm.infos.Reserved_.ERROR_OPCODE, 0)
assert_equal(myDisasm.infos.Reserved_.REGOPCODE, 10)
assert_equal(myDisasm.infos.Reserved_.REX.R_, 1)
assert_equal(myDisasm.infos.Reserved_.EVEX.P0, 17)
assert_equal(myDisasm.infos.Reserved_.EVEX.P1, 0x7f)
assert_equal(myDisasm.infos.Reserved_.EVEX.P2, 0)
assert_equal(myDisasm.infos.Reserved_.EVEX.R1, 0)
assert_equal(myDisasm.infos.Operand1.OpSize, 32)
assert_equal(myDisasm.infos.Operand1.OpType, REGISTER_TYPE)
assert_equal(myDisasm.infos.Operand1.OpMnemonic, "r10d")
assert_equal(myDisasm.infos.Operand1.Registers.type, GENERAL_REG)
assert_equal(myDisasm.infos.Operand1.Registers.cr, 0)
assert_equal(myDisasm.infos.Operand1.Registers.gpr, REG10)
assert_equal(myDisasm.infos.repr, 'vcvttsd2si r10d, qword ptr [r14]')

# EVEX.LIG.F2.0F.W1 2C /r
# VCVTTSD2SI r64, xmm1/m64{sae}

myEVEX = EVEX('EVEX.LIG.F2.0F.W1')
myEVEX.Rprime = 1
myEVEX.R = 1
Buffer = '{}2c16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2c)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvttsd2si ')
assert_equal(myDisasm.infos.repr, 'vcvttsd2si ebp, qword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvttsd2si rdx, qword ptr [r14]')

# F3 0F 2C /r
# CVTTSS2SI r32, xmm1/m32
Expand Down Expand Up @@ -163,23 +183,27 @@ def test(self):
# VCVTTSS2SI r32, xmm1/m32{sae}

myEVEX = EVEX('EVEX.LIG.F3.0F.W0')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2c16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2c)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvttss2si ')
assert_equal(myDisasm.infos.repr, 'vcvttss2si r10w, dword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvttss2si r10d, dword ptr [r14]')

# EVEX.LIG.F3.0F.W1 2C /r
# VCVTTSS2SI r64, xmm1/m32{sae}

myEVEX = EVEX('EVEX.LIG.F3.0F.W1')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2c16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2c)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvttss2si ')
assert_equal(myDisasm.infos.repr, 'vcvttss2si ebp, dword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvttss2si r10, dword ptr [r14]')

# VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.

Expand Down
16 changes: 12 additions & 4 deletions tests/0f2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,27 @@ def test(self):
# VcvtSD2SI r32, xmm1/m64{sae}

myEVEX = EVEX('EVEX.LIG.F2.0F.W0')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2d16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2d)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvtsd2si ')
assert_equal(myDisasm.infos.repr, 'vcvtsd2si r10w, qword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvtsd2si r10d, qword ptr [r14]')

# EVEX.LIG.F2.0F.W1 2d /r
# VcvtSD2SI r64, xmm1/m64{sae}

myEVEX = EVEX('EVEX.LIG.F2.0F.W1')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2d16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2d)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvtsd2si ')
assert_equal(myDisasm.infos.repr, 'vcvtsd2si ebp, qword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvtsd2si r10, qword ptr [r14]')

# F3 0F 2d /r
# cvtSS2SI r32, xmm1/m32
Expand Down Expand Up @@ -163,23 +167,27 @@ def test(self):
# VcvtSS2SI r32, xmm1/m32{sae}

myEVEX = EVEX('EVEX.LIG.F3.0F.W0')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2d16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2d)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvtss2si ')
assert_equal(myDisasm.infos.repr, 'vcvtss2si r10w, dword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvtss2si r10d, dword ptr [r14]')

# EVEX.LIG.F3.0F.W1 2d /r
# VcvtSS2SI r64, xmm1/m32{sae}

myEVEX = EVEX('EVEX.LIG.F3.0F.W1')
myEVEX.Rprime = 1
myEVEX.R = 0
Buffer = '{}2d16'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x2d)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vcvtss2si ')
assert_equal(myDisasm.infos.repr, 'vcvtss2si ebp, dword ptr [r14]')
assert_equal(myDisasm.infos.repr, 'vcvtss2si r10, dword ptr [r14]')

# VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.

Expand Down
42 changes: 32 additions & 10 deletions tests/0f3a19.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,56 +24,78 @@ class TestSuite:
def test(self):

# VEX.256.66.0F3A.W0 19 /r ib
# vextractF128 ymm1, ymm2, xmm3/m128, imm8
# VEXTRACTF128 xmm1/m128, ymm2, imm8

myVEX = VEX('VEX.256.66.0F3A.W0')
Buffer = '{}191033'.format(myVEX.c4()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf128 ')
assert_equal(myDisasm.infos.repr, 'vextractf128 ymm10, ymm0, xmmword ptr [r8], 33h')
assert_equal(myDisasm.infos.repr, 'vextractf128 xmmword ptr [r8], ymm10, 33h')

# VEX.256.66.0F3A.W0 19 /r ib
# VEXTRACTF128 xmm1/m128, ymm2, imm8

myVEX = VEX('VEX.256.66.0F3A.W0')
Buffer = '{}19c001'.format(myVEX.c4()).decode('hex')

myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf128 ')
assert_equal(myDisasm.infos.repr, 'vextractf128 xmm8, ymm8, 01h')

# fix issue #6
Buffer = 'c4c37d19c001'.decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf128 ')
assert_equal(myDisasm.infos.repr, 'vextractf128 xmm8, ymm0, 01h')


# EVEX.256.66.0F3A.W0 19 /r ib
# vextractF32X4 ymm1 {k1}{z}, ymm2, xmm3/m128, imm8
# VEXTRACTF32X4 xmm1/m128 {k1}{z}, ymm2, imm8

myEVEX = EVEX('EVEX.256.66.0F3A.W0')
Buffer = '{}192011'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf32x4 ')
assert_equal(myDisasm.infos.repr, 'vextractf32x4 ymm28, ymm16, xmmword ptr [r8], 11h')
assert_equal(myDisasm.infos.repr, 'vextractf32x4 xmmword ptr [r8], ymm28, 11h')

# EVEX.512.66.0F3A.W0 19 /r ib
# vextractF32X4 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8
# VEXTRACTF32x4 xmm1/m128 {k1}{z}, zmm2, imm8

myEVEX = EVEX('EVEX.512.66.0F3A.W0')
Buffer = '{}192011'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf32x4 ')
assert_equal(myDisasm.infos.repr, 'vextractf32x4 zmm28, zmm16, xmmword ptr [r8], 11h')
assert_equal(myDisasm.infos.repr, 'vextractf32x4 xmmword ptr [r8], zmm28, 11h')


# EVEX.256.66.0F3A.W1 19 /r ib
# vextractF64X2 ymm1 {k1}{z}, ymm2, xmm3/m128, imm8
# VEXTRACTF64X2 xmm1/m128 {k1}{z}, ymm2, imm8

myEVEX = EVEX('EVEX.256.66.0F3A.W1')
Buffer = '{}192011'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf64x2 ')
assert_equal(myDisasm.infos.repr, 'vextractf64x2 ymm28, ymm16, xmmword ptr [r8], 11h')
assert_equal(myDisasm.infos.repr, 'vextractf64x2 xmmword ptr [r8], ymm28, 11h')

# EVEX.512.66.0F3A.W1 19 /r ib
# vextractF64X2 zmm1 {k1}{z}, zmm2, xmm3/m128, imm8
# VEXTRACTF64X2 xmm1/m128 {k1}{z}, zmm2, imm8

myEVEX = EVEX('EVEX.512.66.0F3A.W1')
Buffer = '{}192011'.format(myEVEX.prefix()).decode('hex')
myDisasm = Disasm(Buffer)
myDisasm.read()
assert_equal(myDisasm.infos.Instruction.Opcode, 0x19)
assert_equal(myDisasm.infos.Instruction.Mnemonic, 'vextractf64x2 ')
assert_equal(myDisasm.infos.repr, 'vextractf64x2 zmm28, zmm16, xmmword ptr [r8], 11h')
assert_equal(myDisasm.infos.repr, 'vextractf64x2 xmmword ptr [r8], zmm28, 11h')
Loading

0 comments on commit 93c728e

Please sign in to comment.