Index: pnacl-llvm/include/llvm/Bitcode/NaCl/NaClBitCodes.h |
diff --git a/pnacl-llvm/include/llvm/Bitcode/NaCl/NaClBitCodes.h b/pnacl-llvm/include/llvm/Bitcode/NaCl/NaClBitCodes.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..44069a559c8a1f98f186e6fe76c0ef2efdffa764 |
--- /dev/null |
+++ b/pnacl-llvm/include/llvm/Bitcode/NaCl/NaClBitCodes.h |
@@ -0,0 +1,412 @@ |
+//===- NaClBitCodes.h - Enum values for the bitcode format ------*- C++ -*-===// |
+// |
+// The LLVM Compiler Infrastructure |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// This header Bitcode enum values. |
+// |
+// The enum values defined in this file should be considered permanent. If |
+// new features are added, they should have values added at the end of the |
+// respective lists. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#ifndef LLVM_BITCODE_NACL_NACLBITCODES_H |
+#define LLVM_BITCODE_NACL_NACLBITCODES_H |
+ |
+#include "llvm/ADT/SmallVector.h" |
+#include "llvm/Support/DataTypes.h" |
+#include "llvm/Support/ErrorHandling.h" |
+#include "llvm/Support/MathExtras.h" |
+#include <climits> |
+ |
+namespace llvm { |
+class raw_ostream; |
+ |
+namespace naclbitc { |
+enum StandardWidths { |
+ BlockIDWidth = 8, // We use VBR-8 for block IDs. |
+ CodeLenWidth = 4, // Codelen are VBR-4. |
+ BlockSizeWidth = 32, // BlockSize up to 2^32 32-bit words = 16GB per block. |
+ MaxAbbrevWidth = 32, // Maximum value allowed for Fixed and VBR. |
+ BitstreamWordSize = sizeof(uint32_t), // Number of bytes in bitstream word. |
+ MinRecordBitSize = 2 // Minimum number of bits needed to represent a record. |
+}; |
+ |
+ // The standard abbrev namespace always has a way to exit a block, enter a |
+ // nested block, define abbrevs, and define an unabbreviated record. |
+ enum FixedAbbrevIDs { |
+ END_BLOCK = 0, // Must be zero to guarantee termination for broken bitcode. |
+ ENTER_SUBBLOCK = 1, |
+ |
+ /// DEFINE_ABBREV - Defines an abbrev for the current block. It consists |
+ /// of a vbr5 for # operand infos. Each operand info is emitted with a |
+ /// single bit to indicate if it is a literal encoding. If so, the value is |
+ /// emitted with a vbr8. If not, the encoding is emitted as 3 bits followed |
+ /// by the info value as a vbr5 if needed. |
+ DEFINE_ABBREV = 2, |
+ |
+ // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by |
+ // a vbr6 for the # operands, followed by vbr6's for each operand. |
+ UNABBREV_RECORD = 3, |
+ |
+ // This is not a code, this is a marker for the first abbrev assignment. |
+ // In addition, we assume up to two additional enumerated constants are |
+ // added for each extension. These constants are: |
+ // |
+ // PREFIX_MAX_FIXED_ABBREV |
+ // PREFIX_MAX_ABBREV |
+ // |
+ // PREFIX_MAX_ABBREV defines the maximal enumeration value used for |
+ // the code selector of a block. If Both PREFIX_MAX_FIXED_ABBREV |
+ // and PREFIX_MAX_ABBREV is defined, then PREFIX_MAX_FIXED_ABBREV |
+ // defines the last code selector of the block that must be read using |
+ // a single read (i.e. a FIXED read, or the first chunk of a VBR read. |
+ FIRST_APPLICATION_ABBREV = 4, |
+ // Defines default values for code length, if no additional selectors |
+ // are added. |
+ DEFAULT_MAX_ABBREV = FIRST_APPLICATION_ABBREV-1 |
+ }; |
+ |
+ /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO |
+ /// block, which contains metadata about other blocks in the file. |
+ enum StandardBlockIDs { |
+ /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example, |
+ /// standard abbrevs that should be available to all blocks of a specified |
+ /// ID. |
+ BLOCKINFO_BLOCK_ID = 0, |
+ // Block IDs 1-6 are reserved for future expansion. |
+ // Dummy block added around all records in a bitcode file. Allows the code |
+ // to treat top-level records like all other records (i.e. all records |
+ // appear in a block). |
+ TOP_LEVEL_BLOCKID = 7, |
+ FIRST_APPLICATION_BLOCKID = 8 |
+ }; |
+ |
+ /// BlockInfoCodes - The blockinfo block contains metadata about user-defined |
+ /// blocks. |
+ enum BlockInfoCodes { |
+ // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd |
+ // block, instead of the BlockInfo block. |
+ |
+ BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] |
+ // The following two codes were removed |
+ // because the PNaCl reader could read |
+ // them, but couldn't be generated by |
+ // the writer. |
+ BLOCKINFO_CODE_BLOCKNAME = 2, // Not used in PNaCl. |
+ BLOCKINFO_CODE_SETRECORDNAME = 3 // Not used in PNaCl. |
+ }; |
+ |
+} // End naclbitc namespace |
+ |
+/// NaClBitCodeAbbrevOp - This describes one or more operands in an abbreviation. |
+/// This is actually a union of two different things: |
+/// 1. It could be a literal integer value ("the operand is always 17"). |
+/// 2. It could be an encoding specification ("this operand encoded like so"). |
+/// |
+class NaClBitCodeAbbrevOp { |
+public: |
+ enum Encoding { |
+ Literal = 0, // Value is literal value. |
+ Fixed = 1, // A fixed width field, Val specifies number of bits. |
+ VBR = 2, // A VBR field where Val specifies the width of each chunk. |
+ Array = 3, // A sequence of fields, next field species elt encoding. |
+ Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._]. |
+ Encoding_MAX = Char6 |
+ }; |
+ |
+ explicit NaClBitCodeAbbrevOp(uint64_t V) : Enc(Literal), Val(V) {} |
+ explicit NaClBitCodeAbbrevOp(Encoding E, uint64_t Data = 0); |
+ |
+ Encoding getEncoding() const { return Enc; } |
+ |
+ static bool isValidEncoding(uint64_t Enc) { return Enc <= Encoding_MAX; } |
+ |
+ uint64_t getValue() const { return Val; } |
+ |
+ bool hasValue() const { |
+ return hasValue(Enc); |
+ } |
+ static bool hasValue(Encoding E) { |
+ return E <= Encoding_MAX && HasValueArray[E]; |
+ } |
+ |
+ bool isValid() const { return isValid(Enc, Val); } |
+ static bool isValid(Encoding E, uint64_t Val); |
+ static bool isValid(Encoding E) { return isValid(E, 0); } |
+ |
+ bool isLiteral() const { return Enc == Literal; } |
+ |
+ bool isArrayOp() const { return Enc == Array; } |
+ |
+ /// Returns the number of arguments expected by this abbrevation operator. |
+ unsigned NumArguments() const { |
+ if (isArrayOp()) |
+ return 1; |
+ else |
+ return 0; |
+ } |
+ |
+ // Returns the name of the encoding |
+ static const char *getEncodingName(Encoding E) { |
+ if (E > Encoding_MAX) |
+ return "???"; |
+ return EncodingNameArray[E]; |
+ } |
+ |
+ /// Prints out the abbreviation operator to the given stream. |
+ void Print(raw_ostream &Stream) const; |
+ |
+ /// isChar6 - Return true if this character is legal in the Char6 encoding. |
+ static bool isChar6(char C) { |
+ if (C >= 'a' && C <= 'z') return true; |
+ if (C >= 'A' && C <= 'Z') return true; |
+ if (C >= '0' && C <= '9') return true; |
+ if (C == '.' || C == '_') return true; |
+ return false; |
+ } |
+ static unsigned EncodeChar6(char C) { |
+ if (C >= 'a' && C <= 'z') return C-'a'; |
+ if (C >= 'A' && C <= 'Z') return C-'A'+26; |
+ if (C >= '0' && C <= '9') return C-'0'+26+26; |
+ if (C == '.') return 62; |
+ if (C == '_') return 63; |
+ llvm_unreachable("Not a value Char6 character!"); |
+ } |
+ |
+ static char DecodeChar6(unsigned V) { |
+ assert((V & ~63) == 0 && "Not a Char6 encoded character!"); |
+ if (V < 26) return V+'a'; |
+ if (V < 26+26) return V-26+'A'; |
+ if (V < 26+26+10) return V-26-26+'0'; |
+ if (V == 62) return '.'; |
+ if (V == 63) return '_'; |
+ llvm_unreachable("Not a value Char6 character!"); |
+ } |
+ |
+ /// \brief Compares this to Op. Returns <0 if this is less than Op, |
+ /// Returns 0 if they are equal, and >0 if this is greater than Op. |
+ int Compare(const NaClBitCodeAbbrevOp &Op) const { |
+ // Compare encoding values. |
+ int EncodingDiff = static_cast<int>(Enc) - static_cast<int>(Op.Enc); |
+ if (EncodingDiff != 0) return EncodingDiff; |
+ |
+ // Encodings don't differ, so now base on data associated with the |
+ // encoding. |
+ return ValCompare(Op); |
+ } |
+ |
+private: |
+ Encoding Enc; // The encoding to use. |
+ uint64_t Val; // Data associated with encoding (if any). |
+ |
+ int ValCompare(const NaClBitCodeAbbrevOp &Op) const { |
+ if (Val < Op.Val) |
+ return -1; |
+ else if (Val > Op.Val) |
+ return 1; |
+ else |
+ return 0; |
+ } |
+ static const bool HasValueArray[]; |
+ static const char *EncodingNameArray[]; |
+}; |
+ |
+template <> struct isPodLike<NaClBitCodeAbbrevOp> { |
+ static const bool value=true; |
+}; |
+ |
+static inline bool operator<(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) < 0; |
+} |
+ |
+static inline bool operator<=(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) <= 0; |
+} |
+ |
+static inline bool operator==(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) == 0; |
+} |
+ |
+static inline bool operator!=(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) != 0; |
+} |
+ |
+static inline bool operator>=(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) >= 0; |
+} |
+ |
+static inline bool operator>(const NaClBitCodeAbbrevOp &Op1, |
+ const NaClBitCodeAbbrevOp &Op2) { |
+ return Op1.Compare(Op2) > 0; |
+} |
+ |
+/// NaClBitCodeAbbrev - This class represents an abbreviation record. An |
+/// abbreviation allows a complex record that has redundancy to be stored in a |
+/// specialized format instead of the fully-general, fully-vbr, format. |
+class NaClBitCodeAbbrev { |
+ SmallVector<NaClBitCodeAbbrevOp, 8> OperandList; |
+ unsigned char RefCount; // Number of things using this. |
+ ~NaClBitCodeAbbrev() {} |
+public: |
+ NaClBitCodeAbbrev() : RefCount(1) {} |
+ |
+ void addRef() { ++RefCount; } |
+ void dropRef() { if (--RefCount == 0) delete this; } |
+ |
+ unsigned getNumOperandInfos() const { |
+ return static_cast<unsigned>(OperandList.size()); |
+ } |
+ const NaClBitCodeAbbrevOp &getOperandInfo(unsigned N) const { |
+ return OperandList[N]; |
+ } |
+ |
+ void Add(const NaClBitCodeAbbrevOp &OpInfo) { |
+ OperandList.push_back(OpInfo); |
+ } |
+ |
+ // Returns a simplified version of the abbreviation. Used |
+ // to recognize equivalent abbrevations. |
+ NaClBitCodeAbbrev *Simplify() const; |
+ |
+ // Returns true if the abbreviation is valid wrt to the bitcode reader. |
+ bool isValid() const; |
+ |
+ int Compare(const NaClBitCodeAbbrev &Abbrev) const { |
+ // First order based on number of operands. |
+ size_t OperandListSize = OperandList.size(); |
+ size_t AbbrevOperandListSize = Abbrev.OperandList.size(); |
+ if (OperandListSize < AbbrevOperandListSize) |
+ return -1; |
+ else if (OperandListSize > AbbrevOperandListSize) |
+ return 1; |
+ |
+ // Same number of operands, so compare element by element. |
+ for (size_t I = 0; I < OperandListSize; ++I) { |
+ if (int Diff = OperandList[I].Compare(Abbrev.OperandList[I])) |
+ return Diff; |
+ } |
+ return 0; |
+ } |
+ |
+ // Returns true if all records matching the abbreviation must be |
+ // of fixed length. |
+ bool IsFixedSize() const { |
+ unsigned Size = getNumOperandInfos(); |
+ if (Size < 2) return true; |
+ return !OperandList[Size-2].isArrayOp(); |
+ } |
+ |
+ // Returns the smallest record size that will match this |
+ // abbreviation. |
+ size_t GetMinRecordSize() const { |
+ size_t Min = getNumOperandInfos(); |
+ if (!IsFixedSize()) Min -= 2; |
+ return Min; |
+ } |
+ |
+ void Print(raw_ostream &Stream, bool AddNewline=true) const; |
+ |
+ NaClBitCodeAbbrev *Copy() const { |
+ NaClBitCodeAbbrev *AbbrevCopy = new NaClBitCodeAbbrev(); |
+ for (unsigned I = 0, IEnd = getNumOperandInfos(); |
+ I != IEnd; ++I) { |
+ AbbrevCopy->Add(NaClBitCodeAbbrevOp(getOperandInfo(I))); |
+ } |
+ return AbbrevCopy; |
+ } |
+}; |
+ |
+static inline bool operator<(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) < 0; |
+} |
+ |
+static inline bool operator<=(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) <= 0; |
+} |
+static inline bool operator==(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) == 0; |
+} |
+ |
+static inline bool operator!=(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) != 0; |
+} |
+static inline bool operator>=(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) >= 0; |
+} |
+ |
+static inline bool operator>(const NaClBitCodeAbbrev &A1, |
+ const NaClBitCodeAbbrev &A2) { |
+ return A1.Compare(A2) > 0; |
+} |
+ |
+/// \brief Returns number of bits needed to encode |
+/// value for dense FIXED encoding. |
+inline unsigned NaClBitsNeededForValue(unsigned Value) { |
+ // Note: Need to handle case where Value=0xFFFFFFFF as special case, |
+ // since we can't add 1 to it. |
+ if (Value >= 0x80000000) return 32; |
+ return Log2_32_Ceil(Value+1); |
+} |
+ |
+/// \brief Encode a signed value by moving the sign to the LSB for dense |
+/// VBR encoding. |
+inline uint64_t NaClEncodeSignRotatedValue(int64_t V) { |
+ return (V >= 0) ? (V << 1) : ((-V << 1) | 1); |
+} |
+ |
+/// \brief Decode a signed value stored with the sign bit in |
+/// the LSB for dense VBR encoding. |
+inline uint64_t NaClDecodeSignRotatedValue(uint64_t V) { |
+ if ((V & 1) == 0) |
+ return V >> 1; |
+ if (V != 1) |
+ return -(V >> 1); |
+ // There is no such thing as -0 with integers. "-0" really means MININT. |
+ return 1ULL << 63; |
+} |
+ |
+/// \brief This class determines whether a FIXED or VBR |
+/// abbreviation should be used for the selector, and the number of bits |
+/// needed to capture such selectors. |
+class NaClBitcodeSelectorAbbrev { |
+ |
+public: |
+ // If true, use a FIXED abbreviation. Otherwise, use a VBR abbreviation. |
+ bool IsFixed; |
+ // Number of bits needed for selector. |
+ unsigned NumBits; |
+ |
+ // Creates a selector range for the given values. |
+ NaClBitcodeSelectorAbbrev(bool IF, unsigned NB) |
+ : IsFixed(IF), NumBits(NB) {} |
+ |
+ // Creates a selector range when no abbreviations are defined. |
+ NaClBitcodeSelectorAbbrev() |
+ : IsFixed(true), |
+ NumBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) {} |
+ |
+ // Creates a selector range to handle fixed abbrevations up to |
+ // the specified value. |
+ explicit NaClBitcodeSelectorAbbrev(unsigned MaxAbbrev) |
+ : IsFixed(true), |
+ NumBits(NaClBitsNeededForValue(MaxAbbrev)) {} |
+}; |
+} // End llvm namespace |
+ |
+#endif |