blob: 5bb01665185d72a3ea52e945cdb671faf83723cd [file] [log] [blame]
Chris Lattner44430192004-01-10 18:56:59 +00001//===-- WriterPrimitives.h - Bytecode writer file format prims --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
10// This header defines some basic functions for writing basic primitive types to
11// a bytecode stream.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef WRITERPRIMITIVES_H
16#define WRITERPRIMITIVES_H
17
18#include "Support/DataTypes.h"
19#include <string>
20#include <deque>
21
22namespace llvm {
23
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...
27//
28static inline void output(unsigned i, std::deque<unsigned char> &Out,
29 int pos = -1) {
Chris Lattner44430192004-01-10 18:56:59 +000030 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));
35 } else {
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);
40 }
Chris Lattner44430192004-01-10 18:56:59 +000041}
42
43static inline void output(int i, std::deque<unsigned char> &Out) {
44 output((unsigned)i, Out);
45}
46
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...
50//
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...
53//
54// Note that using this may cause the output buffer to become unaligned...
55//
56static inline void output_vbr(uint64_t i, std::deque<unsigned char> &out) {
57 while (1) {
58 if (i < 0x80) { // done?
59 out.push_back((unsigned char)i); // We know the high bit is clear...
60 return;
61 }
62
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...
67 }
68}
69
70static inline void output_vbr(unsigned i, std::deque<unsigned char> &out) {
71 while (1) {
72 if (i < 0x80) { // done?
73 out.push_back((unsigned char)i); // We know the high bit is clear...
74 return;
75 }
76
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...
81 }
82}
83
84static inline void output_vbr(int64_t i, std::deque<unsigned char> &out) {
85 if (i < 0)
86 output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit...
87 else
88 output_vbr((uint64_t)i << 1, out); // Low order bit is clear.
89}
90
91
92static inline void output_vbr(int i, std::deque<unsigned char> &out) {
93 if (i < 0)
94 output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit...
95 else
96 output_vbr((unsigned)i << 1, out); // Low order bit is clear.
97}
98
99// align32 - emit the minimal number of bytes that will bring us to 32 bit
100// alignment...
101//
102static 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);
105}
106
107static 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());
112
113 if (Aligned)
114 align32(Out); // Make sure we are now aligned...
115}
116
Chris Lattner44e38032004-01-14 18:41:38 +0000117static inline void output_data(const void *Ptr, const void *End,
Chris Lattner0a3a27b2004-01-14 18:50:28 +0000118 std::deque<unsigned char> &Out) {
Chris Lattner44e38032004-01-14 18:41:38 +0000119 Out.insert(Out.end(), (const unsigned char*)Ptr, (const unsigned char*)End);
Chris Lattner44430192004-01-10 18:56:59 +0000120}
121
122} // End llvm namespace
123
124#endif