1252723Sdim//===-- ARMAsmPrinter.h - ARM implementation of AsmPrinter ------*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim
10218885Sdim#ifndef ARMASMPRINTER_H
11218885Sdim#define ARMASMPRINTER_H
12218885Sdim
13218885Sdim#include "ARM.h"
14218885Sdim#include "ARMTargetMachine.h"
15218885Sdim#include "llvm/CodeGen/AsmPrinter.h"
16218885Sdim#include "llvm/Support/Compiler.h"
17218885Sdim
18218885Sdimnamespace llvm {
19218885Sdim
20224145Sdimclass MCOperand;
21224145Sdim
22218885Sdimnamespace ARM {
23218885Sdim  enum DW_ISA {
24218885Sdim    DW_ISA_ARM_thumb = 1,
25218885Sdim    DW_ISA_ARM_arm = 2
26218885Sdim  };
27218885Sdim}
28218885Sdim
29218885Sdimclass LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
30218885Sdim
31218885Sdim  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
32218885Sdim  /// make the right decision when printing asm code for different targets.
33218885Sdim  const ARMSubtarget *Subtarget;
34218885Sdim
35218885Sdim  /// AFI - Keep a pointer to ARMFunctionInfo for the current
36218885Sdim  /// MachineFunction.
37218885Sdim  ARMFunctionInfo *AFI;
38218885Sdim
39218885Sdim  /// MCP - Keep a pointer to constantpool entries of the current
40218885Sdim  /// MachineFunction.
41218885Sdim  const MachineConstantPool *MCP;
42218885Sdim
43245431Sdim  /// InConstantPool - Maintain state when emitting a sequence of constant
44245431Sdim  /// pool entries so we can properly mark them as data regions.
45245431Sdim  bool InConstantPool;
46218885Sdimpublic:
47218885Sdim  explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
48245431Sdim    : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL), InConstantPool(false) {
49218885Sdim      Subtarget = &TM.getSubtarget<ARMSubtarget>();
50218885Sdim    }
51218885Sdim
52245431Sdim  virtual const char *getPassName() const LLVM_OVERRIDE {
53252723Sdim    return "ARM Assembly / Object Emitter";
54218885Sdim  }
55218885Sdim
56218885Sdim  void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
57218885Sdim                    const char *Modifier = 0);
58218885Sdim
59218885Sdim  virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
60218885Sdim                               unsigned AsmVariant, const char *ExtraCode,
61245431Sdim                               raw_ostream &O) LLVM_OVERRIDE;
62218885Sdim  virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
63245431Sdim                                     unsigned AsmVariant, const char *ExtraCode,
64245431Sdim                                     raw_ostream &O) LLVM_OVERRIDE;
65218885Sdim
66218885Sdim  void EmitJumpTable(const MachineInstr *MI);
67218885Sdim  void EmitJump2Table(const MachineInstr *MI);
68245431Sdim  virtual void EmitInstruction(const MachineInstr *MI) LLVM_OVERRIDE;
69245431Sdim  virtual bool runOnMachineFunction(MachineFunction &F) LLVM_OVERRIDE;
70218885Sdim
71245431Sdim  virtual void EmitConstantPool() LLVM_OVERRIDE {
72245431Sdim    // we emit constant pools customly!
73245431Sdim  }
74245431Sdim  virtual void EmitFunctionBodyEnd() LLVM_OVERRIDE;
75245431Sdim  virtual void EmitFunctionEntryLabel() LLVM_OVERRIDE;
76245431Sdim  virtual void EmitStartOfAsmFile(Module &M) LLVM_OVERRIDE;
77245431Sdim  virtual void EmitEndOfAsmFile(Module &M) LLVM_OVERRIDE;
78245431Sdim  virtual void EmitXXStructor(const Constant *CV) LLVM_OVERRIDE;
79218885Sdim
80224145Sdim  // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
81224145Sdim  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
82224145Sdim
83218885Sdimprivate:
84218885Sdim  // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
85218885Sdim  void emitAttributes();
86218885Sdim
87218885Sdim  // Helper for ELF .o only
88218885Sdim  void emitARMAttributeSection();
89218885Sdim
90218885Sdim  // Generic helper used to emit e.g. ARMv5 mul pseudos
91218885Sdim  void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
92218885Sdim
93221345Sdim  void EmitUnwindingInstruction(const MachineInstr *MI);
94221345Sdim
95224145Sdim  // emitPseudoExpansionLowering - tblgen'erated.
96224145Sdim  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
97224145Sdim                                   const MachineInstr *MI);
98224145Sdim
99218885Sdimpublic:
100221345Sdim  /// EmitDwarfRegOp - Emit dwarf register operation.
101263509Sdim  virtual void EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const
102263509Sdim      LLVM_OVERRIDE;
103221345Sdim
104245431Sdim  virtual unsigned getISAEncoding() LLVM_OVERRIDE {
105218885Sdim    // ARM/Darwin adds ISA to the DWARF info for each function.
106218885Sdim    if (!Subtarget->isTargetDarwin())
107218885Sdim      return 0;
108218885Sdim    return Subtarget->isThumb() ?
109235633Sdim      ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
110218885Sdim  }
111218885Sdim
112245431Sdimprivate:
113224145Sdim  MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
114218885Sdim  MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
115218885Sdim
116252723Sdim  MCSymbol *GetARMSJLJEHLabel() const;
117218885Sdim
118218885Sdim  MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
119224145Sdim
120245431Sdimpublic:
121218885Sdim  /// EmitMachineConstantPoolValue - Print a machine constantpool value to
122218885Sdim  /// the .s file.
123245431Sdim  virtual void
124245431Sdim    EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) LLVM_OVERRIDE;
125218885Sdim};
126218885Sdim} // end namespace llvm
127218885Sdim
128218885Sdim#endif
129