<commit_before>/*
 * PyClaw.cpp
 *
 *  Created on: Feb 18, 2012
 *      Author: kristof
 */

#include "peanoclaw/native/SWEKernel.h"

#include "peanoclaw/Patch.h"
#include "peanoclaw/geometry/Region.h"
#include "peanoclaw/interSubgridCommunication/DefaultTransfer.h"
#include "peanoclaw/native/SWE_WavePropagationBlock_patch.hh"

#include "tarch/multicore/MulticoreDefinitions.h"
#include "tarch/timing/Watch.h"
#include "tarch/parallel/Node.h"

tarch::logging::Log peanoclaw::native::SWEKernel::_log("peanoclaw::native::SWEKernel");

void peanoclaw::native::SWEKernel::transformWaterHeight(
  peanoclaw::Patch& subgrid,
  const peanoclaw::geometry::Region&       region,
  bool              modifyUOld,
  bool              absoluteToAboveSeaFloor
) const {
  peanoclaw::grid::SubgridAccessor accessor = subgrid.getAccessor();
  double sign = absoluteToAboveSeaFloor ? -1 : +1;
  if(modifyUOld) {
    dfor(internalSubcellIndex, region._size) {
      tarch::la::Vector<DIMENSIONS,int> subcellIndex = internalSubcellIndex + region._offset;
      accessor.setValueUOld(
        subcellIndex,
        0,
        accessor.getValueUOld(subcellIndex, 0) + sign * accessor.getParameterWithGhostlayer(subcellIndex, 0)
      );
    }
  } else {
    dfor(internalSubcellIndex, region._size) {
      tarch::la::Vector<DIMENSIONS,int> subcellIndex = internalSubcellIndex + region._offset;
      accessor.setValueUNew(
        subcellIndex,
        0,
        accessor.getValueUNew(subcellIndex, 0) + sign * accessor.getParameterWithGhostlayer(subcellIndex, 0)
      );
    }
  }
}

void peanoclaw::native::SWEKernel::advanceBlockInTime(
  SWE_WavePropagationBlock_patch& block,
  peanoclaw::Patch& subgrid,
  double maximumTimestepSize
) {
  peanoclaw::grid::SubgridAccessor accessor = subgrid.getAccessor();

  block.setArrays(
        subgrid,
        reinterpret_cast<float*>(accessor.getUOldWithGhostlayerArray(0)),
        reinterpret_cast<float*>(accessor.getUOldWithGhostlayerArray(1)),
        reinterpret_cast<float*>(accessor.getUOldWithGhostlayerArray(2)),
        reinterpret_cast<float*>(accessor.getParameterWithoutGhostlayerArray(0))
      );

  block.computeNumericalFluxes();

  double dt = fmin(block.getMaxTimestep(), maximumTimestepSize);
  double estimatedNextTimestepSize = block.getMaxTimestep();

  block.updateUnknowns(dt);

  peanoclaw::interSubgridCommunication::DefaultTransfer transfer;
  transfer.swapUNewAndUOld(subgrid);

  assertion4(
      tarch::la::greater(subgrid.getTimeIntervals().getTimestepSize(), 0.0)
      || tarch::la::greater(estimatedNextTimestepSize, 0.0)
      || tarch::la::equals(maximumTimestepSize, 0.0)
      || tarch::la::equals(subgrid.getTimeIntervals().getEstimatedNextTimestepSize(), 0.0),
      subgrid, maximumTimestepSize, estimatedNextTimestepSize, subgrid.toStringUNew());
  assertion(subgrid.getTimeIntervals().getTimestepSize() < std::numeric_limits<double>::infinity());

  if (tarch::la::greater(dt, 0.0)) {
    subgrid.getTimeIntervals().advanceInTime();
    subgrid.getTimeIntervals().setTimestepSize(dt);
  }
  subgrid.getTimeIntervals().setEstimatedNextTimestepSize(estimatedNextTimestepSize);
}

peanoclaw::native::SWEKernel::SWEKernel(
  peanoclaw::native::scenarios::SWEScenario& scenario,
  peanoclaw::interSubgridCommunication::DefaultTransfer* transfer,
  peanoclaw::interSubgridCommunication::Interpolation*   interpolation,
  peanoclaw::interSubgridCommunication::Restriction*     restriction,
  peanoclaw::interSubgridCommunication::FluxCorrection*  fluxCorrection
) : Numerics(transfer, interpolation, restriction, fluxCorrection),
_totalSolverCallbackTime(0.0),
_scenario(scenario),
_cachedSubdivisionFactor(-1),
_cachedGhostlayerWidth(-1),
_cachedBlock(0)
{
  //import_array();
}

peanoclaw::native::SWEKernel::~SWEKernel()
{
}

void peanoclaw::native::SWEKernel::initializePatch(
  Patch& patch
) {
  logTraceIn( "initializePatch(...)");

  _scenario.initializePatch(patch);

  logTraceOutWith1Argument( "initializePatch(...)", demandedMeshWidth);
}

void peanoclaw::native::SWEKernel::update(Patch& subgrid) {
  _scenario.update(subgrid);
}

void peanoclaw::native::SWEKernel::solveTimestep(
  Patch& subgrid,
  double maximumTimestepSize,
  bool useDimensionalSplitting,
  tarch::la::Vector<DIMENSIONS_TIMES_TWO, bool> domainBoundaryFlags
) {
  logTraceInWith2Arguments( "solveTimestep(...)", maximumTimestepSize, useDimensionalSplitting);

  assertion2(tarch::la::greater(maximumTimestepSize, 0.0), "Timestepsize == 0 should be checked outside.", subgrid.getTimeIntervals().getMinimalNeighborTimeConstraint());

  tarch::timing::Watch solverWatch("", "", false);
  solverWatch.startTimer();

  #ifdef SharedMemoryParallelisation
  SWE_WavePropagationBlock_patch block(subgrid);
  advanceBlockInTime(
    block,
    subgrid,
    maximumTimestepSize
  );
  #else
  if(
    _cachedSubdivisionFactor != subgrid.getSubdivisionFactor()
    || _cachedGhostlayerWidth != subgrid.getGhostlayerWidth()
  ) {
    //SWE_WavePropagationBlock_patch swe(patch);
    _cachedBlock = std::auto_ptr<SWE_WavePropagationBlock_patch>(new SWE_WavePropagationBlock_patch(subgrid));
    _cachedSubdivisionFactor = subgrid.getSubdivisionFactor();
    _cachedGhostlayerWidth = subgrid.getGhostlayerWidth();
  }

  advanceBlockInTime(
    *_cachedBlock,
    subgrid,
    maximumTimestepSize
  );
  #endif

  solverWatch.stopTimer();
  _totalSolverCallbackTime += solverWatch.getCalendarTime();

  logTraceOut( "solveTimestep(...)");
}

tarch::la::Vector<DIMENSIONS, double> peanoclaw::native::SWEKernel::getDemandedMeshWidth(Patch& patch, bool isInitializing) {
  return _scenario.computeDemandedMeshWidth(patch, isInitializing);
}

void peanoclaw::native::SWEKernel::addPatchToSolution(Patch& patch) {
}

