39 class MCAsmStreamer final :
public MCStreamer {
40 std::unique_ptr<formatted_raw_ostream> OSOwner;
43 std::unique_ptr<MCInstPrinter> InstPrinter;
44 std::unique_ptr<MCCodeEmitter> Emitter;
45 std::unique_ptr<MCAsmBackend> AsmBackend;
50 unsigned IsVerboseAsm : 1;
51 unsigned ShowInst : 1;
52 unsigned UseDwarfDirectory : 1;
54 void EmitRegisterName(int64_t
Register);
59 MCAsmStreamer(
MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
60 bool isVerboseAsm,
bool useDwarfDirectory,
63 :
MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
64 MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
65 AsmBackend(asmbackend), CommentStream(CommentToEmit),
66 IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
67 UseDwarfDirectory(useDwarfDirectory) {
70 InstPrinter->setCommentStream(CommentStream);
73 inline void EmitEOL() {
81 void EmitCommentsAndEOL();
85 bool isVerboseAsm()
const override {
return IsVerboseAsm; }
88 bool hasRawTextSupport()
const override {
return true; }
94 void AddComment(
const Twine &
T)
override;
105 return CommentStream;
108 void emitRawComment(
const Twine &
T,
bool TabPrefix =
true)
override;
111 void AddBlankLine()
override {
127 unsigned Update)
override;
134 void EmitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue)
override;
136 void EmitCOFFSymbolStorageClass(
int StorageClass)
override;
137 void EmitCOFFSymbolType(
int Type)
override;
138 void EndCOFFSymbolDef()
override;
162 void EmitValueImpl(
const MCExpr *
Value,
unsigned Size,
164 void EmitIntValue(uint64_t Value,
unsigned Size)
override;
166 void EmitULEB128Value(
const MCExpr *Value)
override;
168 void EmitSLEB128Value(
const MCExpr *Value)
override;
170 void EmitGPRel64Value(
const MCExpr *Value)
override;
172 void EmitGPRel32Value(
const MCExpr *Value)
override;
175 void EmitFill(uint64_t NumBytes, uint8_t FillValue)
override;
177 void EmitValueToAlignment(
unsigned ByteAlignment, int64_t Value = 0,
178 unsigned ValueSize = 1,
179 unsigned MaxBytesToEmit = 0)
override;
182 unsigned MaxBytesToEmit = 0)
override;
184 bool EmitValueToOffset(
const MCExpr *Offset,
185 unsigned char Value = 0)
override;
187 void EmitFileDirective(
StringRef Filename)
override;
188 unsigned EmitDwarfFileDirective(
unsigned FileNo,
StringRef Directory,
190 unsigned CUID = 0)
override;
191 void EmitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
192 unsigned Column,
unsigned Flags,
193 unsigned Isa,
unsigned Discriminator,
195 MCSymbol *getDwarfLineTableSymbol(
unsigned CUID)
override;
197 void EmitIdent(
StringRef IdentString)
override;
198 void EmitCFISections(
bool EH,
bool Debug)
override;
199 void EmitCFIDefCfa(int64_t
Register, int64_t Offset)
override;
200 void EmitCFIDefCfaOffset(int64_t Offset)
override;
201 void EmitCFIDefCfaRegister(int64_t
Register)
override;
202 void EmitCFIOffset(int64_t
Register, int64_t Offset)
override;
203 void EmitCFIPersonality(
const MCSymbol *Sym,
unsigned Encoding)
override;
204 void EmitCFILsda(
const MCSymbol *Sym,
unsigned Encoding)
override;
205 void EmitCFIRememberState()
override;
206 void EmitCFIRestoreState()
override;
207 void EmitCFISameValue(int64_t
Register)
override;
208 void EmitCFIRelOffset(int64_t
Register, int64_t Offset)
override;
209 void EmitCFIAdjustCfaOffset(int64_t Adjustment)
override;
210 void EmitCFISignalFrame()
override;
211 void EmitCFIUndefined(int64_t
Register)
override;
212 void EmitCFIRegister(int64_t Register1, int64_t Register2)
override;
213 void EmitCFIWindowSave()
override;
216 void EmitWinCFIEndProc()
override;
217 void EmitWinCFIStartChained()
override;
218 void EmitWinCFIEndChained()
override;
219 void EmitWinCFIPushReg(
unsigned Register)
override;
220 void EmitWinCFISetFrame(
unsigned Register,
unsigned Offset)
override;
221 void EmitWinCFIAllocStack(
unsigned Size)
override;
222 void EmitWinCFISaveReg(
unsigned Register,
unsigned Offset)
override;
223 void EmitWinCFISaveXMM(
unsigned Register,
unsigned Offset)
override;
224 void EmitWinCFIPushFrame(
bool Code)
override;
225 void EmitWinCFIEndProlog()
override;
227 void EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
bool Except)
override;
228 void EmitWinEHHandlerData()
override;
232 void EmitBundleAlignMode(
unsigned AlignPow2)
override;
233 void EmitBundleLock(
bool AlignToEnd)
override;
234 void EmitBundleUnlock()
override;
241 void FinishImpl()
override;
250 void MCAsmStreamer::AddComment(
const Twine &
T) {
251 if (!IsVerboseAsm)
return;
254 CommentStream.flush();
258 CommentToEmit.push_back(
'\n');
261 CommentStream.resync();
264 void MCAsmStreamer::EmitCommentsAndEOL() {
265 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
270 CommentStream.flush();
273 assert(Comments.
back() ==
'\n' &&
274 "Comment array not newline terminated");
277 OS.PadToColumn(MAI->getCommentColumn());
278 size_t Position = Comments.
find(
'\n');
279 OS << MAI->getCommentString() <<
' ' << Comments.
substr(0, Position) <<
'\n';
281 Comments = Comments.
substr(Position+1);
282 }
while (!Comments.
empty());
284 CommentToEmit.clear();
286 CommentStream.resync();
290 assert(Bytes &&
"Invalid size!");
291 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
294 void MCAsmStreamer::emitRawComment(
const Twine &T,
bool TabPrefix) {
297 OS << MAI->getCommentString() <<
T;
302 const MCExpr *Subsection) {
303 assert(Section &&
"Cannot switch to a null section!");
308 assert(Symbol->
isUndefined() &&
"Cannot define a symbol twice!");
311 Symbol->
print(OS, MAI);
312 OS << MAI->getLabelSuffix();
322 assert(NbArgs != -1 && ((
size_t)NbArgs) == Args.
size() &&
"Malformed LOH!");
323 assert(str !=
"" &&
"Invalid LOH name");
333 (*It)->print(OS, MAI);
342 case MCAF_Code16: OS <<
'\t'<< MAI->getCode16Directive();
break;
343 case MCAF_Code32: OS <<
'\t'<< MAI->getCode32Directive();
break;
344 case MCAF_Code64: OS <<
'\t'<< MAI->getCode64Directive();
break;
350 assert(!Options.
empty() &&
"At least one option is required!");
351 OS <<
"\t.linker_option \"" << Options[0] <<
'"';
353 ie = Options.end(); it != ie; ++it) {
354 OS <<
", " <<
'"' << *it <<
'"';
360 if (!MAI->doesSupportDataRegionDirectives())
373 unsigned Minor,
unsigned Update) {
378 OS <<
" " << Major <<
", " << Minor;
380 OS <<
", " << Update;
387 OS <<
"\t.thumb_func";
389 if (MAI->hasSubsectionsViaSymbols()) {
391 Func->
print(OS, MAI);
397 Symbol->
print(OS, MAI);
399 Value->
print(OS, MAI);
406 void MCAsmStreamer::EmitWeakReference(
MCSymbol *Alias,
const MCSymbol *Symbol) {
408 Alias->
print(OS, MAI);
410 Symbol->
print(OS, MAI);
414 bool MCAsmStreamer::EmitSymbolAttribute(
MCSymbol *Symbol,
425 if (!MAI->hasDotTypeDotSizeDirective())
428 Symbol->
print(OS, MAI);
429 OS <<
',' << ((MAI->getCommentString()[0] !=
'@') ?
'@' :
'%');
431 default:
return false;
443 OS << MAI->getGlobalDirective();
451 if (!MAI->hasNoDeadStrip())
453 OS <<
"\t.no_dead_strip\t";
457 OS <<
"\t.private_extern\t";
461 case MCSA_Weak: OS << MAI->getWeakDirective();
break;
463 OS <<
"\t.weak_definition\t";
470 Symbol->
print(OS, MAI);
476 void MCAsmStreamer::EmitSymbolDesc(
MCSymbol *Symbol,
unsigned DescValue) {
477 OS <<
".desc" <<
' ';
478 Symbol->
print(OS, MAI);
479 OS <<
',' << DescValue;
483 void MCAsmStreamer::BeginCOFFSymbolDef(
const MCSymbol *Symbol) {
485 Symbol->
print(OS, MAI);
490 void MCAsmStreamer::EmitCOFFSymbolStorageClass (
int StorageClass) {
491 OS <<
"\t.scl\t" << StorageClass <<
';';
495 void MCAsmStreamer::EmitCOFFSymbolType (
int Type) {
496 OS <<
"\t.type\t" << Type <<
';';
500 void MCAsmStreamer::EndCOFFSymbolDef() {
505 void MCAsmStreamer::EmitCOFFSafeSEH(
MCSymbol const *Symbol) {
506 OS <<
"\t.safeseh\t";
507 Symbol->
print(OS, MAI);
511 void MCAsmStreamer::EmitCOFFSectionIndex(
MCSymbol const *Symbol) {
513 Symbol->
print(OS, MAI);
517 void MCAsmStreamer::EmitCOFFSecRel32(
MCSymbol const *Symbol) {
518 OS <<
"\t.secrel32\t";
519 Symbol->
print(OS, MAI);
524 assert(MAI->hasDotTypeDotSizeDirective());
526 Symbol->
print(OS, MAI);
528 Value->
print(OS, MAI);
532 void MCAsmStreamer::EmitCommonSymbol(
MCSymbol *Symbol, uint64_t Size,
535 AssignSection(Symbol,
nullptr);
538 Symbol->
print(OS, MAI);
541 if (ByteAlignment != 0) {
542 if (MAI->getCOMMDirectiveAlignmentIsInBytes())
543 OS <<
',' << ByteAlignment;
545 OS <<
',' <<
Log2_32(ByteAlignment);
554 void MCAsmStreamer::EmitLocalCommonSymbol(
MCSymbol *Symbol, uint64_t Size,
555 unsigned ByteAlign) {
557 AssignSection(Symbol,
nullptr);
560 Symbol->
print(OS, MAI);
564 switch (MAI->getLCOMMDirectiveAlignmentType()) {
568 OS <<
',' << ByteAlign;
571 assert(
isPowerOf2_32(ByteAlign) &&
"alignment must be a power of 2");
572 OS <<
',' <<
Log2_32(ByteAlign);
580 uint64_t Size,
unsigned ByteAlignment) {
582 AssignSection(Symbol, Section);
593 Symbol->
print(OS, MAI);
595 if (ByteAlignment != 0)
596 OS <<
',' <<
Log2_32(ByteAlignment);
605 uint64_t Size,
unsigned ByteAlignment) {
606 AssignSection(Symbol, Section);
608 assert(Symbol &&
"Symbol shouldn't be NULL!");
612 Symbol->
print(OS, MAI);
617 if (ByteAlignment > 1) OS <<
", " <<
Log2_32(ByteAlignment);
622 static inline char toOctal(
int X) {
return (X&7)+
'0'; }
627 for (
unsigned i = 0, e = Data.
size(); i != e; ++i) {
628 unsigned char C = Data[i];
629 if (C ==
'"' || C ==
'\\') {
630 OS <<
'\\' << (char)C;
634 if (isprint((
unsigned char)C)) {
640 case '\b': OS <<
"\\b";
break;
641 case '\f': OS <<
"\\f";
break;
642 case '\n': OS <<
"\\n";
break;
643 case '\r': OS <<
"\\r";
break;
644 case '\t': OS <<
"\\t";
break;
647 OS << toOctal(C >> 6);
648 OS << toOctal(C >> 3);
649 OS << toOctal(C >> 0);
658 void MCAsmStreamer::EmitBytes(
StringRef Data) {
659 assert(getCurrentSection().first &&
660 "Cannot emit contents before setting section!");
661 if (Data.
empty())
return;
663 if (Data.
size() == 1) {
664 OS << MAI->getData8bitsDirective();
665 OS << (
unsigned)(
unsigned char)Data[0];
672 if (MAI->getAscizDirective() && Data.
back() == 0) {
673 OS << MAI->getAscizDirective();
676 OS << MAI->getAsciiDirective();
683 void MCAsmStreamer::EmitIntValue(uint64_t Value,
unsigned Size) {
687 void MCAsmStreamer::EmitValueImpl(
const MCExpr *Value,
unsigned Size,
689 assert(Size <= 8 &&
"Invalid size");
690 assert(getCurrentSection().first &&
691 "Cannot emit contents before setting section!");
692 const char *Directive =
nullptr;
695 case 1: Directive = MAI->getData8bitsDirective();
break;
696 case 2: Directive = MAI->getData16bitsDirective();
break;
697 case 4: Directive = MAI->getData32bitsDirective();
break;
698 case 8: Directive = MAI->getData64bitsDirective();
break;
703 if (!Value->evaluateAsAbsolute(IntValue))
710 bool IsLittleEndian = MAI->isLittleEndian();
711 for (
unsigned Emitted = 0; Emitted != Size;) {
712 unsigned Remaining = Size - Emitted;
716 if (EmissionSize > 4)
720 unsigned ByteOffset =
721 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
722 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
726 uint64_t Shift = 64 - EmissionSize * 8;
727 assert(Shift < static_cast<uint64_t>(
728 std::numeric_limits<unsigned long long>::digits) &&
729 "undefined behavior");
730 ValueToEmit &= ~0ULL >> Shift;
731 EmitIntValue(ValueToEmit, EmissionSize);
732 Emitted += EmissionSize;
737 assert(Directive &&
"Invalid size for machine code value!");
739 Value->
print(OS, MAI);
743 void MCAsmStreamer::EmitULEB128Value(
const MCExpr *Value) {
745 if (Value->evaluateAsAbsolute(IntValue)) {
746 EmitULEB128IntValue(IntValue);
750 Value->
print(OS, MAI);
754 void MCAsmStreamer::EmitSLEB128Value(
const MCExpr *Value) {
756 if (Value->evaluateAsAbsolute(IntValue)) {
757 EmitSLEB128IntValue(IntValue);
761 Value->
print(OS, MAI);
765 void MCAsmStreamer::EmitGPRel64Value(
const MCExpr *Value) {
766 assert(MAI->getGPRel64Directive() !=
nullptr);
767 OS << MAI->getGPRel64Directive();
768 Value->
print(OS, MAI);
772 void MCAsmStreamer::EmitGPRel32Value(
const MCExpr *Value) {
773 assert(MAI->getGPRel32Directive() !=
nullptr);
774 OS << MAI->getGPRel32Directive();
775 Value->
print(OS, MAI);
782 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
783 if (NumBytes == 0)
return;
785 if (
const char *ZeroDirective = MAI->getZeroDirective()) {
786 OS << ZeroDirective << NumBytes;
788 OS <<
',' << (
int)FillValue;
797 void MCAsmStreamer::EmitValueToAlignment(
unsigned ByteAlignment, int64_t Value,
799 unsigned MaxBytesToEmit) {
819 if (MAI->getAlignmentIsInBytes())
824 if (Value || MaxBytesToEmit) {
829 OS <<
", " << MaxBytesToEmit;
839 case 1: OS <<
".balign";
break;
840 case 2: OS <<
".balignw";
break;
841 case 4: OS <<
".balignl";
break;
848 OS <<
", " << MaxBytesToEmit;
852 void MCAsmStreamer::EmitCodeAlignment(
unsigned ByteAlignment,
853 unsigned MaxBytesToEmit) {
855 EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
859 bool MCAsmStreamer::EmitValueToOffset(
const MCExpr *Offset,
860 unsigned char Value) {
863 Offset->
print(OS, MAI);
870 void MCAsmStreamer::EmitFileDirective(
StringRef Filename) {
871 assert(MAI->hasSingleParameterDotFile());
877 unsigned MCAsmStreamer::EmitDwarfFileDirective(
unsigned FileNo,
885 FileNo = Table.
getFile(Directory, Filename, FileNo);
893 if (!UseDwarfDirectory && !Directory.
empty()) {
897 FullPathName = Directory;
900 Filename = FullPathName;
904 OS <<
"\t.file\t" << FileNo <<
' ';
905 if (!Directory.
empty()) {
915 void MCAsmStreamer::EmitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
916 unsigned Column,
unsigned Flags,
918 unsigned Discriminator,
920 OS <<
"\t.loc\t" << FileNo <<
" " << Line <<
" " << Column;
922 OS <<
" basic_block";
924 OS <<
" prologue_end";
926 OS <<
" epilogue_begin";
928 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
932 if (Flags & DWARF2_FLAG_IS_STMT)
939 OS <<
" isa " << Isa;
941 OS <<
" discriminator " << Discriminator;
944 OS.PadToColumn(MAI->getCommentColumn());
945 OS << MAI->getCommentString() <<
' ' << FileName <<
':'
946 << Line <<
':' << Column;
950 Isa, Discriminator, FileName);
953 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(
unsigned CUID) {
959 void MCAsmStreamer::EmitIdent(
StringRef IdentString) {
960 assert(MAI->hasIdentDirective() &&
".ident directive not supported");
966 void MCAsmStreamer::EmitCFISections(
bool EH,
bool Debug) {
968 OS <<
"\t.cfi_sections ";
972 OS <<
", .debug_frame";
974 OS <<
".debug_frame";
981 OS <<
"\t.cfi_startproc";
989 OS <<
"\t.cfi_endproc";
993 void MCAsmStreamer::EmitRegisterName(int64_t
Register) {
994 if (!MAI->useDwarfRegNumForCFI()) {
997 InstPrinter->printRegName(OS, LLVMRegister);
1003 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
1005 OS <<
"\t.cfi_def_cfa ";
1006 EmitRegisterName(Register);
1007 OS <<
", " << Offset;
1011 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
1013 OS <<
"\t.cfi_def_cfa_offset " << Offset;
1017 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
1019 OS <<
"\t.cfi_def_cfa_register ";
1020 EmitRegisterName(Register);
1024 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
1026 OS <<
"\t.cfi_offset ";
1027 EmitRegisterName(Register);
1028 OS <<
", " << Offset;
1032 void MCAsmStreamer::EmitCFIPersonality(
const MCSymbol *Sym,
1033 unsigned Encoding) {
1035 OS <<
"\t.cfi_personality " << Encoding <<
", ";
1036 Sym->
print(OS, MAI);
1040 void MCAsmStreamer::EmitCFILsda(
const MCSymbol *Sym,
unsigned Encoding) {
1042 OS <<
"\t.cfi_lsda " << Encoding <<
", ";
1043 Sym->
print(OS, MAI);
1047 void MCAsmStreamer::EmitCFIRememberState() {
1049 OS <<
"\t.cfi_remember_state";
1053 void MCAsmStreamer::EmitCFIRestoreState() {
1055 OS <<
"\t.cfi_restore_state";
1059 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1061 OS <<
"\t.cfi_same_value ";
1062 EmitRegisterName(Register);
1066 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1068 OS <<
"\t.cfi_rel_offset ";
1069 EmitRegisterName(Register);
1070 OS <<
", " << Offset;
1074 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1076 OS <<
"\t.cfi_adjust_cfa_offset " << Adjustment;
1080 void MCAsmStreamer::EmitCFISignalFrame() {
1082 OS <<
"\t.cfi_signal_frame";
1086 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1088 OS <<
"\t.cfi_undefined " <<
Register;
1092 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1094 OS <<
"\t.cfi_register " << Register1 <<
", " << Register2;
1098 void MCAsmStreamer::EmitCFIWindowSave() {
1100 OS <<
"\t.cfi_window_save";
1104 void MCAsmStreamer::EmitWinCFIStartProc(
const MCSymbol *Symbol) {
1108 Symbol->
print(OS, MAI);
1112 void MCAsmStreamer::EmitWinCFIEndProc() {
1115 OS <<
"\t.seh_endproc";
1119 void MCAsmStreamer::EmitWinCFIStartChained() {
1122 OS <<
"\t.seh_startchained";
1126 void MCAsmStreamer::EmitWinCFIEndChained() {
1129 OS <<
"\t.seh_endchained";
1133 void MCAsmStreamer::EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
1137 OS <<
"\t.seh_handler ";
1138 Sym->
print(OS, MAI);
1146 void MCAsmStreamer::EmitWinEHHandlerData() {
1156 SwitchSectionNoChange(XData);
1158 OS <<
"\t.seh_handlerdata";
1162 void MCAsmStreamer::EmitWinCFIPushReg(
unsigned Register) {
1165 OS <<
"\t.seh_pushreg " <<
Register;
1169 void MCAsmStreamer::EmitWinCFISetFrame(
unsigned Register,
unsigned Offset) {
1172 OS <<
"\t.seh_setframe " << Register <<
", " << Offset;
1176 void MCAsmStreamer::EmitWinCFIAllocStack(
unsigned Size) {
1179 OS <<
"\t.seh_stackalloc " << Size;
1183 void MCAsmStreamer::EmitWinCFISaveReg(
unsigned Register,
unsigned Offset) {
1186 OS <<
"\t.seh_savereg " << Register <<
", " << Offset;
1190 void MCAsmStreamer::EmitWinCFISaveXMM(
unsigned Register,
unsigned Offset) {
1193 OS <<
"\t.seh_savexmm " << Register <<
", " << Offset;
1197 void MCAsmStreamer::EmitWinCFIPushFrame(
bool Code) {
1200 OS <<
"\t.seh_pushframe";
1206 void MCAsmStreamer::EmitWinCFIEndProlog(
void) {
1209 OS <<
"\t.seh_endprologue";
1213 void MCAsmStreamer::AddEncodingComment(
const MCInst &Inst,
1219 Emitter->encodeInstruction(Inst, VecOS, Fixups, STI);
1227 for (
unsigned i = 0, e = Code.
size() * 8; i != e; ++i)
1230 for (
unsigned i = 0, e = Fixups.
size(); i != e; ++i) {
1233 for (
unsigned j = 0; j != Info.
TargetSize; ++j) {
1235 assert(Index < Code.
size() * 8 &&
"Invalid offset in fixup!");
1236 FixupMap[Index] = 1 + i;
1242 OS <<
"encoding: [";
1243 for (
unsigned i = 0, e = Code.
size(); i != e; ++i) {
1248 uint8_t MapEntry = FixupMap[i * 8 + 0];
1249 for (
unsigned j = 1; j != 8; ++j) {
1250 if (FixupMap[i * 8 + j] == MapEntry)
1253 MapEntry = uint8_t(~0U);
1257 if (MapEntry != uint8_t(~0U)) {
1258 if (MapEntry == 0) {
1259 OS <<
format(
"0x%02x", uint8_t(Code[i]));
1263 OS <<
format(
"0x%02x", uint8_t(Code[i])) <<
'\''
1264 << char(
'A' + MapEntry - 1) <<
'\'';
1266 OS << char(
'A' + MapEntry - 1);
1271 for (
unsigned j = 8; j--;) {
1272 unsigned Bit = (Code[i] >> j) & 1;
1275 if (MAI->isLittleEndian())
1276 FixupBit = i * 8 + j;
1278 FixupBit = i * 8 + (7-j);
1280 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1281 assert(Bit == 0 &&
"Encoder wrote into fixed up bit!");
1282 OS << char(
'A' + MapEntry - 1);
1290 for (
unsigned i = 0, e = Fixups.
size(); i != e; ++i) {
1293 OS <<
" fixup " << char(
'A' + i) <<
" - " <<
"offset: " << F.
getOffset()
1294 <<
", value: " << *F.
getValue() <<
", kind: " << Info.
Name <<
"\n";
1299 assert(getCurrentSection().first &&
1300 "Cannot emit contents before setting section!");
1304 AddEncodingComment(Inst, STI);
1308 Inst.
dump_pretty(GetCommentOS(), InstPrinter.get(),
"\n ");
1309 GetCommentOS() <<
"\n";
1312 if(getTargetStreamer())
1313 getTargetStreamer()->prettyPrintAsm(*InstPrinter, OS, Inst, STI);
1315 InstPrinter->printInst(&Inst, OS,
"", STI);
1320 void MCAsmStreamer::EmitBundleAlignMode(
unsigned AlignPow2) {
1321 OS <<
"\t.bundle_align_mode " << AlignPow2;
1325 void MCAsmStreamer::EmitBundleLock(
bool AlignToEnd) {
1326 OS <<
"\t.bundle_lock";
1328 OS <<
" align_to_end";
1332 void MCAsmStreamer::EmitBundleUnlock() {
1333 OS <<
"\t.bundle_unlock";
1341 if (!String.
empty() && String.
back() ==
'\n')
1347 void MCAsmStreamer::FinishImpl() {
1349 if (getContext().getGenDwarfForAssembly())
1355 auto &Tables = getContext().getMCDwarfLineTables();
1356 if (!Tables.empty()) {
1357 assert(Tables.size() == 1 &&
"asm output only supports one line table");
1358 if (
auto *Label = Tables.begin()->second.getLabel()) {
1359 SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
1366 std::unique_ptr<formatted_raw_ostream> OS,
1367 bool isVerboseAsm,
bool useDwarfDirectory,
1370 return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
1371 useDwarfDirectory, IP, CE, MAB, ShowInst);
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName)
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
virtual void EmitCFISameValue(int64_t Register)
virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
MCSectionMachO - This represents a section on a Mach-O system (used by Mac OS X). ...
#define DWARF2_FLAG_PROLOGUE_END
virtual void EmitWinCFIEndProlog()
size_t size() const
size - Get the string size.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
.type _foo, STT_OBJECT # aka
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
A raw_ostream that writes to an SmallVector or SmallString.
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2)
virtual void EmitCFIDefCfaOffset(int64_t Offset)
.type _foo, STT_NOTYPE # aka
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
COFF::SymbolStorageClass StorageClass
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
unsigned TargetOffset
The bit offset to write the relocation into.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
virtual void EmitCFISections(bool EH, bool Debug)
static int64_t truncateToSize(int64_t Value, unsigned Bytes)
virtual void EmitWinEHHandlerData()
virtual void EmitCFIRememberState()
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding)
#define DWARF2_FLAG_IS_STMT
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
const char * Name
A target specific name for the fixup kind.
bool is_absolute(const Twine &path)
Is path absolute?
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
Context object for machine code objects.
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
.code16 (X86) / .code 16 (ARM)
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
StringRef getSectionName() const
.type _foo, STT_GNU_IFUNC
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
virtual void EmitCFIRestoreState()
uint32_t getOffset() const
Instances of this class represent a single low-level machine instruction.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
Streaming machine code generation interface.
const MCExpr * getValue() const
.weak_def_can_be_hidden (MachO)
The instances of the Type class are immutable: once they are created, they are never changed...
static char toOctal(int X)
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
#define DWARF2_FLAG_EPILOGUE_BEGIN
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst)
Create a machine code streamer which will print out assembly for the native target, suitable for compiling with a native assembler.
virtual void EmitWinCFIPushReg(unsigned Register)
char back() const
back - Get the last character in the string.
MCCodeEmitter - Generic instruction encoding interface.
virtual void EmitCFIDefCfaRegister(int64_t Register)
MCLOHType
Linker Optimization Hint Type.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
.subsections_via_symbols (MachO)
#define DWARF2_FLAG_BASIC_BLOCK
virtual void EmitWinCFIEndChained()
virtual void EmitWinCFIEndProc()
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const =0
virtual void EmitCFIUndefined(int64_t Register)
bool empty() const
empty - Check if the array is empty.
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except)
virtual void EmitWinCFIStartChained()
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset)
virtual void EmitCFIOffset(int64_t Register, int64_t Offset)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
.type _foo, STT_TLS # aka
Promote Memory to Register
unsigned TargetSize
The number of bits written by this fixup.
virtual void EmitWinCFIAllocStack(unsigned Size)
static StringRef MCLOHDirectiveName()
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
const MCSymbol * Function
static void Emit(MCStreamer *MCOS)
StringRef getSegmentName() const
.code32 (X86) / .code 32 (ARM)
.type _foo, STT_COMMON # aka
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void EmitCFISignalFrame()
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset)
.type _foo, STT_FUNC # aka
MCSubtargetInfo - Generic base class for all target subtargets.
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset)
static MCSection * getXDataSection(const MCSymbol *Function, MCContext &Context)
Target independent information on a fixup kind.
const ARM::ArchExtKind Kind
static int MCLOHIdToNbArgs(MCLOHType Kind)
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
LLVM Value Representation.
Generic interface to target specific assembler backends.
static cl::opt< bool, true > Debug("debug", cl::desc("Enable debug output"), cl::Hidden, cl::location(DebugFlag))
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol)
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
static StringRef MCLOHIdToName(MCLOHType Kind)
This class implements an extremely fast bulk output stream that can only output to a stream...
virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset)
virtual void EmitWinCFIPushFrame(bool Code)
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
StringRef - Represent a constant reference to a string, i.e.
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
static void PrintQuotedString(StringRef Data, raw_ostream &OS)
Represents a location in source code.
unsigned getFile(StringRef &Directory, StringRef &FileName, unsigned FileNumber=0)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment)
virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset)
virtual void EmitCFIWindowSave()
bool empty() const
empty - Check if the string is empty.