Mask directive completed with CalleeSave info
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Tue, 28 Aug 2007 05:06:17 +0000 (05:06 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Tue, 28 Aug 2007 05:06:17 +0000 (05:06 +0000)
Comments for Mips directives added.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41526 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsInstrInfo.h

index 48879ee3e384f50097a7794c758013c6bc6e19e2..11db54753c116cdcb36fa02d1702b94052bf184c 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/CommandLine.h"
@@ -62,12 +63,14 @@ namespace {
     void printMemOperand(const MachineInstr *MI, int opNum, 
                          const char *Modifier = 0);
 
+    unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
     void printHex32(unsigned int Value);
+
     void emitFunctionStart(MachineFunction &MF);
     void emitFunctionEnd();
     void emitFrameDirective(MachineFunction &MF);
     void emitMaskDirective(MachineFunction &MF);
-    void emitFMaskDirective();
+    void emitFMaskDirective(MachineFunction &MF);
     void emitSetDirective(SetDirectiveFlags Flag);
 
     bool printInstruction(const MachineInstr *MI);  // autogenerated.
@@ -89,96 +92,92 @@ FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o,
   return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo());
 }
 
-/// This pattern will be emitted :
-///   .frame reg1, size, reg2
-/// It describes the stack frame. 
-/// reg1 - stack pointer
-/// size - stack size allocated for the function
-/// reg2 - return address register
-void MipsAsmPrinter::
-emitFrameDirective(MachineFunction &MF)
-{
-  const MRegisterInfo &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) 
-                    << "," << stackSize << ","
-                    << "$" << LowercaseString(RI.get(returnReg).Name) 
-                    << "\n";
-}
+//===----------------------------------------------------------------------===//
+//
+//  Mips Asm Directives
+//
+//  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
+//  Describe the stack frame.
+//
+//  -- Mask directives "(f)mask  bitmask, offset" 
+//  Tells the assembler which registers are saved and where.
+//  bitmask - contain a little endian bitset indicating which registers are 
+//            saved on function prologue (e.g. with a 0x80000000 mask, the 
+//            assembler knows the register 31 (RA) is saved at prologue.
+//  offset  - the position before stack pointer subtraction indicating where 
+//            the first saved register on prologue is located. (e.g. with a
+//
+//  Consider the following function prologue:
+//
+//    .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 
+//    left to right, RA is saved first. A -8 offset means that after the 
+//    stack pointer subtration, the first register in the mask (RA) will be
+//    saved at address 48-8=40.
+//
+//===----------------------------------------------------------------------===//
 
-/// This pattern will be emitted :
-///   .mask bitmask, offset
-/// Tells the assembler (and possibly linker) which registers are saved and where. 
-/// bitmask - mask of all GPRs (little endian) 
-/// offset  - negative value. offset+stackSize should give where on the stack
-///           the first GPR is saved.
-/// TODO: consider calle saved GPR regs here, not hardcode register numbers.
+/// Mask directive for GPR
 void MipsAsmPrinter::
 emitMaskDirective(MachineFunction &MF)
 {
-  const MRegisterInfo &RI  = *TM.getRegisterInfo();
   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
 
-  bool hasFP  = RI.hasFP(MF);
-  bool saveRA = MF.getFrameInfo()->hasCalls();
-
-  int offset;
-
-  if (!MipsFI->getTopSavedRegOffset())
-    offset = 0;
-  else
-    offset = -(MF.getFrameInfo()->getStackSize()
-               -MipsFI->getTopSavedRegOffset());
-
+  int StackSize = MF.getFrameInfo()->getStackSize();
+  int Offset    = (!MipsFI->getTopSavedRegOffset()) ? 0 : 
+                  (-(StackSize-MipsFI->getTopSavedRegOffset()));
+             
   #ifndef NDEBUG
-  DOUT << "<--ASM PRINTER--emitMaskDirective-->" << "\n";
-  DOUT << "StackSize :  " << MF.getFrameInfo()->getStackSize() << "\n";
-  DOUT << "getTopSavedRegOffset() : " << MipsFI->getTopSavedRegOffset() << "\n";
-  DOUT << "offset : " << offset << "\n\n";
+  DOUT << "--> emitMaskDirective" << "\n";
+  DOUT << "StackSize :  " << StackSize << "\n";
+  DOUT << "getTopSavedReg : " << MipsFI->getTopSavedRegOffset() << "\n";
+  DOUT << "Offset : " << Offset << "\n\n";
   #endif
 
-  unsigned int bitmask = 0;
-
-  if (hasFP) 
-    bitmask |= (1 << 30);
-  
-  if (saveRA) 
-    bitmask |= (1 << 31);
-
+  unsigned int Bitmask = getSavedRegsBitmask(false, MF);
   O << "\t.mask\t"; 
-  printHex32(bitmask);
-  O << "," << offset << "\n";
+  printHex32(Bitmask);
+  O << "," << Offset << "\n";
 }
 
