HexagonAsmPrinter.cpp revision 31d157ae1ac2cd9c787dc3c1d28e64c682803844
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===//
2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//                     The LLVM Compiler Infrastructure
4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source
6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details.
7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
10b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file contains a printer that converts from our internal representation
11b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// of machine-dependent LLVM code to Hexagon assembly language. This printer is
12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// the output mechanism used by `llc'.
13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Documentation at http://developer.apple.com/documentation/DeveloperTools/
15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
18b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#define DEBUG_TYPE "asm-printer"
21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "Hexagon.h"
22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonTargetMachine.h"
23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonSubtarget.h"
24b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonMachineFunctionInfo.h"
25b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Constants.h"
26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/DerivedTypes.h"
27b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Module.h"
28b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Assembly/Writer.h"
29b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/AsmPrinter.h"
30b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineModuleInfo.h"
31b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunctionPass.h"
32b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineInstr.h"
33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineInstrBuilder.h"
34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MCStreamer.h"
35b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MCAsmInfo.h"
36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MCSymbol.h"
37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/MathExtras.h"
38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/MathExtras.h"
39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/CommandLine.h"
40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h"
41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Compiler.h"
42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/raw_ostream.h"
43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/Mangler.h"
44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetData.h"
45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetLoweringObjectFile.h"
46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetRegisterInfo.h"
47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetInstrInfo.h"
48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetOptions.h"
49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/ADT/SmallPtrSet.h"
50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/ADT/SmallString.h"
51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/ADT/StringExtras.h"
52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/TargetRegistry.h"
53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/raw_ostream.h"
54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm;
56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic cl::opt<bool> AlignCalls(
58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         "hexagon-align-calls", cl::Hidden, cl::init(true),
59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          cl::desc("Insert falign after call instruction for Hexagon target"));
60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumnamespace {
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  class HexagonAsmPrinter : public AsmPrinter {
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const HexagonSubtarget *Subtarget;
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  public:
67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      : AsmPrinter(TM, Streamer) {
69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Subtarget = &TM.getSubtarget<HexagonSubtarget>();
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual const char *getPassName() const {
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return "Hexagon Assembly Printer";
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// printInstruction - This method is automatically generated by tablegen
77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// from the instruction set description.  This method returns true if the
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// machine instruction was sufficiently described to print it, otherwise it
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printInstruction(const MachineInstr *MI, raw_ostream &O);
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual void EmitInstruction(const MachineInstr *MI);
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printOp(const MachineOperand &MO, raw_ostream &O);
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// printRegister - Print register according to target requirements.
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    ///
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printRegister(const MachineOperand &MO, bool R0AsZero,
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       raw_ostream &O) {
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned RegNo = MO.getReg();
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << getRegisterName(RegNo);
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS) {
94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO = MI->getOperand(OpNo);
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (MO.isReg()) {
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printRegister(MO, false, OS);
97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else if (MO.isImm()) {
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        OS << MO.getImm();
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printOp(MO, OS);
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         unsigned AsmVariant, const char *ExtraCode,
109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                         raw_ostream &OS);
110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               unsigned AsmVariant, const char *ExtraCode,
112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               raw_ostream &OS);
113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printHexagonImmOperand(const MachineInstr *MI, unsigned OpNo,
116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                raw_ostream &O) {
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      int value = MI->getOperand(OpNo).getImm();
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << value;
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printHexagonNegImmOperand(const MachineInstr *MI, unsigned OpNo,
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                   raw_ostream &O) {
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      int value = MI->getOperand(OpNo).getImm();
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << -value;
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
128ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    void printHexagonNOneImmOperand(const MachineInstr *MI, unsigned OpNo,
129ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                    raw_ostream &O) const {
130ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      O << -1;
131ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    }
132ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printHexagonMEMriOperand(const MachineInstr *MI, unsigned OpNo,
134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                  raw_ostream &O) {
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO1 = MI->getOperand(OpNo);
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO2 = MI->getOperand(OpNo+1);
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << getRegisterName(MO1.getReg())
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        << " + #"
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        << (int) MO2.getImm();
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printHexagonFrameIndexOperand(const MachineInstr *MI, unsigned OpNo,
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       raw_ostream &O) {
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO1 = MI->getOperand(OpNo);
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO2 = MI->getOperand(OpNo+1);
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << getRegisterName(MO1.getReg())
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        << ", #"
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        << MO2.getImm();
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            raw_ostream &O) {
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Branches can take an immediate operand.  This is used by the branch
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // selection pass to print $+8, an eight byte displacement from the PC.
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (MI->getOperand(OpNo).isImm()) {
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        O << "$+" << MI->getOperand(OpNo).getImm()*4;
160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printOp(MI->getOperand(OpNo), O);
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printCallOperand(const MachineInstr *MI, unsigned OpNo,
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          raw_ostream &O) {
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                            raw_ostream &O) {
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "#HI(";
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (MI->getOperand(OpNo).isImm()) {
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printHexagonImmOperand(MI, OpNo, O);
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printOp(MI->getOperand(OpNo), O);
180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << ")";
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "#HI(";
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (MI->getOperand(OpNo).isImm()) {
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printHexagonImmOperand(MI, OpNo, O);
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        printOp(MI->getOperand(OpNo), O);
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << ")";
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               raw_ostream &O);
196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo,
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     raw_ostream &O);
199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O);
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O);
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    static const char *getRegisterName(unsigned RegNo);
206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} // end of anonymous namespace
209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Include the auto-generated portion of the assembly writer.
211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonGenAsmWriter.inc"
212b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
213b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::EmitAlignment(unsigned NumBits,
215b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      const GlobalValue *GV) const {
216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
217b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For basic block level alignment, use falign.
218b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!GV) {
219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    OutStreamer.EmitRawText(StringRef("\t.falign"));
220b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  AsmPrinter::EmitAlignment(NumBits, GV);
224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  switch (MO.getType()) {
228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_Immediate:
229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    dbgs() << "printOp() does not handle immediate values\n";
230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    abort();
231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_MachineBasicBlock:
233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << *MO.getMBB()->getSymbol();
234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_JumpTableIndex:
236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << *GetJTISymbol(MO.getIndex());
237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // FIXME: PIC relocation model.
238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_ConstantPoolIndex:
240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << *GetCPISymbol(MO.getIndex());
241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_ExternalSymbol:
243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << *GetExternalSymbolSymbol(MO.getSymbolName());
244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  case MachineOperand::MO_GlobalAddress: {
246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Computing the address of a global symbol, not calling it.
247b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << *Mang->getSymbol(MO.getGlobal());
248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printOffset(MO.getOffset(), O);
249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  default:
253b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "<unknown operand type: " << MO.getType() << ">";
254b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return;
255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
259b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
260b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// isBlockOnlyReachableByFallthrough - We need to override this since the
261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// default AsmPrinter does not print labels for any basic block that
262b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// is only reachable by a fall through. That works for all cases except
263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// for the case in which the basic block is reachable by a fall through but
264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// through an indirect from a jump table. In this case, the jump table
265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// will contain a label not defined by AsmPrinter.
266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonAsmPrinter::
268b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MBB->hasAddressTaken()) {
270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// PrintAsmOperand - Print out an operand for an inline asm expression.
277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        unsigned AsmVariant,
280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        const char *ExtraCode,
281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      raw_ostream &OS) {
282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Does this asm operand have a single letter operand modifier?
283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (ExtraCode && ExtraCode[0]) {
284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ExtraCode[1] != 0) return true; // Unknown modifier.
285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    switch (ExtraCode[0]) {
287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    default: return true;  // Unknown modifier.
288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case 'c': // Don't print "$" before a global var name or constant.
289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Hexagon never has a prefix.
290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      printOperand(MI, OpNo, OS);
291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case 'L': // Write second word of DImode reference.
293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Verify that this operand has two consecutive registers.
294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (!MI->getOperand(OpNo).isReg() ||
295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          OpNo+1 == MI->getNumOperands() ||
296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          !MI->getOperand(OpNo+1).isReg())
297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        return true;
298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      ++OpNo;   // Return the high-part.
299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      break;
300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    case 'I':
301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Write 'i' if an integer constant, otherwise nothing.  Used to print
302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // addi vs add, etc.
303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (MI->getOperand(OpNo).isImm())
304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        OS << "i";
305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
308b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  printOperand(MI, OpNo, OS);
310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            unsigned OpNo, unsigned AsmVariant,
315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            const char *ExtraCode,
316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                            raw_ostream &O) {
317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (ExtraCode && ExtraCode[0])
318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return true; // Unknown modifier.
319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &Base  = MI->getOperand(OpNo);
321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &Offset = MI->getOperand(OpNo+1);
322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Base.isReg())
324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printOperand(MI, OpNo, O);
325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  else
326bc2198133a1836598b54b943420748e75d5dea94Craig Topper    llvm_unreachable("Unimplemented");
327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Offset.isImm()) {
329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (Offset.getImm())
330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << " + #" << Offset.getImm();
331b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
332b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  else
333bc2198133a1836598b54b943420748e75d5dea94Craig Topper    llvm_unreachable("Unimplemented");
334b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
335b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
336b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
337b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
338b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI,
339b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                              unsigned OpNo,
340b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                              raw_ostream &O) {
341bc2198133a1836598b54b943420748e75d5dea94Craig Topper  llvm_unreachable("Unimplemented");
342b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
345b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// the current output stream.
347b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
348b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
349b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  SmallString<128> Str;
350b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  raw_svector_ostream O(Str);
351b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
352b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineFunction* MF = MI->getParent()->getParent();
353b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const HexagonMachineFunctionInfo* MFI =
354b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    (const HexagonMachineFunctionInfo*)
355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MF->getInfo<HexagonMachineFunctionInfo>();
356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Print a brace for the beginning of the packet.
360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MFI->isStartPacket(MI)) {
361b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\t{" << '\n';
362b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
363b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
364b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DEBUG( O << "// MI = " << *MI << '\n';);
365b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Indent
367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  O << "\t";
368b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
370b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MI->getOpcode() == Hexagon::ENDLOOP0) {
371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (MFI->isEndPacket(MI) && MFI->isStartPacket(MI)) {
372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "\t{ nop }";
373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "}";
375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printInstruction(MI, O);
377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::STriwt) {
378b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
379b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle truncated store on Hexagon.
380b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
381b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemw(";
382b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printHexagonMEMriOperand(MI, 0, O);
383b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
384b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ") = ";
385b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned SubRegNum =
386b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      TM.getRegisterInfo()->getSubReg(MI->getOperand(2)
387b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      .getReg(), Hexagon::subreg_loreg);
388b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const char *SubRegName = getRegisterName(SubRegNum);
389b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << SubRegName << '\n';
390b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MPYI_rin) {
391b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle multipy with -ve constant on Hexagon:
392b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // "$dst =- mpyi($src1, #$src2)"
393b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      printOperand(MI, 0, O);
394b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << " =- mpyi(";
395b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printOperand(MI, 1, O);
396b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ", #";
397b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printHexagonNegImmOperand(MI, 2, O);
398b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ")";
399b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMw_ADDSUBi_indexed_MEM_V4) {
400b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
401b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memw(Rs+u6:2) [+-]= #U5
402b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemw("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
404b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
406b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
407b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
408b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
409b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMw_ADDSUBi_MEM_V4) {
410b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
411b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memw(Rs+u6:2) [+-]= #U5
412b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemw("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMh_ADDSUBi_indexed_MEM_V4) {
420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memh(Rs+u6:1) [+-]= #U5
422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemh("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMh_ADDSUBi_MEM_V4) {
430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
431b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memh(Rs+u6:1) [+-]= #U5
432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemh("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMb_ADDSUBi_indexed_MEM_V4) {
440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memb(Rs+u6:1) [+-]= #U5
442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemb("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::MEMb_ADDSUBi_MEM_V4) {
450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle memb(Rs+u6:1) [+-]= #U5
452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\tmemb("; printHexagonMEMriOperand(MI, 0, O); O << ") ";
454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int addend = MI->getOperand(2).getImm();
455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (addend < 0)
456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "-= " << "#" << -addend << '\n';
457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    else
458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      O << "+= " << "#" << addend << '\n';
459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::CMPbGTri_V4) {
460b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle Pd=cmpb.gt(Rs,#s8)
462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\t";
464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(0), false, O);
465b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << " = cmpb.gt(";
466b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(1), false, O);
467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ", ";
468b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int val = MI->getOperand(2).getImm() >> 24;
469b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "#" << val << ")" << '\n';
470b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::CMPhEQri_V4) {
471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
472b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle Pd=cmph.eq(Rs,#8)
473b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
474b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\t";
475b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(0), false, O);
476b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << " = cmph.eq(";
477b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(1), false, O);
478b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ", ";
479b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int val = MI->getOperand(2).getImm();
480b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert((((0 <= val) && (val <= 127)) ||
481b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            ((65408 <= val) && (val <= 65535))) &&
482b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           "Not in correct range!");
483b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (val >= 65408) val -= 65536;
484b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "#" << val << ")" << '\n';
485b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (MI->getOpcode() == Hexagon::CMPhGTri_V4) {
486b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Handle Pd=cmph.gt(Rs,#8)
488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\t";
490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(0), false, O);
491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << " = cmph.gt(";
492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printRegister(MI->getOperand(1), false, O);
493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << ", ";
494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int val = MI->getOperand(2).getImm() >> 16;
495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "#" << val << ")" << '\n';
496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    printInstruction(MI, O);
498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Print a brace for the end of the packet.
501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MFI->isEndPacket(MI) && MI->getOpcode() != Hexagon::ENDLOOP0) {
502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\n\t}" << '\n';
503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (AlignCalls && MI->getDesc().isCall()) {
506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << "\n\t.falign" << "\n";
507b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
508b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
509b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  OutStreamer.EmitRawText(O.str());
510b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return;
511b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
512b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
513b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// PrintUnmangledNameSafely - Print out the printable characters in the name.
514b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// Don't print things like \n or \0.
515b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
516b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
517b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//        Name != E; ++Name)
518b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//     if (isprint(*Name))
519b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//       OS << *Name;
520b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// }
521b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
522b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
523b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI,
524b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                                    int OpNo, raw_ostream &O) {
525b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &MO1 = MI->getOperand(OpNo);
526b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &MO2 = MI->getOperand(OpNo+1);
527b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
528b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  O << getRegisterName(MO1.getReg())
529b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    << " + #"
530b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    << MO2.getImm();
531b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
532b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
533b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
534b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo,
535b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           raw_ostream &O) {
536b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &MO = MI->getOperand(OpNo);
537b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  assert( (MO.getType() == MachineOperand::MO_GlobalAddress) &&
538b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         "Expecting global address");
539b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
540b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  O << *Mang->getSymbol(MO.getGlobal());
541b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MO.getOffset() != 0) {
542b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << " + ";
543b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    O << MO.getOffset();
544b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
545b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
546b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
547b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo,
548b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       raw_ostream &O) {
549b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand &MO = MI->getOperand(OpNo);
550b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) &&
551b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum	  "Expecting jump table index");
552b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
553b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Hexagon_TODO: Do we need name mangling?
554b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  O << *GetJTISymbol(MO.getIndex());
555b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
556b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
557b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumextern "C" void LLVMInitializeHexagonAsmPrinter() {
558b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget);
559b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
560