Skip to content

Commit

Permalink
Merge branch 'master' into chess
Browse files Browse the repository at this point in the history
* master:
  Add `psubq` instruction (x86) (#2553)
  • Loading branch information
ekilmer committed May 25, 2022
2 parents 937ca98 + 2de39b8 commit d8afc95
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
25 changes: 25 additions & 0 deletions manticore/native/cpu/x86.py
Original file line number Diff line number Diff line change
Expand Up @@ -5803,6 +5803,31 @@ def PSUBB(cpu, dest, src):
result.append((a - b) & 0xFF)
dest.write(Operators.CONCAT(8 * len(result), *result))

@instruction
def PSUBQ(cpu, dest, src):
"""
PSUBQ: Packed add with quadruple words
Packed subtract with quad
Subtracts the second operand (source operand) from the first operand (destination operand) and stores
the result in the destination operand. When packed quadword operands are used, a SIMD subtract is performed.
When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around
and the low 64 bits are written to the destination element (that is, the carry is ignored).
:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.
"""
result = []
value_a = dest.read()
value_b = src.read()

for i in reversed(range(0, dest.size, 64)):
a = Operators.EXTRACT(value_a, i, 64)
b = Operators.EXTRACT(value_b, i, 64)
result.append(a - b)
dest.write(Operators.CONCAT(dest.size, *result))

@instruction
def POR(cpu, dest, src):
"""
Expand Down
64 changes: 64 additions & 0 deletions tests/native/test_x86.py
Original file line number Diff line number Diff line change
Expand Up @@ -22314,6 +22314,70 @@ def test_PSUBB_2(self):
self.assertEqual(cpu.XMM0, 0)
self.assertEqual(cpu.EBP, 4294948352)

def test_PSUBQ_1(self):
mem = Memory32()
cpu = I386Cpu(mem)
mem.mmap(0x08065000, 0x1000, "rwx")

# psubq xmm0, xmm1
mem[0x08065000] = "\x66"
mem[0x08065001] = "\x0f"
mem[0x08065002] = "\xfb"
mem[0x08065003] = "\xc1"
cpu.EIP = 0x8065000
cpu.XMM0 = 0xDEADBEEFCAFEBABE0000000000000000
cpu.XMM1 = 0xDEADBEEFCAFEBABE0000000000000001
cpu.execute()

self.assertEqual(mem[0x8065000], "\x66")
self.assertEqual(mem[0x8065001], "\x0f")
self.assertEqual(mem[0x8065002], "\xfb")
self.assertEqual(mem[0x8065003], "\xc1")
self.assertEqual(cpu.EIP, 0x08065004)
self.assertEqual(cpu.XMM0, 0x0000000000000000FFFFFFFFFFFFFFFF)
self.assertEqual(cpu.XMM1, 0xDEADBEEFCAFEBABE0000000000000001)

def test_PSUBQ_2(self):
mem = Memory32()
cpu = I386Cpu(mem)
mem.mmap(0x08065000, 0x1000, "rwx")
mem.mmap(0xFFFFB000, 0x1000, "rwx")

# psubq xmm0, xmmword ptr [ebp]
mem.write(0x08065000, "f\x0f\xfbE\x00")
mem.write(0xFFFFB600, (0xDEADBEEFCAFEBABE0000000000000001).to_bytes(16, "little"))

cpu.EIP = 0x08065000
cpu.XMM0 = 0xDEADBEEFCAFEBABE0000000000000000
cpu.EBP = 0xFFFFB600
cpu.execute()

self.assertEqual(mem[0x08065000:0x08065005], [b"f", b"\x0f", b"\xfb", b"E", b"\x00"])
self.assertEqual(
mem[0xFFFFB600:0xFFFFB610],
[
b"\x01",
b"\x00",
b"\x00",
b"\x00",
b"\x00",
b"\x00",
b"\x00",
b"\x00",
b"\xBE",
b"\xBA",
b"\xFE",
b"\xCA",
b"\xEF",
b"\xBE",
b"\xAD",
b"\xDE",
],
)
self.assertEqual(cpu.EIP, 0x08065005)
self.assertEqual(cpu.XMM0, 0x0000000000000000FFFFFFFFFFFFFFFF)
self.assertEqual(cpu.EBP, 0xFFFFB600)

def test_PTEST_1(self):
"""Instruction PTEST_1
Groups: sse41
Expand Down

0 comments on commit d8afc95

Please sign in to comment.