Add support for MIPS' floating ABIs (hard, soft and single) to clang driver.
Patch by Simon Atanasyan. llvm-svn: 153348
This commit is contained in:
parent
190e7b6e18
commit
6976ec8551
|
@ -3440,11 +3440,19 @@ namespace {
|
|||
namespace {
|
||||
class MipsTargetInfoBase : public TargetInfo {
|
||||
std::string CPU;
|
||||
bool SoftFloat;
|
||||
bool SingleFloat;
|
||||
|
||||
protected:
|
||||
std::string ABI;
|
||||
|
||||
public:
|
||||
MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr)
|
||||
: TargetInfo(triple), ABI(ABIStr) {}
|
||||
: TargetInfo(triple),
|
||||
SoftFloat(false), SingleFloat(false),
|
||||
ABI(ABIStr)
|
||||
{}
|
||||
|
||||
virtual const char *getABI() const { return ABI.c_str(); }
|
||||
virtual bool setABI(const std::string &Name) = 0;
|
||||
virtual bool setCPU(const std::string &Name) {
|
||||
|
@ -3455,8 +3463,19 @@ public:
|
|||
Features[ABI] = true;
|
||||
Features[CPU] = true;
|
||||
}
|
||||
|
||||
virtual void getArchDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const = 0;
|
||||
MacroBuilder &Builder) const {
|
||||
if (SoftFloat)
|
||||
Builder.defineMacro("__mips_soft_float", Twine(1));
|
||||
else if (SingleFloat)
|
||||
Builder.defineMacro("__mips_single_float", Twine(1));
|
||||
else if (!SoftFloat && !SingleFloat)
|
||||
Builder.defineMacro("__mips_hard_float", Twine(1));
|
||||
else
|
||||
llvm_unreachable("Invalid float ABI for Mips.");
|
||||
}
|
||||
|
||||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const = 0;
|
||||
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
||||
|
@ -3507,6 +3526,37 @@ public:
|
|||
// FIXME: Implement!
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
|
||||
StringRef Name,
|
||||
bool Enabled) const {
|
||||
if (Name == "soft-float" || Name == "single-float") {
|
||||
Features[Name] = Enabled;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
|
||||
SoftFloat = false;
|
||||
SingleFloat = false;
|
||||
|
||||
for (std::vector<std::string>::iterator it = Features.begin(),
|
||||
ie = Features.end(); it != ie; ++it) {
|
||||
if (*it == "+single-float") {
|
||||
SingleFloat = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*it == "+soft-float") {
|
||||
SoftFloat = true;
|
||||
// This option is front-end specific.
|
||||
// Do not need to pass it to the backend.
|
||||
Features.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Mips32TargetInfoBase : public MipsTargetInfoBase {
|
||||
|
@ -3525,6 +3575,8 @@ public:
|
|||
}
|
||||
virtual void getArchDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
MipsTargetInfoBase::getArchDefines(Opts, Builder);
|
||||
|
||||
Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
|
||||
Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
|
||||
Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
|
||||
|
@ -3642,6 +3694,8 @@ public:
|
|||
}
|
||||
virtual void getArchDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
MipsTargetInfoBase::getArchDefines(Opts, Builder);
|
||||
|
||||
if (ABI == "n32") {
|
||||
Builder.defineMacro("__mips_n32");
|
||||
Builder.defineMacro("_ABIN32", "2");
|
||||
|
|
|
@ -787,31 +787,57 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
|
|||
CmdArgs.push_back("-target-abi");
|
||||
CmdArgs.push_back(ABIName);
|
||||
|
||||
// Select the float ABI as determined by -msoft-float, -mhard-float, and
|
||||
// Select the float ABI as determined by -msoft-float, -mhard-float,
|
||||
// and -mfloat-abi=.
|
||||
StringRef FloatABI;
|
||||
if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
|
||||
options::OPT_mhard_float)) {
|
||||
options::OPT_mhard_float,
|
||||
options::OPT_mfloat_abi_EQ)) {
|
||||
if (A->getOption().matches(options::OPT_msoft_float))
|
||||
FloatABI = "soft";
|
||||
else if (A->getOption().matches(options::OPT_mhard_float))
|
||||
FloatABI = "hard";
|
||||
else {
|
||||
FloatABI = A->getValue(Args);
|
||||
if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") {
|
||||
D.Diag(diag::err_drv_invalid_mfloat_abi)
|
||||
<< A->getAsString(Args);
|
||||
FloatABI = "hard";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If unspecified, choose the default based on the platform.
|
||||
if (FloatABI.empty()) {
|
||||
// Assume "soft", but warn the user we are guessing.
|
||||
FloatABI = "soft";
|
||||
D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
|
||||
// Assume "hard", because it's a default value used by gcc.
|
||||
// When we start to recognize specific target MIPS processors,
|
||||
// we will be able to select the default more correctly.
|
||||
FloatABI = "hard";
|
||||
}
|
||||
|
||||
if (FloatABI == "soft") {
|
||||
// Floating point operations and argument passing are soft.
|
||||
//
|
||||
// FIXME: This changes CPP defines, we need -target-soft-float.
|
||||
CmdArgs.push_back("-msoft-float");
|
||||
} else {
|
||||
CmdArgs.push_back("-mfloat-abi");
|
||||
CmdArgs.push_back("soft");
|
||||
|
||||
// FIXME: Note, this is a hack. We need to pass the selected float
|
||||
// mode to the MipsTargetInfoBase to define appropriate macros there.
|
||||
// Now it is the only method.
|
||||
CmdArgs.push_back("-target-feature");
|
||||
CmdArgs.push_back("+soft-float");
|
||||
}
|
||||
else if (FloatABI == "single") {
|
||||
// Restrict the use of hardware floating-point
|
||||
// instructions to 32-bit operations.
|
||||
CmdArgs.push_back("-target-feature");
|
||||
CmdArgs.push_back("+single-float");
|
||||
}
|
||||
else {
|
||||
// Floating point operations and argument passing are hard.
|
||||
assert(FloatABI == "hard" && "Invalid float abi!");
|
||||
CmdArgs.push_back("-mhard-float");
|
||||
CmdArgs.push_back("-mfloat-abi");
|
||||
CmdArgs.push_back("hard");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue