Skip to content

Commit

Permalink
Add instructionAPI/Operand.h
Browse files Browse the repository at this point in the history
  • Loading branch information
hainest committed Apr 3, 2024
1 parent 7ee9e70 commit 32f629b
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 105 deletions.
141 changes: 72 additions & 69 deletions docs/instructionAPI/public/Operand.h.rst
Original file line number Diff line number Diff line change
@@ -1,111 +1,114 @@
.. _`sec:Operand.h`:

Operand.h
=========
#########

.. cpp:namespace:: Dyninst::InstructionAPI

Operand Class
-------------
.. cpp:class:: Operand

An Operand object contains an AST built from RegisterAST and Immediate
leaves, and information about whether the Operand is read, written, or
both. This allows us to determine which of the registers that appear in
the Operand are read and which are written, as well as whether any
memory accesses are reads, writes, or both. An Operand, given full
knowledge of the values of the leaves of the AST, and knowledge of the
logic associated with the tree’s internal nodes, can determine the
result of any computations that are encoded in it. It will rarely be the
case that an Instruction is built with its Operands’ state fully
specified. This mechanism is instead intended to allow a user to fill in
knowledge about the state of the processor at the time the Instruction
is executed.
**An AST containing read/write information**

.. cpp:type:: boost::shared_ptr<Operand> Ptr

.. cpp:function:: explicit Operand(Expression::Ptr val = {}, bool read = false, \
bool written = false, bool implicit = false, \
bool trueP = false, bool falseP = false)

.. code-block:: cpp
Creates an operand from an expression and flags describing its read/write properties.

Operand(Expression::Ptr val, bool read, bool written)
.. csv-table::

``read``, the operand is read from
``written``, the operand is written to
``implicit``, the operand is implicitly read from or written to
``trueP``, the operand is predicated on ``true``
``falseP``, the operand is predicated on ``false``

Create an operand from an ``Expression`` and flags describing whether
the ValueComputation is read, written, or both.
.. Note:: ``trueP`` and ``falseP`` are only used for GPU instructions with predicates.

``val`` is a reference-counted pointer to the ``Expression`` that will
be contained in the ``Operand`` being constructed. ``read`` is true if
this operand is read. ``written`` is true if this operand is written.
.. cpp:function:: void getReadSet(std::set<RegisterAST::Ptr> & regsRead) const

.. code-block:: cpp
Appends the set of registers read by this operand into ``regsRead``.

void getReadSet(std::set<RegisterAST::Ptr> & regsRead) const
See :ref:`sec:instruction-read-write-sets` for a more detailed discussion.

Get the registers read by this operand. The registers read are inserted
into ``regsRead``.
.. cpp:function:: void getWriteSet(std::set<RegisterAST::Ptr> & regsWritten) const

.. code-block:: cpp
Appends the set of registers written by this operand into ``regsWritten``.

void getWriteSet(std::set<RegisterAST::Ptr> & regsWritten) const
See :ref:`sec:instruction-read-write-sets` for a more detailed discussion.

Get the registers written by this operand. The registers written are
inserted into ``regsWritten``.
.. cpp:function:: bool isRead() const

.. code-block:: cpp
Checks if this operand is read from.

bool isRead() const
.. cpp:function:: bool isWritten() const

Returns ``true`` if this operand is read.
Checks if this operand is written to.

.. code-block:: cpp
bool isWritten() const
.. cpp:function:: bool isRead(Expression::Ptr candidate) const

Returns ``true`` if this operand is written.
Checks if ``candidate`` is read by this operand.

.. code-block:: cpp
bool isRead(Expression::Ptr candidate) const
.. cpp:function:: bool isWritten(Expression::Ptr candidate) const

Returns ``true`` if ``candidate`` is read by this operand.
Checks if ``candidate`` is written to by this operand.

.. code-block:: cpp
.. cpp:function:: bool isImplicit() const

bool isWritten(Expression::Ptr candidate) const
Checks if this operand is implicitly read from or written to.

Returns ``true`` if ``candidate`` is written to by this operand.
.. cpp:function:: void setImplicit(bool i)

.. code-block:: cpp
Sets if this operand is implicitly read from or written to.

bool readsMemory() const
.. cpp:function:: bool isTruePredicate() const

Returns ``true`` if this operand reads memory.
Checks if this operand is predicated on ``true``.

.. code-block:: cpp
.. cpp:function:: bool isFalsePredicate() const

bool writesMemory() const
Checks if this operand is predicated on ``false``.

Returns ``true`` if this operand writes memory.
.. cpp:function:: bool readsMemory() const

.. code-block:: cpp
void addEffectiveReadAddresses(std::set<Expression::Ptr> & memAccessors) const
Checks if this operand reads memory.

If ``Operand`` is a memory read operand, insert the ``ExpressionPtr``
representing the address being read into ``memAccessors``.
.. cpp:function:: bool writesMemory() const

.. code-block:: cpp
Checks if this operand writes memory.

void addEffectiveWriteAddresses(std::set<Expression::Ptr> & memAccessors) const
.. cpp:function:: void addEffectiveReadAddresses(std::set<Expression::Ptr> & memAccessors) const

If ``Operand`` is a memory write operand, insert the ``ExpressionPtr``
representing the address being written into ``memAccessors``.
Appends the effective addresses being read from into ``memAccessors``, if this operand reads memory.

.. code-block:: cpp
.. cpp:function:: void addEffectiveWriteAddresses(std::set<Expression::Ptr> & memAccessors) const

