Update copyright to LGPL on all files
[dyninst.git] / instructionAPI / src / BinaryFunction.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "../h/BinaryFunction.h"
33 #include "Result.h"
34 #include "Visitor.h"
35
36 namespace Dyninst
37 {
38   namespace InstructionAPI
39   {
40
41     Result doAddition(Result arg1, Result arg2, Result_Type ResultT)
42     {
43       switch(ResultT)
44       {
45       case s8:
46         return Result(ResultT, arg1.convert<Result_type2type<s8>::type >() + arg2.convert<
47                       Result_type2type<s8>::type >());
48       case u8:
49         return Result(ResultT, arg1.convert<Result_type2type<u8>::type >() + arg2.convert<
50                       Result_type2type<u8>::type >());
51       case s16:
52         return Result(ResultT, arg1.convert<Result_type2type<s16>::type >() + arg2.convert<
53                       Result_type2type<s16>::type >());
54       case u16:
55         return Result(ResultT, arg1.convert<Result_type2type<u16>::type >() + arg2.convert<
56                       Result_type2type<u16>::type >());
57       case s32:
58         return Result(ResultT, arg1.convert<Result_type2type<s32>::type >() + arg2.convert<
59                       Result_type2type<s32>::type >());
60       case u32:
61         return Result(ResultT, arg1.convert<Result_type2type<u32>::type >() + arg2.convert<
62                       Result_type2type<u32>::type >());
63       case s48:
64         return Result(ResultT, arg1.convert<Result_type2type<s48>::type >() + arg2.convert<
65                       Result_type2type<s48>::type >());
66       case u48:
67         return Result(ResultT, arg1.convert<Result_type2type<u48>::type >() + arg2.convert<
68                       Result_type2type<u48>::type >());
69       case s64:
70         return Result(ResultT, arg1.convert<Result_type2type<s64>::type >() + arg2.convert<
71                       Result_type2type<s64>::type >());
72       case u64:
73         return Result(ResultT, arg1.convert<Result_type2type<u64>::type >() + arg2.convert<
74                       Result_type2type<u64>::type >());
75       case sp_float:
76         return Result(ResultT, arg1.convert<Result_type2type<sp_float>::type >() + arg2.convert<
77                       Result_type2type<sp_float>::type >());
78       case dp_float:
79         return Result(ResultT, arg1.convert<Result_type2type<dp_float>::type >() + arg2.convert<
80                       Result_type2type<dp_float>::type >());
81       case bit_flag:
82         return Result(ResultT, arg1.convert<Result_type2type<bit_flag>::type >() + arg2.convert<
83                       Result_type2type<bit_flag>::type >());
84       default:
85         // m512 and dbl128 not implemented yet...
86         return Result(ResultT);
87       }
88     }
89     
90     Result doMultiplication(Result arg1, Result arg2, Result_Type ResultT)
91     {
92       switch(ResultT)
93       {
94       case s8:
95         return Result(ResultT, arg1.convert<Result_type2type<s8>::type >() * arg2.convert<
96                       Result_type2type<s8>::type >());
97       case u8:
98         return Result(ResultT, arg1.convert<Result_type2type<u8>::type >() * arg2.convert<
99                       Result_type2type<u8>::type >());
100       case s16:
101         return Result(ResultT, arg1.convert<Result_type2type<s16>::type >() * arg2.convert<
102                       Result_type2type<s16>::type >());
103       case u16:
104         return Result(ResultT, arg1.convert<Result_type2type<u16>::type >() * arg2.convert<
105                       Result_type2type<u16>::type >());
106       case s32:
107         return Result(ResultT, arg1.convert<Result_type2type<s32>::type >() * arg2.convert<
108                       Result_type2type<s32>::type >());
109       case u32:
110         return Result(ResultT, arg1.convert<Result_type2type<u32>::type >() * arg2.convert<
111                       Result_type2type<u32>::type >());
112       case s48:
113         return Result(ResultT, arg1.convert<Result_type2type<s48>::type >() * arg2.convert<
114                       Result_type2type<s48>::type >());
115       case u48:
116         return Result(ResultT, arg1.convert<Result_type2type<u48>::type >() * arg2.convert<
117                       Result_type2type<u48>::type >());
118       case s64:
119         return Result(ResultT, arg1.convert<Result_type2type<s64>::type >() * arg2.convert<
120                       Result_type2type<s64>::type >());
121       case u64:
122         return Result(ResultT, arg1.convert<Result_type2type<u64>::type >() * arg2.convert<
123                       Result_type2type<u64>::type >());
124       case sp_float:
125         return Result(ResultT, arg1.convert<Result_type2type<sp_float>::type >() * arg2.convert<
126                       Result_type2type<sp_float>::type >());
127       case dp_float:
128         return Result(ResultT, arg1.convert<Result_type2type<dp_float>::type >() * arg2.convert<
129                       Result_type2type<dp_float>::type >());
130       case bit_flag:
131         return Result(ResultT, arg1.convert<Result_type2type<bit_flag>::type >() * arg2.convert<
132                       Result_type2type<bit_flag>::type >());
133       default:
134         // m512 and dbl128 not implemented yet...
135         return Result(ResultT);
136       }
137     }
138     Result operator+(const Result& arg1, const Result& arg2)
139     {
140       Result_Type ResultT = arg1.type > arg2.type ? arg1.type : arg2.type;
141       if(!arg1.defined || !arg2.defined)
142       {
143         return Result(ResultT);
144       }
145       return doAddition(arg1, arg2, ResultT);
146
147     }    
148     Result operator*(const Result& arg1, const Result& arg2)
149     {
150       Result_Type ResultT = arg1.type > arg2.type ? arg1.type : arg2.type;
151       if(!arg1.defined || !arg2.defined)
152       {
153         return Result(ResultT);
154       }
155       return doMultiplication(arg1, arg2, ResultT);
156
157     }    
158     const Result& BinaryFunction::eval() const
159     {
160         Expression::Ptr arg1 = dyn_detail::boost::dynamic_pointer_cast<Expression>(m_arg1);
161         Expression::Ptr arg2 = dyn_detail::boost::dynamic_pointer_cast<Expression>(m_arg2);
162         if(arg1 && arg2)
163         {
164             Result x = arg1->eval();
165             Result y = arg2->eval();
166             Result oracularResult = Expression::eval();
167             if(x.defined && y.defined && !oracularResult.defined)
168             {
169                 Result result = (*m_funcPtr)(x, y);
170                 const_cast<BinaryFunction*>(this)->setValue(result);
171             }
172         }
173         return Expression::eval();
174     }  
175     bool BinaryFunction::bind(Expression* expr, const Result& value)
176     {
177         bool retVal = false;
178         if(Expression::bind(expr, value))
179         {
180             return true;
181         }
182         retVal = retVal | m_arg1->bind(expr, value);
183         retVal = retVal | m_arg2->bind(expr, value);
184                 if(retVal) clearValue();
185         return retVal;
186     }
187
188     void BinaryFunction::apply(Visitor* v)
189     {
190         m_arg1->apply(v);
191         m_arg2->apply(v);
192         v->visit(this);
193     }
194     bool BinaryFunction::isAdd() const
195     {
196         return typeid(*m_funcPtr) == typeid(addResult);
197     }
198     bool BinaryFunction::isMultiply() const
199     {
200         return typeid(*m_funcPtr) == typeid(multResult);
201
202     }
203   };
204 };
205