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 } // namespace naclbitc 106 107 /// NaClBitCodeAbbrevOp - This describes one or more operands in an 108 /// abbreviation. 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 NaClBitCodeAbbrevOp(uint64_t V)123 explicit NaClBitCodeAbbrevOp(uint64_t V) : Enc(Literal), Val(V) {} 124 explicit NaClBitCodeAbbrevOp(Encoding E, uint64_t Data = 0); 125 getEncoding()126 Encoding getEncoding() const { return Enc; } 127 isValidEncoding(uint64_t Enc)128 static bool isValidEncoding(uint64_t Enc) { return Enc <= Encoding_MAX; } 129 getValue()130 uint64_t getValue() const { return Val; } 131 hasValue()132 bool hasValue() const { return hasValue(Enc); } hasValue(Encoding E)133 static bool hasValue(Encoding E) { 134 return E <= Encoding_MAX && HasValueArray[E]; 135 } 136 isValid()137 bool isValid() const { return isValid(Enc, Val); } 138 static bool isValid(Encoding E, uint64_t Val); isValid(Encoding E)139 static bool isValid(Encoding E) { return isValid(E, 0); } 140 isLiteral()141 bool isLiteral() const { return Enc == Literal; } 142 isArrayOp()143 bool isArrayOp() const { return Enc == Array; } 144 145 /// Returns the number of arguments expected by this abbrevation operator. NumArguments()146 unsigned NumArguments() const { 147 if (isArrayOp()) 148 return 1; 149 else 150 return 0; 151 } 152 153 // Returns the name of the encoding getEncodingName(Encoding E)154 static const char *getEncodingName(Encoding E) { 155 if (E > Encoding_MAX) 156 return "???"; 157 return EncodingNameArray[E]; 158 } 159 160 /// Prints out the abbreviation operator to the given stream. 161 void Print(raw_ostream &Stream) const; 162 163 /// isChar6 - Return true if this character is legal in the Char6 encoding. isChar6(char C)164 static bool isChar6(char C) { 165 if (C >= 'a' && C <= 'z') 166 return true; 167 if (C >= 'A' && C <= 'Z') 168 return true; 169 if (C >= '0' && C <= '9') 170 return true; 171 if (C == '.' || C == '_') 172 return true; 173 return false; 174 } EncodeChar6(char C)175 static unsigned EncodeChar6(char C) { 176 if (C >= 'a' && C <= 'z') 177 return C - 'a'; 178 if (C >= 'A' && C <= 'Z') 179 return C - 'A' + 26; 180 if (C >= '0' && C <= '9') 181 return C - '0' + 26 + 26; 182 if (C == '.') 183 return 62; 184 if (C == '_') 185 return 63; 186 llvm_unreachable("Not a value Char6 character!"); 187 } 188 DecodeChar6(unsigned V)189 static char DecodeChar6(unsigned V) { 190 assert((V & ~63) == 0 && "Not a Char6 encoded character!"); 191 if (V < 26) 192 return V + 'a'; 193 if (V < 26 + 26) 194 return V - 26 + 'A'; 195 if (V < 26 + 26 + 10) 196 return V - 26 - 26 + '0'; 197 if (V == 62) 198 return '.'; 199 if (V == 63) 200 return '_'; 201 llvm_unreachable("Not a value Char6 character!"); 202 } 203 204 /// \brief Compares this to Op. Returns <0 if this is less than Op, 205 /// Returns 0 if they are equal, and >0 if this is greater than Op. Compare(const NaClBitCodeAbbrevOp & Op)206 int Compare(const NaClBitCodeAbbrevOp &Op) const { 207 // Compare encoding values. 208 int EncodingDiff = static_cast<int>(Enc) - static_cast<int>(Op.Enc); 209 if (EncodingDiff != 0) 210 return EncodingDiff; 211 212 // Encodings don't differ, so now base on data associated with the 213 // encoding. 214 return ValCompare(Op); 215 } 216 217 private: 218 Encoding Enc; // The encoding to use. 219 uint64_t Val; // Data associated with encoding (if any). 220 ValCompare(const NaClBitCodeAbbrevOp & Op)221 int ValCompare(const NaClBitCodeAbbrevOp &Op) const { 222 if (Val < Op.Val) 223 return -1; 224 else if (Val > Op.Val) 225 return 1; 226 else 227 return 0; 228 } 229 static const bool HasValueArray[]; 230 static const char *EncodingNameArray[]; 231 }; 232 233 template <> struct isPodLike<NaClBitCodeAbbrevOp> { 234 static const bool value = true; 235 }; 236 237 static inline bool operator<(const NaClBitCodeAbbrevOp &Op1, 238 const NaClBitCodeAbbrevOp &Op2) { 239 return Op1.Compare(Op2) < 0; 240 } 241 242 static inline bool operator<=(const NaClBitCodeAbbrevOp &Op1, 243 const NaClBitCodeAbbrevOp &Op2) { 244 return Op1.Compare(Op2) <= 0; 245 } 246 247 static inline bool operator==(const NaClBitCodeAbbrevOp &Op1, 248 const NaClBitCodeAbbrevOp &Op2) { 249 return Op1.Compare(Op2) == 0; 250 } 251 252 static inline bool operator!=(const NaClBitCodeAbbrevOp &Op1, 253 const NaClBitCodeAbbrevOp &Op2) { 254 return Op1.Compare(Op2) != 0; 255 } 256 257 static inline bool operator>=(const NaClBitCodeAbbrevOp &Op1, 258 const NaClBitCodeAbbrevOp &Op2) { 259 return Op1.Compare(Op2) >= 0; 260 } 261 262 static inline bool operator>(const NaClBitCodeAbbrevOp &Op1, 263 const NaClBitCodeAbbrevOp &Op2) { 264 return Op1.Compare(Op2) > 0; 265 } 266 267 /// NaClBitCodeAbbrev - This class represents an abbreviation record. An 268 /// abbreviation allows a complex record that has redundancy to be stored in a 269 /// specialized format instead of the fully-general, fully-vbr, format. 270 class NaClBitCodeAbbrev { 271 SmallVector<NaClBitCodeAbbrevOp, 8> OperandList; 272 unsigned char RefCount; // Number of things using this. 273 ~NaClBitCodeAbbrev() {} 274 275 public: 276 NaClBitCodeAbbrev() : RefCount(1) {} 277 278 void addRef() { ++RefCount; } 279 void dropRef() { 280 if (--RefCount == 0) 281 delete this; 282 } 283 284 unsigned getNumOperandInfos() const { 285 return static_cast<unsigned>(OperandList.size()); 286 } 287 const NaClBitCodeAbbrevOp &getOperandInfo(unsigned N) const { 288 return OperandList[N]; 289 } 290 291 void Add(const NaClBitCodeAbbrevOp &OpInfo) { OperandList.push_back(OpInfo); } 292 293 // Returns a simplified version of the abbreviation. Used 294 // to recognize equivalent abbrevations. 295 NaClBitCodeAbbrev *Simplify() const; 296 297 // Returns true if the abbreviation is valid wrt to the bitcode reader. 298 bool isValid() const; 299 300 int Compare(const NaClBitCodeAbbrev &Abbrev) const { 301 // First order based on number of operands. 302 size_t OperandListSize = OperandList.size(); 303 size_t AbbrevOperandListSize = Abbrev.OperandList.size(); 304 if (OperandListSize < AbbrevOperandListSize) 305 return -1; 306 else if (OperandListSize > AbbrevOperandListSize) 307 return 1; 308 309 // Same number of operands, so compare element by element. 310 for (size_t I = 0; I < OperandListSize; ++I) { 311 if (int Diff = OperandList[I].Compare(Abbrev.OperandList[I])) 312 return Diff; 313 } 314 return 0; 315 } 316 317 // Returns true if all records matching the abbreviation must be 318 // of fixed length. 319 bool IsFixedSize() const { 320 unsigned Size = getNumOperandInfos(); 321 if (Size < 2) 322 return true; 323 return !OperandList[Size - 2].isArrayOp(); 324 } 325 326 // Returns the smallest record size that will match this 327 // abbreviation. 328 size_t GetMinRecordSize() const { 329 size_t Min = getNumOperandInfos(); 330 if (!IsFixedSize()) 331 Min -= 2; 332 return Min; 333 } 334 335 void Print(raw_ostream &Stream, bool AddNewline = true) const; 336 337 NaClBitCodeAbbrev *Copy() const { 338 NaClBitCodeAbbrev *AbbrevCopy = new NaClBitCodeAbbrev(); 339 for (unsigned I = 0, IEnd = getNumOperandInfos(); I != IEnd; ++I) { 340 AbbrevCopy->Add(NaClBitCodeAbbrevOp(getOperandInfo(I))); 341 } 342 return AbbrevCopy; 343 } 344 }; 345 346 static inline bool operator<(const NaClBitCodeAbbrev &A1, 347 const NaClBitCodeAbbrev &A2) { 348 return A1.Compare(A2) < 0; 349 } 350 351 static inline bool operator<=(const NaClBitCodeAbbrev &A1, 352 const NaClBitCodeAbbrev &A2) { 353 return A1.Compare(A2) <= 0; 354 } 355 static inline bool operator==(const NaClBitCodeAbbrev &A1, 356 const NaClBitCodeAbbrev &A2) { 357 return A1.Compare(A2) == 0; 358 } 359 360 static inline bool operator!=(const NaClBitCodeAbbrev &A1, 361 const NaClBitCodeAbbrev &A2) { 362 return A1.Compare(A2) != 0; 363 } 364 static inline bool operator>=(const NaClBitCodeAbbrev &A1, 365 const NaClBitCodeAbbrev &A2) { 366 return A1.Compare(A2) >= 0; 367 } 368 369 static inline bool operator>(const NaClBitCodeAbbrev &A1, 370 const NaClBitCodeAbbrev &A2) { 371 return A1.Compare(A2) > 0; 372 } 373 374 /// \brief Returns number of bits needed to encode 375 /// value for dense FIXED encoding. 376 inline unsigned NaClBitsNeededForValue(unsigned Value) { 377 // Note: Need to handle case where Value=0xFFFFFFFF as special case, 378 // since we can't add 1 to it. 379 if (Value >= 0x80000000) 380 return 32; 381 return Log2_32_Ceil(Value + 1); 382 } 383 384 /// \brief Encode a signed value by moving the sign to the LSB for dense 385 /// VBR encoding. 386 inline uint64_t NaClEncodeSignRotatedValue(int64_t V) { 387 return (V >= 0) ? (V << 1) : ((-V << 1) | 1); 388 } 389 390 /// \brief Decode a signed value stored with the sign bit in 391 /// the LSB for dense VBR encoding. 392 inline uint64_t NaClDecodeSignRotatedValue(uint64_t V) { 393 if ((V & 1) == 0) 394 return V >> 1; 395 if (V != 1) 396 return -(V >> 1); 397 // There is no such thing as -0 with integers. "-0" really means MININT. 398 return 1ULL << 63; 399 } 400 401 /// \brief This class determines whether a FIXED or VBR 402 /// abbreviation should be used for the selector, and the number of bits 403 /// needed to capture such selectors. 404 class NaClBitcodeSelectorAbbrev { 405 406 public: 407 // If true, use a FIXED abbreviation. Otherwise, use a VBR abbreviation. 408 bool IsFixed; 409 // Number of bits needed for selector. 410 unsigned NumBits; 411 412 // Creates a selector range for the given values. 413 NaClBitcodeSelectorAbbrev(bool IF, unsigned NB) : IsFixed(IF), NumBits(NB) {} 414 415 // Creates a selector range when no abbreviations are defined. 416 NaClBitcodeSelectorAbbrev() 417 : IsFixed(true), 418 NumBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) {} 419 420 // Creates a selector range to handle fixed abbrevations up to 421 // the specified value. 422 explicit NaClBitcodeSelectorAbbrev(unsigned MaxAbbrev) 423 : IsFixed(true), NumBits(NaClBitsNeededForValue(MaxAbbrev)) {} 424 }; 425 } // namespace llvm 426 427 #endif 428