void peanoclaw::native::SWEKernel::fillBoundaryLayer(Patch& patch, int dimension, bool setUpper) {
  logTraceInWith3Arguments("fillBoundaryLayerInPyClaw", patch, dimension, setUpper);

  logDebug("fillBoundaryLayerInPyClaw", "Setting left boundary for " << patch.getPosition() << ", dim=" << dimension << ", setUpper=" << setUpper);

   //std::cout << "------ setUpper " << setUpper << " dimension " << dimension << std::endl;
   //std::cout << patch << std::endl;
   //std::cout << "++++++" << std::endl;
   //std::cout << patch.toStringUOldWithGhostLayer() << std::endl;
   //std::cout << "||||||" << std::endl;

   // implement a wall boundary
    tarch::la::Vector<DIMENSIONS, int> src_subcellIndex;
    tarch::la::Vector<DIMENSIONS, int> dest_subcellIndex;

    peanoclaw::grid::SubgridAccessor& accessor = patch.getAccessor();

    if (dimension == 0) {
        for (int yi = -1; yi < patch.getSubdivisionFactor()(1)+1; yi++) {
            int xi = setUpper ? patch.getSubdivisionFactor()(0) : -1;
            src_subcellIndex(0) = xi;
            src_subcellIndex(1) = yi;
            src_subcellIndex(dimension) += setUpper ? -1 : +1;

            dest_subcellIndex(0) = xi;
            dest_subcellIndex(1) = yi;

            for (int unknown=0; unknown < patch.getUnknownsPerSubcell(); unknown++) {
                double q = accessor.getValueUOld(src_subcellIndex, unknown);

                if (unknown == dimension + 1) {
                  accessor.setValueUOld(dest_subcellIndex, unknown, -q);
                } else {
                  accessor.setValueUOld(dest_subcellIndex, unknown, q);
                }
            }
        }

    } else {
        for (int xi = -1; xi < patch.getSubdivisionFactor()(0)+1; xi++) {
            int yi = setUpper ? patch.getSubdivisionFactor()(1) : -1;
            src_subcellIndex(0) = xi;
            src_subcellIndex(1) = yi;
            src_subcellIndex(dimension) += setUpper ? -1 : +1;

            dest_subcellIndex(0) = xi;
            dest_subcellIndex(1) = yi;

            for (int unknown=0; unknown < patch.getUnknownsPerSubcell(); unknown++) {
                double q = accessor.getValueUOld(src_subcellIndex, unknown);

                if (unknown == dimension + 1) {
                  accessor.setValueUOld(dest_subcellIndex, unknown, -q);
                } else {
                  accessor.setValueUOld(dest_subcellIndex, unknown, q);
                }
            }
        }
    }

      logTraceOut("fillBoundaryLayerInPyClaw");
    }

void peanoclaw::native::SWEKernel::interpolateSolution (
  const tarch::la::Vector<DIMENSIONS, int>& destinationSize,
  const tarch::la::Vector<DIMENSIONS, int>& destinationOffset,
  peanoclaw::Patch& source,
  peanoclaw::Patch& destination,
  bool interpolateToUOld,
  bool interpolateToCurrentTime,
  bool useTimeUNewOrTimeUOld
) const {
  peanoclaw::grid::SubgridAccessor sourceAccessor = source.getAccessor();
  peanoclaw::grid::SubgridAccessor destinationAccessor = destination.getAccessor();
  tarch::la::Vector<DIMENSIONS,int> sourceSubdivisionFactor = source.getSubdivisionFactor();

  peanoclaw::geometry::Region destinationRegion(destinationOffset, destinationSize);
  peanoclaw::geometry::Region sourceRegion = destinationRegion.mapToPatch(destination, source);

  //Increase sourceRegion by one cell in each direction.
  for(int d = 0; d < DIMENSIONS; d++) {
    if(sourceRegion._offset[d] > 0) {
      sourceRegion._offset[d] = sourceRegion._offset[d]-1;
      sourceRegion._size[d] = std::min(sourceSubdivisionFactor[d], sourceRegion._size[d] + 2);
    } else {
      sourceRegion._size[d] = std::min(sourceSubdivisionFactor[d], sourceRegion._size[d] + 1);
    }
  }

  //Source: Water Height above Sea Floor -> Absolute Water Height
  transformWaterHeight(source, sourceRegion, true, false); //UOld
  transformWaterHeight(source, sourceRegion, false, false); // UNew

  //Interpolate
  Numerics::interpolateSolution (
    destinationSize,
    destinationOffset,
    source,
    destination,
    interpolateToUOld,
    interpolateToCurrentTime,
    useTimeUNewOrTimeUOld
  );

  //Source: Absolute Water Height -> Water Height above Sea Floor
  transformWaterHeight(source, sourceRegion, true, true); //UOld
  transformWaterHeight(source, sourceRegion, false, true); // UNew

  //Destination: Absolute Water Height -> Water Height above Sea Floor
  transformWaterHeight(destination, destinationRegion, interpolateToUOld, true);
}

void peanoclaw::native::SWEKernel::restrictSolution (
  peanoclaw::Patch& source,
  peanoclaw::Patch& destination,
  bool              restrictOnlyOverlappedRegions
) const {

  peanoclaw::geometry::Region sourceRegion(tarch::la::Vector<DIMENSIONS,int>(0), source.getSubdivisionFactor());

  transformWaterHeight(source, sourceRegion, true, false); //UOld
  transformWaterHeight(source, sourceRegion, false, false); //UNew

  Numerics::restrictSolution(
    source,
    destination,
    restrictOnlyOverlappedRegions
  );

  transformWaterHeight(source, sourceRegion, true, true); //UOld
  transformWaterHeight(source, sourceRegion, false, true); //UNew
}

void peanoclaw::native::SWEKernel::postProcessRestriction(
  peanoclaw::Patch& destination,
  bool              restrictOnlyOverlappedRegions
) const {
  peanoclaw::geometry::Region destinationRegion(tarch::la::Vector<DIMENSIONS,int>(0), destination.getSubdivisionFactor());
  transformWaterHeight(destination, destinationRegion, true, true); //UOld
  transformWaterHeight(destination, destinationRegion, false, true); //UNew
}

<commit_msg>fixed<commit_after>/*
 * PyClaw.cpp
 *
 *  Created on: Feb 18, 2012
 *      Author: kristof
 */

#include "peanoclaw/native/SWEKernel.h"

#include "peanoclaw/Patch.h"
#include "peanoclaw/geometry/Region.h"
#include "peanoclaw/interSubgridCommunication/DefaultTransfer.h"
#include "peanoclaw/native/SWE_WavePropagationBlock_patch.hh"

#include "tarch/multicore/MulticoreDefinitions.h"
#include "tarch/timing/Watch.h"
#include "tarch/parallel/Node.h"

tarch::logging::Log peanoclaw::native::SWEKernel::_log("peanoclaw::native::SWEKernel");

void peanoclaw::native::SWEKernel::transformWaterHeight(
  peanoclaw::Patch& subgrid,
  const peanoclaw::geometry::Region&       region,
  bool              modifyUOld,
  bool              absoluteToAboveSeaFloor
) const {
  peanoclaw::grid::SubgridAccessor accessor = subgrid.getAccessor();
  double sign = absoluteToAboveSeaFloor ? -1 : +1;
  if(modifyUOld) {
    dfor(internalSubcellIndex, region._size) {
      tarch::la::Vector<DIMENSIONS,int> subcellIndex = internalSubcellIndex + region._offset;
      accessor.setValueUOld(
        subcellIndex,
        0,
        accessor.getValueUOld(subcellIndex, 0) + sign * accessor.getParameterWithGhostlayer(subcellIndex, 0)
      );
    }
  } else {
    dfor(internalSubcellIndex, region._size) {
      tarch::la::Vector<DIMENSIONS,int> subcellIndex = internalSubcellIndex + region._offset;
      accessor.setValueUNew(
        subcellIndex,
        0,
        accessor.getValueUNew(subcellIndex, 0) + sign * accessor.getParameterWithGhostlayer(subcellIndex, 0)
      );
    }
  }
}

