Coverage Report

Created: 2023-09-25 06:27

/src/keystone/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file provides PowerPC specific target descriptions.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "PPCMCTargetDesc.h"
15
#include "llvm/ADT/STLExtras.h"
16
#include "PPCMCAsmInfo.h"
17
#include "PPCTargetStreamer.h"
18
#include "llvm/MC/MCContext.h"
19
#include "llvm/MC/MCELFStreamer.h"
20
#include "llvm/MC/MCExpr.h"
21
#include "llvm/MC/MCInstrInfo.h"
22
#include "llvm/MC/MCRegisterInfo.h"
23
#include "llvm/MC/MCStreamer.h"
24
#include "llvm/MC/MCSubtargetInfo.h"
25
#include "llvm/MC/MCSymbolELF.h"
26
#include "llvm/MC/MachineLocation.h"
27
#include "llvm/Support/ELF.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/FormattedStream.h"
30
#include "llvm/Support/TargetRegistry.h"
31
32
using namespace llvm_ks;
33
34
#define GET_INSTRINFO_MC_DESC
35
#include "PPCGenInstrInfo.inc"
36
37
#define GET_SUBTARGETINFO_MC_DESC
38
#include "PPCGenSubtargetInfo.inc"
39
40
#define GET_REGINFO_MC_DESC
41
#include "PPCGenRegisterInfo.inc"
42
43
// Pin the vtable to this file.
44
0
PPCTargetStreamer::~PPCTargetStreamer() {}
45
0
PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
46
47
5.68k
static MCInstrInfo *createPPCMCInstrInfo() {
48
5.68k
  MCInstrInfo *X = new MCInstrInfo();
49
5.68k
  InitPPCMCInstrInfo(X);
50
5.68k
  return X;
51
5.68k
}
52
53
5.68k
static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) {
54
5.68k
  bool isPPC64 =
55
5.68k
      (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le);
56
5.68k
  unsigned Flavour = isPPC64 ? 0 : 1;
57
5.68k
  unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR;
58
59
5.68k
  MCRegisterInfo *X = new MCRegisterInfo();
60
5.68k
  InitPPCMCRegisterInfo(X, RA, Flavour, Flavour);
61
5.68k
  return X;
62
5.68k
}
63
64
static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT,
65
5.68k
                                                 StringRef CPU, StringRef FS) {
66
5.68k
  return createPPCMCSubtargetInfoImpl(TT, CPU, FS);
67
5.68k
}
68
69
static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
70
5.68k
                                     const Triple &TheTriple) {
71
5.68k
  bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
72
5.68k
                  TheTriple.getArch() == Triple::ppc64le);
73
74
5.68k
  MCAsmInfo *MAI;
75
5.68k
  if (TheTriple.isOSDarwin())
76
0
    MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple);
77
5.68k
  else
78
5.68k
    MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple);
79
80
  // Initial state of the frame pointer is R1.
81
5.68k
  unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1;
82
5.68k
  MCCFIInstruction Inst =
83
5.68k
      MCCFIInstruction::createDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0);
84
5.68k
  MAI->addInitialFrameState(Inst);
85
86
5.68k
  return MAI;
