Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Print MCInst instructions to .ptx format.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MCTargetDesc/NVPTXInstPrinter.h"
14
#include "MCTargetDesc/NVPTXBaseInfo.h"
15
#include "NVPTX.h"
16
#include "llvm/MC/MCExpr.h"
17
#include "llvm/MC/MCInst.h"
18
#include "llvm/MC/MCInstrInfo.h"
19
#include "llvm/MC/MCSubtargetInfo.h"
20
#include "llvm/MC/MCSymbol.h"
21
#include "llvm/Support/ErrorHandling.h"
22
#include "llvm/Support/FormattedStream.h"
23
#include <cctype>
24
using namespace llvm;
25
26
#define DEBUG_TYPE "asm-printer"
27
28
#include "NVPTXGenAsmWriter.inc"
29
30
NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31
                                   const MCRegisterInfo &MRI)
32
258
    : MCInstPrinter(MAI, MII, MRI) {}
33
34
18.1k
void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
35
18.1k
  // Decode the virtual register
36
18.1k
  // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
37
18.1k
  unsigned RCId = (RegNo >> 28);
38
18.1k
  switch (RCId) {
39
18.1k
  
default: report_fatal_error("Bad virtual register encoding")0
;
40
18.1k
  case 0:
41
207
    // This is actually a physical register, so defer to the autogenerated
42
207
    // register printer
43
207
    OS << getRegisterName(RegNo);
44
207
    return;
45
18.1k
  case 1:
46
884
    OS << "%p";
47
884
    break;
48
18.1k
  case 2:
49
1.75k
    OS << "%rs";
50
1.75k
    break;
51
18.1k
  case 3:
52
4.68k
    OS << "%r";
53
4.68k
    break;
54
18.1k
  case 4:
55
2.93k
    OS << "%rd";
56
2.93k
    break;
57
18.1k
  case 5:
58
3.36k
    OS << "%f";
59
3.36k
    break;
60
18.1k
  case 6:
61
624
    OS << "%fd";
62
624
    break;
63
18.1k
  case 7:
64
2.72k
    OS << "%h";
65
2.72k
    break;
66
18.1k
  case 8:
67
931
    OS << "%hh";
68
931
    break;
69
17.9k
  }
70
17.9k
71
17.9k
  unsigned VReg = RegNo & 0x0FFFFFFF;
72
17.9k
  OS << VReg;
73
17.9k
}
74
75
void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
76
13.4k
                                 StringRef Annot, const MCSubtargetInfo &STI) {
77
13.4k
  printInstruction(MI, OS);
78
13.4k
79
13.4k
  // Next always print the annotation.
80
13.4k
  printAnnotation(OS, Annot);
81
13.4k
}
82
83
void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
84
29.7k
                                    raw_ostream &O) {
85
29.7k
  const MCOperand &Op = MI->getOperand(OpNo);
86
29.7k
  if (Op.isReg()) {
87
18.1k
    unsigned Reg = Op.getReg();
88
18.1k
    printRegName(O, Reg);
89
18.1k
  } else 
if (11.6k
Op.isImm()11.6k
) {
90
8.44k
    O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
91
8.44k
  } else {
92
3.21k
    assert(Op.isExpr() && "Unknown operand kind in printOperand");
93
3.21k
    Op.getExpr()->print(O, &MAI);
94
3.21k
  }
95
29.7k
}
96
97
void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
98
3.48k
                                    const char *Modifier) {
99
3.48k
  const MCOperand &MO = MI->getOperand(OpNum);
100
3.48k
  int64_t Imm = MO.getImm();
101
3.48k
102
3.48k
  if (strcmp(Modifier, "ftz") == 0) {
103
1.16k
    // FTZ flag
104
1.16k
    if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
105
25
      O << ".ftz";
106
2.32k
  } else if (strcmp(Modifier, "sat") == 0) {
107
1.16k
    // SAT flag
108
1.16k
    if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
109
0
      O << ".sat";
110
1.16k
  } else if (strcmp(Modifier, "base") == 0) {
111
1.16k
    // Default operand
112
1.16k
    switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
113
1.16k
    default:
114
0
      return;
115
1.16k
    case NVPTX::PTXCvtMode::NONE:
116
711
      break;
117
1.16k
    case NVPTX::PTXCvtMode::RNI:
118
26
      O << ".rni";
119
26
      break;
120
1.16k
    case NVPTX::PTXCvtMode::RZI:
121
102
      O << ".rzi";
122
102
      break;
123
1.16k
    case NVPTX::PTXCvtMode::RMI:
124
23
      O << ".rmi";
125
23
      break;
126
1.16k
    case NVPTX::PTXCvtMode::RPI:
127
13
      O << ".rpi";
128
13
      break;
129
1.16k
    case NVPTX::PTXCvtMode::RN:
130
287
      O << ".rn";
131
287
      break;
132
1.16k
    case NVPTX::PTXCvtMode::RZ:
133
0
      O << ".rz";
134
0
      break;
135
1.16k
    case NVPTX::PTXCvtMode::RM:
136
0
      O << ".rm";
137
0
      break;
138
1.16k
    case NVPTX::PTXCvtMode::RP:
139
0
      O << ".rp";
140
0
      break;
141
0
    }
142
0
  } else {
143
0
    llvm_unreachable("Invalid conversion modifier");
144
0
  }
