| 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 |