//===-- CSKYMCTargetDesc.cpp - CSKY Target Descriptions -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// This file provides CSKY specific target descriptions.
///
//===----------------------------------------------------------------------===//

#include "CSKYMCTargetDesc.h"
#include "CSKYAsmBackend.h"
#include "CSKYELFStreamer.h"
#include "CSKYInstPrinter.h"
#include "CSKYMCAsmInfo.h"
#include "CSKYMCCodeEmitter.h"
#include "CSKYTargetStreamer.h"
#include "TargetInfo/CSKYTargetInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"

#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "CSKYGenInstrInfo.inc"

#define GET_REGINFO_MC_DESC
#include "CSKYGenRegisterInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "CSKYGenSubtargetInfo.inc"

using namespace llvm;

static MCAsmInfo *createCSKYMCAsmInfo(const MCRegisterInfo &MRI,
                                      const Triple &TT,
                                      const MCTargetOptions &Options) {
  MCAsmInfo *MAI = new CSKYMCAsmInfo(TT);

  // Initial state of the frame pointer is SP.
  unsigned Reg = MRI.getDwarfRegNum(CSKY::R14, true);
  MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0);
  MAI->addInitialFrameState(Inst);
  return MAI;
}

static MCInstrInfo *createCSKYMCInstrInfo() {
  MCInstrInfo *Info = new MCInstrInfo();
  InitCSKYMCInstrInfo(Info);
  return Info;
}

static MCInstPrinter *createCSKYMCInstPrinter(const Triple &T,
                                              unsigned SyntaxVariant,
                                              const MCAsmInfo &MAI,
                                              const MCInstrInfo &MII,
                                              const MCRegisterInfo &MRI) {
  return new CSKYInstPrinter(MAI, MII, MRI);
}

static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) {
  MCRegisterInfo *Info = new MCRegisterInfo();
  InitCSKYMCRegisterInfo(Info, CSKY::R15);
  return Info;
}

static MCSubtargetInfo *createCSKYMCSubtargetInfo(const Triple &TT,
                                                  StringRef CPU, StringRef FS) {
  std::string CPUName = std::string(CPU);
  if (CPUName.empty())
    CPUName = "generic";
  return createCSKYMCSubtargetInfoImpl(TT, CPUName, /*TuneCPU=*/CPUName, FS);
}

static MCTargetStreamer *
createCSKYObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
  const Triple &TT = STI.getTargetTriple();
  if (TT.isOSBinFormatELF())
    return new CSKYTargetELFStreamer(S, STI);
  return nullptr;
}

static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
                                     std::unique_ptr<MCAsmBackend> &&MAB,
                                     std::unique_ptr<MCObjectWriter> &&OW,
                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
                                     bool RelaxAll) {
  CSKYELFStreamer *S = new CSKYELFStreamer(Ctx, std::move(MAB), std::move(OW),
                                           std::move(Emitter));

  if (RelaxAll)
    S->getAssembler().setRelaxAll(true);
  return S;
}

static MCTargetStreamer *createCSKYAsmTargetStreamer(MCStreamer &S,
                                                     formatted_raw_ostream &OS,
                                                     MCInstPrinter *InstPrinter,
                                                     bool isVerboseAsm) {
  return new CSKYTargetAsmStreamer(S, OS);
}

static MCTargetStreamer *createCSKYNullTargetStreamer(MCStreamer &S) {
  return new CSKYTargetStreamer(S);
}

namespace {

class CSKYMCInstrAnalysis : public MCInstrAnalysis {
public:
  explicit CSKYMCInstrAnalysis(const MCInstrInfo *Info)
      : MCInstrAnalysis(Info) {}

  bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
                      uint64_t &Target) const override {
    if (isConditionalBranch(Inst) || isUnconditionalBranch(Inst)) {
      int64_t Imm;
      Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
      Target = Addr + Imm;
      return true;
    }

    if (Inst.getOpcode() == CSKY::BSR32) {
      Target = Addr + Inst.getOperand(0).getImm();
      return true;
    }

    switch (Inst.getOpcode()) {
    default:
      return false;
    case CSKY::LRW16:
    case CSKY::LRW32:
    case CSKY::JSRI32:
    case CSKY::JMPI32:
      int64_t Imm = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
      Target = ((Addr + Imm) & 0xFFFFFFFC);
      return true;
    }

    return false;
  }
};

} // end anonymous namespace

static MCInstrAnalysis *createCSKYInstrAnalysis(const MCInstrInfo *Info) {
  return new CSKYMCInstrAnalysis(Info);
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() {
  auto &CSKYTarget = getTheCSKYTarget();
  TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend);
  TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo);
  TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo);
  TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo);
  TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter);
  TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter);
  TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget,
                                          createCSKYMCSubtargetInfo);
  TargetRegistry::RegisterELFStreamer(CSKYTarget, createELFStreamer);
  TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget,
                                               createCSKYObjectTargetStreamer);
  TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget,
                                            createCSKYAsmTargetStreamer);
  // Register the null target streamer.
  TargetRegistry::RegisterNullTargetStreamer(CSKYTarget,
                                             createCSKYNullTargetStreamer);
  TargetRegistry::RegisterMCInstrAnalysis(CSKYTarget, createCSKYInstrAnalysis);
}
