24#define DEBUG_TYPE "goff-writer"
34 constexpr static uint8_t bits(uint8_t BitIndex, uint8_t
Length, uint8_t
Value,
36 assert(BitIndex < 8 &&
"Bit index out of bounds!");
37 assert(
Length + BitIndex <= 8 &&
"Bit length too long!");
39 uint8_t Mask = ((1 <<
Length) - 1) << (8 - BitIndex -
Length);
43 return (OldValue & ~Mask) |
Value;
47 constexpr Flags() : Val(0) {}
48 constexpr Flags(uint8_t BitIndex, uint8_t
Length, uint8_t
Value)
51 void set(uint8_t BitIndex, uint8_t
Length, uint8_t
Value) {
55 constexpr operator uint8_t()
const {
return Val; }
61constexpr uint8_t RecContinued = Flags(7, 1, 1);
64constexpr uint8_t RecContinuation = Flags(6, 1, 1);
92 bool NewLogicalRecord;
101 size_t bytesToNextPhysicalRecord() {
108 size_t RemainingSize,
109 uint8_t Flags = RecContinuation);
115 void write_impl(
const char *
Ptr,
size_t Size)
override;
123 :
OS(
OS), RemainingSize(0), LogicalRecords(0), NewLogicalRecord(
false) {
135 uint32_t logicalRecords() {
return LogicalRecords; }
138 template <
typename value_type>
void writebe(value_type
Value) {
141 write(
reinterpret_cast<const char *
>(&
Value),
sizeof(value_type));
146 size_t RemainingSize, uint8_t Flags) {
147 uint8_t TypeAndFlags = Flags | (
Type << 4);
149 TypeAndFlags |= RecContinued;
151 <<
static_cast<unsigned char>(TypeAndFlags)
152 <<
static_cast<unsigned char>(0);
158 RemainingSize =
Size;
165 RemainingSize += Gap;
167 NewLogicalRecord =
true;
171void GOFFOstream::fillRecord() {
172 assert((GetNumBytesInBuffer() <= RemainingSize) &&
173 "More bytes in buffer than expected");
174 size_t Remains = RemainingSize - GetNumBytesInBuffer();
176 assert(Remains == Gap &&
"Wrong size of fill gap");
178 "Attempt to fill more than one physical record");
182 assert(RemainingSize == 0 &&
"Not fully flushed");
183 assert(GetNumBytesInBuffer() == 0 &&
"Buffer not fully empty");
194void GOFFOstream::write_impl(
const char *
Ptr,
size_t Size) {
195 assert((RemainingSize >=
Size) &&
"Attempt to write too much data");
196 assert(RemainingSize &&
"Logical record overflow");
198 writeRecordPrefix(
OS, CurrentType, RemainingSize,
199 NewLogicalRecord ? 0 : RecContinuation);
200 NewLogicalRecord =
false;
202 assert(!NewLogicalRecord &&
203 "New logical record not on physical record boundary");
207 size_t BytesToWrite = bytesToNextPhysicalRecord();
208 if (BytesToWrite >
Size)
212 Size -= BytesToWrite;
213 RemainingSize -= BytesToWrite;
215 writeRecordPrefix(
OS, CurrentType, RemainingSize);
221 std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
227 GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
229 : TargetObjectWriter(std::move(MOTW)),
OS(
OS) {}
231 ~GOFFObjectWriter()
override {}
245void GOFFObjectWriter::writeHeader() {
259void GOFFObjectWriter::writeEnd() {
267 OS.writebe<uint8_t>(
Flags(6, 2,
F));
268 OS.writebe<uint8_t>(AMODE);
284 LLVM_DEBUG(
dbgs() <<
"Wrote " <<
OS.logicalRecords() <<
" logical records.");
286 return OS.
tell() - StartOffset;
289std::unique_ptr<MCObjectWriter>
292 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())
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)=0
Write the object file and returns the number of bytes written.
virtual void recordRelocation(MCAssembler &Asm, 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.