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/MC/MCStreamer.h" 14 15 namespace llvm { 16 17 class MCStreamer; 18 19 struct MipsABIFlagsSection { 20 // Values for the xxx_size bytes of an ABI flags structure. 21 enum AFL_REG { 22 AFL_REG_NONE = 0x00, // No registers. 23 AFL_REG_32 = 0x01, // 32-bit registers. 24 AFL_REG_64 = 0x02, // 64-bit registers. 25 AFL_REG_128 = 0x03 // 128-bit registers. 26 }; 27 28 // Masks for the ases word of an ABI flags structure. 29 enum AFL_ASE { 30 AFL_ASE_DSP = 0x00000001, // DSP ASE. 31 AFL_ASE_DSPR2 = 0x00000002, // DSP R2 ASE. 32 AFL_ASE_EVA = 0x00000004, // Enhanced VA Scheme. 33 AFL_ASE_MCU = 0x00000008, // MCU (MicroController) ASE. 34 AFL_ASE_MDMX = 0x00000010, // MDMX ASE. 35 AFL_ASE_MIPS3D = 0x00000020, // MIPS-3D ASE. 36 AFL_ASE_MT = 0x00000040, // MT ASE. 37 AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE. 38 AFL_ASE_VIRT = 0x00000100, // VZ ASE. 39 AFL_ASE_MSA = 0x00000200, // MSA ASE. 40 AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE. 41 AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE. 42 AFL_ASE_XPA = 0x00001000 // XPA ASE. 43 }; 44 45 // Values for the isa_ext word of an ABI flags structure. 46 enum AFL_EXT { 47 AFL_EXT_XLR = 1, // RMI Xlr instruction. 48 AFL_EXT_OCTEON2 = 2, // Cavium Networks Octeon2. 49 AFL_EXT_OCTEONP = 3, // Cavium Networks OcteonP. 50 AFL_EXT_LOONGSON_3A = 4, // Loongson 3A. 51 AFL_EXT_OCTEON = 5, // Cavium Networks Octeon. 52 AFL_EXT_5900 = 6, // MIPS R5900 instruction. 53 AFL_EXT_4650 = 7, // MIPS R4650 instruction. 54 AFL_EXT_4010 = 8, // LSI R4010 instruction. 55 AFL_EXT_4100 = 9, // NEC VR4100 instruction. 56 AFL_EXT_3900 = 10, // Toshiba R3900 instruction. 57 AFL_EXT_10000 = 11, // MIPS R10000 instruction. 58 AFL_EXT_SB1 = 12, // Broadcom SB-1 instruction. 59 AFL_EXT_4111 = 13, // NEC VR4111/VR4181 instruction. 60 AFL_EXT_4120 = 14, // NEC VR4120 instruction. 61 AFL_EXT_5400 = 15, // NEC VR5400 instruction. 62 AFL_EXT_5500 = 16, // NEC VR5500 instruction. 63 AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E. 64 AFL_EXT_LOONGSON_2F = 18 // ST Microelectronics Loongson 2F. 65 }; 66 67 // Values for the fp_abi word of an ABI flags structure. 68 enum Val_GNU_MIPS_ABI { 69 Val_GNU_MIPS_ABI_FP_ANY = 0, 70 Val_GNU_MIPS_ABI_FP_DOUBLE = 1, 71 Val_GNU_MIPS_ABI_FP_XX = 5, 72 Val_GNU_MIPS_ABI_FP_64 = 6, 73 Val_GNU_MIPS_ABI_FP_64A = 7 74 }; 75 76 enum AFL_FLAGS1 { 77 AFL_FLAGS1_ODDSPREG = 1 78 }; 79 80 // Internal representation of the values used in .module fp=value 81 enum class FpABIKind { ANY, XX, S32, S64 }; 82 83 // Version of flags structure. 84 uint16_t Version; 85 // The level of the ISA: 1-5, 32, 64. 86 uint8_t ISALevel; 87 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise. 88 uint8_t ISARevision; 89 // The size of general purpose registers. 90 AFL_REG GPRSize; 91 // The size of co-processor 1 registers. 92 AFL_REG CPR1Size; 93 // The size of co-processor 2 registers. 94 AFL_REG CPR2Size; 95 // Processor-specific extension. 96 uint32_t ISAExtensionSet; 97 // Mask of ASEs used. 98 uint32_t ASESet; 99 100 bool OddSPReg; 101 102 bool Is32BitABI; 103 104 protected: 105 // The floating-point ABI. 106 FpABIKind FpABI; 107 108 public: MipsABIFlagsSectionMipsABIFlagsSection109 MipsABIFlagsSection() 110 : Version(0), ISALevel(0), ISARevision(0), GPRSize(AFL_REG_NONE), 111 CPR1Size(AFL_REG_NONE), CPR2Size(AFL_REG_NONE), ISAExtensionSet(0), 112 ASESet(0), OddSPReg(false), Is32BitABI(false), FpABI(FpABIKind::ANY) {} 113 getVersionValueMipsABIFlagsSection114 uint16_t getVersionValue() { return (uint16_t)Version; } getISALevelValueMipsABIFlagsSection115 uint8_t getISALevelValue() { return (uint8_t)ISALevel; } getISARevisionValueMipsABIFlagsSection116 uint8_t getISARevisionValue() { return (uint8_t)ISARevision; } getGPRSizeValueMipsABIFlagsSection117 uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; } 118 uint8_t getCPR1SizeValue(); getCPR2SizeValueMipsABIFlagsSection119 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; } 120 uint8_t getFpABIValue(); getISAExtensionSetValueMipsABIFlagsSection121 uint32_t getISAExtensionSetValue() { return (uint32_t)ISAExtensionSet; } getASESetValueMipsABIFlagsSection122 uint32_t getASESetValue() { return (uint32_t)ASESet; } 123 getFlags1ValueMipsABIFlagsSection124 uint32_t getFlags1Value() { 125 uint32_t Value = 0; 126 127 if (OddSPReg) 128 Value |= (uint32_t)AFL_FLAGS1_ODDSPREG; 129 130 return Value; 131 } 132 getFlags2ValueMipsABIFlagsSection133 uint32_t getFlags2Value() { return 0; } 134 getFpABIMipsABIFlagsSection135 FpABIKind getFpABI() { return FpABI; } setFpABIMipsABIFlagsSection136 void setFpABI(FpABIKind Value, bool IsABI32Bit) { 137 FpABI = Value; 138 Is32BitABI = IsABI32Bit; 139 } 140 StringRef getFpABIString(FpABIKind Value); 141 142 template <class PredicateLibrary> setISALevelAndRevisionFromPredicatesMipsABIFlagsSection143 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) { 144 if (P.hasMips64()) { 145 ISALevel = 64; 146 if (P.hasMips64r6()) 147 ISARevision = 6; 148 else if (P.hasMips64r5()) 149 ISARevision = 5; 150 else if (P.hasMips64r3()) 151 ISARevision = 3; 152 else if (P.hasMips64r2()) 153 ISARevision = 2; 154 else 155 ISARevision = 1; 156 } else if (P.hasMips32()) { 157 ISALevel = 32; 158 if (P.hasMips32r6()) 159 ISARevision = 6; 160 else if (P.hasMips32r5()) 161 ISARevision = 5; 162 else if (P.hasMips32r3()) 163 ISARevision = 3; 164 else if (P.hasMips32r2()) 165 ISARevision = 2; 166 else 167 ISARevision = 1; 168 } else { 169 ISARevision = 0; 170 if (P.hasMips5()) 171 ISALevel = 5; 172 else if (P.hasMips4()) 173 ISALevel = 4; 174 else if (P.hasMips3()) 175 ISALevel = 3; 176 else if (P.hasMips2()) 177 ISALevel = 2; 178 else if (P.hasMips1()) 179 ISALevel = 1; 180 else 181 llvm_unreachable("Unknown ISA level!"); 182 } 183 } 184 185 template <class PredicateLibrary> setGPRSizeFromPredicatesMipsABIFlagsSection186 void setGPRSizeFromPredicates(const PredicateLibrary &P) { 187 GPRSize = P.isGP64bit() ? AFL_REG_64 : AFL_REG_32; 188 } 189 190 template <class PredicateLibrary> setCPR1SizeFromPredicatesMipsABIFlagsSection191 void setCPR1SizeFromPredicates(const PredicateLibrary &P) { 192 if (P.abiUsesSoftFloat()) 193 CPR1Size = AFL_REG_NONE; 194 else if (P.hasMSA()) 195 CPR1Size = AFL_REG_128; 196 else 197 CPR1Size = P.isFP64bit() ? AFL_REG_64 : AFL_REG_32; 198 } 199 200 template <class PredicateLibrary> setASESetFromPredicatesMipsABIFlagsSection201 void setASESetFromPredicates(const PredicateLibrary &P) { 202 ASESet = 0; 203 if (P.hasDSP()) 204 ASESet |= AFL_ASE_DSP; 205 if (P.hasDSPR2()) 206 ASESet |= AFL_ASE_DSPR2; 207 if (P.hasMSA()) 208 ASESet |= AFL_ASE_MSA; 209 if (P.inMicroMipsMode()) 210 ASESet |= AFL_ASE_MICROMIPS; 211 if (P.inMips16Mode()) 212 ASESet |= AFL_ASE_MIPS16; 213 } 214 215 template <class PredicateLibrary> setFpAbiFromPredicatesMipsABIFlagsSection216 void setFpAbiFromPredicates(const PredicateLibrary &P) { 217 Is32BitABI = P.isABI_O32(); 218 219 FpABI = FpABIKind::ANY; 220 if (P.isABI_N32() || P.isABI_N64()) 221 FpABI = FpABIKind::S64; 222 else if (P.isABI_O32()) { 223 if (P.isABI_FPXX()) 224 FpABI = FpABIKind::XX; 225 else if (P.isFP64bit()) 226 FpABI = FpABIKind::S64; 227 else 228 FpABI = FpABIKind::S32; 229 } 230 } 231 232 template <class PredicateLibrary> setAllFromPredicatesMipsABIFlagsSection233 void setAllFromPredicates(const PredicateLibrary &P) { 234 setISALevelAndRevisionFromPredicates(P); 235 setGPRSizeFromPredicates(P); 236 setCPR1SizeFromPredicates(P); 237 setASESetFromPredicates(P); 238 setFpAbiFromPredicates(P); 239 OddSPReg = P.useOddSPReg(); 240 } 241 }; 242 243 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection); 244 } 245 246 #endif 247