Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- RISCVAsmPrinter.cpp - RISCV LLVM assembly writer ------------------===//
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 file contains a printer that converts from our internal representation
10
// of machine-dependent LLVM code to the RISCV assembly language.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "RISCV.h"
15
#include "MCTargetDesc/RISCVInstPrinter.h"
16
#include "MCTargetDesc/RISCVMCExpr.h"
17
#include "RISCVTargetMachine.h"
18
#include "TargetInfo/RISCVTargetInfo.h"
19
#include "llvm/CodeGen/AsmPrinter.h"
20
#include "llvm/CodeGen/MachineConstantPool.h"
21
#include "llvm/CodeGen/MachineFunctionPass.h"
22
#include "llvm/CodeGen/MachineInstr.h"
23
#include "llvm/CodeGen/MachineModuleInfo.h"
24
#include "llvm/MC/MCAsmInfo.h"
25
#include "llvm/MC/MCInst.h"
26
#include "llvm/MC/MCStreamer.h"
27
#include "llvm/MC/MCSymbol.h"
28
#include "llvm/Support/TargetRegistry.h"
29
#include "llvm/Support/raw_ostream.h"
30
using namespace llvm;
31
32
#define DEBUG_TYPE "asm-printer"
33
34
namespace {
35
class RISCVAsmPrinter : public AsmPrinter {
36
public:
37
  explicit RISCVAsmPrinter(TargetMachine &TM,
38
                           std::unique_ptr<MCStreamer> Streamer)
39
329
      : AsmPrinter(TM, std::move(Streamer)) {}
40
41
3.35k
  StringRef getPassName() const override { return "RISCV Assembly Printer"; }
42
43
  void EmitInstruction(const MachineInstr *MI) override;
44
45
  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
46
                       const char *ExtraCode, raw_ostream &OS) override;
47
  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
48
                             const char *ExtraCode, raw_ostream &OS) override;
49
50
  void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
51
  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
52
                                   const MachineInstr *MI);
53
54
  // Wrapper needed for tblgenned pseudo lowering.
55
411
  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
56
411
    return LowerRISCVMachineOperandToMCOperand(MO, MCOp, *this);
57
411
  }
58
};
59
}
60
61
#define GEN_COMPRESS_INSTR
62
#include "RISCVGenCompressInstEmitter.inc"
63
37.5k
void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
64
37.5k
  MCInst CInst;
65
37.5k
  bool Res = compressInst(CInst, Inst, *TM.getMCSubtargetInfo(),
66
37.5k
                          OutStreamer->getContext());
67
37.5k
  AsmPrinter::EmitToStreamer(*OutStreamer, Res ? 
CInst44
:
Inst37.5k
);
68
37.5k
}
69
70
// Simple pseudo-instructions have their lowering (with expansion to real
71
// instructions) auto-generated.
72
#include "RISCVGenMCPseudoLowering.inc"
73
74
37.5k
void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
75
37.5k
  // Do any auto-generated pseudo lowerings.
76
37.5k
  if (emitPseudoExpansionLowering(*OutStreamer, MI))
77
3.71k
    return;
78
33.8k
79
33.8k
  MCInst TmpInst;
80
33.8k
  LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this);
81
33.8k
  EmitToStreamer(*OutStreamer, TmpInst);
82
33.8k
}
83
84
bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
85
56
                                      const char *ExtraCode, raw_ostream &OS) {
86
56
  // First try the generic code, which knows about modifiers like 'c' and 'n'.
87
56
  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
88
1
    return false;
89
55
90
55
  const MachineOperand &MO = MI->getOperand(OpNo);
91
55
  if (ExtraCode && 
ExtraCode[0]8
) {
92
8
    if (ExtraCode[1] != 0)
93
0
      return true; // Unknown modifier.
94
8
95
8
    switch (ExtraCode[0]) {
96
8
    default:
97
0
      return true; // Unknown modifier.
98
8
    case 'z':      // Print zero register if zero, regular printing otherwise.
99
4
      if (MO.isImm() && 
MO.getImm() == 00
) {
100
0
        OS << RISCVInstPrinter::getRegisterName(RISCV::X0);
101
0
        return false;
102
0
      }
103
4
      break;
104
4
    case 'i': // Literal 'i' if operand is not a register.
105
4
      if (!MO.isReg())
106
2
        OS << 'i';
107
4
      return false;
108
51
    }
109
51
  }
110
51
111
51
  switch (MO.getType()) {
112
51
  case MachineOperand::MO_Immediate:
113
14
    OS << MO.getImm();
114
14
    return false;
115
51
  case MachineOperand::MO_Register:
116
37
    OS << RISCVInstPrinter::getRegisterName(MO.getReg());
117
37
    return false;
118
51
  default:
119
0
    break;
120
0
  }
121
0
122
0
  return true;
123
0
}
124
125
bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
126
                                            unsigned OpNo,
127
                                            const char *ExtraCode,
128
2
                                            raw_ostream &OS) {
129
2
  if (!ExtraCode) {
130
2
    const MachineOperand &MO = MI->getOperand(OpNo);
131
2
    // For now, we only support register memory operands in registers and
132
2
    // assume there is no addend
133
2
    if (!MO.isReg())
134
0
      return true;
135
2
136
2
    OS << "0(" << RISCVInstPrinter::getRegisterName(MO.getReg()) << ")";
137
2
    return false;
138
2
  }
139
0
140
0
  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
141
0
}
142
143
// Force static initialization.
144
78.9k
extern "C" void LLVMInitializeRISCVAsmPrinter() {
145
78.9k
  RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
146
78.9k
  RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
147
78.9k
}