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