timing_expr.cc revision 10259:ebb376f73dd2
1/*
2 * Copyright (c) 2013-2014 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andrew Bardsley
38 */
39
40#include "base/intmath.hh"
41#include "cpu/timing_expr.hh"
42
43TimingExprEvalContext::TimingExprEvalContext (StaticInstPtr inst_,
44    ThreadContext *thread_,
45    TimingExprLet *let_) :
46    inst(inst_), thread(thread_), let(let_)
47{
48    /* Reserve space to hold the results of evaluating the
49     *  let expressions */
50    if (let) {
51        unsigned int num_defns = let->defns.size();
52
53        results.resize(num_defns, 0);
54        resultAvailable.resize(num_defns, false);
55    }
56}
57
58uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
59{
60    return context.inst->srcRegIdx(index);
61}
62
63uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)
64{
65    return context.thread->readIntReg(reg->eval(context));
66}
67
68uint64_t TimingExprLet::eval(TimingExprEvalContext &context)
69{
70    TimingExprEvalContext new_context(context.inst,
71        context.thread, this);
72
73    return expr->eval(new_context);
74}
75
76uint64_t TimingExprRef::eval(TimingExprEvalContext &context)
77{
78    /* Lookup the result, evaluating if necessary.  @todo, this
79     *  should have more error checking */
80    if (!context.resultAvailable[index]) {
81        context.results[index] = context.let->defns[index]->eval(context);
82        context.resultAvailable[index] = true;
83    }
84
85    return context.results[index];
86}
87
88uint64_t TimingExprUn::eval(TimingExprEvalContext &context)
89{
90    uint64_t arg_value = arg->eval(context);
91    uint64_t ret = 0;
92
93    switch (op) {
94      case Enums::timingExprSizeInBits:
95        if (arg_value == 0)
96            ret = 0;
97        else
98            ret = ceilLog2(arg_value);
99        break;
100      case Enums::timingExprNot:
101        ret = arg_value != 0;
102        break;
103      case Enums::timingExprInvert:
104        ret = ~arg_value;
105        break;
106      case Enums::timingExprSignExtend32To64:
107        ret = static_cast<int64_t>(
108            static_cast<int32_t>(arg_value));
109        break;
110      case Enums::timingExprAbs:
111        if (static_cast<int64_t>(arg_value) < 0)
112            ret = -arg_value;
113        else
114            ret = arg_value;
115        break;
116      default:
117        break;
118    }
119
120    return ret;
121}
122
123uint64_t TimingExprBin::eval(TimingExprEvalContext &context)
124{
125    uint64_t left_value = left->eval(context);
126    uint64_t right_value = right->eval(context);
127    uint64_t ret = 0;
128
129    switch (op) {
130      case Enums::timingExprAdd:
131          ret = left_value + right_value;
132          break;
133      case Enums::timingExprSub:
134          ret = left_value - right_value;
135          break;
136      case Enums::timingExprUMul:
137          ret = left_value * right_value;
138          break;
139      case Enums::timingExprUDiv:
140          if (right_value != 0) {
141              ret = left_value / right_value;
142          }
143          break;
144      case Enums::timingExprUCeilDiv:
145          if (right_value != 0) {
146              ret = (left_value + (right_value - 1)) / right_value;
147          }
148          break;
149      case Enums::timingExprSMul:
150          ret = static_cast<int64_t>(left_value) *
151              static_cast<int64_t>(right_value);
152          break;
153      case Enums::timingExprSDiv:
154          if (right_value != 0) {
155              ret = static_cast<int64_t>(left_value) /
156                  static_cast<int64_t>(right_value);
157          }
158          break;
159      case Enums::timingExprEqual:
160          ret = left_value == right_value;
161          break;
162      case Enums::timingExprNotEqual:
163          ret = left_value != right_value;
164          break;
165      case Enums::timingExprULessThan:
166          ret = left_value < right_value;
167          break;
168      case Enums::timingExprUGreaterThan:
169          ret = left_value > right_value;
170          break;
171      case Enums::timingExprSLessThan:
172          ret = static_cast<int64_t>(left_value) <
173              static_cast<int64_t>(right_value);
174          break;
175      case Enums::timingExprSGreaterThan:
176          ret = static_cast<int64_t>(left_value) >
177              static_cast<int64_t>(right_value);
178          break;
179      case Enums::timingExprAnd:
180          ret = (left_value != 0) && (right_value != 0);
181          break;
182      case Enums::timingExprOr:
183          ret = (left_value != 0) || (right_value != 0);
184          break;
185      default:
186          break;
187    }
188
189    return ret;
190}
191
192uint64_t TimingExprIf::eval(TimingExprEvalContext &context)
193{
194    uint64_t cond_value = cond->eval(context);
195
196    if (cond_value != 0)
197        return trueExpr->eval(context);
198    else
199        return falseExpr->eval(context);
200}
201
202TimingExprLiteral *
203TimingExprLiteralParams::create()
204{
205    return new TimingExprLiteral(this);
206}
207
208TimingExprSrcReg *
209TimingExprSrcRegParams::create()
210{
211    return new TimingExprSrcReg(this);
212}
213
214TimingExprReadIntReg *
215TimingExprReadIntRegParams::create()
216{
217    return new TimingExprReadIntReg(this);
218}
219
220TimingExprLet *
221TimingExprLetParams::create()
222{
223    return new TimingExprLet(this);
224}
225
226TimingExprRef *
227TimingExprRefParams::create()
228{
229    return new TimingExprRef(this);
230}
231
232TimingExprUn *
233TimingExprUnParams::create()
234{
235    return new TimingExprUn(this);
236}
237
238TimingExprBin *
239TimingExprBinParams::create()
240{
241    return new TimingExprBin(this);
242}
243
244TimingExprIf *
245TimingExprIfParams::create()
246{
247    return new TimingExprIf(this);
248}
249