Change errs() to dbgs().
[oota-llvm.git] / lib / Target / X86 / X86COFFMachineModuleInfo.cpp
1 //===-- llvm/CodeGen/X86COFFMachineModuleInfo.cpp -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is an MMI implementation for X86 COFF (windows) targets.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86COFFMachineModuleInfo.h"
15 #include "X86MachineFunctionInfo.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Function.h"
18 #include "llvm/Target/TargetData.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Support/raw_ostream.h"
21 using namespace llvm;
22
23 X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
24 }
25 X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
26   
27 }
28
29 void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
30                                             const X86MachineFunctionInfo &Val) {
31   FunctionInfoMap[F] = Val;
32 }
33
34
35
36 static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
37                                                     const TargetData &TD) {
38   X86MachineFunctionInfo Info;
39   uint64_t Size = 0;
40   
41   switch (F->getCallingConv()) {
42   case CallingConv::X86_StdCall:
43     Info.setDecorationStyle(StdCall);
44     break;
45   case CallingConv::X86_FastCall:
46     Info.setDecorationStyle(FastCall);
47     break;
48   default:
49     return Info;
50   }
51   
52   unsigned argNum = 1;
53   for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
54        AI != AE; ++AI, ++argNum) {
55     const Type* Ty = AI->getType();
56     
57     // 'Dereference' type in case of byval parameter attribute
58     if (F->paramHasAttr(argNum, Attribute::ByVal))
59       Ty = cast<PointerType>(Ty)->getElementType();
60     
61     // Size should be aligned to DWORD boundary
62     Size += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
63   }
64   
65   // We're not supporting tooooo huge arguments :)
66   Info.setBytesToPopOnReturn((unsigned int)Size);
67   return Info;
68 }
69
70
71 /// DecorateCygMingName - Query FunctionInfoMap and use this information for
72 /// various name decorations for Cygwin and MingW.
73 void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
74                                                    const GlobalValue *GV,
75                                                    const TargetData &TD) {
76   const Function *F = dyn_cast<Function>(GV);
77   if (!F) return;
78   
79   // Save function name for later type emission.
80   if (F->isDeclaration())
81     CygMingStubs.insert(StringRef(Name.data(), Name.size()));
82   
83   // We don't want to decorate non-stdcall or non-fastcall functions right now
84   CallingConv::ID CC = F->getCallingConv();
85   if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
86     return;
87   
88   const X86MachineFunctionInfo *Info;
89   
90   FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
91   if (info_item == FunctionInfoMap.end()) {
92     // Calculate apropriate function info and populate map
93     FunctionInfoMap[F] = calculateFunctionInfo(F, TD);
94     Info = &FunctionInfoMap[F];
95   } else {
96     Info = &info_item->second;
97   }
98   
99   if (Info->getDecorationStyle() == None) return;
100   const FunctionType *FT = F->getFunctionType();
101   
102   // "Pure" variadic functions do not receive @0 suffix.
103   if (!FT->isVarArg() || FT->getNumParams() == 0 ||
104       (FT->getNumParams() == 1 && F->hasStructRetAttr()))
105     raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
106   
107   if (Info->getDecorationStyle() == FastCall) {
108     if (Name[0] == '_')
109       Name[0] = '@';
110     else
111       Name.insert(Name.begin(), '@');
112   }    
113 }
114
115 /// DecorateCygMingName - Query FunctionInfoMap and use this information for
116 /// various name decorations for Cygwin and MingW.
117 void X86COFFMachineModuleInfo::DecorateCygMingName(std::string &Name,
118                                                    const GlobalValue *GV,
119                                                    const TargetData &TD) {
120   SmallString<128> NameStr(Name.begin(), Name.end());
121   DecorateCygMingName(NameStr, GV, TD);
122   Name.assign(NameStr.begin(), NameStr.end());
123 }