diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 182 |
1 files changed, 114 insertions, 68 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 00e321f9b8509..3a94820dac8d3 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -84,8 +84,8 @@ public: return MCInstLowering.lowerOperand(MO, MCOp); } - void EmitStartOfAsmFile(Module &M) override; - void EmitJumpTableInfo() override; + void emitStartOfAsmFile(Module &M) override; + void emitJumpTableInfo() override; void emitJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned JTI); @@ -112,7 +112,9 @@ public: bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, const MachineInstr *MI); - void EmitInstruction(const MachineInstr *MI) override; + void emitInstruction(const MachineInstr *MI) override; + + void emitFunctionHeaderComment() override; void getAnalysisUsage(AnalysisUsage &AU) const override { AsmPrinter::getAnalysisUsage(AU); @@ -139,7 +141,7 @@ public: } // Emit the rest of the function body. - EmitFunctionBody(); + emitFunctionBody(); // Emit the XRay table for this function. emitXRayTable(); @@ -162,10 +164,10 @@ private: void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); - void EmitFunctionBodyEnd() override; + void emitFunctionBodyEnd() override; MCSymbol *GetCPISymbol(unsigned CPID) const override; - void EmitEndOfAsmFile(Module &M) override; + void emitEndOfAsmFile(Module &M) override; AArch64FunctionInfo *AArch64FI = nullptr; @@ -182,7 +184,7 @@ private: } // end anonymous namespace -void AArch64AsmPrinter::EmitStartOfAsmFile(Module &M) { +void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { if (!TM.getTargetTriple().isOSBinFormatELF()) return; @@ -225,22 +227,29 @@ void AArch64AsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer->SwitchSection(Nt); // Emit the note header. - EmitAlignment(Align(8)); - OutStreamer->EmitIntValue(4, 4); // data size for "GNU\0" - OutStreamer->EmitIntValue(4 * 4, 4); // Elf_Prop size - OutStreamer->EmitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); - OutStreamer->EmitBytes(StringRef("GNU", 4)); // note name + emitAlignment(Align(8)); + OutStreamer->emitInt32(4); // data size for "GNU\0" + OutStreamer->emitInt32(4 * 4); // Elf_Prop size + OutStreamer->emitInt32(ELF::NT_GNU_PROPERTY_TYPE_0); + OutStreamer->emitBytes(StringRef("GNU", 4)); // note name // Emit the PAC/BTI properties. - OutStreamer->EmitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4); - OutStreamer->EmitIntValue(4, 4); // data size - OutStreamer->EmitIntValue(Flags, 4); // data - OutStreamer->EmitIntValue(0, 4); // pad + OutStreamer->emitInt32(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND); + OutStreamer->emitInt32(4); // data size + OutStreamer->emitInt32(Flags); // data + OutStreamer->emitInt32(0); // pad OutStreamer->endSection(Nt); OutStreamer->SwitchSection(Cur); } +void AArch64AsmPrinter::emitFunctionHeaderComment() { + const AArch64FunctionInfo *FI = MF->getInfo<AArch64FunctionInfo>(); + Optional<std::string> OutlinerString = FI->getOutliningStyle(); + if (OutlinerString != None) + OutStreamer->GetCommentOS() << ' ' << OutlinerString; +} + void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) { const Function &F = MF->getFunction(); @@ -250,8 +259,7 @@ void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) .getValueAsString() .getAsInteger(10, Num)) return; - for (; Num; --Num) - EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0)); + emitNops(Num); return; } @@ -291,9 +299,9 @@ void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) // ;DATA: higher 32 bits of the address of the trampoline // LDP X0, X30, [SP], #16 ; pop X0 and the link register from the stack // - OutStreamer->EmitCodeAlignment(4); + OutStreamer->emitCodeAlignment(4); auto CurSled = OutContext.createTempSymbol("xray_sled_", true); - OutStreamer->EmitLabel(CurSled); + OutStreamer->emitLabel(CurSled); auto Target = OutContext.createTempSymbol(); // Emit "B #32" instruction, which jumps over the next 28 bytes. @@ -304,8 +312,8 @@ void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) for (int8_t I = 0; I < NoopsInSledCount; I++) EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0)); - OutStreamer->EmitLabel(Target); - recordSled(CurSled, MI, Kind); + OutStreamer->emitLabel(Target); + recordSled(CurSled, MI, Kind, 2); } void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) { @@ -364,25 +372,25 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, Sym->getName())); - OutStreamer->EmitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); - OutStreamer->EmitSymbolAttribute(Sym, MCSA_Weak); - OutStreamer->EmitSymbolAttribute(Sym, MCSA_Hidden); - OutStreamer->EmitLabel(Sym); + OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); + OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak); + OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden); + OutStreamer->emitLabel(Sym); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::UBFMXri) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::UBFMXri) .addReg(AArch64::X16) .addReg(Reg) .addImm(4) .addImm(55), *STI); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::LDRBBroX) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDRBBroX) .addReg(AArch64::W16) .addReg(AArch64::X9) .addReg(AArch64::X16) .addImm(0) .addImm(0), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::SUBSXrs) .addReg(AArch64::XZR) .addReg(AArch64::X16) @@ -390,33 +398,33 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSR, 56)), *STI); MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol(); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::Bcc) .addImm(AArch64CC::NE) .addExpr(MCSymbolRefExpr::create(HandleMismatchOrPartialSym, OutContext)), *STI); MCSymbol *ReturnSym = OutContext.createTempSymbol(); - OutStreamer->EmitLabel(ReturnSym); - OutStreamer->EmitInstruction( + OutStreamer->emitLabel(ReturnSym); + OutStreamer->emitInstruction( MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI); - OutStreamer->EmitLabel(HandleMismatchOrPartialSym); + OutStreamer->emitLabel(HandleMismatchOrPartialSym); if (IsShort) { - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::SUBSWri) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSWri) .addReg(AArch64::WZR) .addReg(AArch64::W16) .addImm(15) .addImm(0), *STI); MCSymbol *HandleMismatchSym = OutContext.createTempSymbol(); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::Bcc) .addImm(AArch64CC::HI) .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::ANDXri) .addReg(AArch64::X17) .addReg(Reg) @@ -424,59 +432,59 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { *STI); unsigned Size = 1 << (AccessInfo & 0xf); if (Size != 1) - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::ADDXri) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::ADDXri) .addReg(AArch64::X17) .addReg(AArch64::X17) .addImm(Size - 1) .addImm(0), *STI); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::SUBSWrs) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSWrs) .addReg(AArch64::WZR) .addReg(AArch64::W16) .addReg(AArch64::W17) .addImm(0), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::Bcc) .addImm(AArch64CC::LS) .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::ORRXri) .addReg(AArch64::X16) .addReg(Reg) .addImm(AArch64_AM::encodeLogicalImmediate(0xf, 64)), *STI); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::LDRBBui) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDRBBui) .addReg(AArch64::W16) .addReg(AArch64::X16) .addImm(0), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::SUBSXrs) .addReg(AArch64::XZR) .addReg(AArch64::X16) .addReg(Reg) .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSR, 56)), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::Bcc) .addImm(AArch64CC::EQ) .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)), *STI); - OutStreamer->EmitLabel(HandleMismatchSym); + OutStreamer->emitLabel(HandleMismatchSym); } - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::STPXpre) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre) .addReg(AArch64::SP) .addReg(AArch64::X0) .addReg(AArch64::X1) .addReg(AArch64::SP) .addImm(-32), *STI); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::STPXi) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXi) .addReg(AArch64::FP) .addReg(AArch64::LR) .addReg(AArch64::SP) @@ -484,13 +492,13 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { *STI); if (Reg != AArch64::X0) - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::ORRXrs) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::ORRXrs) .addReg(AArch64::X0) .addReg(AArch64::XZR) .addReg(Reg) .addImm(0), *STI); - OutStreamer->EmitInstruction(MCInstBuilder(AArch64::MOVZXi) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::MOVZXi) .addReg(AArch64::X1) .addImm(AccessInfo) .addImm(0), @@ -499,14 +507,14 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { // Intentionally load the GOT entry and branch to it, rather than possibly // late binding the function, which may clobber the registers before we have // a chance to save them. - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::ADRP) .addReg(AArch64::X16) .addExpr(AArch64MCExpr::create( HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE, OutContext)), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::LDRXui) .addReg(AArch64::X16) .addReg(AArch64::X16) @@ -514,12 +522,12 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) { HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12, OutContext)), *STI); - OutStreamer->EmitInstruction( + OutStreamer->emitInstruction( MCInstBuilder(AArch64::BR).addReg(AArch64::X16), *STI); } } -void AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) { +void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { EmitHwasanMemaccessSymbols(M); const Triple &TT = TM.getTargetTriple(); @@ -529,7 +537,7 @@ void AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) { // implementation of multiple entry points). If this doesn't occur, the // linker can safely perform dead code stripping. Since LLVM never // generates code that does this, it is always safe to set. - OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); + OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); } emitStackMaps(SM); } @@ -544,12 +552,12 @@ void AArch64AsmPrinter::EmitLOHs() { "Label hasn't been inserted for LOH related instruction"); MCArgs.push_back(LabelIt->second); } - OutStreamer->EmitLOHDirective(D.getKind(), MCArgs); + OutStreamer->emitLOHDirective(D.getKind(), MCArgs); MCArgs.clear(); } } -void AArch64AsmPrinter::EmitFunctionBodyEnd() { +void AArch64AsmPrinter::emitFunctionBodyEnd() { if (!AArch64FI->getLOHRelated().empty()) EmitLOHs(); } @@ -741,11 +749,10 @@ void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI, assert(NOps == 4); OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; // cast away const; DIetc do not take const operands for some reason. - OS << cast<DILocalVariable>(MI->getOperand(NOps - 2).getMetadata()) - ->getName(); + OS << MI->getDebugVariable()->getName(); OS << " <- "; // Frame address. Currently handles register +- offset only. - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); + assert(MI->getDebugOperand(0).isReg() && MI->isDebugOffsetImm()); OS << '['; printOperand(MI, 0, OS); OS << '+'; @@ -755,7 +762,7 @@ void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI, printOperand(MI, NOps - 2, OS); } -void AArch64AsmPrinter::EmitJumpTableInfo() { +void AArch64AsmPrinter::emitJumpTableInfo() { const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); if (!MJTI) return; @@ -783,8 +790,8 @@ void AArch64AsmPrinter::EmitJumpTableInfo() { if (JTBBs.empty()) continue; unsigned Size = AFI->getJumpTableEntrySize(JTI); - EmitAlignment(Align(Size)); - OutStreamer->EmitLabel(GetJTISymbol(JTI)); + emitAlignment(Align(Size)); + OutStreamer->emitLabel(GetJTISymbol(JTI)); for (auto *JTBB : JTBBs) emitJumpTableEntry(MJTI, JTBB, JTI); @@ -812,7 +819,7 @@ void AArch64AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI, Value, MCConstantExpr::create(2, OutContext), OutContext); } - OutStreamer->EmitValue(Value, Size); + OutStreamer->emitValue(Value, Size); } /// Small jump tables contain an unsigned byte or half, representing the offset @@ -868,7 +875,7 @@ void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM, auto &Ctx = OutStreamer.getContext(); MCSymbol *MILabel = Ctx.createTempSymbol(); - OutStreamer.EmitLabel(MILabel); + OutStreamer.emitLabel(MILabel); SM.recordStackMap(*MILabel, MI); assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); @@ -898,7 +905,7 @@ void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, const MachineInstr &MI) { auto &Ctx = OutStreamer.getContext(); MCSymbol *MILabel = Ctx.createTempSymbol(); - OutStreamer.EmitLabel(MILabel); + OutStreamer.emitLabel(MILabel); SM.recordPatchPoint(*MILabel, MI); PatchPointOpers Opers(&MI); @@ -982,7 +989,7 @@ void AArch64AsmPrinter::EmitFMov0(const MachineInstr &MI) { // instructions) auto-generated. #include "AArch64GenMCPseudoLowering.inc" -void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { +void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { // Do any auto-generated pseudo lowerings. if (emitPseudoExpansionLowering(*OutStreamer, MI)) return; @@ -992,7 +999,7 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { MCSymbol *LOHLabel = createTempSymbol("loh"); // Associate the instruction with the label LOHInstToLabel[MI] = LOHLabel; - OutStreamer->EmitLabel(LOHLabel); + OutStreamer->emitLabel(LOHLabel); } AArch64TargetStreamer *TS = @@ -1001,6 +1008,26 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { switch (MI->getOpcode()) { default: break; + case AArch64::HINT: { + // CurrentPatchableFunctionEntrySym can be CurrentFnBegin only for + // -fpatchable-function-entry=N,0. The entry MBB is guaranteed to be + // non-empty. If MI is the initial BTI, place the + // __patchable_function_entries label after BTI. + if (CurrentPatchableFunctionEntrySym && + CurrentPatchableFunctionEntrySym == CurrentFnBegin && + MI == &MF->front().front()) { + int64_t Imm = MI->getOperand(0).getImm(); + if ((Imm & 32) && (Imm & 6)) { + MCInst Inst; + MCInstLowering.Lower(MI, Inst); + EmitToStreamer(*OutStreamer, Inst); + CurrentPatchableFunctionEntrySym = createTempSymbol("patch"); + OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym); + return; + } + } + break; + } case AArch64::MOVMCSym: { Register DestReg = MI->getOperand(0).getReg(); const MachineOperand &MO_Sym = MI->getOperand(1); @@ -1048,7 +1075,7 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { SmallString<128> TmpStr; raw_svector_ostream OS(TmpStr); PrintDebugValueComment(MI, OS); - OutStreamer->EmitRawText(StringRef(OS.str())); + OutStreamer->emitRawText(StringRef(OS.str())); } return; @@ -1061,7 +1088,7 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { if (needsCFIMoves() == CFI_M_None) return; - OutStreamer->EmitCFIBKeyFrame(); + OutStreamer->emitCFIBKeyFrame(); return; } } @@ -1087,6 +1114,25 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); return; } + case AArch64::SpeculationBarrierISBDSBEndBB: { + // Print DSB SYS + ISB + MCInst TmpInstDSB; + TmpInstDSB.setOpcode(AArch64::DSB); + TmpInstDSB.addOperand(MCOperand::createImm(0xf)); + EmitToStreamer(*OutStreamer, TmpInstDSB); + MCInst TmpInstISB; + TmpInstISB.setOpcode(AArch64::ISB); + TmpInstISB.addOperand(MCOperand::createImm(0xf)); + EmitToStreamer(*OutStreamer, TmpInstISB); + return; + } + case AArch64::SpeculationBarrierSBEndBB: { + // Print SB + MCInst TmpInstSB; + TmpInstSB.setOpcode(AArch64::SB); + EmitToStreamer(*OutStreamer, TmpInstSB); + return; + } case AArch64::TLSDESC_CALLSEQ: { /// lower this to: /// adrp x0, :tlsdesc:var |