xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
130b57cec5SDimitry Andric #include "llvm/Support/MipsABIFlags.h"
140b57cec5SDimitry Andric #include <cstdint>
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric namespace llvm {
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric class MCStreamer;
19*81ad6265SDimitry Andric class StringRef;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric struct MipsABIFlagsSection {
220b57cec5SDimitry Andric   // Internal representation of the fp_abi related values used in .module.
230b57cec5SDimitry Andric   enum class FpABIKind { ANY, XX, S32, S64, SOFT };
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric   // Version of flags structure.
260b57cec5SDimitry Andric   uint16_t Version = 0;
270b57cec5SDimitry Andric   // The level of the ISA: 1-5, 32, 64.
280b57cec5SDimitry Andric   uint8_t ISALevel = 0;
290b57cec5SDimitry Andric   // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
300b57cec5SDimitry Andric   uint8_t ISARevision = 0;
310b57cec5SDimitry Andric   // The size of general purpose registers.
320b57cec5SDimitry Andric   Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;
330b57cec5SDimitry Andric   // The size of co-processor 1 registers.
340b57cec5SDimitry Andric   Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;
350b57cec5SDimitry Andric   // The size of co-processor 2 registers.
360b57cec5SDimitry Andric   Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;
370b57cec5SDimitry Andric   // Processor-specific extension.
380b57cec5SDimitry Andric   Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;
390b57cec5SDimitry Andric   // Mask of ASEs used.
400b57cec5SDimitry Andric   uint32_t ASESet = 0;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   bool OddSPReg = false;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   bool Is32BitABI = false;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric protected:
470b57cec5SDimitry Andric   // The floating-point ABI.
480b57cec5SDimitry Andric   FpABIKind FpABI = FpABIKind::ANY;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric public:
510b57cec5SDimitry Andric   MipsABIFlagsSection() = default;
520b57cec5SDimitry Andric 
getVersionValueMipsABIFlagsSection530b57cec5SDimitry Andric   uint16_t getVersionValue() { return (uint16_t)Version; }
getISALevelValueMipsABIFlagsSection540b57cec5SDimitry Andric   uint8_t getISALevelValue() { return (uint8_t)ISALevel; }
getISARevisionValueMipsABIFlagsSection550b57cec5SDimitry Andric   uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }
getGPRSizeValueMipsABIFlagsSection560b57cec5SDimitry Andric   uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }
570b57cec5SDimitry Andric   uint8_t getCPR1SizeValue();
getCPR2SizeValueMipsABIFlagsSection580b57cec5SDimitry Andric   uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
590b57cec5SDimitry Andric   uint8_t getFpABIValue();
getISAExtensionValueMipsABIFlagsSection600b57cec5SDimitry Andric   uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
getASESetValueMipsABIFlagsSection610b57cec5SDimitry Andric   uint32_t getASESetValue() { return (uint32_t)ASESet; }
620b57cec5SDimitry Andric 
getFlags1ValueMipsABIFlagsSection630b57cec5SDimitry Andric   uint32_t getFlags1Value() {
640b57cec5SDimitry Andric     uint32_t Value = 0;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric     if (OddSPReg)
670b57cec5SDimitry Andric       Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric     return Value;
700b57cec5SDimitry Andric   }
710b57cec5SDimitry Andric 
getFlags2ValueMipsABIFlagsSection720b57cec5SDimitry Andric   uint32_t getFlags2Value() { return 0; }
730b57cec5SDimitry Andric 
getFpABIMipsABIFlagsSection740b57cec5SDimitry Andric   FpABIKind getFpABI() { return FpABI; }
setFpABIMipsABIFlagsSection750b57cec5SDimitry Andric   void setFpABI(FpABIKind Value, bool IsABI32Bit) {
760b57cec5SDimitry Andric     FpABI = Value;
770b57cec5SDimitry Andric     Is32BitABI = IsABI32Bit;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   StringRef getFpABIString(FpABIKind Value);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   template <class PredicateLibrary>
setISALevelAndRevisionFromPredicatesMipsABIFlagsSection830b57cec5SDimitry Andric   void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
840b57cec5SDimitry Andric     if (P.hasMips64()) {
850b57cec5SDimitry Andric       ISALevel = 64;
860b57cec5SDimitry Andric       if (P.hasMips64r6())
870b57cec5SDimitry Andric         ISARevision = 6;
880b57cec5SDimitry Andric       else if (P.hasMips64r5())
890b57cec5SDimitry Andric         ISARevision = 5;
900b57cec5SDimitry Andric       else if (P.hasMips64r3())
910b57cec5SDimitry Andric         ISARevision = 3;
920b57cec5SDimitry Andric       else if (P.hasMips64r2())
930b57cec5SDimitry Andric         ISARevision = 2;
940b57cec5SDimitry Andric       else
950b57cec5SDimitry Andric         ISARevision = 1;
960b57cec5SDimitry Andric     } else if (P.hasMips32()) {
970b57cec5SDimitry Andric       ISALevel = 32;
980b57cec5SDimitry Andric       if (P.hasMips32r6())
990b57cec5SDimitry Andric         ISARevision = 6;
1000b57cec5SDimitry Andric       else if (P.hasMips32r5())
1010b57cec5SDimitry Andric         ISARevision = 5;
1020b57cec5SDimitry Andric       else if (P.hasMips32r3())
1030b57cec5SDimitry Andric         ISARevision = 3;
1040b57cec5SDimitry Andric       else if (P.hasMips32r2())
1050b57cec5SDimitry Andric         ISARevision = 2;
1060b57cec5SDimitry Andric       else
1070b57cec5SDimitry Andric         ISARevision = 1;
1080b57cec5SDimitry Andric     } else {
1090b57cec5SDimitry Andric       ISARevision = 0;
1100b57cec5SDimitry Andric       if (P.hasMips5())
1110b57cec5SDimitry Andric         ISALevel = 5;
1120b57cec5SDimitry Andric       else if (P.hasMips4())
1130b57cec5SDimitry Andric         ISALevel = 4;
1140b57cec5SDimitry Andric       else if (P.hasMips3())
1150b57cec5SDimitry Andric         ISALevel = 3;
1160b57cec5SDimitry Andric       else if (P.hasMips2())
1170b57cec5SDimitry Andric         ISALevel = 2;
1180b57cec5SDimitry Andric       else if (P.hasMips1())
1190b57cec5SDimitry Andric         ISALevel = 1;
1200b57cec5SDimitry Andric       else
1210b57cec5SDimitry Andric         llvm_unreachable("Unknown ISA level!");
1220b57cec5SDimitry Andric     }
1230b57cec5SDimitry Andric   }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   template <class PredicateLibrary>
setGPRSizeFromPredicatesMipsABIFlagsSection1260b57cec5SDimitry Andric   void setGPRSizeFromPredicates(const PredicateLibrary &P) {
1270b57cec5SDimitry Andric     GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   template <class PredicateLibrary>
setCPR1SizeFromPredicatesMipsABIFlagsSection1310b57cec5SDimitry Andric   void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
1320b57cec5SDimitry Andric     if (P.useSoftFloat())
1330b57cec5SDimitry Andric       CPR1Size = Mips::AFL_REG_NONE;
1340b57cec5SDimitry Andric     else if (P.hasMSA())
1350b57cec5SDimitry Andric       CPR1Size = Mips::AFL_REG_128;
1360b57cec5SDimitry Andric     else
1370b57cec5SDimitry Andric       CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   template <class PredicateLibrary>
setISAExtensionFromPredicatesMipsABIFlagsSection1410b57cec5SDimitry Andric   void setISAExtensionFromPredicates(const PredicateLibrary &P) {
1420b57cec5SDimitry Andric     if (P.hasCnMipsP())
1430b57cec5SDimitry Andric       ISAExtension = Mips::AFL_EXT_OCTEONP;
1440b57cec5SDimitry Andric     else if (P.hasCnMips())
1450b57cec5SDimitry Andric       ISAExtension = Mips::AFL_EXT_OCTEON;
1460b57cec5SDimitry Andric     else
1470b57cec5SDimitry Andric       ISAExtension = Mips::AFL_EXT_NONE;
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   template <class PredicateLibrary>
setASESetFromPredicatesMipsABIFlagsSection1510b57cec5SDimitry Andric   void setASESetFromPredicates(const PredicateLibrary &P) {
1520b57cec5SDimitry Andric     ASESet = 0;
1530b57cec5SDimitry Andric     if (P.hasDSP())
1540b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_DSP;
1550b57cec5SDimitry Andric     if (P.hasDSPR2())
1560b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_DSPR2;
1570b57cec5SDimitry Andric     if (P.hasMSA())
1580b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_MSA;
1590b57cec5SDimitry Andric     if (P.inMicroMipsMode())
1600b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_MICROMIPS;
1610b57cec5SDimitry Andric     if (P.inMips16Mode())
1620b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_MIPS16;
1630b57cec5SDimitry Andric     if (P.hasMT())
1640b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_MT;
1650b57cec5SDimitry Andric     if (P.hasCRC())
1660b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_CRC;
1670b57cec5SDimitry Andric     if (P.hasVirt())
1680b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_VIRT;
1690b57cec5SDimitry Andric     if (P.hasGINV())
1700b57cec5SDimitry Andric       ASESet |= Mips::AFL_ASE_GINV;
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   template <class PredicateLibrary>
setFpAbiFromPredicatesMipsABIFlagsSection1740b57cec5SDimitry Andric   void setFpAbiFromPredicates(const PredicateLibrary &P) {
1750b57cec5SDimitry Andric     Is32BitABI = P.isABI_O32();
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric     FpABI = FpABIKind::ANY;
1780b57cec5SDimitry Andric     if (P.useSoftFloat())
1790b57cec5SDimitry Andric       FpABI = FpABIKind::SOFT;
1800b57cec5SDimitry Andric     else if (P.isABI_N32() || P.isABI_N64())
1810b57cec5SDimitry Andric       FpABI = FpABIKind::S64;
1820b57cec5SDimitry Andric     else if (P.isABI_O32()) {
1830b57cec5SDimitry Andric       if (P.isABI_FPXX())
1840b57cec5SDimitry Andric         FpABI = FpABIKind::XX;
1850b57cec5SDimitry Andric       else if (P.isFP64bit())
1860b57cec5SDimitry Andric         FpABI = FpABIKind::S64;
1870b57cec5SDimitry Andric       else
1880b57cec5SDimitry Andric         FpABI = FpABIKind::S32;
1890b57cec5SDimitry Andric     }
1900b57cec5SDimitry Andric   }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   template <class PredicateLibrary>
setAllFromPredicatesMipsABIFlagsSection1930b57cec5SDimitry Andric   void setAllFromPredicates(const PredicateLibrary &P) {
1940b57cec5SDimitry Andric     setISALevelAndRevisionFromPredicates(P);
1950b57cec5SDimitry Andric     setGPRSizeFromPredicates(P);
1960b57cec5SDimitry Andric     setCPR1SizeFromPredicates(P);
1970b57cec5SDimitry Andric     setISAExtensionFromPredicates(P);
1980b57cec5SDimitry Andric     setASESetFromPredicates(P);
1990b57cec5SDimitry Andric     setFpAbiFromPredicates(P);
2000b57cec5SDimitry Andric     OddSPReg = P.useOddSPReg();
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric };
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric } // end namespace llvm
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
209