25#define DEBUG_TYPE "goff-writer"
35 constexpr static uint8_t bits(uint8_t BitIndex, uint8_t
Length, uint8_t
Value,
37 assert(BitIndex < 8 &&
"Bit index out of bounds!");
38 assert(
Length + BitIndex <= 8 &&
"Bit length too long!");
40 uint8_t Mask = ((1 <<
Length) - 1) << (8 - BitIndex -
Length);
44 return (OldValue & ~Mask) |
Value;
48 constexpr Flags() : Val(0) {}
49 constexpr Flags(uint8_t BitIndex, uint8_t
Length, uint8_t
Value)
52 void set(uint8_t BitIndex, uint8_t
Length, uint8_t
Value) {
56 constexpr operator uint8_t()
const {
return Val; }
62constexpr uint8_t RecContinued = Flags(7, 1, 1);
65constexpr uint8_t RecContinuation = Flags(6, 1, 1);
93 bool NewLogicalRecord;
102 size_t bytesToNextPhysicalRecord() {
109 size_t RemainingSize,
110 uint8_t Flags = RecContinuation);
116 void write_impl(
const char *
Ptr,
size_t Size)
override;
124 :
OS(
OS), RemainingSize(0), LogicalRecords(0), NewLogicalRecord(
false) {
136 uint32_t logicalRecords() {
return LogicalRecords; }
139 template <
typename value_type>
void writebe(value_type
Value) {
142 write(
reinterpret_cast<const char *
>(&
Value),
sizeof(value_type));
147 size_t RemainingSize, uint8_t Flags) {
148 uint8_t TypeAndFlags = Flags | (
Type << 4);
150 TypeAndFlags |= RecContinued;
152 <<
static_cast<unsigned char>(TypeAndFlags)
153 <<
static_cast<unsigned char>(0);
159 RemainingSize =
Size;
166 RemainingSize += Gap;
168 NewLogicalRecord =
true;
172void GOFFOstream::fillRecord() {
173 assert((GetNumBytesInBuffer() <= RemainingSize) &&
174 "More bytes in buffer than expected");
175 size_t Remains = RemainingSize - GetNumBytesInBuffer();
177 assert(Remains == Gap &&
"Wrong size of fill gap");
179 "Attempt to fill more than one physical record");
183 assert(RemainingSize == 0 &&
"Not fully flushed");
184 assert(GetNumBytesInBuffer() == 0 &&
"Buffer not fully empty");
195void GOFFOstream::write_impl(
const char *
Ptr,
size_t Size) {
196 assert((RemainingSize >=
Size) &&
"Attempt to write too much data");
197 assert(RemainingSize &&
"Logical record overflow");
199 writeRecordPrefix(
OS, CurrentType, RemainingSize,
200 NewLogicalRecord ? 0 : RecContinuation);
201 NewLogicalRecord =
false;
203 assert(!NewLogicalRecord &&
204 "New logical record not on physical record boundary");
208 size_t BytesToWrite = bytesToNextPhysicalRecord();
209 if (BytesToWrite >
Size)
213 Size -= BytesToWrite;
214 RemainingSize -= BytesToWrite;
216 writeRecordPrefix(
OS, CurrentType, RemainingSize);
222 std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
228 GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
230 : TargetObjectWriter(std::move(MOTW)),
OS(
OS) {}
232 ~GOFFObjectWriter()
override {}
248void GOFFObjectWriter::writeHeader() {
262void GOFFObjectWriter::writeEnd() {
270 OS.writebe<uint8_t>(
Flags(6, 2,
F));
271 OS.writebe<uint8_t>(AMODE);
288 LLVM_DEBUG(
dbgs() <<
"Wrote " <<
OS.logicalRecords() <<
" logical records.");
290 return OS.
tell() - StartOffset;
293std::unique_ptr<MCObjectWriter>
296 return std::make_unique<GOFFObjectWriter>(std::move(MOTW),
OS);
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Encapsulates the layout of an assembly file at a particular point in time.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Defines the object file and target independent interfaces used by the assembler backend to write nati...
virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Write the object file and returns the number of bytes written.
virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
Record a relocation entry.
This represents an "assembler immediate".
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
void SetBuffer(char *BufferStart, size_t Size)
Use the provided buffer as the raw_ostream buffer.
raw_ostream & write(unsigned char C)
An abstract base class for streams implementations that also support a pwrite operation.
constexpr uint8_t RecordContentLength
constexpr uint8_t PTVPrefix
Prefix byte on every record. This indicates GOFF format.
constexpr uint8_t RecordLength
Length of the parts of a physical GOFF record.
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< MCObjectWriter > createGOFFObjectWriter(std::unique_ptr< MCGOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
Construct a new GOFF writer instance.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.