Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax -----==//
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
// This class prints an Sparc MCInst to a .s file.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "SparcInstPrinter.h"
14
#include "Sparc.h"
15
#include "llvm/MC/MCExpr.h"
16
#include "llvm/MC/MCInst.h"
17
#include "llvm/MC/MCRegisterInfo.h"
18
#include "llvm/MC/MCSubtargetInfo.h"
19
#include "llvm/MC/MCSymbol.h"
20
#include "llvm/Support/raw_ostream.h"
21
using namespace llvm;
22
23
#define DEBUG_TYPE "asm-printer"
24
25
// The generated AsmMatcher SparcGenAsmWriter uses "Sparc" as the target
26
// namespace. But SPARC backend uses "SP" as its namespace.
27
namespace llvm {
28
namespace Sparc {
29
  using namespace SP;
30
}
31
}
32
33
#define GET_INSTRUCTION_NAME
34
#define PRINT_ALIAS_INSTR
35
#include "SparcGenAsmWriter.inc"
36
37
6
bool SparcInstPrinter::isV9(const MCSubtargetInfo &STI) const {
38
6
  return (STI.getFeatureBits()[Sparc::FeatureV9]) != 0;
39
6
}
40
41
void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
42
32.3k
{
43
32.3k
  OS << '%' << StringRef(getRegisterName(RegNo)).lower();
44
32.3k
}
45
46
void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
47
18.6k
                                 StringRef Annot, const MCSubtargetInfo &STI) {
48
18.6k
  if (!printAliasInstr(MI, STI, O) && 
!printSparcAliasInstr(MI, STI, O)15.9k
)
49
15.9k
    printInstruction(MI, STI, O);
50
18.6k
  printAnnotation(O, Annot);
51
18.6k
}
52
53
bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI,
54
                                            const MCSubtargetInfo &STI,
55
15.9k
                                            raw_ostream &O) {
56
15.9k
  switch (MI->getOpcode()) {
57
15.9k
  
default: return false15.9k
;
58
15.9k
  case SP::JMPLrr:
59
29
  case SP::JMPLri: {
60
29
    if (MI->getNumOperands() != 3)
61
0
      return false;
62
29
    if (!MI->getOperand(0).isReg())
63
0
      return false;
64
29
    switch (MI->getOperand(0).getReg()) {
65
29
    
default: return false8
;
66
29
    case SP::G0: // jmp $addr | ret | retl
67
11
      if (MI->getOperand(2).isImm() &&
68
11
          
MI->getOperand(2).getImm() == 85
) {
69
4
        switch(MI->getOperand(1).getReg()) {
70
4
        
default: break2
;
71
4
        
case SP::I7: O << "\tret"; return true1
;
72
4
        
case SP::O7: O << "\tretl"; return true1
;
73
9
        }
74
9
      }
75
9
      O << "\tjmp "; printMemOperand(MI, 1, STI, O);
76
9
      return true;
77
10
    case SP::O7: // call $addr
78
10
      O << "\tcall "; printMemOperand(MI, 1, STI, O);
79
10
      return true;
80
0
    }
81
0
  }
82
6
  case SP::V9FCMPS:  case SP::V9FCMPD:  case SP::V9FCMPQ:
83
6
  case SP::V9FCMPES: case SP::V9FCMPED: case SP::V9FCMPEQ: {
84
6
    if (isV9(STI)
85
6
        || 
(MI->getNumOperands() != 3)0
86
6
        || 
(!MI->getOperand(0).isReg())0
87
6
        || 
(MI->getOperand(0).getReg() != SP::FCC0)0
)
88
6
      return false;
89
0
    // if V8, skip printing %fcc0.
90
0
    switch(MI->getOpcode()) {
91
0
    default:
92
0
    case SP::V9FCMPS:  O << "\tfcmps "; break;
93
0
    case SP::V9FCMPD:  O << "\tfcmpd "; break;
94
0
    case SP::V9FCMPQ:  O << "\tfcmpq "; break;
95
0
    case SP::V9FCMPES: O << "\tfcmpes "; break;
96
0
    case SP::V9FCMPED: O << "\tfcmped "; break;
97
0
    case SP::V9FCMPEQ: O << "\tfcmpeq "; break;
98
0
    }
99
0
    printOperand(MI, 1, STI, O);
100
0
    O << ", ";
101
0
    printOperand(MI, 2, STI, O);
102
0
    return true;
103
0
  }
104
15.9k
  }
105
15.9k
}
106
107
void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
108
                                    const MCSubtargetInfo &STI,