void peanoclaw::native::SWEKernel::advanceBlockInTime(
  SWE_WavePropagationBlock_patch& block,
  peanoclaw::Patch& subgrid,
  double maximumTimestepSize
) {
  peanoclaw::grid::SubgridAccessor accessor = subgrid.getAccessor();

  block.setArrays(
        subgrid,
        reinterpret_cast<float*>(accessor.getUOldWithGhostLayerArray(0)),
        reinterpret_cast<float*>(accessor.getUOldWithGhostLayerArray(1)),
        reinterpret_cast<float*>(accessor.getUOldWithGhostLayerArray(2)),
        reinterpret_cast<float*>(accessor.getParameterWithoutGhostLayerArray(0))
      );

  block.computeNumericalFluxes();

  double dt = fmin(block.getMaxTimestep(), maximumTimestepSize);
  double estimatedNextTimestepSize = block.getMaxTimestep();

  block.updateUnknowns(dt);

  peanoclaw::interSubgridCommunication::DefaultTransfer transfer;
  transfer.swapUNewAndUOld(subgrid);

  assertion4(
      tarch::la::greater(subgrid.getTimeIntervals().getTimestepSize(), 0.0)
      || tarch::la::greater(estimatedNextTimestepSize, 0.0)
      || tarch::la::equals(maximumTimestepSize, 0.0)
      || tarch::la::equals(subgrid.getTimeIntervals().getEstimatedNextTimestepSize(), 0.0),
      subgrid, maximumTimestepSize, estimatedNextTimestepSize, subgrid.toStringUNew());
  assertion(subgrid.getTimeIntervals().getTimestepSize() < std::numeric_limits<double>::infinity());

  if (tarch::la::greater(dt, 0.0)) {
    subgrid.getTimeIntervals().advanceInTime();
    subgrid.getTimeIntervals().setTimestepSize(dt);
  }
  subgrid.getTimeIntervals().setEstimatedNextTimestepSize(estimatedNextTimestepSize);
}

peanoclaw::native::SWEKernel::SWEKernel(
  peanoclaw::native::scenarios::SWEScenario& scenario,
  peanoclaw::interSubgridCommunication::DefaultTransfer* transfer,
  peanoclaw::interSubgridCommunication::Interpolation*   interpolation,
  peanoclaw::interSubgridCommunication::Restriction*     restriction,
  peanoclaw::interSubgridCommunication::FluxCorrection*  fluxCorrection
) : Numerics(transfer, interpolation, restriction, fluxCorrection),
_totalSolverCallbackTime(0.0),
_scenario(scenario),
_cachedSubdivisionFactor(-1),
_cachedGhostlayerWidth(-1),
_cachedBlock(0)
{
  //import_array();
}

peanoclaw::native::SWEKernel::~SWEKernel()
{
}

void peanoclaw::native::SWEKernel::initializePatch(
  Patch& patch
) {
  logTraceIn( "initializePatch(...)");

  _scenario.initializePatch(patch);

  logTraceOutWith1Argument( "initializePatch(...)", demandedMeshWidth);
}

void peanoclaw::native::SWEKernel::update(Patch& subgrid) {
  _scenario.update(subgrid);
}

void peanoclaw::native::SWEKernel::solveTimestep(
  Patch& subgrid,
  double maximumTimestepSize,
  bool useDimensionalSplitting,
  tarch::la::Vector<DIMENSIONS_TIMES_TWO, bool> domainBoundaryFlags
) {
  logTraceInWith2Arguments( "solveTimestep(...)", maximumTimestepSize, useDimensionalSplitting);

  assertion2(tarch::la::greater(maximumTimestepSize, 0.0), "Timestepsize == 0 should be checked outside.", subgrid.getTimeIntervals().getMinimalNeighborTimeConstraint());

  tarch::timing::Watch solverWatch("", "", false);
  solverWatch.startTimer();

  #ifdef SharedMemoryParallelisation
  SWE_WavePropagationBlock_patch block(subgrid);
  advanceBlockInTime(
    block,
    subgrid,
    maximumTimestepSize
  );
  #else
  if(
    _cachedSubdivisionFactor != subgrid.getSubdivisionFactor()
    || _cachedGhostlayerWidth != subgrid.getGhostlayerWidth()
  ) {
    //SWE_WavePropagationBlock_patch swe(patch);
    _cachedBlock = std::auto_ptr<SWE_WavePropagationBlock_patch>(new SWE_WavePropagationBlock_patch(subgrid));
    _cachedSubdivisionFactor = subgrid.getSubdivisionFactor();
    _cachedGhostlayerWidth = subgrid.getGhostlayerWidth();
  }

  advanceBlockInTime(
    *_cachedBlock,
    subgrid,
    maximumTimestepSize
  );
  #endif

  solverWatch.stopTimer();
  _totalSolverCallbackTime += solverWatch.getCalendarTime();

  logTraceOut( "solveTimestep(...)");
}

tarch::la::Vector<DIMENSIONS, double> peanoclaw::native::SWEKernel::getDemandedMeshWidth(Patch& patch, bool isInitializing) {
  return _scenario.computeDemandedMeshWidth(patch, isInitializing);
}

void peanoclaw::native::SWEKernel::addPatchToSolution(Patch& patch) {
}

void peanoclaw::native::SWEKernel::fillBoundaryLayer(Patch& patch, int dimension, bool setUpper) {
  logTraceInWith3Arguments("fillBoundaryLayerInPyClaw", patch, dimension, setUpper);

  logDebug("fillBoundaryLayerInPyClaw", "Setting left boundary for " << patch.getPosition() << ", dim=" << dimension << ", setUpper=" << setUpper);

   //std::cout << "------ setUpper " << setUpper << " dimension " << dimension << std::endl;
   //std::cout << patch << std::endl;
   //std::cout << "++++++" << std::endl;
   //std::cout << patch.toStringUOldWithGhostLayer() << std::endl;
   //std::cout << "||||||" << std::endl;

   // implement a wall boundary
    tarch::la::Vector<DIMENSIONS, int> src_subcellIndex;
    tarch::la::Vector<DIMENSIONS, int> dest_subcellIndex;

    peanoclaw::grid::SubgridAccessor& accessor = patch.getAccessor();

    if (dimension == 0) {
        for (int yi = -1; yi < patch.getSubdivisionFactor()(1)+1; yi++) {
            int xi = setUpper ? patch.getSubdivisionFactor()(0) : -1;
            src_subcellIndex(0) = xi;
            src_subcellIndex(1) = yi;
            src_subcellIndex(dimension) += setUpper ? -1 : +1;

            dest_subcellIndex(0) = xi;
            dest_subcellIndex(1) = yi;

            for (int unknown=0; unknown < patch.getUnknownsPerSubcell(); unknown++) {
                double q = accessor.getValueUOld(src_subcellIndex, unknown);

                if (unknown == dimension + 1) {
                  accessor.setValueUOld(dest_subcellIndex, unknown, -q);
                } else {
                  accessor.setValueUOld(dest_subcellIndex, unknown, q);
                }
            }
        }

    } else {
        for (int xi = -1; xi < patch.getSubdivisionFactor()(0)+1; xi++) {
            int yi = setUpper ? patch.getSubdivisionFactor()(1) : -1;
            src_subcellIndex(0) = xi;
            src_subcellIndex(1) = yi;
            src_subcellIndex(dimension) += setUpper ? -1 : +1;

            dest_subcellIndex(0) = xi;
            dest_subcellIndex(1) = yi;

            for (int unknown=0; unknown < patch.getUnknownsPerSubcell(); unknown++) {
                double q = accessor.getValueUOld(src_subcellIndex, unknown);

                if (unknown == dimension + 1) {
                  accessor.setValueUOld(dest_subcellIndex, unknown, -q);
                } else {
                  accessor.setValueUOld(dest_subcellIndex, unknown, q);
                }
            }
        }
    }

      logTraceOut("fillBoundaryLayerInPyClaw");
    }

