blob: 99b79e5576fe7777a3c0502e6b5d5f5d0070da2c [file] [log] [blame]
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +00001#include "llvm/ADT/StringMap.h"
2
Mikhail Glushenkov84612022009-12-07 17:03:21 +00003#include <string>
4#include <vector>
5
6namespace hooks {
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +00007
8/// NUM_KEYS - Calculate the size of a const char* array.
9#define NUM_KEYS(Keys) sizeof(Keys) / sizeof(const char*)
10
11// See http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
12inline unsigned NextHighestPowerOf2 (unsigned i) {
13 i |= i >> 1;
14 i |= i >> 2;
15 i |= i >> 4;
16 i |= i >> 8;
17 i |= i >> 16;
18 i++;
19 return i;
20}
21
Mikhail Glushenkov84612022009-12-07 17:03:21 +000022typedef std::vector<std::string> StrVec;
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000023typedef llvm::StringMap<const char*> ArgMap;
Mikhail Glushenkov84612022009-12-07 17:03:21 +000024
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000025/// ConvertToMAttrImpl - Common implementation of ConvertMArchToMAttr and
26/// ConvertToMAttr. The optional Args parameter contains information about how
27/// to transform special-cased values (for example, '-march=armv6' must be
28/// forwarded as '-mattr=+v6').
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000029std::string ConvertToMAttrImpl(const StrVec& Opts,
30 const ArgMap* Args = 0,
31 const ArgMap* MCpuArgs = 0) {
32 std::string mattr("-mattr=");
33 std::string mcpu("-mcpu=");
34 bool mattrTouched = false;
35 bool mcpuTouched = false;
Mikhail Glushenkov84612022009-12-07 17:03:21 +000036 bool firstIter = true;
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000037
Mikhail Glushenkov84612022009-12-07 17:03:21 +000038 for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
39 const std::string& Arg = *B;
40
41 if (firstIter)
42 firstIter = false;
43 else
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000044 mattr += ",";
Mikhail Glushenkov84612022009-12-07 17:03:21 +000045
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000046 // Check if the argument is a special case.
47 if (Args != 0) {
48 ArgMap::const_iterator I = Args->find(Arg);
49
50 if (I != Args->end()) {
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000051 mattr += '+';
52 mattr += I->getValue();
53 continue;
54 }
55 }
56
57 // Check if the argument should be forwarded to -mcpu instead of -mattr.
58 if (MCpuArgs != 0 && !mcpuTouched) {
59 ArgMap::const_iterator I = MCpuArgs->find(Arg);
60
61 if (I != MCpuArgs->end()) {
62 mcpuTouched = true;
63 mcpu += I->getValue();
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000064 continue;
65 }
66 }
67
68 // Convert 'no-foo' to '-foo'.
Mikhail Glushenkov84612022009-12-07 17:03:21 +000069 if (Arg.find("no-") == 0 && Arg[3] != 0) {
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000070 mattr += '-';
71 mattr += Arg.c_str() + 3;
Mikhail Glushenkov84612022009-12-07 17:03:21 +000072 }
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000073 // Convert 'foo' to '+foo'.
Mikhail Glushenkov84612022009-12-07 17:03:21 +000074 else {
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000075 mattr += '+';
76 mattr += Arg;
Mikhail Glushenkov84612022009-12-07 17:03:21 +000077 }
78 }
79
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000080 std::string out;
81 if (mattrTouched)
82 out += mattr;
83 if (mcpuTouched)
84 out += (mattrTouched ? " " : "") + mcpu;
85
Mikhail Glushenkov84612022009-12-07 17:03:21 +000086 return out;
87}
88
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +000089// -march values that need to be special-cased.
90const char* MArchKeysARM[] = { "armv4t", "armv5t", "armv5te", "armv6",
Mikhail Glushenkov26e10ae2010-12-15 01:22:15 +000091 "armv6-m", "armv6t2", "armv7-a", "armv7-m" };
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +000092const char* MArchValuesARM[] = { "v4t", "v5t", "v5te", "v6", "v6m", "v6t2",
Mikhail Glushenkov26e10ae2010-12-15 01:22:15 +000093 "v7a", "v7m" };
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +000094const unsigned MArchNumKeysARM = NUM_KEYS(MArchKeysARM);
95const unsigned MArchMapSize = NextHighestPowerOf2(MArchNumKeysARM);
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +000096
Mikhail Glushenkov42db9972010-12-15 01:22:25 +000097// -march values that should be forwarded as -mcpu
98const char* MArchMCpuKeysARM[] = { "iwmmxt", "ep9312" };
99const char* MArchMCpuValuesARM[] = { "iwmmxt", "ep9312"};
100const unsigned MArchMCpuNumKeysARM = NUM_KEYS(MArchMCpuKeysARM);
101const unsigned MArchMCpuMapSize = NextHighestPowerOf2(MArchMCpuNumKeysARM);
102
103
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000104void FillInArgMap(ArgMap& Args, const char* Keys[],
105 const char* Values[], unsigned NumKeys)
106{
107 for (unsigned i = 0; i < NumKeys; ++i) {
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000108 // Explicit cast to StringRef here is necessary to pick up the right
109 // overload.
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000110 Args.GetOrCreateValue(llvm::StringRef(Keys[i]), Values[i]);
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000111 }
112}
113
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000114/// ConvertMArchToMAttr - Convert -march from the gcc dialect to
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000115/// something llc can understand.
116std::string ConvertMArchToMAttr(const StrVec& Opts) {
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000117 static ArgMap MArchMap(MArchMapSize);
Mikhail Glushenkov42db9972010-12-15 01:22:25 +0000118 static ArgMap MArchMCpuMap(MArchMapSize);
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000119 static bool StaticDataInitialized = false;
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000120
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000121 if (!StaticDataInitialized) {
122 FillInArgMap(MArchMap, MArchKeysARM, MArchValuesARM, MArchNumKeysARM);
Mikhail Glushenkov42db9972010-12-15 01:22:25 +0000123 FillInArgMap(MArchMCpuMap, MArchMCpuKeysARM,
124 MArchMCpuValuesARM, MArchMCpuNumKeysARM);
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000125 StaticDataInitialized = true;
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000126 }
127
Mikhail Glushenkov42db9972010-12-15 01:22:25 +0000128 return ConvertToMAttrImpl(Opts, &MArchMap, &MArchMCpuMap);
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000129}
130
Mikhail Glushenkov2ac7eb82010-12-15 01:22:20 +0000131// -mcpu values that need to be special-cased.
132const char* MCpuKeysPPC[] = { "G3", "G4", "G5", "powerpc", "powerpc64"};
133const char* MCpuValuesPPC[] = { "g3", "g4", "g5", "ppc", "ppc64"};
134const unsigned MCpuNumKeysPPC = NUM_KEYS(MCpuKeysPPC);
135const unsigned MCpuMapSize = NextHighestPowerOf2(MCpuNumKeysPPC);
136
137/// ConvertMCpu - Convert -mcpu value from the gcc to the llc dialect.
138std::string ConvertMCpu(const char* Val) {
139 static ArgMap MCpuMap(MCpuMapSize);
140 static bool StaticDataInitialized = false;
141
142 if (!StaticDataInitialized) {
143 FillInArgMap(MCpuMap, MCpuKeysPPC, MCpuValuesPPC, MCpuNumKeysPPC);
144 StaticDataInitialized = true;
145 }
146
147 std::string ret = "-mcpu=";
148 ArgMap::const_iterator I = MCpuMap.find(Val);
149 if (I != MCpuMap.end()) {
150 return ret + I->getValue();
151 }
152 return ret + Val;
153}
154
155// -mfpu values that need to be special-cased.
156const char* MFpuKeysARM[] = { "vfp", "vfpv3",
157 "vfpv3-fp16", "vfpv3-d16", "vfpv3-d16-fp16",
158 "neon", "neon-fp16" };
159const char* MFpuValuesARM[] = { "vfp2", "vfp3",
160 "+vfp3,+fp16", "+vfp3,+d16", "+vfp3,+d16,+fp16",
161 "+neon", "+neon,+neonfp" };
162const unsigned MFpuNumKeysARM = NUM_KEYS(MFpuKeysARM);
163const unsigned MFpuMapSize = NextHighestPowerOf2(MFpuNumKeysARM);
164
165/// ConvertMFpu - Convert -mfpu value from the gcc to the llc dialect.
166std::string ConvertMFpu(const char* Val) {
167 static ArgMap MFpuMap(MFpuMapSize);
168 static bool StaticDataInitialized = false;
169
170 if (!StaticDataInitialized) {
171 FillInArgMap(MFpuMap, MFpuKeysARM, MFpuValuesARM, MFpuNumKeysARM);
172 StaticDataInitialized = true;
173 }
174
175 std::string ret = "-mattr=";
176 ArgMap::const_iterator I = MFpuMap.find(Val);
177 if (I != MFpuMap.end()) {
178 return ret + I->getValue();
179 }
180 return ret + '+' + Val;
181}
182
Mikhail Glushenkov325f69d2010-11-28 00:31:13 +0000183/// ConvertToMAttr - Convert '-mfoo' and '-mno-bar' to '-mattr=+foo,-bar'.
184std::string ConvertToMAttr(const StrVec& Opts) {
185 return ConvertToMAttrImpl(Opts);
186}
187
Mikhail Glushenkov84612022009-12-07 17:03:21 +0000188}