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 #define DEBUG_TYPE "asm-printer"
00017 #include "Hexagon.h"
00018 #include "HexagonAsmPrinter.h"
00019 #include "HexagonMachineFunctionInfo.h"
00020 #include "HexagonTargetMachine.h"
00021 #include "HexagonSubtarget.h"
00022 #include "MCTargetDesc/HexagonMCInst.h"
00023 #include "InstPrinter/HexagonInstPrinter.h"
00024 #include "llvm/ADT/SmallString.h"
00025 #include "llvm/ADT/SmallVector.h"
00026 #include "llvm/ADT/StringExtras.h"
00027 #include "llvm/Analysis/ConstantFolding.h"
00028 #include "llvm/Assembly/Writer.h"
00029 #include "llvm/CodeGen/AsmPrinter.h"
00030 #include "llvm/CodeGen/MachineFunctionPass.h"
00031 #include "llvm/CodeGen/MachineInstr.h"
00032 #include "llvm/CodeGen/MachineInstrBuilder.h"
00033 #include "llvm/CodeGen/MachineModuleInfo.h"
00034 #include "llvm/IR/Constants.h"
00035 #include "llvm/IR/DataLayout.h"
00036 #include "llvm/IR/DerivedTypes.h"
00037 #include "llvm/IR/Module.h"
00038 #include "llvm/MC/MCAsmInfo.h"
00039 #include "llvm/MC/MCContext.h"
00040 #include "llvm/MC/MCExpr.h"
00041 #include "llvm/MC/MCInst.h"
00042 #include "llvm/MC/MCSection.h"
00043 #include "llvm/MC/MCStreamer.h"
00044 #include "llvm/MC/MCSymbol.h"
00045 #include "llvm/Support/CommandLine.h"
00046 #include "llvm/Support/Compiler.h"
00047 #include "llvm/Support/Debug.h"
00048 #include "llvm/Support/Format.h"
00049 #include "llvm/Support/MathExtras.h"
00050 #include "llvm/Support/TargetRegistry.h"
00051 #include "llvm/Support/raw_ostream.h"
00052 #include "llvm/Target/Mangler.h"
00053 #include "llvm/Target/TargetInstrInfo.h"
00054 #include "llvm/Target/TargetLoweringObjectFile.h"
00055 #include "llvm/Target/TargetOptions.h"
00056 #include "llvm/Target/TargetRegisterInfo.h"
00057 
00058 using namespace llvm;
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::EmitAlignment(unsigned NumBits,
00065                                       const GlobalValue *GV) const {
00066   // For basic block level alignment, use ".falign".
00067   if (!GV) {
00068     OutStreamer.EmitRawText(StringRef("\t.falign"));
00069     return;
00070   }
00071 
00072   AsmPrinter::EmitAlignment(NumBits, GV);
00073 }
00074 
00075 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
00076                                     raw_ostream &O) {
00077   const MachineOperand &MO = MI->getOperand(OpNo);
00078 
00079   switch (MO.getType()) {
00080   default: llvm_unreachable ("<unknown operand type>");
00081   case MachineOperand::MO_Register:
00082     O << HexagonInstPrinter::getRegisterName(MO.getReg());
00083     return;
00084   case MachineOperand::MO_Immediate:
00085     O << MO.getImm();
00086     return;
00087   case MachineOperand::MO_MachineBasicBlock:
00088     O << *MO.getMBB()->getSymbol();
00089     return;
00090   case MachineOperand::MO_JumpTableIndex:
00091     O << *GetJTISymbol(MO.getIndex());
00092     // FIXME: PIC relocation model.
00093     return;
00094   case MachineOperand::MO_ConstantPoolIndex:
00095     O << *GetCPISymbol(MO.getIndex());
00096     return;
00097   case MachineOperand::MO_ExternalSymbol:
00098     O << *GetExternalSymbolSymbol(MO.getSymbolName());
00099     return;
00100   case MachineOperand::MO_GlobalAddress:
00101     // Computing the address of a global symbol, not calling it.
00102     O << *Mang->getSymbol(MO.getGlobal());
00103     printOffset(MO.getOffset(), O);
00104     return;
00105   }
00106 }
00107 
00108 //
00109 // isBlockOnlyReachableByFallthrough - We need to override this since the
00110 // default AsmPrinter does not print labels for any basic block that
00111 // is only reachable by a fall through. That works for all cases except
00112 // for the case in which the basic block is reachable by a fall through but
00113 // through an indirect from a jump table. In this case, the jump table
00114 // will contain a label not defined by AsmPrinter.
00115 //
00116 bool HexagonAsmPrinter::
00117 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
00118   if (MBB->hasAddressTaken()) {
00119     return false;
00120   }
00121   return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
00122 }
00123 
00124 
00125 /// PrintAsmOperand - Print out an operand for an inline asm expression.
00126 ///
00127 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00128                                         unsigned AsmVariant,
00129                                         const char *ExtraCode,
00130                                         raw_ostream &OS) {
00131   // Does this asm operand have a single letter operand modifier?
00132   if (ExtraCode && ExtraCode[0]) {
00133     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00134 
00135     switch (ExtraCode[0]) {
00136     default:
00137       // See if this is a generic print operand
00138       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
00139     case 'c': // Don't print "$" before a global var name or constant.
00140       // Hexagon never has a prefix.
00141       printOperand(MI, OpNo, OS);
00142       return false;
00143     case 'L': // Write second word of DImode reference.
00144       // Verify that this operand has two consecutive registers.
00145       if (!MI->getOperand(OpNo).isReg() ||
00146           OpNo+1 == MI->getNumOperands() ||
00147           !MI->getOperand(OpNo+1).isReg())
00148         return true;
00149       ++OpNo;   // Return the high-part.
00150       break;
00151     case 'I':
00152       // Write 'i' if an integer constant, otherwise nothing.  Used to print
00153       // addi vs add, etc.
00154       if (MI->getOperand(OpNo).isImm())
00155         OS << "i";
00156       return false;
00157     }
00158   }
00159 
00160   printOperand(MI, OpNo, OS);
00161   return false;
00162 }
00163 
00164 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
00165                                             unsigned OpNo, unsigned AsmVariant,
00166                                             const char *ExtraCode,
00167                                             raw_ostream &O) {
00168   if (ExtraCode && ExtraCode[0])
00169     return true; // Unknown modifier.
00170 
00171   const MachineOperand &Base  = MI->getOperand(OpNo);
00172   const MachineOperand &Offset = MI->getOperand(OpNo+1);
00173 
00174   if (Base.isReg())
00175     printOperand(MI, OpNo, O);
00176   else
00177     llvm_unreachable("Unimplemented");
00178 
00179   if (Offset.isImm()) {
00180     if (Offset.getImm())
00181       O << " + #" << Offset.getImm();
00182   }
00183   else
00184     llvm_unreachable("Unimplemented");
00185 
00186   return false;
00187 }
00188 
00189 void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI,
00190                                               unsigned OpNo,
00191                                               raw_ostream &O) {
00192   llvm_unreachable("Unimplemented");
00193 }
00194 
00195 
00196 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
00197 /// the current output stream.
00198 ///
00199 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
00200   if (MI->isBundle()) {
00201     std::vector<const MachineInstr*> BundleMIs;
00202 
00203     const MachineBasicBlock *MBB = MI->getParent();
00204     MachineBasicBlock::const_instr_iterator MII = MI;
00205     ++MII;
00206     unsigned int IgnoreCount = 0;
00207     while (MII != MBB->end() && MII->isInsideBundle()) {
00208       const MachineInstr *MInst = MII;
00209       if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
00210           MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
00211           IgnoreCount++;
00212           ++MII;
00213           continue;
00214       }
00215       //BundleMIs.push_back(&*MII);
00216       BundleMIs.push_back(MInst);
00217       ++MII;
00218     }
00219     unsigned Size = BundleMIs.size();
00220     assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
00221     for (unsigned Index = 0; Index < Size; Index++) {
00222       HexagonMCInst MCI;
00223       MCI.setPacketStart(Index == 0);
00224       MCI.setPacketEnd(Index == (Size-1));
00225 
00226       HexagonLowerToMC(BundleMIs[Index], MCI, *this);
00227       OutStreamer.EmitInstruction(MCI);
00228     }
00229   }
00230   else {
00231     HexagonMCInst MCI;
00232     if (MI->getOpcode() == Hexagon::ENDLOOP0) {
00233       MCI.setPacketStart(true);
00234       MCI.setPacketEnd(true);
00235     }
00236     HexagonLowerToMC(MI, MCI, *this);
00237     OutStreamer.EmitInstruction(MCI);
00238   }
00239 
00240   return;
00241 }
00242 
00243 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
00244 /// Don't print things like \n or \0.
00245 // static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
00246 //   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
00247 //        Name != E; ++Name)
00248 //     if (isprint(*Name))
00249 //       OS << *Name;
00250 // }
00251 
00252 
00253 void HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI,
00254                                                     int OpNo, raw_ostream &O) {
00255   const MachineOperand &MO1 = MI->getOperand(OpNo);
00256   const MachineOperand &MO2 = MI->getOperand(OpNo+1);
00257 
00258   O << HexagonInstPrinter::getRegisterName(MO1.getReg())
00259     << " + #"
00260     << MO2.getImm();
00261 }
00262 
00263 
00264 void HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo,
00265                                            raw_ostream &O) {
00266   const MachineOperand &MO = MI->getOperand(OpNo);
00267   assert( (MO.getType() == MachineOperand::MO_GlobalAddress) &&
00268          "Expecting global address");
00269 
00270   O << *Mang->getSymbol(MO.getGlobal());
00271   if (MO.getOffset() != 0) {
00272     O << " + ";
00273     O << MO.getOffset();
00274   }
00275 }
00276 
00277 void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo,
00278                                        raw_ostream &O) {
00279   const MachineOperand &MO = MI->getOperand(OpNo);
00280   assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && 
00281            "Expecting jump table index");
00282 
00283   // Hexagon_TODO: Do we need name mangling?
00284   O << *GetJTISymbol(MO.getIndex());
00285 }
00286 
00287 void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo,
00288                                        raw_ostream &O) {
00289   const MachineOperand &MO = MI->getOperand(OpNo);
00290   assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) &&
00291           "Expecting constant pool index");
00292 
00293   // Hexagon_TODO: Do we need name mangling?
00294   O << *GetCPISymbol(MO.getIndex());
00295 }
00296 
00297 static MCInstPrinter *createHexagonMCInstPrinter(const Target &T,
00298                                                  unsigned SyntaxVariant,
00299                                                  const MCAsmInfo &MAI,
00300                                                  const MCInstrInfo &MII,
00301                                                  const MCRegisterInfo &MRI,
00302                                                  const MCSubtargetInfo &STI) {
00303   if (SyntaxVariant == 0)
00304     return(new HexagonInstPrinter(MAI, MII, MRI));
00305   else
00306    return NULL;
00307 }
00308 
00309 extern "C" void LLVMInitializeHexagonAsmPrinter() {
00310   RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget);
00311 
00312   TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
00313                                         createHexagonMCInstPrinter);
00314 }