From ea21a6c82acb8ed58f60cc27dcc1584a618eacaa Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sat, 20 Oct 2001 20:57:06 +0000 Subject: [PATCH] Use CALL for direct function calls; JMPL for indirect ones. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@927 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SparcV9/SparcV9InstrSelection.cpp | 45 +++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index ac8388a27bf..8841cc8ed81 100644 --- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp +++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp @@ -1708,8 +1708,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, CallInst *callInstr = cast(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; -- 2.34.1