126a5c4dd3176a7e3a7cc9601d32ccad8f41d3104Eli Bendersky//===-- ARMAsmPrinter.h - ARM implementation of AsmPrinter ------*- C++ -*-===//
2baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach//
3baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach//                     The LLVM Compiler Infrastructure
4baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach//
5baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach// This file is distributed under the University of Illinois Open Source
6baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach// License. See LICENSE.TXT for details.
7baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach//
8baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach//===----------------------------------------------------------------------===//
9baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
10baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#ifndef ARMASMPRINTER_H
11baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#define ARMASMPRINTER_H
12baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "ARMSubtarget.h"
14baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#include "llvm/CodeGen/AsmPrinter.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetMachine.h"
16baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
17baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachnamespace llvm {
18baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass ARMFunctionInfo;
2053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbachclass MCOperand;
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MachineConstantPool;
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MachineOperand;
2353e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
24baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachnamespace ARM {
25baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  enum DW_ISA {
26baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    DW_ISA_ARM_thumb = 1,
27baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    DW_ISA_ARM_arm = 2
28baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  };
29baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach}
30baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
31baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachclass LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
32baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
33baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
34baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// make the right decision when printing asm code for different targets.
35baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  const ARMSubtarget *Subtarget;
36baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
37baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// AFI - Keep a pointer to ARMFunctionInfo for the current
38baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// MachineFunction.
39baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  ARMFunctionInfo *AFI;
40baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
41baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// MCP - Keep a pointer to constantpool entries of the current
42baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// MachineFunction.
43baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  const MachineConstantPool *MCP;
44baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
453e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  /// InConstantPool - Maintain state when emitting a sequence of constant
463e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  /// pool entries so we can properly mark them as data regions.
473e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  bool InConstantPool;
48baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachpublic:
49baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : AsmPrinter(TM, Streamer), AFI(nullptr), MCP(nullptr),
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      InConstantPool(false) {
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Subtarget = &TM.getSubtarget<ARMSubtarget>();
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
54baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const char *getPassName() const override {
5626a5c4dd3176a7e3a7cc9601d32ccad8f41d3104Eli Bendersky    return "ARM Assembly / Object Emitter";
57baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  }
58baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
59baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    const char *Modifier = nullptr);
61baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       unsigned AsmVariant, const char *ExtraCode,
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       raw_ostream &O) override;
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             unsigned AsmVariant, const char *ExtraCode,
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             raw_ostream &O) override;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo *EndInfo) const override;
71baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
72baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  void EmitJumpTable(const MachineInstr *MI);
73baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  void EmitJump2Table(const MachineInstr *MI);
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitInstruction(const MachineInstr *MI) override;
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool runOnMachineFunction(MachineFunction &F) override;
76baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitConstantPool() override {
787747496736376c97d8bbf71302151287d1056abcCraig Topper    // we emit constant pools customly!
797747496736376c97d8bbf71302151287d1056abcCraig Topper  }
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFunctionBodyEnd() override;
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFunctionEntryLabel() override;
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitStartOfAsmFile(Module &M) override;
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitEndOfAsmFile(Module &M) override;
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitXXStructor(const Constant *CV) override;
85baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
8653e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
8753e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
8853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
89baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachprivate:
90baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
91baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  void emitAttributes();
92baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
934d7286083537833880901953d29786cf831affc4Anton Korobeynikov  // Generic helper used to emit e.g. ARMv5 mul pseudos
944d7286083537833880901953d29786cf831affc4Anton Korobeynikov  void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
954d7286083537833880901953d29786cf831affc4Anton Korobeynikov
9657caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov  void EmitUnwindingInstruction(const MachineInstr *MI);
9757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov
9853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  // emitPseudoExpansionLowering - tblgen'erated.
9953e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
10053e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach                                   const MachineInstr *MI);
10153e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
102baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbachpublic:
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getISAEncoding() override {
104baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    // ARM/Darwin adds ISA to the DWARF info for each function.
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!Subtarget->isTargetMachO())
106baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach      return 0;
107baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach    return Subtarget->isThumb() ?
108c89c744b69cecac576317a98322fd295e36e9886Craig Topper      ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
109baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  }
110baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
1117747496736376c97d8bbf71302151287d1056abcCraig Topperprivate:
11253e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach  MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
113baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
114baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
11579c07d2a36282b09b9c5d0aa65ebf4bff017621bDmitri Gribenko  MCSymbol *GetARMSJLJEHLabel() const;
116baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbol *GetARMGVSymbol(const GlobalValue *GV, unsigned char TargetFlags);
11853e3fc463e3d9ee840510b08ebd6db17694fa2c5Jim Grosbach
1197747496736376c97d8bbf71302151287d1056abcCraig Topperpublic:
120baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// EmitMachineConstantPoolValue - Print a machine constantpool value to
121baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach  /// the .s file.
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
123baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach};
124baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach} // end namespace llvm
125baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach
126baf120fbe8056ef68fc91b16465590fdf2311c27Jim Grosbach#endif
127