/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 526 | : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) { |
35 | 526 | } |
36 | | |
37 | 0 | StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { |
38 | 0 | return MII.getName(Opcode); |
39 | 0 | } |
40 | | |
41 | 4.52k | void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { |
42 | 4.52k | O << getRegName(RegNo); |
43 | 4.52k | } |
44 | | |
45 | 4.52k | StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { |
46 | 4.52k | return getRegisterName(RegNo); |
47 | 4.52k | } |
48 | | |
49 | 27.2k | void HexagonInstPrinter::setExtender(MCInst const &MCI) { |
50 | 27.2k | HasExtender = HexagonMCInstrInfo::isImmext(MCI); |
51 | 27.2k | } |
52 | | |
53 | | void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, |
54 | 20.5k | StringRef Annot, const MCSubtargetInfo &STI) { |
55 | 20.5k | assert(HexagonMCInstrInfo::isBundle(*MI)); |
56 | 20.5k | assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE); |
57 | 20.5k | assert(HexagonMCInstrInfo::bundleSize(*MI) > 0); |
58 | 20.5k | HasExtender = false; |
59 | 27.2k | for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) { |
60 | 27.2k | MCInst const &MCI = *I.getInst(); |
61 | 27.2k | if (HexagonMCInstrInfo::isDuplex(MII, MCI)27.2k ) { |
62 | 484 | printInstruction(MCI.getOperand(1).getInst(), OS); |
63 | 484 | OS << '\v'; |
64 | 484 | HasExtender = false; |
65 | 484 | printInstruction(MCI.getOperand(0).getInst(), OS); |
66 | 484 | } else |
67 | 26.7k | printInstruction(&MCI, OS); |
68 | 27.2k | setExtender(MCI); |
69 | 27.2k | OS << "\n"; |
70 | 27.2k | } |
71 | 20.5k | |
72 | 20.5k | auto Separator = ""; |
73 | 20.5k | if (HexagonMCInstrInfo::isInnerLoop(*MI)20.5k ) { |
74 | 134 | OS << Separator; |
75 | 134 | Separator = " "; |
76 | 134 | MCInst ME; |
77 | 134 | ME.setOpcode(Hexagon::ENDLOOP0); |
78 | 134 | printInstruction(&ME, OS); |
79 | 134 | } |
80 | 20.5k | if (HexagonMCInstrInfo::isOuterLoop(*MI)20.5k ) { |
81 | 10 | OS << Separator; |
82 | 10 | MCInst ME; |
83 | 10 | ME.setOpcode(Hexagon::ENDLOOP1); |
84 | 10 | printInstruction(&ME, OS); |
85 | 10 | } |
86 | 20.5k | } |
87 | | |
88 | | void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo, |
89 | 64.7k | raw_ostream &O) const { |
90 | 64.7k | if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo && |
91 | 24.8k | (HasExtender || 24.8k HexagonMCInstrInfo::isConstExtended(MII, *MI)23.7k )) |
92 | 1.07k | O << "#"; |
93 | 64.7k | MCOperand const &MO = MI->getOperand(OpNo); |
94 | 64.7k | if (MO.isReg()64.7k ) { |
95 | 49.2k | O << getRegisterName(MO.getReg()); |
96 | 64.7k | } else if (15.5k MO.isExpr()15.5k ) { |
97 | 15.5k | int64_t Value; |
98 | 15.5k | if (MO.getExpr()->evaluateAsAbsolute(Value)) |
99 | 14.3k | O << formatImm(Value); |
100 | 15.5k | else |
101 | 1.16k | O << *MO.getExpr(); |
102 | 0 | } else { |
103 | 0 | llvm_unreachable("Unknown operand"); |
104 | 15.5k | } |
105 | 64.7k | } |
106 | | |
107 | | void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo, |
108 | 0 | raw_ostream &O) const { |
109 | 0 | printOperand(MI, OpNo, O); |
110 | 0 | } |
111 | | |
112 | | void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI, |
113 | | unsigned OpNo, |
114 | 0 | raw_ostream &O) const { |
115 | 0 | O << MI->getOperand(OpNo).getImm(); |
116 | 0 | } |
117 | | |
118 | | void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo, |
119 | 0 | raw_ostream &O) const { |
120 | 0 | O << -MI->getOperand(OpNo).getImm(); |
121 | 0 | } |
122 | | |
123 | | void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo, |
124 | 0 | raw_ostream &O) const { |
125 | 0 | O << -1; |
126 | 0 | } |
127 | | |
128 | | void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo, |
129 | 0 | raw_ostream &O) const { |
130 | 0 | printOperand(MI, OpNo, O); |
131 | 0 | } |
132 | | |
133 | | void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo, |
134 | 0 | raw_ostream &O) const { |
135 | 0 | assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); |
136 | 0 |
|
137 | 0 | printOperand(MI, OpNo, O); |
138 | 0 | } |
139 | | |
140 | | void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo, |
141 | 0 | raw_ostream &O) const { |
142 | 0 | assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); |
143 | 0 |
|
144 | 0 | printOperand(MI, OpNo, O); |
145 | 0 | } |
146 | | |
147 | | void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo, |
148 | 0 | raw_ostream &O) const { |
149 | 0 | // Branches can take an immediate operand. This is used by the branch |
150 | 0 | // selection pass to print $+8, an eight byte displacement from the PC. |
151 | 0 | llvm_unreachable("Unknown branch operand."); |
152 | 0 | } |
153 | | |
154 | | void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo, |
155 | 0 | raw_ostream &O) const {} |
156 | | |
157 | | void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo, |
158 | 0 | raw_ostream &O) const {} |
159 | | |
160 | | void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo, |
161 | 0 | raw_ostream &O) const {} |
162 | | |
163 | | void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo, |
164 | 0 | raw_ostream &O, bool hi) const { |
165 | 0 | assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); |
166 | 0 |
|
167 | 0 | O << '#' << (hi ? "HI"0 : "LO"0 ) << '('; |
168 | 0 | O << '#'; |
169 | 0 | printOperand(MI, OpNo, O); |
170 | 0 | O << ')'; |
171 | 0 | } |
172 | | |
173 | | void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo, |
174 | 1.04k | raw_ostream &O) const { |
175 | 1.04k | MCOperand const &MO = MI->getOperand(OpNo); |
176 | 1.04k | assert (MO.isExpr()); |
177 | 1.04k | MCExpr const &Expr = *MO.getExpr(); |
178 | 1.04k | int64_t Value; |
179 | 1.04k | if (Expr.evaluateAsAbsolute(Value)) |
180 | 314 | O << format("0x%" PRIx64, Value); |
181 | 728 | else { |
182 | 728 | if (HasExtender || 728 HexagonMCInstrInfo::isConstExtended(MII, *MI)719 ) |
183 | 9 | if (9 HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo9 ) |
184 | 9 | O << "##"; |
185 | 728 | O << Expr; |
186 | 728 | } |
187 | 1.04k | } |