std::string format(Architecture arch, Address addr = 0) const
Appends the effective addresses being written to into ``memAccessors``, if this operand writes memory.

Return a printable string representation of the operand. The ``arch``
parameter must be supplied, as operands do not record their
architectures. The optional ``addr`` parameter specifies the value of
the program counter.
.. cpp:function:: std::string format(Architecture arch, Address addr = 0) const

.. code-block:: cpp
Returns a string representation of this expression using the :cpp:class:`ArchSpecificFormatter`
associated with ``arch``. The optional ``addr`` parameter specifies the value of
the program counter.

Expression::Ptr getValue() const
.. cpp:function:: Expression::Ptr getValue() const

The ``getValue`` method returns an ``ExpressionPtr`` to the AST
contained by the operand.
Returns the the :cpp:class:`AST` of the operand.

.. _`sec:operand-notes`:

Notes
=====

This classes can be used to determine which of the registers that appear in
the Operand are read and which are written, as well as whether any
memory accesses are reads, writes, or both. An Operand, given full
knowledge of the values of the leaves of the AST, and knowledge of the
logic associated with the tree’s internal nodes, can determine the
result of any computations that are encoded in it. It will rarely be the
case that an :cpp:class:``Instruction`` is built with its Operands’ state fully
specified. This mechanism is instead intended to allow users to fill in
knowledge about the state of the processor at the time the instruction
is executed.
44 changes: 8 additions & 36 deletions instructionAPI/h/Operand.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,44 +44,24 @@ namespace Dyninst
{
namespace InstructionAPI
{
/// An %Operand object contains an AST built from %RegisterAST and %Immediate leaves,
/// and information about whether the %Operand
/// is read, written, or both. This allows us to determine which of the registers
/// that appear in the %Operand are read and which are written, as well as whether
/// any memory accesses are reads, writes, or both.
/// An %Operand, given full knowledge of the values of the leaves of the AST, and knowledge of
/// the logic associated with the tree's internal nodes, can determine the
/// result of any computations that are encoded in it. It will rarely be the case
/// that an %Instruction is built with its %Operands' state fully specified. This mechanism is
/// instead intended to allow a user to fill in knowledge about the state of the processor
/// at the time the %Instruction is executed.

class Operand
{
public:
typedef boost::shared_ptr<Operand> Ptr;
/// \brief Create an operand from a %Expression and flags describing whether the %ValueComputation
/// is read, written or both.
/// \param val Reference-counted pointer to the %Expression that will be contained in the %Operand being constructed
/// \param read True if this operand is read
/// \param written True if this operand is written
// An instruction can be true predicated, false predicated, or not predicated at all

explicit Operand(Expression::Ptr val = {}, bool read = false, bool written = false, bool implicit = false,
bool trueP = false, bool falseP = false) noexcept :
op_value(val), m_isRead(read), m_isWritten(written), m_isImplicit(implicit), m_isTruePredicate(trueP), m_isFalsePredicate(falseP) {}

/// \brief Get the registers read by this operand
/// \param regsRead Has the registers read inserted into it
INSTRUCTION_EXPORT void getReadSet(std::set<RegisterAST::Ptr>& regsRead) const;
/// \brief Get the registers written by this operand
/// \param regsWritten Has the registers written inserted into it

INSTRUCTION_EXPORT void getWriteSet(std::set<RegisterAST::Ptr>& regsWritten) const;

INSTRUCTION_EXPORT RegisterAST::Ptr getPredicate() const;

/// Returns true if this operand is read

INSTRUCTION_EXPORT bool isRead(Expression::Ptr candidate) const;
/// Returns true if this operand is written

INSTRUCTION_EXPORT bool isWritten(Expression::Ptr candidate) const;

INSTRUCTION_EXPORT bool isRead() const { return m_isRead; }
Expand All @@ -93,23 +73,16 @@ namespace Dyninst
INSTRUCTION_EXPORT bool isTruePredicate() const { return m_isTruePredicate; }
INSTRUCTION_EXPORT bool isFalsePredicate() const { return m_isFalsePredicate; }

/// Returns true if this operand reads memory
INSTRUCTION_EXPORT bool readsMemory() const;
/// Returns true if this operand writes memory

INSTRUCTION_EXPORT bool writesMemory() const;
/// \brief Inserts the effective addresses read by this operand into memAccessors
/// \param memAccessors If this is a memory read operand, insert the \c %Expression::Ptr representing
/// the address being read into \c memAccessors.

INSTRUCTION_EXPORT void addEffectiveReadAddresses(std::set<Expression::Ptr>& memAccessors) const;
/// \brief Inserts the effective addresses written by this operand into memAccessors
/// \param memAccessors If this is a memory write operand, insert the \c %Expression::Ptr representing
/// the address being written into \c memAccessors.

INSTRUCTION_EXPORT void addEffectiveWriteAddresses(std::set<Expression::Ptr>& memAccessors) const;
/// \brief Return a printable string representation of the operand.
/// \return The operand in a disassembly format

INSTRUCTION_EXPORT std::string format(Architecture arch, Address addr = 0) const;

/// The \c getValue method returns an %Expression::Ptr to the AST contained by the operand.
INSTRUCTION_EXPORT Expression::Ptr getValue() const;

private:
Expand All @@ -118,7 +91,6 @@ namespace Dyninst
bool m_isWritten{};
bool m_isImplicit{};

// Used for GPU instructions with predicates
bool m_isTruePredicate{};
bool m_isFalsePredicate{};
};
Expand Down

0 comments on commit 32f629b

Please sign in to comment.