1 //===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H 11 #define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H 12 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include "llvm/Support/MipsABIFlags.h" 16 #include <cstdint> 17 18 namespace llvm { 19 20 class MCStreamer; 21 22 struct MipsABIFlagsSection { 23 // Internal representation of the fp_abi related values used in .module. 24 enum class FpABIKind { ANY, XX, S32, S64, SOFT }; 25 26 // Version of flags structure. 27 uint16_t Version = 0; 28 // The level of the ISA: 1-5, 32, 64. 29 uint8_t ISALevel = 0; 30 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise. 31 uint8_t ISARevision = 0; 32 // The size of general purpose registers. 33 Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE; 34 // The size of co-processor 1 registers. 35 Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE; 36 // The size of co-processor 2 registers. 37 Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE; 38 // Processor-specific extension. 39 Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE; 40 // Mask of ASEs used. 41 uint32_t ASESet = 0; 42 43 bool OddSPReg = false; 44 45 bool Is32BitABI = false; 46 47 protected: 48 // The floating-point ABI. 49 FpABIKind FpABI = FpABIKind::ANY; 50 51 public: 52 MipsABIFlagsSection() = default; 53 getVersionValueMipsABIFlagsSection54 uint16_t getVersionValue() { return (uint16_t)Version; } getISALevelValueMipsABIFlagsSection55 uint8_t getISALevelValue() { return (uint8_t)ISALevel; } getISARevisionValueMipsABIFlagsSection56 uint8_t getISARevisionValue() { return (uint8_t)ISARevision; } getGPRSizeValueMipsABIFlagsSection57 uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; } 58 uint8_t getCPR1SizeValue(); getCPR2SizeValueMipsABIFlagsSection59 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; } 60 uint8_t getFpABIValue(); getISAExtensionValueMipsABIFlagsSection61 uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; } getASESetValueMipsABIFlagsSection62 uint32_t getASESetValue() { return (uint32_t)ASESet; } 63 getFlags1ValueMipsABIFlagsSection64 uint32_t getFlags1Value() { 65 uint32_t Value = 0; 66 67 if (OddSPReg) 68 Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG; 69 70 return Value; 71 } 72 getFlags2ValueMipsABIFlagsSection73 uint32_t getFlags2Value() { return 0; } 74 getFpABIMipsABIFlagsSection75 FpABIKind getFpABI() { return FpABI; } setFpABIMipsABIFlagsSection76 void setFpABI(FpABIKind Value, bool IsABI32Bit) { 77 FpABI = Value; 78 Is32BitABI = IsABI32Bit; 79 } 80 81 StringRef getFpABIString(FpABIKind Value); 82 83 template <class PredicateLibrary> setISALevelAndRevisionFromPredicatesMipsABIFlagsSection84 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) { 85 if (P.hasMips64()) { 86 ISALevel = 64; 87 if (P.hasMips64r6()) 88 ISARevision = 6; 89 else if (P.hasMips64r5()) 90 ISARevision = 5; 91 else if (P.hasMips64r3()) 92 ISARevision = 3; 93 else if (P.hasMips64r2()) 94 ISARevision = 2; 95 else 96 ISARevision = 1; 97 } else if (P.hasMips32()) { 98 ISALevel = 32; 99 if (P.hasMips32r6()) 100 ISARevision = 6; 101 else if (P.hasMips32r5()) 102 ISARevision = 5; 103 else if (P.hasMips32r3()) 104 ISARevision = 3; 105 else if (P.hasMips32r2()) 106 ISARevision = 2; 107 else 108 ISARevision = 1; 109 } else { 110 ISARevision = 0; 111 if (P.hasMips5()) 112 ISALevel = 5; 113 else if (P.hasMips4()) 114 ISALevel = 4; 115 else if (P.hasMips3()) 116 ISALevel = 3; 117 else if (P.hasMips2()) 118 ISALevel = 2; 119 else if (P.hasMips1()) 120 ISALevel = 1; 121 else 122 llvm_unreachable("Unknown ISA level!"); 123 } 124 } 125 126 template <class PredicateLibrary> setGPRSizeFromPredicatesMipsABIFlagsSection127 void setGPRSizeFromPredicates(const PredicateLibrary &P) { 128 GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32; 129 } 130 131 template <class PredicateLibrary> setCPR1SizeFromPredicatesMipsABIFlagsSection132 void setCPR1SizeFromPredicates(const PredicateLibrary &P) { 133 if (P.useSoftFloat()) 134 CPR1Size = Mips::AFL_REG_NONE; 135 else if (P.hasMSA()) 136 CPR1Size = Mips::AFL_REG_128; 137 else 138 CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32; 139 } 140 141 template <class PredicateLibrary> setISAExtensionFromPredicatesMipsABIFlagsSection142 void setISAExtensionFromPredicates(const PredicateLibrary &P) { 143 if (P.hasCnMips()) 144 ISAExtension = Mips::AFL_EXT_OCTEON; 145 else 146 ISAExtension = Mips::AFL_EXT_NONE; 147 } 148 149 template <class PredicateLibrary> setASESetFromPredicatesMipsABIFlagsSection150 void setASESetFromPredicates(const PredicateLibrary &P) { 151 ASESet = 0; 152 if (P.hasDSP()) 153 ASESet |= Mips::AFL_ASE_DSP; 154 if (P.hasDSPR2()) 155 ASESet |= Mips::AFL_ASE_DSPR2; 156 if (P.hasMSA()) 157 ASESet |= Mips::AFL_ASE_MSA; 158 if (P.inMicroMipsMode()) 159 ASESet |= Mips::AFL_ASE_MICROMIPS; 160 if (P.inMips16Mode()) 161 ASESet |= Mips::AFL_ASE_MIPS16; 162 if (P.hasMT()) 163 ASESet |= Mips::AFL_ASE_MT; 164 if (P.hasCRC()) 165 ASESet |= Mips::AFL_ASE_CRC; 166 if (P.hasVirt()) 167 ASESet |= Mips::AFL_ASE_VIRT; 168 if (P.hasGINV()) 169 ASESet |= Mips::AFL_ASE_GINV; 170 } 171 172 template <class PredicateLibrary> setFpAbiFromPredicatesMipsABIFlagsSection173 void setFpAbiFromPredicates(const PredicateLibrary &P) { 174 Is32BitABI = P.isABI_O32(); 175 176 FpABI = FpABIKind::ANY; 177 if (P.useSoftFloat()) 178 FpABI = FpABIKind::SOFT; 179 else if (P.isABI_N32() || P.isABI_N64()) 180 FpABI = FpABIKind::S64; 181 else if (P.isABI_O32()) { 182 if (P.isABI_FPXX()) 183 FpABI = FpABIKind::XX; 184 else if (P.isFP64bit()) 185 FpABI = FpABIKind::S64; 186 else 187 FpABI = FpABIKind::S32; 188 } 189 } 190 191 template <class PredicateLibrary> setAllFromPredicatesMipsABIFlagsSection192 void setAllFromPredicates(const PredicateLibrary &P) { 193 setISALevelAndRevisionFromPredicates(P); 194 setGPRSizeFromPredicates(P); 195 setCPR1SizeFromPredicates(P); 196 setISAExtensionFromPredicates(P); 197 setASESetFromPredicates(P); 198 setFpAbiFromPredicates(P); 199 OddSPReg = P.useOddSPReg(); 200 } 201 }; 202 203 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection); 204 205 } // end namespace llvm 206 207 #endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H 208