diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in index c1898a694e6..efb259fbe01 100644 --- a/tools/llvmc/src/Base.td.in +++ b/tools/llvmc/src/Base.td.in @@ -46,8 +46,8 @@ def OptList : OptionList<[ (help "Choose linker (possible values: gcc, g++)")), (parameter_option "mtune", (help "Target a specific CPU type"), (forward_not_split)), - (parameter_option "march", - (help "Architecture to generate code for"), (forward_not_split)), + (parameter_list_option "march", + (help "Generate code for the specified machine type")), (parameter_option "mcpu", (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)), (switch_option "mfix-and-continue", @@ -295,7 +295,8 @@ def llc : Tool< (switch_on "fPIC"), (append_cmd "-relocation-model=pic"), (switch_on "mdynamic-no-pic"), (append_cmd "-relocation-model=dynamic-no-pic"), - (not_empty "march"), (forward "march"), + (not_empty "march"), (forward_transformed_value + "march", "ConvertMArchToMAttr"), (not_empty "mcpu"), (forward "mcpu"), (and (not_empty "mtune"), (empty "mcpu")), (forward_as "mtune", "-mcpu"), diff --git a/tools/llvmc/src/Hooks.cpp b/tools/llvmc/src/Hooks.cpp index 661a914489d..efc91cf407c 100644 --- a/tools/llvmc/src/Hooks.cpp +++ b/tools/llvmc/src/Hooks.cpp @@ -1,14 +1,20 @@ +#include "llvm/ADT/StringMap.h" + #include #include namespace hooks { typedef std::vector StrVec; +typedef llvm::StringMap ArgMap; -/// ConvertToMAttr - Convert -m* and -mno-* to -mattr=+*,-* -std::string ConvertToMAttr(const StrVec& Opts) { +/// ConvertToMAttrImpl - Common implementation of ConvertMArchToMAttr and +/// ConvertToMAttr. The optional Args parameter contains information about how +/// to transform special-cased values (for example, '-march=armv6' must be +/// forwarded as '-mattr=+v6'). +std::string ConvertToMAttrImpl(const StrVec& Opts, const ArgMap* Args = 0) { std::string out("-mattr="); - bool firstIter = true; + for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) { const std::string& Arg = *B; @@ -17,10 +23,23 @@ std::string ConvertToMAttr(const StrVec& Opts) { else out += ","; + // Check if the argument is a special case. + if (Args != 0) { + ArgMap::const_iterator I = Args->find(Arg); + + if (I != Args->end()) { + out += '+'; + out += I->getValue(); + continue; + } + } + + // Convert 'no-foo' to '-foo'. if (Arg.find("no-") == 0 && Arg[3] != 0) { out += '-'; out += Arg.c_str() + 3; } + // Convert 'foo' to '+foo'. else { out += '+'; out += Arg; @@ -30,4 +49,36 @@ std::string ConvertToMAttr(const StrVec& Opts) { return out; } +// Values needed to be special-cased by ConvertMArchToMAttr. +const char* MArchMapKeys[] = { "armv6" }; +const char* MArchMapValues[] = { "v6" }; +const unsigned NumMArchMapKeys = sizeof(MArchMapKeys) / sizeof(const char*); + +void InitializeMArchMap(ArgMap& Args) { + for (unsigned i = 0; i < NumMArchMapKeys; ++i) { + // Explicit cast to StringRef here is necessary to pick up the right + // overload. + Args.GetOrCreateValue(llvm::StringRef(MArchMapKeys[i]), MArchMapValues[i]); + } +} + +/// ConvertMArchToMAttr - Try to convert -march from the gcc dialect to +/// something llc can understand. +std::string ConvertMArchToMAttr(const StrVec& Opts) { + static ArgMap MArchMap(NumMArchMapKeys); + static bool MArchMapInitialized = false; + + if (!MArchMapInitialized) { + InitializeMArchMap(MArchMap); + MArchMapInitialized = true; + } + + return ConvertToMAttrImpl(Opts, &MArchMap); +} + +/// ConvertToMAttr - Convert '-mfoo' and '-mno-bar' to '-mattr=+foo,-bar'. +std::string ConvertToMAttr(const StrVec& Opts) { + return ConvertToMAttrImpl(Opts); +} + }