Calculation of immediate operand in logical immediate instructions was done wrong...
[dyninst.git] / instructionAPI / h / Operand.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #if !defined(OPERAND_H)
32 #define OPERAND_H
33
34 #include "Expression.h"
35 #include "Register.h"
36 #include <set>
37 #include <string>
38
39 #include "util.h"
40
41 namespace Dyninst
42 {
43   namespace InstructionAPI
44   {
45
46     /// An %Operand object contains an AST built from %RegisterAST and %Immediate leaves,
47     /// and information about whether the %Operand
48     /// is read, written, or both. This allows us to determine which of the registers
49     /// that appear in the %Operand are read and which are written, as well as whether
50     /// any memory accesses are reads, writes, or both.
51     /// An %Operand, given full knowledge of the values of the leaves of the AST, and knowledge of
52     /// the logic associated with the tree's internal nodes, can determine the
53     /// result of any computations that are encoded in it.  It will rarely be the case
54     /// that an %Instruction is built with its %Operands' state fully specified.  This mechanism is
55     /// instead intended to allow a user to fill in knowledge about the state of the processor
56     /// at the time the %Instruction is executed.
57     
58     class Operand
59     {
60     public:
61         typedef boost::shared_ptr<Operand> Ptr;
62     Operand() : m_isRead(false), m_isWritten(false) {}
63       /// \brief Create an operand from a %Expression and flags describing whether the %ValueComputation
64       /// is read, written or both.
65       /// \param val Reference-counted pointer to the %Expression that will be contained in the %Operand being constructed
66       /// \param read True if this operand is read
67       /// \param written True if this operand is written
68       Operand(Expression::Ptr val, bool read, bool written) : op_value(val), m_isRead(read), m_isWritten(written) 
69       {
70       }
71       virtual ~Operand()
72       {
73         op_value.reset();
74       }
75       Operand(const Operand& o) :
76       op_value(o.op_value), m_isRead(o.m_isRead), m_isWritten(o.m_isWritten)
77       {
78       }
79       const Operand& operator=(const Operand& rhs)
80       {
81         op_value = rhs.op_value;
82         m_isRead = rhs.m_isRead;
83         m_isWritten = rhs.m_isWritten;
84         return *this;
85       }
86       
87
88       /// \brief Get the registers read by this operand
89       /// \param regsRead Has the registers read inserted into it
90       INSTRUCTION_EXPORT void getReadSet(std::set<RegisterAST::Ptr>& regsRead) const;
91       /// \brief Get the registers written by this operand
92       /// \param regsWritten Has the registers written  inserted into it
93       INSTRUCTION_EXPORT void getWriteSet(std::set<RegisterAST::Ptr>& regsWritten) const;
94
95       /// Returns true if this operand is read
96       INSTRUCTION_EXPORT bool isRead(Expression::Ptr candidate) const;
97       /// Returns true if this operand is written
98       INSTRUCTION_EXPORT bool isWritten(Expression::Ptr candidate) const;
99
100       INSTRUCTION_EXPORT bool isRead() const {
101         return m_isRead; }
102       INSTRUCTION_EXPORT bool isWritten() const {
103         return m_isWritten; }
104       
105       /// Returns true if this operand reads memory
106       INSTRUCTION_EXPORT bool readsMemory() const;
107       /// Returns true if this operand writes memory
108       INSTRUCTION_EXPORT bool writesMemory() const;
109       /// \brief Inserts the effective addresses read by this operand into memAccessors
110       /// \param memAccessors If this is a memory read operand, insert the \c %Expression::Ptr representing
111       /// the address being read into \c memAccessors.
112       INSTRUCTION_EXPORT void addEffectiveReadAddresses(std::set<Expression::Ptr>& memAccessors) const;
113       /// \brief Inserts the effective addresses written by this operand into memAccessors
114       /// \param memAccessors If this is a memory write operand, insert the \c %Expression::Ptr representing
115       /// the address being written into \c memAccessors.
116       INSTRUCTION_EXPORT void addEffectiveWriteAddresses(std::set<Expression::Ptr>& memAccessors) const;
117       /// \brief Return a printable string representation of the operand
118       /// \return The operand in a disassembly format
119       INSTRUCTION_EXPORT std::string format(Architecture arch, Address addr = 0) const;
120       /// The \c getValue method returns an %Expression::Ptr to the AST contained by the operand.
121       INSTRUCTION_EXPORT Expression::Ptr getValue() const;
122       
123     private:
124       Expression::Ptr op_value;
125       bool m_isRead;
126       bool m_isWritten;
127     };
128   };
129 };
130
131
132
133
134 #endif //!defined(OPERAND_H)