[Nios2] final infrastructure to provide compilation of a return from a function

This patch includes all missing functionality needed to provide first
compilation of a simple program that just returns from a function.
I've added a test case that checks for "ret" instruction printed in assembly
output.

Patch by Andrei Grischenko (andrei.l.grischenko@intel.com)
Differential revision: https://reviews.llvm.org/D39688

llvm-svn: 320035
diff --git a/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp b/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp
index 0c70dc0..e57b44d 100644
--- a/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp
+++ b/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp
@@ -12,8 +12,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "Nios2MCTargetDesc.h"
+#include "InstPrinter/Nios2InstPrinter.h"
+#include "Nios2MCAsmInfo.h"
+#include "Nios2TargetStreamer.h"
 #include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/TargetRegistry.h"
 
 using namespace llvm;
 
@@ -26,4 +31,72 @@
 #define GET_REGINFO_MC_DESC
 #include "Nios2GenRegisterInfo.inc"
 
-extern "C" void LLVMInitializeNios2TargetMC() {}
+static MCInstrInfo *createNios2MCInstrInfo() {
+  MCInstrInfo *X = new MCInstrInfo();
+  InitNios2MCInstrInfo(X); // defined in Nios2GenInstrInfo.inc
+  return X;
+}
+
+static MCRegisterInfo *createNios2MCRegisterInfo(const Triple &TT) {
+  MCRegisterInfo *X = new MCRegisterInfo();
+  InitNios2MCRegisterInfo(X, Nios2::R15); // defined in Nios2GenRegisterInfo.inc
+  return X;
+}
+
+static MCSubtargetInfo *
+createNios2MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+  if (CPU.empty() || CPU == "generic")
+    CPU = "nios2r1";
+  return createNios2MCSubtargetInfoImpl(TT, CPU, FS);
+  // createNios2MCSubtargetInfoImpl defined in Nios2GenSubtargetInfo.inc
+}
+
+static MCAsmInfo *createNios2MCAsmInfo(const MCRegisterInfo &MRI,
+                                       const Triple &TT) {
+  MCAsmInfo *MAI = new Nios2MCAsmInfo(TT);
+
+  unsigned SP = MRI.getDwarfRegNum(Nios2::SP, true);
+  MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0);
+  MAI->addInitialFrameState(Inst);
+
+  return MAI;
+}
+
+static MCInstPrinter *createNios2MCInstPrinter(const Triple &T,
+                                               unsigned SyntaxVariant,
+                                               const MCAsmInfo &MAI,
+                                               const MCInstrInfo &MII,
+                                               const MCRegisterInfo &MRI) {
+  return new Nios2InstPrinter(MAI, MII, MRI);
+}
+
+static MCTargetStreamer *createNios2AsmTargetStreamer(MCStreamer &S,
+                                                      formatted_raw_ostream &OS,
+                                                      MCInstPrinter *InstPrint,
+                                                      bool isVerboseAsm) {
+  return new Nios2TargetAsmStreamer(S, OS);
+}
+
+extern "C" void LLVMInitializeNios2TargetMC() {
+  Target *T = &getTheNios2Target();
+
+  // Register the MC asm info.
+  RegisterMCAsmInfoFn X(*T, createNios2MCAsmInfo);
+
+  // Register the MC instruction info.
+  TargetRegistry::RegisterMCInstrInfo(*T, createNios2MCInstrInfo);
+
+  // Register the MC register info.
+  TargetRegistry::RegisterMCRegInfo(*T, createNios2MCRegisterInfo);
+
+  // Register the asm target streamer.
+  TargetRegistry::RegisterAsmTargetStreamer(*T, createNios2AsmTargetStreamer);
+
+  // Register the MC subtarget info.
+  TargetRegistry::RegisterMCSubtargetInfo(*T, createNios2MCSubtargetInfo);
+  // Register the MCInstPrinter.
+  TargetRegistry::RegisterMCInstPrinter(*T, createNios2MCInstPrinter);
+
+  // Register the asm backend.
+  TargetRegistry::RegisterMCAsmBackend(*T, createNios2AsmBackend);
+}