C++程序  |  106行  |  2.78 KB

/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bcc/Support/TargetCompilerConfigs.h"

// Get ARM version number (i.e., __ARM_ARCH__)
#ifdef __arm__
#include <machine/cpu-features.h>
#endif

using namespace bcc;

//===----------------------------------------------------------------------===//
// ARM
//===----------------------------------------------------------------------===//
#if defined(PROVIDE_ARM_CODEGEN)

bool ARMBaseCompilerConfig::HasThumb2() {
#if !defined(TARGET_BUILD)
  // Cross-compiler can always generate Thumb-2 instructions.
  return true;
#else // defined(TARGET_BUILD)
#  if (__ARM_ARCH__ >= 7) || defined(__ARM_ARCH_6T2__)
  return true;
#  else
  // ARM prior to V6T2 doesn't support Thumb-2.
  return false;
#  endif
#endif
}

void
ARMBaseCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
                                        bool pInThumbMode, bool pEnableNEON) {
#if defined(ARCH_ARM_HAVE_VFP)
  pAttributes.push_back("+vfp3");
#  if !defined(ARCH_ARM_HAVE_VFP_D32)
  pAttributes.push_back("+d16");
#  endif
#endif

  if (pInThumbMode) {
    if (HasThumb2()) {
      pAttributes.push_back("+thumb2");
    } else {
      pAttributes.push_back("-thumb2");
    }
  }

#if defined(ARCH_ARM_HAVE_NEON)
  if (pEnableNEON) {
    pAttributes.push_back("+neon");
  } else {
    pAttributes.push_back("-neon");
    pAttributes.push_back("-neonfp");
  }
#else
  pAttributes.push_back("-neon");
  pAttributes.push_back("-neonfp");
#endif

  return;
}

ARMBaseCompilerConfig::ARMBaseCompilerConfig(const std::string &pTriple,
                                             bool pInThumbMode)
  : CompilerConfig(pTriple), mInThumbMode(pInThumbMode) {

  // Enable NEON by default.
  mEnableNEON = true;

  std::vector<std::string> attributes;
  GetFeatureVector(attributes, mInThumbMode, mEnableNEON);
  setFeatureString(attributes);

  return;
}

bool ARMBaseCompilerConfig::enableNEON(bool pEnable) {
#if defined(ARCH_ARM_HAVE_NEON)
  if (mEnableNEON != pEnable) {
    std::vector<std::string> attributes;
    GetFeatureVector(attributes, mInThumbMode, pEnable);
    setFeatureString(attributes);
    mEnableNEON = pEnable;
    return true;
  }
  // Fall-through
#endif
  return false;
}
#endif // defined(PROVIDE_ARM_CODEGEN)