Added Subtarget support into RegisterInfo
Added HasABICall and HasAbsoluteCall (equivalent to gcc -mabicall and 
-mno-shared). HasAbsoluteCall is not implemented but HasABICall is the 
default for o32 ABI. Now, both should help into a more accurate 
relocation types implementation. 
Added IsLinux is needed to choose between asm directives.
Instruction name strings cleanup.
AsmPrinter improved.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53551 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 178ca14..d2288e6 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -15,6 +15,7 @@
 #define DEBUG_TYPE "mips-asm-printer"
 
 #include "Mips.h"
+#include "MipsSubtarget.h"
 #include "MipsInstrInfo.h"
 #include "MipsTargetMachine.h"
 #include "MipsMachineFunction.h"
@@ -44,21 +45,19 @@
 
 namespace {
   struct VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter {
+
+    const MipsSubtarget *Subtarget;
+
     MipsAsmPrinter(std::ostream &O, MipsTargetMachine &TM, 
                    const TargetAsmInfo *T): 
-                   AsmPrinter(O, TM, T) {}
+                   AsmPrinter(O, TM, T) {
+      Subtarget = &TM.getSubtarget<MipsSubtarget>();
+    }
 
     virtual const char *getPassName() const {
       return "Mips Assembly Printer";
     }
 
-    enum SetDirectiveFlags {
-      REORDER,      // enables instruction reordering.
-      NOREORDER,    // disables instruction reordering.
-      MACRO,        // enables GAS macros.
-      NOMACRO       // disables GAS macros.
-    };
-
     void printOperand(const MachineInstr *MI, int opNum);
     void printMemOperand(const MachineInstr *MI, int opNum, 
                          const char *Modifier = 0);
@@ -68,13 +67,13 @@
     unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
     void printHex32(unsigned int Value);
 
+    const char *emitCurrentABIString(void);
     void emitFunctionStart(MachineFunction &MF);
     void emitFunctionEnd(MachineFunction &MF);
     void emitFrameDirective(MachineFunction &MF);
     void emitMaskDirective(MachineFunction &MF);
     void emitFMaskDirective(MachineFunction &MF);
-    void emitSetDirective(SetDirectiveFlags Flag);
-
+    
     bool printInstruction(const MachineInstr *MI);  // autogenerated.
     bool runOnMachineFunction(MachineFunction &F);
     bool doInitialization(Module &M);
@@ -125,6 +124,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+//===----------------------------------------------------------------------===//
+// Mask directives
+//===----------------------------------------------------------------------===//
+
 /// Mask directive for GPR
 void MipsAsmPrinter::
 emitMaskDirective(MachineFunction &MF)
@@ -159,37 +162,6 @@
   O << ",0" << "\n";
 }
 
-/// Frame Directive
-void MipsAsmPrinter::
-emitFrameDirective(MachineFunction &MF)
-{
-  const TargetRegisterInfo &RI = *TM.getRegisterInfo();
-
-  unsigned stackReg  = RI.getFrameRegister(MF);
-  unsigned returnReg = RI.getRARegister();
-  unsigned stackSize = MF.getFrameInfo()->getStackSize();
-
-
-  O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName)
-                    << "," << stackSize << ","
-                    << "$" << LowercaseString(RI.get(returnReg).AsmName)
-                    << "\n";
-}
-
-/// Emit Set directives.
-void MipsAsmPrinter::
-emitSetDirective(SetDirectiveFlags Flag) 
-{  
-  O << "\t.set\t";
-  switch(Flag) {
-      case REORDER:   O << "reorder" << "\n"; break;
-      case NOREORDER: O << "noreorder" << "\n"; break;
-      case MACRO:     O << "macro" << "\n"; break;
-      case NOMACRO:   O << "nomacro" << "\n"; break;
-      default: break;
-  }
-}  
-
 // Create a bitmask with all callee saved registers for CPU
 // or Floating Point registers. For CPU registers consider RA,
 // GP and FP for saving if necessary.
