xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1e8d8bef9SDimitry Andric //===-- CSKYMCTargetDesc.cpp - CSKY Target Descriptions -------------------===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric ///
9e8d8bef9SDimitry Andric /// This file provides CSKY specific target descriptions.
10e8d8bef9SDimitry Andric ///
11e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
12e8d8bef9SDimitry Andric 
13e8d8bef9SDimitry Andric #include "CSKYMCTargetDesc.h"
14e8d8bef9SDimitry Andric #include "CSKYAsmBackend.h"
1581ad6265SDimitry Andric #include "CSKYELFStreamer.h"
16fe6060f1SDimitry Andric #include "CSKYInstPrinter.h"
17e8d8bef9SDimitry Andric #include "CSKYMCAsmInfo.h"
18e8d8bef9SDimitry Andric #include "CSKYMCCodeEmitter.h"
1981ad6265SDimitry Andric #include "CSKYTargetStreamer.h"
20e8d8bef9SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h"
2181ad6265SDimitry Andric #include "llvm/MC/MCAssembler.h"
2281ad6265SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h"
23e8d8bef9SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
24e8d8bef9SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
25e8d8bef9SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
26349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
27e8d8bef9SDimitry Andric 
28e8d8bef9SDimitry Andric #define GET_INSTRINFO_MC_DESC
29753f127fSDimitry Andric #define ENABLE_INSTR_PREDICATE_VERIFIER
30e8d8bef9SDimitry Andric #include "CSKYGenInstrInfo.inc"
31e8d8bef9SDimitry Andric 
32e8d8bef9SDimitry Andric #define GET_REGINFO_MC_DESC
33e8d8bef9SDimitry Andric #include "CSKYGenRegisterInfo.inc"
34e8d8bef9SDimitry Andric 
35fe6060f1SDimitry Andric #define GET_SUBTARGETINFO_MC_DESC
36fe6060f1SDimitry Andric #include "CSKYGenSubtargetInfo.inc"
37fe6060f1SDimitry Andric 
38e8d8bef9SDimitry Andric using namespace llvm;
39e8d8bef9SDimitry Andric 
40e8d8bef9SDimitry Andric static MCAsmInfo *createCSKYMCAsmInfo(const MCRegisterInfo &MRI,
41e8d8bef9SDimitry Andric                                       const Triple &TT,
42e8d8bef9SDimitry Andric                                       const MCTargetOptions &Options) {
43e8d8bef9SDimitry Andric   MCAsmInfo *MAI = new CSKYMCAsmInfo(TT);
44e8d8bef9SDimitry Andric 
45e8d8bef9SDimitry Andric   // Initial state of the frame pointer is SP.
46e8d8bef9SDimitry Andric   unsigned Reg = MRI.getDwarfRegNum(CSKY::R14, true);
47e8d8bef9SDimitry Andric   MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0);
48e8d8bef9SDimitry Andric   MAI->addInitialFrameState(Inst);
49e8d8bef9SDimitry Andric   return MAI;
50e8d8bef9SDimitry Andric }
51e8d8bef9SDimitry Andric 
52e8d8bef9SDimitry Andric static MCInstrInfo *createCSKYMCInstrInfo() {
53e8d8bef9SDimitry Andric   MCInstrInfo *Info = new MCInstrInfo();
54e8d8bef9SDimitry Andric   InitCSKYMCInstrInfo(Info);
55e8d8bef9SDimitry Andric   return Info;
56e8d8bef9SDimitry Andric }
57e8d8bef9SDimitry Andric 
58fe6060f1SDimitry Andric static MCInstPrinter *createCSKYMCInstPrinter(const Triple &T,
59fe6060f1SDimitry Andric                                               unsigned SyntaxVariant,
60fe6060f1SDimitry Andric                                               const MCAsmInfo &MAI,
61fe6060f1SDimitry Andric                                               const MCInstrInfo &MII,
62fe6060f1SDimitry Andric                                               const MCRegisterInfo &MRI) {
63fe6060f1SDimitry Andric   return new CSKYInstPrinter(MAI, MII, MRI);
64fe6060f1SDimitry Andric }
65fe6060f1SDimitry Andric 
66e8d8bef9SDimitry Andric static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) {
67e8d8bef9SDimitry Andric   MCRegisterInfo *Info = new MCRegisterInfo();
68e8d8bef9SDimitry Andric   InitCSKYMCRegisterInfo(Info, CSKY::R15);
69e8d8bef9SDimitry Andric   return Info;
70e8d8bef9SDimitry Andric }
71e8d8bef9SDimitry Andric 
72fe6060f1SDimitry Andric static MCSubtargetInfo *createCSKYMCSubtargetInfo(const Triple &TT,
73fe6060f1SDimitry Andric                                                   StringRef CPU, StringRef FS) {
74fe6060f1SDimitry Andric   std::string CPUName = std::string(CPU);
75fe6060f1SDimitry Andric   if (CPUName.empty())
76fe6060f1SDimitry Andric     CPUName = "generic";
77fe6060f1SDimitry Andric   return createCSKYMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU=*/CPUName, FS);
78fe6060f1SDimitry Andric }
79fe6060f1SDimitry Andric 
8081ad6265SDimitry Andric static MCTargetStreamer *
8181ad6265SDimitry Andric createCSKYObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
8281ad6265SDimitry Andric   const Triple &TT = STI.getTargetTriple();
8381ad6265SDimitry Andric   if (TT.isOSBinFormatELF())
8481ad6265SDimitry Andric     return new CSKYTargetELFStreamer(S, STI);
8581ad6265SDimitry Andric   return nullptr;
8681ad6265SDimitry Andric }
8781ad6265SDimitry Andric 
8881ad6265SDimitry Andric static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
8981ad6265SDimitry Andric                                      std::unique_ptr<MCAsmBackend> &&MAB,
9081ad6265SDimitry Andric                                      std::unique_ptr<MCObjectWriter> &&OW,
91*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCCodeEmitter> &&Emitter) {
9281ad6265SDimitry Andric   CSKYELFStreamer *S = new CSKYELFStreamer(Ctx, std::move(MAB), std::move(OW),
9381ad6265SDimitry Andric                                            std::move(Emitter));
9481ad6265SDimitry Andric 
9581ad6265SDimitry Andric   return S;
9681ad6265SDimitry Andric }
9781ad6265SDimitry Andric 
98*0fca6ea1SDimitry Andric static MCTargetStreamer *
99*0fca6ea1SDimitry Andric createCSKYAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
100*0fca6ea1SDimitry Andric                             MCInstPrinter *InstPrinter) {
10181ad6265SDimitry Andric   return new CSKYTargetAsmStreamer(S, OS);
10281ad6265SDimitry Andric }
10381ad6265SDimitry Andric 
10481ad6265SDimitry Andric static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) {
10581ad6265SDimitry Andric   return new CSKYTargetStreamer(S);
10681ad6265SDimitry Andric }
10781ad6265SDimitry Andric 
10881ad6265SDimitry Andric namespace {
10981ad6265SDimitry Andric 
11081ad6265SDimitry Andric class CSKYMCInstrAnalysis : public MCInstrAnalysis {
11181ad6265SDimitry Andric public:
11281ad6265SDimitry Andric   explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info)
11381ad6265SDimitry Andric       : MCInstrAnalysis(Info) {}
11481ad6265SDimitry Andric 
11581ad6265SDimitry Andric   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
11681ad6265SDimitry Andric                       uint64_t &Target) const override {
11781ad6265SDimitry Andric     if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) {
11881ad6265SDimitry Andric       int64_t Imm;
11981ad6265SDimitry Andric       Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
12081ad6265SDimitry Andric       Target = Addr + Imm;
12181ad6265SDimitry Andric       return true;
12281ad6265SDimitry Andric     }
12381ad6265SDimitry Andric 
12481ad6265SDimitry Andric     if (Inst.getOpcode() == CSKY::BSR32) {
12581ad6265SDimitry Andric       Target = Addr + Inst.getOperand(0).getImm();
12681ad6265SDimitry Andric       return true;
12781ad6265SDimitry Andric     }
12881ad6265SDimitry Andric 
12981ad6265SDimitry Andric     switch (Inst.getOpcode()) {
13081ad6265SDimitry Andric     default:
13181ad6265SDimitry Andric       return false;
13281ad6265SDimitry Andric     case CSKY::LRW16:
13381ad6265SDimitry Andric     case CSKY::LRW32:
13481ad6265SDimitry Andric     case CSKY::JSRI32:
13581ad6265SDimitry Andric     case CSKY::JMPI32:
13681ad6265SDimitry Andric       int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
13781ad6265SDimitry Andric       Target = ((Addr + Imm) & 0xFFFFFFFC);
13881ad6265SDimitry Andric       return true;
13981ad6265SDimitry Andric     }
14081ad6265SDimitry Andric 
14181ad6265SDimitry Andric     return false;
14281ad6265SDimitry Andric   }
14381ad6265SDimitry Andric };
14481ad6265SDimitry Andric 
14581ad6265SDimitry Andric } // end anonymous namespace
14681ad6265SDimitry Andric 
14781ad6265SDimitry Andric static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) {
14881ad6265SDimitry Andric   return new CSKYMCInstrAnalysis(Info);
14981ad6265SDimitry Andric }
15081ad6265SDimitry Andric 
151e8d8bef9SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() {
152e8d8bef9SDimitry Andric   auto &CSKYTarget = getTheCSKYTarget();
153e8d8bef9SDimitry Andric   TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend);
154e8d8bef9SDimitry Andric   TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo);
155e8d8bef9SDimitry Andric   TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo);
156e8d8bef9SDimitry Andric   TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo);
157e8d8bef9SDimitry Andric   TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter);
158fe6060f1SDimitry Andric   TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter);
159fe6060f1SDimitry Andric   TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget,
160fe6060f1SDimitry Andric                                           createCSKYMCSubtargetInfo);
16181ad6265SDimitry Andric   TargetRegistry::RegisterELFStreamer(CSKYTarget, createELFStreamer);
16281ad6265SDimitry Andric   TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget,
16381ad6265SDimitry Andric                                                createCSKYObjectTargetStreamer);
16481ad6265SDimitry Andric   TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget,
16581ad6265SDimitry Andric                                             createCSKYAsmTargetStreamer);
16681ad6265SDimitry Andric   // Register the null target streamer.
16781ad6265SDimitry Andric   TargetRegistry::RegisterNullTargetStreamer(CSKYTarget,
16881ad6265SDimitry Andric                                              createCSKYNullTargetStreamer);
16981ad6265SDimitry Andric   TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis);
170e8d8bef9SDimitry Andric }
171