<commit_before>#include "gtest/gtest.h"

#include <smt>
#include <cstdint>

TEST(SmtFunctionalTest, DeMorgan)
{
  const smt::ExprPtr<smt::Bool> x = smt::any<smt::Bool>("x");
  const smt::ExprPtr<smt::Bool> y = smt::any<smt::Bool>("y");
  const smt::ExprPtr<smt::Bool> lhs = !(x && y);
  const smt::ExprPtr<smt::Bool> rhs = !x || !y;

  smt::Z3Solver z3_solver;
  z3_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, SeparateDecls)
{
  const smt::Decl<smt::Bool> x_decl("x");
  const smt::Decl<smt::Bool> y_decl("y");
  const smt::ExprPtr<smt::Bool> x = smt::constant(x_decl);
  const smt::ExprPtr<smt::Bool> y = smt::constant(y_decl);
  const smt::ExprPtr<smt::Bool> lhs = !(x && y);
  const smt::ExprPtr<smt::Bool> rhs = !x || !y;

  smt::Z3Solver z3_solver;
  z3_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, BitVectors)
{
  const smt::ExprPtr<unsigned long> x = smt::any<unsigned long>("x");
  const smt::ExprPtr<unsigned long> y = smt::any<unsigned long>("y");
  const smt::ExprPtr<unsigned long> z = smt::any<unsigned long>("z");
  const smt::ExprPtr<smt::Bool> equality = (x == y) && ((x & ~y) == z);

  smt::Z3Solver z3_solver;
  z3_solver.add(equality);

  z3_solver.push();
  {
    z3_solver.add(z != 0L);
    EXPECT_EQ(smt::unsat, z3_solver.check());
  }
  z3_solver.pop();
  z3_solver.push();
  {
    z3_solver.add(z == 0L);
    EXPECT_EQ(smt::sat, z3_solver.check());
  }
  z3_solver.pop();

  smt::MsatSolver msat_solver;
  msat_solver.add(equality);

  msat_solver.push();
  {
    msat_solver.add(z != 0L);
    EXPECT_EQ(smt::unsat, msat_solver.check());
  }
  msat_solver.pop();
  msat_solver.push();
  {
    msat_solver.add(z == 0L);
    EXPECT_EQ(smt::sat, msat_solver.check());
  }
  msat_solver.pop();
}