@@ -231,6 +203,44 @@
   O << std::dec;
 }
 
+//===----------------------------------------------------------------------===//
+// Frame and Set directives
+//===----------------------------------------------------------------------===//
+
+/// Frame Directive
+void MipsAsmPrinter::
+emitFrameDirective(MachineFunction &MF)
+{
+  const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+
+  unsigned stackReg  = RI.getFrameRegister(MF);
+  unsigned returnReg = RI.getRARegister();
+  unsigned stackSize = MF.getFrameInfo()->getStackSize();
+
+
+  O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName)
+                    << "," << stackSize << ","
+                    << "$" << LowercaseString(RI.get(returnReg).AsmName)
+                    << "\n";
+}
+
+/// Emit Set directives.
+const char * MipsAsmPrinter::
+emitCurrentABIString(void) 
+{  
+  switch(Subtarget->getTargetABI()) {
+    case MipsSubtarget::O32:  return "abi32";  
+    case MipsSubtarget::O64:  return "abiO64";
+    case MipsSubtarget::N32:  return "abiN32";
+    case MipsSubtarget::N64:  return "abi64";
+    case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
+    default: break;
+  }
+
+  assert(0 && "Unknown Mips ABI");
+  return NULL;
+}  
+
 /// Emit the directives used by GAS on the start of functions
 void MipsAsmPrinter::
 emitFunctionStart(MachineFunction &MF)
@@ -244,18 +254,16 @@
 
   O << "\t.globl\t"  << CurrentFnName << "\n";
   O << "\t.ent\t"    << CurrentFnName << "\n";
-  O << "\t.type\t"   << CurrentFnName << ", @function\n";
+
+  if ((TAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
+    O << "\t.type\t"   << CurrentFnName << ", @function\n";
+
   O << CurrentFnName << ":\n";
 
   emitFrameDirective(MF);
   emitMaskDirective(MF);
   emitFMaskDirective(MF);
 
-  if (TM.getRelocationModel() == Reloc::Static) {
-    emitSetDirective(NOREORDER);
-    emitSetDirective(NOMACRO);
-  }
-
   O << "\n";
 }
 
@@ -263,12 +271,15 @@
 void MipsAsmPrinter::
 emitFunctionEnd(MachineFunction &MF) 
 {
-  if (TM.getRelocationModel() == Reloc::Static) {
-    emitSetDirective(MACRO);
-    emitSetDirective(REORDER);
-  }    
+  // There are instruction for this macros, but they must
+  // always be at the function end, and we can't emit and
+  // break with BB logic. 
+  O << "\t.set\tmacro\n"; 
+  O << "\t.set\treorder\n"; 
 
   O << "\t.end\t" << CurrentFnName << "\n";
+  if (TAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux())
+    O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << "\n";
 }
 
 /// runOnMachineFunction - This uses the printMachineInstruction()
@@ -441,6 +452,18 @@
 doInitialization(Module &M) 
 {
   Mang = new Mangler(M);
+
+  // Tell the assembler which ABI we are using
+  O << "\t.section .mdebug." << emitCurrentABIString() << "\n";
+
+  // TODO: handle O64 ABI
+  if (Subtarget->isABI_EABI())
+    O << "\t.section .gcc_compiled_long" << 
+      (Subtarget->isGP32bit() ? "32" : "64") << "\n";
+
+  // return to previous section
+  O << "\t.previous" << "\n"; 
+
   return false; // success
 }
 
@@ -548,8 +571,11 @@
         }
 
         O << "\t.align " << Align << "\n";
-        O << "\t.type " << name << ",@object\n";
-        O << "\t.size " << name << "," << Size << "\n";
+
+        if (TAI->hasDotTypeDotSizeDirective()) {
+          O << "\t.type " << name << ",@object\n";
+          O << "\t.size " << name << "," << Size << "\n";
+        }
         O << name << ":\n";
         EmitGlobalConstant(C);
     }