Refactored output buffer methods from MachO and ELF writers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33310 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2007-01-17 22:17:24 +00:00
parent 75f9abf517
commit f341ccbff9

View File

@ -0,0 +1,146 @@
//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Bill Wendling and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Methods to output values to a data buffer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
#define LLVM_SUPPORT_OUTPUTBUFFER_H
#include <vector>
namespace llvm {
class OutputBuffer {
/// Output buffer.
std::vector<unsigned char> &Output;
/// is64Bit/isLittleEndian - This information is inferred from the target
/// machine directly, indicating what header values and flags to set.
bool is64Bit, isLittleEndian;
public:
OutputBuffer(const TargetMachine& TM,
std::vector<unsigned char> &Out) : Output(Out) {
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData()->isLittleEndian();
}
// align - Emit padding into the file until the current output position is
// aligned to the specified power of two boundary.
void align(unsigned Boundary) {
assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
"Must alitypedef std::vector<unsigned char> DataBuffer;gn to 2^k boundary");
size_t Size = Output.size();
if (Size & (Boundary - 1)) {
// Add padding to get alignment to the correct place.
size_t Pad = Boundary - (Size & (Boundary - 1));
Output.resize(Size + Pad);
}
}
//===------------------------------------------------------------------===//
// Out Functions - Output the specified value to the data buffer.
void outbyte(unsigned char X) {
Output.push_back(X);
}
void outhalf(unsigned short X) {
if (isLittleEndian) {
Output.push_back(X & 255);
Output.push_back(X >> 8);
} else {
Output.push_back(X >> 8);
Output.push_back(X & 255);
}
}
void outword(unsigned X) {
if (isLittleEndian) {
Output.push_back((X >> 0) & 255);
Output.push_back((X >> 8) & 255);
Output.push_back((X >> 16) & 255);
Output.push_back((X >> 24) & 255);
} else {
Output.push_back((X >> 24) & 255);
Output.push_back((X >> 16) & 255);
Output.push_back((X >> 8) & 255);
Output.push_back((X >> 0) & 255);
}
}
void outxword(uint64_t X) {
if (isLittleEndian) {
Output.push_back(unsigned(X >> 0) & 255);
Output.push_back(unsigned(X >> 8) & 255);
Output.push_back(unsigned(X >> 16) & 255);
Output.push_back(unsigned(X >> 24) & 255);
Output.push_back(unsigned(X >> 32) & 255);
Output.push_back(unsigned(X >> 40) & 255);
Output.push_back(unsigned(X >> 48) & 255);
Output.push_back(unsigned(X >> 56) & 255);
} else {
Output.push_back(unsigned(X >> 56) & 255);
Output.push_back(unsigned(X >> 48) & 255);
Output.push_back(unsigned(X >> 40) & 255);
Output.push_back(unsigned(X >> 32) & 255);
Output.push_back(unsigned(X >> 24) & 255);
Output.push_back(unsigned(X >> 16) & 255);
Output.push_back(unsigned(X >> 8) & 255);
Output.push_back(unsigned(X >> 0) & 255);
}
}
void outaddr32(unsigned X) {
outword(X);
}
void outaddr64(uint64_t X) {
outxword(X);
}
void outaddr(uint64_t X) {
if (!is64Bit)
outword((unsigned)X);
else
outxword(X);
}
void outstring(std::string &S, unsigned Length) {
unsigned len_to_copy = S.length() < Length ? S.length() : Length;
unsigned len_to_fill = S.length() < Length ? Length - S.length() : 0;
for (unsigned i = 0; i < len_to_copy; ++i)
outbyte(S[i]);
for (unsigned i = 0; i < len_to_fill; ++i)
outbyte(0);
}
//===------------------------------------------------------------------===//
// Fix Functions - Replace an existing entry at an offset.
void fixhalf(unsigned short X, unsigned Offset) {
unsigned char *P = &Output[Offset];
P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
}
void fixword(unsigned X, unsigned Offset) {
unsigned char *P = &Output[Offset];
P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
}
void fixaddr(uint64_t X, unsigned Offset) {
if (!is64Bit)
fixword((unsigned)X, Offset);
else
assert(0 && "Emission of 64-bit data not implemented yet!");
}
};
} // end llvm namespace
#endif // LLVM_SUPPORT_OUTPUTBUFFER_H