• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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