Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: lib/Target/ARM/ARMAsmPrinter.cpp

Issue 3770019: updated .ARM.attributes work (Closed) Base URL: https://llvm.org/svn/llvm-project/llvm/trunk/
Patch Set: Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/Target/ARM/ARMAsmBackend.cpp ('k') | lib/Target/ARM/ARMBuildAttrs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file contains a printer that converts from our internal representation 10 // This file contains a printer that converts from our internal representation
(...skipping 20 matching lines...) Expand all
31 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 31 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
32 #include "llvm/CodeGen/MachineFunctionPass.h" 32 #include "llvm/CodeGen/MachineFunctionPass.h"
33 #include "llvm/CodeGen/MachineJumpTableInfo.h" 33 #include "llvm/CodeGen/MachineJumpTableInfo.h"
34 #include "llvm/MC/MCAsmInfo.h" 34 #include "llvm/MC/MCAsmInfo.h"
35 #include "llvm/MC/MCContext.h" 35 #include "llvm/MC/MCContext.h"
36 #include "llvm/MC/MCExpr.h" 36 #include "llvm/MC/MCExpr.h"
37 #include "llvm/MC/MCInst.h" 37 #include "llvm/MC/MCInst.h"
38 #include "llvm/MC/MCSectionMachO.h" 38 #include "llvm/MC/MCSectionMachO.h"
39 #include "llvm/MC/MCStreamer.h" 39 #include "llvm/MC/MCStreamer.h"
40 #include "llvm/MC/MCSymbol.h" 40 #include "llvm/MC/MCSymbol.h"
41 #include "llvm/MC/MCAssembler.h"
41 #include "llvm/Target/Mangler.h" 42 #include "llvm/Target/Mangler.h"
42 #include "llvm/Target/TargetData.h" 43 #include "llvm/Target/TargetData.h"
43 #include "llvm/Target/TargetMachine.h" 44 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Target/TargetOptions.h" 45 #include "llvm/Target/TargetOptions.h"
45 #include "llvm/Target/TargetRegistry.h" 46 #include "llvm/Target/TargetRegistry.h"
46 #include "llvm/ADT/SmallPtrSet.h" 47 #include "llvm/ADT/SmallPtrSet.h"
47 #include "llvm/ADT/SmallString.h" 48 #include "llvm/ADT/SmallString.h"
48 #include "llvm/ADT/StringExtras.h" 49 #include "llvm/ADT/StringExtras.h"
49 #include "llvm/Support/CommandLine.h" 50 #include "llvm/Support/CommandLine.h"
50 #include "llvm/Support/Debug.h" 51 #include "llvm/Support/Debug.h"
52 #include "llvm/Support/ELF.h"
51 #include "llvm/Support/ErrorHandling.h" 53 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/raw_ostream.h" 54 #include "llvm/Support/raw_ostream.h"
53 #include <cctype> 55 #include <cctype>
54 using namespace llvm; 56 using namespace llvm;
55 57
56 namespace llvm { 58 namespace llvm {
57 namespace ARM { 59 namespace ARM {
58 enum DW_ISA { 60 enum DW_ISA {
59 DW_ISA_ARM_thumb = 1, 61 DW_ISA_ARM_thumb = 1,
60 DW_ISA_ARM_arm = 2 62 DW_ISA_ARM_arm = 2
(...skipping 11 matching lines...) Expand all
72 /// AFI - Keep a pointer to ARMFunctionInfo for the current 74 /// AFI - Keep a pointer to ARMFunctionInfo for the current
73 /// MachineFunction. 75 /// MachineFunction.
74 ARMFunctionInfo *AFI; 76 ARMFunctionInfo *AFI;
75 77
76 /// MCP - Keep a pointer to constantpool entries of the current 78 /// MCP - Keep a pointer to constantpool entries of the current
77 /// MachineFunction. 79 /// MachineFunction.
78 const MachineConstantPool *MCP; 80 const MachineConstantPool *MCP;
79 81
80 public: 82 public:
81 explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 83 explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
82 : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) { 84 : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL),
85 headFragment(NULL), currFileFragment(NULL),
86 currSectionFragment(NULL), currSymbolFragment(NULL) {
83 Subtarget = &TM.getSubtarget<ARMSubtarget>(); 87 Subtarget = &TM.getSubtarget<ARMSubtarget>();
84 } 88 }
85 89
86 virtual const char *getPassName() const { 90 virtual const char *getPassName() const {
87 return "ARM Assembly Printer"; 91 return "ARM Assembly Printer";
88 } 92 }
89 93
90 void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, 94 void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
91 const char *Modifier = 0); 95 const char *Modifier = 0);
92 96
93 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 97 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
94 unsigned AsmVariant, const char *ExtraCode, 98 unsigned AsmVariant, const char *ExtraCode,
95 raw_ostream &O); 99 raw_ostream &O);
96 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 100 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
97 unsigned AsmVariant, 101 unsigned AsmVariant,
98 const char *ExtraCode, raw_ostream &O); 102 const char *ExtraCode, raw_ostream &O);
99 103
100 void EmitJumpTable(const MachineInstr *MI); 104 void EmitJumpTable(const MachineInstr *MI);
101 void EmitJump2Table(const MachineInstr *MI); 105 void EmitJump2Table(const MachineInstr *MI);
102 virtual void EmitInstruction(const MachineInstr *MI); 106 virtual void EmitInstruction(const MachineInstr *MI);
103 bool runOnMachineFunction(MachineFunction &F); 107 bool runOnMachineFunction(MachineFunction &F);
104 108
105 virtual void EmitConstantPool() {} // we emit constant pools customly! 109 virtual void EmitConstantPool() {} // we emit constant pools customly!
106 virtual void EmitFunctionEntryLabel(); 110 virtual void EmitFunctionEntryLabel();
107 void EmitStartOfAsmFile(Module &M); 111 void EmitStartOfAsmFile(Module &M);
108 void EmitEndOfAsmFile(Module &M); 112 void EmitEndOfAsmFile(Module &M);
109 113
110 private: 114 private:
115
111 // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() 116 // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
117 // Helper for ELF .s/.o only
112 void emitAttributes(); 118 void emitAttributes();
113 void emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, StringRef v); 119 void emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, StringRef v);
114 void emitAttribute(ARMBuildAttrs::AttrType attr, int v); 120 void emitAttribute(ARMBuildAttrs::AttrType attr, int v);
115 121
116 // Helper for ELF .o only
117 void emitARMAttributeSection(); 122 void emitARMAttributeSection();
118 123
124 // Slots for keeping state for above member funcs.
125 MCDataFragment *headFragment;
126
127 // Fixme: do we ever need more than one of each?
128 MCDataFragment *currFileFragment,
129 *currSectionFragment, *currSymbolFragment;
130
131 // Section-global offset counters
132 int currOffset;
133 int attrDataStartOffset;
134
135 // Helper routine for the emit*() functions above
136 MCDataFragment *addAttrSubsec(MCSectionData *AttrSecData,
137 ARMBuildAttrs::AttrType attr,
138 int SecOrSym=0);
139
140 int fixupAttrSizes();
141 int fixupAttrSize(MCDataFragment *F, int secLenOffset, int lenAdjust);
119 public: 142 public:
120 void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 143 void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
121 144
122 MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 145 MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
123 MachineLocation Location; 146 MachineLocation Location;
124 assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 147 assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
125 // Frame address. Currently handles register +- offset only. 148 // Frame address. Currently handles register +- offset only.
126 if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 149 if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
127 Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 150 Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
128 else { 151 else {
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // 8-bytes alignment stuff. 546 // 8-bytes alignment stuff.
524 emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 547 emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
525 emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 548 emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
526 549
527 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 550 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
528 if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 551 if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
529 emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 552 emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
530 emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 553 emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
531 } 554 }
532 // FIXME: Should we signal R9 usage? 555 // FIXME: Should we signal R9 usage?
556
557 // FIXME: This is just a freebie set by GNU/ARM as for ELF/.o only.
558 // LLVM never emitted this explicitly for .s
559 if (!OutStreamer.hasRawTextSupport()) {
560 emitAttribute(ARMBuildAttrs::DIV_use, 1);
561 }
562
563 (void) fixupAttrSizes();
533 } 564 }
534 565
535 void ARMAsmPrinter::emitARMAttributeSection() { 566 void ARMAsmPrinter::emitARMAttributeSection() {
536 // <format-version> 567 // <format-version>
537 // [ <section-length> "vendor-name" 568 // [ <section-length> "vendor-name"
538 // [ <file-tag> <size> <attribute>* 569 // [ <file-tag> <size> <attribute>*
539 // | <section-tag> <size> <section-number>* 0 <attribute>* 570 // | <section-tag> <size> <section-number>* 0 <attribute>*
540 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 571 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
541 // ]+ 572 // ]+
542 // ]* 573 // ]*
543 574
544 if (OutStreamer.hasRawTextSupport()) 575 if (OutStreamer.hasRawTextSupport())
545 return; 576 return;
546 577
547 const ARMElfTargetObjectFile &TLOFELF = 578 const ARMElfTargetObjectFile &TLOFELF =
548 static_cast<const ARMElfTargetObjectFile &> 579 static_cast<const ARMElfTargetObjectFile &>
549 (getObjFileLowering()); 580 (getObjFileLowering());
550 581
551 OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 582 OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
552 // Fixme: Still more to do here. 583
584 MCObjectStreamer *ELFStreamer = static_cast<MCObjectStreamer*>(&OutStreamer);
585 MCAssembler *Asm = &ELFStreamer->getAssembler();
586
587 bool newSec = false;
588 MCSectionData *AttrSecData =
589 &(Asm->getOrCreateSectionData(*TLOFELF.getAttributesSection(), &newSec));
590
591 headFragment = new MCDataFragment(AttrSecData);
592 SmallString<32> *FC = &headFragment->getContents();
593
594 (*FC) += ((char)ARMBuildAttrs::Format_Version);
595
596 FC->append(sizeof(ELF::Elf32_Word), 0);
597
598 FC->append(ARMBuildAttrs::Vendor_Name,
599 ARMBuildAttrs::Vendor_Name_End);
600
601 currFileFragment =
602 addAttrSubsec(AttrSecData, ARMBuildAttrs::File);
553 } 603 }
554 604
555 void ARMAsmPrinter::emitAttribute(ARMBuildAttrs::AttrType attr, int v) { 605 void ARMAsmPrinter::emitAttribute(ARMBuildAttrs::AttrType attr, int v) {
556 if (OutStreamer.hasRawTextSupport()) { 606 if (OutStreamer.hasRawTextSupport()) {
557 OutStreamer.EmitRawText("\t.eabi_attribute " + 607 OutStreamer.EmitRawText("\t.eabi_attribute " +
558 Twine(attr) + ", " + Twine(v)); 608 Twine(attr) + ", " + Twine(v));
559 609
560 } else { 610 } else {
561 assert(0 && "ELF .ARM.attributes unimplemented"); 611 switch (attr) {
612 // These all go into the File subsection
613 case ARMBuildAttrs::VFP_arch:
614 case ARMBuildAttrs::ABI_FP_denormal:
615 case ARMBuildAttrs::ABI_FP_exceptions:
616 case ARMBuildAttrs::ABI_FP_number_model:
617 case ARMBuildAttrs::ABI_align8_needed:
618 case ARMBuildAttrs::ABI_align8_preserved:
619 case ARMBuildAttrs::ABI_HardFP_use:
620 case ARMBuildAttrs::ABI_VFP_args:
621 case ARMBuildAttrs::DIV_use: {
622 assert(currFileFragment && "No File subsection found");
623 SmallString<32> *FC = &currFileFragment->getContents();
624 (*FC) += static_cast<char>(attr);
625 (*FC) += static_cast<char>(0xFF & v);
626 }; break;
627 default: assert(0 && "Unsupported ARMBuildAttrs::AttrType"); break;
628 }
562 } 629 }
563 } 630 }
564 631
565 void ARMAsmPrinter::emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, 632 void ARMAsmPrinter::emitTextAttribute(ARMBuildAttrs::SpecialAttr attr,
566 StringRef val) { 633 StringRef val) {
567 switch (attr) { 634 switch (attr) {
568 default: assert(0 && "Unimplemented ARMBuildAttrs::SpecialAttr"); break; 635 default: assert(0 && "Unimplemented ARMBuildAttrs::SpecialAttr"); break;
569 case ARMBuildAttrs::SEL_CPU: 636 case ARMBuildAttrs::SEL_CPU:
570 if (OutStreamer.hasRawTextSupport()) { 637 if (OutStreamer.hasRawTextSupport()) {
571 if (val != "generic") { 638 if (val != "generic") {
572 OutStreamer.EmitRawText("\t.cpu " + val); 639 OutStreamer.EmitRawText("\t.cpu " + val);
573 } 640 }
574 } else { 641 } else {
575 // FIXME: ELF 642 // .o
643 if (val == "generic") {
644 assert(currFileFragment && "No File subsection found");
645 SmallString<32> *FC = &currFileFragment->getContents();
646 (*FC) += static_cast<char>(ARMBuildAttrs::CPU_arch);
647 (*FC) += static_cast<char>(ARMBuildAttrs::v4T);
648
649 (*FC) += static_cast<char>(ARMBuildAttrs::ARM_ISA_use);
650 (*FC) += static_cast<char>(1);
651
652 (*FC) += static_cast<char>(ARMBuildAttrs::THUMB_ISA_use);
653 (*FC) += static_cast<char>(1);
654 } else {
655 assert(0 && "unsupported .cpu attribute for ELF/.o");
656 }
576 } 657 }
577 } 658 }
578 } 659 }
579 660
661 MCDataFragment *ARMAsmPrinter::addAttrSubsec(MCSectionData *AttrSecData,
662 ARMBuildAttrs::AttrType attr,
663 int SecOrSym) {
664 MCDataFragment *rtn = new MCDataFragment(AttrSecData);
665 SmallString<32> *FC = &rtn->getContents();
666
667 (*FC) += static_cast<char>(ARMBuildAttrs::File);
668 FC->append(sizeof(ELF::Elf32_Word), 0);
669
670 switch (attr) {
671 case ARMBuildAttrs::File: break;
672 case ARMBuildAttrs::Section:
673 case ARMBuildAttrs::Symbol: {
674 (*FC) += (0xFF & SecOrSym);
675 (*FC) += (0xFF & (SecOrSym >> 8));
676 (*FC) += (0xFF & (SecOrSym >> 16));
677 (*FC) += (0xFF & (SecOrSym >> 24));
678
679 (*FC) += 0;
680 } break;
681 default: assert(0 && "Unknown .ARM.attributes subsection"); break;
682 }
683
684 return rtn;
685 }
686
687 int ARMAsmPrinter::fixupAttrSizes() {
688 int SFileAttr = fixupAttrSize(currFileFragment, 1, 0);
689 int SSecAttr = fixupAttrSize(currSectionFragment, 1, 0);
690 int SSymAttr = fixupAttrSize(currSymbolFragment, 1, 0);
691 int Shead = fixupAttrSize(headFragment, 1,
692 (SFileAttr + SSecAttr + SSymAttr - 1));
693 return Shead;
694 }
695
696 int ARMAsmPrinter::fixupAttrSize(MCDataFragment *F,
697 int secLenOffset, int lenAdjust) {
698 if (F) {
699 SmallString<32> *FC = &F->getContents();
700
701 int S = (int)(FC->size() + lenAdjust);
702 (*FC)[secLenOffset+0] = 0xFF & S;
703 (*FC)[secLenOffset+1] = 0xFF & (S>>8);
704 (*FC)[secLenOffset+2] = 0xFF & (S>>16);
705 (*FC)[secLenOffset+3] = 0xFF & (S>>24);
706 return S + lenAdjust;
707 }
708 return 0;
709 }
710
580 //===----------------------------------------------------------------------===// 711 //===----------------------------------------------------------------------===//
581 712
582 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 713 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
583 unsigned LabelId, MCContext &Ctx) { 714 unsigned LabelId, MCContext &Ctx) {
584 715
585 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 716 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
586 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 717 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
587 return Label; 718 return Label;
588 } 719 }
589 720
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 1403
1273 // Force static initialization. 1404 // Force static initialization.
1274 extern "C" void LLVMInitializeARMAsmPrinter() { 1405 extern "C" void LLVMInitializeARMAsmPrinter() {
1275 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 1406 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1276 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 1407 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1277 1408
1278 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 1409 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
1279 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 1410 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
1280 } 1411 }
1281 1412
OLDNEW
« no previous file with comments | « lib/Target/ARM/ARMAsmBackend.cpp ('k') | lib/Target/ARM/ARMBuildAttrs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698