87
5.68k
}
88
89
namespace {
90
class PPCTargetAsmStreamer : public PPCTargetStreamer {
91
  formatted_raw_ostream &OS;
92
93
public:
94
  PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
95
0
      : PPCTargetStreamer(S), OS(OS) {}
96
0
  void emitTCEntry(const MCSymbol &S) override {
97
0
    OS << "\t.tc ";
98
0
    OS << S.getName();
99
0
    OS << "[TC],";
100
0
    OS << S.getName();
101
0
    OS << '\n';
102
0
  }
103
0
  void emitMachine(StringRef CPU) override {
104
0
    OS << "\t.machine " << CPU << '\n';
105
0
  }
106
0
  void emitAbiVersion(int AbiVersion) override {
107
0
    OS << "\t.abiversion " << AbiVersion << '\n';
108
0
  }
109
0
  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
110
0
    const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
111
0
112
0
    OS << "\t.localentry\t";
113
0
    S->print(OS, MAI);
114
0
    OS << ", ";
115
0
    LocalOffset->print(OS, MAI);
116
0
    OS << '\n';
117
0
  }
118
};
119
120
class PPCTargetELFStreamer : public PPCTargetStreamer {
121
public:
122
0
  PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
123
0
  MCELFStreamer &getStreamer() {
124
0
    return static_cast<MCELFStreamer &>(Streamer);
125
0
  }
126
0
  void emitTCEntry(const MCSymbol &S) override {
127
0
    // Creates a R_PPC64_TOC relocation
128
0
    Streamer.EmitValueToAlignment(8);
129
0
    Streamer.EmitSymbolValue(&S, 8);
130
0
  }
131
0
  void emitMachine(StringRef CPU) override {
132
0
    // FIXME: Is there anything to do in here or does this directive only
133
0
    // limit the parser?
134
0
  }
135
0
  void emitAbiVersion(int AbiVersion) override {
136
0
    MCAssembler &MCA = getStreamer().getAssembler();
137
0
    unsigned Flags = MCA.getELFHeaderEFlags();
138
0
    Flags &= ~ELF::EF_PPC64_ABI;
139
0
    Flags |= (AbiVersion & ELF::EF_PPC64_ABI);
140
0
    MCA.setELFHeaderEFlags(Flags);
141
0
  }
142
0
  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
143
0
    MCAssembler &MCA = getStreamer().getAssembler();
144
0
145
0
    int64_t Res;
146
0
    if (!LocalOffset->evaluateAsAbsolute(Res, MCA))
147
0
      report_fatal_error(".localentry expression must be absolute.");
148
0
149
0
    unsigned Encoded = ELF::encodePPC64LocalEntryOffset(Res);
150
0
    if (Res != ELF::decodePPC64LocalEntryOffset(Encoded))
151
0
      report_fatal_error(".localentry expression cannot be encoded.");
152
0
153
0
    unsigned Other = S->getOther();
154
0
    Other &= ~ELF::STO_PPC64_LOCAL_MASK;
155
0
    Other |= Encoded;
156
0
    S->setOther(Other);
157
0
158
0
    // For GAS compatibility, unless we already saw a .abiversion directive,
159
0
    // set e_flags to indicate ELFv2 ABI.
160
0
    unsigned Flags = MCA.getELFHeaderEFlags();
161
0
    if ((Flags & ELF::EF_PPC64_ABI) == 0)
162
0
      MCA.setELFHeaderEFlags(Flags | 2);
163
0
  }
164
0
  void emitAssignment(MCSymbol *S, const MCExpr *Value) override {
165
0
    auto *Symbol = cast<MCSymbolELF>(S);
166
0
    // When encoding an assignment to set symbol A to symbol B, also copy
167
0
    // the st_other bits encoding the local entry point offset.
168
0
    if (Value->getKind() != MCExpr::SymbolRef)
169
0
      return;
170
0
    const auto &RhsSym = cast<MCSymbolELF>(
171
0
        static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
172
0
    unsigned Other = Symbol->getOther();
173
0
    Other &= ~ELF::STO_PPC64_LOCAL_MASK;
174
0
    Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK;
175
0
    Symbol->setOther(Other);
176
0
  }
177
};
178
179
class PPCTargetMachOStreamer : public PPCTargetStreamer {
180
public:
181
0
  PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
182
0
  void emitTCEntry(const MCSymbol &S) override {
183
0
    llvm_unreachable("Unknown pseudo-op: .tc");
184
0
  }
185
0
  void emitMachine(StringRef CPU) override {
186
0
    // FIXME: We should update the CPUType, CPUSubType in the Object file if
187
0
    // the new values are different from the defaults.
188
0
  }
189
0
  void emitAbiVersion(int AbiVersion) override {
190
0
    llvm_unreachable("Unknown pseudo-op: .abiversion");
191
0
  }
192
0
  void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
193
0
    llvm_unreachable("Unknown pseudo-op: .localentry");
194
0
  }
195
};
196
}
197
198
26
extern "C" void LLVMInitializePowerPCTargetMC() {
199
78
  for (Target *T : {&ThePPC32Target, &ThePPC64Target, &ThePPC64LETarget}) {
200
    // Register the MC asm info.
201
78
    RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
202
203
    // Register the MC instruction info.
204
78
    TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo);
205
206
    // Register the MC register info.
207
78
    TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo);
208
209
    // Register the MC subtarget info.
210
78
    TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo);
211
212
    // Register the MC Code Emitter
213
78
    TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter);
214
215
    // Register the asm backend.
216
78
    TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend);
217
78
  }
218
26
}