summaryrefslogtreecommitdiff
path: root/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h
blob: 0dd35a7aa366d101b7a5842bd8a37d8aa42af0fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//===-- 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 MCOperand;
class MCStreamer;
class MCSymbol;

class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
  const X86Subtarget *Subtarget;
 public:
  explicit X86ATTAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
                            const MCAsmInfo *T, bool V)
    : AsmPrinter(O, TM, T, V) {
    Subtarget = &TM.getSubtarget<X86Subtarget>();
  }

  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<MachineModuleInfo>();
    }
    AU.addRequired<DwarfWriter>();
    AsmPrinter::getAnalysisUsage(AU);
  }

  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.
  void printInstruction(const MachineInstr *MI);

  void printInstructionThroughMCStreamer(const MachineInstr *MI);

  
  // New MCInst printing stuff.
  void printInstruction(const MCInst *MI);
  MCSymbol *GetPICBaseSymbol();
  MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO);
  MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO);
  MCSymbol *GetJumpTableSymbol(const MachineOperand &MO);
  MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO);
  MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym);


  virtual void printMCInst(const MCInst *MI) { printInstruction(MI); }

  void printSymbolOperand(const MachineOperand &MO);
  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 printopaquemem(const MCInst *MI, unsigned OpNo) {
    printMemReference(MI, 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 printopaquemem(const MachineInstr *MI, unsigned OpNo) {
    printMemReference(MI, 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 PrintGlobalVariable(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
  StringMap<std::string> FnStubs, GVStubs, HiddenGVStubs;

  // Necessary for dllexport support
  StringSet<> CygMingStubs, 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<const Function*, X86MachineFunctionInfo> FMFInfoMap;
  FMFInfoMap FunctionInfoMap;

  void DecorateCygMingName(std::string &Name, const GlobalValue *GV);
  void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV);
};

} // end namespace llvm

#endif