| OLD | NEW | 
|---|
| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 100     void EmitJumpTable(const MachineInstr *MI); | 100     void EmitJumpTable(const MachineInstr *MI); | 
| 101     void EmitJump2Table(const MachineInstr *MI); | 101     void EmitJump2Table(const MachineInstr *MI); | 
| 102     virtual void EmitInstruction(const MachineInstr *MI); | 102     virtual void EmitInstruction(const MachineInstr *MI); | 
| 103     bool runOnMachineFunction(MachineFunction &F); | 103     bool runOnMachineFunction(MachineFunction &F); | 
| 104 | 104 | 
| 105     virtual void EmitConstantPool() {} // we emit constant pools customly! | 105     virtual void EmitConstantPool() {} // we emit constant pools customly! | 
| 106     virtual void EmitFunctionEntryLabel(); | 106     virtual void EmitFunctionEntryLabel(); | 
| 107     void EmitStartOfAsmFile(Module &M); | 107     void EmitStartOfAsmFile(Module &M); | 
| 108     void EmitEndOfAsmFile(Module &M); | 108     void EmitEndOfAsmFile(Module &M); | 
| 109 | 109 | 
|  | 110   private: | 
|  | 111     // Two helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() | 
|  | 112     void emitAsmAttributes(Module &M); | 
|  | 113     void emitELFAttributes(Module &M); | 
|  | 114   public: | 
|  | 115 | 
| 110     void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); | 116     void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); | 
| 111 | 117 | 
| 112     MachineLocation getDebugValueLocation(const MachineInstr *MI) const { | 118     MachineLocation getDebugValueLocation(const MachineInstr *MI) const { | 
| 113       MachineLocation Location; | 119       MachineLocation Location; | 
| 114       assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); | 120       assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); | 
| 115       // Frame address.  Currently handles register +- offset only. | 121       // Frame address.  Currently handles register +- offset only. | 
| 116       if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) | 122       if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) | 
| 117         Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); | 123         Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); | 
| 118       else { | 124       else { | 
| 119         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); | 125         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); | 
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 415                                    SectionKind::getText()); | 421                                    SectionKind::getText()); | 
| 416       OutStreamer.SwitchSection(StaticInitSect); | 422       OutStreamer.SwitchSection(StaticInitSect); | 
| 417     } | 423     } | 
| 418   } | 424   } | 
| 419 | 425 | 
| 420   // Use unified assembler syntax. | 426   // Use unified assembler syntax. | 
| 421   OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); | 427   OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); | 
| 422 | 428 | 
| 423   // Emit ARM Build Attributes | 429   // Emit ARM Build Attributes | 
| 424   if (Subtarget->isTargetELF()) { | 430   if (Subtarget->isTargetELF()) { | 
| 425     // CPU Type |  | 
| 426     std::string CPUString = Subtarget->getCPUString(); |  | 
| 427     if (CPUString != "generic") |  | 
| 428       OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString)); |  | 
| 429 | 431 | 
| 430     // FIXME: Emit FPU type | 432     emitAsmAttributes(M); | 
| 431     if (Subtarget->hasVFP2()) |  | 
| 432       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 433                               Twine(ARMBuildAttrs::VFP_arch) + ", 2"); |  | 
| 434 |  | 
| 435     // Signal various FP modes. |  | 
| 436     if (!UnsafeFPMath) { |  | 
| 437       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 438                               Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1"); |  | 
| 439       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 440                               Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1"); |  | 
| 441     } |  | 
| 442 |  | 
| 443     if (NoInfsFPMath && NoNaNsFPMath) |  | 
| 444       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 445                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1"); |  | 
| 446     else |  | 
| 447       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 448                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3"); |  | 
| 449 |  | 
| 450     // 8-bytes alignment stuff. |  | 
| 451     OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 452                             Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1"); |  | 
| 453     OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 454                             Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1"); |  | 
| 455 |  | 
| 456     // Hard float.  Use both S and D registers and conform to AAPCS-VFP. |  | 
| 457     if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { |  | 
| 458       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 459                               Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3"); |  | 
| 460       OutStreamer.EmitRawText("\t.eabi_attribute " + |  | 
| 461                               Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1"); |  | 
| 462     } |  | 
| 463     // FIXME: Should we signal R9 usage? |  | 
| 464   } | 433   } | 
| 465 } | 434 } | 
| 466 | 435 | 
| 467 | 436 | 
| 468 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { | 437 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { | 
| 469   if (Subtarget->isTargetDarwin()) { | 438   if (Subtarget->isTargetDarwin()) { | 
| 470     // All darwin targets use mach-o. | 439     // All darwin targets use mach-o. | 
| 471     const TargetLoweringObjectFileMachO &TLOFMacho = | 440     const TargetLoweringObjectFileMachO &TLOFMacho = | 
| 472       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); | 441       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); | 
| 473     MachineModuleInfoMachO &MMIMacho = | 442     MachineModuleInfoMachO &MMIMacho = | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 526 | 495 | 
| 527     // Funny Darwin hack: This flag tells the linker that no global symbols | 496     // Funny Darwin hack: This flag tells the linker that no global symbols | 
| 528     // contain code that falls through to other global symbols (e.g. the obvious | 497     // contain code that falls through to other global symbols (e.g. the obvious | 
| 529     // implementation of multiple entry points).  If this doesn't occur, the | 498     // implementation of multiple entry points).  If this doesn't occur, the | 
| 530     // linker can safely perform dead code stripping.  Since LLVM never | 499     // linker can safely perform dead code stripping.  Since LLVM never | 
| 531     // generates code that does this, it is always safe to set. | 500     // generates code that does this, it is always safe to set. | 
| 532     OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); | 501     OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); | 
| 533   } | 502   } | 
| 534 } | 503 } | 
| 535 | 504 | 
|  | 505 | 
|  | 506 //===----------------------------------------------------------------------===// | 
|  | 507 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() | 
|  | 508 // FIXME: | 
|  | 509 // The following seem like one-off assembler flags, but they actually need | 
|  | 510 // to appear in the .ARM.attributes section in ELF. This is the reason why | 
|  | 511 // having a common interface to emit these for both the MC/.s and | 
|  | 512 // MC/ELF/obj emission is complicated. | 
|  | 513 // Instead of subclassing the MCELFStreamer, we do the work here. | 
|  | 514 | 
|  | 515 void ARMAsmPrinter::emitAsmAttributes(Module &M) { | 
|  | 516   if (!OutStreamer.hasRawTextSupport()) | 
|  | 517     return; | 
|  | 518 | 
|  | 519   // CPU Type | 
|  | 520   std::string CPUString = Subtarget->getCPUString(); | 
|  | 521   if (CPUString != "generic") | 
|  | 522     OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString)); | 
|  | 523 | 
|  | 524   // FIXME: Emit FPU type | 
|  | 525   if (Subtarget->hasVFP2()) | 
|  | 526     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 527                             Twine(ARMBuildAttrs::VFP_arch) + ", 2"); | 
|  | 528 | 
|  | 529   // Signal various FP modes. | 
|  | 530   if (!UnsafeFPMath) { | 
|  | 531     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 532                             Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1"); | 
|  | 533     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 534                             Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1"); | 
|  | 535   } | 
|  | 536 | 
|  | 537   if (NoInfsFPMath && NoNaNsFPMath) | 
|  | 538     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 539                             Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1"); | 
|  | 540   else | 
|  | 541     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 542                             Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3"); | 
|  | 543 | 
|  | 544   // 8-bytes alignment stuff. | 
|  | 545   OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 546                           Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1"); | 
|  | 547   OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 548                           Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1"); | 
|  | 549 | 
|  | 550   // Hard float.  Use both S and D registers and conform to AAPCS-VFP. | 
|  | 551   if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { | 
|  | 552     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 553                             Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3"); | 
|  | 554     OutStreamer.EmitRawText("\t.eabi_attribute " + | 
|  | 555                             Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1"); | 
|  | 556   } | 
|  | 557   // FIXME: Should we signal R9 usage? | 
|  | 558 } | 
|  | 559 | 
|  | 560 void ARMAsmPrinter::emitELFAttributes(Module &M) { | 
|  | 561   // FIXME: | 
|  | 562 } | 
|  | 563 | 
| 536 //===----------------------------------------------------------------------===// | 564 //===----------------------------------------------------------------------===// | 
| 537 | 565 | 
| 538 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, | 566 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, | 
| 539                              unsigned LabelId, MCContext &Ctx) { | 567                              unsigned LabelId, MCContext &Ctx) { | 
| 540 | 568 | 
| 541   MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) | 569   MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) | 
| 542                        + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); | 570                        + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); | 
| 543   return Label; | 571   return Label; | 
| 544 } | 572 } | 
| 545 | 573 | 
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1228 | 1256 | 
| 1229 // Force static initialization. | 1257 // Force static initialization. | 
| 1230 extern "C" void LLVMInitializeARMAsmPrinter() { | 1258 extern "C" void LLVMInitializeARMAsmPrinter() { | 
| 1231   RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); | 1259   RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); | 
| 1232   RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); | 1260   RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); | 
| 1233 | 1261 | 
| 1234   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); | 1262   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); | 
| 1235   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); | 1263   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); | 
| 1236 } | 1264 } | 
| 1237 | 1265 | 
| OLD | NEW | 
|---|