From 1adacceba9c9ee0f16e54388e56c9a249b296f75 Mon Sep 17 00:00:00 2001 From: rdivacky Date: Thu, 15 Oct 2009 16:26:17 +0000 Subject: Delete all stale files. --- lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp | 1108 ---------------------- lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h | 226 ----- lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp | 633 ------------ lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h | 162 ---- lib/Target/X86/X86TargetAsmInfo.cpp | 429 --------- lib/Target/X86/X86TargetAsmInfo.h | 75 -- 6 files changed, 2633 deletions(-) delete mode 100644 lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp delete mode 100644 lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h delete mode 100644 lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp delete mode 100644 lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h delete mode 100644 lib/Target/X86/X86TargetAsmInfo.cpp delete mode 100644 lib/Target/X86/X86TargetAsmInfo.h (limited to 'lib/Target/X86') diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp deleted file mode 100644 index 127f228..0000000 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ /dev/null @@ -1,1108 +0,0 @@ -//===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly -----===// -// -// 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 AT&T format assembly -// language. This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "X86ATTAsmPrinter.h" -#include "X86.h" -#include "X86COFF.h" -#include "X86MachineFunctionInfo.h" -#include "X86TargetMachine.h" -#include "X86TargetAsmInfo.h" -#include "llvm/CallingConv.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/MDNode.h" -#include "llvm/Type.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetOptions.h" -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static cl::opt NewAsmPrinter("experimental-asm-printer", - cl::Hidden); - -//===----------------------------------------------------------------------===// -// Primitive Helper Functions. -//===----------------------------------------------------------------------===// - -void X86ATTAsmPrinter::PrintPICBaseSymbol() const { - if (Subtarget->isTargetDarwin()) - O << "\"L" << getFunctionNumber() << "$pb\""; - else if (Subtarget->isTargetELF()) - O << ".Lllvm$" << getFunctionNumber() << "." "$piclabel"; - else - assert(0 && "Don't know how to print PIC label!\n"); -} - -/// PrintUnmangledNameSafely - Print out the printable characters in the name. -/// Don't print things like \\n or \\0. -static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { - for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); - Name != E; ++Name) - if (isprint(*Name)) - OS << *Name; -} - -static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, - const TargetData *TD) { - X86MachineFunctionInfo Info; - uint64_t Size = 0; - - switch (F->getCallingConv()) { - case CallingConv::X86_StdCall: - Info.setDecorationStyle(StdCall); - break; - case CallingConv::X86_FastCall: - Info.setDecorationStyle(FastCall); - break; - default: - return Info; - } - - unsigned argNum = 1; - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI, ++argNum) { - const Type* Ty = AI->getType(); - - // 'Dereference' type in case of byval parameter attribute - if (F->paramHasAttr(argNum, Attribute::ByVal)) - Ty = cast(Ty)->getElementType(); - - // Size should be aligned to DWORD boundary - Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; - } - - // We're not supporting tooooo huge arguments :) - Info.setBytesToPopOnReturn((unsigned int)Size); - return Info; -} - -/// decorateName - Query FunctionInfoMap and use this information for various -/// name decoration. -void X86ATTAsmPrinter::decorateName(std::string &Name, - const GlobalValue *GV) { - const Function *F = dyn_cast(GV); - if (!F) return; - - // We don't want to decorate non-stdcall or non-fastcall functions right now - unsigned CC = F->getCallingConv(); - if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) - return; - - // Decorate names only when we're targeting Cygwin/Mingw32 targets - if (!Subtarget->isTargetCygMing()) - return; - - FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); - - const X86MachineFunctionInfo *Info; - if (info_item == FunctionInfoMap.end()) { - // Calculate apropriate function info and populate map - FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); - Info = &FunctionInfoMap[F]; - } else { - Info = &info_item->second; - } - - const FunctionType *FT = F->getFunctionType(); - switch (Info->getDecorationStyle()) { - case None: - break; - case StdCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - break; - case FastCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - - if (Name[0] == '_') { - Name[0] = '@'; - } else { - Name = '@' + Name; - } - break; - default: - assert(0 && "Unsupported DecorationStyle"); - } -} - -void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { - unsigned FnAlign = MF.getAlignment(); - const Function *F = MF.getFunction(); - - decorateName(CurrentFnName, F); - - SwitchToSection(TAI->SectionForGlobal(F)); - switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case Function::InternalLinkage: // Symbols default to internal. - case Function::PrivateLinkage: - EmitAlignment(FnAlign, F); - break; - case Function::DLLExportLinkage: - case Function::ExternalLinkage: - EmitAlignment(FnAlign, F); - O << "\t.globl\t" << CurrentFnName << '\n'; - break; - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - EmitAlignment(FnAlign, F); - if (Subtarget->isTargetDarwin()) { - O << "\t.globl\t" << CurrentFnName << '\n'; - O << TAI->getWeakDefDirective() << CurrentFnName << '\n'; - } else if (Subtarget->isTargetCygMing()) { - O << "\t.globl\t" << CurrentFnName << "\n" - "\t.linkonce discard\n"; - } else { - O << "\t.weak\t" << CurrentFnName << '\n'; - } - break; - } - - printVisibility(CurrentFnName, F->getVisibility()); - - if (Subtarget->isTargetELF()) - O << "\t.type\t" << CurrentFnName << ",@function\n"; - else if (Subtarget->isTargetCygMing()) { - O << "\t.def\t " << CurrentFnName - << ";\t.scl\t" << - (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT) - << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) - << ";\t.endef\n"; - } - - O << CurrentFnName << ":\n"; - // Add some workaround for linkonce linkage on Cygwin\MinGW - if (Subtarget->isTargetCygMing() && - (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) - O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n"; -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - const Function *F = MF.getFunction(); - this->MF = &MF; - unsigned CC = F->getCallingConv(); - - SetupMachineFunction(MF); - O << "\n\n"; - - // Populate function information map. Actually, We don't want to populate - // non-stdcall or non-fastcall functions' information right now. - if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) - FunctionInfoMap[F] = *MF.getInfo(); - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - if (F->hasDLLExportLinkage()) - DLLExportedFns.insert(Mang->makeNameProper(F->getName(), "")); - - // Print the 'header' of function - emitFunctionHeader(MF); - - // Emit pre-function debug and/or EH information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->BeginFunction(&MF); - - // Print out code for the function. - bool hasAnyRealCode = false; - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) { - // This is an entry block or a block that's only reachable via a - // fallthrough edge. In non-VerboseAsm mode, don't print the label. - } else { - printBasicBlockLabel(I, true, true, VerboseAsm); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); - II != IE; ++II) { - // Print the assembly for the instruction. - if (!II->isLabel()) - hasAnyRealCode = true; - printMachineInstruction(II); - } - } - - if (Subtarget->isTargetDarwin() && !hasAnyRealCode) { - // If the function is empty, then we need to emit *something*. Otherwise, - // the function's label might be associated with something that it wasn't - // meant to be associated with. We emit a noop in this situation. - // We are assuming inline asms are code. - O << "\tnop\n"; - } - - if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; - - // Emit post-function debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->EndFunction(&MF); - - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - O.flush(); - - // We didn't modify anything. - return false; -} - -static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_; -} - -static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isPICStyleStub() && TM.getRelocationModel() != Reloc::Static; -} - -/// print_pcrel_imm - This is used to print an immediate value that ends up -/// being encoded as a pc-relative value. These print slightly differently, for -/// example, a $ is not emitted. -void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "Unknown pcrel immediate operand"); - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm); - return; - - case MachineOperand::MO_GlobalAddress: { - const GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - bool needCloseParen = false; - if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - if (shouldPrintStub(TM, Subtarget)) { - // DARWIN/X86-32 in != static mode. - - // Link-once, declaration, or Weakly-linked global variables need - // non-lazily-resolved stubs - if (GV->isDeclaration() || GV->isWeakForLinker()) { - // Dynamically-resolved functions need a stub for the function. - if (isa(GV)) { - // Function stubs are no longer needed for Mac OS X 10.5 and up. - if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { - O << Name; - } else { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - } - } else if (GV->hasHiddenVisibility()) { - if (!GV->isDeclaration() && !GV->hasCommonLinkage()) - // Definition is not definitely in the current translation unit. - O << Name; - else { - HiddenGVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - - if (shouldPrintPLT(TM, Subtarget)) { - // Assemble call via PLT for externally visible symbols - if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && - !GV->hasLocalLinkage()) - O << "@PLT"; - } - if (Subtarget->isTargetCygMing() && GV->isDeclaration()) - // Save function name for later type emission - FnStubs.insert(Name); - } - - printOffset(MO.getOffset()); - - if (needCloseParen) - O << ')'; - return; - } - - case MachineOperand::MO_ExternalSymbol: { - bool needCloseParen = false; - std::string Name(TAI->getGlobalPrefix()); - Name += MO.getSymbolName(); - // Print function stub suffix unless it's Mac OS X 10.5 and up. - if (shouldPrintStub(TM, Subtarget) && - // DARWIN/X86-32 in != static mode. - !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { - - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - return; - } - - if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - O << Name; - - if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) { - O << " + [.-"; - PrintPICBaseSymbol(); - O << ']'; - } - - if (shouldPrintPLT(TM, Subtarget)) - O << "@PLT"; - - if (needCloseParen) - O << ')'; - - return; - } - } -} - -void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "unknown operand type!"); - case MachineOperand::MO_Register: { - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Virtual registers should not make it this far!"); - O << '%'; - unsigned Reg = MO.getReg(); - if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { - MVT VT = (strcmp(Modifier+6,"64") == 0) ? - MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : - ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); - Reg = getX86SubSuperRegister(Reg, VT); - } - O << TRI->getAsmName(Reg); - return; - } - - case MachineOperand::MO_Immediate: - if (!Modifier || (strcmp(Modifier, "debug") && - strcmp(Modifier, "mem"))) - O << '$'; - O << MO.getImm(); - return; - case MachineOperand::MO_JumpTableIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' - << MO.getIndex(); - break; - } - case MachineOperand::MO_ConstantPoolIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << MO.getIndex(); - - printOffset(MO.getOffset()); - break; - } - case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - - const GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - bool needCloseParen = false; - if (!isMemOp) - O << '$'; - else if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - if (shouldPrintStub(TM, Subtarget)) { - // DARWIN/X86-32 in != static mode. - - // Link-once, declaration, or Weakly-linked global variables need - // non-lazily-resolved stubs - if (GV->isDeclaration() || GV->isWeakForLinker()) { - // Dynamically-resolved functions need a stub for the function. - if (GV->hasHiddenVisibility()) { - if (!GV->isDeclaration() && !GV->hasCommonLinkage()) - // Definition is not definitely in the current translation unit. - O << Name; - else { - HiddenGVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - - if (TM.getRelocationModel() == Reloc::PIC_) { - O << '-'; - PrintPICBaseSymbol(); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - - printOffset(MO.getOffset()); - - if (needCloseParen) - O << ')'; - - break; - } - case MachineOperand::MO_ExternalSymbol: - /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated - /// by _GLOBAL_OFFSET_TABLE_ on X86-32. All others are call operands, which - /// are pcrel_imm's. - assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel()); - // These are never used as memory operands. - assert(!(Modifier && !strcmp(Modifier, "mem"))); - - O << '$'; - O << TAI->getGlobalPrefix(); - O << MO.getSymbolName(); - break; - } - - switch (MO.getTargetFlags()) { - default: - assert(0 && "Unknown target flag on GV operand"); - case X86II::MO_NO_FLAG: - break; - case X86II::MO_GOT_ABSOLUTE_ADDRESS: - O << " + [.-"; - PrintPICBaseSymbol(); - O << ']'; - break; - case X86II::MO_PIC_BASE_OFFSET: - O << '-'; - PrintPICBaseSymbol(); - break; - case X86II::MO_TLSGD: O << "@TLSGD"; break; - case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; - case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; - case X86II::MO_TPOFF: O << "@TPOFF"; break; - case X86II::MO_NTPOFF: O << "@NTPOFF"; break; - case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; - case X86II::MO_GOT: O << "@GOT"; break; - case X86II::MO_GOTOFF: O << "@GOTOFF"; break; - } -} - -void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { - unsigned char value = MI->getOperand(Op).getImm(); - assert(value <= 7 && "Invalid ssecc argument!"); - switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; - } -} - -void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - MachineOperand BaseReg = MI->getOperand(Op); - MachineOperand IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - if (DispSpec.isGlobal() || - DispSpec.isCPI() || - DispSpec.isJTI() || - DispSpec.isSymbol()) { - printOperand(MI, Op+3, "mem"); - } else { - int DispVal = DispSpec.getImm(); - if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) - O << DispVal; - } - - if ((IndexReg.getReg() || BaseReg.getReg()) && - (Modifier == 0 || strcmp(Modifier, "no-rip"))) { - unsigned ScaleVal = MI->getOperand(Op+1).getImm(); - unsigned BaseRegOperand = 0, IndexRegOperand = 2; - - // There are cases where we can end up with ESP/RSP in the indexreg slot. - // If this happens, swap the base/index register to support assemblers that - // don't work when the index is *SP. - if (IndexReg.getReg() == X86::ESP || IndexReg.getReg() == X86::RSP) { - assert(ScaleVal == 1 && "Scale not supported for stack pointer!"); - std::swap(BaseReg, IndexReg); - std::swap(BaseRegOperand, IndexRegOperand); - } - - O << '('; - if (BaseReg.getReg()) - printOperand(MI, Op+BaseRegOperand, Modifier); - - if (IndexReg.getReg()) { - O << ','; - printOperand(MI, Op+IndexRegOperand, Modifier); - if (ScaleVal != 1) - O << ',' << ScaleVal; - } - O << ')'; - } -} - -void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - MachineOperand Segment = MI->getOperand(Op+4); - if (Segment.getReg()) { - printOperand(MI, Op+4, Modifier); - O << ':'; - } - printLeaMemReference(MI, Op, Modifier); -} - -void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) - return; - - // We don't need .set machinery if we have GOT-style relocations - if (Subtarget->isPICStyleGOT()) - return; - - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; - printBasicBlockLabel(MBB, false, false, false); - if (Subtarget->isPICStyleRIPRel()) - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '\n'; - else { - O << '-'; - PrintPICBaseSymbol(); - O << '\n'; - } -} - - -void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - PrintPICBaseSymbol(); - O << '\n'; - PrintPICBaseSymbol(); - O << ':'; -} - - -void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const -{ - const char *JTEntryDirective = MJTI->getEntrySize() == 4 ? - TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); - - O << JTEntryDirective << ' '; - - if (TM.getRelocationModel() == Reloc::PIC_) { - if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStub()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << uid << "_set_" << MBB->getNumber(); - } else if (Subtarget->isPICStyleGOT()) { - printBasicBlockLabel(MBB, false, false, false); - O << "@GOTOFF"; - } else - assert(0 && "Don't know how to print MBB label for this PIC mode"); - } else - printBasicBlockLabel(MBB, false, false, false); -} - -bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) { - unsigned Reg = MO.getReg(); - switch (Mode) { - default: return true; // Unknown mode. - case 'b': // Print QImode register - Reg = getX86SubSuperRegister(Reg, MVT::i8); - break; - case 'h': // Print QImode high register - Reg = getX86SubSuperRegister(Reg, MVT::i8, true); - break; - case 'w': // Print HImode register - Reg = getX86SubSuperRegister(Reg, MVT::i16); - break; - case 'k': // Print SImode register - Reg = getX86SubSuperRegister(Reg, MVT::i32); - break; - case 'q': // Print DImode register - Reg = getX86SubSuperRegister(Reg, MVT::i64); - break; - } - - O << '%'<< TRI->getAsmName(Reg); - return false; -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'c': // Don't print "$" before a global var name or constant. - printOperand(MI, OpNo, "mem"); - return false; - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print DImode register - if (MI->getOperand(OpNo).isReg()) - return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); - printOperand(MI, OpNo); - return false; - - case 'P': // Don't print @PLT, but do print as memory. - printOperand(MI, OpNo, "mem"); - return false; - - case 'n': { // Negate the immediate or print a '-' before the operand. - // Note: this is a temporary solution. It should be handled target - // independently as part of the 'MC' work. - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.isImm()) { - O << -MO.getImm(); - return false; - } - O << '-'; - } - } - } - - printOperand(MI, OpNo); - return false; -} - -bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print SImode register - // These only apply to registers, ignore on mem. - break; - case 'P': // Don't print @PLT, but do print as memory. - printMemReference(MI, OpNo, "no-rip"); - return false; - } - } - printMemReference(MI, OpNo); - return false; -} - -static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) { - // Convert registers in the addr mode according to subreg64. - for (unsigned i = 0; i != 4; ++i) { - if (!MI->getOperand(i).isReg()) continue; - - unsigned Reg = MI->getOperand(i).getReg(); - if (Reg == 0) continue; - - MI->getOperand(i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); - } -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction MI in -/// AT&T syntax to the current output stream. -/// -void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - if (NewAsmPrinter) { - if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { - O << "\t"; - printInlineAsm(MI); - return; - } else if (MI->isLabel()) { - printLabel(MI); - return; - } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) { - printDeclare(MI); - return; - } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - printImplicitDef(MI); - return; - } - - O << "NEW: "; - MCInst TmpInst; - - TmpInst.setOpcode(MI->getOpcode()); - - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - - MCOperand MCOp; - if (MO.isReg()) { - MCOp.MakeReg(MO.getReg()); - } else if (MO.isImm()) { - MCOp.MakeImm(MO.getImm()); - } else if (MO.isMBB()) { - MCOp.MakeMBBLabel(getFunctionNumber(), MO.getMBB()->getNumber()); - } else { - assert(0 && "Unimp"); - } - - TmpInst.addOperand(MCOp); - } - - switch (TmpInst.getOpcode()) { - case X86::LEA64_32r: - // Handle the 'subreg rewriting' for the lea64_32mem operand. - lower_lea64_32mem(&TmpInst, 1); - break; - } - - // FIXME: Convert TmpInst. - printInstruction(&TmpInst); - O << "OLD: "; - } - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -/// doInitialization -bool X86ATTAsmPrinter::doInitialization(Module &M) { - if (NewAsmPrinter) { - Context = new MCContext(); - // FIXME: Send this to "O" instead of outs(). For now, we force it to - // stdout to make it easy to compare. - Streamer = createAsmStreamer(*Context, outs()); - } - - return AsmPrinter::doInitialization(M); -} - -void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { - const TargetData *TD = TM.getTargetData(); - - if (!GVar->hasInitializer()) - return; // External global require no code - - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(GVar)) { - if (Subtarget->isTargetDarwin() && - TM.getRelocationModel() == Reloc::Static) { - if (GVar->getName() == "llvm.global_ctors") - O << ".reference .constructors_used\n"; - else if (GVar->getName() == "llvm.global_dtors") - O << ".reference .destructors_used\n"; - } - return; - } - - std::string name = Mang->getValueName(GVar); - Constant *C = GVar->getInitializer(); - if (isa(C) || isa(C)) - return; - const Type *Type = C->getType(); - unsigned Size = TD->getTypeAllocSize(Type); - unsigned Align = TD->getPreferredAlignmentLog(GVar); - - printVisibility(name, GVar->getVisibility()); - - if (Subtarget->isTargetELF()) - O << "\t.type\t" << name << ",@object\n"; - - SwitchToSection(TAI->SectionForGlobal(GVar)); - - if (C->isNullValue() && !GVar->hasSection() && - !(Subtarget->isTargetDarwin() && - TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) { - // FIXME: This seems to be pretty darwin-specific - if (GVar->hasExternalLinkage()) { - if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl " << name << '\n'; - O << Directive << "__DATA, __common, " << name << ", " - << Size << ", " << Align << '\n'; - return; - } - } - - if (!GVar->isThreadLocal() && - (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (TAI->getLCOMMDirective() != NULL) { - if (GVar->hasLocalLinkage()) { - O << TAI->getLCOMMDirective() << name << ',' << Size; - if (Subtarget->isTargetDarwin()) - O << ',' << Align; - } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) { - O << "\t.globl " << name << '\n' - << TAI->getWeakDefDirective() << name << '\n'; - EmitAlignment(Align, GVar); - O << name << ":"; - if (VerboseAsm) { - O << "\t\t\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - EmitGlobalConstant(C); - return; - } else { - O << TAI->getCOMMDirective() << name << ',' << Size; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - } else { - if (!Subtarget->isTargetCygMing()) { - if (GVar->hasLocalLinkage()) - O << "\t.local\t" << name << '\n'; - } - O << TAI->getCOMMDirective() << name << ',' << Size; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - if (VerboseAsm) { - O << "\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - return; - } - } - - switch (GVar->getLinkage()) { - case GlobalValue::CommonLinkage: - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - if (Subtarget->isTargetDarwin()) { - O << "\t.globl " << name << '\n' - << TAI->getWeakDefDirective() << name << '\n'; - } else if (Subtarget->isTargetCygMing()) { - O << "\t.globl\t" << name << "\n" - "\t.linkonce same_size\n"; - } else { - O << "\t.weak\t" << name << '\n'; - } - break; - case GlobalValue::DLLExportLinkage: - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.globl " << name << '\n'; - // FALL THROUGH - case GlobalValue::PrivateLinkage: - case GlobalValue::InternalLinkage: - break; - default: - assert(0 && "Unknown linkage type!"); - } - - EmitAlignment(Align, GVar); - O << name << ":"; - if (VerboseAsm){ - O << "\t\t\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << name << ", " << Size << '\n'; - - EmitGlobalConstant(C); -} - -bool X86ATTAsmPrinter::doFinalization(Module &M) { - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - printModuleLevelGV(I); - - if (I->hasDLLExportLinkage()) - DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),"")); - } - - if (Subtarget->isTargetDarwin()) { - SwitchToDataSection(""); - - // Add the (possibly multiple) personalities to the set of global value - // stubs. Only referenced functions get into the Personalities list. - if (TAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) { - const std::vector &Personalities = MMI->getPersonalities(); - for (unsigned i = 0, e = Personalities.size(); i != e; ++i) { - if (Personalities[i] == 0) - continue; - std::string Name = Mang->getValueName(Personalities[i]); - decorateName(Name, Personalities[i]); - GVStubs.insert(Name); - } - } - - // Output stubs for dynamically-linked functions - if (!FnStubs.empty()) { - for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end(); - I != E; ++I) { - SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," - "self_modifying_code+pure_instructions,5", 0); - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$stub"); - O << ":\n" - "\t.indirect_symbol " << Name << "\n" - "\thlt ; hlt ; hlt ; hlt ; hlt\n"; - } - O << '\n'; - } - - // Output stubs for external and common global variables. - if (!GVStubs.empty()) { - SwitchToDataSection( - "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); - for (StringSet<>::iterator I = GVStubs.begin(), E = GVStubs.end(); - I != E; ++I) { - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$non_lazy_ptr"); - O << ":\n\t.indirect_symbol " << Name << "\n\t.long\t0\n"; - } - } - - if (!HiddenGVStubs.empty()) { - SwitchToSection(TAI->getDataSection()); - EmitAlignment(2); - for (StringSet<>::iterator I = HiddenGVStubs.begin(), - E = HiddenGVStubs.end(); I != E; ++I) { - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$non_lazy_ptr"); - O << ":\n" << TAI->getData32bitsDirective() << Name << '\n'; - } - } - - // Funny Darwin hack: This flag tells the linker that no global symbols - // contain code that falls through to other global symbols (e.g. the obvious - // 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. - O << "\t.subsections_via_symbols\n"; - } else if (Subtarget->isTargetCygMing()) { - // Emit type information for external functions - for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i) { - O << "\t.def\t " << i->getKeyData() - << ";\t.scl\t" << COFF::C_EXT - << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) - << ";\t.endef\n"; - } - } - - - // Output linker support code for dllexported globals on windows. - if (!DLLExportedGVs.empty()) { - SwitchToDataSection(".section .drectve"); - - for (StringSet<>::iterator i = DLLExportedGVs.begin(), - e = DLLExportedGVs.end(); i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n"; - } - - if (!DLLExportedFns.empty()) { - SwitchToDataSection(".section .drectve"); - - for (StringSet<>::iterator i = DLLExportedFns.begin(), - e = DLLExportedFns.end(); - i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n"; - } - - // Do common shutdown. - bool Changed = AsmPrinter::doFinalization(M); - - if (NewAsmPrinter) { - Streamer->Finish(); - - delete Streamer; - delete Context; - Streamer = 0; - Context = 0; - } - - return Changed; -} - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter.inc" diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h deleted file mode 100644 index f47daf1..0000000 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h +++ /dev/null @@ -1,226 +0,0 @@ -//===-- X86ATTAsmPrinter.h - Convert X86 LLVM code to AT&T assembly -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// AT&T assembly code printer class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86ATTASMPRINTER_H -#define X86ATTASMPRINTER_H - -#include "../X86.h" -#include "../X86MachineFunctionInfo.h" -#include "../X86TargetMachine.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - -class MachineJumpTableInfo; -class MCContext; -class MCInst; -class MCStreamer; - -class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { - const X86Subtarget *Subtarget; - - MCContext *Context; - MCStreamer *Streamer; - public: - explicit X86ATTAsmPrinter(raw_ostream &O, X86TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V) { - Subtarget = &TM.getSubtarget(); - Context = 0; - Streamer = 0; - } - - virtual const char *getPassName() const { - return "X86 AT&T-Style Assembly Printer"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - if (Subtarget->isTargetDarwin() || - Subtarget->isTargetELF() || - Subtarget->isTargetCygMing()) { - AU.addRequired(); - } - AU.addRequired(); - AsmPrinter::getAnalysisUsage(AU); - } - - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - - // New MCInst printing stuff. - bool printInstruction(const MCInst *MI); - - void printOperand(const MCInst *MI, unsigned OpNo, - const char *Modifier = 0); - void printMemReference(const MCInst *MI, unsigned Op); - void printLeaMemReference(const MCInst *MI, unsigned Op); - void printSSECC(const MCInst *MI, unsigned Op); - void printPICLabel(const MCInst *MI, unsigned Op); - void print_pcrel_imm(const MCInst *MI, unsigned OpNo); - - void printi8mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi16mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi32mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi64mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi128mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf32mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf64mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf80mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf128mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printlea32mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - - - - // These methods are used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier = 0); - void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); - void printi8mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi16mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi32mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi64mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi128mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf32mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf64mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf128mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printlea32mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo, "subreg64"); - } - - bool printAsmMRegister(const MachineOperand &MO, char Mode); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - - void printMachineInstruction(const MachineInstr *MI); - void printSSECC(const MachineInstr *MI, unsigned Op); - void printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const { - AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); - } - void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const; - - void printPICLabel(const MachineInstr *MI, unsigned Op); - void printModuleLevelGV(const GlobalVariable* GVar); - - void PrintPICBaseSymbol() const; - - bool runOnMachineFunction(MachineFunction &F); - - void emitFunctionHeader(const MachineFunction &MF); - - // Necessary for Darwin to print out the apprioriate types of linker stubs - StringSet<> FnStubs, GVStubs, HiddenGVStubs; - - // Necessary for dllexport support - StringSet<> DLLExportedFns, DLLExportedGVs; - - // We have to propagate some information about MachineFunction to - // AsmPrinter. It's ok, when we're printing the function, since we have - // access to MachineFunction and can get the appropriate MachineFunctionInfo. - // Unfortunately, this is not possible when we're printing reference to - // Function (e.g. calling it and so on). Even more, there is no way to get the - // corresponding MachineFunctions: it can even be not created at all. That's - // why we should use additional structure, when we're collecting all necessary - // information. - // - // This structure is using e.g. for name decoration for stdcall & fastcall'ed - // function, since we have to use arguments' size for decoration. - typedef std::map FMFInfoMap; - FMFInfoMap FunctionInfoMap; - - void decorateName(std::string& Name, const GlobalValue* GV); -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp deleted file mode 100644 index 9d4df93..0000000 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp +++ /dev/null @@ -1,633 +0,0 @@ -//===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===// -// -// 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 Intel format assembly language. -// This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "X86IntelAsmPrinter.h" -#include "X86InstrInfo.h" -#include "X86TargetAsmInfo.h" -#include "X86.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetOptions.h" -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, - const TargetData *TD) { - X86MachineFunctionInfo Info; - uint64_t Size = 0; - - switch (F->getCallingConv()) { - case CallingConv::X86_StdCall: - Info.setDecorationStyle(StdCall); - break; - case CallingConv::X86_FastCall: - Info.setDecorationStyle(FastCall); - break; - default: - return Info; - } - - unsigned argNum = 1; - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI, ++argNum) { - const Type* Ty = AI->getType(); - - // 'Dereference' type in case of byval parameter attribute - if (F->paramHasAttr(argNum, Attribute::ByVal)) - Ty = cast(Ty)->getElementType(); - - // Size should be aligned to DWORD boundary - Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; - } - - // We're not supporting tooooo huge arguments :) - Info.setBytesToPopOnReturn((unsigned int)Size); - return Info; -} - - -/// decorateName - Query FunctionInfoMap and use this information for various -/// name decoration. -void X86IntelAsmPrinter::decorateName(std::string &Name, - const GlobalValue *GV) { - const Function *F = dyn_cast(GV); - if (!F) return; - - // We don't want to decorate non-stdcall or non-fastcall functions right now - unsigned CC = F->getCallingConv(); - if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) - return; - - FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); - - const X86MachineFunctionInfo *Info; - if (info_item == FunctionInfoMap.end()) { - // Calculate apropriate function info and populate map - FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); - Info = &FunctionInfoMap[F]; - } else { - Info = &info_item->second; - } - - const FunctionType *FT = F->getFunctionType(); - switch (Info->getDecorationStyle()) { - case None: - break; - case StdCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - break; - case FastCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - - if (Name[0] == '_') - Name[0] = '@'; - else - Name = '@' + Name; - - break; - default: - assert(0 && "Unsupported DecorationStyle"); - } -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - this->MF = &MF; - SetupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - const Function *F = MF.getFunction(); - unsigned CC = F->getCallingConv(); - unsigned FnAlign = MF.getAlignment(); - - // Populate function information map. Actually, We don't want to populate - // non-stdcall or non-fastcall functions' information right now. - if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) - FunctionInfoMap[F] = *MF.getInfo(); - - decorateName(CurrentFnName, F); - - SwitchToTextSection("_text", F); - switch (F->getLinkage()) { - default: assert(0 && "Unsupported linkage type!"); - case Function::PrivateLinkage: - case Function::InternalLinkage: - EmitAlignment(FnAlign); - break; - case Function::DLLExportLinkage: - DLLExportedFns.insert(CurrentFnName); - //FALLS THROUGH - case Function::ExternalLinkage: - O << "\tpublic " << CurrentFnName << "\n"; - EmitAlignment(FnAlign); - break; - } - - O << CurrentFnName << "\tproc near\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block if there are any predecessors. - if (!I->pred_empty()) { - printBasicBlockLabel(I, true, true); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - printMachineInstruction(II); - } - } - - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - O << CurrentFnName << "\tendp\n"; - - O.flush(); - - // We didn't modify anything. - return false; -} - -void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { - unsigned char value = MI->getOperand(Op).getImm(); - assert(value <= 7 && "Invalid ssecc argument!"); - switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; - } -} - -void X86IntelAsmPrinter::printOp(const MachineOperand &MO, - const char *Modifier) { - switch (MO.getType()) { - case MachineOperand::MO_Register: { - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { - unsigned Reg = MO.getReg(); - if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { - MVT VT = (strcmp(Modifier,"subreg64") == 0) ? - MVT::i64 : ((strcmp(Modifier, "subreg32") == 0) ? MVT::i32 : - ((strcmp(Modifier,"subreg16") == 0) ? MVT::i16 :MVT::i8)); - Reg = getX86SubSuperRegister(Reg, VT); - } - O << TRI->getName(Reg); - } else - O << "reg" << MO.getReg(); - return; - } - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_JumpTableIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << "OFFSET "; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << "_" << MO.getIndex(); - return; - } - case MachineOperand::MO_ConstantPoolIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << "OFFSET "; - O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getIndex(); - printOffset(MO.getOffset()); - O << "]"; - return; - } - case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - - decorateName(Name, GV); - - if (!isMemOp) O << "OFFSET "; - if (GV->hasDLLImportLinkage()) { - // FIXME: This should be fixed with full support of stdcall & fastcall - // CC's - O << "__imp_"; - } - O << Name; - printOffset(MO.getOffset()); - return; - } - case MachineOperand::MO_ExternalSymbol: { - O << TAI->getGlobalPrefix() << MO.getSymbolName(); - return; - } - default: - O << ""; return; - } -} - -void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo){ - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "Unknown pcrel immediate operand"); - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - - case MachineOperand::MO_GlobalAddress: { - GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - if (GV->hasDLLImportLinkage()) { - // FIXME: This should be fixed with full support of stdcall & fastcall - // CC's - O << "__imp_"; - } - O << Name; - printOffset(MO.getOffset()); - return; - } - - case MachineOperand::MO_ExternalSymbol: - O << TAI->getGlobalPrefix() << MO.getSymbolName(); - return; - } -} - - -void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr *MI, - unsigned Op, - const char *Modifier) { - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImm(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - O << "["; - bool NeedPlus = false; - if (BaseReg.getReg()) { - printOp(BaseReg, Modifier); - NeedPlus = true; - } - - if (IndexReg.getReg()) { - if (NeedPlus) O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg, Modifier); - NeedPlus = true; - } - - if (DispSpec.isGlobal() || DispSpec.isCPI() || - DispSpec.isJTI()) { - if (NeedPlus) - O << " + "; - printOp(DispSpec, "mem"); - } else { - int DispVal = DispSpec.getImm(); - if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { - if (NeedPlus) { - if (DispVal > 0) - O << " + "; - else { - O << " - "; - DispVal = -DispVal; - } - } - O << DispVal; - } - } - O << "]"; -} - -void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - MachineOperand Segment = MI->getOperand(Op+4); - if (Segment.getReg()) { - printOperand(MI, Op+4, Modifier); - O << ':'; - } - printLeaMemReference(MI, Op, Modifier); -} - -void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) - return; - - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; - printBasicBlockLabel(MBB, false, false, false); - O << '-' << "\"L" << getFunctionNumber() << "$pb\"'\n"; -} - -void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - O << "L" << getFunctionNumber() << "$pb\n"; - O << "L" << getFunctionNumber() << "$pb:"; -} - -bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, - const char Mode) { - unsigned Reg = MO.getReg(); - switch (Mode) { - default: return true; // Unknown mode. - case 'b': // Print QImode register - Reg = getX86SubSuperRegister(Reg, MVT::i8); - break; - case 'h': // Print QImode high register - Reg = getX86SubSuperRegister(Reg, MVT::i8, true); - break; - case 'w': // Print HImode register - Reg = getX86SubSuperRegister(Reg, MVT::i16); - break; - case 'k': // Print SImode register - Reg = getX86SubSuperRegister(Reg, MVT::i32); - break; - } - - O << TRI->getName(Reg); - return false; -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); - } - } - - printOperand(MI, OpNo); - return false; -} - -bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier. - printMemReference(MI, OpNo); - return false; -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -bool X86IntelAsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - - Mang->markCharUnacceptable('.'); - - O << "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n"; - - // Emit declarations for external functions. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->isDeclaration()) { - std::string Name = Mang->getValueName(I); - decorateName(Name, I); - - O << "\tEXTERN " ; - if (I->hasDLLImportLinkage()) { - O << "__imp_"; - } - O << Name << ":near\n"; - } - - // Emit declarations for external globals. Note that VC++ always declares - // external globals to have type byte, and if that's good enough for VC++... - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (I->isDeclaration()) { - std::string Name = Mang->getValueName(I); - - O << "\tEXTERN " ; - if (I->hasDLLImportLinkage()) { - O << "__imp_"; - } - O << Name << ":byte\n"; - } - } - - return Result; -} - -bool X86IntelAsmPrinter::doFinalization(Module &M) { - const TargetData *TD = TM.getTargetData(); - - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (I->isDeclaration()) continue; // External global require no code - - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(I)) - continue; - - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Align = TD->getPreferredAlignmentLog(I); - bool bCustomSegment = false; - - switch (I->getLinkage()) { - case GlobalValue::CommonLinkage: - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - SwitchToDataSection(""); - O << name << "?\tSEGEMNT PARA common 'COMMON'\n"; - bCustomSegment = true; - // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 - // are also available. - break; - case GlobalValue::AppendingLinkage: - SwitchToDataSection(""); - O << name << "?\tSEGMENT PARA public 'DATA'\n"; - bCustomSegment = true; - // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 - // are also available. - break; - case GlobalValue::DLLExportLinkage: - DLLExportedGVs.insert(name); - // FALL THROUGH - case GlobalValue::ExternalLinkage: - O << "\tpublic " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - SwitchToSection(TAI->getDataSection()); - break; - default: - assert(0 && "Unknown linkage type!"); - } - - if (!bCustomSegment) - EmitAlignment(Align, I); - - O << name << ":"; - if (VerboseAsm) - O << "\t\t\t\t" << TAI->getCommentString() - << " " << I->getName(); - O << '\n'; - - EmitGlobalConstant(C); - - if (bCustomSegment) - O << name << "?\tends\n"; - } - - // Output linker support code for dllexported globals - if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) { - SwitchToDataSection(""); - O << "; WARNING: The following code is valid only with MASM v8.x" - << "and (possible) higher\n" - << "; This version of MASM is usually shipped with Microsoft " - << "Visual Studio 2005\n" - << "; or (possible) further versions. Unfortunately, there is no " - << "way to support\n" - << "; dllexported symbols in the earlier versions of MASM in fully " - << "automatic way\n\n"; - O << "_drectve\t segment info alias('.drectve')\n"; - } - - for (StringSet<>::iterator i = DLLExportedGVs.begin(), - e = DLLExportedGVs.end(); - i != e; ++i) - O << "\t db ' /EXPORT:" << i->getKeyData() << ",data'\n"; - - for (StringSet<>::iterator i = DLLExportedFns.begin(), - e = DLLExportedFns.end(); - i != e; ++i) - O << "\t db ' /EXPORT:" << i->getKeyData() << "'\n"; - - if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) - O << "_drectve\t ends\n"; - - // Bypass X86SharedAsmPrinter::doFinalization(). - bool Result = AsmPrinter::doFinalization(M); - SwitchToDataSection(""); - O << "\tend\n"; - return Result; -} - -void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const { - unsigned NumElts = CVA->getNumOperands(); - if (NumElts) { - // ML does not have escape sequences except '' for '. It also has a maximum - // string length of 255. - unsigned len = 0; - bool inString = false; - for (unsigned i = 0; i < NumElts; i++) { - int n = cast(CVA->getOperand(i))->getZExtValue() & 255; - if (len == 0) - O << "\tdb "; - - if (n >= 32 && n <= 127) { - if (!inString) { - if (len > 0) { - O << ",'"; - len += 2; - } else { - O << "'"; - len++; - } - inString = true; - } - if (n == '\'') { - O << "'"; - len++; - } - O << char(n); - } else { - if (inString) { - O << "'"; - len++; - inString = false; - } - if (len > 0) { - O << ","; - len++; - } - O << n; - len += 1 + (n > 9) + (n > 99); - } - - if (len > 60) { - if (inString) { - O << "'"; - inString = false; - } - O << "\n"; - len = 0; - } - } - - if (len > 0) { - if (inString) - O << "'"; - O << "\n"; - } - } -} - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter1.inc" diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h deleted file mode 100644 index a724c3c..0000000 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h +++ /dev/null @@ -1,162 +0,0 @@ -//===-- X86IntelAsmPrinter.h - Convert X86 LLVM code to Intel assembly ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Intel assembly code printer class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86INTELASMPRINTER_H -#define X86INTELASMPRINTER_H - -#include "../X86.h" -#include "../X86MachineFunctionInfo.h" -#include "../X86TargetMachine.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -struct VISIBILITY_HIDDEN X86IntelAsmPrinter : public AsmPrinter { - explicit X86IntelAsmPrinter(raw_ostream &O, X86TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V) {} - - virtual const char *getPassName() const { - return "X86 Intel-Style Assembly Printer"; - } - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - // This method is used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier = 0) { - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.isReg()) { - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Not physreg??"); - O << TM.getRegisterInfo()->get(MO.getReg()).Name; // Capitalized names - } else { - printOp(MO, Modifier); - } - } - - void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); - - - void printi8mem(const MachineInstr *MI, unsigned OpNo) { - O << "BYTE PTR "; - printMemReference(MI, OpNo); - } - void printi16mem(const MachineInstr *MI, unsigned OpNo) { - O << "WORD PTR "; - printMemReference(MI, OpNo); - } - void printi32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printMemReference(MI, OpNo); - } - void printi64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printMemReference(MI, OpNo); - } - void printi128mem(const MachineInstr *MI, unsigned OpNo) { - O << "XMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printi256mem(const MachineInstr *MI, unsigned OpNo) { - O << "YMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printf32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printMemReference(MI, OpNo); - } - void printf64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printMemReference(MI, OpNo); - } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { - O << "XWORD PTR "; - printMemReference(MI, OpNo); - } - void printf128mem(const MachineInstr *MI, unsigned OpNo) { - O << "XMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printf256mem(const MachineInstr *MI, unsigned OpNo) { - O << "YMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printlea32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printLeaMemReference(MI, OpNo, "subreg64"); - } - - bool printAsmMRegister(const MachineOperand &MO, const char Mode); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, const char *Modifier = 0); - void printSSECC(const MachineInstr *MI, unsigned Op); - void printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const { - AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); - } - void printPICLabel(const MachineInstr *MI, unsigned Op); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - // We have to propagate some information about MachineFunction to - // AsmPrinter. It's ok, when we're printing the function, since we have - // access to MachineFunction and can get the appropriate MachineFunctionInfo. - // Unfortunately, this is not possible when we're printing reference to - // Function (e.g. calling it and so on). Even more, there is no way to get the - // corresponding MachineFunctions: it can even be not created at all. That's - // why we should use additional structure, when we're collecting all necessary - // information. - // - // This structure is using e.g. for name decoration for stdcall & fastcall'ed - // function, since we have to use arguments' size for decoration. - typedef std::map FMFInfoMap; - FMFInfoMap FunctionInfoMap; - - void decorateName(std::string& Name, const GlobalValue* GV); - - virtual void EmitString(const ConstantArray *CVA) const; - - // Necessary for dllexport support - StringSet<> DLLExportedFns, DLLExportedGVs; -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp deleted file mode 100644 index f49ca15..0000000 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ /dev/null @@ -1,429 +0,0 @@ -//===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the X86TargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "X86TargetAsmInfo.h" -#include "X86TargetMachine.h" -#include "X86Subtarget.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/Module.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Dwarf.h" - -using namespace llvm; -using namespace llvm::dwarf; - -const char *const llvm::x86_asm_table[] = { - "{si}", "S", - "{di}", "D", - "{ax}", "a", - "{cx}", "c", - "{memory}", "memory", - "{flags}", "", - "{dirflag}", "", - "{fpsr}", "", - "{cc}", "cc", - 0,0}; - -X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): - X86TargetAsmInfo(TM) { - const X86Subtarget* Subtarget = &TM.getSubtarget(); - bool is64Bit = Subtarget->is64Bit(); - - AlignmentIsInBytes = false; - TextAlignFillValue = 0x90; - - - if (!is64Bit) - Data64bitsDirective = 0; // we can't emit a 64-bit unit - ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. - ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill - if (TM.getRelocationModel() != Reloc::Static) - ConstantPoolSection = "\t.const_data"; - else - ConstantPoolSection = "\t.const\n"; - // FIXME: Why don't we always use this section? - if (is64Bit) - SixteenByteConstantSection = getUnnamedSection("\t.literal16\n", - SectionFlags::Mergeable); - LCOMMDirective = "\t.lcomm\t"; - // Leopard and above support aligned common symbols. - COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9); - HasDotTypeDotSizeDirective = false; - NonLocalEHFrameLabel = true; - if (is64Bit) { - PersonalityPrefix = ""; - PersonalitySuffix = "+4@GOTPCREL"; - } else { - PersonalityPrefix = "L"; - PersonalitySuffix = "$non_lazy_ptr"; - } - InlineAsmStart = "## InlineAsm Start"; - InlineAsmEnd = "## InlineAsm End"; - CommentString = "##"; - SetDirective = "\t.set"; - PCSymbol = "."; - UsedDirective = "\t.no_dead_strip\t"; - ProtectedDirective = "\t.globl\t"; - - SupportsDebugInformation = true; - - DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug"; - DwarfUsesInlineInfoSection = true; - - // Exceptions handling - SupportsExceptionHandling = true; - GlobalEHDirective = "\t.globl\t"; - SupportsWeakOmittedEHFrame = false; - AbsoluteEHSectionOffsets = false; - DwarfEHFrameSection = - ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; - DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; -} - -unsigned -X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - if (Reason == DwarfEncoding::Functions && Global) - return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); - else if (Reason == DwarfEncoding::CodeLabels || !Global) - return DW_EH_PE_pcrel; - else - return DW_EH_PE_absptr; -} - -const char * -X86DarwinTargetAsmInfo::getEHGlobalPrefix() const -{ - const X86Subtarget* Subtarget = &TM.getSubtarget(); - if (Subtarget->getDarwinVers() > 9) - return PrivateGlobalPrefix; - else - return ""; -} - -X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM): - X86TargetAsmInfo(TM) { - - CStringSection = ".rodata.str"; - PrivateGlobalPrefix = ".L"; - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - PCSymbol = "."; - - // Set up DWARF directives - HasLEB128 = true; // Target asm supports leb128 directives (little-endian) - - // Debug Information - AbsoluteDebugSectionOffsets = true; - SupportsDebugInformation = true; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; - DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; - DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; - DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; - DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; - DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; - DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; - DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; - - // Exceptions handling - SupportsExceptionHandling = true; - AbsoluteEHSectionOffsets = false; - DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits"; - DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits"; - - // On Linux we must declare when we can use a non-executable stack. - if (TM.getSubtarget().isLinux()) - NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits"; -} - -unsigned -X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - CodeModel::Model CM = TM.getCodeModel(); - bool is64Bit = TM.getSubtarget().is64Bit(); - - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned Format = 0; - - if (!is64Bit) - // 32 bit targets always encode pointers as 4 bytes - Format = DW_EH_PE_sdata4; - else { - // 64 bit targets encode pointers in 4 bytes iff: - // - code model is small OR - // - code model is medium and we're emitting externally visible symbols - // or any code symbols - if (CM == CodeModel::Small || - (CM == CodeModel::Medium && (Global || - Reason != DwarfEncoding::Data))) - Format = DW_EH_PE_sdata4; - else - Format = DW_EH_PE_sdata8; - } - - if (Global) - Format |= DW_EH_PE_indirect; - - return (Format | DW_EH_PE_pcrel); - } else { - if (is64Bit && - (CM == CodeModel::Small || - (CM == CodeModel::Medium && Reason != DwarfEncoding::Data))) - return DW_EH_PE_udata4; - else - return DW_EH_PE_absptr; - } -} - -X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM): - X86GenericTargetAsmInfo(TM) { - - GlobalPrefix = "_"; - LCOMMDirective = "\t.lcomm\t"; - COMMDirectiveTakesAlignment = false; - HasDotTypeDotSizeDirective = false; - HasSingleParameterDotFile = false; - StaticCtorsSection = "\t.section .ctors,\"aw\""; - StaticDtorsSection = "\t.section .dtors,\"aw\""; - HiddenDirective = NULL; - PrivateGlobalPrefix = "L"; // Prefix for private global symbols - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - - // Set up DWARF directives - HasLEB128 = true; // Target asm supports leb128 directives (little-endian) - AbsoluteDebugSectionOffsets = true; - AbsoluteEHSectionOffsets = false; - SupportsDebugInformation = true; - DwarfSectionOffsetDirective = "\t.secrel32\t"; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"dr\""; - DwarfInfoSection = "\t.section\t.debug_info,\"dr\""; - DwarfLineSection = "\t.section\t.debug_line,\"dr\""; - DwarfFrameSection = "\t.section\t.debug_frame,\"dr\""; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\""; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\""; - DwarfStrSection = "\t.section\t.debug_str,\"dr\""; - DwarfLocSection = "\t.section\t.debug_loc,\"dr\""; - DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\""; - DwarfRangesSection = "\t.section\t.debug_ranges,\"dr\""; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\""; -} - -unsigned -X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - CodeModel::Model CM = TM.getCodeModel(); - bool is64Bit = TM.getSubtarget().is64Bit(); - - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned Format = 0; - - if (!is64Bit) - // 32 bit targets always encode pointers as 4 bytes - Format = DW_EH_PE_sdata4; - else { - // 64 bit targets encode pointers in 4 bytes iff: - // - code model is small OR - // - code model is medium and we're emitting externally visible symbols - // or any code symbols - if (CM == CodeModel::Small || - (CM == CodeModel::Medium && (Global || - Reason != DwarfEncoding::Data))) - Format = DW_EH_PE_sdata4; - else - Format = DW_EH_PE_sdata8; - } - - if (Global) - Format |= DW_EH_PE_indirect; - - return (Format | DW_EH_PE_pcrel); - } else { - if (is64Bit && - (CM == CodeModel::Small || - (CM == CodeModel::Medium && Reason != DwarfEncoding::Data))) - return DW_EH_PE_udata4; - else - return DW_EH_PE_absptr; - } -} - -std::string -X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind kind) const { - switch (kind) { - case SectionKind::Text: - return ".text$linkonce" + GV->getName(); - case SectionKind::Data: - case SectionKind::BSS: - case SectionKind::ThreadData: - case SectionKind::ThreadBSS: - return ".data$linkonce" + GV->getName(); - case SectionKind::ROData: - case SectionKind::RODataMergeConst: - case SectionKind::RODataMergeStr: - return ".rdata$linkonce" + GV->getName(); - default: - assert(0 && "Unknown section kind"); - } - return NULL; -} - -std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const { - std::string Flags = ",\""; - - if (flags & SectionFlags::Code) - Flags += 'x'; - if (flags & SectionFlags::Writeable) - Flags += 'w'; - - Flags += "\""; - - return Flags; -} - -X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM): - X86GenericTargetAsmInfo(TM) { - GlobalPrefix = "_"; - CommentString = ";"; - - InlineAsmStart = "; InlineAsm Start"; - InlineAsmEnd = "; InlineAsm End"; - - PrivateGlobalPrefix = "$"; - AlignDirective = "\tALIGN\t"; - ZeroDirective = "\tdb\t"; - ZeroDirectiveSuffix = " dup(0)"; - AsciiDirective = "\tdb\t"; - AscizDirective = 0; - Data8bitsDirective = "\tdb\t"; - Data16bitsDirective = "\tdw\t"; - Data32bitsDirective = "\tdd\t"; - Data64bitsDirective = "\tdq\t"; - HasDotTypeDotSizeDirective = false; - HasSingleParameterDotFile = false; - - AlignmentIsInBytes = true; - - TextSection = getUnnamedSection("_text", SectionFlags::Code); - DataSection = getUnnamedSection("_data", SectionFlags::Writeable); - - JumpTableDataSection = NULL; - SwitchToSectionDirective = ""; - TextSectionStartSuffix = "\tSEGMENT PARA 'CODE'"; - DataSectionStartSuffix = "\tSEGMENT PARA 'DATA'"; - SectionEndDirectiveSuffix = "\tends\n"; -} - -template -bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const { - // FIXME: this should verify that we are targetting a 486 or better. If not, - // we will turn this bswap into something that will be lowered to logical ops - // instead of emitting the bswap asm. For now, we don't support 486 or lower - // so don't worry about this. - - // Verify this is a simple bswap. - if (CI->getNumOperands() != 2 || - CI->getType() != CI->getOperand(1)->getType() || - !CI->getType()->isInteger()) - return false; - - const IntegerType *Ty = dyn_cast(CI->getType()); - if (!Ty || Ty->getBitWidth() % 16 != 0) - return false; - - // Okay, we can do this xform, do so now. - const Type *Tys[] = { Ty }; - Module *M = CI->getParent()->getParent()->getParent(); - Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); - - Value *Op = CI->getOperand(1); - Op = CallInst::Create(Int, Op, CI->getName(), CI); - - CI->replaceAllUsesWith(Op); - CI->eraseFromParent(); - return true; -} - -template -bool X86TargetAsmInfo::ExpandInlineAsm(CallInst *CI) const { - InlineAsm *IA = cast(CI->getCalledValue()); - std::vector Constraints = IA->ParseConstraints(); - - std::string AsmStr = IA->getAsmString(); - - // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a" - std::vector AsmPieces; - SplitString(AsmStr, AsmPieces, "\n"); // ; as separator? - - switch (AsmPieces.size()) { - default: return false; - case 1: - AsmStr = AsmPieces[0]; - AsmPieces.clear(); - SplitString(AsmStr, AsmPieces, " \t"); // Split with whitespace. - - // bswap $0 - if (AsmPieces.size() == 2 && - (AsmPieces[0] == "bswap" || - AsmPieces[0] == "bswapq" || - AsmPieces[0] == "bswapl") && - (AsmPieces[1] == "$0" || - AsmPieces[1] == "${0:q}")) { - // No need to check constraints, nothing other than the equivalent of - // "=r,0" would be valid here. - return LowerToBSwap(CI); - } - // rorw $$8, ${0:w} --> llvm.bswap.i16 - if (CI->getType() == Type::Int16Ty && - AsmPieces.size() == 3 && - AsmPieces[0] == "rorw" && - AsmPieces[1] == "$$8," && - AsmPieces[2] == "${0:w}" && - IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") { - return LowerToBSwap(CI); - } - break; - case 3: - if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 && - Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && - Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { - // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64 - std::vector Words; - SplitString(AsmPieces[0], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { - Words.clear(); - SplitString(AsmPieces[1], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { - Words.clear(); - SplitString(AsmPieces[2], Words, " \t,"); - if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && - Words[2] == "%edx") { - return LowerToBSwap(CI); - } - } - } - } - break; - } - return false; -} - -// Instantiate default implementation. -TEMPLATE_INSTANTIATION(class X86TargetAsmInfo); diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h deleted file mode 100644 index f89171d..0000000 --- a/lib/Target/X86/X86TargetAsmInfo.h +++ /dev/null @@ -1,75 +0,0 @@ -//=====-- X86TargetAsmInfo.h - X86 asm properties -------------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the X86TargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86TARGETASMINFO_H -#define X86TARGETASMINFO_H - -#include "X86TargetMachine.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "llvm/Target/DarwinTargetAsmInfo.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - - extern const char *const x86_asm_table[]; - - template - struct X86TargetAsmInfo : public BaseTAI { - explicit X86TargetAsmInfo(const X86TargetMachine &TM): - BaseTAI(TM) { - const X86Subtarget *Subtarget = &TM.getSubtarget(); - - BaseTAI::AsmTransCBE = x86_asm_table; - BaseTAI::AssemblerDialect = Subtarget->getAsmFlavor(); - } - - virtual bool ExpandInlineAsm(CallInst *CI) const; - - private: - bool LowerToBSwap(CallInst *CI) const; - }; - - typedef X86TargetAsmInfo X86GenericTargetAsmInfo; - - EXTERN_TEMPLATE_INSTANTIATION(class X86TargetAsmInfo); - - struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo { - explicit X86DarwinTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - virtual const char *getEHGlobalPrefix() const; - }; - - struct X86ELFTargetAsmInfo : public X86TargetAsmInfo { - explicit X86ELFTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - }; - - struct X86COFFTargetAsmInfo : public X86GenericTargetAsmInfo { - explicit X86COFFTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind kind) const; - virtual std::string printSectionFlags(unsigned flags) const; - }; - - struct X86WinTargetAsmInfo : public X86GenericTargetAsmInfo { - explicit X86WinTargetAsmInfo(const X86TargetMachine &TM); - }; - -} // namespace llvm - -#endif -- cgit v1.1