Mips.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. //===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "Mips.h"
  9. #include "ToolChains/CommonArgs.h"
  10. #include "clang/Driver/Driver.h"
  11. #include "clang/Driver/DriverDiagnostic.h"
  12. #include "clang/Driver/Options.h"
  13. #include "llvm/ADT/StringSwitch.h"
  14. #include "llvm/Option/ArgList.h"
  15. using namespace clang::driver;
  16. using namespace clang::driver::tools;
  17. using namespace clang;
  18. using namespace llvm::opt;
  19. // Get CPU and ABI names. They are not independent
  20. // so we have to calculate them together.
  21. void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
  22. StringRef &CPUName, StringRef &ABIName) {
  23. const char *DefMips32CPU = "mips32r2";
  24. const char *DefMips64CPU = "mips64r2";
  25. // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
  26. // default for mips64(el)?-img-linux-gnu.
  27. if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
  28. Triple.isGNUEnvironment()) {
  29. DefMips32CPU = "mips32r6";
  30. DefMips64CPU = "mips64r6";
  31. }
  32. if (Triple.getSubArch() == llvm::Triple::MipsSubArch_r6) {
  33. DefMips32CPU = "mips32r6";
  34. DefMips64CPU = "mips64r6";
  35. }
  36. // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
  37. if (Triple.isAndroid()) {
  38. DefMips32CPU = "mips32";
  39. DefMips64CPU = "mips64r6";
  40. }
  41. // MIPS3 is the default for mips64*-unknown-openbsd.
  42. if (Triple.isOSOpenBSD())
  43. DefMips64CPU = "mips3";
  44. // MIPS2 is the default for mips(el)?-unknown-freebsd.
  45. // MIPS3 is the default for mips64(el)?-unknown-freebsd.
  46. if (Triple.isOSFreeBSD()) {
  47. DefMips32CPU = "mips2";
  48. DefMips64CPU = "mips3";
  49. }
  50. if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
  51. options::OPT_mcpu_EQ))
  52. CPUName = A->getValue();
  53. if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
  54. ABIName = A->getValue();
  55. // Convert a GNU style Mips ABI name to the name
  56. // accepted by LLVM Mips backend.
  57. ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
  58. .Case("32", "o32")
  59. .Case("64", "n64")
  60. .Default(ABIName);
  61. }
  62. // Setup default CPU and ABI names.
  63. if (CPUName.empty() && ABIName.empty()) {
  64. switch (Triple.getArch()) {
  65. default:
  66. llvm_unreachable("Unexpected triple arch name");
  67. case llvm::Triple::mips:
  68. case llvm::Triple::mipsel:
  69. CPUName = DefMips32CPU;
  70. break;
  71. case llvm::Triple::mips64:
  72. case llvm::Triple::mips64el:
  73. CPUName = DefMips64CPU;
  74. break;
  75. }
  76. }
  77. if (ABIName.empty() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32))
  78. ABIName = "n32";
  79. if (ABIName.empty() &&
  80. (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
  81. Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
  82. ABIName = llvm::StringSwitch<const char *>(CPUName)
  83. .Case("mips1", "o32")
  84. .Case("mips2", "o32")
  85. .Case("mips3", "n64")
  86. .Case("mips4", "n64")
  87. .Case("mips5", "n64")
  88. .Case("mips32", "o32")
  89. .Case("mips32r2", "o32")
  90. .Case("mips32r3", "o32")
  91. .Case("mips32r5", "o32")
  92. .Case("mips32r6", "o32")
  93. .Case("mips64", "n64")
  94. .Case("mips64r2", "n64")
  95. .Case("mips64r3", "n64")
  96. .Case("mips64r5", "n64")
  97. .Case("mips64r6", "n64")
  98. .Case("octeon", "n64")
  99. .Case("p5600", "o32")
  100. .Default("");
  101. }
  102. if (ABIName.empty()) {
  103. // Deduce ABI name from the target triple.
  104. ABIName = Triple.isMIPS32() ? "o32" : "n64";
  105. }
  106. if (CPUName.empty()) {
  107. // Deduce CPU name from ABI name.
  108. CPUName = llvm::StringSwitch<const char *>(ABIName)
  109. .Case("o32", DefMips32CPU)
  110. .Cases("n32", "n64", DefMips64CPU)
  111. .Default("");
  112. }
  113. // FIXME: Warn on inconsistent use of -march and -mabi.
  114. }
  115. std::string mips::getMipsABILibSuffix(const ArgList &Args,
  116. const llvm::Triple &Triple) {
  117. StringRef CPUName, ABIName;
  118. tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
  119. return llvm::StringSwitch<std::string>(ABIName)
  120. .Case("o32", "")
  121. .Case("n32", "32")
  122. .Case("n64", "64");
  123. }
  124. // Convert ABI name to the GNU tools acceptable variant.
  125. StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
  126. return llvm::StringSwitch<llvm::StringRef>(ABI)
  127. .Case("o32", "32")
  128. .Case("n64", "64")
  129. .Default(ABI);
  130. }
  131. // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
  132. // and -mfloat-abi=.
  133. mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args,
  134. const llvm::Triple &Triple) {
  135. mips::FloatABI ABI = mips::FloatABI::Invalid;
  136. if (Arg *A =
  137. Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
  138. options::OPT_mfloat_abi_EQ)) {
  139. if (A->getOption().matches(options::OPT_msoft_float))
  140. ABI = mips::FloatABI::Soft;
  141. else if (A->getOption().matches(options::OPT_mhard_float))
  142. ABI = mips::FloatABI::Hard;
  143. else {
  144. ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
  145. .Case("soft", mips::FloatABI::Soft)
  146. .Case("hard", mips::FloatABI::Hard)
  147. .Default(mips::FloatABI::Invalid);
  148. if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
  149. D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
  150. ABI = mips::FloatABI::Hard;
  151. }
  152. }
  153. }
  154. // If unspecified, choose the default based on the platform.
  155. if (ABI == mips::FloatABI::Invalid) {
  156. if (Triple.isOSFreeBSD()) {
  157. // For FreeBSD, assume "soft" on all flavors of MIPS.
  158. ABI = mips::FloatABI::Soft;
  159. } else {
  160. // Assume "hard", because it's a default value used by gcc.
  161. // When we start to recognize specific target MIPS processors,
  162. // we will be able to select the default more correctly.
  163. ABI = mips::FloatABI::Hard;
  164. }
  165. }
  166. assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
  167. return ABI;
  168. }
  169. void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
  170. const ArgList &Args,
  171. std::vector<StringRef> &Features) {
  172. StringRef CPUName;
  173. StringRef ABIName;
  174. getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
  175. ABIName = getGnuCompatibleMipsABIName(ABIName);
  176. // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
  177. // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
  178. // extension was developed by Richard Sandiford & Code Sourcery to support
  179. // static code calling PIC code (CPIC). For O32 and N32 this means we have
  180. // several combinations of PIC/static and abicalls. Pure static, static
  181. // with the CPIC extension, and pure PIC code.
  182. // At final link time, O32 and N32 with CPIC will have another section
  183. // added to the binary which contains the stub functions to perform
  184. // any fixups required for PIC code.
  185. // For N64, the situation is more regular: code can either be static
  186. // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
  187. // code for N64. Since Clang has already built the relocation model portion
  188. // of the commandline, we pick add +noabicalls feature in the N64 static
  189. // case.
  190. // The is another case to be accounted for: -msym32, which enforces that all
  191. // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
  192. // but it is unsupported.
  193. // The combinations for N64 are:
  194. // a) Static without abicalls and 64bit symbols.
  195. // b) Static with abicalls and 32bit symbols.
  196. // c) PIC with abicalls and 64bit symbols.
  197. // For case (a) we need to add +noabicalls for N64.
  198. bool IsN64 = ABIName == "64";
  199. bool IsPIC = false;
  200. bool NonPIC = false;
  201. Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
  202. options::OPT_fpic, options::OPT_fno_pic,
  203. options::OPT_fPIE, options::OPT_fno_PIE,
  204. options::OPT_fpie, options::OPT_fno_pie);
  205. if (LastPICArg) {
  206. Option O = LastPICArg->getOption();
  207. NonPIC =
  208. (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
  209. O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
  210. IsPIC =
  211. (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
  212. O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
  213. }
  214. bool UseAbiCalls = false;
  215. Arg *ABICallsArg =
  216. Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
  217. UseAbiCalls =
  218. !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
  219. if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
  220. D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
  221. << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
  222. }
  223. if (ABICallsArg && !UseAbiCalls && IsPIC) {
  224. D.Diag(diag::err_drv_unsupported_noabicalls_pic);
  225. }
  226. if (!UseAbiCalls)
  227. Features.push_back("+noabicalls");
  228. else
  229. Features.push_back("-noabicalls");
  230. if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
  231. options::OPT_mno_long_calls)) {
  232. if (A->getOption().matches(options::OPT_mno_long_calls))
  233. Features.push_back("-long-calls");
  234. else if (!UseAbiCalls)
  235. Features.push_back("+long-calls");
  236. else
  237. D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
  238. }
  239. if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
  240. if (A->getOption().matches(options::OPT_mxgot))
  241. Features.push_back("+xgot");
  242. else
  243. Features.push_back("-xgot");
  244. }
  245. mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
  246. if (FloatABI == mips::FloatABI::Soft) {
  247. // FIXME: Note, this is a hack. We need to pass the selected float
  248. // mode to the MipsTargetInfoBase to define appropriate macros there.
  249. // Now it is the only method.
  250. Features.push_back("+soft-float");
  251. }
  252. if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
  253. StringRef Val = StringRef(A->getValue());
  254. if (Val == "2008") {
  255. if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
  256. Features.push_back("+nan2008");
  257. else {
  258. Features.push_back("-nan2008");
  259. D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
  260. }
  261. } else if (Val == "legacy") {
  262. if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
  263. Features.push_back("-nan2008");
  264. else {
  265. Features.push_back("+nan2008");
  266. D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
  267. }
  268. } else
  269. D.Diag(diag::err_drv_unsupported_option_argument)
  270. << A->getOption().getName() << Val;
  271. }
  272. if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
  273. StringRef Val = StringRef(A->getValue());
  274. if (Val == "2008") {
  275. if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
  276. Features.push_back("+abs2008");
  277. } else {
  278. Features.push_back("-abs2008");
  279. D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
  280. }
  281. } else if (Val == "legacy") {
  282. if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
  283. Features.push_back("-abs2008");
  284. } else {
  285. Features.push_back("+abs2008");
  286. D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
  287. }
  288. } else {
  289. D.Diag(diag::err_drv_unsupported_option_argument)
  290. << A->getOption().getName() << Val;
  291. }
  292. }
  293. AddTargetFeature(Args, Features, options::OPT_msingle_float,
  294. options::OPT_mdouble_float, "single-float");
  295. AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
  296. "mips16");
  297. AddTargetFeature(Args, Features, options::OPT_mmicromips,
  298. options::OPT_mno_micromips, "micromips");
  299. AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
  300. "dsp");
  301. AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
  302. "dspr2");
  303. AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
  304. "msa");
  305. // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
  306. // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
  307. // nooddspreg.
  308. if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
  309. options::OPT_mfp64)) {
  310. if (A->getOption().matches(options::OPT_mfp32))
  311. Features.push_back("-fp64");
  312. else if (A->getOption().matches(options::OPT_mfpxx)) {
  313. Features.push_back("+fpxx");
  314. Features.push_back("+nooddspreg");
  315. } else
  316. Features.push_back("+fp64");
  317. } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
  318. Features.push_back("+fpxx");
  319. Features.push_back("+nooddspreg");
  320. } else if (mips::isFP64ADefault(Triple, CPUName)) {
  321. Features.push_back("+fp64");
  322. Features.push_back("+nooddspreg");
  323. }
  324. AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
  325. options::OPT_modd_spreg, "nooddspreg");
  326. AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
  327. "nomadd4");
  328. AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
  329. AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
  330. "crc");
  331. AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
  332. "virt");
  333. AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
  334. "ginv");
  335. if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
  336. StringRef Val = StringRef(A->getValue());
  337. if (Val == "hazard") {
  338. Arg *B =
  339. Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
  340. Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
  341. if (B && B->getOption().matches(options::OPT_mmicromips))
  342. D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
  343. << "hazard" << "micromips";
  344. else if (C && C->getOption().matches(options::OPT_mips16))
  345. D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
  346. << "hazard" << "mips16";
  347. else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
  348. Features.push_back("+use-indirect-jump-hazard");
  349. else
  350. D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
  351. << "hazard" << CPUName;
  352. } else
  353. D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
  354. }
  355. }
  356. mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
  357. // Strictly speaking, mips32r2 and mips64r2 do not conform to the
  358. // IEEE754-2008 standard. Support for this standard was first introduced
  359. // in Release 3. However, other compilers have traditionally allowed it
  360. // for Release 2 so we should do the same.
  361. return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
  362. .Case("mips1", Legacy)
  363. .Case("mips2", Legacy)
  364. .Case("mips3", Legacy)
  365. .Case("mips4", Legacy)
  366. .Case("mips5", Legacy)
  367. .Case("mips32", Legacy)
  368. .Case("mips32r2", Legacy | Std2008)
  369. .Case("mips32r3", Legacy | Std2008)
  370. .Case("mips32r5", Legacy | Std2008)
  371. .Case("mips32r6", Std2008)
  372. .Case("mips64", Legacy)
  373. .Case("mips64r2", Legacy | Std2008)
  374. .Case("mips64r3", Legacy | Std2008)
  375. .Case("mips64r5", Legacy | Std2008)
  376. .Case("mips64r6", Std2008)
  377. .Default(Std2008);
  378. }
  379. bool mips::hasCompactBranches(StringRef &CPU) {
  380. // mips32r6 and mips64r6 have compact branches.
  381. return llvm::StringSwitch<bool>(CPU)
  382. .Case("mips32r6", true)
  383. .Case("mips64r6", true)
  384. .Default(false);
  385. }
  386. bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
  387. Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
  388. return A && (A->getValue() == StringRef(Value));
  389. }
  390. bool mips::isUCLibc(const ArgList &Args) {
  391. Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
  392. return A && A->getOption().matches(options::OPT_muclibc);
  393. }
  394. bool mips::isNaN2008(const Driver &D, const ArgList &Args,
  395. const llvm::Triple &Triple) {
  396. if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
  397. return llvm::StringSwitch<bool>(NaNArg->getValue())
  398. .Case("2008", true)
  399. .Case("legacy", false)
  400. .Default(false);
  401. // NaN2008 is the default for MIPS32r6/MIPS64r6.
  402. return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
  403. .Cases("mips32r6", "mips64r6", true)
  404. .Default(false);
  405. }
  406. bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
  407. if (!Triple.isAndroid())
  408. return false;
  409. // Android MIPS32R6 defaults to FP64A.
  410. return llvm::StringSwitch<bool>(CPUName)
  411. .Case("mips32r6", true)
  412. .Default(false);
  413. }
  414. bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
  415. StringRef ABIName, mips::FloatABI FloatABI) {
  416. if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
  417. Triple.getVendor() != llvm::Triple::MipsTechnologies &&
  418. !Triple.isAndroid())
  419. return false;
  420. if (ABIName != "32")
  421. return false;
  422. // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
  423. // present.
  424. if (FloatABI == mips::FloatABI::Soft)
  425. return false;
  426. return llvm::StringSwitch<bool>(CPUName)
  427. .Cases("mips2", "mips3", "mips4", "mips5", true)
  428. .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
  429. .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
  430. .Default(false);
  431. }
  432. bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
  433. StringRef CPUName, StringRef ABIName,
  434. mips::FloatABI FloatABI) {
  435. bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
  436. // FPXX shouldn't be used if -msingle-float is present.
  437. if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
  438. options::OPT_mdouble_float))
  439. if (A->getOption().matches(options::OPT_msingle_float))
  440. UseFPXX = false;
  441. return UseFPXX;
  442. }
  443. bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
  444. // Supporting the hazard barrier method of dealing with indirect
  445. // jumps requires MIPSR2 support.
  446. return llvm::StringSwitch<bool>(CPU)
  447. .Case("mips32r2", true)
  448. .Case("mips32r3", true)
  449. .Case("mips32r5", true)
  450. .Case("mips32r6", true)
  451. .Case("mips64r2", true)
  452. .Case("mips64r3", true)
  453. .Case("mips64r5", true)
  454. .Case("mips64r6", true)
  455. .Case("octeon", true)
  456. .Case("p5600", true)
  457. .Default(false);
  458. }