aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SparcV9/SparcV9InstrSelection.cpp
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-04-25 04:37:51 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-04-25 04:37:51 +0000
commitdbc4fad5773460fb5c44ac1f8c783b8e172d2f60 (patch)
tree481978de622b51a678d803b68ea844f323994040 /lib/Target/SparcV9/SparcV9InstrSelection.cpp
parenta4a943dd5a5af56bb6d050a0a47f947d4b179420 (diff)
downloadexternal_llvm-dbc4fad5773460fb5c44ac1f8c783b8e172d2f60.zip
external_llvm-dbc4fad5773460fb5c44ac1f8c783b8e172d2f60.tar.gz
external_llvm-dbc4fad5773460fb5c44ac1f8c783b8e172d2f60.tar.bz2
Insert copy operations for FP arguments to a varargs function,
to copy the FP arg. to an integer. Necessary so that the register allocator has two different live ranges for the FP value and the int. argument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SparcV9/SparcV9InstrSelection.cpp')
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp100
1 files changed, 69 insertions, 31 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index a5c1a35..5e6aafd 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -239,12 +239,11 @@ ChooseMovpccAfterSub(const InstructionNode* instrNode,
}
static inline MachineOpCode
-ChooseConvertToFloatInstr(const InstructionNode* instrNode,
- const Type* opType)
+ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
{
MachineOpCode opCode = INVALID_OPCODE;
- switch(instrNode->getOpLabel())
+ switch(vopCode)
{
case ToFloatTy:
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
@@ -285,14 +284,11 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
}
static inline MachineOpCode
-ChooseConvertToIntInstr(const InstructionNode* instrNode,
- const Type* opType)
+ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
{
MachineOpCode opCode = INVALID_OPCODE;;
- int instrType = (int) instrNode->getOpLabel();
-
- if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
+ if (vopCode == ToSByteTy || vopCode == ToShortTy || vopCode == ToIntTy)
{
switch (opType->getPrimitiveID())
{
@@ -303,7 +299,7 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
break;
}
}
- else if (instrType == ToLongTy)
+ else if (vopCode == ToLongTy)
{
switch (opType->getPrimitiveID())
{
@@ -320,6 +316,17 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
return opCode;
}
+MachineInstr*
+CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal)
+{
+ MachineOpCode opCode = ChooseConvertToIntInstr(vopCode, srcVal->getType());
+ assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
+
+ MachineInstr* M = new MachineInstr(opCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, srcVal);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, destVal);
+ return M;
+}
static inline MachineOpCode
ChooseAddInstructionByType(const Type* resultType)
@@ -1565,9 +1572,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
(dest->getType() == Type::LongTy)? Type::DoubleTy
: Type::FloatTy;
destForCast = new TmpInstruction(destTypeToUse, leftVal);
- MachineCodeForInstruction &MCFI =
+ MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest);
- MCFI.addTemp(destForCast);
+ destMCFI.addTemp(destForCast);
vector<TmpInstruction*> tempVec;
target.getInstrInfo().CreateCodeToCopyFloatToInt(
@@ -1576,21 +1583,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
minstrVec, tempVec, target);
for (unsigned i=0; i < tempVec.size(); ++i)
- MCFI.addTemp(tempVec[i]);
+ destMCFI.addTemp(tempVec[i]);
}
else
destForCast = leftVal;
- MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType);
- assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
-
- M = new MachineInstr(opCode);
- M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
- leftVal);
- M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
- destForCast);
+ M = CreateConvertToIntInstr(subtreeRoot->getOpLabel(),
+ leftVal, destForCast);
mvec.push_back(M);
-
+
// Append the copy code, if any, after the conversion instr.
mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
@@ -1616,7 +1617,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{
Value* leftVal = subtreeRoot->leftChild()->getValue();
const Type* opType = leftVal->getType();
- MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
+ MachineOpCode opCode=ChooseConvertToFloatInstr(
+ subtreeRoot->getOpLabel(), opType);
if (opCode == INVALID_OPCODE) // no conversion needed
{
forwardOperandNum = 0; // forward first operand to user
@@ -1641,9 +1643,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
: Type::FloatTy;
srcForCast = new TmpInstruction(srcTypeToUse, dest);
- MachineCodeForInstruction &DestMCFI =
+ MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest);
- DestMCFI.addTemp(srcForCast);
+ destMCFI.addTemp(srcForCast);
vector<MachineInstr*> minstrVec;
vector<TmpInstruction*> tempVec;
@@ -1655,7 +1657,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
for (unsigned i=0; i < tempVec.size(); ++i)
- DestMCFI.addTemp(tempVec[i]);
+ destMCFI.addTemp(tempVec[i]);
}
else
srcForCast = leftVal;
@@ -2003,14 +2005,16 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
}
case 61: // reg: Call
- { // Generate a call-indirect (i.e., jmpl) for now to expose
- // the potential need for registers. If an absolute address
- // is available, replace this with a CALL instruction.
- // Mark both the indirection register and the return-address
- // register as hidden virtual registers.
+ { // Generate a direct (CALL) or indirect (JMPL). depending
+ // Mark the return-address register and the indirection
+ // register (if any) as hidden virtual registers.
// Also, mark the operands of the Call and return value (if
// any) as implicit operands of the CALL machine instruction.
//
+ // If this is a varargs function, floating point arguments
+ // have to passed in integer registers so insert
+ // copy-float-to-int instructions for each float operand.
+ //
CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
Value *callee = callInstr->getCalledValue();
@@ -2048,9 +2052,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// in register allocation.
//
// Add the call operands and return value as implicit refs
+ // const Type* funcType = isa<Function>(callee)? callee->getType()
+ // : cast<PointerType>(callee->getType())->getElementType();
+ const Type* funcType = callee->getType();
+ bool isVarArgs = cast<FunctionType>(cast<PointerType>(funcType)
+ ->getElementType())->isVarArg();
+
for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
if (callInstr->getOperand(i) != callee)
- mvec.back()->addImplicitRef(callInstr->getOperand(i));
+ {
+ Value* argVal = callInstr->getOperand(i);
+
+ // Check for FP arguments to varargs functions
+ if (isVarArgs && argVal->getType()->isFloatingPoint())
+ { // Add a copy-float-to-int instruction
+ MachineCodeForInstruction &destMCFI =
+ MachineCodeForInstruction::get(callInstr);
+ Instruction* intArgReg =
+ new TmpInstruction(Type::IntTy, argVal);
+ destMCFI.addTemp(intArgReg);
+
+ vector<MachineInstr*> minstrVec;
+ vector<TmpInstruction*> tempVec;
+ target.getInstrInfo().CreateCodeToCopyFloatToInt(
+ callInstr->getParent()->getParent(),
+ argVal, (TmpInstruction*) intArgReg,
+ minstrVec, tempVec, target);
+
+ mvec.insert(mvec.begin(), minstrVec.begin(),minstrVec.end());
+
+ for (unsigned i=0; i < tempVec.size(); ++i)
+ destMCFI.addTemp(tempVec[i]);
+
+ argVal = intArgReg;
+ }
+
+ mvec.back()->addImplicitRef(argVal);
+ }
if (callInstr->getType() != Type::VoidTy)
mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);