Infrastructure for getting the machine code size of a function and an instruction...
[oota-llvm.git] / lib / Target / Mips / MipsAsmPrinter.cpp
index 2dc9c2f2663dca51f78e7c730e42e763776d4a14..6c0c908ae7b06f0bdaaed06f014e2064c72262c0 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Bruno Cardoso Lopes and is distributed under the 
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -29,6 +29,7 @@
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/SetVector.h"
@@ -109,11 +110,11 @@ FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o,
 //
 //  Consider the following function prologue:
 //
-//    .frame   $fp,48,$ra
-//    .mask      0xc0000000,-8
-//       addiu $sp, $sp, -48
-//       sw $ra, 40($sp)
-//       sw $fp, 36($sp)
+//    .frame  $fp,48,$ra
+//    .mask   0xc0000000,-8
+//       addiu $sp, $sp, -48
+//       sw $ra, 40($sp)
+//       sw $fp, 36($sp)
 //
 //    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 
 //    30 (FP) are saved at prologue. As the save order on prologue is from 
@@ -161,16 +162,16 @@ emitFMaskDirective(MachineFunction &MF)
 void MipsAsmPrinter::
 emitFrameDirective(MachineFunction &MF)
 {
-  const MRegisterInfo &RI = *TM.getRegisterInfo();
+  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).Name) 
+  O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName)
                     << "," << stackSize << ","
-                    << "$" << LowercaseString(RI.get(returnReg).Name) 
+                    << "$" << LowercaseString(RI.get(returnReg).AsmName)
                     << "\n";
 }
 
@@ -194,7 +195,7 @@ emitSetDirective(SetDirectiveFlags Flag)
 unsigned int MipsAsmPrinter::
 getSavedRegsBitmask(bool isFloat, MachineFunction &MF)
 {
-  const MRegisterInfo &RI = *TM.getRegisterInfo();
+  const TargetRegisterInfo &RI = *TM.getRegisterInfo();
              
   // Float Point Registers, TODO
   if (isFloat)
@@ -237,9 +238,8 @@ emitFunctionStart(MachineFunction &MF)
   const Function *F = MF.getFunction();
   SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
 
-  // On Mips GAS, if .align #n is present, #n means the number of bits 
-  // to be cleared. So, if we want 4 byte alignment, we must have .align 2
-  EmitAlignment(1, F);
+  // 2 bits aligned
+  EmitAlignment(2, F);
 
   O << "\t.globl\t"  << CurrentFnName << "\n";
   O << "\t.ent\t"    << CurrentFnName << "\n";
@@ -280,6 +280,9 @@ runOnMachineFunction(MachineFunction &MF)
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
+  // Print out jump tables referenced by the function
+  EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
+
   O << "\n\n";
 
   // What's my mangled name?
@@ -294,14 +297,13 @@ runOnMachineFunction(MachineFunction &MF)
 
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true);
+      printBasicBlockLabel(I, true, true);
       O << '\n';
     }
 
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printInstruction(II);
       ++EmittedInsts;
     }
@@ -321,7 +323,7 @@ void MipsAsmPrinter::
 printOperand(const MachineInstr *MI, int opNum) 
 {
   const MachineOperand &MO = MI->getOperand(opNum);
-  const MRegisterInfo  &RI = *TM.getRegisterInfo();
+  const TargetRegisterInfo  &RI = *TM.getRegisterInfo();
   bool closeP = false;
   bool isPIC = (TM.getRelocationModel() == Reloc::PIC_);
   bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
@@ -362,8 +364,8 @@ printOperand(const MachineInstr *MI, int opNum)
   switch (MO.getType()) 
   {
     case MachineOperand::MO_Register:
-      if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
-        O << "$" << LowercaseString (RI.get(MO.getReg()).Name);
+      if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+        O << "$" << LowercaseString (RI.get(MO.getReg()).AsmName);
       else
         O << "$" << MO.getReg();
       break;
@@ -371,13 +373,13 @@ printOperand(const MachineInstr *MI, int opNum)
     case MachineOperand::MO_Immediate:
       if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) || 
           (MI->getOpcode() == Mips::LUi)   || (MI->getOpcode() == Mips::ANDi))
-        O << (unsigned short int)MO.getImmedValue();
+        O << (unsigned short int)MO.getImm();
       else
-        O << (short int)MO.getImmedValue();
+        O << (short int)MO.getImm();
       break;
 
     case MachineOperand::MO_MachineBasicBlock:
