1e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//===-- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file ----===//
2e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//
3e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//                     The LLVM Compiler Infrastructure
4e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//
5e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes// This file is distributed under the University of Illinois Open Source
6e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes// License. See LICENSE.TXT for details.
7e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//
8e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//===----------------------------------------------------------------------===//
9e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//
10e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes// Hexagon Assembly printer class.
11e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//
12e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes//===----------------------------------------------------------------------===//
13e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
14e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#ifndef HEXAGONASMPRINTER_H
15e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#define HEXAGONASMPRINTER_H
16e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
17e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#include "Hexagon.h"
18e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#include "HexagonTargetMachine.h"
19e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#include "llvm/CodeGen/AsmPrinter.h"
20e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#include "llvm/Support/Compiler.h"
21e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#include "llvm/Support/raw_ostream.h"
22e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
23e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezesnamespace llvm {
24e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes  class HexagonAsmPrinter : public AsmPrinter {
25e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    const HexagonSubtarget *Subtarget;
26e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
27e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes  public:
28e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
29e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      : AsmPrinter(TM, Streamer) {
30e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      Subtarget = &TM.getSubtarget<HexagonSubtarget>();
31e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
32e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
33e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    virtual const char *getPassName() const {
34e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      return "Hexagon Assembly Printer";
35e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
36e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
37e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
38e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
39e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    virtual void EmitInstruction(const MachineInstr *MI);
40e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    virtual void EmitAlignment(unsigned NumBits,
41e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                               const GlobalValue *GV = 0) const;
42e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
43e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
44e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
45e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                         unsigned AsmVariant, const char *ExtraCode,
46e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                         raw_ostream &OS);
47e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
48e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                               unsigned AsmVariant, const char *ExtraCode,
49e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                               raw_ostream &OS);
50e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
51e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    /// printInstruction - This method is automatically generated by tablegen
52e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    /// from the instruction set description.  This method returns true if the
53e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    /// machine instruction was sufficiently described to print it, otherwise it
54e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    /// returns false.
55e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printInstruction(const MachineInstr *MI, raw_ostream &O);
56e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
57e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    //    void printMachineInstruction(const MachineInstr *MI);
58e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printOp(const MachineOperand &MO, raw_ostream &O);
59e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
60e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    /// printRegister - Print register according to target requirements.
61e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    ///
62e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printRegister(const MachineOperand &MO, bool R0AsZero,
63e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                       raw_ostream &O) {
64e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      unsigned RegNo = MO.getReg();
65e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
66e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << getRegisterName(RegNo);
67e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
68e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
69e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printImmOperand(const MachineInstr *MI, unsigned OpNo,
70e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                                raw_ostream &O) {
71e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      int value = MI->getOperand(OpNo).getImm();
72e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << value;
73e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
74e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
75e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printNegImmOperand(const MachineInstr *MI, unsigned OpNo,
76e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                                   raw_ostream &O) {
77e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      int value = MI->getOperand(OpNo).getImm();
78e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << -value;
79e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
80e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
81e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printMEMriOperand(const MachineInstr *MI, unsigned OpNo,
82e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                                  raw_ostream &O) {
83e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      const MachineOperand &MO1 = MI->getOperand(OpNo);
84e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      const MachineOperand &MO2 = MI->getOperand(OpNo+1);
85e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
86e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << getRegisterName(MO1.getReg())
87e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        << " + #"
88e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        << (int) MO2.getImm();
89e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
90e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
91e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printFrameIndexOperand(const MachineInstr *MI, unsigned OpNo,
92e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                                       raw_ostream &O) {
93e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      const MachineOperand &MO1 = MI->getOperand(OpNo);
94e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      const MachineOperand &MO2 = MI->getOperand(OpNo+1);
95e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
96e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << getRegisterName(MO1.getReg())
97e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        << ", #"
98e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        << MO2.getImm();
99e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
100e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
101e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
102e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                            raw_ostream &O) {
103e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      // Branches can take an immediate operand.  This is used by the branch
104e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      // selection pass to print $+8, an eight byte displacement from the PC.
105e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      if (MI->getOperand(OpNo).isImm()) {
106e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        O << "$+" << MI->getOperand(OpNo).getImm()*4;
107e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      } else {
108e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        printOp(MI->getOperand(OpNo), O);
109e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      }
110e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
111e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
112e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printCallOperand(const MachineInstr *MI, unsigned OpNo,
113e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                          raw_ostream &O) {
114e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
115e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
116e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
117e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                             raw_ostream &O) {
118e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
119e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
120e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
121e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << "#HI(";
122e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      if (MI->getOperand(OpNo).isImm()) {
123e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        printImmOperand(MI, OpNo, O);
124e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      }
125e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      else {
126e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        printOp(MI->getOperand(OpNo), O);
127e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      }
128e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << ")";
129e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
130e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
131e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
132e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << "#HI(";
133e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      if (MI->getOperand(OpNo).isImm()) {
134e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        printImmOperand(MI, OpNo, O);
135e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      }
136e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      else {
137e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes        printOp(MI->getOperand(OpNo), O);
138e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      }
139e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes      O << ")";
140e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    }
141e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
142e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
143e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                               raw_ostream &O);
144e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
145e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#if 0
146e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printModuleLevelGV(const GlobalVariable* GVar, raw_ostream &O);
147e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#endif
148e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
149e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo,
150e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes                                     raw_ostream &O);
151e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
152e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O);
153e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O);
154e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void printConstantPool(const MachineInstr *MI, int OpNo, raw_ostream &O);
155e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
156e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    static const char *getRegisterName(unsigned RegNo);
157e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
158e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#if 0
159e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes    void EmitStartOfAsmFile(Module &M);
160e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#endif
161e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes  };
162e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
163e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes} // end of llvm namespace
164e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes
165e5041e6fa8fa74a26e031b7487be1912257c87f1Evandro Menezes#endif
166