void peanoclaw::native::SWEKernel::interpolateSolution (
  const tarch::la::Vector<DIMENSIONS, int>& destinationSize,
  const tarch::la::Vector<DIMENSIONS, int>& destinationOffset,
  peanoclaw::Patch& source,
  peanoclaw::Patch& destination,
  bool interpolateToUOld,
  bool interpolateToCurrentTime,
  bool useTimeUNewOrTimeUOld
) const {
  peanoclaw::grid::SubgridAccessor sourceAccessor = source.getAccessor();
  peanoclaw::grid::SubgridAccessor destinationAccessor = destination.getAccessor();
  tarch::la::Vector<DIMENSIONS,int> sourceSubdivisionFactor = source.getSubdivisionFactor();

  peanoclaw::geometry::Region destinationRegion(destinationOffset, destinationSize);
  peanoclaw::geometry::Region sourceRegion = destinationRegion.mapToPatch(destination, source);

  //Increase sourceRegion by one cell in each direction.
  for(int d = 0; d < DIMENSIONS; d++) {
    if(sourceRegion._offset[d] > 0) {
      sourceRegion._offset[d] = sourceRegion._offset[d]-1;
      sourceRegion._size[d] = std::min(sourceSubdivisionFactor[d], sourceRegion._size[d] + 2);
    } else {
      sourceRegion._size[d] = std::min(sourceSubdivisionFactor[d], sourceRegion._size[d] + 1);
    }
  }

  //Source: Water Height above Sea Floor -> Absolute Water Height
  transformWaterHeight(source, sourceRegion, true, false); //UOld
  transformWaterHeight(source, sourceRegion, false, false); // UNew

  //Interpolate
  Numerics::interpolateSolution (
    destinationSize,
    destinationOffset,
    source,
    destination,
    interpolateToUOld,
    interpolateToCurrentTime,
    useTimeUNewOrTimeUOld
  );

  //Source: Absolute Water Height -> Water Height above Sea Floor
  transformWaterHeight(source, sourceRegion, true, true); //UOld
  transformWaterHeight(source, sourceRegion, false, true); // UNew

  //Destination: Absolute Water Height -> Water Height above Sea Floor
  transformWaterHeight(destination, destinationRegion, interpolateToUOld, true);
}

void peanoclaw::native::SWEKernel::restrictSolution (
  peanoclaw::Patch& source,
  peanoclaw::Patch& destination,
  bool              restrictOnlyOverlappedRegions
) const {

  peanoclaw::geometry::Region sourceRegion(tarch::la::Vector<DIMENSIONS,int>(0), source.getSubdivisionFactor());

  transformWaterHeight(source, sourceRegion, true, false); //UOld
  transformWaterHeight(source, sourceRegion, false, false); //UNew

  Numerics::restrictSolution(
    source,
    destination,
    restrictOnlyOverlappedRegions
  );

  transformWaterHeight(source, sourceRegion, true, true); //UOld
  transformWaterHeight(source, sourceRegion, false, true); //UNew
}

void peanoclaw::native::SWEKernel::postProcessRestriction(
  peanoclaw::Patch& destination,
  bool              restrictOnlyOverlappedRegions
) const {
  peanoclaw::geometry::Region destinationRegion(tarch::la::Vector<DIMENSIONS,int>(0), destination.getSubdivisionFactor());
  transformWaterHeight(destination, destinationRegion, true, true); //UOld
  transformWaterHeight(destination, destinationRegion, false, true); //UNew
}

<|endoftext|>


<commit_before>/*
 * perf_counter.c

 *
 *  Created on: Sep 24, 2014
 *      Author: roman
 */
#include <stdlib.h>
#include <stdio.h>
#include <systemlib/perf_counter.h>

perf_counter_t	perf_alloc(enum perf_counter_type type, const char *name)
{
	return NULL;
}

/**
 * Free a counter.
 *
 * @param handle		The performance counter's handle.
 */
void perf_free(perf_counter_t handle)
{

}

/**
 * Count a performance event.
 *
 * This call only affects counters that take single events; PC_COUNT, PC_INTERVAL etc.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_count(perf_counter_t handle)
{

}

/**
 * Begin a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_begin(perf_counter_t handle)
{

}

/**
 * End a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 * If a call is made without a corresopnding perf_begin call, or if perf_cancel
 * has been called subsequently, no change is made to the counter.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_end(perf_counter_t handle)
{

}

/**
 * Cancel a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 * It reverts the effect of a previous perf_begin.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_cancel(perf_counter_t handle)
{

}

/**
 * Reset a performance counter.
 *
 * This call resets performance counter to initial state
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_reset(perf_counter_t handle)
{

}

/**
 * Print one performance counter to stdout
 *
 * @param handle		The counter to print.
 */
void		perf_print_counter(perf_counter_t handle)
{

}

/**
 * Print one performance counter to a fd.
 *
 * @param fd			File descriptor to print to - e.g. 0 for stdout
 * @param handle		The counter to print.
 */
void		perf_print_counter_fd(int fd, perf_counter_t handle)
{

}

/**
 * Print all of the performance counters.
 *
 * @param fd			File descriptor to print to - e.g. 0 for stdout
 */
void		perf_print_all(int fd)
{

}

/**
 * Reset all of the performance counters.
 */
void		perf_reset_all(void)
{

}

/**
 * Return current event_count
 *
 * @param handle		The counter returned from perf_alloc.
 * @return			event_count
 */
uint64_t	perf_event_count(perf_counter_t handle)
{

}

<commit_msg>fix header for cpp perf_counter dummy<commit_after>/****************************************************************************
 *
 *   Copyright (C) 2012 - 2014 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 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.
 *
 ****************************************************************************/

/*
 * @file perf_counter.cpp
 *
 * Empty function calls for ros compatibility
 *
 * @author Roman Bapst <bapstr@ethz.ch>
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <systemlib/perf_counter.h>

perf_counter_t	perf_alloc(enum perf_counter_type type, const char *name)
{
	return NULL;
}

/**
 * Free a counter.
 *
 * @param handle		The performance counter's handle.
 */
void perf_free(perf_counter_t handle)
{

}

/**
 * Count a performance event.
 *
 * This call only affects counters that take single events; PC_COUNT, PC_INTERVAL etc.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_count(perf_counter_t handle)
{

}

/**
 * Begin a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_begin(perf_counter_t handle)
{

}

/**
 * End a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 * If a call is made without a corresopnding perf_begin call, or if perf_cancel
 * has been called subsequently, no change is made to the counter.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_end(perf_counter_t handle)
{

}

/**
 * Cancel a performance event.
 *
 * This call applies to counters that operate over ranges of time; PC_ELAPSED etc.
 * It reverts the effect of a previous perf_begin.
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_cancel(perf_counter_t handle)
{

}

/**
 * Reset a performance counter.
 *
 * This call resets performance counter to initial state
 *
 * @param handle		The handle returned from perf_alloc.
 */
void		perf_reset(perf_counter_t handle)
{

}

/**
 * Print one performance counter to stdout
 *
 * @param handle		The counter to print.
 */
void		perf_print_counter(perf_counter_t handle)
{

}

/**
 * Print one performance counter to a fd.
 *
 * @param fd			File descriptor to print to - e.g. 0 for stdout
 * @param handle		The counter to print.
 */
void		perf_print_counter_fd(int fd, perf_counter_t handle)
{

}

/**
 * Print all of the performance counters.
 *
 * @param fd			File descriptor to print to - e.g. 0 for stdout
 */
void		perf_print_all(int fd)
{

}

/**
 * Reset all of the performance counters.
 */
void		perf_reset_all(void)
{

}

/**
 * Return current event_count
 *
 * @param handle		The counter returned from perf_alloc.
 * @return			event_count
 */
uint64_t	perf_event_count(perf_counter_t handle)
{

}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: namecrea.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: dr $ $Date: 2001-05-23 10:50:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#include "namecrea.hxx"
#include "scresid.hxx"
#include "miscdlgs.hrc"

//==================================================================

ScNameCreateDlg::ScNameCreateDlg( Window * pParent, USHORT nFlags )
    : ModalDialog( pParent, ScResId(RID_SCDLG_NAMES_CREATE) ),
    aTopBox         ( this, ScResId( BTN_TOP ) ),
    aLeftBox        ( this, ScResId( BTN_LEFT ) ),
    aBottomBox      ( this, ScResId( BTN_BOTTOM ) ),
    aRightBox       ( this, ScResId( BTN_RIGHT ) ),
    aOKButton       ( this, ScResId( BTN_OK ) ),
    aCancelButton   ( this, ScResId( BTN_CANCEL ) ),
    aHelpButton     ( this, ScResId( BTN_HELP ) ),
    aFixedLine      ( this, ScResId( FL_FRAME ) )
{
    aTopBox.Check   ( (nFlags & NAME_TOP)   ? TRUE : FALSE );
    aLeftBox.Check  ( (nFlags & NAME_LEFT)  ? TRUE : FALSE );
    aBottomBox.Check( (nFlags & NAME_BOTTOM)? TRUE : FALSE );
    aRightBox.Check ( (nFlags & NAME_RIGHT) ? TRUE : FALSE );

    FreeResource();
}

