Use CALL for direct function calls; JMPL for indirect ones.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 20 Oct 2001 20:57:06 +0000 (20:57 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 20 Oct 2001 20:57:06 +0000 (20:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@927 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/SparcV9InstrSelection.cpp

index ac8388a27bf0aa9a8b3c650d38fc662ec2e92746..8841cc8ed81c245016ae359e8974c10b71aba41d 100644 (file)
@@ -1708,8 +1708,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
         Value *callee = callInstr->getCalledValue();
         
-        Instruction* jmpAddrReg = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                                     callee, NULL);
         Instruction* retAddrReg = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
                                                      callInstr, NULL);
         
@@ -1719,33 +1717,42 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         //          The result value must go in slot N.  This is assumed
         //          in register allocation.
         // 
-        callInstr->getMachineInstrVec().addTempValue(jmpAddrReg);
         callInstr->getMachineInstrVec().addTempValue(retAddrReg);
         
-        // Generate the machine instruction and its operands
-        mvec[0] = new MachineInstr(JMPL);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                      jmpAddrReg);
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
-                                      (int64_t) 0);
-        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                      retAddrReg);
+        
+        // Generate the machine instruction and its operands.
+        // Use CALL for direct function calls; this optimistically assumes
+        // the PC-relative address fits in the CALL address field (22 bits).
+        // Use JMPL for indirect calls.
+        // 
+        if (callee->getValueType() == Value::MethodVal)
+          { // direct function call
+            mvec[0] = new MachineInstr(CALL);
+            mvec[0]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
+                                          callee);
+          } 
+        else
+          { // indirect function call
+            mvec[0] = new MachineInstr(JMPL);
+            mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+                                          callee);
+            mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+                                          (int64_t) 0);
+            mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
+                                          retAddrReg);
+          }
         
         // Add the call operands and return value as implicit refs
         for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
           if (callInstr->getOperand(i) != callee)
             mvec[0]->addImplicitRef(callInstr->getOperand(i));
         
-        if (callInstr->getCalledMethod()->getReturnType() != Type::VoidTy)
+        if (callInstr->getType() != Type::VoidTy)
           mvec[0]->addImplicitRef(callInstr, /*isDef*/ true);
         
-        // NOTE: jmpAddrReg will be loaded by a different instruction generated
-        //   by the final code generator, so we just mark the CALL instruction
-        //   as computing that value.
-        //   The retAddrReg is actually computed by the CALL instruction.
-        //
-        // jmpAddrReg->addMachineInstruction(mvec[0]);
-        // retAddrReg->addMachineInstruction(mvec[0]);
+        // For the CALL instruction, the ret. addr. reg. is also implicit
+        if (callee->getValueType() == Value::MethodVal)
+          mvec[0]->addImplicitRef(retAddrReg, /*isDef*/ true);
         
         mvec[numInstr++] = new MachineInstr(NOP); // delay slot
         break;