From: Chris Lattner Date: Sat, 10 Jan 2004 18:56:59 +0000 (+0000) Subject: Refactor writer stuff out of include/llvm/Bytecode/Primitives.h. This is X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4443019b7df16797da58d1cc2fd24a4a3351f8f7;p=oota-llvm.git Refactor writer stuff out of include/llvm/Bytecode/Primitives.h. This is internal implementation details for the writer, not public interfaces! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10738 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Bytecode/Writer/WriterInternals.h b/lib/Bytecode/Writer/WriterInternals.h index 29465157c7c..9fb778df200 100644 --- a/lib/Bytecode/Writer/WriterInternals.h +++ b/lib/Bytecode/Writer/WriterInternals.h @@ -20,8 +20,8 @@ #define LLVM_LIB_BYTECODE_WRITER_WRITERINTERNALS_H #include "llvm/Bytecode/Writer.h" +#include "WriterPrimitives.h" #include "llvm/Bytecode/Format.h" -#include "llvm/Bytecode/Primitives.h" #include "llvm/SlotCalculator.h" #include "llvm/Instruction.h" diff --git a/lib/Bytecode/Writer/WriterPrimitives.h b/lib/Bytecode/Writer/WriterPrimitives.h new file mode 100644 index 00000000000..b782c1829b5 --- /dev/null +++ b/lib/Bytecode/Writer/WriterPrimitives.h @@ -0,0 +1,141 @@ +//===-- WriterPrimitives.h - Bytecode writer file format prims --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines some basic functions for writing basic primitive types to +// a bytecode stream. +// +//===----------------------------------------------------------------------===// + +#ifndef WRITERPRIMITIVES_H +#define WRITERPRIMITIVES_H + +#include "Support/DataTypes.h" +#include +#include + +namespace llvm { + +// output - If a position is specified, it must be in the valid portion of the +// string... note that this should be inlined always so only the relevant IF +// body should be included... +// +static inline void output(unsigned i, std::deque &Out, + int pos = -1) { +#ifdef ENDIAN_LITTLE + if (pos == -1) + Out.insert(Out.end(), (unsigned char*)&i, (unsigned char*)&i+4); + else + // This cannot use block copy because deques are not guaranteed contiguous! + std::copy((unsigned char*)&i, 4+(unsigned char*)&i, Out.begin()+pos); +#else + if (pos == -1) { // Be endian clean, little endian is our friend + Out.push_back((unsigned char)i); + Out.push_back((unsigned char)(i >> 8)); + Out.push_back((unsigned char)(i >> 16)); + Out.push_back((unsigned char)(i >> 24)); + } else { + Out[pos ] = (unsigned char)i; + Out[pos+1] = (unsigned char)(i >> 8); + Out[pos+2] = (unsigned char)(i >> 16); + Out[pos+3] = (unsigned char)(i >> 24); + } +#endif +} + +static inline void output(int i, std::deque &Out) { + output((unsigned)i, Out); +} + +// output_vbr - Output an unsigned value, by using the least number of bytes +// possible. This is useful because many of our "infinite" values are really +// very small most of the time... but can be large a few times... +// +// Data format used: If you read a byte with the night bit set, use the low +// seven bits as data and then read another byte... +// +// Note that using this may cause the output buffer to become unaligned... +// +static inline void output_vbr(uint64_t i, std::deque &out) { + while (1) { + if (i < 0x80) { // done? + out.push_back((unsigned char)i); // We know the high bit is clear... + return; + } + + // Nope, we are bigger than a character, output the next 7 bits and set the + // high bit to say that there is more coming... + out.push_back(0x80 | (i & 0x7F)); + i >>= 7; // Shift out 7 bits now... + } +} + +static inline void output_vbr(unsigned i, std::deque &out) { + while (1) { + if (i < 0x80) { // done? + out.push_back((unsigned char)i); // We know the high bit is clear... + return; + } + + // Nope, we are bigger than a character, output the next 7 bits and set the + // high bit to say that there is more coming... + out.push_back(0x80 | (i & 0x7F)); + i >>= 7; // Shift out 7 bits now... + } +} + +static inline void output_vbr(int64_t i, std::deque &out) { + if (i < 0) + output_vbr(((uint64_t)(-i) << 1) | 1, out); // Set low order sign bit... + else + output_vbr((uint64_t)i << 1, out); // Low order bit is clear. +} + + +static inline void output_vbr(int i, std::deque &out) { + if (i < 0) + output_vbr(((unsigned)(-i) << 1) | 1, out); // Set low order sign bit... + else + output_vbr((unsigned)i << 1, out); // Low order bit is clear. +} + +// align32 - emit the minimal number of bytes that will bring us to 32 bit +// alignment... +// +static inline void align32(std::deque &Out) { + int NumPads = (4-(Out.size() & 3)) & 3; // Bytes to get padding to 32 bits + while (NumPads--) Out.push_back((unsigned char)0xAB); +} + +static inline void output(const std::string &s, std::deque &Out, + bool Aligned = true) { + unsigned Len = s.length(); + output_vbr(Len, Out); // Strings may have an arbitrary length... + Out.insert(Out.end(), s.begin(), s.end()); + + if (Aligned) + align32(Out); // Make sure we are now aligned... +} + +static inline void output_data(void *Ptr, void *End, + std::deque &Out, + bool Align = false) { +#ifdef ENDIAN_LITTLE + Out.insert(Out.end(), (unsigned char*)Ptr, (unsigned char*)End); +#else + unsigned char *E = (unsigned char *)End; + while (Ptr != E) + Out.push_back(*--E); +#endif + + if (Align) align32(Out); +} + +} // End llvm namespace + +#endif