//------------------------------------------------------------------

USHORT ScNameCreateDlg::GetFlags() const
{
    USHORT  nResult = 0;

    nResult |= aTopBox.IsChecked()      ? NAME_TOP:     0 ;
    nResult |= aLeftBox.IsChecked()     ? NAME_LEFT:    0 ;
    nResult |= aBottomBox.IsChecked()   ? NAME_BOTTOM:  0 ;
    nResult |= aRightBox.IsChecked()    ? NAME_RIGHT:   0 ;

    return nResult;
}

<commit_msg>INTEGRATION: CWS tune03 (1.2.516); FILE MERGED 2004/07/08 16:45:14 mhu 1.2.516.1: #i29979# Added SC_DLLPUBLIC/PRIVATE (see scdllapi.h) to exported symbols/classes.<commit_after>/*************************************************************************
 *
 *  $RCSfile: namecrea.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-23 09:38:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#undef SC_DLLIMPLEMENTATION

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#include "namecrea.hxx"
#include "scresid.hxx"
#include "miscdlgs.hrc"

//==================================================================

ScNameCreateDlg::ScNameCreateDlg( Window * pParent, USHORT nFlags )
    : ModalDialog( pParent, ScResId(RID_SCDLG_NAMES_CREATE) ),
    aTopBox         ( this, ScResId( BTN_TOP ) ),
    aLeftBox        ( this, ScResId( BTN_LEFT ) ),
    aBottomBox      ( this, ScResId( BTN_BOTTOM ) ),
    aRightBox       ( this, ScResId( BTN_RIGHT ) ),
    aOKButton       ( this, ScResId( BTN_OK ) ),
    aCancelButton   ( this, ScResId( BTN_CANCEL ) ),
    aHelpButton     ( this, ScResId( BTN_HELP ) ),
    aFixedLine      ( this, ScResId( FL_FRAME ) )
{
    aTopBox.Check   ( (nFlags & NAME_TOP)   ? TRUE : FALSE );
    aLeftBox.Check  ( (nFlags & NAME_LEFT)  ? TRUE : FALSE );
    aBottomBox.Check( (nFlags & NAME_BOTTOM)? TRUE : FALSE );
    aRightBox.Check ( (nFlags & NAME_RIGHT) ? TRUE : FALSE );

    FreeResource();
}

//------------------------------------------------------------------

USHORT ScNameCreateDlg::GetFlags() const
{
    USHORT  nResult = 0;

    nResult |= aTopBox.IsChecked()      ? NAME_TOP:     0 ;
    nResult |= aLeftBox.IsChecked()     ? NAME_LEFT:    0 ;
    nResult |= aBottomBox.IsChecked()   ? NAME_BOTTOM:  0 ;
    nResult |= aRightBox.IsChecked()    ? NAME_RIGHT:   0 ;

    return nResult;
}

<|endoftext|>


<commit_before>//====--------------- lib/Support/BlockFrequency.cpp -----------*- C++ -*-====//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Block Frequency class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>

using namespace llvm;

/// Multiply FREQ by N and store result in W array.
static void mult96bit(uint64_t freq, uint32_t N, uint64_t W[2]) {
  uint64_t u0 = freq & UINT32_MAX;
  uint64_t u1 = freq >> 32;

  // Represent 96-bit value as w[2]:w[1]:w[0];
  uint32_t w[3] = { 0, 0, 0 };

  uint64_t t = u0 * N;
  uint64_t k = t >> 32;
  w[0] = t;
  t = u1 * N + k;
  w[1] = t;
  w[2] = t >> 32;

  // W[1] - higher bits.
  // W[0] - lower bits.
  W[0] = w[0] + ((uint64_t) w[1] << 32);
  W[1] = w[2];
}

/// Divide 96-bit value stored in W array by D.
/// Return 64-bit quotient, saturated to UINT64_MAX on overflow.
static uint64_t div96bit(uint64_t W[2], uint32_t D) {
  uint64_t y = W[0];
  uint64_t x = W[1];
  unsigned i;

  // This long division algorithm automatically saturates on overflow.
  for (i = 0; i < 64 && x; ++i) {
    uint32_t t = (int)x >> 31;
    x = (x << 1) | (y >> 63);
    y = y << 1;
    if ((x | t) >= D) {
      x -= D;
      ++y;
    }
  }

  return y << (64 - i);
}

void BlockFrequency::scale(uint32_t N, uint32_t D) {
  assert(D != 0 && "Division by zero");

  // Calculate Frequency * N.
  uint64_t MulLo = (Frequency & UINT32_MAX) * N;
  uint64_t MulHi = (Frequency >> 32) * N;
  uint64_t MulRes = (MulHi << 32) + MulLo;

  // If the product fits in 64 bits, just use built-in division.
  if (MulHi <= UINT32_MAX && MulRes <= MulLo) {
    Frequency = MulRes / D;
    return;
  }

  // Product overflowed, use 96-bit operations.
  // 96-bit value represented as W[1]:W[0].
  uint64_t W[2];
  mult96bit(Frequency, N, W);
  Frequency = div96bit(W, D);
  return;
}

BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
  scale(Prob.getNumerator(), Prob.getDenominator());
  return *this;
}

const BlockFrequency
BlockFrequency::operator*(const BranchProbability &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq *= Prob;
  return Freq;
}

BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {
  scale(Prob.getDenominator(), Prob.getNumerator());
  return *this;
}

BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq /= Prob;
  return Freq;
}

BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
  uint64_t Before = Freq.Frequency;
  Frequency += Freq.Frequency;

  // If overflow, set frequency to the maximum value.
  if (Frequency < Before)
    Frequency = UINT64_MAX;

  return *this;
}

const BlockFrequency
BlockFrequency::operator+(const BlockFrequency &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq += Prob;
  return Freq;
}

void BlockFrequency::print(raw_ostream &OS) const {
  // Convert fixed-point number to decimal.
  OS << Frequency / getEntryFrequency() << ".";
  uint64_t Rem = Frequency % getEntryFrequency();
  uint64_t Eps = 1;
  do {
    Rem *= 10;
    Eps *= 10;
    OS << Rem / getEntryFrequency();
    Rem = Rem % getEntryFrequency();
  } while (Rem >= Eps/2);
}

namespace llvm {

raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) {
  Freq.print(OS);
  return OS;
}

}
<commit_msg>Eliminate an assortment of undefined behavior.<commit_after>//====--------------- lib/Support/BlockFrequency.cpp -----------*- C++ -*-====//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Block Frequency class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>

using namespace llvm;

/// Multiply FREQ by N and store result in W array.
static void mult96bit(uint64_t freq, uint32_t N, uint64_t W[2]) {
  uint64_t u0 = freq & UINT32_MAX;
  uint64_t u1 = freq >> 32;

  // Represent 96-bit value as w[2]:w[1]:w[0];
  uint32_t w[3] = { 0, 0, 0 };

  uint64_t t = u0 * N;
  uint64_t k = t >> 32;
  w[0] = t;
  t = u1 * N + k;
  w[1] = t;
  w[2] = t >> 32;

  // W[1] - higher bits.
  // W[0] - lower bits.
  W[0] = w[0] + ((uint64_t) w[1] << 32);
  W[1] = w[2];
}

