Index: lib/Target/NDS32/CMakeLists.txt =================================================================== --- lib/Target/NDS32/CMakeLists.txt +++ lib/Target/NDS32/CMakeLists.txt @@ -5,6 +5,7 @@ tablegen(LLVM NDS32GenInstrInfo.inc -gen-instr-info) tablegen(LLVM NDS32GenDAGISel.inc -gen-dag-isel) tablegen(LLVM NDS32GenCallingConv.inc -gen-callingconv) +tablegen(LLVM NDS32GenAsmWriter.inc -gen-asm-writer) add_public_tablegen_target(NDS32CommonTableGen) @@ -18,7 +19,10 @@ NDS32ISelDAGToDAG.cpp NDS32ISelLowering.cpp NDS32MachineFunctionInfo.cpp + NDS32MCInstLower.cpp + NDS32AsmPrinter.cpp ) add_subdirectory(TargetInfo) add_subdirectory(MCTargetDesc) +add_subdirectory(InstPrinter) Index: lib/Target/NDS32/InstPrinter/CMakeLists.txt =================================================================== --- /dev/null +++ lib/Target/NDS32/InstPrinter/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMNDS32AsmPrinter + NDS32InstPrinter.cpp + ) Index: lib/Target/NDS32/InstPrinter/LLVMBuild.txt =================================================================== --- /dev/null +++ lib/Target/NDS32/InstPrinter/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/NDS32/InstPrinter/LLVMBuild.txt ------------*- Conf -*---===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = NDS32AsmPrinter +parent = NDS32 +required_libraries = MC Support +add_to_library_groups = NDS32 Index: lib/Target/NDS32/InstPrinter/NDS32InstPrinter.h =================================================================== --- /dev/null +++ lib/Target/NDS32/InstPrinter/NDS32InstPrinter.h @@ -0,0 +1,40 @@ +//==- NDS32InstPrinter.h - Convert NDS32 MCInst to assembly syntax -*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints a NDS32 MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_NDS32_INSTPRINTER_NDS32INSTPRINTER_H +#define LLVM_LIB_TARGET_NDS32_INSTPRINTER_NDS32INSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + class NDS32InstPrinter : public MCInstPrinter { + public: + NDS32InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} + + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, + const MCSubtargetInfo &STI) override; + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = nullptr); + + void printRegName(raw_ostream &OS, unsigned RegNo) const override; + }; +} + +#endif Index: lib/Target/NDS32/InstPrinter/NDS32InstPrinter.cpp =================================================================== --- /dev/null +++ lib/Target/NDS32/InstPrinter/NDS32InstPrinter.cpp @@ -0,0 +1,50 @@ +//===-- NDS32InstPrinter.cpp - Convert NDS32 MCInst to assembly syntax ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an NDS32 MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "NDS32InstPrinter.h" +#include "NDS32.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +// Include the auto-generated portion of the assembly writer. +#include "NDS32GenAsmWriter.inc" + +void NDS32InstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot, const MCSubtargetInfo &STI) { + printInstruction(MI, O); + printAnnotation(O, Annot); +} + +void NDS32InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier) { + assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported"); + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + O << '$' << getRegisterName(Op.getReg()); + } else if (Op.isImm()) { + O << Op.getImm(); + } else { + assert(Op.isExpr() && "unknown operand kind in printOperand"); + Op.getExpr()->print(O, &MAI); + } +} + +void NDS32InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + OS << markup(""); +} Index: lib/Target/NDS32/LLVMBuild.txt =================================================================== --- lib/Target/NDS32/LLVMBuild.txt +++ lib/Target/NDS32/LLVMBuild.txt @@ -16,16 +16,17 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = TargetInfo MCTargetDesc +subdirectories = TargetInfo MCTargetDesc InstPrinter [component_0] type = TargetGroup name = NDS32 parent = Target +has_asmprinter = 1 [component_1] type = Library name = NDS32CodeGen parent = NDS32 -required_libraries = CodeGen Core Support Target NDS32Info NDS32Desc +required_libraries = CodeGen Core Support Target NDS32Info NDS32Desc MC AsmPrinter NDS32AsmPrinter add_to_library_groups = NDS32 Index: lib/Target/NDS32/MCTargetDesc/CMakeLists.txt =================================================================== --- lib/Target/NDS32/MCTargetDesc/CMakeLists.txt +++ lib/Target/NDS32/MCTargetDesc/CMakeLists.txt @@ -1,3 +1,4 @@ add_llvm_library(LLVMNDS32Desc NDS32MCTargetDesc.cpp + NDS32MCAsmInfo.cpp ) Index: lib/Target/NDS32/MCTargetDesc/LLVMBuild.txt =================================================================== --- lib/Target/NDS32/MCTargetDesc/LLVMBuild.txt +++ lib/Target/NDS32/MCTargetDesc/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = NDS32Desc parent = NDS32 -required_libraries = MC NDS32Info Support +required_libraries = MC NDS32Info Support NDS32AsmPrinter add_to_library_groups = NDS32 Index: lib/Target/NDS32/MCTargetDesc/NDS32MCAsmInfo.h =================================================================== --- /dev/null +++ lib/Target/NDS32/MCTargetDesc/NDS32MCAsmInfo.h @@ -0,0 +1,31 @@ +//===-- NDS32MCAsmInfo.h - NDS32 asm properties --------------*- C++ -*----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the NDS32MCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_NDS32_MCTARGETDESC_NDS32MCASMINFO_H +#define LLVM_LIB_TARGET_NDS32_MCTARGETDESC_NDS32MCASMINFO_H + +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class Triple; + +class NDS32MCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit NDS32MCAsmInfo(const Triple &TT); +}; + +} // namespace llvm + +#endif Index: lib/Target/NDS32/MCTargetDesc/NDS32MCAsmInfo.cpp =================================================================== --- /dev/null +++ lib/Target/NDS32/MCTargetDesc/NDS32MCAsmInfo.cpp @@ -0,0 +1,31 @@ +//===-- NDS32MCAsmInfo.cpp - NDS32 asm properties -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the NDS32MCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "NDS32MCAsmInfo.h" +using namespace llvm; + +void NDS32MCAsmInfo::anchor() { } + +NDS32MCAsmInfo::NDS32MCAsmInfo(const Triple &TT) { + PointerSize = CalleeSaveStackSlotSize = 4; + + CommentString = "!"; + + AlignmentIsInBytes = false; + UsesELFSectionDirectiveForBSS = true; + + SupportsDebugInformation = true; + ExceptionsType = ExceptionHandling::DwarfCFI; + DwarfRegNumForCFI = true; + UseIntegratedAssembler = true; +} Index: lib/Target/NDS32/MCTargetDesc/NDS32MCTargetDesc.cpp =================================================================== --- lib/Target/NDS32/MCTargetDesc/NDS32MCTargetDesc.cpp +++ lib/Target/NDS32/MCTargetDesc/NDS32MCTargetDesc.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "NDS32MCTargetDesc.h" +#include "InstPrinter/NDS32InstPrinter.h" +#include "NDS32MCAsmInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -45,6 +47,27 @@ return X; } +static MCAsmInfo *createNDS32MCAsmInfo(const MCRegisterInfo &MRI, + const Triple &TT) { + MCAsmInfo *MAI = new NDS32MCAsmInfo(TT); + + unsigned SP = MRI.getDwarfRegNum(NDS32::SP, true); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); + MAI->addInitialFrameState(Inst); + + return MAI; +} + +static MCInstPrinter *createNDS32MCInstPrinter(const Triple &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) { + if (SyntaxVariant == 0) + return new NDS32InstPrinter(MAI, MII, MRI); + return nullptr; +} + extern "C" void LLVMInitializeNDS32TargetMC() { // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(getTheNDS32Target(), @@ -57,4 +80,11 @@ // Register the MC instruction info. TargetRegistry::RegisterMCInstrInfo(getTheNDS32Target(), createNDS32MCInstrInfo); + + // Register the MC asm info. + RegisterMCAsmInfoFn X(getTheNDS32Target(), createNDS32MCAsmInfo); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(getTheNDS32Target(), + createNDS32MCInstPrinter); } Index: lib/Target/NDS32/NDS32AsmPrinter.h =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32AsmPrinter.h @@ -0,0 +1,38 @@ +//===-- NDS32AsmPrinter.h - NDS32 LLVM Assembly Printer --------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// NDS32 Assembly printer class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_NDS32_NDS32ASMPRINTER_H +#define LLVM_LIB_TARGET_NDS32_NDS32ASMPRINTER_H + +#include "NDS32Subtarget.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { +class LLVM_LIBRARY_VISIBILITY NDS32AsmPrinter : public AsmPrinter { + public: + explicit NDS32AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer); + + StringRef getPassName() const override { return "NDS32 Assembly Printer"; } + void printOperand(const MachineInstr *MI, int OpNum, + raw_ostream &O, const char* Modifier = nullptr); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O) override; + void EmitInstruction(const MachineInstr *MI) override; + }; +} + +#endif Index: lib/Target/NDS32/NDS32AsmPrinter.cpp =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32AsmPrinter.cpp @@ -0,0 +1,113 @@ +//===-- NDS32AsmPrinter.cpp - NDS32 LLVM assembly writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the NDS32 assembly language. +// +//===----------------------------------------------------------------------===// + +#include "NDS32.h" +#include "InstPrinter/NDS32InstPrinter.h" +#include "NDS32InstrInfo.h" +#include "NDS32MCInstLower.h" +#include "NDS32TargetMachine.h" +#include "NDS32AsmPrinter.h" +#include "MCTargetDesc/NDS32BaseInfo.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Mangler.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +NDS32AsmPrinter::NDS32AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)) {} + +void NDS32AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, + raw_ostream &O, const char *Modifier) { + const MachineOperand &MO = MI->getOperand(OpNum); + + switch (MO.getType()) { + default: llvm_unreachable("Not implemented yet!"); + case MachineOperand::MO_Register: + O << NDS32InstPrinter::getRegisterName(MO.getReg()); + return; + case MachineOperand::MO_Immediate: + O << MO.getImm(); + return; + case MachineOperand::MO_MachineBasicBlock: + MO.getMBB()->getSymbol()->print(O, MAI); + return; + case MachineOperand::MO_GlobalAddress: { + uint64_t Offset = MO.getOffset(); + + if (Offset) + O << '(' << Offset << '+'; + + getSymbol(MO.getGlobal())->print(O, MAI); + + if (Offset) + O << ')'; + + return; + } + } +} + +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool NDS32AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode, raw_ostream &O) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) { + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: + // See if this is a generic print operand + return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); + case 'c': + if (!MI->getOperand(OpNo).isImm()) + return true; + O << MI->getOperand(OpNo).getImm(); + return false; + } + } + + printOperand(MI, OpNo, O); + return false; +} + +//===----------------------------------------------------------------------===// +void NDS32AsmPrinter::EmitInstruction(const MachineInstr *MI) { + NDS32MCInstLower MCInstLowering(OutContext, *this); + + MCInst TmpInst; + MCInstLowering.Lower(MI, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); +} + +// Force static initialization. +extern "C" void LLVMInitializeNDS32AsmPrinter() { + RegisterAsmPrinter X(getTheNDS32Target()); +} Index: lib/Target/NDS32/NDS32MCInstLower.h =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32MCInstLower.h @@ -0,0 +1,43 @@ +//===-- NDS32MCInstLower.h - Lower MachineInstr to MCInst ------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_NDS32_NDS32MCINSTLOWER_H +#define LLVM_LIB_TARGET_NDS32_NDS32MCINSTLOWER_H +#include "llvm/Support/Compiler.h" +#include "llvm/CodeGen/MachineOperand.h" + +namespace llvm { + class NDS32AsmPrinter; + class MCContext; + class MCInst; + class MCOperand; + class MCSymbol; + class MachineInstr; + class MachineModuleInfoMachO; + class MachineOperand; + + /// NDS32MCInstLower - This class is used to lower an MachineInstr + /// into an MCInst. +class LLVM_LIBRARY_VISIBILITY NDS32MCInstLower { + typedef MachineOperand::MachineOperandType MachineOperandType; + MCContext &Ctx; + + NDS32AsmPrinter &Printer; +public: + NDS32MCInstLower(MCContext &ctx, NDS32AsmPrinter &printer) + : Ctx(ctx), Printer(printer) {} + void Lower(const MachineInstr *MI, MCInst &OutMI) const; + + MCOperand LowerSymbolOperand(const MachineOperand &MO, + MachineOperandType MOTy, unsigned Offset) const; +}; + +} + +#endif Index: lib/Target/NDS32/NDS32MCInstLower.cpp =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32MCInstLower.cpp @@ -0,0 +1,128 @@ +//===-- NDS32MCInstLower.cpp - Convert NDS32 MachineInstr to an MCInst ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower NDS32 MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "NDS32MCInstLower.h" +#include "NDS32AsmPrinter.h" +#include "NDS32MCInstLower.h" +#include "MCTargetDesc/NDS32BaseInfo.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Mangler.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +using namespace llvm; + + +MCOperand NDS32MCInstLower:: +LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, + unsigned Offset) const { + + const MCSymbol *Symbol; + + switch (MOTy) { + case MachineOperand::MO_MachineBasicBlock: + Symbol = MO.getMBB()->getSymbol(); + break; + + case MachineOperand::MO_GlobalAddress: + Symbol = Printer.getSymbol(MO.getGlobal()); + Offset += MO.getOffset(); + break; + + case MachineOperand::MO_BlockAddress: + Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress()); + Offset += MO.getOffset(); + break; + + case MachineOperand::MO_ExternalSymbol: + Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); + Offset += MO.getOffset(); + break; + + case MachineOperand::MO_MCSymbol: + Symbol = MO.getMCSymbol(); + Offset += MO.getOffset(); + break; + + case MachineOperand::MO_JumpTableIndex: + Symbol = Printer.GetJTISymbol(MO.getIndex()); + break; + + case MachineOperand::MO_ConstantPoolIndex: + Symbol = Printer.GetCPISymbol(MO.getIndex()); + Offset += MO.getOffset(); + break; + + default: + llvm_unreachable(""); + } + + + const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Ctx); + + if (Offset) { + // Assume offset is never negative. + assert(Offset > 0); + + Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), + Ctx); + } + + return MCOperand::createExpr(Expr); +} + +void NDS32MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + unsigned offset = 0; + + OutMI.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + + MCOperand MCOp; + switch (MO.getType()) { + default: + MI->dump(); + llvm_unreachable("unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. + if (MO.isImplicit()) continue; + MCOp = MCOperand::createReg(MO.getReg()); + break; + case MachineOperand::MO_Immediate: + MCOp = MCOperand::createImm(MO.getImm()); + break; + case MachineOperand::MO_MachineBasicBlock: + case MachineOperand::MO_GlobalAddress: + case MachineOperand::MO_ExternalSymbol: + case MachineOperand::MO_JumpTableIndex: + case MachineOperand::MO_ConstantPoolIndex: + case MachineOperand::MO_BlockAddress: + MCOp = LowerSymbolOperand(MO, MO.getType(), offset); + break; + case MachineOperand::MO_RegisterMask: + continue; + } + + OutMI.addOperand(MCOp); + } +}