Fix bugs in FITOS/D instruction generation.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Thu, 8 Nov 2001 05:04:09 +0000 (05:04 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Thu, 8 Nov 2001 05:04:09 +0000 (05:04 +0000)
The space for optional args in the stack frame is now being computed,
so finish the code generation for the variable `alloca'.
Finally, made a major overhaul of how stack frame is managed.

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

lib/Target/SparcV9/SparcV9InstrSelection.cpp

index bf27a2abd5f064228edc7967eaaea35765a5a82e..1af03e7a9b1433145e36abbe6f0dda294514cf2c 100644 (file)
@@ -139,11 +139,11 @@ ChooseBFpccInstruction(const InstructionNode* instrNode,
 // For now, hack this using a little static cache of TmpInstructions.
 // Eventually the entire BURG instruction selection should be put
 // into a separate class that can hold such information.
-// The static cache is not too bad because that memory for these
-// TmpInstructions will be freed elsewhere in any case.
+// The static cache is not too bad because the memory for these
+// TmpInstructions will be freed along with the rest of the Method anyway.
 // 
 static TmpInstruction*
-GetTmpForCC(Value* boolVal, const Method* method)
+GetTmpForCC(Value* boolVal, const Method* method, const Type* ccType)
 {
   typedef  hash_map<const Value*, TmpInstruction*> BoolTmpCache;
   static BoolTmpCache boolToTmpCache;     // Map boolVal -> TmpInstruction*
@@ -157,11 +157,11 @@ GetTmpForCC(Value* boolVal, const Method* method)
       boolToTmpCache.clear();
     }
   
-  // Look for tmpI and create a new one otherswise.
-  // new value is directly written to map using 
+  // Look for tmpI and create a new one otherwise.  The new value is
+  // directly written to map using the ref returned by operator[].
   TmpInstruction*& tmpI = boolToTmpCache[boolVal];
   if (tmpI == NULL)
-    tmpI = new TmpInstruction(TMP_INSTRUCTION_OPCODE, boolVal, NULL);
+    tmpI = new TmpInstruction(TMP_INSTRUCTION_OPCODE, ccType, boolVal, NULL);
   
   return tmpI;
 }
@@ -259,9 +259,12 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
       break;
       
     case ToDoubleTy: 
-      if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
-        opCode = FITOD;
-      else if (opType == Type::LongTy)
+      // Use FXTOD for all integer-to-double conversions.  This has to be
+      // consistent with the code in CreateCodeToCopyIntToFloat() since
+      // that will be used to load the integer into an FP register.
+      // 
+      if (opType == Type::SByteTy || opType == Type::ShortTy ||
+          opType == Type::IntTy || opType == Type::LongTy)
         opCode = FXTOD;
       else if (opType == Type::FloatTy)
         opCode = FSTOD;
@@ -1033,13 +1036,22 @@ GetInstructionsForProlog(BasicBlock* entryBB,
 {
   int64_t s0=0;                // used to avoid overloading ambiguity below
   
+  const MachineFrameInfo& frameInfo = target.getFrameInfo();
+  
   // The second operand is the stack size. If it does not fit in the
   // immediate field, we either have to find an unused register in the
   // caller's window or move some elements to the dynamically allocated
   // area of the stack frame (just above save area and method args).
   Method* method = entryBB->getParent();
-  MachineCodeForMethod& mcodeInfo = method->getMachineCode();
-  unsigned int staticStackSize = mcodeInfo.getStaticStackSize();
+  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+  unsigned int staticStackSize = mcInfo.getStaticStackSize();
+  
+  if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize())
+    staticStackSize = (unsigned) frameInfo.getMinStackFrameSize();
+  
+  if (unsigned padsz = (staticStackSize %
+                        (unsigned) frameInfo.getStackFrameSizeAlignment()))
+    staticStackSize += padsz;
   
   assert(target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)
          && "Stack size too large for immediate field of SAVE instruction. Need additional work as described in the comment above");
@@ -1047,7 +1059,7 @@ GetInstructionsForProlog(BasicBlock* entryBB,
   mvec[0] = new MachineInstr(SAVE);
   mvec[0]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
   mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
-                                - staticStackSize);
+                                - (int) staticStackSize);
   mvec[0]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
   
   return 1;
@@ -1122,7 +1134,7 @@ unsigned
 GetInstructionsByRule(InstructionNode* subtreeRoot,
                       int ruleForNode,
                       short* nts,
-                      TargetMachine &tgt,
+                      TargetMachine &target,
                       MachineInstr** mvec)
 {
   int numInstr = 1;                    // initialize for common case
@@ -1134,8 +1146,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
   int64_t s0=0, s8=8;                  // variables holding constants to avoid
   uint64_t u0=0;                       // overloading ambiguities below
   
-  UltraSparc& target = (UltraSparc&) tgt;
-  
   for (unsigned i=0; i < MAX_INSTR_PER_VMINSTR; i++)
     mvec[i] = NULL;
   
@@ -1266,9 +1276,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot,
                                                         isFPBranch));
         
-        Value* ccValue = isFPBranch? subtreeRoot->leftChild()->getValue()
-          : GetTmpForCC(subtreeRoot->leftChild()->getValue(),
-                        brInst->getParent()->getParent());
+        Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
+                                     brInst->getParent()->getParent(),
+                                     isFPBranch? Type::FloatTy : Type::IntTy);
         
         mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister, ccValue);
         mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
@@ -1343,7 +1353,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         assert(0 && "VRegList should never be the topmost non-chain rule");
         break;
 
-      case 21: // reg:   Not(reg):     Implemented as reg = reg XOR-NOT 0
+      case 21: // bool:  Not(bool):    Both these are implemented as:
+      case 321:        // reg:   BNot(reg) :        reg = reg XOR-NOT 0
         mvec[0] = new MachineInstr(XNOR);
         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
                                       subtreeRoot->leftChild()->getValue());
@@ -1408,7 +1419,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
           }
         else
           {
-            opType = subtreeRoot->leftChild()->getValue()->getType();
+            leftVal = subtreeRoot->leftChild()->getValue();
+            opType = leftVal->getType();
             MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
             if (opCode == INVALID_OPCODE)      // no conversion needed
               {
@@ -1417,8 +1429,42 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
               }
             else
               {
-                mvec[0] = new MachineInstr(opCode);
-                Set2OperandsFromInstr(mvec[0], subtreeRoot, target);
+                // If the source operand is a non-FP type it must be
+                // first copied from int to float register via memory!
+                Instruction *dest = subtreeRoot->getInstruction();
+                Value* srcForCast;
+                int n = 0;
+                if (opType != Type::FloatTy && opType != Type::DoubleTy)
+                  {
+                    // Create a temporary to represent the FP register
+                    // into which the integer will be copied via memory.
+                    srcForCast = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
+                                                    dest, NULL);
+                    dest->getMachineInstrVec().addTempValue(srcForCast);
+                    
+                    vector<MachineInstr*> minstrVec;
+                    vector<TmpInstruction*> tempVec;
+                    target.getInstrInfo().CreateCodeToCopyIntToFloat(
+                         dest->getParent()->getParent(),
+                         leftVal, (TmpInstruction*) srcForCast,
+                         minstrVec, tempVec, target);
+                    
+                    for (unsigned i=0; i < minstrVec.size(); ++i)
+                      mvec[n++] = minstrVec[i];
+
+                    for (unsigned i=0; i < tempVec.size(); ++i)
+                       dest->getMachineInstrVec().addTempValue(tempVec[i]);
+                  }
+                else
+                  srcForCast = leftVal;
+                
+                MachineInstr* castI = new MachineInstr(opCode);
+                castI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+                                            srcForCast);
+                castI->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
+                                            dest);
+                mvec[n++] = castI;
+                numInstr = n;
               }
           }
         break;
@@ -1528,35 +1574,44 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         break;
       }
       
-      case  38:        // reg:   And(reg, reg)
-      case 238:        // reg:   And(reg, Constant)
+      case  38:        // bool:   And(bool, bool)
+      case 238:        // bool:   And(bool, boolconst)
+      case 338:        // reg :   BAnd(reg, reg)
+      case 538:        // reg :   BAnd(reg, Constant)
         mvec[0] = new MachineInstr(AND);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case 138:        // reg:   And(reg, not)
+      case 138:        // bool:   And(bool, not)
+      case 438:        // bool:   BAnd(bool, not)
         mvec[0] = new MachineInstr(ANDN);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case  39:        // reg:   Or(reg, reg)
-      case 239:        // reg:   Or(reg, Constant)
+      case  39:        // bool:   Or(bool, bool)
+      case 239:        // bool:   Or(bool, boolconst)
+      case 339:        // reg :   BOr(reg, reg)
+      case 539:        // reg :   BOr(reg, Constant)
         mvec[0] = new MachineInstr(ORN);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case 139:        // reg:   Or(reg, not)
+      case 139:        // bool:   Or(bool, not)
+      case 439:        // bool:   BOr(bool, not)
         mvec[0] = new MachineInstr(ORN);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case  40:        // reg:   Xor(reg, reg)
-      case 240:        // reg:   Xor(reg, Constant)
+      case  40:        // bool:   Xor(bool, bool)
+      case 240:        // bool:   Xor(bool, boolconst)
+      case 340:        // reg :   BXor(reg, reg)
+      case 540:        // reg :   BXor(reg, Constant)
         mvec[0] = new MachineInstr(XOR);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
 
-      case 140:        // reg:   Xor(reg, not)
+      case 140:        // bool:   Xor(bool, not)
+      case 440:        // bool:   BXor(bool, not)
         mvec[0] = new MachineInstr(XNOR);
         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
         break;
@@ -1617,10 +1672,28 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         bool mustClearReg;
         int valueToMove;
         MachineOpCode movOpCode = 0;
-        Value* ccValue = NULL;
+
+        // Mark the 4th operand as being a CC register, and as a def
+        // A TmpInstruction is created to represent the CC "result".
+        // Unlike other instances of TmpInstruction, this one is used
+        // by machine code of multiple LLVM instructions, viz.,
+        // the SetCC and the branch.  Make sure to get the same one!
+        // Note that we do this even for FP CC registers even though they
+        // are explicit operands, because the type of the operand
+        // needs to be a floating point condition code, not an integer
+        // condition code.  Think of this as casting the bool result to
+        // a FP condition code register.
+        // 
+        leftVal = subtreeRoot->leftChild()->getValue();
+        bool isFPCompare = (leftVal->getType() == Type::FloatTy || 
+                            leftVal->getType() == Type::DoubleTy);
+        
+        TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
+                                     setCCInstr->getParent()->getParent(),
+                                     isFPCompare? Type::FloatTy : Type::IntTy);
+        setCCInstr->getMachineInstrVec().addTempValue(tmpForCC);
         
-        if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral() ||
-            subtreeRoot->leftChild()->getValue()->getType()->isPointerType())
+        if (! isFPCompare)
           {
             // Integer condition: dest. should be %g0 or an integer register.
             // If result must be saved but condition is not SetEQ then we need
@@ -1630,16 +1703,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             mvec[0] = new MachineInstr(SUBcc);
             Set3OperandsFromInstr(mvec[0], subtreeRoot, target, ! keepSubVal);
             
-            // Mark the 4th operand as being a CC register, and as a def
-            // A TmpInstruction is created to represent the int CC "result".
-            // Unlike other instances of TmpInstruction, this one is used by
-            // used by machine code of multiple LLVM instructions, viz.,
-            // the SetCC and the branch.  Make sure to get the same one!
-            // 
-            TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
-                                         setCCInstr->getParent()->getParent());
-            setCCInstr->getMachineInstrVec().addTempValue(tmpForCC);
-            
             mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
                                           tmpForCC, /*def*/true);
             
@@ -1647,7 +1710,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
               { // recompute bool using the integer condition codes
                 movOpCode =
                   ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove);
-                ccValue = tmpForCC;
               }
           }
         else
@@ -1655,7 +1717,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             // FP condition: dest of FCMP should be some FCCn register
             mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
             mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                          setCCInstr);
+                                          tmpForCC);
             mvec[0]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
                                          subtreeRoot->leftChild()->getValue());
             mvec[0]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
@@ -1666,14 +1728,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 mustClearReg = true;
                 valueToMove = 1;
                 movOpCode = ChooseMovFpccInstruction(subtreeRoot);
-                ccValue = setCCInstr;
               }
           }
         
         if (computeBoolVal)
           {
-            assert(ccValue && "Inconsistent logic above and here");
-            
             if (mustClearReg)
               {// Unconditionally set register to 0
                int n = numInstr++;
@@ -1688,7 +1747,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             int n = numInstr++;
             mvec[n] = new MachineInstr(movOpCode);
             mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                          ccValue);
+                                          tmpForCC);
             mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
                                           valueToMove);
             mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
@@ -1742,12 +1801,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         assert(tsize != 0 && "Just to check when this can happen");
         
         Method* method = instr->getParent()->getParent();
-        MachineCodeForMethod& mcode = method->getMachineCode();
-        int offsetFromFP =
-          target.getFrameInfo().getFirstAutomaticVarOffsetFromFP(method)
-          - (tsize + mcode.getAutomaticVarsSize());
-        
-        mcode.putLocalVarAtOffsetFromFP(instr, offsetFromFP, tsize);
+        MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+        int offsetFromFP = mcInfo.allocateLocalVar(target, instr);
         
         // Create a temporary Value to hold the constant offset.
         // This is needed because it may not fit in the immediate field.
@@ -1782,17 +1837,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         
         // Create a temporary Value to hold the constant offset from SP
         Method* method = instr->getParent()->getParent();
-        MachineCodeForMethod& mcode = method->getMachineCode();
-        int frameSizeBelowDynamicArea =
-          target.getFrameInfo().getFrameSizeBelowDynamicArea(method);
-        ConstPoolSInt* lowerAreaSizeVal = ConstPoolSInt::get(Type::IntTy,
-                                                  frameSizeBelowDynamicArea);
-        cerr << "***" << endl
-             << "*** Variable-size ALLOCA operation needs more work:" << endl
-             << "*** We have to precompute the size of "
-             << " optional arguments in the stack frame" << endl
-             << "***" << endl; 
-        assert(0 && "SEE MESSAGE ABOVE");
+        bool ignore;                    // we don't need this 
+        ConstPoolSInt* dynamicAreaOffset = ConstPoolSInt::get(Type::IntTy,
+          target.getFrameInfo().getDynamicAreaOffset(MachineCodeForMethod::get(method),
+                                                     ignore));
         
         // Create a temporary value to hold `tmp'
         Instruction* tmpInstr = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
@@ -1822,7 +1870,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         mvec[2] = new MachineInstr(ADD);
         mvec[2]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
         mvec[2]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      lowerAreaSizeVal);
+                                      dynamicAreaOffset);
         mvec[2]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,instr);
         break;
       }