//===-- 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/Type.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineJumpTableInfo.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 std::string getPICLabelString(unsigned FnNum,
const TargetAsmInfo *TAI,
const X86Subtarget* Subtarget) {
std::string label;
if (Subtarget->isTargetDarwin())
label = "\"L" + utostr_32(FnNum) + "$pb\"";
else if (Subtarget->isTargetELF())
label = ".Lllvm$" + utostr_32(FnNum) + "." "$piclabel";
else
assert(0 && "Don't know how to print PIC label!\n");
return label;
}
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->getTypePaddedSize(Ty) + 3)/4)*4;
}
// We're not supporting tooooo huge arguments :)
Info.setBytesToPopOnReturn((unsigned int)Size);
return Info;
}
/// 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;
}
/// 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<Function>(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