Expose passinfo from BreakCriticalEdges pass so that it may be "Required" by
[oota-llvm.git] / include / llvm / Bytecode / Primitives.h
1 //===-- llvm/Bytecode/Primitives.h - Bytecode file format prims --*- C++ -*--=//
2 //
3 // This header defines some basic functions for reading and writing basic 
4 // primitive types to a bytecode stream.
5 //
6 // Using the routines defined in this file does not require linking to any 
7 // libraries, as all of the services are small self contained units that are to
8 // be inlined as neccesary.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_BYTECODE_PRIMITIVES_H
13 #define LLVM_BYTECODE_PRIMITIVES_H
14
15 #include "Support/DataTypes.h"
16 #include <string>
17 #include <deque>
18
19 //===----------------------------------------------------------------------===//
20 //                             Reading Primitives
21 //===----------------------------------------------------------------------===//
22
23 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
24                         unsigned &Result) {
25   if (Buf+4 > EndBuf) return true;
26 #ifdef LITTLE_ENDIAN
27   Result = *(unsigned*)Buf;
28 #else
29   Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24);
30 #endif
31   Buf += 4;
32   return false;
33 }
34
35 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
36                         uint64_t &Result) {
37   if (Buf+8 > EndBuf) return true;
38
39 #ifdef LITTLE_ENDIAN
40   Result = *(uint64_t*)Buf;
41 #else
42   Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24) |
43     ((uint64_t)(Buf[4] | (Buf[5] << 8) | (Buf[6] << 16) | (Buf[7] << 24)) <<32);
44 #endif
45   Buf += 8;
46   return false;
47 }
48
49 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
50                         int &Result) {
51   return read(Buf, EndBuf, (unsigned &)Result);
52 }
53
54 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
55                         int64_t &Result) {
56   return read(Buf, EndBuf, (uint64_t &)Result);
57 }
58
59
60 // read_vbr - Read an unsigned integer encoded in variable bitrate format.
61 //
62 static inline bool read_vbr(const unsigned char *&Buf, 
63                             const unsigned char *EndBuf, unsigned &Result) {
64   unsigned Shift = Result = 0;
65
66   do {
67     Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
68     Shift += 7;
69   } while (Buf[-1] & 0x80 && Buf < EndBuf);
70
71   return Buf > EndBuf;
72 }
73
74 static inline bool read_vbr(const unsigned char *&Buf, 
75                             const unsigned char *EndBuf, uint64_t &Result) {
76   unsigned Shift = 0; Result = 0;
77
78   do {
79     Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
80     Shift += 7;
81   } while (Buf[-1] & 0x80 && Buf < EndBuf);
82   return Buf > EndBuf;
83 }
84
85 // read_vbr (signed) - Read a signed number stored in sign-magnitude format
86 static inline bool read_vbr(const unsigned char *&Buf, 
87                             const unsigned char *EndBuf, int &Result) {
88   unsigned R;
89   if (read_vbr(Buf, EndBuf, R)) return true;
90   if (R & 1)
91     Result = -(int)(R >> 1);
92   else
93     Result =  (int)(R >> 1);
94   
95   return false;
96 }
97
98
99 static inline bool read_vbr(const unsigned char *&Buf, 
100                             const unsigned char *EndBuf, int64_t &Result) {
101   uint64_t R;
102   if (read_vbr(Buf, EndBuf, R)) return true;
103   if (R & 1)
104     Result = -(int64_t)(R >> 1);
105   else
106     Result =  (int64_t)(R >> 1);
107   
108   return false;
109 }
110
111 // align32 - Round up to multiple of 32 bits...
112 static inline bool align32(const unsigned char *&Buf, 
113                            const unsigned char *EndBuf) {
114   Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
115   return Buf > EndBuf;
116 }
117
118 static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf, 
119                         std::string &Result, bool Aligned = true) {
120   unsigned Size;
121   if (read_vbr(Buf, EndBuf, Size)) return true;   // Failure reading size?
122   if (Buf+Size > EndBuf) return true;             // Size invalid?
123
124   Result = std::string((char*)Buf, Size);
125   Buf += Size;
126
127   if (Aligned)        // If we should stay aligned do so...
128     if (align32(Buf, EndBuf)) return true;        // Failure aligning?
129
130   return false;
131 }
132
133 static inline bool input_data(const unsigned char *&Buf,
134                               const unsigned char *EndBuf, 
135                               void *Ptr, void *End, bool Align = false) {
136   unsigned char *Start = (unsigned char *)Ptr;
137   unsigned Amount = (unsigned char *)End - Start;
138   if (Buf+Amount > EndBuf) return true;
139 #ifdef LITTLE_ENDIAN
140   std::copy(Buf, Buf+Amount, Start);
141   Buf += Amount;
142 #else
143   unsigned char *E = (unsigned char *)End;
144   while (Ptr != E)
145     *--E = *Buf++;
146 #endif
147
148   if (Align) return align32(Buf, EndBuf);
149   return false;
150 }
151
152 //===----------------------------------------------------------------------===//
153 //                             Writing Primitives
154 //===----------------------------------------------------------------------===//
155
156 // output - If a position is specified, it must be in the valid portion of the
157 // string... note that this should be inlined always so only the relevant IF 
158 // body should be included...
159 //
160 static inline void output(unsigned i, std::deque<unsigned char> &Out,
161                           int pos = -1) {
162 #ifdef LITTLE_ENDIAN
163   if (pos == -1) 
164     Out.insert(Out.end(), (unsigned char*)&i, (unsigned char*)&i+4);
165   else
166     *(unsigned*)&Out[pos] = i;
167 #else
168   if (pos == -1) { // Be endian clean, little endian is our friend
169     Out.push_back((unsigned char)i); 
170     Out.push_back((unsigned char)(i >> 8));
171     Out.push_back((unsigned char)(i >> 16));
172     Out.push_back((unsigned char)(i >> 24));
173   } else {
174     Out[pos  ] = (unsigned char)i;
175     Out[pos+1] = (unsigned char)(i >> 8);
176     Out[pos+2] = (unsigned char)(i >> 16);
177     Out[pos+3] = (unsigned char)(i >> 24);
178   }
179 #endif
180 }
181
182 static inline void output(int i, std::deque<unsigned char> &Out) {
183   output((unsigned)i, Out);
184 }
185
186 // output_vbr - Output an unsigned value, by using the least number of bytes
187 // possible.  This is useful because many of our "infinite" values are really
188 // very small most of the time... but can be large a few times...
189 //
190 // Data format used:  If you read a byte with the night bit set, use the low 
191 // seven bits as data and then read another byte...
192 //
193 // Note that using this may cause the output buffer to become unaligned...
194 //
195 static inline void output_vbr(uint64_t i, std::deque<unsigned char> &out) {
196   while (1) {
197     if (i < 0x80) { // done?
198       out.push_back((unsigned char)i);   // We know the high bit is clear...
199       return;
200     }
201     
202     // Nope, we are bigger than a character, output the next 7 bits and set the
203     // high bit to say that there is more coming...
204     out.push_back(0x80 | (i & 0x7F));
205     i >>= 7;  // Shift out 7 bits now...
206   }
207 }
208
209 static inline void output_vbr(unsigned i, std::deque<unsigned char> &out) {
210   while (1) {
211     if (i < 0x80) { // done?
212       out.push_back((unsigned char)i);   // We know the high bit is clear...
213       return;
214     }
215     
216     // Nope, we are bigger than a character, output the next 7 bits and set the
217     // high bit to say that there is more coming...
218     out.push_back(0x80 | (i & 0x7F));
219     i >>= 7;  // Shift out 7 bits now...
220   }
221 }
222
223 static inline void output_vbr(int64_t i, std::deque<unsigned char> &out) {
224   if (i < 0) 
225     output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit...
226   else
227     output_vbr((uint64_t)i << 1, out);          // Low order bit is clear.
228 }
229
230
231 static inline void output_vbr(int i, std::deque<unsigned char> &out) {
232   if (i < 0) 
233     output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit...
234   else
235     output_vbr((unsigned)i << 1, out);          // Low order bit is clear.
236 }
237
238 // align32 - emit the minimal number of bytes that will bring us to 32 bit 
239 // alignment...
240 //
241 static inline void align32(std::deque<unsigned char> &Out) {
242   int NumPads = (4-(Out.size() & 3)) & 3; // Bytes to get padding to 32 bits
243   while (NumPads--) Out.push_back((unsigned char)0xAB);
244 }
245
246 static inline void output(const std::string &s, std::deque<unsigned char> &Out, 
247                           bool Aligned = true) {
248   unsigned Len = s.length();
249   output_vbr(Len, Out);             // Strings may have an arbitrary length...
250   Out.insert(Out.end(), s.begin(), s.end());
251
252   if (Aligned)
253     align32(Out);                   // Make sure we are now aligned...
254 }
255
256 static inline void output_data(void *Ptr, void *End,
257                                std::deque<unsigned char> &Out,
258                                bool Align = false) {
259 #ifdef LITTLE_ENDIAN
260   Out.insert(Out.end(), (unsigned char*)Ptr, (unsigned char*)End);
261 #else
262   unsigned char *E = (unsigned char *)End;
263   while (Ptr != E)
264     Out.push_back(*--E);
265 #endif
266
267   if (Align) align32(Out);
268 }
269
270 #endif