Index: llvm/lib/Target/CSKY/CMakeLists.txt =================================================================== --- llvm/lib/Target/CSKY/CMakeLists.txt +++ llvm/lib/Target/CSKY/CMakeLists.txt @@ -4,6 +4,7 @@ tablegen(LLVM CSKYGenRegisterInfo.inc -gen-register-info) tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM CSKYGenMCCodeEmitter.inc -gen-emitter) add_public_tablegen_target(CSKYCommonTableGen) @@ -22,3 +23,4 @@ ) add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) Index: llvm/lib/Target/CSKY/CSKYInstrInfo.td =================================================================== --- llvm/lib/Target/CSKY/CSKYInstrInfo.td +++ llvm/lib/Target/CSKY/CSKYInstrInfo.td @@ -24,17 +24,17 @@ class oimm : Operand, ImmLeaf(Imm - 1);"> { - let EncoderMethod = "getOImmOpValue<"#num#">"; + let EncoderMethod = "getOImmOpValue"; } class uimm : Operand, ImmLeaf(Imm);"> { - let EncoderMethod = "getImmOpValue<"#num#", "#shift#">"; + let EncoderMethod = "getImmOpValue<"#shift#">"; } class simm : Operand, ImmLeaf(Imm);"> { - let EncoderMethod = "getImmOpValue<"#num#", "#shift#">"; + let EncoderMethod = "getImmOpValue<"#shift#">"; } def nimm_XFORM : SDNodeXForm Data, + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override; + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override; + void relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + std::unique_ptr + createObjectTargetWriter() const override; +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYASMBACKEND_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -0,0 +1,69 @@ +//===-- CSKYAsmBackend.cpp - CSKY Assembler Backend -----------------------===// +// +// 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 "CSKYAsmBackend.h" +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/MC/MCAsmLayout.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "csky-asmbackend" + +using namespace llvm; + +std::unique_ptr +CSKYAsmBackend::createObjectTargetWriter() const { + return createCSKYELFObjectWriter(); +} + +unsigned int CSKYAsmBackend::getNumFixupKinds() const { return 1; } + +void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, + MutableArrayRef Data, uint64_t Value, + bool IsResolved, + const MCSubtargetInfo *STI) const { + return; +} + +bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const { + return false; +} + +void CSKYAsmBackend::relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const { + llvm_unreachable("CSKYAsmBackend::relaxInstruction() unimplemented"); +} + +bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { + if (Count % 2) + return false; + + // MOV32 r0, r0 + while (Count >= 4) { + OS.write("\xc4\x00\x48\x20", 4); + Count -= 4; + } + // MOV16 r0, r0 + if (Count) + OS.write("\x6c\x03", 2); + + return true; +} + +MCAsmBackend *llvm::createCSKYAsmBackend(const Target &T, + const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options) { + return new CSKYAsmBackend(STI, Options); +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp @@ -0,0 +1,45 @@ +//===-- CSKYELFObjectWriter.cpp - CSKY ELF Writer -------------------------===// +// +// 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 "CSKYMCTargetDesc.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCObjectWriter.h" + +#define DEBUG_TYPE "csky-elf-object-writer" + +using namespace llvm; + +namespace { + +class CSKYELFObjectWriter : public MCELFObjectTargetWriter { +public: + CSKYELFObjectWriter(uint8_t OSABI = 0) + : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){}; + ~CSKYELFObjectWriter() {} + + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override; +}; + +} // namespace + +unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + // Determine the type of the relocation. + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("invalid fixup kind!"); + } +} + +std::unique_ptr llvm::createCSKYELFObjectWriter() { + return std::make_unique(); +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.h @@ -0,0 +1,29 @@ +//===-- CSKYMCAsmInfo.h - CSKY Asm Info ------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the CSKYMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H + +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class Triple; + +class CSKYMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit CSKYMCAsmInfo(const Triple &TargetTriple); +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp @@ -0,0 +1,25 @@ +//===-- CSKYMCAsmInfo.cpp - CSKY Asm properties ---------------------------===// +// +// 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 contains the declarations of the CSKYMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCAsmInfo.h" +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/MC/MCStreamer.h" + +using namespace llvm; + +void CSKYMCAsmInfo::anchor() {} + +CSKYMCAsmInfo::CSKYMCAsmInfo(const Triple &TargetTriple) { + AlignmentIsInBytes = false; + SupportsDebugInformation = true; + CommentString = "#"; +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h @@ -0,0 +1,61 @@ +//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// +// +// 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 implements the CSKYMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H + +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" + +namespace llvm { + +class CSKYMCCodeEmitter : public MCCodeEmitter { + MCContext &Ctx; + const MCInstrInfo &MII; + +public: + CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII) + : Ctx(Ctx), MII(MII) {} + + ~CSKYMCCodeEmitter() {} + + void encodeInstruction(const MCInst &Inst, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const override; + + // Generated by tablegen. + uint64_t getBinaryCodeForInstr(const MCInst &MI, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + // Default encoding method used by tablegen. + unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + template + unsigned getImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isImm() && "Unexpected MO type."); + return (MO.getImm() >> shift); + } + + unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp @@ -0,0 +1,71 @@ +//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// +// +// 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 implements the CSKYMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCCodeEmitter.h" +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/Support/EndianStream.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-mccode-emitter" + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isImm() && "Unexpected MO type."); + return MO.getImm() - 1; +} + +void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCInstrDesc &Desc = MII.get(MI.getOpcode()); + unsigned Size = Desc.getSize(); + uint32_t Bin = getBinaryCodeForInstr(MI, Fixups, STI); + + uint16_t LO16 = static_cast(Bin); + uint16_t HI16 = static_cast(Bin >> 16); + + if (Size == 4) + support::endian::write(OS, HI16, support::little); + + support::endian::write(OS, LO16, support::little); + ++MCNumEmitted; // Keep track of the # of mi's emitted. +} + +unsigned +CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + if (MO.isReg()) + return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); + + if (MO.isImm()) + return static_cast(MO.getImm()); + + llvm_unreachable("Unhandled expression!"); + return 0; +} + +MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx) { + return new CSKYMCCodeEmitter(Ctx, MCII); +} + +#include "CSKYGenMCCodeEmitter.inc" Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h @@ -0,0 +1,48 @@ +//===-- CSKYMCTargetDesc.h - CSKY Target Descriptions -----------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides CSKY specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H + +#include "llvm/MC/MCTargetOptions.h" +#include + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCRegisterInfo; +class MCObjectTargetWriter; +class MCRegisterInfo; +class MCSubtargetInfo; +class Target; +class Triple; + +std::unique_ptr createCSKYELFObjectWriter(); + +MCAsmBackend *createCSKYAsmBackend(const Target &T, const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options); + +MCCodeEmitter *createCSKYMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx); +} // namespace llvm + +#define GET_REGINFO_ENUM +#include "CSKYGenRegisterInfo.inc" + +#define GET_INSTRINFO_ENUM +#include "CSKYGenInstrInfo.inc" + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp @@ -0,0 +1,62 @@ +//===-- 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 "CSKYMCAsmInfo.h" +#include "CSKYMCCodeEmitter.h" +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/TargetRegistry.h" + +#define GET_INSTRINFO_MC_DESC +#include "CSKYGenInstrInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "CSKYGenRegisterInfo.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 MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *Info = new MCRegisterInfo(); + InitCSKYMCRegisterInfo(Info, CSKY::R15); + return 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); +} Index: llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp =================================================================== --- llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp +++ llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp @@ -18,8 +18,3 @@ extern "C" void LLVMInitializeCSKYTargetInfo() { RegisterTarget X(getTheCSKYTarget(), "csky", "C-SKY", "CSKY"); } - -// FIXME: Temporary stub - this function must be defined for linking -// to succeed and will be called unconditionally by llc, so must be a no-op. -// Remove once this function is properly implemented. -extern "C" void LLVMInitializeCSKYTargetMC() {}