File: CSKYTargetStreamer.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (143 lines) | stat: -rw-r--r-- 4,707 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CSKYTargetStreamer.h"
#include "CSKYSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/FormattedStream.h"

using namespace llvm;

//
// ConstantPool implementation
//
// Emit the contents of the constant pool using the provided streamer.
void CSKYConstantPool::emitAll(MCStreamer &Streamer) {
  if (Entries.empty())
    return;

  if (CurrentSection != nullptr)
    Streamer.switchSection(CurrentSection);

  Streamer.emitDataRegion(MCDR_DataRegion);
  for (const ConstantPoolEntry &Entry : Entries) {
    Streamer.emitCodeAlignment(
        Align(Entry.Size),
        Streamer.getContext().getSubtargetInfo()); // align naturally
    Streamer.emitLabel(Entry.Label);
    Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
  }
  Streamer.emitDataRegion(MCDR_DataRegionEnd);
  Entries.clear();
}

const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer,
                                         const MCExpr *Value, unsigned Size,
                                         SMLoc Loc, const MCExpr *AdjustExpr) {
  if (CurrentSection == nullptr)
    CurrentSection = Streamer.getCurrentSectionOnly();

  auto &Context = Streamer.getContext();

  const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);

  // Check if there is existing entry for the same constant. If so, reuse it.
  auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
  if (Itr != CachedEntries.end())
    return Itr->second;

  MCSymbol *CPEntryLabel = Context.createTempSymbol();
  const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);

  if (AdjustExpr) {
    const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value);

    Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);
    Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);
    Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), Context);
  }

  Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));

  if (C)
    CachedEntries[C->getValue()] = SymRef;
  return SymRef;
}

bool CSKYConstantPool::empty() { return Entries.empty(); }

void CSKYConstantPool::clearCache() {
  CurrentSection = nullptr;
  CachedEntries.clear();
}

CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)
    : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}

const MCExpr *
CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc,
                                         const MCExpr *AdjustExpr) {
  auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid;
  ConstantCounter++;

  const MCExpr *OrigExpr = Expr;

  if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) {
    Expr = CE->getSubExpr();
    ELFRefKind = CE->getKind();
  }

  if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
    const MCSymbol *Sym = &SymExpr->getSymbol();

    SymbolIndex Index = {Sym, ELFRefKind};

    if (ConstantMap.find(Index) == ConstantMap.end()) {
      ConstantMap[Index] =
          ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);
    }
    return ConstantMap[Index];
  }

  return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);
}

void CSKYTargetStreamer::emitCurrentConstantPool() {
  ConstantPool->emitAll(Streamer);
  ConstantPool->clearCache();
}

// finish() - write out any non-empty assembler constant pools.
void CSKYTargetStreamer::finish() {
  if (ConstantCounter != 0) {
    ConstantPool->emitAll(Streamer);
  }

  finishAttributeSection();
}

void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}

void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,
                                           StringRef String) {}
void CSKYTargetStreamer::finishAttributeSection() {}

void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
  OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
}

void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
                                              StringRef String) {
  OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
}

void CSKYTargetAsmStreamer::finishAttributeSection() {}