Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp
Line
Count
Source (jump to first uncovered line)
1
//=== HexagonMCELFStreamer.cpp - Hexagon subclass of MCELFStreamer -------===//
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 is a stub that parses a MCInst bundle and passes the
10
// instructions on to the real streamer.
11
//
12
//===----------------------------------------------------------------------===//
13
#define DEBUG_TYPE "hexagonmcelfstreamer"
14
15
#include "MCTargetDesc/HexagonMCELFStreamer.h"
16
#include "MCTargetDesc/HexagonMCInstrInfo.h"
17
#include "MCTargetDesc/HexagonMCShuffler.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/BinaryFormat/ELF.h"
20
#include "llvm/MC/MCAsmBackend.h"
21
#include "llvm/MC/MCAssembler.h"
22
#include "llvm/MC/MCCodeEmitter.h"
23
#include "llvm/MC/MCContext.h"
24
#include "llvm/MC/MCExpr.h"
25
#include "llvm/MC/MCInst.h"
26
#include "llvm/MC/MCObjectStreamer.h"
27
#include "llvm/MC/MCObjectWriter.h"
28
#include "llvm/MC/MCSection.h"
29
#include "llvm/MC/MCSectionELF.h"
30
#include "llvm/MC/MCStreamer.h"
31
#include "llvm/MC/MCSymbol.h"
32
#include "llvm/MC/MCSymbolELF.h"
33
#include "llvm/Support/Casting.h"
34
#include "llvm/Support/CommandLine.h"
35
#include "llvm/Support/ErrorHandling.h"
36
#include "llvm/Support/MathExtras.h"
37
#include <cassert>
38
#include <cstdint>
39
40
using namespace llvm;
41
42
static cl::opt<unsigned> GPSize
43
  ("gpsize", cl::NotHidden,
44
   cl::desc("Global Pointer Addressing Size.  The default size is 8."),
45
   cl::Prefix,
46
   cl::init(8));
47
48
HexagonMCELFStreamer::HexagonMCELFStreamer(
49
    MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
50
    std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter)
51
    : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)),
52
128
      MCII(createHexagonMCInstrInfo()) {}
53
54
HexagonMCELFStreamer::HexagonMCELFStreamer(
55
    MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
56
    std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
57
    MCAssembler *Assembler)
58
    : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)),
59
0
      MCII(createHexagonMCInstrInfo()) {}
60
61
void HexagonMCELFStreamer::EmitInstruction(const MCInst &MCB,
62
2.64k
                                           const MCSubtargetInfo &STI) {
63
2.64k
  assert(MCB.getOpcode() == Hexagon::BUNDLE);
64
2.64k
  assert(HexagonMCInstrInfo::bundleSize(MCB) <= HEXAGON_PACKET_SIZE);
65
2.64k
  assert(HexagonMCInstrInfo::bundleSize(MCB) > 0);
66
2.64k
67
2.64k
  // At this point, MCB is a bundle
68
2.64k
  // Iterate through the bundle and assign addends for the instructions
69
3.54k
  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
70
3.54k
    MCInst *MCI = const_cast<MCInst *>(I.getInst());
71
3.54k
    EmitSymbol(*MCI);
72
3.54k
  }
73
2.64k
74
2.64k
  MCObjectStreamer::EmitInstruction(MCB, STI);
75
2.64k
}
76
77
3.54k
void HexagonMCELFStreamer::EmitSymbol(const MCInst &Inst) {
78
3.54k
  // Scan for values.
79
13.6k
  for (unsigned i = Inst.getNumOperands(); i--;)
80
10.0k
    if (Inst.getOperand(i).isExpr())
81
1.85k
      visitUsedExpr(*Inst.getOperand(i).getExpr());
82
3.54k
}
83
84
// EmitCommonSymbol and EmitLocalCommonSymbol are extended versions of the
85
// functions found in MCELFStreamer.cpp taking AccessSize as an additional
86
// parameter.
87
void HexagonMCELFStreamer::HexagonMCEmitCommonSymbol(MCSymbol *Symbol,
88
                                                     uint64_t Size,
89
                                                     unsigned ByteAlignment,
90
6
                                                     unsigned AccessSize) {
91
6
  getAssembler().registerSymbol(*Symbol);
92
6
  StringRef sbss[4] = {".sbss.1", ".sbss.2", ".sbss.4", ".sbss.8"};
93
6
94
6
  auto ELFSymbol = cast<MCSymbolELF>(Symbol);
95
6
  if (!ELFSymbol->isBindingSet()) {
96
1
    ELFSymbol->setBinding(ELF::STB_GLOBAL);
97
1
    ELFSymbol->setExternal(true);
98
1
  }
99
6
100
6
  ELFSymbol->setType(ELF::STT_OBJECT);
101
6
102
6
  if (ELFSymbol->getBinding() == ELF::STB_LOCAL) {
103
4
    StringRef SectionName =
104
4
        ((AccessSize == 0) || (Size == 0) || (Size > GPSize))
105
4
            ? 
".bss"0
106
4
            : sbss[(Log2_64(AccessSize))];
107
4
    MCSection &Section = *getAssembler().getContext().getELFSection(
108
4
        SectionName, ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
109
4
    MCSectionSubPair P = getCurrentSection();
110
4
    SwitchSection(&Section);
111
4
112
4
    if (ELFSymbol->isUndefined()) {
113
4
      EmitValueToAlignment(ByteAlignment, 0, 1, 0);
114
4
      EmitLabel(Symbol);
115
4
      EmitZeros(Size);
116
4
    }
117
4
118
4
    // Update the maximum alignment of the section if necessary.
119
4
    if (ByteAlignment > Section.getAlignment())
120
0
      Section.setAlignment(ByteAlignment);
121
4
122
4
    SwitchSection(P.first, P.second);
123
4
  } else {
124
2
    if (ELFSymbol->declareCommon(Size, ByteAlignment))
125
0
      report_fatal_error("Symbol: " + Symbol->getName() +
126
0
                         " redeclared as different type");
127
2
    if ((AccessSize) && 
(Size <= GPSize)0
) {
128
0
      uint64_t SectionIndex =
129
0
          (AccessSize <= GPSize)
130
0
              ? ELF::SHN_HEXAGON_SCOMMON + (Log2_64(AccessSize) + 1)
131
0
              : (unsigned)ELF::SHN_HEXAGON_SCOMMON;
132
0
      ELFSymbol->setIndex(SectionIndex);
133
0
    }
134
2
  }
135
6
136
6
  ELFSymbol->setSize(MCConstantExpr::create(Size, getContext()));
137
6
}
138
139
void HexagonMCELFStreamer::HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol,
140
                                                         uint64_t Size,
141
                                                         unsigned ByteAlignment,
142
4
                                                         unsigned AccessSize) {
143
4
  getAssembler().registerSymbol(*Symbol);
144
4
  auto ELFSymbol = cast<MCSymbolELF>(Symbol);
145
4
  ELFSymbol->setBinding(ELF::STB_LOCAL);
146
4
  ELFSymbol->setExternal(false);
147
4
  HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, AccessSize);
148
4
}
149
150
151
namespace llvm {
152
MCStreamer *createHexagonELFStreamer(Triple const &TT, MCContext &Context,
153
                                     std::unique_ptr<MCAsmBackend> MAB,
154
                                     std::unique_ptr<MCObjectWriter> OW,
155
128
                                     std::unique_ptr<MCCodeEmitter> CE) {
156
128
  return new HexagonMCELFStreamer(Context, std::move(MAB), std::move(OW),
157
128
                                  std::move(CE));
158
128
  }
159
160
} // end namespace llvm