/// Divide 96-bit value stored in W array by D.
/// Return 64-bit quotient, saturated to UINT64_MAX on overflow.
static uint64_t div96bit(uint64_t W[2], uint32_t D) {
  uint64_t y = W[0];
  uint64_t x = W[1];
  unsigned i;

  // This is really a 64-bit division.
  if (!x)
    return y / D;

  // This long division algorithm automatically saturates on overflow.
  for (i = 0; i < 64 && x; ++i) {
    uint32_t t = -((x >> 31) & 1); // Splat bit 31 to bits 0-31.
    x = (x << 1) | (y >> 63);
    y = y << 1;
    if ((x | t) >= D) {
      x -= D;
      ++y;
    }
  }

  return y << (64 - i);
}

void BlockFrequency::scale(uint32_t N, uint32_t D) {
  assert(D != 0 && "Division by zero");

  // Calculate Frequency * N.
  uint64_t MulLo = (Frequency & UINT32_MAX) * N;
  uint64_t MulHi = (Frequency >> 32) * N;
  uint64_t MulRes = (MulHi << 32) + MulLo;

  // If the product fits in 64 bits, just use built-in division.
  if (MulHi <= UINT32_MAX && MulRes <= MulLo) {
    Frequency = MulRes / D;
    return;
  }

  // Product overflowed, use 96-bit operations.
  // 96-bit value represented as W[1]:W[0].
  uint64_t W[2];
  mult96bit(Frequency, N, W);
  Frequency = div96bit(W, D);
  return;
}

BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
  scale(Prob.getNumerator(), Prob.getDenominator());
  return *this;
}

const BlockFrequency
BlockFrequency::operator*(const BranchProbability &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq *= Prob;
  return Freq;
}

BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {
  scale(Prob.getDenominator(), Prob.getNumerator());
  return *this;
}

BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq /= Prob;
  return Freq;
}

BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
  uint64_t Before = Freq.Frequency;
  Frequency += Freq.Frequency;

  // If overflow, set frequency to the maximum value.
  if (Frequency < Before)
    Frequency = UINT64_MAX;

  return *this;
}

const BlockFrequency
BlockFrequency::operator+(const BlockFrequency &Prob) const {
  BlockFrequency Freq(Frequency);
  Freq += Prob;
  return Freq;
}

void BlockFrequency::print(raw_ostream &OS) const {
  // Convert fixed-point number to decimal.
  OS << Frequency / getEntryFrequency() << ".";
  uint64_t Rem = Frequency % getEntryFrequency();
  uint64_t Eps = 1;
  do {
    Rem *= 10;
    Eps *= 10;
    OS << Rem / getEntryFrequency();
    Rem = Rem % getEntryFrequency();
  } while (Rem >= Eps/2);
}

namespace llvm {

raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) {
  Freq.print(OS);
  return OS;
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "probe.h"
#include "iarewprobe.h"

#include "../shared/logging/consolelogger.h"

#include <logging/translator.h>

#include <tools/hostosinfo.h>
#include <tools/profile.h>

#include <QtCore/qprocess.h>
#include <QtCore/qsettings.h>
#include <QtCore/qstandardpaths.h>

using namespace qbs;
using Internal::Tr;
using Internal::HostOsInfo;

static QStringList knownIarCompilerNames()
{
    return {QStringLiteral("icc8051"), QStringLiteral("iccarm"),
            QStringLiteral("iccavr"), QStringLiteral("iccstm8"),
            QStringLiteral("icc430"), QStringLiteral("iccrl78"),
            QStringLiteral("iccrx")};
}

static QString guessIarArchitecture(const QFileInfo &compiler)
{
    const auto baseName = compiler.baseName();
    if (baseName == QLatin1String("icc8051"))
        return QStringLiteral("mcs51");
    if (baseName == QLatin1String("iccarm"))
        return QStringLiteral("arm");
    if (baseName == QLatin1String("iccavr"))
        return QStringLiteral("avr");
    if (baseName == QLatin1String("iccstm8"))
        return QStringLiteral("stm8");
    if (baseName == QLatin1String("icc430"))
        return QStringLiteral("msp430");
    if (baseName == QLatin1String("iccrl78"))
        return QStringLiteral("rl78");
    if (baseName == QLatin1String("iccrx"))
        return QStringLiteral("rx");
    return {};
}

static Profile createIarProfileHelper(const ToolchainInstallInfo &info,
                                      Settings *settings,
                                      QString profileName = QString())
{
    const QFileInfo compiler = info.compilerPath;
    const QString architecture = guessIarArchitecture(compiler);

    // In case the profile is auto-detected.
    if (profileName.isEmpty()) {
        if (!info.compilerVersion.isValid()) {
            profileName = QStringLiteral("iar-unknown-%1").arg(architecture);
        } else {
            const QString version = info.compilerVersion.toString(QLatin1Char('_'),
                                                                  QLatin1Char('_'));
            profileName = QStringLiteral("iar-%1-%2").arg(
                        version, architecture);
        }
    }

    Profile profile(profileName, settings);
    profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath());
    profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("iar"));
    if (!architecture.isEmpty())
        profile.setValue(QLatin1String("qbs.architecture"), architecture);

    qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg(
                     profile.name(), compiler.absoluteFilePath());
    return profile;
}

static Version dumpIarCompilerVersion(const QFileInfo &compiler)
{
    const QString outFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation)
            + QLatin1String("/macros.dump");
    const QStringList args = {QStringLiteral("."),
                              QStringLiteral("--predef_macros"),
                              outFilePath};
    QProcess p;
    p.start(compiler.absoluteFilePath(), args);
    p.waitForFinished(3000);
    const auto es = p.exitStatus();
    if (es != QProcess::NormalExit) {
        const QByteArray out = p.readAll();
        qbsWarning() << Tr::tr("Compiler dumping failed:\n%1")
                        .arg(QString::fromUtf8(out));
        return Version{};
    }

    QByteArray dump;
    QFile out(outFilePath);
    if (out.open(QIODevice::ReadOnly))
        dump = out.readAll();
    out.remove();

    const int verCode = extractVersion(dump, "__VER__ ");
    if (verCode < 0) {
        qbsWarning() << Tr::tr("No '__VER__' token was found in a compiler dump:\n%1")
                        .arg(QString::fromUtf8(dump));
        return Version{};
    }

    const QString arch = guessIarArchitecture(compiler);
    if (arch == QLatin1String("arm")) {
        return Version{verCode / 1000000, (verCode / 1000) % 1000, verCode % 1000};
    } else if (arch == QLatin1String("avr")
               || arch == QLatin1String("mcs51")
               || arch == QLatin1String("stm8")
               || arch == QLatin1String("msp430")
               || arch == QLatin1String("rl78")
               || arch == QLatin1String("rx")) {
        return Version{verCode / 100, verCode % 100};
    }

    return Version{};
}

static std::vector<ToolchainInstallInfo> installedIarsFromPath()
{
    std::vector<ToolchainInstallInfo> infos;
    const auto compilerNames = knownIarCompilerNames();
    for (const QString &compilerName : compilerNames) {
        const QFileInfo iarPath(
                    findExecutable(
                        HostOsInfo::appendExecutableSuffix(compilerName)));
        if (!iarPath.exists())
            continue;
        const Version version = dumpIarCompilerVersion(iarPath);
        infos.push_back({iarPath, version});
    }
    std::sort(infos.begin(), infos.end());
    return infos;
}

