//===-- 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 "X86ATTInstPrinter.h"
#include "X86MCInstLower.h"
#include "X86.h"
#include "X86COFF.h"
#include "X86MachineFunctionInfo.h"
#include "X86TargetMachine.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
//===----------------------------------------------------------------------===//
// Primitive Helper Functions.
//===----------------------------------------------------------------------===//
void X86ATTAsmPrinter::printMCInst(const MCInst *MI) {
X86ATTInstPrinter(O, *MAI).printInstruction(MI);
}
void X86ATTAsmPrinter::PrintPICBaseSymbol() const {
// FIXME: Gross const cast hack.
X86ATTAsmPrinter *AP = const_cast<X86ATTAsmPrinter*>(this);
X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol()->print(O, MAI);
}
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<PointerType>(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;
}
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
/// various name decorations for Cygwin and MingW.
void X86ATTAsmPrinter::DecorateCygMingName(SmallVectorImpl<char> &Name,
const GlobalValue *GV) {
assert(Subtarget->isTargetCygMing() && "This is only for cygwin and mingw");
const Function *F = dyn_cast<Function>(GV);
if (!F) return;
// Save function name for later type emission.
if (F->isDeclaration())
CygMingStubs.insert(StringRef(Name.data(), Name.size()));
// We don't want to decorate non-stdcall or non-fastcall functions right now
CallingConv::ID CC = F->getCallingConv();
if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
return;
const X86MachineFunctionInfo *Info;
FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
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;
}
if (Info->getDecorationStyle() == None) return;
const FunctionType *FT = F->getFunctionType();
// "Pure" variadic functions do not receive @0 suffix.
if (!FT->isVarArg() || FT->getNumParams() == 0 ||
(FT->getNumParams() == 1 && F->hasStructRetAttr()))
raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
if