145
3.48k
}
146
147
void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
148
808
                                    const char *Modifier) {
149
808
  const MCOperand &MO = MI->getOperand(OpNum);
150
808
  int64_t Imm = MO.getImm();
151
808
152
808
  if (strcmp(Modifier, "ftz") == 0) {
153
404
    // FTZ flag
154
404
    if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
155
23
      O << ".ftz";
156
404
  } else if (strcmp(Modifier, "base") == 0) {
157
404
    switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
158
404
    default:
159
0
      return;
160
404
    case NVPTX::PTXCmpMode::EQ:
161
99
      O << ".eq";
162
99
      break;
163
404
    case NVPTX::PTXCmpMode::NE:
164
39
      O << ".ne";
165
39
      break;
166
404
    case NVPTX::PTXCmpMode::LT:
167
55
      O << ".lt";
168
55
      break;
169
404
    case NVPTX::PTXCmpMode::LE:
170
35
      O << ".le";
171
35
      break;
172
404
    case NVPTX::PTXCmpMode::GT:
173
44
      O << ".gt";
174
44
      break;
175
404
    case NVPTX::PTXCmpMode::GE:
176
27
      O << ".ge";
177
27
      break;
178
404
    case NVPTX::PTXCmpMode::LO:
179
0
      O << ".lo";
180
0
      break;
181
404
    case NVPTX::PTXCmpMode::LS:
182
0
      O << ".ls";
183
0
      break;
184
404
    case NVPTX::PTXCmpMode::HI:
185
0
      O << ".hi";
186
0
      break;
187
404
    case NVPTX::PTXCmpMode::HS:
188
0
      O << ".hs";
189
0
      break;
190
404
    case NVPTX::PTXCmpMode::EQU:
191
9
      O << ".equ";
192
9
      break;
193
404
    case NVPTX::PTXCmpMode::NEU:
194
42
      O << ".neu";
195
42
      break;
196
404
    case NVPTX::PTXCmpMode::LTU:
197
9
      O << ".ltu";
198
9
      break;
199
404
    case NVPTX::PTXCmpMode::LEU:
200
9
      O << ".leu";
201
9
      break;
202
404
    case NVPTX::PTXCmpMode::GTU:
203
9
      O << ".gtu";
204
9
      break;
205
404
    case NVPTX::PTXCmpMode::GEU:
206
9
      O << ".geu";
207
9
      break;
208
404
    case NVPTX::PTXCmpMode::NUM:
209
9
      O << ".num";
210
9
      break;
211
404
    case NVPTX::PTXCmpMode::NotANumber:
212
9
      O << ".nan";
213
9
      break;
214
0
    }
215
0
  } else {
216
0
    llvm_unreachable("Empty Modifier");
217
0
  }