static std::vector<ToolchainInstallInfo> installedIarsFromRegistry()
{
    std::vector<ToolchainInstallInfo> infos;

    if (HostOsInfo::isWindowsHost()) {

#ifdef Q_OS_WIN64
        static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\IAR Systems\\Embedded Workbench";
#else
        static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\IAR Systems\\Embedded Workbench";
#endif

        // Dictionary for know toolchains.
        static const struct Entry {
            QString registryKey;
            QString subExePath;
        } knowToolchains[] = {
            {QStringLiteral("EWARM"), QStringLiteral("\\arm\\bin\\iccarm.exe")},
            {QStringLiteral("EWAVR"), QStringLiteral("\\avr\\bin\\iccavr.exe")},
            {QStringLiteral("EW8051"), QStringLiteral("\\8051\\bin\\icc8051.exe")},
            {QStringLiteral("EWSTM8"), QStringLiteral("\\stm8\\bin\\iccstm8.exe")},
            {QStringLiteral("EW430"), QStringLiteral("\\430\\bin\\icc430.exe")},
            {QStringLiteral("EWRL78"), QStringLiteral("\\rl78\\bin\\iccrl78.exe")},
            {QStringLiteral("EWRX"), QStringLiteral("\\rx\\bin\\iccrx.exe")},
        };

        QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat);
        const auto oneLevelGroups = registry.childGroups();
        for (const QString &oneLevelKey : oneLevelGroups) {
            registry.beginGroup(oneLevelKey);
            const auto twoLevelGroups = registry.childGroups();
            for (const Entry &entry : knowToolchains) {
                if (twoLevelGroups.contains(entry.registryKey)) {
                    registry.beginGroup(entry.registryKey);
                    const auto threeLevelGroups = registry.childGroups();
                    for (const QString &threeLevelKey : threeLevelGroups) {
                        registry.beginGroup(threeLevelKey);
                        const QString rootPath = registry.value(
                                    QStringLiteral("InstallPath")).toString();
                        if (!rootPath.isEmpty()) {
                            // Build full compiler path.
                            const QFileInfo iarPath(rootPath + entry.subExePath);
                            if (iarPath.exists()) {
                                // Note: threeLevelKey is a guessed toolchain version.
                                infos.push_back({iarPath, Version::fromString(threeLevelKey)});
                            }
                        }
                        registry.endGroup();
                    }
                    registry.endGroup();
                }
            }
            registry.endGroup();
        }

    }

    std::sort(infos.begin(), infos.end());
    return infos;
}

bool isIarCompiler(const QString &compilerName)
{
    return Internal::any_of(knownIarCompilerNames(), [compilerName](
                            const QString &knownName) {
        return compilerName.contains(knownName);
    });
}

void createIarProfile(const QFileInfo &compiler, Settings *settings,
                      QString profileName)
{
    const ToolchainInstallInfo info = {compiler, Version{}};
    createIarProfileHelper(info, settings, std::move(profileName));
}