109
45.7k
                                    raw_ostream &O) {
110
45.7k
  const MCOperand &MO = MI->getOperand (opNum);
111
45.7k
112
45.7k
  if (MO.isReg()) {
113
31.9k
    printRegName(O, MO.getReg());
114
31.9k
    return ;
115
31.9k
  }
116
13.7k
117
13.7k
  if (MO.isImm()) {
118
12.1k
    switch (MI->getOpcode()) {
119
12.1k
      default:
120
12.0k
        O << (int)MO.getImm();
121
12.0k
        return;
122
12.1k
123
12.1k
      case SP::TICCri: // Fall through
124
126
      case SP::TICCrr: // Fall through
125
126
      case SP::TRAPri: // Fall through
126
126
      case SP::TRAPrr: // Fall through
127
126
      case SP::TXCCri: // Fall through
128
126
      case SP::TXCCrr: // Fall through
129
126
        // Only seven-bit values up to 127.
130
126
        O << ((int) MO.getImm() & 0x7f);
131
126
        return;
132
1.60k
    }
133
1.60k
  }
134
1.60k
135
1.60k
  assert(MO.isExpr() && "Unknown operand kind in printOperand");
136
1.60k
  MO.getExpr()->print(O, &MAI);
137
1.60k
}
138
139
void SparcInstPrinter::printMemOperand(const MCInst *MI, int opNum,
140
                                       const MCSubtargetInfo &STI,
141
10.9k
                                       raw_ostream &O, const char *Modifier) {
142
10.9k
  printOperand(MI, opNum, STI, O);
143
10.9k
144
10.9k
  // If this is an ADD operand, emit it like normal operands.
145
10.9k
  if (Modifier && 
!strcmp(Modifier, "arith")125
) {
146
125
    O << ", ";
147
125
    printOperand(MI, opNum+1, STI, O);
148
125
    return;
149
125
  }
150
10.8k
  const MCOperand &MO = MI->getOperand(opNum+1);
151
10.8k
152
10.8k
  if (MO.isReg() && 
MO.getReg() == SP::G0766
)
153
600
    return;   // don't print "+%g0"
154
10.2k
  if (MO.isImm() && 
MO.getImm() == 09.99k
)
155
28
    return;   // don't print "+0"
156
10.2k
157
10.2k
  O << "+";
158
10.2k
159
10.2k
  printOperand(MI, opNum+1, STI, O);
160
10.2k
}
161
162
void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum,
163
                                      const MCSubtargetInfo &STI,
164
382
                                      raw_ostream &O) {
165
382
  int CC = (int)MI->getOperand(opNum).getImm();
166
382
  switch (MI->getOpcode()) {
167
382
  
default: break97
;
168
382
  case SP::FBCOND:
169
180
  case SP::FBCONDA:
170
180
  case SP::BPFCC:
171
180
  case SP::BPFCCA:
172
180
  case SP::BPFCCNT:
173
180
  case SP::BPFCCANT:
174
180
  case SP::MOVFCCrr:  case SP::V9MOVFCCrr:
175
180
  case SP::MOVFCCri:  case SP::V9MOVFCCri:
176
180
  case SP::FMOVS_FCC: case SP::V9FMOVS_FCC:
177
180
  case SP::FMOVD_FCC: case SP::V9FMOVD_FCC:
178
180
  case SP::FMOVQ_FCC: case SP::V9FMOVQ_FCC:
179
180
    // Make sure CC is a fp conditional flag.
180
180
    CC = (CC < 16) ? 
(CC + 16)144
:
CC36
;
181
180
    break;
182
180
  case SP::CBCOND:
183
105
  case SP::CBCONDA:
184
105
    // Make sure CC is a cp conditional flag.
185
105
    CC = (CC < 32) ? (CC + 32) : 
CC0
;
186
105
    break;
187
382
  }
188
382
  O << SPARCCondCodeToString((SPCC::CondCodes)CC);
189
382
}
190
191
bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum,
192
                                   const MCSubtargetInfo &STI,
193
0
                                   raw_ostream &O) {
194
0
  llvm_unreachable("FIXME: Implement SparcInstPrinter::printGetPCX.");
195
0
  return true;
196
0
}
197
198
void SparcInstPrinter::printMembarTag(const MCInst *MI, int opNum,
199
                                      const MCSubtargetInfo &STI,
200
39
                                      raw_ostream &O) {
201
39
  static const char *const TagNames[] = {
202
39
      "#LoadLoad",  "#StoreLoad", "#LoadStore", "#StoreStore",
203
39
      "#Lookaside", "#MemIssue",  "#Sync"};
204
39
205
39
  unsigned Imm = MI->getOperand(opNum).getImm();
206
39
207
39
  if (Imm > 127) {
208
1
    O << Imm;
209
1
    return;
210
1
  }
211
38
212
38
  bool First = true;
213
304
  for (unsigned i = 0; i < sizeof(TagNames) / sizeof(char *); 
i++266
) {
214
266
    if (Imm & (1 << i)) {
215
148
      O << (First ? 
""38
:
" | "110
) << TagNames[i];
216
148
      First = false;
217
148
    }
218
266
  }
219
38
}