TEST(SmtFunctionalTest, UnsafeExpr)
{
  const smt::UnsafeDecl unsafe_decl("x", smt::bv_sort(true, sizeof(int) * 8));
  const smt::UnsafeExprPtr x = smt::constant(unsafe_decl);
  const smt::UnsafeExprPtr equality = (x & smt::literal<int>(3)) != x;

  smt::Z3Solver z3_solver;
  z3_solver.unsafe_add(equality);
  EXPECT_EQ(smt::sat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.unsafe_add(equality);
  EXPECT_EQ(smt::sat, msat_solver.check());
}

TEST(SmtFunctionalTest, Reflection)
{
  constexpr size_t bv_int_size = sizeof(int) * 8;
  EXPECT_EQ(smt::bv_sort(true, bv_int_size), smt::literal<int>(3)->sort());

  const smt::ExprPtr<uint32_t> x = smt::any<uint32_t>("x");
  EXPECT_TRUE(x->sort().is_bv());
  EXPECT_FALSE(x->sort().is_signed());
  EXPECT_EQ(32, x->sort().bv_size());

  typedef smt::Func<smt::Int, smt::Real, char> SomeFunc;
  const smt::ExprPtr<SomeFunc> f = smt::any<SomeFunc>("f");
  EXPECT_TRUE(f->sort().is_func());
  EXPECT_EQ(3, f->sort().sorts_size());
  EXPECT_TRUE(f->sort().sorts(0).is_int());
  EXPECT_TRUE(f->sort().sorts(1).is_real());
  EXPECT_TRUE(f->sort().sorts(2).is_bv());
  EXPECT_EQ(sizeof(char) * 8, f->sort().sorts(2).bv_size());
}

TEST(SmtFunctionalTest, Array)
{
  typedef smt::Array<smt::Int, char> IntToCharArray;
  const smt::Decl<IntToCharArray> array_decl("array");

  smt::ExprPtr<IntToCharArray> array, new_array;
  smt::ExprPtr<smt::Int> index;
  smt::ExprPtr<char> value;

  array = smt::constant(array_decl);
  index = smt::any<smt::Int>("index");
  value = smt::literal<char>('p');

  new_array = smt::store(array, index, value);

  smt::Z3Solver z3_solver;
  z3_solver.add(smt::select(new_array, index) != value);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(smt::select(new_array, index) != value);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, Function)
{
  const smt::Decl<smt::Func<smt::Int, smt::Int>> func_decl("f");
  const smt::ExprPtr<smt::Int> x = smt::any<smt::Int>("x");
  const smt::ExprPtr<smt::Bool> formula =
    smt::apply(func_decl, 3) == 7 && x == smt::apply(func_decl, 3);

  smt::Z3Solver z3_solver;
  z3_solver.add(formula && x != smt::literal<smt::Int>(7));
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(formula && x != 7);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}
<commit_msg>Show how to access global solver objects<commit_after>#include "gtest/gtest.h"

#include <smt>
#include <cstdint>

// Only access global solver through a function that has a static local object!
smt::Solver& global_solver()
{
  static smt::MsatSolver s_msat_solver;
  return s_msat_solver;
}

TEST(SmtFunctionalTest, Reset)
{
  global_solver().reset();
}

TEST(SmtFunctionalTest, DeMorgan)
{
  const smt::ExprPtr<smt::Bool> x = smt::any<smt::Bool>("x");
  const smt::ExprPtr<smt::Bool> y = smt::any<smt::Bool>("y");
  const smt::ExprPtr<smt::Bool> lhs = !(x && y);
  const smt::ExprPtr<smt::Bool> rhs = !x || !y;

  smt::Z3Solver z3_solver;
  z3_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, SeparateDecls)
{
  const smt::Decl<smt::Bool> x_decl("x");
  const smt::Decl<smt::Bool> y_decl("y");
  const smt::ExprPtr<smt::Bool> x = smt::constant(x_decl);
  const smt::ExprPtr<smt::Bool> y = smt::constant(y_decl);
  const smt::ExprPtr<smt::Bool> lhs = !(x && y);
  const smt::ExprPtr<smt::Bool> rhs = !x || !y;

  smt::Z3Solver z3_solver;
  z3_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(lhs != rhs);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, BitVectors)
{
  const smt::ExprPtr<unsigned long> x = smt::any<unsigned long>("x");
  const smt::ExprPtr<unsigned long> y = smt::any<unsigned long>("y");
  const smt::ExprPtr<unsigned long> z = smt::any<unsigned long>("z");
  const smt::ExprPtr<smt::Bool> equality = (x == y) && ((x & ~y) == z);

  smt::Z3Solver z3_solver;
  z3_solver.add(equality);

  z3_solver.push();
  {
    z3_solver.add(z != 0L);
    EXPECT_EQ(smt::unsat, z3_solver.check());
  }
  z3_solver.pop();
  z3_solver.push();
  {
    z3_solver.add(z == 0L);
    EXPECT_EQ(smt::sat, z3_solver.check());
  }
  z3_solver.pop();

  smt::MsatSolver msat_solver;
  msat_solver.add(equality);

  msat_solver.push();
  {
    msat_solver.add(z != 0L);
    EXPECT_EQ(smt::unsat, msat_solver.check());
  }
  msat_solver.pop();
  msat_solver.push();
  {
    msat_solver.add(z == 0L);
    EXPECT_EQ(smt::sat, msat_solver.check());
  }
  msat_solver.pop();
}

TEST(SmtFunctionalTest, UnsafeExpr)
{
  const smt::UnsafeDecl unsafe_decl("x", smt::bv_sort(true, sizeof(int) * 8));
  const smt::UnsafeExprPtr x = smt::constant(unsafe_decl);
  const smt::UnsafeExprPtr equality = (x & smt::literal<int>(3)) != x;

  smt::Z3Solver z3_solver;
  z3_solver.unsafe_add(equality);
  EXPECT_EQ(smt::sat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.unsafe_add(equality);
  EXPECT_EQ(smt::sat, msat_solver.check());
}

TEST(SmtFunctionalTest, Reflection)
{
  constexpr size_t bv_int_size = sizeof(int) * 8;
  EXPECT_EQ(smt::bv_sort(true, bv_int_size), smt::literal<int>(3)->sort());

  const smt::ExprPtr<uint32_t> x = smt::any<uint32_t>("x");
  EXPECT_TRUE(x->sort().is_bv());
  EXPECT_FALSE(x->sort().is_signed());
  EXPECT_EQ(32, x->sort().bv_size());

  typedef smt::Func<smt::Int, smt::Real, char> SomeFunc;
  const smt::ExprPtr<SomeFunc> f = smt::any<SomeFunc>("f");
  EXPECT_TRUE(f->sort().is_func());
  EXPECT_EQ(3, f->sort().sorts_size());
  EXPECT_TRUE(f->sort().sorts(0).is_int());
  EXPECT_TRUE(f->sort().sorts(1).is_real());
  EXPECT_TRUE(f->sort().sorts(2).is_bv());
  EXPECT_EQ(sizeof(char) * 8, f->sort().sorts(2).bv_size());
}

TEST(SmtFunctionalTest, Array)
{
  typedef smt::Array<smt::Int, char> IntToCharArray;
  const smt::Decl<IntToCharArray> array_decl("array");

  smt::ExprPtr<IntToCharArray> array, new_array;
  smt::ExprPtr<smt::Int> index;
  smt::ExprPtr<char> value;

  array = smt::constant(array_decl);
  index = smt::any<smt::Int>("index");
  value = smt::literal<char>('p');

  new_array = smt::store(array, index, value);

  smt::Z3Solver z3_solver;
  z3_solver.add(smt::select(new_array, index) != value);
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(smt::select(new_array, index) != value);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}

TEST(SmtFunctionalTest, Function)
{
  const smt::Decl<smt::Func<smt::Int, smt::Int>> func_decl("f");
  const smt::ExprPtr<smt::Int> x = smt::any<smt::Int>("x");
  const smt::ExprPtr<smt::Bool> formula =
    smt::apply(func_decl, 3) == 7 && x == smt::apply(func_decl, 3);

  smt::Z3Solver z3_solver;
  z3_solver.add(formula && x != smt::literal<smt::Int>(7));
  EXPECT_EQ(smt::unsat, z3_solver.check());

  smt::MsatSolver msat_solver;
  msat_solver.add(formula && x != 7);
  EXPECT_EQ(smt::unsat, msat_solver.check());
}
<|endoftext|>


<commit_before><commit_msg>rtl_cipher_decode doesn't like 0 len data<commit_after><|endoftext|>


<commit_before>#include <ostream>
#include <gtest/gtest.h>
#include "FromEvent.hpp"

using namespace org_pqrs_KeyRemap4MacBook;

Params_KeyboardEventCallBack::auto_ptr down_return(
  Params_KeyboardEventCallBack::alloc(
    EventType::DOWN,
    Flags(0),
    KeyCode::RETURN,
    CharCode(0),
    CharSet(0),
    OrigCharCode(0),
    OrigCharSet(0),
    KeyboardType(0),
    false));

Params_KeyboardEventCallBack::auto_ptr up_return(
  Params_KeyboardEventCallBack::alloc(
    EventType::UP,
    Flags(0),
    KeyCode::RETURN,
    CharCode(0),
    CharSet(0),
    OrigCharCode(0),
    OrigCharSet(0),
    KeyboardType(0),
    false));

Params_KeyboardEventCallBack::auto_ptr down_shift(
  Params_KeyboardEventCallBack::alloc(
    EventType::MODIFY,
    Flags(ModifierFlag::SHIFT_L),
    KeyCode::SHIFT_L,
    CharCode(0),
    CharSet(0),
    OrigCharCode(0),
    OrigCharSet(0),
    KeyboardType(0),
    false));

Params_KeyboardEventCallBack::auto_ptr up_shift(
  Params_KeyboardEventCallBack::alloc(
    EventType::MODIFY,
    Flags(0),
    KeyCode::SHIFT_L,
    CharCode(0),
    CharSet(0),
    OrigCharCode(0),
    OrigCharSet(0),
    KeyboardType(0),
    false));

TEST(Generic, getModifierFlag) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(ModifierFlag::SHIFT_L, fe.getModifierFlag());
  }
  {
    FromEvent fe(ConsumerKeyCode::VOLUME_MUTE);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
  {
    FromEvent fe(PointingButton::LEFT);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
}

TEST(Generic, changePressingState) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(false, fe.isPressing());

    Flags currentFlags(0);
    Flags fromFlags(0);

    // ----------------------------------------
    // Without Flags
    // (For example, "change return to tab".)

    EXPECT_EQ(true,  fe.changePressingState(*down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(*up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // Another event does not modify state
    EXPECT_EQ(false, fe.changePressingState(*down_shift, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());
    EXPECT_EQ(false, fe.changePressingState(*up_shift, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------------------------------------
    // Set currentFlags
    // (For example, "change return to tab".)

    currentFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(*down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(*up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------------------------------------
    // Set fromFlags
    // (For example, "change shift-return to tab".)

    // Does not change state if currentFlags lacks flags.
    currentFlags = Flags(0);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(false, fe.changePressingState(*down_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------
    currentFlags = Flags(ModifierFlag::SHIFT_L);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(*down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(*up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------
    currentFlags = Flags(ModifierFlag::SHIFT_L);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(*down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    // Change state even if currentFlags lacks flags when key is pressing.
    // This behavior is necessary for this case.
    // - shift down
    // - return down (shift-return is pressed.)
    // - shift up
    // - return up (shift-return is released.)
    currentFlags = Flags(0);
    EXPECT_EQ(true,  fe.changePressingState(*up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());
    // return false if call changePressingState once again.
    EXPECT_EQ(false, fe.changePressingState(*up_return, currentFlags, fromFlags));
  }
  {
    FromEvent fe(KeyCode::SPACE);
    EXPECT_EQ(false, fe.changePressingState(*down_return, Flags(0), Flags(0)));
    EXPECT_EQ(false, fe.changePressingState(*up_return, Flags(0), Flags(0)));
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(*down_shift, Flags(ModifierFlag::SHIFT_L), Flags(0)));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(*up_shift, Flags(0), Flags(0)));
    EXPECT_EQ(false, fe.isPressing());
  }
}

TEST(Generic, isTargetDownEvent) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(true,  fe.isTargetDownEvent(*down_return));
    EXPECT_EQ(false, fe.isTargetUpEvent(*down_return));

    EXPECT_EQ(false, fe.isTargetDownEvent(*up_return));
    EXPECT_EQ(true,  fe.isTargetUpEvent(*up_return));

    EXPECT_EQ(false, fe.isTargetDownEvent(*down_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(*down_shift));
    EXPECT_EQ(false, fe.isTargetDownEvent(*up_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(*up_shift));
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(true,  fe.isTargetDownEvent(*down_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(*down_shift));

    EXPECT_EQ(false, fe.isTargetDownEvent(*up_shift));
    EXPECT_EQ(true,  fe.isTargetUpEvent(*up_shift));
  }
}
<commit_msg>update Tests<commit_after>#include <ostream>
#include <gtest/gtest.h>
#include "FromEvent.hpp"

using namespace org_pqrs_KeyRemap4MacBook;

ParamsUnion down_return(
  *(Params_KeyboardEventCallBack::auto_ptr(
      Params_KeyboardEventCallBack::alloc(
        EventType::DOWN,
        Flags(0),
        KeyCode::RETURN,
        CharCode(0),
        CharSet(0),
        OrigCharCode(0),
        OrigCharSet(0),
        KeyboardType(0),
        false))));

ParamsUnion up_return(
  *(Params_KeyboardEventCallBack::auto_ptr(
      Params_KeyboardEventCallBack::alloc(
        EventType::UP,
        Flags(0),
        KeyCode::RETURN,
        CharCode(0),
        CharSet(0),
        OrigCharCode(0),
        OrigCharSet(0),
        KeyboardType(0),
        false))));

ParamsUnion down_shift(
  *(Params_KeyboardEventCallBack::auto_ptr(
      Params_KeyboardEventCallBack::alloc(
        EventType::MODIFY,
        Flags(ModifierFlag::SHIFT_L),
        KeyCode::SHIFT_L,
        CharCode(0),
        CharSet(0),
        OrigCharCode(0),
        OrigCharSet(0),
        KeyboardType(0),
        false))));

ParamsUnion up_shift(
  *(Params_KeyboardEventCallBack::auto_ptr(
      Params_KeyboardEventCallBack::alloc(
        EventType::MODIFY,
        Flags(0),
        KeyCode::SHIFT_L,
        CharCode(0),
        CharSet(0),
        OrigCharCode(0),
        OrigCharSet(0),
        KeyboardType(0),
        false))));

TEST(Generic, getModifierFlag) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(ModifierFlag::SHIFT_L, fe.getModifierFlag());
  }
  {
    FromEvent fe(ConsumerKeyCode::VOLUME_MUTE);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
  {
    FromEvent fe(PointingButton::LEFT);
    EXPECT_EQ(ModifierFlag::NONE, fe.getModifierFlag());
  }
}

TEST(Generic, changePressingState) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(false, fe.isPressing());

    Flags currentFlags(0);
    Flags fromFlags(0);

    // ----------------------------------------
    // Without Flags
    // (For example, "change return to tab".)

    EXPECT_EQ(true,  fe.changePressingState(down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // Another event does not modify state
    EXPECT_EQ(false, fe.changePressingState(down_shift, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());
    EXPECT_EQ(false, fe.changePressingState(up_shift, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------------------------------------
    // Set currentFlags
    // (For example, "change return to tab".)

    currentFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------------------------------------
    // Set fromFlags
    // (For example, "change shift-return to tab".)

    // Does not change state if currentFlags lacks flags.
    currentFlags = Flags(0);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(false, fe.changePressingState(down_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    EXPECT_EQ(false, fe.changePressingState(up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------
    currentFlags = Flags(ModifierFlag::SHIFT_L);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());

    // ----------
    currentFlags = Flags(ModifierFlag::SHIFT_L);
    fromFlags = Flags(ModifierFlag::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(down_return, currentFlags, fromFlags));
    EXPECT_EQ(true,  fe.isPressing());

    // Change state even if currentFlags lacks flags when key is pressing.
    // This behavior is necessary for this case.
    // - shift down
    // - return down (shift-return is pressed.)
    // - shift up
    // - return up (shift-return is released.)
    currentFlags = Flags(0);
    EXPECT_EQ(true,  fe.changePressingState(up_return, currentFlags, fromFlags));
    EXPECT_EQ(false, fe.isPressing());
    // return false if call changePressingState once again.
    EXPECT_EQ(false, fe.changePressingState(up_return, currentFlags, fromFlags));
  }
  {
    FromEvent fe(KeyCode::SPACE);
    EXPECT_EQ(false, fe.changePressingState(down_return, Flags(0), Flags(0)));
    EXPECT_EQ(false, fe.changePressingState(up_return, Flags(0), Flags(0)));
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(true,  fe.changePressingState(down_shift, Flags(ModifierFlag::SHIFT_L), Flags(0)));
    EXPECT_EQ(true,  fe.isPressing());

    EXPECT_EQ(true,  fe.changePressingState(up_shift, Flags(0), Flags(0)));
    EXPECT_EQ(false, fe.isPressing());
  }
}

TEST(Generic, unsetPressingState) {
  {
    FromEvent fe(KeyCode::RETURN);

    EXPECT_EQ(true,  fe.changePressingState(down_return, Flags(0), Flags(0)));
    EXPECT_EQ(true,  fe.isPressing());

    fe.unsetPressingState();
    EXPECT_EQ(false, fe.isPressing());
  }
}

TEST(Generic, isTargetDownEvent) {
  {
    FromEvent fe(KeyCode::RETURN);
    EXPECT_EQ(true,  fe.isTargetDownEvent(down_return));
    EXPECT_EQ(false, fe.isTargetUpEvent(down_return));

    EXPECT_EQ(false, fe.isTargetDownEvent(up_return));
    EXPECT_EQ(true,  fe.isTargetUpEvent(up_return));

    EXPECT_EQ(false, fe.isTargetDownEvent(down_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(down_shift));
    EXPECT_EQ(false, fe.isTargetDownEvent(up_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(up_shift));
  }
  {
    FromEvent fe(KeyCode::SHIFT_L);
    EXPECT_EQ(true,  fe.isTargetDownEvent(down_shift));
    EXPECT_EQ(false, fe.isTargetUpEvent(down_shift));

    EXPECT_EQ(false, fe.isTargetDownEvent(up_shift));
    EXPECT_EQ(true,  fe.isTargetUpEvent(up_shift));
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2009 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * 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/testers/rubytest/RubyTester.hh"
#include "mem/physical.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/RubyPort.hh"

RubyPort::RubyPort(const Params *p)
    : MemObject(p)
{
    m_version = p->version;
    assert(m_version != -1);

    physmem = p->physmem;

    m_controller = NULL;
    m_mandatory_q_ptr = NULL;

    m_request_cnt = 0;
    pio_port = NULL;
    physMemPort = NULL;
}

void
RubyPort::init()
{
    assert(m_controller != NULL);
    m_mandatory_q_ptr = m_controller->getMandatoryQueue();
}

Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
    if (if_name == "port") {
        return new M5Port(csprintf("%s-port%d", name(), idx), this);
    }

    if (if_name == "pio_port") {
        // ensure there is only one pio port
        assert(pio_port == NULL);

        pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this);

        return pio_port;
    }

    if (if_name == "physMemPort") {
        // RubyPort should only have one port to physical memory
        assert (physMemPort == NULL);

        physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this);

        return physMemPort;
    }

    if (if_name == "functional") {
        // Calls for the functional port only want to access
        // functional memory.  Therefore, directly pass these calls
        // ports to physmem.
        assert(physmem != NULL);
        return physmem->getPort(if_name, idx);
    }

    return NULL;
}

RubyPort::PioPort::PioPort(const std::string &_name,
                           RubyPort *_port)
    : SimpleTimingPort(_name, _port)
{
    DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name);
    ruby_port = _port;
}

RubyPort::M5Port::M5Port(const std::string &_name,
                         RubyPort *_port)
    : SimpleTimingPort(_name, _port)
{
    DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name);
    ruby_port = _port;
}

Tick
RubyPort::PioPort::recvAtomic(PacketPtr pkt)
{
    panic("RubyPort::PioPort::recvAtomic() not implemented!\n");
    return 0;
}

Tick
RubyPort::M5Port::recvAtomic(PacketPtr pkt)
{
    panic("RubyPort::M5Port::recvAtomic() not implemented!\n");
    return 0;
}

bool
RubyPort::PioPort::recvTiming(PacketPtr pkt)
{
    // In FS mode, ruby memory will receive pio responses from devices
    // and it must forward these responses back to the particular CPU.
    DPRINTF(MemoryAccess,  "Pio response for address %#x\n", pkt->getAddr());

    assert(pkt->isResponse());

    // First we must retrieve the request port from the sender State
    RubyPort::SenderState *senderState =
      safe_cast<RubyPort::SenderState *>(pkt->senderState);
    M5Port *port = senderState->port;
    assert(port != NULL);

    // pop the sender state from the packet
    pkt->senderState = senderState->saved;
    delete senderState;

    port->sendTiming(pkt);

    return true;
}

bool
RubyPort::M5Port::recvTiming(PacketPtr pkt)
{
    DPRINTF(MemoryAccess,
            "Timing access caught for address %#x\n", pkt->getAddr());

    //dsm: based on SimpleTimingPort::recvTiming(pkt);

    // The received packets should only be M5 requests, which should never
    // get nacked.  There used to be code to hanldle nacks here, but
    // I'm pretty sure it didn't work correctly with the drain code,
    // so that would need to be fixed if we ever added it back.
    assert(pkt->isRequest());

    if (pkt->memInhibitAsserted()) {
        warn("memInhibitAsserted???");
        // snooper will supply based on copy of packet
        // still target's responsibility to delete packet
        delete pkt;
        return true;
    }

    // Save the port in the sender state object to be used later to
    // route the response
    pkt->senderState = new SenderState(this, pkt->senderState);

    // Check for pio requests and directly send them to the dedicated
    // pio port.
    if (!isPhysMemAddress(pkt->getAddr())) {
        assert(ruby_port->pio_port != NULL);
        DPRINTF(MemoryAccess,
                "Request for address 0x%#x is assumed to be a pio request\n",
                pkt->getAddr());

        return ruby_port->pio_port->sendTiming(pkt);
    }

    // For DMA and CPU requests, translate them to ruby requests before
    // sending them to our assigned ruby port.
    RubyRequestType type = RubyRequestType_NULL;

    // If valid, copy the pc to the ruby request
    Addr pc = 0;
    if (pkt->req->hasPC()) {
        pc = pkt->req->getPC();
    }

    if (pkt->isLLSC()) {
        if (pkt->isWrite()) {
            DPRINTF(MemoryAccess, "Issuing SC\n");
            type = RubyRequestType_Locked_Write;
        } else {
            DPRINTF(MemoryAccess, "Issuing LL\n");
            assert(pkt->isRead());
            type = RubyRequestType_Locked_Read;
        }
    } else {
        if (pkt->isRead()) {
            if (pkt->req->isInstFetch()) {
                type = RubyRequestType_IFETCH;
            } else {
                type = RubyRequestType_LD;
            }
        } else if (pkt->isWrite()) {
            type = RubyRequestType_ST;
        } else if (pkt->isReadWrite()) {
            // Fix me.  This conditional will never be executed
            // because isReadWrite() is just an OR of isRead() and
            // isWrite().  Furthermore, just because the packet is a
            // read/write request does not necessary mean it is a
            // read-modify-write atomic operation.
            type = RubyRequestType_RMW_Write;
        } else {
            panic("Unsupported ruby packet type\n");
        }
    }

    RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
                             pkt->getSize(), pc, type,
                             RubyAccessMode_Supervisor, pkt);

    // Submit the ruby request
    RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);

    // If the request successfully issued then we should return true.
    // Otherwise, we need to delete the senderStatus we just created and return
    // false.
    if (requestStatus == RequestStatus_Issued) {
        return true;
    }

    DPRINTF(MemoryAccess,
            "Request for address #x did not issue because %s\n",
            pkt->getAddr(), RequestStatus_to_string(requestStatus));

    SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
    pkt->senderState = senderState->saved;
    delete senderState;
    return false;
}

void
RubyPort::ruby_hit_callback(PacketPtr pkt)
{
    // Retrieve the request port from the sender State
    RubyPort::SenderState *senderState =
        safe_cast<RubyPort::SenderState *>(pkt->senderState);
    M5Port *port = senderState->port;
    assert(port != NULL);

    // pop the sender state from the packet
    pkt->senderState = senderState->saved;
    delete senderState;

    port->hitCallback(pkt);
}

void
RubyPort::M5Port::hitCallback(PacketPtr pkt)
{
    bool needsResponse = pkt->needsResponse();

    //
    // All responses except failed SC operations access M5 physical memory
    //
    bool accessPhysMem = true;

    if (pkt->isLLSC()) {
        if (pkt->isWrite()) {
            if (pkt->req->getExtraData() != 0) {
                //
                // Successful SC packets convert to normal writes
                //
                pkt->convertScToWrite();
            } else {
                //
                // Failed SC packets don't access physical memory and thus
                // the RubyPort itself must convert it to a response.
                //
                accessPhysMem = false;
                pkt->makeAtomicResponse();
            }
        } else {
            //
            // All LL packets convert to normal loads so that M5 PhysMem does
            // not lock the blocks.
            //
            pkt->convertLlToRead();
        }
    }
    DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse);

    if (accessPhysMem) {
        ruby_port->physMemPort->sendAtomic(pkt);
    }

    // turn packet around to go back to requester if response expected
    if (needsResponse) {
        // sendAtomic() should already have turned packet into
        // atomic response
        assert(pkt->isResponse());
        DPRINTF(MemoryAccess, "Sending packet back over port\n");
        sendTiming(pkt);
    } else {
        delete pkt;
    }
    DPRINTF(MemoryAccess, "Hit callback done!\n");
}

bool
RubyPort::M5Port::sendTiming(PacketPtr pkt)
{
    //minimum latency, must be > 0
    schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
    return true;
}

bool
RubyPort::PioPort::sendTiming(PacketPtr pkt)
{
    //minimum latency, must be > 0
    schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
    return true;
}

bool
RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
    AddrRangeList physMemAddrList;
    bool snoop = false;
    ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
    for (AddrRangeIter iter = physMemAddrList.begin();
         iter != physMemAddrList.end();
         iter++) {
        if (addr >= iter->start && addr <= iter->end) {
            DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n",
                    iter->start, iter->end);
            return true;
        }
    }
    return false;
}
<commit_msg>ruby: Assert for x86 misaligned access<commit_after>/*
 * Copyright (c) 2009 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * 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/testers/rubytest/RubyTester.hh"
#include "mem/physical.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/RubyPort.hh"

RubyPort::RubyPort(const Params *p)
    : MemObject(p)
{
    m_version = p->version;
    assert(m_version != -1);

    physmem = p->physmem;

    m_controller = NULL;
    m_mandatory_q_ptr = NULL;

    m_request_cnt = 0;
    pio_port = NULL;
    physMemPort = NULL;
}

void
RubyPort::init()
{
    assert(m_controller != NULL);
    m_mandatory_q_ptr = m_controller->getMandatoryQueue();
}

Port *
RubyPort::getPort(const std::string &if_name, int idx)
{
    if (if_name == "port") {
        return new M5Port(csprintf("%s-port%d", name(), idx), this);
    }

    if (if_name == "pio_port") {
        // ensure there is only one pio port
        assert(pio_port == NULL);

        pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this);

        return pio_port;
    }

    if (if_name == "physMemPort") {
        // RubyPort should only have one port to physical memory
        assert (physMemPort == NULL);

        physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this);

        return physMemPort;
    }

    if (if_name == "functional") {
        // Calls for the functional port only want to access
        // functional memory.  Therefore, directly pass these calls
        // ports to physmem.
        assert(physmem != NULL);
        return physmem->getPort(if_name, idx);
    }

    return NULL;
}

RubyPort::PioPort::PioPort(const std::string &_name,
                           RubyPort *_port)
    : SimpleTimingPort(_name, _port)
{
    DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name);
    ruby_port = _port;
}

RubyPort::M5Port::M5Port(const std::string &_name,
                         RubyPort *_port)
    : SimpleTimingPort(_name, _port)
{
    DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name);
    ruby_port = _port;
}

Tick
RubyPort::PioPort::recvAtomic(PacketPtr pkt)
{
    panic("RubyPort::PioPort::recvAtomic() not implemented!\n");
    return 0;
}

Tick
RubyPort::M5Port::recvAtomic(PacketPtr pkt)
{
    panic("RubyPort::M5Port::recvAtomic() not implemented!\n");
    return 0;
}

bool
RubyPort::PioPort::recvTiming(PacketPtr pkt)
{
    // In FS mode, ruby memory will receive pio responses from devices
    // and it must forward these responses back to the particular CPU.
    DPRINTF(MemoryAccess,  "Pio response for address %#x\n", pkt->getAddr());

    assert(pkt->isResponse());

    // First we must retrieve the request port from the sender State
    RubyPort::SenderState *senderState =
      safe_cast<RubyPort::SenderState *>(pkt->senderState);
    M5Port *port = senderState->port;
    assert(port != NULL);

    // pop the sender state from the packet
    pkt->senderState = senderState->saved;
    delete senderState;

    port->sendTiming(pkt);

    return true;
}

bool
RubyPort::M5Port::recvTiming(PacketPtr pkt)
{
    DPRINTF(MemoryAccess,
            "Timing access caught for address %#x\n", pkt->getAddr());

    //dsm: based on SimpleTimingPort::recvTiming(pkt);

    // The received packets should only be M5 requests, which should never
    // get nacked.  There used to be code to hanldle nacks here, but
    // I'm pretty sure it didn't work correctly with the drain code,
    // so that would need to be fixed if we ever added it back.
    assert(pkt->isRequest());

    if (pkt->memInhibitAsserted()) {
        warn("memInhibitAsserted???");
        // snooper will supply based on copy of packet
        // still target's responsibility to delete packet
        delete pkt;
        return true;
    }

    // Save the port in the sender state object to be used later to
    // route the response
    pkt->senderState = new SenderState(this, pkt->senderState);

    // Check for pio requests and directly send them to the dedicated
    // pio port.
    if (!isPhysMemAddress(pkt->getAddr())) {
        assert(ruby_port->pio_port != NULL);
        DPRINTF(MemoryAccess,
                "Request for address 0x%#x is assumed to be a pio request\n",
                pkt->getAddr());

        return ruby_port->pio_port->sendTiming(pkt);
    }

    // For DMA and CPU requests, translate them to ruby requests before
    // sending them to our assigned ruby port.
    RubyRequestType type = RubyRequestType_NULL;

    // If valid, copy the pc to the ruby request
    Addr pc = 0;
    if (pkt->req->hasPC()) {
        pc = pkt->req->getPC();
    }

    if (pkt->isLLSC()) {
        if (pkt->isWrite()) {
            DPRINTF(MemoryAccess, "Issuing SC\n");
            type = RubyRequestType_Locked_Write;
        } else {
            DPRINTF(MemoryAccess, "Issuing LL\n");
            assert(pkt->isRead());
            type = RubyRequestType_Locked_Read;
        }
    } else {
        if (pkt->isRead()) {
            if (pkt->req->isInstFetch()) {
                type = RubyRequestType_IFETCH;
            } else {
                type = RubyRequestType_LD;
            }
        } else if (pkt->isWrite()) {
            type = RubyRequestType_ST;
        } else if (pkt->isReadWrite()) {
            // Fix me.  This conditional will never be executed
            // because isReadWrite() is just an OR of isRead() and
            // isWrite().  Furthermore, just because the packet is a
            // read/write request does not necessary mean it is a
            // read-modify-write atomic operation.
            type = RubyRequestType_RMW_Write;
        } else {
            panic("Unsupported ruby packet type\n");
        }
    }

    RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
                             pkt->getSize(), pc, type,
                             RubyAccessMode_Supervisor, pkt);

    assert(Address(ruby_request.paddr).getOffset() + ruby_request.len <=
        RubySystem::getBlockSizeBytes());

    // Submit the ruby request
    RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);

    // If the request successfully issued then we should return true.
    // Otherwise, we need to delete the senderStatus we just created and return
    // false.
    if (requestStatus == RequestStatus_Issued) {
        return true;
    }

    DPRINTF(MemoryAccess,
            "Request for address %#x did not issue because %s\n",
            pkt->getAddr(), RequestStatus_to_string(requestStatus));

    SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
    pkt->senderState = senderState->saved;
    delete senderState;
    return false;
}

void
RubyPort::ruby_hit_callback(PacketPtr pkt)
{
    // Retrieve the request port from the sender State
    RubyPort::SenderState *senderState =
        safe_cast<RubyPort::SenderState *>(pkt->senderState);
    M5Port *port = senderState->port;
    assert(port != NULL);

    // pop the sender state from the packet
    pkt->senderState = senderState->saved;
    delete senderState;

    port->hitCallback(pkt);
}

void
RubyPort::M5Port::hitCallback(PacketPtr pkt)
{
    bool needsResponse = pkt->needsResponse();

    //
    // All responses except failed SC operations access M5 physical memory
    //
    bool accessPhysMem = true;

    if (pkt->isLLSC()) {
        if (pkt->isWrite()) {
            if (pkt->req->getExtraData() != 0) {
                //
                // Successful SC packets convert to normal writes
                //
                pkt->convertScToWrite();
            } else {
                //
                // Failed SC packets don't access physical memory and thus
                // the RubyPort itself must convert it to a response.
                //
                accessPhysMem = false;
                pkt->makeAtomicResponse();
            }
        } else {
            //
            // All LL packets convert to normal loads so that M5 PhysMem does
            // not lock the blocks.
            //
            pkt->convertLlToRead();
        }
    }
    DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse);

    if (accessPhysMem) {
        ruby_port->physMemPort->sendAtomic(pkt);
    }

    // turn packet around to go back to requester if response expected
    if (needsResponse) {
        // sendAtomic() should already have turned packet into
        // atomic response
        assert(pkt->isResponse());
        DPRINTF(MemoryAccess, "Sending packet back over port\n");
        sendTiming(pkt);
    } else {
        delete pkt;
    }
    DPRINTF(MemoryAccess, "Hit callback done!\n");
}

bool
RubyPort::M5Port::sendTiming(PacketPtr pkt)
{
    //minimum latency, must be > 0
    schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
    return true;
}

bool
RubyPort::PioPort::sendTiming(PacketPtr pkt)
{
    //minimum latency, must be > 0
    schedSendTiming(pkt, curTick() + (1 * g_eventQueue_ptr->getClock()));
    return true;
}

bool
RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
    AddrRangeList physMemAddrList;
    bool snoop = false;
    ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
    for (AddrRangeIter iter = physMemAddrList.begin();
         iter != physMemAddrList.end();
         iter++) {
        if (addr >= iter->start && addr <= iter->end) {
            DPRINTF(MemoryAccess, "Request found in %#llx - %#llx range\n",
                    iter->start, iter->end);
            return true;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>#include "llvmtgsi.h"

#include "pipe/tgsi/exec/tgsi_exec.h"
#include "pipe/tgsi/exec/tgsi_token.h"
#include "pipe/tgsi/exec/tgsi_build.h"
#include "pipe/tgsi/exec/tgsi_util.h"
#include "pipe/tgsi/exec/tgsi_parse.h"
#include "pipe/tgsi/exec/tgsi_dump.h"
//#include "pipe/tgsi/tgsi_platform.h"

#include <llvm/Module.h>
#include <llvm/CallingConv.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <iostream>

static void
translate_declaration(llvm::Module *module,
                      struct tgsi_full_declaration *decl,
                      struct tgsi_full_declaration *fd)
{
}

static void
translate_immediate(llvm::Module *module,
                    struct tgsi_full_immediate *imm)
{
}

static void
translate_instruction(llvm::Module *module,
                      struct tgsi_full_instruction *inst,
                      struct tgsi_full_instruction *fi)
{
}

static llvm::Module *
tgsi_to_llvm(const struct tgsi_token *tokens)
{
   llvm::Module *mod = new llvm::Module("tgsi");
   struct tgsi_parse_context parse;
   struct tgsi_full_instruction fi;
   struct tgsi_full_declaration fd;

   tgsi_parse_init(&parse, tokens);

   //parse.FullHeader.Processor.Processor

   //parse.FullVersion.Version.MajorVersion
   //parse.FullVersion.Version.MinorVersion

   //parse.FullHeader.Header.HeaderSize
   //parse.FullHeader.Header.BodySize
   //parse.FullHeader.Processor.Processor

   fi = tgsi_default_full_instruction();
   fd = tgsi_default_full_declaration();

   while(!tgsi_parse_end_of_tokens(&parse)) {
      tgsi_parse_token(&parse);

      fprintf(stderr, "Translating %d\n", parse.FullToken.Token.Type);

      switch (parse.FullToken.Token.Type) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         translate_declaration(mod,
                               &parse.FullToken.FullDeclaration,
                               &fd);
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         translate_immediate(mod,
                             &parse.FullToken.FullImmediate);
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         translate_instruction(mod,
                               &parse.FullToken.FullInstruction,
                               &fi);
         break;

      default:
         assert(0);
      }
   }

   //TXT("\ntgsi-dump end -------------------\n");

   tgsi_parse_free(&parse);

   return mod;
}

struct ga_llvm_prog *
ga_llvm_from_tgsi(const struct tgsi_token *tokens)
{
   std::cout << "Creating llvm " <<std::endl;
   struct ga_llvm_prog *ga_llvm =
      (struct ga_llvm_prog *)malloc(sizeof(struct ga_llvm_prog));
   llvm::Module *mod = tgsi_to_llvm(tokens);
   llvm::ExistingModuleProvider *mp =
      new llvm::ExistingModuleProvider(mod);
   //llvm::ExecutionEngine *ee =
   //   llvm::ExecutionEngine::create(mp, false);

   ga_llvm->module = mod;
   ga_llvm->engine = 0;//ee;
   fprintf(stderr, "DUMPX \n");
   //tgsi_dump(tokens, TGSI_DUMP_VERBOSE);
   tgsi_dump(tokens, 0);
   fprintf(stderr, "DUMPEND \n");

   return ga_llvm;
}

void ga_llvm_prog_delete(struct ga_llvm_prog *prog)
{
   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
   delete mod;
   prog->module = 0;
   prog->engine = 0;
   free(prog);
}

int ga_llvm_prog_exec(struct ga_llvm_prog *prog)
{
   //std::cout << "START "<<std::endl;
   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
   llvm::Function *func = mod->getFunction("main");
   llvm::ExecutionEngine *ee = static_cast<llvm::ExecutionEngine*>(prog->engine);

   std::vector<llvm::GenericValue> args(0);
   //args[0] = GenericValue(&st);
   //std::cout << "Mod is "<<*mod;
   //std::cout << "\n\nRunning llvm: " << std::endl;
   if (func) {
      std::cout << "Func is "<<func;
      llvm::GenericValue gv = ee->runFunction(func, args);
   }

//delete ee;
//delete mp;

   return 0;
}
<commit_msg>Stub out some conversion.<commit_after>#include "llvmtgsi.h"

#include "pipe/tgsi/exec/tgsi_exec.h"
#include "pipe/tgsi/exec/tgsi_token.h"
#include "pipe/tgsi/exec/tgsi_build.h"
#include "pipe/tgsi/exec/tgsi_util.h"
#include "pipe/tgsi/exec/tgsi_parse.h"
#include "pipe/tgsi/exec/tgsi_dump.h"
//#include "pipe/tgsi/tgsi_platform.h"

#include <llvm/Module.h>
#include <llvm/CallingConv.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <iostream>

static void
translate_declaration(llvm::Module *module,
                      struct tgsi_full_declaration *decl,
                      struct tgsi_full_declaration *fd)
{
   /* i think this is going to be a noop */
}

static void
translate_immediate(llvm::Module *module,
                    struct tgsi_full_immediate *imm)
{
}

static void
translate_instruction(llvm::Module *module,
                      struct tgsi_full_instruction *inst,
                      struct tgsi_full_instruction *fi)
{
   switch (inst->Instruction.Opcode) {
   case TGSI_OPCODE_ARL:
      break;
   case TGSI_OPCODE_MOV:
      break;
   case TGSI_OPCODE_LIT:
      break;
   case TGSI_OPCODE_RCP:
      break;
   case TGSI_OPCODE_RSQ:
      break;
   case TGSI_OPCODE_EXP:
      break;
   case TGSI_OPCODE_LOG:
      break;
   case TGSI_OPCODE_MUL:
      break;
   case TGSI_OPCODE_ADD:
      break;
   case TGSI_OPCODE_DP3:
      break;
   case TGSI_OPCODE_DP4:
      break;
   case TGSI_OPCODE_DST:
      break;
   case TGSI_OPCODE_MIN:
      break;
   case TGSI_OPCODE_MAX:
      break;
   case TGSI_OPCODE_SLT:
      break;
   case TGSI_OPCODE_SGE:
      break;
   case TGSI_OPCODE_MAD:
      break;
   case TGSI_OPCODE_SUB:
      break;
   case TGSI_OPCODE_LERP:
      break;
   case TGSI_OPCODE_CND:
      break;
   case TGSI_OPCODE_CND0:
      break;
   case TGSI_OPCODE_DOT2ADD:
      break;
   case TGSI_OPCODE_INDEX:
      break;
   case TGSI_OPCODE_NEGATE:
      break;
   case TGSI_OPCODE_FRAC:
      break;
   case TGSI_OPCODE_CLAMP:
      break;
   case TGSI_OPCODE_FLOOR:
      break;
   case TGSI_OPCODE_ROUND:
      break;
   case TGSI_OPCODE_EXPBASE2:
      break;
   case TGSI_OPCODE_LOGBASE2:
      break;
   case TGSI_OPCODE_POWER:
      break;
   case TGSI_OPCODE_CROSSPRODUCT:
      break;
   case TGSI_OPCODE_MULTIPLYMATRIX:
      break;
   case TGSI_OPCODE_ABS:
      break;
   case TGSI_OPCODE_RCC:
      break;
   case TGSI_OPCODE_DPH:
      break;
   case TGSI_OPCODE_COS:
      break;
   case TGSI_OPCODE_DDX:
      break;
   case TGSI_OPCODE_DDY:
      break;
   case TGSI_OPCODE_KILP:
      break;
   case TGSI_OPCODE_PK2H:
      break;
   case TGSI_OPCODE_PK2US:
      break;
   case TGSI_OPCODE_PK4B:
      break;
   case TGSI_OPCODE_PK4UB:
      break;
   case TGSI_OPCODE_RFL:
      break;
   case TGSI_OPCODE_SEQ:
      break;
   case TGSI_OPCODE_SFL:
      break;
   case TGSI_OPCODE_SGT:
      break;
   case TGSI_OPCODE_SIN:
      break;
   case TGSI_OPCODE_SLE:
      break;
   case TGSI_OPCODE_SNE:
      break;
   case TGSI_OPCODE_STR:
      break;
   case TGSI_OPCODE_TEX:
      break;
   case TGSI_OPCODE_TXD:
      break;
   case TGSI_OPCODE_TXP:
      break;
   case TGSI_OPCODE_UP2H:
      break;
   case TGSI_OPCODE_UP2US:
      break;
   case TGSI_OPCODE_UP4B:
      break;
   case TGSI_OPCODE_UP4UB:
      break;
   case TGSI_OPCODE_X2D:
      break;
   case TGSI_OPCODE_ARA:
      break;
   case TGSI_OPCODE_ARR:
      break;
   case TGSI_OPCODE_BRA:
      break;
   case TGSI_OPCODE_CAL:
      break;
   case TGSI_OPCODE_RET:
      break;
   case TGSI_OPCODE_SSG:
      break;
   case TGSI_OPCODE_CMP:
      break;
   case TGSI_OPCODE_SCS:
      break;
   case TGSI_OPCODE_TXB:
      break;
   case TGSI_OPCODE_NRM:
      break;
   case TGSI_OPCODE_DIV:
      break;
   case TGSI_OPCODE_DP2:
      break;
   case TGSI_OPCODE_TXL:
      break;
   case TGSI_OPCODE_BRK:
      break;
   case TGSI_OPCODE_IF:
      break;
   case TGSI_OPCODE_LOOP:
      break;
   case TGSI_OPCODE_REP:
      break;
   case TGSI_OPCODE_ELSE:
      break;
   case TGSI_OPCODE_ENDIF:
      break;
   case TGSI_OPCODE_ENDLOOP:
      break;
   case TGSI_OPCODE_ENDREP:
      break;
   case TGSI_OPCODE_PUSHA:
      break;
   case TGSI_OPCODE_POPA:
      break;
   case TGSI_OPCODE_CEIL:
      break;
   case TGSI_OPCODE_I2F:
      break;
   case TGSI_OPCODE_NOT:
      break;
   case TGSI_OPCODE_TRUNC:
      break;
   case TGSI_OPCODE_SHL:
      break;
   case TGSI_OPCODE_SHR:
      break;
   case TGSI_OPCODE_AND:
      break;
   case TGSI_OPCODE_OR:
      break;
   case TGSI_OPCODE_MOD:
      break;
   case TGSI_OPCODE_XOR:
      break;
   case TGSI_OPCODE_SAD:
      break;
   case TGSI_OPCODE_TXF:
      break;
   case TGSI_OPCODE_TXQ:
      break;
   case TGSI_OPCODE_CONT:
      break;
   case TGSI_OPCODE_EMIT:
      break;
   case TGSI_OPCODE_ENDPRIM:
      break;
   case TGSI_OPCODE_BGNLOOP2:
      break;
   case TGSI_OPCODE_BGNSUB:
      break;
   case TGSI_OPCODE_ENDLOOP2:
      break;
   case TGSI_OPCODE_ENDSUB:
      break;
   case TGSI_OPCODE_NOISE1:
      break;
   case TGSI_OPCODE_NOISE2:
      break;
   case TGSI_OPCODE_NOISE3:
      break;
   case TGSI_OPCODE_NOISE4:
      break;
   case TGSI_OPCODE_NOP:
      break;
   case TGSI_OPCODE_TEXBEM:
      break;
   case TGSI_OPCODE_TEXBEML:
      break;
   case TGSI_OPCODE_TEXREG2AR:
      break;
   case TGSI_OPCODE_TEXM3X2PAD:
      break;
   case TGSI_OPCODE_TEXM3X2TEX:
      break;
   case TGSI_OPCODE_TEXM3X3PAD:
      break;
   case TGSI_OPCODE_TEXM3X3TEX:
      break;
   case TGSI_OPCODE_TEXM3X3SPEC:
      break;
   case TGSI_OPCODE_TEXM3X3VSPEC:
      break;
   case TGSI_OPCODE_TEXREG2GB:
      break;
   case TGSI_OPCODE_TEXREG2RGB:
      break;
   case TGSI_OPCODE_TEXDP3TEX:
      break;
   case TGSI_OPCODE_TEXDP3:
      break;
   case TGSI_OPCODE_TEXM3X3:
      break;
   case TGSI_OPCODE_TEXM3X2DEPTH:
      break;
   case TGSI_OPCODE_TEXDEPTH:
      break;
   case TGSI_OPCODE_BEM:
      break;
   case TGSI_OPCODE_M4X3:
      break;
   case TGSI_OPCODE_M3X4:
      break;
   case TGSI_OPCODE_M3X3:
      break;
   case TGSI_OPCODE_M3X2:
      break;
   case TGSI_OPCODE_NRM4:
      break;
   case TGSI_OPCODE_CALLNZ:
      break;
   case TGSI_OPCODE_IFC:
      break;
   case TGSI_OPCODE_BREAKC:
      break;
   case TGSI_OPCODE_KIL:
      break;
   case TGSI_OPCODE_END:
      break;
   default:
      fprintf(stderr, "ERROR: Unknown opcode %d\n",
              inst->Instruction.Opcode);
      assert(0);
      break;
   }

   switch( inst->Instruction.Saturate ) {
   case TGSI_SAT_NONE:
      break;
   case TGSI_SAT_ZERO_ONE:
      /*TXT( "_SAT" );*/
      break;
   case TGSI_SAT_MINUS_PLUS_ONE:
      /*TXT( "_SAT[-1,1]" );*/
      break;
   default:
      assert( 0 );
   }
}

static llvm::Module *
tgsi_to_llvm(const struct tgsi_token *tokens)
{
   llvm::Module *mod = new llvm::Module("tgsi");
   struct tgsi_parse_context parse;
   struct tgsi_full_instruction fi;
   struct tgsi_full_declaration fd;

   tgsi_parse_init(&parse, tokens);

   //parse.FullHeader.Processor.Processor

   //parse.FullVersion.Version.MajorVersion
   //parse.FullVersion.Version.MinorVersion

   //parse.FullHeader.Header.HeaderSize
   //parse.FullHeader.Header.BodySize
   //parse.FullHeader.Processor.Processor

   fi = tgsi_default_full_instruction();
   fd = tgsi_default_full_declaration();

   while(!tgsi_parse_end_of_tokens(&parse)) {
      tgsi_parse_token(&parse);

      fprintf(stderr, "Translating %d\n", parse.FullToken.Token.Type);

      switch (parse.FullToken.Token.Type) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         translate_declaration(mod,
                               &parse.FullToken.FullDeclaration,
                               &fd);
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         translate_immediate(mod,
                             &parse.FullToken.FullImmediate);
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         translate_instruction(mod,
                               &parse.FullToken.FullInstruction,
                               &fi);
         break;

      default:
         assert(0);
      }
   }

   //TXT("\ntgsi-dump end -------------------\n");

   tgsi_parse_free(&parse);

   return mod;
}

struct ga_llvm_prog *
ga_llvm_from_tgsi(const struct tgsi_token *tokens)
{
   std::cout << "Creating llvm " <<std::endl;
   struct ga_llvm_prog *ga_llvm =
      (struct ga_llvm_prog *)malloc(sizeof(struct ga_llvm_prog));
   llvm::Module *mod = tgsi_to_llvm(tokens);
   llvm::ExistingModuleProvider *mp =
      new llvm::ExistingModuleProvider(mod);
   //llvm::ExecutionEngine *ee =
   //   llvm::ExecutionEngine::create(mp, false);

   ga_llvm->module = mod;
   ga_llvm->engine = 0;//ee;
   fprintf(stderr, "DUMPX \n");
   //tgsi_dump(tokens, TGSI_DUMP_VERBOSE);
   tgsi_dump(tokens, 0);
   fprintf(stderr, "DUMPEND \n");

   return ga_llvm;
}

void ga_llvm_prog_delete(struct ga_llvm_prog *prog)
{
   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
   delete mod;
   prog->module = 0;
   prog->engine = 0;
   free(prog);
}

int ga_llvm_prog_exec(struct ga_llvm_prog *prog)
{
   //std::cout << "START "<<std::endl;
   llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
   llvm::Function *func = mod->getFunction("main");
   llvm::ExecutionEngine *ee = static_cast<llvm::ExecutionEngine*>(prog->engine);

   std::vector<llvm::GenericValue> args(0);
   //args[0] = GenericValue(&st);
   //std::cout << "Mod is "<<*mod;
   //std::cout << "\n\nRunning llvm: " << std::endl;
   if (func) {
      std::cout << "Func is "<<func;
      llvm::GenericValue gv = ee->runFunction(func, args);
   }

//delete ee;
//delete mp;

   return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *                                                                         *
 * Copyright (C) 2007-2015 by frePPLe bv                                   *
 *                                                                         *
 * This library is free software; you can redistribute it and/or modify it *
 * under the terms of the GNU Affero General Public License as published   *
 * by the Free Software Foundation; either version 3 of the License, or    *
 * (at your option) any later version.                                     *
 *                                                                         *
 * This library is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 * GNU Affero General Public License for more details.                     *
 *                                                                         *
 * You should have received a copy of the GNU Affero General Public        *
 * License along with this program.                                        *
 * If not, see <http://www.gnu.org/licenses/>.                             *
 *                                                                         *
 ***************************************************************************/

#define FREPPLE_CORE
#include "frepple/model.h"

namespace frepple {

void Resource::updateProblems() {
  // Delete existing problems for this resource
  Problem::clearProblems(*this, true, false);

  // Problem detection disabled on this resource
  if (!getDetectProblems()) return;

  // Loop through the loadplans
  Date excessProblemStart;
  Date shortageProblemStart;
  bool excessProblem = false;
  bool shortageProblem = false;
  double curMax(0.0);
  double shortageQty(0.0);
  double curMin(0.0);
  double excessQty(0.0);
  for (auto iter = loadplans.begin(); iter != loadplans.end();) {
    // Process changes in the maximum or minimum targets
    if (iter->getEventType() == 4)
      curMax = iter->getMax();
    else if (iter->getEventType() == 3)
      curMin = iter->getMin();

    // Only consider the last loadplan for a certain date
    const TimeLine<LoadPlan>::Event *f = &*(iter++);
    if (iter != loadplans.end() && iter->getDate() == f->getDate()) continue;

    // Check against minimum target
    double delta = f->getOnhand() - curMin;
    if (delta < -ROUNDING_ERROR) {
      if (!shortageProblem) {
        shortageProblemStart = f->getDate();
        shortageQty = delta;
        shortageProblem = true;
      } else if (delta < shortageQty)
        // New shortage qty
        shortageQty = delta;
    } else {
      if (shortageProblem) {
        // New problem now ends
        if (f->getDate() != shortageProblemStart)
          new ProblemCapacityUnderload(
              this, DateRange(shortageProblemStart, f->getDate()),
              -shortageQty);
        shortageProblem = false;
      }
    }

    // Note that theoretically we can have a minimum and a maximum problem for
    // the same moment in time.

    // Check against maximum target
    delta = f->getOnhand() - curMax;
    if (delta > ROUNDING_ERROR) {
      if (!excessProblem) {
        excessProblemStart = f->getDate();
        excessQty = delta;
        excessProblem = true;
      } else if (delta > excessQty)
        excessQty = delta;
    } else {
      if (excessProblem) {
        // New problem now ends
        if (f->getDate() != excessProblemStart)
          new ProblemCapacityOverload(this, excessProblemStart, f->getDate(),
                                      excessQty);
        excessProblem = false;
      }
    }

  }  // End of for-loop through the loadplans

  // The excess lasts till the end of the horizon...
  if (excessProblem)
    new ProblemCapacityOverload(this, excessProblemStart, Date::infiniteFuture,
                                excessQty);

  // The shortage lasts till the end of the horizon...
  if (shortageProblem)
    new ProblemCapacityUnderload(
        this, DateRange(shortageProblemStart, Date::infiniteFuture),
        -shortageQty);
}

void ResourceBuckets::updateProblems() {
  // Delete existing problems for this resource
  Problem::clearProblems(*this, true, false);

  // Problem detection disabled on this resource
  if (!getDetectProblems()) return;

  // Loop over all events
  Date startdate = Date::infinitePast;
  double load = 0.0;
  for (auto iter = loadplans.begin(); iter != loadplans.end(); iter++) {
    if (iter->getEventType() != 2)
      load = iter->getOnhand();
    else {
      // Evaluate previous bucket
      if (load < -ROUNDING_ERROR)
        new ProblemCapacityOverload(this, startdate, iter->getDate(), -load);
      // Reset evaluation for the new bucket
      startdate = iter->getDate();
      load = 0.0;
    }
  }
  // Evaluate the final bucket
  if (load < -ROUNDING_ERROR)
    new ProblemCapacityOverload(this, startdate, Date::infiniteFuture, -load);
}

string ProblemCapacityUnderload::getDescription() const {
  ostringstream ch;
  ch << "Resource '" << getResource() << "' has excess capacity of " << qty;
  return ch.str();
}

string ProblemCapacityOverload::getDescription() const {
  ostringstream ch;
  ch << "Resource '" << getResource() << "' has capacity shortage of " << qty;
  return ch.str();
}

}  // namespace frepple
<commit_msg>unconstrained resources shouldn't flag overload problems<commit_after>/***************************************************************************
 *                                                                         *
 * Copyright (C) 2007-2015 by frePPLe bv                                   *
 *                                                                         *
 * This library is free software; you can redistribute it and/or modify it *
 * under the terms of the GNU Affero General Public License as published   *
 * by the Free Software Foundation; either version 3 of the License, or    *
 * (at your option) any later version.                                     *
 *                                                                         *
 * This library is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
 * GNU Affero General Public License for more details.                     *
 *                                                                         *
 * You should have received a copy of the GNU Affero General Public        *
 * License along with this program.                                        *
 * If not, see <http://www.gnu.org/licenses/>.                             *
 *                                                                         *
 ***************************************************************************/

#define FREPPLE_CORE
#include "frepple/model.h"

namespace frepple {

void Resource::updateProblems() {
  // Delete existing problems for this resource
  Problem::clearProblems(*this, true, false);

  // Problem detection disabled on this resource
  if (!getDetectProblems() || !getConstrained()) return;

  // Loop through the loadplans
  Date excessProblemStart;
  Date shortageProblemStart;
  bool excessProblem = false;
  bool shortageProblem = false;
  double curMax(0.0);
  double shortageQty(0.0);
  double curMin(0.0);
  double excessQty(0.0);
  for (auto iter = loadplans.begin(); iter != loadplans.end();) {
    // Process changes in the maximum or minimum targets
    if (iter->getEventType() == 4)
      curMax = iter->getMax();
    else if (iter->getEventType() == 3)
      curMin = iter->getMin();

    // Only consider the last loadplan for a certain date
    const TimeLine<LoadPlan>::Event *f = &*(iter++);
    if (iter != loadplans.end() && iter->getDate() == f->getDate()) continue;

    // Check against minimum target
    double delta = f->getOnhand() - curMin;
    if (delta < -ROUNDING_ERROR) {
      if (!shortageProblem) {
        shortageProblemStart = f->getDate();
        shortageQty = delta;
        shortageProblem = true;
      } else if (delta < shortageQty)
        // New shortage qty
        shortageQty = delta;
    } else {
      if (shortageProblem) {
        // New problem now ends
        if (f->getDate() != shortageProblemStart)
          new ProblemCapacityUnderload(
              this, DateRange(shortageProblemStart, f->getDate()),
              -shortageQty);
        shortageProblem = false;
      }
    }

    // Note that theoretically we can have a minimum and a maximum problem for
    // the same moment in time.

    // Check against maximum target
    delta = f->getOnhand() - curMax;
    if (delta > ROUNDING_ERROR) {
      if (!excessProblem) {
        excessProblemStart = f->getDate();
        excessQty = delta;
        excessProblem = true;
      } else if (delta > excessQty)
        excessQty = delta;
    } else {
      if (excessProblem) {
        // New problem now ends
        if (f->getDate() != excessProblemStart)
          new ProblemCapacityOverload(this, excessProblemStart, f->getDate(),
                                      excessQty);
        excessProblem = false;
      }
    }

  }  // End of for-loop through the loadplans

  // The excess lasts till the end of the horizon...
  if (excessProblem)
    new ProblemCapacityOverload(this, excessProblemStart, Date::infiniteFuture,
                                excessQty);

  // The shortage lasts till the end of the horizon...
  if (shortageProblem)
    new ProblemCapacityUnderload(
        this, DateRange(shortageProblemStart, Date::infiniteFuture),
        -shortageQty);
}

void ResourceBuckets::updateProblems() {
  // Delete existing problems for this resource
  Problem::clearProblems(*this, true, false);

  // Problem detection disabled on this resource
  if (!getDetectProblems() || !getConstrained()) return;

  // Loop over all events
  Date startdate = Date::infinitePast;
  double load = 0.0;
  for (auto iter = loadplans.begin(); iter != loadplans.end(); iter++) {
    if (iter->getEventType() != 2)
      load = iter->getOnhand();
    else {
      // Evaluate previous bucket
      if (load < -ROUNDING_ERROR)
        new ProblemCapacityOverload(this, startdate, iter->getDate(), -load);
      // Reset evaluation for the new bucket
      startdate = iter->getDate();
      load = 0.0;
    }
  }
  // Evaluate the final bucket
  if (load < -ROUNDING_ERROR)
    new ProblemCapacityOverload(this, startdate, Date::infiniteFuture, -load);
}

string ProblemCapacityUnderload::getDescription() const {
  ostringstream ch;
  ch << "Resource '" << getResource() << "' has excess capacity of " << qty;
  return ch.str();
}

string ProblemCapacityOverload::getDescription() const {
  ostringstream ch;
  ch << "Resource '" << getResource() << "' has capacity shortage of " << qty;
  return ch.str();
}

}  // namespace frepple
<|endoftext|>


<commit_before>//
// Copyright © 2020 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <ostream>
#include <cmath>
#include <stdint.h>

namespace armnn
{
class BFloat16
{
public:
    BFloat16()
    : m_Value(0)
    {}

    BFloat16(const BFloat16& v) = default;

    explicit BFloat16(uint16_t v)
    : m_Value(v)
    {}

    explicit BFloat16(float v)
    {
        m_Value = Float32ToBFloat16(v).Val();
    }

    operator float() const
    {
        return ToFloat32();
    }

    BFloat16& operator=(const BFloat16& other) = default;

    BFloat16& operator=(float v)
    {
        m_Value = Float32ToBFloat16(v).Val();
        return *this;
    }

    bool operator==(const BFloat16& r) const
    {
        return m_Value == r.Val();
    }

    static BFloat16 Float32ToBFloat16(const float v)
    {
        if (std::isnan(v))
        {
            return Nan();
        }
        else
        {
            // Round value to the nearest even
            // Float32
            // S EEEEEEEE MMMMMMLRMMMMMMMMMMMMMMM
            // BFloat16
            // S EEEEEEEE MMMMMML
            // LSB (L): Least significat bit of BFloat16 (last bit of the Mantissa of BFloat16)
            // R: Rounding bit
            // LSB = 0, R = 0 -> round down
            // LSB = 1, R = 0 -> round down
            // LSB = 0, R = 1, all the rest = 0 -> round down
            // LSB = 1, R = 1 -> round up
            // LSB = 0, R = 1 -> round up
            const uint32_t* u32 = reinterpret_cast<const uint32_t*>(&v);
            uint16_t u16 = static_cast<uint16_t>(*u32 >> 16u);
            // Mark the LSB
            const uint16_t lsb = u16 & 0x0001;
            // Mark the error to be truncate (the rest of 16 bits of FP32)
            const uint16_t error = static_cast<uint16_t>((*u32 & 0x0000FFFF));
            if ((error > 0x8000 || (error == 0x8000 && lsb == 1)))
            {
                u16++;
            }
            BFloat16 b(u16);
            return b;
        }
    }

    float ToFloat32() const
    {
        const uint32_t u32 = static_cast<uint32_t>(m_Value << 16u);
        const float* f32 = reinterpret_cast<const float*>(&u32);
        return *f32;
    }

    uint16_t Val() const
    {
        return m_Value;
    }

    static BFloat16 Max()
    {
        uint16_t max = 0x7F7F;
        return BFloat16(max);
    }

    static BFloat16 Nan()
    {
        uint16_t nan = 0x7FC0;
        return BFloat16(nan);
    }

    static BFloat16 Inf()
    {
        uint16_t infVal = 0x7F80;
        return BFloat16(infVal);
    }

private:
    uint16_t m_Value;
};

inline std::ostream& operator<<(std::ostream& os, const BFloat16& b)
{
    os << b.ToFloat32() << "(0x" << std::hex << b.Val() << ")";
    return os;
}

} //namespace armnn
<commit_msg>Fix undefined reinterpret_cast in BFloat16.hpp<commit_after>//
// Copyright © 2020 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <ostream>
#include <cmath>
#include <cstring>
#include <stdint.h>

namespace armnn
{
class BFloat16
{
public:
    BFloat16()
    : m_Value(0)
    {}

    BFloat16(const BFloat16& v) = default;

    explicit BFloat16(uint16_t v)
    : m_Value(v)
    {}

    explicit BFloat16(float v)
    {
        m_Value = Float32ToBFloat16(v).Val();
    }

    operator float() const
    {
        return ToFloat32();
    }

    BFloat16& operator=(const BFloat16& other) = default;

    BFloat16& operator=(float v)
    {
        m_Value = Float32ToBFloat16(v).Val();
        return *this;
    }

    bool operator==(const BFloat16& r) const
    {
        return m_Value == r.Val();
    }

    static BFloat16 Float32ToBFloat16(const float v)
    {
        if (std::isnan(v))
        {
            return Nan();
        }
        else
        {
            // Round value to the nearest even
            // Float32
            // S EEEEEEEE MMMMMMLRMMMMMMMMMMMMMMM
            // BFloat16
            // S EEEEEEEE MMMMMML
            // LSB (L): Least significat bit of BFloat16 (last bit of the Mantissa of BFloat16)
            // R: Rounding bit
            // LSB = 0, R = 0 -> round down
            // LSB = 1, R = 0 -> round down
            // LSB = 0, R = 1, all the rest = 0 -> round down
            // LSB = 1, R = 1 -> round up
            // LSB = 0, R = 1 -> round up
            const uint32_t* u32 = reinterpret_cast<const uint32_t*>(&v);
            uint16_t u16 = static_cast<uint16_t>(*u32 >> 16u);
            // Mark the LSB
            const uint16_t lsb = u16 & 0x0001;
            // Mark the error to be truncate (the rest of 16 bits of FP32)
            const uint16_t error = static_cast<uint16_t>((*u32 & 0x0000FFFF));
            if ((error > 0x8000 || (error == 0x8000 && lsb == 1)))
            {
                u16++;
            }
            BFloat16 b(u16);
            return b;
        }
    }

    float ToFloat32() const
    {
        const uint32_t u32 = static_cast<uint32_t>(m_Value << 16u);
        float f32;
        static_assert(sizeof u32 == sizeof f32, "");
        std::memcpy(&f32, &u32, sizeof u32);
        return f32;
    }

    uint16_t Val() const
    {
        return m_Value;
    }

    static BFloat16 Max()
    {
        uint16_t max = 0x7F7F;
        return BFloat16(max);
    }

    static BFloat16 Nan()
    {
        uint16_t nan = 0x7FC0;
        return BFloat16(nan);
    }

    static BFloat16 Inf()
    {
        uint16_t infVal = 0x7F80;
        return BFloat16(infVal);
    }

private:
    uint16_t m_Value;
};

inline std::ostream& operator<<(std::ostream& os, const BFloat16& b)
{
    os << b.ToFloat32() << "(0x" << std::hex << b.Val() << ")";
    return os;
}

} //namespace armnn
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlelementwrapper_xmlsecimpl.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 17:28:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX
#define _XMLELEMENTWRAPPER_XMLSECIMPL_HXX

#ifndef _COM_SUN_STAR_XML_WRAPPER_XXMLELEMENTWRAPPER_HPP_
#include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif

#include <libxml/tree.h>

class XMLElementWrapper_XmlSecImpl : public cppu::WeakImplHelper3
<
    com::sun::star::xml::wrapper::XXMLElementWrapper,
    com::sun::star::lang::XUnoTunnel,
    com::sun::star::lang::XServiceInfo
>
/****** XMLElementWrapper_XmlSecImpl.hxx/CLASS XMLElementWrapper_XmlSecImpl ***
 *
 *   NAME
 *  XMLElementWrapper_XmlSecImpl -- Class to wrap a libxml2 node
 *
 *   FUNCTION
 *  Used as a wrapper class to transfer a libxml2 node structure
 *  between different UNO components.
 *
 *   HISTORY
 *  05.01.2004 -    Interface supported: XXMLElementWrapper, XUnoTunnel
 *          XServiceInfo
 *
 *   AUTHOR
 *  Michael Mi
 *  Email: michael.mi@sun.com
 ******************************************************************************/
{
private:
    /* the libxml2 node wrapped by this object */
    xmlNodePtr m_pElement;

public:
    explicit XMLElementWrapper_XmlSecImpl(const xmlNodePtr pNode);
    virtual ~XMLElementWrapper_XmlSecImpl() {};

    /* XXMLElementWrapper */

    /* com::sun::star::lang::XUnoTunnel */
    virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw (com::sun::star::uno::RuntimeException);
    static com::sun::star::uno::Sequence < sal_Int8 > getUnoTunnelImplementationId( void )
        throw(com::sun::star::uno::RuntimeException);

    /* com::sun::star::lang::XServiceInfo */
    virtual rtl::OUString SAL_CALL getImplementationName(  )
        throw (com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName )
        throw (com::sun::star::uno::RuntimeException);
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw (com::sun::star::uno::RuntimeException);

public:
    xmlNodePtr getNativeElement( ) const;
    void setNativeElement(const xmlNodePtr pNode);
};

rtl::OUString XMLElementWrapper_XmlSecImpl_getImplementationName()
    throw ( com::sun::star::uno::RuntimeException );

sal_Bool SAL_CALL XMLElementWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL XMLElementWrapper_XmlSecImpl_getSupportedServiceNames(  )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
SAL_CALL XMLElementWrapper_XmlSecImpl_createInstance(
    const com::sun::star::uno::Reference<
        com::sun::star::lang::XMultiServiceFactory > & rSMgr)
    throw ( com::sun::star::uno::Exception );

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.2.190); FILE MERGED 2008/04/01 16:11:02 thb 1.2.190.3: #i85898# Stripping all external header guards 2008/04/01 13:06:24 thb 1.2.190.2: #i85898# Stripping all external header guards 2008/03/31 16:31:03 rt 1.2.190.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: xmlelementwrapper_xmlsecimpl.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX
#define _XMLELEMENTWRAPPER_XMLSECIMPL_HXX

#include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <cppuhelper/implbase3.hxx>

#include <libxml/tree.h>

class XMLElementWrapper_XmlSecImpl : public cppu::WeakImplHelper3
<
    com::sun::star::xml::wrapper::XXMLElementWrapper,
    com::sun::star::lang::XUnoTunnel,
    com::sun::star::lang::XServiceInfo
>
/****** XMLElementWrapper_XmlSecImpl.hxx/CLASS XMLElementWrapper_XmlSecImpl ***
 *
 *   NAME
 *  XMLElementWrapper_XmlSecImpl -- Class to wrap a libxml2 node
 *
 *   FUNCTION
 *  Used as a wrapper class to transfer a libxml2 node structure
 *  between different UNO components.
 *
 *   HISTORY
 *  05.01.2004 -    Interface supported: XXMLElementWrapper, XUnoTunnel
 *          XServiceInfo
 *
 *   AUTHOR
 *  Michael Mi
 *  Email: michael.mi@sun.com
 ******************************************************************************/
{
private:
    /* the libxml2 node wrapped by this object */
    xmlNodePtr m_pElement;

public:
    explicit XMLElementWrapper_XmlSecImpl(const xmlNodePtr pNode);
    virtual ~XMLElementWrapper_XmlSecImpl() {};

    /* XXMLElementWrapper */

    /* com::sun::star::lang::XUnoTunnel */
    virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw (com::sun::star::uno::RuntimeException);
    static com::sun::star::uno::Sequence < sal_Int8 > getUnoTunnelImplementationId( void )
        throw(com::sun::star::uno::RuntimeException);

    /* com::sun::star::lang::XServiceInfo */
    virtual rtl::OUString SAL_CALL getImplementationName(  )
        throw (com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName )
        throw (com::sun::star::uno::RuntimeException);
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw (com::sun::star::uno::RuntimeException);

public:
    xmlNodePtr getNativeElement( ) const;
    void setNativeElement(const xmlNodePtr pNode);
};

rtl::OUString XMLElementWrapper_XmlSecImpl_getImplementationName()
    throw ( com::sun::star::uno::RuntimeException );

sal_Bool SAL_CALL XMLElementWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL XMLElementWrapper_XmlSecImpl_getSupportedServiceNames(  )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
SAL_CALL XMLElementWrapper_XmlSecImpl_createInstance(
    const com::sun::star::uno::Reference<
        com::sun::star::lang::XMultiServiceFactory > & rSMgr)
    throw ( com::sun::star::uno::Exception );

#endif

<|endoftext|>


<commit_before>#include <miniMAT/util/PrintResult.hpp>

#include <iostream>
#include <iomanip>

namespace miniMAT {
	namespace util {
		void PrintResult(std::string varname, Matrix m, bool suppressed) {
			if (!suppressed) {
                // Print a row at a time (default precision is 4)
                std::cout << varname << " =" << std::endl << std::endl;
                for (int i = 0; i < m.rows(); i++) {
                    std::cout << "    ";
                    for (int j = 0; j < m.cols(); j++)
                        std::cout << std::fixed << std::showpoint << std::setprecision(4) << m(i,j) << " ";
                    std::cout << std::endl;
                }
                std::cout << std::endl;
            }
		}
	}
}<commit_msg>Fix formatting for matrix output<commit_after>#include <miniMAT/util/PrintResult.hpp>

#include <iostream>
#include <iomanip>
#include <cmath>

namespace miniMAT {
	namespace util {
		void PrintResult(std::string varname, Matrix m, bool suppressed) {
			if (!suppressed) {
                using namespace std;

                int maxdigits = log10(m.maxCoeff()) + 1;    // Get number of digits of max element
                int precision = 4;
                int space = 1, dot = 1;

                // Print a row at a time (default precision is 4)
                cout << varname << " =" << endl << endl;
                for (int i = 0; i < m.rows(); i++) {
                    cout << "    ";
                    for (int j = 0; j < m.cols(); j++)
                        cout << right
                             << fixed
                             << showpoint
                             << setprecision(precision)
                             << setw(maxdigits + precision + dot + space)
                             << m(i,j);
                    cout << endl;
                }
                cout << endl;
            }
		}
	}
}<|endoftext|>