1 //===-- WriterPrimitives.h - Bytecode writer file format prims --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This header defines some basic functions for writing basic primitive types to
13 //===----------------------------------------------------------------------===//
15 #ifndef WRITERPRIMITIVES_H
16 #define WRITERPRIMITIVES_H
18 #include "Support/DataTypes.h"
24 // output - If a position is specified, it must be in the valid portion of the
25 // string... note that this should be inlined always so only the relevant IF
26 // body should be included...
28 static inline void output(unsigned i, std::deque<unsigned char> &Out,
30 if (pos == -1) { // Be endian clean, little endian is our friend
31 Out.push_back((unsigned char)i);
32 Out.push_back((unsigned char)(i >> 8));
33 Out.push_back((unsigned char)(i >> 16));
34 Out.push_back((unsigned char)(i >> 24));
36 Out[pos ] = (unsigned char)i;
37 Out[pos+1] = (unsigned char)(i >> 8);
38 Out[pos+2] = (unsigned char)(i >> 16);
39 Out[pos+3] = (unsigned char)(i >> 24);
43 static inline void output(int i, std::deque<unsigned char> &Out) {
44 output((unsigned)i, Out);
47 // output_vbr - Output an unsigned value, by using the least number of bytes
48 // possible. This is useful because many of our "infinite" values are really
49 // very small most of the time... but can be large a few times...
51 // Data format used: If you read a byte with the night bit set, use the low
52 // seven bits as data and then read another byte...
54 // Note that using this may cause the output buffer to become unaligned...
56 static inline void output_vbr(uint64_t i, std::deque<unsigned char> &out) {
58 if (i < 0x80) { // done?
59 out.push_back((unsigned char)i); // We know the high bit is clear...
63 // Nope, we are bigger than a character, output the next 7 bits and set the
64 // high bit to say that there is more coming...
65 out.push_back(0x80 | (i & 0x7F));
66 i >>= 7; // Shift out 7 bits now...
70 static inline void output_vbr(unsigned i, std::deque<unsigned char> &out) {
72 if (i < 0x80) { // done?
73 out.push_back((unsigned char)i); // We know the high bit is clear...
77 // Nope, we are bigger than a character, output the next 7 bits and set the
78 // high bit to say that there is more coming...
79 out.push_back(0x80 | (i & 0x7F));
80 i >>= 7; // Shift out 7 bits now...
84 static inline void output_vbr(int64_t i, std::deque<unsigned char> &out) {
86 output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit...
88 output_vbr((uint64_t)i << 1, out); // Low order bit is clear.
92 static inline void output_vbr(int i, std::deque<unsigned char> &out) {
94 output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit...
96 output_vbr((unsigned)i << 1, out); // Low order bit is clear.
99 // align32 - emit the minimal number of bytes that will bring us to 32 bit
102 static inline void align32(std::deque<unsigned char> &Out) {
103 int NumPads = (4-(Out.size() & 3)) & 3; // Bytes to get padding to 32 bits
104 while (NumPads--) Out.push_back((unsigned char)0xAB);
107 static inline void output(const std::string &s, std::deque<unsigned char> &Out,
108 bool Aligned = true) {
109 unsigned Len = s.length();
110 output_vbr(Len, Out); // Strings may have an arbitrary length...
111 Out.insert(Out.end(), s.begin(), s.end());
114 align32(Out); // Make sure we are now aligned...
117 static inline void output_data(const void *Ptr, const void *End,
118 std::deque<unsigned char> &Out) {
119 Out.insert(Out.end(), (const unsigned char*)Ptr, (const unsigned char*)End);
122 } // End llvm namespace