1 //===- NaClBitCodes.h - Enum values for the bitcode format ------*- 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 // This header Bitcode enum values. 11 // 12 // The enum values defined in this file should be considered permanent. If 13 // new features are added, they should have values added at the end of the 14 // respective lists. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_BITCODE_NACL_NACLBITCODES_H 19 #define LLVM_BITCODE_NACL_NACLBITCODES_H 20 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/Support/DataTypes.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/MathExtras.h" 25 #include <climits> 26 27 namespace llvm { 28 class raw_ostream; 29 30 namespace naclbitc { 31 enum StandardWidths { 32 BlockIDWidth = 8, // We use VBR-8 for block IDs. 33 CodeLenWidth = 4, // Codelen are VBR-4. 34 BlockSizeWidth = 32, // BlockSize up to 2^32 32-bit words = 16GB per block. 35 MaxAbbrevWidth = 32, // Maximum value allowed for Fixed and VBR. 36 BitstreamWordSize = sizeof(uint32_t), // Number of bytes in bitstream word. 37 MinRecordBitSize = 2 // Minimum number of bits needed to represent a record. 38 }; 39 40 // The standard abbrev namespace always has a way to exit a block, enter a 41 // nested block, define abbrevs, and define an unabbreviated record. 42 enum FixedAbbrevIDs { 43 END_BLOCK = 0, // Must be zero to guarantee termination for broken bitcode. 44 ENTER_SUBBLOCK = 1, 45 46 /// DEFINE_ABBREV - Defines an abbrev for the current block. It consists 47 /// of a vbr5 for # operand infos. Each operand info is emitted with a 48 /// single bit to indicate if it is a literal encoding. If so, the value is 49 /// emitted with a vbr8. If not, the encoding is emitted as 3 bits followed 50 /// by the info value as a vbr5 if needed. 51 DEFINE_ABBREV = 2, 52 53 // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by 54 // a vbr6 for the # operands, followed by vbr6's for each operand. 55 UNABBREV_RECORD = 3, 56 57 // This is not a code, this is a marker for the first abbrev assignment. 58 // In addition, we assume up to two additional enumerated constants are 59 // added for each extension. These constants are: 60 // 61 // PREFIX_MAX_FIXED_ABBREV 62 // PREFIX_MAX_ABBREV 63 // 64 // PREFIX_MAX_ABBREV defines the maximal enumeration value used for 65 // the code selector of a block. If Both PREFIX_MAX_FIXED_ABBREV 66 // and PREFIX_MAX_ABBREV is defined, then PREFIX_MAX_FIXED_ABBREV 67 // defines the last code selector of the block that must be read using 68 // a single read (i.e. a FIXED read, or the first chunk of a VBR read. 69 FIRST_APPLICATION_ABBREV = 4, 70 // Defines default values for code length, if no additional selectors 71 // are added. 72 DEFAULT_MAX_ABBREV = FIRST_APPLICATION_ABBREV-1 73 }; 74 75 /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO 76 /// block, which contains metadata about other blocks in the file. 77 enum StandardBlockIDs { 78 /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example, 79 /// standard abbrevs that should be available to all blocks of a specified 80 /// ID. 81 BLOCKINFO_BLOCK_ID = 0, 82 // Block IDs 1-6 are reserved for future expansion. 83 // Dummy block added around all records in a bitcode file. Allows the code 84 // to treat top-level records like all other records (i.e. all records 85 // appear in a block). 86 TOP_LEVEL_BLOCKID = 7, 87 FIRST_APPLICATION_BLOCKID = 8 88 }; 89 90 /// BlockInfoCodes - The blockinfo block contains metadata about user-defined 91 /// blocks. 92 enum BlockInfoCodes { 93 // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd 94 // block, instead of the BlockInfo block. 95 96 BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] 97 // The following two codes were removed 98 // because the PNaCl reader could read 99 // them, but couldn't be generated by 100 // the writer. 101 BLOCKINFO_CODE_BLOCKNAME = 2, // Not used in PNaCl. 102 BLOCKINFO_CODE_SETRECORDNAME = 3 // Not used in PNaCl. 103 }; 104 105 } // End naclbitc namespace 106 107 /// NaClBitCodeAbbrevOp - This describes one or more operands in an abbreviation. 108 /// This is actually a union of two different things: 109 /// 1. It could be a literal integer value ("the operand is always 17"). 110 /// 2. It could be an encoding specification ("this operand encoded like so"). 111 /// 112 class NaClBitCodeAbbrevOp { 113 public: 114 enum Encoding { 115 Literal = 0, // Value is literal value. 116 Fixed = 1, // A fixed width field, Val specifies number of bits. 117 VBR = 2, // A VBR field where Val specifies the width of each chunk. 118 Array = 3, // A sequence of fields, next field species elt encoding. 119 Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._]. 120 Encoding_MAX = Char6 121 }; 122 123 explicit NaClBitCodeAbbrevOp(uint64_t V) : Enc(Literal), Val(V) {} 124 explicit NaClBitCodeAbbrevOp(Encoding E, uint64_t Data = 0); 125 126 Encoding getEncoding() const { return Enc; } 127 128 static bool isValidEncoding(uint64_t Enc) { return Enc <= Encoding_MAX; } 129 130 uint64_t getValue() const { return Val; } 131 132 bool hasValue() const { 133 return hasValue(Enc); 134 } 135 static bool hasValue(Encoding E) { 136 return E <= Encoding_MAX && HasValueArray[E]; 137 } 138 139 bool isValid() const { return isValid(Enc, Val); } 140 static bool isValid(Encoding E, uint64_t Val); 141 static bool isValid(Encoding E) { return isValid(E, 0); } 142 143 bool isLiteral() const { return Enc == Literal; } 144 145 bool isArrayOp() const { return Enc == Array; } 146 147 /// Returns the number of arguments expected by this abbrevation operator. 148 unsigned NumArguments() const { 149 if (isArrayOp()) 150 return 1; 151 else 152 return 0; 153 } 154 155 // Returns the name of the encoding 156 static const char *getEncodingName(Encoding E) { 157 if (E > Encoding_MAX) 158 return "???"; 159 return EncodingNameArray[E]; 160 } 161 162 /// Prints out the abbreviation operator to the given stream. 163 void Print(raw_ostream &Stream) const; 164 165 /// isChar6 - Return true if this character is legal in the Char6 encoding. 166 static bool isChar6(char C) { 167 if (C >= 'a' && C <= 'z') return true; 168 if (C >= 'A' && C <= 'Z') return true; 169 if (C >= '0' && C <= '9') return true; 170 if (C == '.' || C == '_') return true; 171 return false; 172 } 173 static unsigned EncodeChar6(char C) { 174 if (C >= 'a' && C <= 'z') return C-'a'; 175 if (C >= 'A' && C <= 'Z') return C-'A'+26; 176 if (C >= '0' && C <= '9') return C-'0'+26+26; 177 if (C == '.') return 62; 178 if (C == '_') return 63; 179 llvm_unreachable("Not a value Char6 character!"); 180 } 181 182 static char DecodeChar6(unsigned V) { 183 assert((V & ~63) == 0 && "Not a Char6 encoded character!"); 184 if (V < 26) return V+'a'; 185 if (V < 26+26) return V-26+'A'; 186 if (V < 26+26+10) return V-26-26+'0'; 187 if (V == 62) return '.'; 188 if (V == 63) return '_'; 189 llvm_unreachable("Not a value Char6 character!"); 190 } 191 192 /// \brief Compares this to Op. Returns <0 if this is less than Op, 193 /// Returns 0 if they are equal, and >0 if this is greater than Op. 194 int Compare(const NaClBitCodeAbbrevOp &Op) const { 195 // Compare encoding values. 196 int EncodingDiff = static_cast<int>(Enc) - static_cast<int>(Op.Enc); 197 if (EncodingDiff != 0) return EncodingDiff; 198 199 // Encodings don't differ, so now base on data associated with the 200 // encoding. 201 return ValCompare(Op); 202 } 203 204 private: 205 Encoding Enc; // The encoding to use. 206 uint64_t Val; // Data associated with encoding (if any). 207 208 int ValCompare(const NaClBitCodeAbbrevOp &Op) const { 209 if (Val < Op.Val) 210 return -1; 211 else if (Val > Op.Val) 212 return 1; 213 else 214 return 0; 215 } 216 static const bool HasValueArray[]; 217 static const char *EncodingNameArray[]; 218 }; 219 220 template <> struct isPodLike<NaClBitCodeAbbrevOp> { 221 static const bool value=true; 222 }; 223 224 static inline bool operator<(const NaClBitCodeAbbrevOp &Op1, 225 const NaClBitCodeAbbrevOp &Op2) { 226 return Op1.Compare(Op2) < 0; 227 } 228 229 static inline bool operator<=(const NaClBitCodeAbbrevOp &Op1, 230 const NaClBitCodeAbbrevOp &Op2) { 231 return Op1.Compare(Op2) <= 0; 232 } 233 234 static inline bool operator==(const NaClBitCodeAbbrevOp &Op1, 235 const NaClBitCodeAbbrevOp &Op2) { 236 return Op1.Compare(Op2) == 0; 237 } 238 239 static inline bool operator!=(const NaClBitCodeAbbrevOp &Op1, 240 const NaClBitCodeAbbrevOp &Op2) { 241 return Op1.Compare(Op2) != 0; 242 } 243 244 static inline bool operator>=(const NaClBitCodeAbbrevOp &Op1, 245 const NaClBitCodeAbbrevOp &Op2) { 246 return Op1.Compare(Op2) >= 0; 247 } 248 249 static inline bool operator>(const NaClBitCodeAbbrevOp &Op1, 250 const NaClBitCodeAbbrevOp &Op2) { 251 return Op1.Compare(Op2) > 0; 252 } 253 254 /// NaClBitCodeAbbrev - This class represents an abbreviation record. An 255 /// abbreviation allows a complex record that has redundancy to be stored in a 256 /// specialized format instead of the fully-general, fully-vbr, format. 257 class NaClBitCodeAbbrev { 258 SmallVector<NaClBitCodeAbbrevOp, 8> OperandList; 259 unsigned char RefCount; // Number of things using this. 260 ~NaClBitCodeAbbrev() {} 261 public: 262 NaClBitCodeAbbrev() : RefCount(1) {} 263 264 void addRef() { ++RefCount; } 265 void dropRef() { if (--RefCount == 0) delete this; } 266 267 unsigned getNumOperandInfos() const { 268 return static_cast<unsigned>(OperandList.size()); 269 } 270 const NaClBitCodeAbbrevOp &getOperandInfo(unsigned N) const { 271 return OperandList[N]; 272 } 273 274 void Add(const NaClBitCodeAbbrevOp &OpInfo) { 275 OperandList.push_back(OpInfo); 276 } 277 278 // Returns a simplified version of the abbreviation. Used 279 // to recognize equivalent abbrevations. 280 NaClBitCodeAbbrev *Simplify() const; 281 282 // Returns true if the abbreviation is valid wrt to the bitcode reader. 283 bool isValid() const; 284 285 int Compare(const NaClBitCodeAbbrev &Abbrev) const { 286 // First order based on number of operands. 287 size_t OperandListSize = OperandList.size(); 288 size_t AbbrevOperandListSize = Abbrev.OperandList.size(); 289 if (OperandListSize < AbbrevOperandListSize) 290 return -1; 291 else if (OperandListSize > AbbrevOperandListSize) 292 return 1; 293 294 // Same number of operands, so compare element by element. 295 for (size_t I = 0; I < OperandListSize; ++I) { 296 if (int Diff = OperandList[I].Compare(Abbrev.OperandList[I])) 297 return Diff; 298 } 299 return 0; 300 } 301 302 // Returns true if all records matching the abbreviation must be 303 // of fixed length. 304 bool IsFixedSize() const { 305 unsigned Size = getNumOperandInfos(); 306 if (Size < 2) return true; 307 return !OperandList[Size-2].isArrayOp(); 308 } 309 310 // Returns the smallest record size that will match this 311 // abbreviation. 312 size_t GetMinRecordSize() const { 313 size_t Min = getNumOperandInfos(); 314 if (!IsFixedSize()) Min -= 2; 315 return Min; 316 } 317 318 void Print(raw_ostream &Stream, bool AddNewline=true) const; 319 320 NaClBitCodeAbbrev *Copy() const { 321 NaClBitCodeAbbrev *AbbrevCopy = new NaClBitCodeAbbrev(); 322 for (unsigned I = 0, IEnd = getNumOperandInfos(); 323 I != IEnd; ++I) { 324 AbbrevCopy->Add(NaClBitCodeAbbrevOp(getOperandInfo(I))); 325 } 326 return AbbrevCopy; 327 } 328 }; 329 330 static inline bool operator<(const NaClBitCodeAbbrev &A1, 331 const NaClBitCodeAbbrev &A2) { 332 return A1.Compare(A2) < 0; 333 } 334 335 static inline bool operator<=(const NaClBitCodeAbbrev &A1, 336 const NaClBitCodeAbbrev &A2) { 337 return A1.Compare(A2) <= 0; 338 } 339 static inline bool operator==(const NaClBitCodeAbbrev &A1, 340 const NaClBitCodeAbbrev &A2) { 341 return A1.Compare(A2) == 0; 342 } 343 344 static inline bool operator!=(const NaClBitCodeAbbrev &A1, 345 const NaClBitCodeAbbrev &A2) { 346 return A1.Compare(A2) != 0; 347 } 348 static inline bool operator>=(const NaClBitCodeAbbrev &A1, 349 const NaClBitCodeAbbrev &A2) { 350 return A1.Compare(A2) >= 0; 351 } 352 353 static inline bool operator>(const NaClBitCodeAbbrev &A1, 354 const NaClBitCodeAbbrev &A2) { 355 return A1.Compare(A2) > 0; 356 } 357 358 /// \brief Returns number of bits needed to encode 359 /// value for dense FIXED encoding. 360 inline unsigned NaClBitsNeededForValue(unsigned Value) { 361 // Note: Need to handle case where Value=0xFFFFFFFF as special case, 362 // since we can't add 1 to it. 363 if (Value >= 0x80000000) return 32; 364 return Log2_32_Ceil(Value+1); 365 } 366 367 /// \brief Encode a signed value by moving the sign to the LSB for dense 368 /// VBR encoding. 369 inline uint64_t NaClEncodeSignRotatedValue(int64_t V) { 370 return (V >= 0) ? (V << 1) : ((-V << 1) | 1); 371 } 372 373 /// \brief Decode a signed value stored with the sign bit in 374 /// the LSB for dense VBR encoding. 375 inline uint64_t NaClDecodeSignRotatedValue(uint64_t V) { 376 if ((V & 1) == 0) 377 return V >> 1; 378 if (V != 1) 379 return -(V >> 1); 380 // There is no such thing as -0 with integers. "-0" really means MININT. 381 return 1ULL << 63; 382 } 383 384 /// \brief This class determines whether a FIXED or VBR 385 /// abbreviation should be used for the selector, and the number of bits 386 /// needed to capture such selectors. 387 class NaClBitcodeSelectorAbbrev { 388 389 public: 390 // If true, use a FIXED abbreviation. Otherwise, use a VBR abbreviation. 391 bool IsFixed; 392 // Number of bits needed for selector. 393 unsigned NumBits; 394 395 // Creates a selector range for the given values. 396 NaClBitcodeSelectorAbbrev(bool IF, unsigned NB) 397 : IsFixed(IF), NumBits(NB) {} 398 399 // Creates a selector range when no abbreviations are defined. 400 NaClBitcodeSelectorAbbrev() 401 : IsFixed(true), 402 NumBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) {} 403 404 // Creates a selector range to handle fixed abbrevations up to 405 // the specified value. 406 explicit NaClBitcodeSelectorAbbrev(unsigned MaxAbbrev) 407 : IsFixed(true), 408 NumBits(NaClBitsNeededForValue(MaxAbbrev)) {} 409 }; 410 } // End llvm namespace 411 412 #endif 413