//===-- AlphaAsmPrinter.cpp - Alpha LLVM assembly writer ------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains a printer that converts from our internal representation // of machine-dependent LLVM code to GAS-format Alpha assembly language. // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asm-printer" #include "Alpha.h" #include "AlphaInstrInfo.h" #include "AlphaTargetMachine.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DwarfWriter.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; namespace { struct AlphaAsmPrinter : public AsmPrinter { /// Unique incrementer for label values for referencing Global values. /// explicit AlphaAsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, MCStreamer &Streamer) : AsmPrinter(o, tm, Streamer) {} virtual const char *getPassName() const { return "Alpha Assembly Printer"; } void printInstruction(const MachineInstr *MI); void EmitInstruction(const MachineInstr *MI) { printInstruction(MI); OutStreamer.AddBlankLine(); } static const char *getRegisterName(unsigned RegNo); void printOp(const MachineOperand &MO, bool IsCallOp = false); void printOperand(const MachineInstr *MI, int opNum); void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true); virtual void EmitFunctionBodyStart(); virtual void EmitFunctionBodyEnd(); void EmitStartOfAsmFile(Module &M); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); }; } // end of anonymous namespace #include "AlphaGenAsmWriter.inc" void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { const MachineOperand &MO = MI->getOperand(opNum); if (MO.getType() == MachineOperand::MO_Register) { assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && "Not physreg??"); O << getRegisterName(MO.getReg()); } else if (MO.isImm()) { O << MO.getImm(); assert(MO.getImm() < (1 << 30)); } else { printOp(MO); } } void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { switch (MO.getType()) { case MachineOperand::MO_Register: O << getRegisterName(MO.getReg()); return; case MachineOperand::MO_Immediate: llvm_unreachable("printOp() does not handle immediate values"); return; case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); return; case MachineOperand::MO_ConstantPoolIndex: O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); return; case MachineOperand::MO_GlobalAddress: O << *Mang->getSymbol(MO.getGlobal()); return; case MachineOperand::MO_JumpTableIndex: O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: O << ""; return; } } /// EmitFunctionBodyStart - Targets can override this to emit stuff before /// the first basic block in the function. void AlphaAsmPrinter::EmitFunctionBodyStart() { O << "\t.ent " << *CurrentFnSym << "\n"; } /// EmitFunctionBodyEnd - Targets can override this to emit stuff after /// the last basic block in the function. void AlphaAsmPrinter::EmitFunctionBodyEnd() { O << "\t.end " << *CurrentFnSym << "\n"; } void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) { if (TM.getSubtarget().hasCT()) O << "\t.arch ev6\n"; //This might need to be ev67, so leave this test here else O << "\t.arch ev6\n"; O << "\t.set noat\n"; } /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode) { printOperand(MI, OpNo); return false; } bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode) { if (ExtraCode && ExtraCode[0]) return true; // Unknown modifier. O << "0("; printOperand(MI, OpNo); O << ")"; return false; } // Force static initialization. extern "C" void LLVMInitializeAlphaAsmPrinter() { RegisterAsmPrinter X(TheAlphaTarget); }