void iarProbe(Settings *settings, std::vector<Profile> &profiles)
{
    qbsInfo() << Tr::tr("Trying to detect IAR toolchains...");

    // Make sure that a returned infos are sorted before using the std::set_union!
    const std::vector<ToolchainInstallInfo> regInfos = installedIarsFromRegistry();
    const std::vector<ToolchainInstallInfo> pathInfos = installedIarsFromPath();
    std::vector<ToolchainInstallInfo> allInfos;
    allInfos.reserve(regInfos.size() + pathInfos.size());
    std::set_union(regInfos.cbegin(), regInfos.cend(),
                   pathInfos.cbegin(), pathInfos.cend(),
                   std::back_inserter(allInfos));

    for (const ToolchainInstallInfo &info : allInfos) {
        const auto profile = createIarProfileHelper(info, settings);
        profiles.push_back(profile);
    }

    if (allInfos.empty())
        qbsInfo() << Tr::tr("No IAR toolchains found.");
}
<commit_msg>baremetal: Auto-detect IAR toolchain for Renesas RH850 architecture<commit_after>/****************************************************************************
**
** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "probe.h"
#include "iarewprobe.h"

#include "../shared/logging/consolelogger.h"

#include <logging/translator.h>

#include <tools/hostosinfo.h>
#include <tools/profile.h>

#include <QtCore/qprocess.h>
#include <QtCore/qsettings.h>
#include <QtCore/qstandardpaths.h>

using namespace qbs;
using Internal::Tr;
using Internal::HostOsInfo;

static QStringList knownIarCompilerNames()
{
    return {QStringLiteral("icc8051"), QStringLiteral("iccarm"),
            QStringLiteral("iccavr"), QStringLiteral("iccstm8"),
            QStringLiteral("icc430"), QStringLiteral("iccrl78"),
            QStringLiteral("iccrx"), QStringLiteral("iccrh850")};
}

static QString guessIarArchitecture(const QFileInfo &compiler)
{
    const auto baseName = compiler.baseName();
    if (baseName == QLatin1String("icc8051"))
        return QStringLiteral("mcs51");
    if (baseName == QLatin1String("iccarm"))
        return QStringLiteral("arm");
    if (baseName == QLatin1String("iccavr"))
        return QStringLiteral("avr");
    if (baseName == QLatin1String("iccstm8"))
        return QStringLiteral("stm8");
    if (baseName == QLatin1String("icc430"))
        return QStringLiteral("msp430");
    if (baseName == QLatin1String("iccrl78"))
        return QStringLiteral("rl78");
    if (baseName == QLatin1String("iccrx"))
        return QStringLiteral("rx");
    if (baseName == QLatin1String("iccrh850"))
        return QStringLiteral("rh850");
    return {};
}

static Profile createIarProfileHelper(const ToolchainInstallInfo &info,
                                      Settings *settings,
                                      QString profileName = QString())
{
    const QFileInfo compiler = info.compilerPath;
    const QString architecture = guessIarArchitecture(compiler);

    // In case the profile is auto-detected.
    if (profileName.isEmpty()) {
        if (!info.compilerVersion.isValid()) {
            profileName = QStringLiteral("iar-unknown-%1").arg(architecture);
        } else {
            const QString version = info.compilerVersion.toString(QLatin1Char('_'),
                                                                  QLatin1Char('_'));
            profileName = QStringLiteral("iar-%1-%2").arg(
                        version, architecture);
        }
    }

    Profile profile(profileName, settings);
    profile.setValue(QLatin1String("cpp.toolchainInstallPath"), compiler.absolutePath());
    profile.setValue(QLatin1String("qbs.toolchainType"), QLatin1String("iar"));
    if (!architecture.isEmpty())
        profile.setValue(QLatin1String("qbs.architecture"), architecture);

    qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg(
                     profile.name(), compiler.absoluteFilePath());
    return profile;
}

static Version dumpIarCompilerVersion(const QFileInfo &compiler)
{
    const QString outFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation)
            + QLatin1String("/macros.dump");
    const QStringList args = {QStringLiteral("."),
                              QStringLiteral("--predef_macros"),
                              outFilePath};
    QProcess p;
    p.start(compiler.absoluteFilePath(), args);
    p.waitForFinished(3000);
    const auto es = p.exitStatus();
    if (es != QProcess::NormalExit) {
        const QByteArray out = p.readAll();
        qbsWarning() << Tr::tr("Compiler dumping failed:\n%1")
                        .arg(QString::fromUtf8(out));
        return Version{};
    }

    QByteArray dump;
    QFile out(outFilePath);
    if (out.open(QIODevice::ReadOnly))
        dump = out.readAll();
    out.remove();

    const int verCode = extractVersion(dump, "__VER__ ");
    if (verCode < 0) {
        qbsWarning() << Tr::tr("No '__VER__' token was found in a compiler dump:\n%1")
                        .arg(QString::fromUtf8(dump));
        return Version{};
    }

    const QString arch = guessIarArchitecture(compiler);
    if (arch == QLatin1String("arm")) {
        return Version{verCode / 1000000, (verCode / 1000) % 1000, verCode % 1000};
    } else if (arch == QLatin1String("avr")
               || arch == QLatin1String("mcs51")
               || arch == QLatin1String("stm8")
               || arch == QLatin1String("msp430")
               || arch == QLatin1String("rl78")
               || arch == QLatin1String("rx")
               || arch == QLatin1String("rh850")) {
        return Version{verCode / 100, verCode % 100};
    }

    return Version{};
}

static std::vector<ToolchainInstallInfo> installedIarsFromPath()
{
    std::vector<ToolchainInstallInfo> infos;
    const auto compilerNames = knownIarCompilerNames();
    for (const QString &compilerName : compilerNames) {
        const QFileInfo iarPath(
                    findExecutable(
                        HostOsInfo::appendExecutableSuffix(compilerName)));
        if (!iarPath.exists())
            continue;
        const Version version = dumpIarCompilerVersion(iarPath);
        infos.push_back({iarPath, version});
    }
    std::sort(infos.begin(), infos.end());
    return infos;
}

static std::vector<ToolchainInstallInfo> installedIarsFromRegistry()
{
    std::vector<ToolchainInstallInfo> infos;

    if (HostOsInfo::isWindowsHost()) {

#ifdef Q_OS_WIN64
        static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\IAR Systems\\Embedded Workbench";
#else
        static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\IAR Systems\\Embedded Workbench";
#endif

        // Dictionary for know toolchains.
        static const struct Entry {
            QString registryKey;
            QString subExePath;
        } knowToolchains[] = {
            {QStringLiteral("EWARM"), QStringLiteral("\\arm\\bin\\iccarm.exe")},
            {QStringLiteral("EWAVR"), QStringLiteral("\\avr\\bin\\iccavr.exe")},
            {QStringLiteral("EW8051"), QStringLiteral("\\8051\\bin\\icc8051.exe")},
            {QStringLiteral("EWSTM8"), QStringLiteral("\\stm8\\bin\\iccstm8.exe")},
            {QStringLiteral("EW430"), QStringLiteral("\\430\\bin\\icc430.exe")},
            {QStringLiteral("EWRL78"), QStringLiteral("\\rl78\\bin\\iccrl78.exe")},
            {QStringLiteral("EWRX"), QStringLiteral("\\rx\\bin\\iccrx.exe")},
            {QStringLiteral("EWRH850"), QStringLiteral("\\rh850\\bin\\iccrh850.exe")},
        };

        QSettings registry(QLatin1String(kRegistryNode), QSettings::NativeFormat);
        const auto oneLevelGroups = registry.childGroups();
        for (const QString &oneLevelKey : oneLevelGroups) {
            registry.beginGroup(oneLevelKey);
            const auto twoLevelGroups = registry.childGroups();
            for (const Entry &entry : knowToolchains) {
                if (twoLevelGroups.contains(entry.registryKey)) {
                    registry.beginGroup(entry.registryKey);
                    const auto threeLevelGroups = registry.childGroups();
                    for (const QString &threeLevelKey : threeLevelGroups) {
                        registry.beginGroup(threeLevelKey);
                        const QString rootPath = registry.value(
                                    QStringLiteral("InstallPath")).toString();
                        if (!rootPath.isEmpty()) {
                            // Build full compiler path.
                            const QFileInfo iarPath(rootPath + entry.subExePath);
                            if (iarPath.exists()) {
                                // Note: threeLevelKey is a guessed toolchain version.
                                infos.push_back({iarPath, Version::fromString(threeLevelKey)});
                            }
                        }
                        registry.endGroup();
                    }
                    registry.endGroup();
                }
            }
            registry.endGroup();
        }

    }

    std::sort(infos.begin(), infos.end());
    return infos;
}

bool isIarCompiler(const QString &compilerName)
{
    return Internal::any_of(knownIarCompilerNames(), [compilerName](
                            const QString &knownName) {
        return compilerName.contains(knownName);
    });
}

void createIarProfile(const QFileInfo &compiler, Settings *settings,
                      QString profileName)
{
    const ToolchainInstallInfo info = {compiler, Version{}};
    createIarProfileHelper(info, settings, std::move(profileName));
}

void iarProbe(Settings *settings, std::vector<Profile> &profiles)
{
    qbsInfo() << Tr::tr("Trying to detect IAR toolchains...");

    // Make sure that a returned infos are sorted before using the std::set_union!
    const std::vector<ToolchainInstallInfo> regInfos = installedIarsFromRegistry();
    const std::vector<ToolchainInstallInfo> pathInfos = installedIarsFromPath();
    std::vector<ToolchainInstallInfo> allInfos;
    allInfos.reserve(regInfos.size() + pathInfos.size());
    std::set_union(regInfos.cbegin(), regInfos.cend(),
                   pathInfos.cbegin(), pathInfos.cend(),
                   std::back_inserter(allInfos));

    for (const ToolchainInstallInfo &info : allInfos) {
        const auto profile = createIarProfileHelper(info, settings);
        profiles.push_back(profile);
    }

    if (allInfos.empty())
        qbsInfo() << Tr::tr("No IAR toolchains found.");
}
<|endoftext|>


<commit_before>//===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Constant.h"
#include "llvm/DerivedTypes.h"
using namespace llvm;

namespace llvm {
  // External object describing the machine instructions Initialized only when
  // the TargetMachine class is created and reset when that class is destroyed.
  //
  // FIXME: UGLY SPARCV9 HACK!
  const TargetInstrDescriptor* TargetInstrDescriptors = 0;
}

TargetInstrInfo::TargetInstrInfo(const TargetInstrDescriptor* Desc,
                                 unsigned numOpcodes)
  : desc(Desc), NumOpcodes(numOpcodes) {
  // FIXME: TargetInstrDescriptors should not be global
  assert(TargetInstrDescriptors == NULL && desc != NULL
         && "TargetMachine data structure corrupt; maybe you tried to create another TargetMachine? (only one may exist in a program)");
  TargetInstrDescriptors = desc; // initialize global variable
}

TargetInstrInfo::~TargetInstrInfo() {
  TargetInstrDescriptors = NULL; // reset global variable
}

// FIXME: SPARCV9 SPECIFIC!
bool TargetInstrInfo::constantFitsInImmedField(MachineOpCode opCode,
                                               int64_t intValue) const {
  // First, check if opCode has an immed field.
  bool isSignExtended;
  uint64_t maxImmedValue = maxImmedConstant(opCode, isSignExtended);
  if (maxImmedValue != 0)
    {
      // NEED TO HANDLE UNSIGNED VALUES SINCE THEY MAY BECOME MUCH
      // SMALLER AFTER CASTING TO SIGN-EXTENDED int, short, or char.
      // See CreateUIntSetInstruction in SparcInstrInfo.cpp.

      // Now check if the constant fits
      if (intValue <= (int64_t) maxImmedValue &&
          intValue >= -((int64_t) maxImmedValue+1))
        return true;
    }

  return false;
}

// commuteInstruction - The default implementation of this method just exchanges
// operand 1 and 2.
MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI) const {
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  unsigned Reg1 = MI->getOperand(1).getReg();
  unsigned Reg2 = MI->getOperand(1).getReg();
  MI->SetMachineOperandReg(2, Reg1);
  MI->SetMachineOperandReg(1, Reg2);
  return MI;
}
<commit_msg>remove some v9 specific code<commit_after>//===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Constant.h"
#include "llvm/DerivedTypes.h"
using namespace llvm;

namespace llvm {
  // External object describing the machine instructions Initialized only when
  // the TargetMachine class is created and reset when that class is destroyed.
  //
  // FIXME: UGLY SPARCV9 HACK!
  const TargetInstrDescriptor* TargetInstrDescriptors = 0;
}

TargetInstrInfo::TargetInstrInfo(const TargetInstrDescriptor* Desc,
                                 unsigned numOpcodes)
  : desc(Desc), NumOpcodes(numOpcodes) {
  // FIXME: TargetInstrDescriptors should not be global
  assert(TargetInstrDescriptors == NULL && desc != NULL
         && "TargetMachine data structure corrupt; maybe you tried to create another TargetMachine? (only one may exist in a program)");
  TargetInstrDescriptors = desc; // initialize global variable
}

TargetInstrInfo::~TargetInstrInfo() {
  TargetInstrDescriptors = NULL; // reset global variable
}

// commuteInstruction - The default implementation of this method just exchanges
// operand 1 and 2.
MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI) const {
  assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() &&
         "This only knows how to commute register operands so far");
  unsigned Reg1 = MI->getOperand(1).getReg();
  unsigned Reg2 = MI->getOperand(1).getReg();
  MI->SetMachineOperandReg(2, Reg1);
  MI->SetMachineOperandReg(1, Reg2);
  return MI;
}
<|endoftext|>