]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / MCTargetDesc / HexagonInstPrinter.cpp
1 //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This class prints an Hexagon MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "HexagonInstPrinter.h"
15 #include "HexagonAsmPrinter.h"
16 #include "MCTargetDesc/HexagonBaseInfo.h"
17 #include "MCTargetDesc/HexagonMCInstrInfo.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 using namespace llvm;
25
26 #define DEBUG_TYPE "asm-printer"
27
28 #define GET_INSTRUCTION_NAME
29 #include "HexagonGenAsmWriter.inc"
30
31 HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI,
32                                        MCInstrInfo const &MII,
33                                        MCRegisterInfo const &MRI)
34     : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) {
35 }
36
37 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
38   return MII.getName(Opcode);
39 }
40
41 void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
42   O << getRegName(RegNo);
43 }
44
45 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
46   return getRegisterName(RegNo);
47 }
48
49 void HexagonInstPrinter::setExtender(MCInst const &MCI) {
50   HasExtender = HexagonMCInstrInfo::isImmext(MCI);
51 }
52
53 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
54                                    StringRef Annot, const MCSubtargetInfo &STI) {
55   assert(HexagonMCInstrInfo::isBundle(*MI));
56   assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
57   assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
58   HasExtender = false;
59   for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
60     MCInst const &MCI = *I.getInst();
61     if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
62       printInstruction(MCI.getOperand(1).getInst(), OS);
63       OS << '\v';
64       HasExtender = false;
65       printInstruction(MCI.getOperand(0).getInst(), OS);
66     } else
67       printInstruction(&MCI, OS);
68     setExtender(MCI);
69     OS << "\n";
70   }
71
72   bool IsLoop0 = HexagonMCInstrInfo::isInnerLoop(*MI);
73   bool IsLoop1 = HexagonMCInstrInfo::isOuterLoop(*MI);
74   if (IsLoop0) {
75     OS << (IsLoop1 ? " :endloop01" : " :endloop0");
76   } else if (IsLoop1) {
77     OS << " :endloop1";
78   }
79 }
80
81 void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
82                                       raw_ostream &O) const {
83   if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
84       (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
85     O << "#";
86   MCOperand const &MO = MI->getOperand(OpNo);
87   if (MO.isReg()) {
88     O << getRegisterName(MO.getReg());
89   } else if (MO.isExpr()) {
90     int64_t Value;
91     if (MO.getExpr()->evaluateAsAbsolute(Value))
92       O << formatImm(Value);
93     else
94       O << *MO.getExpr();
95   } else {
96     llvm_unreachable("Unknown operand");
97   }
98 }
99
100 void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo,
101                                          raw_ostream &O) const {
102   printOperand(MI, OpNo, O);
103 }
104
105 void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI,
106                                                  unsigned OpNo,
107                                                  raw_ostream &O) const {
108   O << MI->getOperand(OpNo).getImm();
109 }
110
111 void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo,
112                                             raw_ostream &O) const {
113   O << -MI->getOperand(OpNo).getImm();
114 }
115
116 void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo,
117                                              raw_ostream &O) const {
118   O << -1;
119 }
120
121 void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo,
122                                             raw_ostream &O) const {
123   printOperand(MI, OpNo, O);
124 }
125
126 void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo,
127                                         raw_ostream &O) const {
128   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
129
130   printOperand(MI, OpNo, O);
131 }
132
133 void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo,
134                                            raw_ostream &O) const {
135   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
136
137   printOperand(MI, OpNo, O);
138 }
139
140 void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo,
141                                             raw_ostream &O) const {
142   // Branches can take an immediate operand.  This is used by the branch
143   // selection pass to print $+8, an eight byte displacement from the PC.
144   llvm_unreachable("Unknown branch operand.");
145 }
146
147 void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo,
148                                           raw_ostream &O) const {}
149
150 void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
151                                              raw_ostream &O) const {}
152
153 void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo,
154                                                raw_ostream &O) const {}
155
156 void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo,
157                                      raw_ostream &O, bool hi) const {
158   assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
159
160   O << '#' << (hi ? "HI" : "LO") << '(';
161   O << '#';
162   printOperand(MI, OpNo, O);
163   O << ')';
164 }
165
166 void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
167                                        raw_ostream &O) const {
168   MCOperand const &MO = MI->getOperand(OpNo);
169   assert (MO.isExpr());
170   MCExpr const &Expr = *MO.getExpr();
171   int64_t Value;
172   if (Expr.evaluateAsAbsolute(Value))
173     O << format("0x%" PRIx64, Value);
174   else {
175     if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
176       if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
177         O << "##";
178     O << Expr;
179   }
180 }