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 "cpu/timing_expr.hh" 41 42#include "base/intmath.hh" 43 44TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_, 45 ThreadContext *thread_, 46 TimingExprLet *let_) : 47 inst(inst_), thread(thread_), let(let_) 48{ 49 /* Reserve space to hold the results of evaluating the 50 * let expressions */ 51 if (let) { 52 unsigned int num_defns = let->defns.size(); 53 54 results.resize(num_defns, 0); 55 resultAvailable.resize(num_defns, false); 56 } 57} 58 59uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context) 60{ 61 return context.inst->srcRegIdx(index).index(); 62} 63 64uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context) 65{ 66 return context.thread->readIntReg(reg->eval(context)); 67} 68 69uint64_t TimingExprLet::eval(TimingExprEvalContext &context) 70{ 71 TimingExprEvalContext new_context(context.inst, 72 context.thread, this); 73 74 return expr->eval(new_context); 75} 76 77uint64_t TimingExprRef::eval(TimingExprEvalContext &context) 78{ 79 /* Lookup the result, evaluating if necessary. @todo, this 80 * should have more error checking */ 81 if (!context.resultAvailable[index]) { 82 context.results[index] = context.let->defns[index]->eval(context); 83 context.resultAvailable[index] = true; 84 } 85 86 return context.results[index]; 87} 88 89uint64_t TimingExprUn::eval(TimingExprEvalContext &context) 90{ 91 uint64_t arg_value = arg->eval(context); 92 uint64_t ret = 0; 93 94 switch (op) { 95 case Enums::timingExprSizeInBits: 96 if (arg_value == 0) 97 ret = 0; 98 else 99 ret = ceilLog2(arg_value); 100 break; 101 case Enums::timingExprNot: 102 ret = arg_value != 0; 103 break; 104 case Enums::timingExprInvert: 105 ret = ~arg_value; 106 break; 107 case Enums::timingExprSignExtend32To64: 108 ret = static_cast<int64_t>( 109 static_cast<int32_t>(arg_value)); 110 break; 111 case Enums::timingExprAbs: 112 if (static_cast<int64_t>(arg_value) < 0) 113 ret = -arg_value; 114 else 115 ret = arg_value; 116 break; 117 default: 118 break; 119 } 120 121 return ret; 122} 123 124uint64_t TimingExprBin::eval(TimingExprEvalContext &context) 125{ 126 uint64_t left_value = left->eval(context); 127 uint64_t right_value = right->eval(context); 128 uint64_t ret = 0; 129 130 switch (op) { 131 case Enums::timingExprAdd: 132 ret = left_value + right_value; 133 break; 134 case Enums::timingExprSub: 135 ret = left_value - right_value; 136 break; 137 case Enums::timingExprUMul: 138 ret = left_value * right_value; 139 break; 140 case Enums::timingExprUDiv: 141 if (right_value != 0) { 142 ret = left_value / right_value; 143 } 144 break; 145 case Enums::timingExprUCeilDiv: 146 if (right_value != 0) { 147 ret = (left_value + (right_value - 1)) / right_value; 148 } 149 break; 150 case Enums::timingExprSMul: 151 ret = static_cast<int64_t>(left_value) * 152 static_cast<int64_t>(right_value); 153 break; 154 case Enums::timingExprSDiv: 155 if (right_value != 0) { 156 ret = static_cast<int64_t>(left_value) / 157 static_cast<int64_t>(right_value); 158 } 159 break; 160 case Enums::timingExprEqual: 161 ret = left_value == right_value; 162 break; 163 case Enums::timingExprNotEqual: 164 ret = left_value != right_value; 165 break; 166 case Enums::timingExprULessThan: 167 ret = left_value < right_value; 168 break; 169 case Enums::timingExprUGreaterThan: 170 ret = left_value > right_value; 171 break; 172 case Enums::timingExprSLessThan: 173 ret = static_cast<int64_t>(left_value) < 174 static_cast<int64_t>(right_value); 175 break; 176 case Enums::timingExprSGreaterThan: 177 ret = static_cast<int64_t>(left_value) > 178 static_cast<int64_t>(right_value); 179 break; 180 case Enums::timingExprAnd: 181 ret = (left_value != 0) && (right_value != 0); 182 break; 183 case Enums::timingExprOr: 184 ret = (left_value != 0) || (right_value != 0); 185 break; 186 default: 187 break; 188 } 189 190 return ret; 191} 192 193uint64_t TimingExprIf::eval(TimingExprEvalContext &context) 194{ 195 uint64_t cond_value = cond->eval(context); 196 197 if (cond_value != 0) 198 return trueExpr->eval(context); 199 else 200 return falseExpr->eval(context); 201} 202 203TimingExprLiteral * 204TimingExprLiteralParams::create() 205{ 206 return new TimingExprLiteral(this); 207} 208 209TimingExprSrcReg * 210TimingExprSrcRegParams::create() 211{ 212 return new TimingExprSrcReg(this); 213} 214 215TimingExprReadIntReg * 216TimingExprReadIntRegParams::create() 217{ 218 return new TimingExprReadIntReg(this); 219} 220 221TimingExprLet * 222TimingExprLetParams::create() 223{ 224 return new TimingExprLet(this); 225} 226 227TimingExprRef * 228TimingExprRefParams::create() 229{ 230 return new TimingExprRef(this); 231} 232 233TimingExprUn * 234TimingExprUnParams::create() 235{ 236 return new TimingExprUn(this); 237} 238 239TimingExprBin * 240TimingExprBinParams::create() 241{ 242 return new TimingExprBin(this); 243} 244 245TimingExprIf * 246TimingExprIfParams::create() 247{ 248 return new TimingExprIf(this); 249} 250