LLVM API Documentation

HexagonAsmPrinter.cpp
Go to the documentation of this file.
00001 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains a printer that converts from our internal representation
00011 // of machine-dependent LLVM code to Hexagon assembly language. This printer is
00012 // the output mechanism used by `llc'.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "Hexagon.h"
00017 #include "HexagonAsmPrinter.h"
00018 #include "HexagonMachineFunctionInfo.h"
00019 #include "HexagonSubtarget.h"
00020 #include "HexagonTargetMachine.h"
00021 #include "InstPrinter/HexagonInstPrinter.h"
00022 #include "MCTargetDesc/HexagonMCInst.h"
00023 #include "llvm/ADT/SmallString.h"
00024 #include "llvm/ADT/SmallVector.h"
00025 #include "llvm/ADT/StringExtras.h"
00026 #include "llvm/Analysis/ConstantFolding.h"
00027 #include "llvm/CodeGen/AsmPrinter.h"
00028 #include "llvm/CodeGen/MachineFunctionPass.h"
00029 #include "llvm/CodeGen/MachineInstr.h"
00030 #include "llvm/CodeGen/MachineInstrBuilder.h"
00031 #include "llvm/CodeGen/MachineModuleInfo.h"
00032 #include "llvm/IR/Constants.h"
00033 #include "llvm/IR/DataLayout.h"
00034 #include "llvm/IR/DerivedTypes.h"
00035 #include "llvm/IR/Mangler.h"
00036 #include "llvm/IR/Module.h"
00037 #include "llvm/MC/MCAsmInfo.h"
00038 #include "llvm/MC/MCContext.h"
00039 #include "llvm/MC/MCExpr.h"
00040 #include "llvm/MC/MCInst.h"
00041 #include "llvm/MC/MCSection.h"
00042 #include "llvm/MC/MCStreamer.h"
00043 #include "llvm/MC/MCSymbol.h"
00044 #include "llvm/Support/CommandLine.h"
00045 #include "llvm/Support/Compiler.h"
00046 #include "llvm/Support/Debug.h"
00047 #include "llvm/Support/Format.h"
00048 #include "llvm/Support/MathExtras.h"
00049 #include "llvm/Support/TargetRegistry.h"
00050 #include "llvm/Support/raw_ostream.h"
00051 #include "llvm/Target/TargetInstrInfo.h"
00052 #include "llvm/Target/TargetLoweringObjectFile.h"
00053 #include "llvm/Target/TargetOptions.h"
00054 #include "llvm/Target/TargetRegisterInfo.h"
00055 
00056 using namespace llvm;
00057 
00058 #define DEBUG_TYPE "asm-printer"
00059 
00060 static cl::opt<bool> AlignCalls(
00061          "hexagon-align-calls", cl::Hidden, cl::init(true),
00062           cl::desc("Insert falign after call instruction for Hexagon target"));
00063 
00064 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
00065                                     raw_ostream &O) {
00066   const MachineOperand &MO = MI->getOperand(OpNo);
00067 
00068   switch (MO.getType()) {
00069   default: llvm_unreachable ("<unknown operand type>");
00070   case MachineOperand::MO_Register:
00071     O << HexagonInstPrinter::getRegisterName(MO.getReg());
00072     return;
00073   case MachineOperand::MO_Immediate:
00074     O << MO.getImm();
00075     return;
00076   case MachineOperand::MO_MachineBasicBlock:
00077     O << *MO.getMBB()->getSymbol();
00078     return;
00079   case MachineOperand::MO_ConstantPoolIndex:
00080     O << *GetCPISymbol(MO.getIndex());
00081     return;
00082   case MachineOperand::MO_GlobalAddress:
00083     // Computing the address of a global symbol, not calling it.
00084     O << *getSymbol(MO.getGlobal());
00085     printOffset(MO.getOffset(), O);
00086     return;
00087   }
00088 }
00089 
00090 //
00091 // isBlockOnlyReachableByFallthrough - We need to override this since the
00092 // default AsmPrinter does not print labels for any basic block that
00093 // is only reachable by a fall through. That works for all cases except
00094 // for the case in which the basic block is reachable by a fall through but
00095 // through an indirect from a jump table. In this case, the jump table
00096 // will contain a label not defined by AsmPrinter.
00097 //
00098 bool HexagonAsmPrinter::
00099 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
00100   if (MBB->hasAddressTaken()) {
00101     return false;
00102   }
00103   return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
00104 }
00105 
00106 
00107 /// PrintAsmOperand - Print out an operand for an inline asm expression.
00108 ///
00109 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00110                                         unsigned AsmVariant,
00111                                         const char *ExtraCode,
00112                                         raw_ostream &OS) {
00113   // Does this asm operand have a single letter operand modifier?
00114   if (ExtraCode && ExtraCode[0]) {
00115     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00116 
00117     switch (ExtraCode[0]) {
00118     default:
00119       // See if this is a generic print operand
00120       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
00121     case 'c': // Don't print "$" before a global var name or constant.
00122       // Hexagon never has a prefix.
00123       printOperand(MI, OpNo, OS);
00124       return false;
00125     case 'L': // Write second word of DImode reference.
00126       // Verify that this operand has two consecutive registers.
00127       if (!MI->getOperand(OpNo).isReg() ||
00128           OpNo+1 == MI->getNumOperands() ||
00129           !MI->getOperand(OpNo+1).isReg())
00130         return true;
00131       ++OpNo;   // Return the high-part.
00132       break;
00133     case 'I':
00134       // Write 'i' if an integer constant, otherwise nothing.  Used to print
00135       // addi vs add, etc.
00136       if (MI->getOperand(OpNo).isImm())
00137         OS << "i";
00138       return false;
00139     }
00140   }
00141 
00142   printOperand(MI, OpNo, OS);
00143   return false;
00144 }
00145 
00146 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
00147                                             unsigned OpNo, unsigned AsmVariant,
00148                                             const char *ExtraCode,
00149                                             raw_ostream &O) {
00150   if (ExtraCode && ExtraCode[0])
00151     return true; // Unknown modifier.
00152 
00153   const MachineOperand &Base  = MI->getOperand(OpNo);
00154   const MachineOperand &Offset = MI->getOperand(OpNo+1);
00155 
00156   if (Base.isReg())
00157     printOperand(MI, OpNo, O);
00158   else
00159     llvm_unreachable("Unimplemented");
00160 
00161   if (Offset.isImm()) {
00162     if (Offset.getImm())
00163       O << " + #" << Offset.getImm();
00164   }
00165   else
00166     llvm_unreachable("Unimplemented");
00167 
00168   return false;
00169 }
00170 
00171 
00172 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
00173 /// the current output stream.
00174 ///
00175 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
00176   if (MI->isBundle()) {
00177     std::vector<const MachineInstr*> BundleMIs;
00178 
00179     const MachineBasicBlock *MBB = MI->getParent();
00180     MachineBasicBlock::const_instr_iterator MII = MI;
00181     ++MII;
00182     unsigned int IgnoreCount = 0;
00183     while (MII != MBB->end() && MII->isInsideBundle()) {
00184       const MachineInstr *MInst = MII;
00185       if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
00186           MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
00187           IgnoreCount++;
00188           ++MII;
00189           continue;
00190       }
00191       //BundleMIs.push_back(&*MII);
00192       BundleMIs.push_back(MInst);
00193       ++MII;
00194     }
00195     unsigned Size = BundleMIs.size();
00196     assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
00197     for (unsigned Index = 0; Index < Size; Index++) {
00198       HexagonMCInst MCI;
00199       MCI.setPacketStart(Index == 0);
00200       MCI.setPacketEnd(Index == (Size-1));
00201 
00202       HexagonLowerToMC(BundleMIs[Index], MCI, *this);
00203       EmitToStreamer(OutStreamer, MCI);
00204     }
00205   }
00206   else {
00207     HexagonMCInst MCI;
00208     if (MI->getOpcode() == Hexagon::ENDLOOP0) {
00209       MCI.setPacketStart(true);
00210       MCI.setPacketEnd(true);
00211     }
00212     HexagonLowerToMC(MI, MCI, *this);
00213     EmitToStreamer(OutStreamer, MCI);
00214   }
00215 
00216   return;
00217 }
00218 
00219 static MCInstPrinter *createHexagonMCInstPrinter(const Target &T,
00220                                                  unsigned SyntaxVariant,
00221                                                  const MCAsmInfo &MAI,
00222                                                  const MCInstrInfo &MII,
00223                                                  const MCRegisterInfo &MRI,
00224                                                  const MCSubtargetInfo &STI) {
00225   if (SyntaxVariant == 0)
00226     return(new HexagonInstPrinter(MAI, MII, MRI));
00227   else
00228    return nullptr;
00229 }
00230 
00231 extern "C" void LLVMInitializeHexagonAsmPrinter() {
00232   RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget);
00233 
00234   TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
00235                                         createHexagonMCInstPrinter);
00236 }