003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/SystemZ
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
SystemZ
/
📁
..
📁
AsmParser
📁
Disassembler
📁
MCTargetDesc
📄
README.txt
(3.94 KB)
📄
SystemZ.h
(8.19 KB)
📄
SystemZ.td
(2.86 KB)
📄
SystemZAsmPrinter.cpp
(23.49 KB)
📄
SystemZAsmPrinter.h
(1.88 KB)
📄
SystemZCallingConv.cpp
(710 B)
📄
SystemZCallingConv.h
(4.89 KB)
📄
SystemZCallingConv.td
(6.99 KB)
📄
SystemZConstantPoolValue.cpp
(1.78 KB)
📄
SystemZConstantPoolValue.h
(1.75 KB)
📄
SystemZCopyPhysRegs.cpp
(3.82 KB)
📄
SystemZElimCompare.cpp
(26.21 KB)
📄
SystemZFeatures.td
(12.3 KB)
📄
SystemZFrameLowering.cpp
(29.88 KB)
📄
SystemZFrameLowering.h
(3.02 KB)
📄
SystemZHazardRecognizer.cpp
(14.75 KB)
📄
SystemZHazardRecognizer.h
(5.86 KB)
📄
SystemZISelDAGToDAG.cpp
(68.74 KB)
📄
SystemZISelLowering.cpp
(321.22 KB)
📄
SystemZISelLowering.h
(28.44 KB)
📄
SystemZInstrBuilder.h
(1.63 KB)
📄
SystemZInstrDFP.td
(9.3 KB)
📄
SystemZInstrFP.td
(26.21 KB)
📄
SystemZInstrFormats.td
(182.82 KB)
📄
SystemZInstrHFP.td
(9.46 KB)
📄
SystemZInstrInfo.cpp
(69.75 KB)
📄
SystemZInstrInfo.h
(14.6 KB)
📄
SystemZInstrInfo.td
(103.17 KB)
📄
SystemZInstrSystem.td
(17.18 KB)
📄
SystemZInstrVector.td
(84.36 KB)
📄
SystemZLDCleanup.cpp
(4.91 KB)
📄
SystemZLongBranch.cpp
(16.04 KB)
📄
SystemZMCInstLower.cpp
(3.16 KB)
📄
SystemZMCInstLower.h
(1.28 KB)
📄
SystemZMachineFunctionInfo.cpp
(508 B)
📄
SystemZMachineFunctionInfo.h
(3.77 KB)
📄
SystemZMachineScheduler.cpp
(8.76 KB)
📄
SystemZMachineScheduler.h
(5.05 KB)
📄
SystemZOperands.td
(24.89 KB)
📄
SystemZOperators.td
(48.97 KB)
📄
SystemZPatterns.td
(8.52 KB)
📄
SystemZPostRewrite.cpp
(10.33 KB)
📄
SystemZProcessors.td
(1.78 KB)
📄
SystemZRegisterInfo.cpp
(16.27 KB)
📄
SystemZRegisterInfo.h
(3.52 KB)
📄
SystemZRegisterInfo.td
(12.04 KB)
📄
SystemZSchedule.td
(2.1 KB)
📄
SystemZScheduleZ13.td
(72.43 KB)
📄
SystemZScheduleZ14.td
(78.06 KB)
📄
SystemZScheduleZ15.td
(80.69 KB)
📄
SystemZScheduleZ196.td
(55.68 KB)
📄
SystemZScheduleZEC12.td
(57.44 KB)
📄
SystemZSelectionDAGInfo.cpp
(12.92 KB)
📄
SystemZSelectionDAGInfo.h
(3.15 KB)
📄
SystemZShortenInst.cpp
(12 KB)
📄
SystemZSubtarget.cpp
(3.67 KB)
📄
SystemZSubtarget.h
(9.14 KB)
📄
SystemZTDC.cpp
(13.52 KB)
📄
SystemZTargetMachine.cpp
(11.58 KB)
📄
SystemZTargetMachine.h
(2.09 KB)
📄
SystemZTargetTransformInfo.cpp
(43.51 KB)
📄
SystemZTargetTransformInfo.h
(4.88 KB)
📁
TargetInfo
Editing: SystemZAsmPrinter.cpp
//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Streams SystemZ assembly language and associated data, in the form of // MCInsts and MCExprs respectively. // //===----------------------------------------------------------------------===// #include "SystemZAsmPrinter.h" #include "MCTargetDesc/SystemZInstPrinter.h" #include "SystemZConstantPoolValue.h" #include "SystemZMCInstLower.h" #include "TargetInfo/SystemZTargetInfo.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; // Return an RI instruction like MI with opcode Opcode, but with the // GR64 register operands turned into GR32s. static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { if (MI->isCompare()) return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) .addImm(MI->getOperand(1).getImm()); else return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) .addImm(MI->getOperand(2).getImm()); } // Return an RI instruction like MI with opcode Opcode, but with the // GR64 register operands turned into GRH32s. static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { if (MI->isCompare()) return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) .addImm(MI->getOperand(1).getImm()); else return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) .addImm(MI->getOperand(2).getImm()); } // Return an RI instruction like MI with opcode Opcode, but with the // R2 register turned into a GR64. static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { return MCInstBuilder(Opcode) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) .addImm(MI->getOperand(3).getImm()) .addImm(MI->getOperand(4).getImm()) .addImm(MI->getOperand(5).getImm()); } static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { StringRef Name = "__tls_get_offset"; return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), MCSymbolRefExpr::VK_PLT, Context); } static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { StringRef Name = "_GLOBAL_OFFSET_TABLE_"; return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), MCSymbolRefExpr::VK_None, Context); } // MI is an instruction that accepts an optional alignment hint, // and which was already lowered to LoweredMI. If the alignment // of the original memory operand is known, update LoweredMI to // an instruction with the corresponding hint set. static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, unsigned Opcode) { if (!MI->hasOneMemOperand()) return; const MachineMemOperand *MMO = *MI->memoperands_begin(); unsigned AlignmentHint = 0; if (MMO->getAlign() >= Align(16)) AlignmentHint = 4; else if (MMO->getAlign() >= Align(8)) AlignmentHint = 3; if (AlignmentHint == 0) return; LoweredMI.setOpcode(Opcode); LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); } // MI loads the high part of a vector from memory. Return an instruction // that uses replicating vector load Opcode to do the same thing. static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(MI->getOperand(3).getReg()); } // MI stores the high part of a vector to memory. Return an instruction // that uses elemental vector store Opcode to do the same thing. static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { return MCInstBuilder(Opcode) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(MI->getOperand(3).getReg()) .addImm(0); } void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { SystemZMCInstLower Lower(MF->getContext(), *this); MCInst LoweredMI; switch (MI->getOpcode()) { case SystemZ::Return: LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); break; case SystemZ::CondReturn: LoweredMI = MCInstBuilder(SystemZ::BCR) .addImm(MI->getOperand(0).getImm()) .addImm(MI->getOperand(1).getImm()) .addReg(SystemZ::R14D); break; case SystemZ::CRBReturn: LoweredMI = MCInstBuilder(SystemZ::CRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CGRBReturn: LoweredMI = MCInstBuilder(SystemZ::CGRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CIBReturn: LoweredMI = MCInstBuilder(SystemZ::CIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CGIBReturn: LoweredMI = MCInstBuilder(SystemZ::CGIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CLRBReturn: LoweredMI = MCInstBuilder(SystemZ::CLRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CLGRBReturn: LoweredMI = MCInstBuilder(SystemZ::CLGRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CLIBReturn: LoweredMI = MCInstBuilder(SystemZ::CLIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CLGIBReturn: LoweredMI = MCInstBuilder(SystemZ::CLGIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R14D) .addImm(0); break; case SystemZ::CallBRASL: LoweredMI = MCInstBuilder(SystemZ::BRASL) .addReg(SystemZ::R14D) .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); break; case SystemZ::CallBASR: LoweredMI = MCInstBuilder(SystemZ::BASR) .addReg(SystemZ::R14D) .addReg(MI->getOperand(0).getReg()); break; case SystemZ::CallJG: LoweredMI = MCInstBuilder(SystemZ::JG) .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); break; case SystemZ::CallBRCL: LoweredMI = MCInstBuilder(SystemZ::BRCL) .addImm(MI->getOperand(0).getImm()) .addImm(MI->getOperand(1).getImm()) .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); break; case SystemZ::CallBR: LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); break; case SystemZ::CallBCR: LoweredMI = MCInstBuilder(SystemZ::BCR) .addImm(MI->getOperand(0).getImm()) .addImm(MI->getOperand(1).getImm()) .addReg(SystemZ::R1D); break; case SystemZ::CRBCall: LoweredMI = MCInstBuilder(SystemZ::CRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CGRBCall: LoweredMI = MCInstBuilder(SystemZ::CGRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CIBCall: LoweredMI = MCInstBuilder(SystemZ::CIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CGIBCall: LoweredMI = MCInstBuilder(SystemZ::CGIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CLRBCall: LoweredMI = MCInstBuilder(SystemZ::CLRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CLGRBCall: LoweredMI = MCInstBuilder(SystemZ::CLGRB) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CLIBCall: LoweredMI = MCInstBuilder(SystemZ::CLIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::CLGIBCall: LoweredMI = MCInstBuilder(SystemZ::CLGIB) .addReg(MI->getOperand(0).getReg()) .addImm(MI->getOperand(1).getImm()) .addImm(MI->getOperand(2).getImm()) .addReg(SystemZ::R1D) .addImm(0); break; case SystemZ::TLS_GDCALL: LoweredMI = MCInstBuilder(SystemZ::BRASL) .addReg(SystemZ::R14D) .addExpr(getTLSGetOffset(MF->getContext())) .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); break; case SystemZ::TLS_LDCALL: LoweredMI = MCInstBuilder(SystemZ::BRASL) .addReg(SystemZ::R14D) .addExpr(getTLSGetOffset(MF->getContext())) .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); break; case SystemZ::GOT: LoweredMI = MCInstBuilder(SystemZ::LARL) .addReg(MI->getOperand(0).getReg()) .addExpr(getGlobalOffsetTable(MF->getContext())); break; case SystemZ::IILF64: LoweredMI = MCInstBuilder(SystemZ::IILF) .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) .addImm(MI->getOperand(2).getImm()); break; case SystemZ::IIHF64: LoweredMI = MCInstBuilder(SystemZ::IIHF) .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) .addImm(MI->getOperand(2).getImm()); break; case SystemZ::RISBHH: case SystemZ::RISBHL: LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); break; case SystemZ::RISBLH: case SystemZ::RISBLL: LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); break; case SystemZ::VLVGP32: LoweredMI = MCInstBuilder(SystemZ::VLVGP) .addReg(MI->getOperand(0).getReg()) .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); break; case SystemZ::VLR32: case SystemZ::VLR64: LoweredMI = MCInstBuilder(SystemZ::VLR) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); break; case SystemZ::VL: Lower.lower(MI, LoweredMI); lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); break; case SystemZ::VST: Lower.lower(MI, LoweredMI); lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); break; case SystemZ::VLM: Lower.lower(MI, LoweredMI); lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); break; case SystemZ::VSTM: Lower.lower(MI, LoweredMI); lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); break; case SystemZ::VL32: LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); break; case SystemZ::VL64: LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); break; case SystemZ::VST32: LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); break; case SystemZ::VST64: LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); break; case SystemZ::LFER: LoweredMI = MCInstBuilder(SystemZ::VLGVF) .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) .addReg(0).addImm(0); break; case SystemZ::LEFR: LoweredMI = MCInstBuilder(SystemZ::VLVGF) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) .addReg(MI->getOperand(1).getReg()) .addReg(0).addImm(0); break; #define LOWER_LOW(NAME) \ case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break LOWER_LOW(IILL); LOWER_LOW(IILH); LOWER_LOW(TMLL); LOWER_LOW(TMLH); LOWER_LOW(NILL); LOWER_LOW(NILH); LOWER_LOW(NILF); LOWER_LOW(OILL); LOWER_LOW(OILH); LOWER_LOW(OILF); LOWER_LOW(XILF); #undef LOWER_LOW #define LOWER_HIGH(NAME) \ case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break LOWER_HIGH(IIHL); LOWER_HIGH(IIHH); LOWER_HIGH(TMHL); LOWER_HIGH(TMHH); LOWER_HIGH(NIHL); LOWER_HIGH(NIHH); LOWER_HIGH(NIHF); LOWER_HIGH(OIHL); LOWER_HIGH(OIHH); LOWER_HIGH(OIHF); LOWER_HIGH(XIHF); #undef LOWER_HIGH case SystemZ::Serialize: if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) LoweredMI = MCInstBuilder(SystemZ::BCRAsm) .addImm(14).addReg(SystemZ::R0D); else LoweredMI = MCInstBuilder(SystemZ::BCRAsm) .addImm(15).addReg(SystemZ::R0D); break; // Emit nothing here but a comment if we can. case SystemZ::MemBarrier: OutStreamer->emitRawComment("MEMBARRIER"); return; // We want to emit "j .+2" for traps, jumping to the relative immediate field // of the jump instruction, which is an illegal instruction. We cannot emit a // "." symbol, so create and emit a temp label before the instruction and use // that instead. case SystemZ::Trap: { MCSymbol *DotSym = OutContext.createTempSymbol(); OutStreamer->emitLabel(DotSym); const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); LoweredMI = MCInstBuilder(SystemZ::J) .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); } break; // Conditional traps will create a branch on condition instruction that jumps // to the relative immediate field of the jump instruction. (eg. "jo .+2") case SystemZ::CondTrap: { MCSymbol *DotSym = OutContext.createTempSymbol(); OutStreamer->emitLabel(DotSym); const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); LoweredMI = MCInstBuilder(SystemZ::BRC) .addImm(MI->getOperand(0).getImm()) .addImm(MI->getOperand(1).getImm()) .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); } break; case TargetOpcode::FENTRY_CALL: LowerFENTRY_CALL(*MI, Lower); return; case TargetOpcode::STACKMAP: LowerSTACKMAP(*MI); return; case TargetOpcode::PATCHPOINT: LowerPATCHPOINT(*MI, Lower); return; default: Lower.lower(MI, LoweredMI); break; } EmitToStreamer(*OutStreamer, LoweredMI); } // Emit the largest nop instruction smaller than or equal to NumBytes // bytes. Return the size of nop emitted. static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, unsigned NumBytes, const MCSubtargetInfo &STI) { if (NumBytes < 2) { llvm_unreachable("Zero nops?"); return 0; } else if (NumBytes < 4) { OutStreamer.emitInstruction( MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI); return 2; } else if (NumBytes < 6) { OutStreamer.emitInstruction( MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0), STI); return 4; } else { MCSymbol *DotSym = OutContext.createTempSymbol(); const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); OutStreamer.emitLabel(DotSym); OutStreamer.emitInstruction( MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI); return 6; } } void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &Lower) { MCContext &Ctx = MF->getContext(); if (MF->getFunction().hasFnAttribute("mrecord-mcount")) { MCSymbol *DotSym = OutContext.createTempSymbol(); OutStreamer->PushSection(); OutStreamer->SwitchSection( Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC)); OutStreamer->emitSymbolValue(DotSym, 8); OutStreamer->PopSection(); OutStreamer->emitLabel(DotSym); } if (MF->getFunction().hasFnAttribute("mnop-mcount")) { EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); return; } MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); const MCSymbolRefExpr *Op = MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); OutStreamer->emitInstruction( MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op), getSubtargetInfo()); } void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { const SystemZInstrInfo *TII = static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); unsigned NumNOPBytes = MI.getOperand(1).getImm(); auto &Ctx = OutStreamer->getContext(); MCSymbol *MILabel = Ctx.createTempSymbol(); OutStreamer->emitLabel(MILabel); SM.recordStackMap(*MILabel, MI); assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); // Scan ahead to trim the shadow. unsigned ShadowBytes = 0; const MachineBasicBlock &MBB = *MI.getParent(); MachineBasicBlock::const_iterator MII(MI); ++MII; while (ShadowBytes < NumNOPBytes) { if (MII == MBB.end() || MII->getOpcode() == TargetOpcode::PATCHPOINT || MII->getOpcode() == TargetOpcode::STACKMAP) break; ShadowBytes += TII->getInstSizeInBytes(*MII); if (MII->isCall()) break; ++MII; } // Emit nops. while (ShadowBytes < NumNOPBytes) ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, getSubtargetInfo()); } // Lower a patchpoint of the form: // [<def>], <id>, <numBytes>, <target>, <numArgs> void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower) { auto &Ctx = OutStreamer->getContext(); MCSymbol *MILabel = Ctx.createTempSymbol(); OutStreamer->emitLabel(MILabel); SM.recordPatchPoint(*MILabel, MI); PatchPointOpers Opers(&MI); unsigned EncodedBytes = 0; const MachineOperand &CalleeMO = Opers.getCallTarget(); if (CalleeMO.isImm()) { uint64_t CallTarget = CalleeMO.getImm(); if (CallTarget) { unsigned ScratchIdx = -1; unsigned ScratchReg = 0; do { ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); ScratchReg = MI.getOperand(ScratchIdx).getReg(); } while (ScratchReg == SystemZ::R0D); // Materialize the call target address EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) .addReg(ScratchReg) .addImm(CallTarget & 0xFFFFFFFF)); EncodedBytes += 6; if (CallTarget >> 32) { EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) .addReg(ScratchReg) .addImm(CallTarget >> 32)); EncodedBytes += 6; } EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) .addReg(SystemZ::R14D) .addReg(ScratchReg)); EncodedBytes += 2; } } else if (CalleeMO.isGlobal()) { const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) .addReg(SystemZ::R14D) .addExpr(Expr)); EncodedBytes += 6; } // Emit padding. unsigned NumBytes = Opers.getNumPatchBytes(); assert(NumBytes >= EncodedBytes && "Patchpoint can't request size less than the length of a call."); assert((NumBytes - EncodedBytes) % 2 == 0 && "Invalid number of NOP bytes requested!"); while (EncodedBytes < NumBytes) EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, getSubtargetInfo()); } // Convert a SystemZ-specific constant pool modifier into the associated // MCSymbolRefExpr variant kind. static MCSymbolRefExpr::VariantKind getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { switch (Modifier) { case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; } llvm_unreachable("Invalid SystemCPModifier!"); } void SystemZAsmPrinter::emitMachineConstantPoolValue( MachineConstantPoolValue *MCPV) { auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); const MCExpr *Expr = MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), getModifierVariantKind(ZCPV->getModifier()), OutContext); uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); OutStreamer->emitValue(Expr, Size); } bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) { if (ExtraCode) return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); SystemZMCInstLower Lower(MF->getContext(), *this); MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); SystemZInstPrinter::printOperand(MO, MAI, OS); return false; } bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) { SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), MI->getOperand(OpNo + 1).getImm(), MI->getOperand(OpNo + 2).getReg(), OS); return false; } void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { emitStackMaps(SM); } // Force static initialization. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() { RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); }
Upload File
Create Folder