-/// This pattern will be emitted :
-///   .fmask bitmask, offset
-/// Tells the assembler (and possibly linker) which float registers are saved.
-/// bitmask - mask of all Float Point registers (little endian) 
-/// offset  - negative value. offset+stackSize should give where on the stack
-///           the first Float Point register is saved.
-/// TODO: implement this, dummy for now
+/// TODO: Mask Directive for Float Point
 void MipsAsmPrinter::
-emitFMaskDirective()
+emitFMaskDirective(MachineFunction &MF)
 {
-  O << "\t.fmask\t0x00000000,0" << "\n";
+  unsigned int Bitmask = getSavedRegsBitmask(true, MF);
+
+  O << "\t.fmask\t";
+  printHex32(Bitmask);
+  O << ",0" << "\n";
 }
 
-/// Print a 32 bit hex number filling with 0's on the left.
-/// TODO: make this setfill and setw
+/// Frame Directive
 void MipsAsmPrinter::
-printHex32(unsigned int Value) {
-  O << "0x" << std::hex << Value << std::dec;  
+emitFrameDirective(MachineFunction &MF)
+{
+  const MRegisterInfo &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) 
+                    << "," << stackSize << ","
+                    << "$" << LowercaseString(RI.get(returnReg).Name) 
+                    << "\n";
 }
 
 /// Emit Set directives.
 void MipsAsmPrinter::
-emitSetDirective(SetDirectiveFlags Flag) {
-  
+emitSetDirective(SetDirectiveFlags Flag) 
+{  
   O << "\t.set\t";
   switch(Flag) {
       case REORDER:   O << "reorder" << "\n"; break;
@@ -187,6 +186,45 @@ emitSetDirective(SetDirectiveFlags Flag) {
       case NOMACRO:   O << "nomacro" << "\n"; break;
       default: break;
   }
+}  
+
+// Create a bitmask with all callee saved registers for CPU
+// or Float Point registers. For CPU registers consider RA,
+// GP and FP for saving if necessary.
+unsigned int MipsAsmPrinter::
+getSavedRegsBitmask(bool isFloat, MachineFunction &MF)
+{
+  const MRegisterInfo &RI = *TM.getRegisterInfo();
+             
+  // Float Point Registers, TODO
+  if (isFloat)
+    return 0;
+
+  // CPU Registers
+  unsigned int Bitmask = 0;
+
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
+  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
+    Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg()));
+
+  if (RI.hasFP(MF)) 
+    Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getFrameRegister(MF)));
+  
+  if (MF.getFrameInfo()->hasCalls()) 
+    Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getRARegister()));
+
+  return Bitmask;
+}
+
+// Print a 32 bit hex number with all numbers.
+void MipsAsmPrinter::
+printHex32(unsigned int Value) 
+{
+  O << "0x" << std::hex;
+  for (int i = 7; i >= 0; i--) 
+    O << std::hex << ( (Value & (0xF << (i*4))) >> (i*4) );
+  O << std::dec;
 }
 
 /// Emit the directives used by GAS on the start of functions
@@ -208,7 +246,7 @@ emitFunctionStart(MachineFunction &MF)
 
   emitFrameDirective(MF);
   emitMaskDirective(MF);
-  emitFMaskDirective();
+  emitFMaskDirective(MF);
   emitSetDirective(NOREORDER);
   emitSetDirective(NOMACRO);
   O << "\n";
@@ -420,6 +458,7 @@ doFinalization(Module &M)
           default:
             assert(0 && "Unknown linkage type!");          
         }
+
         O << "\t.align " << Align << "\n";
         O << "\t.type " << name << ",@object\n";
         O << "\t.size " << name << "," << Size << "\n";
index b120f23256405e6add17bec512f3b8ae0fd846a5..f86f193118521681ee179fbe6e38bbe9cebbc4ef 100644 (file)
@@ -22,8 +22,7 @@ namespace llvm {
 
 namespace Mips {
 
-  // All CC branch operations on Mips I are turned
-  // into BEQ and BNE CC branches instructions.
+  // Mips Condition Codes
   enum CondCode {
     COND_E,
     COND_GZ,