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 MIPSABIFLAGSSECTION_H 11 #define 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; } getCPR1SizeValueMipsABIFlagsSection118 uint8_t getCPR1SizeValue() { return (uint8_t)CPR1Size; } 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.hasMips64r2()) 149 ISARevision = 2; 150 else 151 ISARevision = 1; 152 } else if (P.hasMips32()) { 153 ISALevel = 32; 154 if (P.hasMips32r6()) 155 ISARevision = 6; 156 else if (P.hasMips32r2()) 157 ISARevision = 2; 158 else 159 ISARevision = 1; 160 } else { 161 ISARevision = 0; 162 if (P.hasMips5()) 163 ISALevel = 5; 164 else if (P.hasMips4()) 165 ISALevel = 4; 166 else if (P.hasMips3()) 167 ISALevel = 3; 168 else if (P.hasMips2()) 169 ISALevel = 2; 170 else if (P.hasMips1()) 171 ISALevel = 1; 172 else 173 llvm_unreachable("Unknown ISA level!"); 174 } 175 } 176 177 template <class PredicateLibrary> setGPRSizeFromPredicatesMipsABIFlagsSection178 void setGPRSizeFromPredicates(const PredicateLibrary &P) { 179 GPRSize = P.isGP64bit() ? AFL_REG_64 : AFL_REG_32; 180 } 181 182 template <class PredicateLibrary> setCPR1SizeFromPredicatesMipsABIFlagsSection183 void setCPR1SizeFromPredicates(const PredicateLibrary &P) { 184 if (P.mipsSEUsesSoftFloat()) 185 CPR1Size = AFL_REG_NONE; 186 else if (P.hasMSA()) 187 CPR1Size = AFL_REG_128; 188 else 189 CPR1Size = P.isFP64bit() ? AFL_REG_64 : AFL_REG_32; 190 } 191 192 template <class PredicateLibrary> setASESetFromPredicatesMipsABIFlagsSection193 void setASESetFromPredicates(const PredicateLibrary &P) { 194 ASESet = 0; 195 if (P.hasDSP()) 196 ASESet |= AFL_ASE_DSP; 197 if (P.hasDSPR2()) 198 ASESet |= AFL_ASE_DSPR2; 199 if (P.hasMSA()) 200 ASESet |= AFL_ASE_MSA; 201 if (P.inMicroMipsMode()) 202 ASESet |= AFL_ASE_MICROMIPS; 203 if (P.inMips16Mode()) 204 ASESet |= AFL_ASE_MIPS16; 205 } 206 207 template <class PredicateLibrary> setFpAbiFromPredicatesMipsABIFlagsSection208 void setFpAbiFromPredicates(const PredicateLibrary &P) { 209 Is32BitABI = P.isABI_O32(); 210 211 FpABI = FpABIKind::ANY; 212 if (P.isABI_N32() || P.isABI_N64()) 213 FpABI = FpABIKind::S64; 214 else if (P.isABI_O32()) { 215 if (P.isFP64bit()) 216 FpABI = FpABIKind::S64; 217 else if (P.isABI_FPXX()) 218 FpABI = FpABIKind::XX; 219 else 220 FpABI = FpABIKind::S32; 221 } 222 } 223 224 template <class PredicateLibrary> setAllFromPredicatesMipsABIFlagsSection225 void setAllFromPredicates(const PredicateLibrary &P) { 226 setISALevelAndRevisionFromPredicates(P); 227 setGPRSizeFromPredicates(P); 228 setCPR1SizeFromPredicates(P); 229 setASESetFromPredicates(P); 230 setFpAbiFromPredicates(P); 231 } 232 }; 233 234 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection); 235 } 236 237 #endif 238