/*
 * Copyright (c) 2013-2014 ARM Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Andrew Bardsley
 */

/*
 * These classes define an expression language over uint64_t with only
 * a few operators.  This can be used to form expressions for the extra
 * delay required in variable execution time instructions.
 *
 * Expressions, in evaluation, will have access to the ThreadContext and
 * a StaticInst.
 */

#ifndef __CPU_TIMING_EXPR_HH__
#define __CPU_TIMING_EXPR_HH__

#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "enums/TimingExprOp.hh"
#include "params/TimingExpr.hh"
#include "params/TimingExprBin.hh"
#include "params/TimingExprIf.hh"
#include "params/TimingExprLet.hh"
#include "params/TimingExprLiteral.hh"
#include "params/TimingExprReadIntReg.hh"
#include "params/TimingExprRef.hh"
#include "params/TimingExprSrcReg.hh"
#include "params/TimingExprUn.hh"
#include "sim/sim_object.hh"

/** These classes are just the C++ counterparts for those in Expr.py and
 *  are, therefore, documented there */

class TimingExprLet;

/** Object to gather the visible context for evaluation */
class TimingExprEvalContext
{
  public:
    /** Special visible context */
    const StaticInstPtr &inst;
    ThreadContext *thread;

    /** Context visible as sub expressions.  results will hold the results
     *  of (lazily) evaluating let's expressions.  resultAvailable elements
     *  are true when a result has actually been evaluated */
    TimingExprLet *let;
    std::vector<uint64_t> results;
    std::vector<bool > resultAvailable;

    TimingExprEvalContext(const StaticInstPtr &inst_,
        ThreadContext *thread_, TimingExprLet *let_);
};

class TimingExpr : public SimObject
{
  public:
    TimingExpr(const TimingExprParams *params) :
        SimObject(params)
    { }

    virtual uint64_t eval(TimingExprEvalContext &context) = 0;
};

class TimingExprLiteral : public TimingExpr
{
  public:
    uint64_t value;

    TimingExprLiteral(const TimingExprLiteralParams *params) :
        TimingExpr(params),
        value(params->value)
    { }

    uint64_t eval(TimingExprEvalContext &context) { return value; }
};

class TimingExprSrcReg : public TimingExpr
{
  public:
    unsigned int index;

    TimingExprSrcReg(const TimingExprSrcRegParams *params) :
        TimingExpr(params),
        index(params->index)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprReadIntReg : public TimingExpr
{
  public:
    TimingExpr *reg;

    TimingExprReadIntReg(const TimingExprReadIntRegParams *params) :
        TimingExpr(params),
        reg(params->reg)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprLet : public TimingExpr
{
  public:
    std::vector<TimingExpr *> defns;
    TimingExpr *expr;

    TimingExprLet(const TimingExprLetParams *params) :
        TimingExpr(params),
        defns(params->defns),
        expr(params->expr)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprRef : public TimingExpr
{
  public:
    unsigned int index;

    TimingExprRef(const TimingExprRefParams *params) :
        TimingExpr(params),
        index(params->index)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprUn : public TimingExpr
{
  public:
    Enums::TimingExprOp op;
    TimingExpr *arg;

    TimingExprUn(const TimingExprUnParams *params) :
        TimingExpr(params),
        op(params->op),
        arg(params->arg)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprBin : public TimingExpr
{
  public:
    Enums::TimingExprOp op;
    TimingExpr *left;
    TimingExpr *right;

    TimingExprBin(const TimingExprBinParams *params) :
        TimingExpr(params),
        op(params->op),
        left(params->left),
        right(params->right)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

class TimingExprIf : public TimingExpr
{
  public:
    TimingExpr *cond;
    TimingExpr *trueExpr;
    TimingExpr *falseExpr;

    TimingExprIf(const TimingExprIfParams *params) :
        TimingExpr(params),
        cond(params->cond),
        trueExpr(params->trueExpr),
        falseExpr(params->falseExpr)
    { }

    uint64_t eval(TimingExprEvalContext &context);
};

#endif
