/*
 * 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.
 */

#include "cpu/timing_expr.hh"

#include "base/intmath.hh"

namespace gem5
{

TimingExprEvalContext::TimingExprEvalContext(const StaticInstPtr &inst_,
    ThreadContext *thread_,
    TimingExprLet *let_) :
    inst(inst_), thread(thread_), let(let_)
{
    /* Reserve space to hold the results of evaluating the
     *  let expressions */
    if (let) {
        unsigned int num_defns = let->defns.size();

        results.resize(num_defns, 0);
        resultAvailable.resize(num_defns, false);
    }
}

uint64_t TimingExprSrcReg::eval(TimingExprEvalContext &context)
{
    return context.inst->srcRegIdx(index).index();
}

uint64_t TimingExprReadIntReg::eval(TimingExprEvalContext &context)
{
    return context.thread->readIntReg(reg->eval(context));
}

uint64_t TimingExprLet::eval(TimingExprEvalContext &context)
{
    TimingExprEvalContext new_context(context.inst,
        context.thread, this);

    return expr->eval(new_context);
}

uint64_t TimingExprRef::eval(TimingExprEvalContext &context)
{
    /* Lookup the result, evaluating if necessary.  @todo, this
     *  should have more error checking */
    if (!context.resultAvailable[index]) {
        context.results[index] = context.let->defns[index]->eval(context);
        context.resultAvailable[index] = true;
    }

    return context.results[index];
}

uint64_t TimingExprUn::eval(TimingExprEvalContext &context)
{
    uint64_t arg_value = arg->eval(context);
    uint64_t ret = 0;

    switch (op) {
      case enums::timingExprSizeInBits:
        if (arg_value == 0)
            ret = 0;
        else
            ret = ceilLog2(arg_value);
        break;
      case enums::timingExprNot:
        ret = arg_value != 0;
        break;
      case enums::timingExprInvert:
        ret = ~arg_value;
        break;
      case enums::timingExprSignExtend32To64:
        ret = static_cast<int64_t>(
            static_cast<int32_t>(arg_value));
        break;
      case enums::timingExprAbs:
        if (static_cast<int64_t>(arg_value) < 0)
            ret = -arg_value;
        else
            ret = arg_value;
        break;
      default:
        break;
    }

    return ret;
}

uint64_t TimingExprBin::eval(TimingExprEvalContext &context)
{
    uint64_t left_value = left->eval(context);
    uint64_t right_value = right->eval(context);
    uint64_t ret = 0;

    switch (op) {
      case enums::timingExprAdd:
          ret = left_value + right_value;
          break;
      case enums::timingExprSub:
          ret = left_value - right_value;
          break;
      case enums::timingExprUMul:
          ret = left_value * right_value;
          break;
      case enums::timingExprUDiv:
          if (right_value != 0) {
              ret = left_value / right_value;
          }
          break;
      case enums::timingExprUCeilDiv:
          if (right_value != 0) {
              ret = (left_value + (right_value - 1)) / right_value;
          }
          break;
      case enums::timingExprSMul:
          ret = static_cast<int64_t>(left_value) *
              static_cast<int64_t>(right_value);
          break;
      case enums::timingExprSDiv:
          if (right_value != 0) {
              ret = static_cast<int64_t>(left_value) /
                  static_cast<int64_t>(right_value);
          }
          break;
      case enums::timingExprEqual:
          ret = left_value == right_value;
          break;
      case enums::timingExprNotEqual:
          ret = left_value != right_value;
          break;
      case enums::timingExprULessThan:
          ret = left_value < right_value;
          break;
      case enums::timingExprUGreaterThan:
          ret = left_value > right_value;
          break;
      case enums::timingExprSLessThan:
          ret = static_cast<int64_t>(left_value) <
              static_cast<int64_t>(right_value);
          break;
      case enums::timingExprSGreaterThan:
          ret = static_cast<int64_t>(left_value) >
              static_cast<int64_t>(right_value);
          break;
      case enums::timingExprAnd:
          ret = (left_value != 0) && (right_value != 0);
          break;
      case enums::timingExprOr:
          ret = (left_value != 0) || (right_value != 0);
          break;
      default:
          break;
    }

    return ret;
}

uint64_t TimingExprIf::eval(TimingExprEvalContext &context)
{
    uint64_t cond_value = cond->eval(context);

    if (cond_value != 0)
        return trueExpr->eval(context);
    else
        return falseExpr->eval(context);
}

} // namespace gem5
