1 /*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "bcc/Support/Properties.h"
18 #include "bcc/Support/TargetCompilerConfigs.h"
19
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/Support/Host.h"
22
23 // Get ARM version number (i.e., __ARM_ARCH__)
24 #ifdef __arm__
25 #include <machine/cpu-features.h>
26 #endif
27
28 using namespace bcc;
29
30 //===----------------------------------------------------------------------===//
31 // ARM
32 //===----------------------------------------------------------------------===//
33 #if defined(PROVIDE_ARM_CODEGEN)
34
HasThumb2()35 bool ARMBaseCompilerConfig::HasThumb2() {
36 #if !defined(TARGET_BUILD)
37 // Cross-compiler can always generate Thumb-2 instructions.
38 return true;
39 #else // defined(TARGET_BUILD)
40 # if (__ARM_ARCH__ >= 7) || defined(__ARM_ARCH_6T2__)
41 return true;
42 # else
43 // ARM prior to V6T2 doesn't support Thumb-2.
44 return false;
45 # endif
46 #endif
47 }
48
49 void
GetFeatureVector(std::vector<std::string> & pAttributes,bool pInThumbMode,bool pEnableNEON)50 ARMBaseCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
51 bool pInThumbMode, bool pEnableNEON) {
52 llvm::StringMap<bool> Features;
53 llvm::sys::getHostCPUFeatures(Features);
54
55 #if defined(ARCH_ARM_HAVE_VFP)
56 pAttributes.push_back("+vfp3");
57 # if !defined(ARCH_ARM_HAVE_VFP_D32)
58 pAttributes.push_back("+d16");
59 # endif
60 #endif
61
62 if (pInThumbMode) {
63 if (HasThumb2()) {
64 pAttributes.push_back("+thumb2");
65 } else {
66 pAttributes.push_back("-thumb2");
67 }
68 }
69
70 if (pEnableNEON && Features.count("neon") && Features["neon"]) {
71 pAttributes.push_back("+neon");
72 } else {
73 pAttributes.push_back("-neon");
74 pAttributes.push_back("-neonfp");
75 }
76
77 if (!getProperty("debug.rs.arm-no-hwdiv")) {
78 if (Features.count("hwdiv-arm") && Features["hwdiv-arm"])
79 pAttributes.push_back("+hwdiv-arm");
80
81 if (Features.count("hwdiv") && Features["hwdiv"])
82 pAttributes.push_back("+hwdiv");
83 }
84
85 return;
86 }
87
ARMBaseCompilerConfig(const std::string & pTriple,bool pInThumbMode)88 ARMBaseCompilerConfig::ARMBaseCompilerConfig(const std::string &pTriple,
89 bool pInThumbMode)
90 : CompilerConfig(pTriple), mInThumbMode(pInThumbMode) {
91
92 // Enable NEON by default.
93 mEnableNEON = true;
94
95 if (!getProperty("debug.rs.arm-no-tune-for-cpu"))
96 setCPU(llvm::sys::getHostCPUName());
97
98 std::vector<std::string> attributes;
99 GetFeatureVector(attributes, mInThumbMode, mEnableNEON);
100 setFeatureString(attributes);
101
102 return;
103 }
104
enableNEON(bool pEnable)105 bool ARMBaseCompilerConfig::enableNEON(bool pEnable) {
106 #if defined(ARCH_ARM_HAVE_NEON)
107 if (mEnableNEON != pEnable) {
108 std::vector<std::string> attributes;
109 GetFeatureVector(attributes, mInThumbMode, pEnable);
110 setFeatureString(attributes);
111 mEnableNEON = pEnable;
112 return true;
113 }
114 // Fall-through
115 #endif
116 return false;
117 }
118 #endif // defined(PROVIDE_ARM_CODEGEN)
119