Warning: This blog post is not going to be useful to you unless you are trying to understand the pcmpistri
instruction. It is not self-contained. See Section 4.1 of the Intel Manual for reference.
A while back I wrote a blog post about how bad the
documentation is for the x86 instruction pcmpistri
. I wrote the previous blog post on pcmpistri
as I was trying to implement the behavior of
pcmpistri
only for the control byte 0xc
.
Now I’m trying to add a more general implementation to BAP. This
involves reading and understanding the documentation, specifically focusing on the various aggregation modes that effectively control the behavior of pcmpistri
. The problem
with the documentation is that it’s a literal translation of what the
processor is doing, i.e., a description of the circuit that implements
the instruction, rather than an abstract description of what’s going
on. A more abstract view is helpful when not implementing
hardware. In this blog post, I give pseudocode that computes the intres1
intermediate result variable for each of
the four aggregation modes.
I hope these are helpful in understanding the various aggregation modes. Even though each one of these cases is simple, it was difficult for me to get here from the documentation. However, you should take these pseudocode algorithms with a grain of salt. I will update them as I find any problems, but I haven’t tested these yet. Each pseudocode listing is a direct translation from my notes of the Intel manual. I have also yet to formally demonstrate that these are equivalent to the specifications in the documentation. I hope to write a blogpost about how you can use BAP’s verification condition algorithms to show such an equivalence.
Notation
r
is the register operand, rm
is the register or memory operand,
and u
is the upper bound on the number of elements inside each
operand (i.e., 16 for byte-size elements, and 8 for word-size).
Pseudocode
EqualAny
EqualAny sets intres1[j]
if rm[j]
is a character listed in r
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Ranges
Ranges sets intres1[j]
if r[i] <= rm[j] <= r[i+1]
for some even
index i
. r
is a list of ranges.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
EqualEach
EqualEach sets intres1[j]
iff rm[j] = r[j]
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
EqualOrdered
EqualOrdered sets intres1[j]
iff the substring in r
is present at
rm[j]
.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Musings
Ideally we’d be able to compute each intres1[j]
independently, but
it doesn’t seem to be the case. break
can be thought of as using
implied state, i.e., whether we executed break
or not.