110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved. 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4011793Sbrandon.potter@amd.com#include "cpu/timing_expr.hh" 4111793Sbrandon.potter@amd.com 4210259SAndrew.Bardsley@arm.com#include "base/intmath.hh" 4310259SAndrew.Bardsley@arm.com 4410417Sandreas.hansson@arm.comTimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_, 4510259SAndrew.Bardsley@arm.com ThreadContext *thread_, 4610259SAndrew.Bardsley@arm.com TimingExprLet *let_) : 4710259SAndrew.Bardsley@arm.com inst(inst_), thread(thread_), let(let_) 4810259SAndrew.Bardsley@arm.com{ 4910259SAndrew.Bardsley@arm.com /* Reserve space to hold the results of evaluating the 5010259SAndrew.Bardsley@arm.com * let expressions */ 5110259SAndrew.Bardsley@arm.com if (let) { 5210259SAndrew.Bardsley@arm.com unsigned int num_defns = let->defns.size(); 5310259SAndrew.Bardsley@arm.com 5410259SAndrew.Bardsley@arm.com results.resize(num_defns, 0); 5510259SAndrew.Bardsley@arm.com resultAvailable.resize(num_defns, false); 5610259SAndrew.Bardsley@arm.com } 5710259SAndrew.Bardsley@arm.com} 5810259SAndrew.Bardsley@arm.com 5910259SAndrew.Bardsley@arm.comuint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context) 6010259SAndrew.Bardsley@arm.com{ 6112106SRekai.GonzalezAlberquilla@arm.com return context.inst->srcRegIdx(index).index(); 6210259SAndrew.Bardsley@arm.com} 6310259SAndrew.Bardsley@arm.com 6410259SAndrew.Bardsley@arm.comuint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context) 6510259SAndrew.Bardsley@arm.com{ 6610259SAndrew.Bardsley@arm.com return context.thread->readIntReg(reg->eval(context)); 6710259SAndrew.Bardsley@arm.com} 6810259SAndrew.Bardsley@arm.com 6910259SAndrew.Bardsley@arm.comuint64_t TimingExprLet::eval(TimingExprEvalContext &context) 7010259SAndrew.Bardsley@arm.com{ 7110259SAndrew.Bardsley@arm.com TimingExprEvalContext new_context(context.inst, 7210259SAndrew.Bardsley@arm.com context.thread, this); 7310259SAndrew.Bardsley@arm.com 7410259SAndrew.Bardsley@arm.com return expr->eval(new_context); 7510259SAndrew.Bardsley@arm.com} 7610259SAndrew.Bardsley@arm.com 7710259SAndrew.Bardsley@arm.comuint64_t TimingExprRef::eval(TimingExprEvalContext &context) 7810259SAndrew.Bardsley@arm.com{ 7910259SAndrew.Bardsley@arm.com /* Lookup the result, evaluating if necessary. @todo, this 8010259SAndrew.Bardsley@arm.com * should have more error checking */ 8110259SAndrew.Bardsley@arm.com if (!context.resultAvailable[index]) { 8210259SAndrew.Bardsley@arm.com context.results[index] = context.let->defns[index]->eval(context); 8310259SAndrew.Bardsley@arm.com context.resultAvailable[index] = true; 8410259SAndrew.Bardsley@arm.com } 8510259SAndrew.Bardsley@arm.com 8610259SAndrew.Bardsley@arm.com return context.results[index]; 8710259SAndrew.Bardsley@arm.com} 8810259SAndrew.Bardsley@arm.com 8910259SAndrew.Bardsley@arm.comuint64_t TimingExprUn::eval(TimingExprEvalContext &context) 9010259SAndrew.Bardsley@arm.com{ 9110259SAndrew.Bardsley@arm.com uint64_t arg_value = arg->eval(context); 9210259SAndrew.Bardsley@arm.com uint64_t ret = 0; 9310259SAndrew.Bardsley@arm.com 9410259SAndrew.Bardsley@arm.com switch (op) { 9510259SAndrew.Bardsley@arm.com case Enums::timingExprSizeInBits: 9610259SAndrew.Bardsley@arm.com if (arg_value == 0) 9710259SAndrew.Bardsley@arm.com ret = 0; 9810259SAndrew.Bardsley@arm.com else 9910259SAndrew.Bardsley@arm.com ret = ceilLog2(arg_value); 10010259SAndrew.Bardsley@arm.com break; 10110259SAndrew.Bardsley@arm.com case Enums::timingExprNot: 10210259SAndrew.Bardsley@arm.com ret = arg_value != 0; 10310259SAndrew.Bardsley@arm.com break; 10410259SAndrew.Bardsley@arm.com case Enums::timingExprInvert: 10510259SAndrew.Bardsley@arm.com ret = ~arg_value; 10610259SAndrew.Bardsley@arm.com break; 10710259SAndrew.Bardsley@arm.com case Enums::timingExprSignExtend32To64: 10810259SAndrew.Bardsley@arm.com ret = static_cast<int64_t>( 10910259SAndrew.Bardsley@arm.com static_cast<int32_t>(arg_value)); 11010259SAndrew.Bardsley@arm.com break; 11110259SAndrew.Bardsley@arm.com case Enums::timingExprAbs: 11210259SAndrew.Bardsley@arm.com if (static_cast<int64_t>(arg_value) < 0) 11310259SAndrew.Bardsley@arm.com ret = -arg_value; 11410259SAndrew.Bardsley@arm.com else 11510259SAndrew.Bardsley@arm.com ret = arg_value; 11610259SAndrew.Bardsley@arm.com break; 11710259SAndrew.Bardsley@arm.com default: 11810259SAndrew.Bardsley@arm.com break; 11910259SAndrew.Bardsley@arm.com } 12010259SAndrew.Bardsley@arm.com 12110259SAndrew.Bardsley@arm.com return ret; 12210259SAndrew.Bardsley@arm.com} 12310259SAndrew.Bardsley@arm.com 12410259SAndrew.Bardsley@arm.comuint64_t TimingExprBin::eval(TimingExprEvalContext &context) 12510259SAndrew.Bardsley@arm.com{ 12610259SAndrew.Bardsley@arm.com uint64_t left_value = left->eval(context); 12710259SAndrew.Bardsley@arm.com uint64_t right_value = right->eval(context); 12810259SAndrew.Bardsley@arm.com uint64_t ret = 0; 12910259SAndrew.Bardsley@arm.com 13010259SAndrew.Bardsley@arm.com switch (op) { 13110259SAndrew.Bardsley@arm.com case Enums::timingExprAdd: 13210259SAndrew.Bardsley@arm.com ret = left_value + right_value; 13310259SAndrew.Bardsley@arm.com break; 13410259SAndrew.Bardsley@arm.com case Enums::timingExprSub: 13510259SAndrew.Bardsley@arm.com ret = left_value - right_value; 13610259SAndrew.Bardsley@arm.com break; 13710259SAndrew.Bardsley@arm.com case Enums::timingExprUMul: 13810259SAndrew.Bardsley@arm.com ret = left_value * right_value; 13910259SAndrew.Bardsley@arm.com break; 14010259SAndrew.Bardsley@arm.com case Enums::timingExprUDiv: 14110259SAndrew.Bardsley@arm.com if (right_value != 0) { 14210259SAndrew.Bardsley@arm.com ret = left_value / right_value; 14310259SAndrew.Bardsley@arm.com } 14410259SAndrew.Bardsley@arm.com break; 14510259SAndrew.Bardsley@arm.com case Enums::timingExprUCeilDiv: 14610259SAndrew.Bardsley@arm.com if (right_value != 0) { 14710259SAndrew.Bardsley@arm.com ret = (left_value + (right_value - 1)) / right_value; 14810259SAndrew.Bardsley@arm.com } 14910259SAndrew.Bardsley@arm.com break; 15010259SAndrew.Bardsley@arm.com case Enums::timingExprSMul: 15110259SAndrew.Bardsley@arm.com ret = static_cast<int64_t>(left_value) * 15210259SAndrew.Bardsley@arm.com static_cast<int64_t>(right_value); 15310259SAndrew.Bardsley@arm.com break; 15410259SAndrew.Bardsley@arm.com case Enums::timingExprSDiv: 15510259SAndrew.Bardsley@arm.com if (right_value != 0) { 15610259SAndrew.Bardsley@arm.com ret = static_cast<int64_t>(left_value) / 15710259SAndrew.Bardsley@arm.com static_cast<int64_t>(right_value); 15810259SAndrew.Bardsley@arm.com } 15910259SAndrew.Bardsley@arm.com break; 16010259SAndrew.Bardsley@arm.com case Enums::timingExprEqual: 16110259SAndrew.Bardsley@arm.com ret = left_value == right_value; 16210259SAndrew.Bardsley@arm.com break; 16310259SAndrew.Bardsley@arm.com case Enums::timingExprNotEqual: 16410259SAndrew.Bardsley@arm.com ret = left_value != right_value; 16510259SAndrew.Bardsley@arm.com break; 16610259SAndrew.Bardsley@arm.com case Enums::timingExprULessThan: 16710259SAndrew.Bardsley@arm.com ret = left_value < right_value; 16810259SAndrew.Bardsley@arm.com break; 16910259SAndrew.Bardsley@arm.com case Enums::timingExprUGreaterThan: 17010259SAndrew.Bardsley@arm.com ret = left_value > right_value; 17110259SAndrew.Bardsley@arm.com break; 17210259SAndrew.Bardsley@arm.com case Enums::timingExprSLessThan: 17310259SAndrew.Bardsley@arm.com ret = static_cast<int64_t>(left_value) < 17410259SAndrew.Bardsley@arm.com static_cast<int64_t>(right_value); 17510259SAndrew.Bardsley@arm.com break; 17610259SAndrew.Bardsley@arm.com case Enums::timingExprSGreaterThan: 17710259SAndrew.Bardsley@arm.com ret = static_cast<int64_t>(left_value) > 17810259SAndrew.Bardsley@arm.com static_cast<int64_t>(right_value); 17910259SAndrew.Bardsley@arm.com break; 18010259SAndrew.Bardsley@arm.com case Enums::timingExprAnd: 18110259SAndrew.Bardsley@arm.com ret = (left_value != 0) && (right_value != 0); 18210259SAndrew.Bardsley@arm.com break; 18310259SAndrew.Bardsley@arm.com case Enums::timingExprOr: 18410259SAndrew.Bardsley@arm.com ret = (left_value != 0) || (right_value != 0); 18510259SAndrew.Bardsley@arm.com break; 18610259SAndrew.Bardsley@arm.com default: 18710259SAndrew.Bardsley@arm.com break; 18810259SAndrew.Bardsley@arm.com } 18910259SAndrew.Bardsley@arm.com 19010259SAndrew.Bardsley@arm.com return ret; 19110259SAndrew.Bardsley@arm.com} 19210259SAndrew.Bardsley@arm.com 19310259SAndrew.Bardsley@arm.comuint64_t TimingExprIf::eval(TimingExprEvalContext &context) 19410259SAndrew.Bardsley@arm.com{ 19510259SAndrew.Bardsley@arm.com uint64_t cond_value = cond->eval(context); 19610259SAndrew.Bardsley@arm.com 19710259SAndrew.Bardsley@arm.com if (cond_value != 0) 19810259SAndrew.Bardsley@arm.com return trueExpr->eval(context); 19910259SAndrew.Bardsley@arm.com else 20010259SAndrew.Bardsley@arm.com return falseExpr->eval(context); 20110259SAndrew.Bardsley@arm.com} 20210259SAndrew.Bardsley@arm.com 20310259SAndrew.Bardsley@arm.comTimingExprLiteral * 20410259SAndrew.Bardsley@arm.comTimingExprLiteralParams::create() 20510259SAndrew.Bardsley@arm.com{ 20610259SAndrew.Bardsley@arm.com return new TimingExprLiteral(this); 20710259SAndrew.Bardsley@arm.com} 20810259SAndrew.Bardsley@arm.com 20910259SAndrew.Bardsley@arm.comTimingExprSrcReg * 21010259SAndrew.Bardsley@arm.comTimingExprSrcRegParams::create() 21110259SAndrew.Bardsley@arm.com{ 21210259SAndrew.Bardsley@arm.com return new TimingExprSrcReg(this); 21310259SAndrew.Bardsley@arm.com} 21410259SAndrew.Bardsley@arm.com 21510259SAndrew.Bardsley@arm.comTimingExprReadIntReg * 21610259SAndrew.Bardsley@arm.comTimingExprReadIntRegParams::create() 21710259SAndrew.Bardsley@arm.com{ 21810259SAndrew.Bardsley@arm.com return new TimingExprReadIntReg(this); 21910259SAndrew.Bardsley@arm.com} 22010259SAndrew.Bardsley@arm.com 22110259SAndrew.Bardsley@arm.comTimingExprLet * 22210259SAndrew.Bardsley@arm.comTimingExprLetParams::create() 22310259SAndrew.Bardsley@arm.com{ 22410259SAndrew.Bardsley@arm.com return new TimingExprLet(this); 22510259SAndrew.Bardsley@arm.com} 22610259SAndrew.Bardsley@arm.com 22710259SAndrew.Bardsley@arm.comTimingExprRef * 22810259SAndrew.Bardsley@arm.comTimingExprRefParams::create() 22910259SAndrew.Bardsley@arm.com{ 23010259SAndrew.Bardsley@arm.com return new TimingExprRef(this); 23110259SAndrew.Bardsley@arm.com} 23210259SAndrew.Bardsley@arm.com 23310259SAndrew.Bardsley@arm.comTimingExprUn * 23410259SAndrew.Bardsley@arm.comTimingExprUnParams::create() 23510259SAndrew.Bardsley@arm.com{ 23610259SAndrew.Bardsley@arm.com return new TimingExprUn(this); 23710259SAndrew.Bardsley@arm.com} 23810259SAndrew.Bardsley@arm.com 23910259SAndrew.Bardsley@arm.comTimingExprBin * 24010259SAndrew.Bardsley@arm.comTimingExprBinParams::create() 24110259SAndrew.Bardsley@arm.com{ 24210259SAndrew.Bardsley@arm.com return new TimingExprBin(this); 24310259SAndrew.Bardsley@arm.com} 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.comTimingExprIf * 24610259SAndrew.Bardsley@arm.comTimingExprIfParams::create() 24710259SAndrew.Bardsley@arm.com{ 24810259SAndrew.Bardsley@arm.com return new TimingExprIf(this); 24910259SAndrew.Bardsley@arm.com} 250