-      printBasicBlockLabel(MO.getMachineBasicBlock());
+      printBasicBlockLabel(MO.getMBB());
       return;
 
     case MachineOperand::MO_GlobalAddress:
@@ -388,10 +390,15 @@ printOperand(const MachineInstr *MI, int opNum)
       O << MO.getSymbolName();
       break;
 
+    case MachineOperand::MO_JumpTableIndex:
+      O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+      << '_' << MO.getIndex();
+      break;
+
     // FIXME: Verify correct
     case MachineOperand::MO_ConstantPoolIndex:
       O << TAI->getPrivateGlobalPrefix() << "CPI"
-        << getFunctionNumber() << "_" << MO.getConstantPoolIndex();
+        << getFunctionNumber() << "_" << MO.getIndex();
       break;
   
     default:
@@ -450,19 +457,30 @@ doFinalization(Module &M)
       std::string name = Mang->getValueName(I);
       Constant *C      = I->getInitializer();
       unsigned Size    = TD->getABITypeSize(C->getType());
-      unsigned Align   = TD->getPrefTypeAlignment(C->getType());
+      unsigned Align   = TD->getPreferredAlignmentLog(I);
 
+      // Is this correct ?
       if (C->isNullValue() && (I->hasLinkOnceLinkage() || 
-        I->hasInternalLinkage() || I->hasWeakLinkage() 
-        /* FIXME: Verify correct */)) {
-
-        SwitchToDataSection(".data", I);
-        if (I->hasInternalLinkage())
-          O << "\t.local " << name << "\n";
-
-        O << "\t.comm " << name << "," 
-          << TD->getABITypeSize(C->getType())
-          << "," << Align << "\n";
+          I->hasInternalLinkage() || I->hasWeakLinkage())) 
+      {
+        if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
+
+        if (!NoZerosInBSS && TAI->getBSSSection())
+          SwitchToDataSection(TAI->getBSSSection(), I);
+        else
+          SwitchToDataSection(TAI->getDataSection(), I);
+
+        if (I->hasInternalLinkage()) {
+          if (TAI->getLCOMMDirective())
+            O << TAI->getLCOMMDirective() << name << "," << Size;
+          else            
+            O << "\t.local\t" << name << "\n";
+        } else {
+          O << TAI->getCOMMDirective() << name << "," << Size;
+          // The .comm alignment in bytes.
+          if (TAI->getCOMMDirectiveTakesAlignment())
+            O << "," << (1 << Align);
+        }
 
       } else {
 
@@ -483,24 +501,37 @@ doFinalization(Module &M)
             // something.  For now, just emit them as external.
           case GlobalValue::ExternalLinkage:
             // If external or appending, declare as a global symbol
-            O << "\t.globl " << name << "\n";
+            O << TAI->getGlobalDirective() << name << "\n";
+            // Fall Through
           case GlobalValue::InternalLinkage:
-            if (C->isNullValue())
-              SwitchToDataSection(".bss", I);
-            else
-              SwitchToDataSection(".data", I);
+            // FIXME: special handling for ".ctors" & ".dtors" sections
+            if (I->hasSection() && (I->getSection() == ".ctors" ||
+                I->getSection() == ".dtors")) {
+              std::string SectionName = ".section " + I->getSection();
+              SectionName += ",\"aw\",%progbits";
+              SwitchToDataSection(SectionName.c_str());
+            } else {
+              if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
+                SwitchToDataSection(TAI->getBSSSection(), I);
+              else if (!I->isConstant())
+                SwitchToDataSection(TAI->getDataSection(), I);
+              else {
+                // Read-only data.
+                if (TAI->getReadOnlySection())
+                  SwitchToDataSection(TAI->getReadOnlySection(), I);
+                else
+                  SwitchToDataSection(TAI->getDataSection(), I);
+              }
+            }
             break;
           case GlobalValue::GhostLinkage:
-            cerr << "Should not have any" 
-                 << "unmaterialized functions!\n";
+            cerr << "Should not have any unmaterialized functions!\n";
             abort();
           case GlobalValue::DLLImportLinkage:
-            cerr << "DLLImport linkage is" 
-                 << "not supported by this target!\n";
+            cerr << "DLLImport linkage is not supported by this target!\n";
             abort();
           case GlobalValue::DLLExportLinkage:
-            cerr << "DLLExport linkage is" 
-                 << "not supported by this target!\n";
+            cerr << "DLLExport linkage is not supported by this target!\n";
             abort();
           default:
             assert(0 && "Unknown linkage type!");