218
808
}
219
220
void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
221
14.1k
                                     raw_ostream &O, const char *Modifier) {
222
14.1k
  if (Modifier) {
223
14.1k
    const MCOperand &MO = MI->getOperand(OpNum);
224
14.1k
    int Imm = (int) MO.getImm();
225
14.1k
    if (!strcmp(Modifier, "volatile")) {
226
3.53k
      if (Imm)
227
31
        O << ".volatile";
228
10.6k
    } else if (!strcmp(Modifier, "addsp")) {
229
3.53k
      switch (Imm) {
230
3.53k
      case NVPTX::PTXLdStInstCode::GLOBAL:
231
207
        O << ".global";
232
207
        break;
233
3.53k
      case NVPTX::PTXLdStInstCode::SHARED:
234
88
        O << ".shared";
235
88
        break;
236
3.53k
      case NVPTX::PTXLdStInstCode::LOCAL:
237
54
        O << ".local";
238
54
        break;
239
3.53k
      case NVPTX::PTXLdStInstCode::PARAM:
240
2.69k
        O << ".param";
241
2.69k
        break;
242
3.53k
      case NVPTX::PTXLdStInstCode::CONSTANT:
243
4
        O << ".const";
244
4
        break;
245
3.53k
      case NVPTX::PTXLdStInstCode::GENERIC:
246
487
        break;
247
3.53k
      default:
248
0
        llvm_unreachable("Wrong Address Space");
249
7.07k
      }
250
7.07k
    } else if (!strcmp(Modifier, "sign")) {
251
3.53k
      if (Imm == NVPTX::PTXLdStInstCode::Signed)
252
20
        O << "s";
253
3.51k
      else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
254
2.12k
        O << "u";
255
1.39k
      else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
256
745
        O << "b";
257
652
      else if (Imm == NVPTX::PTXLdStInstCode::Float)
258
652
        O << "f";
259
652
      else
260
652
        
llvm_unreachable0
("Unknown register type");
261
3.53k
    } else if (!strcmp(Modifier, "vec")) {
262
3.53k
      if (Imm == NVPTX::PTXLdStInstCode::V2)
263
143
        O << ".v2";
264
3.39k
      else if (Imm == NVPTX::PTXLdStInstCode::V4)
265
81
        O << ".v4";
266
3.53k
    } else
267
3.53k
      
llvm_unreachable0
("Unknown Modifier");
268
14.1k
  } else
269
14.1k
    
llvm_unreachable0
("Empty Modifier");
270
14.1k
}
271
272
void NVPTXInstPrinter::printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O,
273
0
                                    const char *Modifier) {
274
0
  const MCOperand &MO = MI->getOperand(OpNum);
275
0
  int Imm = (int)MO.getImm();
276
0
  if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {
277
0
    O << Imm; // Just print out PTX version
278
0
  } else if (strcmp(Modifier, "aligned") == 0) {
279
0
    // PTX63 requires '.aligned' in the name of the instruction.
280
0
    if (Imm >= 63)
281
0
      O << ".aligned";
282
0
  } else
283
0
    llvm_unreachable("Unknown Modifier");
284
0
}
285
286
void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
287
27
                                       raw_ostream &O, const char *Modifier) {
288
27
  printOperand(MI, OpNum, O);
289
27
290
27
  if (Modifier && 
!strcmp(Modifier, "add")22
) {
291
22
    O << ", ";
292
22
    printOperand(MI, OpNum + 1, O);
293
22
  } else {
294
5
    if (MI->getOperand(OpNum + 1).isImm() &&
295
5
        MI->getOperand(OpNum + 1).getImm() == 0)
296
0
      return; // don't print ',0' or '+0'
297
5
    O << "+";
298
5
    printOperand(MI, OpNum + 1, O);
299
5
  }
300
27
}
301
302
void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
303
1
                                       raw_ostream &O, const char *Modifier) {
304
1
  const MCOperand &Op = MI->getOperand(OpNum);
305
1
  assert(Op.isExpr() && "Call prototype is not an MCExpr?");
306
1
  const MCExpr *Expr = Op.getExpr();
307
1
  const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
308
1
  O << Sym.getName();
309
1
}