2 * Copyright (c) 2013-2014 ARM Limited
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.
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.
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.
38 #include "cpu/timing_expr.hh"
40 #include "base/intmath.hh"
42 TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr
&inst_
,
43 ThreadContext
*thread_
,
44 TimingExprLet
*let_
) :
45 inst(inst_
), thread(thread_
), let(let_
)
47 /* Reserve space to hold the results of evaluating the
50 unsigned int num_defns
= let
->defns
.size();
52 results
.resize(num_defns
, 0);
53 resultAvailable
.resize(num_defns
, false);
57 uint64_t TimingExprSrcReg::eval(TimingExprEvalContext
&context
)
59 return context
.inst
->srcRegIdx(index
).index();
62 uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext
&context
)
64 return context
.thread
->readIntReg(reg
->eval(context
));
67 uint64_t TimingExprLet::eval(TimingExprEvalContext
&context
)
69 TimingExprEvalContext
new_context(context
.inst
,
70 context
.thread
, this);
72 return expr
->eval(new_context
);
75 uint64_t TimingExprRef::eval(TimingExprEvalContext
&context
)
77 /* Lookup the result, evaluating if necessary. @todo, this
78 * should have more error checking */
79 if (!context
.resultAvailable
[index
]) {
80 context
.results
[index
] = context
.let
->defns
[index
]->eval(context
);
81 context
.resultAvailable
[index
] = true;
84 return context
.results
[index
];
87 uint64_t TimingExprUn::eval(TimingExprEvalContext
&context
)
89 uint64_t arg_value
= arg
->eval(context
);
93 case Enums::timingExprSizeInBits
:
97 ret
= ceilLog2(arg_value
);
99 case Enums::timingExprNot
:
100 ret
= arg_value
!= 0;
102 case Enums::timingExprInvert
:
105 case Enums::timingExprSignExtend32To64
:
106 ret
= static_cast<int64_t>(
107 static_cast<int32_t>(arg_value
));
109 case Enums::timingExprAbs
:
110 if (static_cast<int64_t>(arg_value
) < 0)
122 uint64_t TimingExprBin::eval(TimingExprEvalContext
&context
)
124 uint64_t left_value
= left
->eval(context
);
125 uint64_t right_value
= right
->eval(context
);
129 case Enums::timingExprAdd
:
130 ret
= left_value
+ right_value
;
132 case Enums::timingExprSub
:
133 ret
= left_value
- right_value
;
135 case Enums::timingExprUMul
:
136 ret
= left_value
* right_value
;
138 case Enums::timingExprUDiv
:
139 if (right_value
!= 0) {
140 ret
= left_value
/ right_value
;
143 case Enums::timingExprUCeilDiv
:
144 if (right_value
!= 0) {
145 ret
= (left_value
+ (right_value
- 1)) / right_value
;
148 case Enums::timingExprSMul
:
149 ret
= static_cast<int64_t>(left_value
) *
150 static_cast<int64_t>(right_value
);
152 case Enums::timingExprSDiv
:
153 if (right_value
!= 0) {
154 ret
= static_cast<int64_t>(left_value
) /
155 static_cast<int64_t>(right_value
);
158 case Enums::timingExprEqual
:
159 ret
= left_value
== right_value
;
161 case Enums::timingExprNotEqual
:
162 ret
= left_value
!= right_value
;
164 case Enums::timingExprULessThan
:
165 ret
= left_value
< right_value
;
167 case Enums::timingExprUGreaterThan
:
168 ret
= left_value
> right_value
;
170 case Enums::timingExprSLessThan
:
171 ret
= static_cast<int64_t>(left_value
) <
172 static_cast<int64_t>(right_value
);
174 case Enums::timingExprSGreaterThan
:
175 ret
= static_cast<int64_t>(left_value
) >
176 static_cast<int64_t>(right_value
);
178 case Enums::timingExprAnd
:
179 ret
= (left_value
!= 0) && (right_value
!= 0);
181 case Enums::timingExprOr
:
182 ret
= (left_value
!= 0) || (right_value
!= 0);
191 uint64_t TimingExprIf::eval(TimingExprEvalContext
&context
)
193 uint64_t cond_value
= cond
->eval(context
);
196 return trueExpr
->eval(context
);
198 return falseExpr
->eval(context
);
202 TimingExprLiteralParams::create()
204 return new TimingExprLiteral(this);
208 TimingExprSrcRegParams::create()
210 return new TimingExprSrcReg(this);
213 TimingExprReadIntReg
*
214 TimingExprReadIntRegParams::create()
216 return new TimingExprReadIntReg(this);
220 TimingExprLetParams::create()
222 return new TimingExprLet(this);
226 TimingExprRefParams::create()
228 return new TimingExprRef(this);
232 TimingExprUnParams::create()
234 return new TimingExprUn(this);
238 TimingExprBinParams::create()
240 return new TimingExprBin(this);
244 TimingExprIfParams::create()
246 return new TimingExprIf(this);