mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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
This commit is contained in:
parent
a4a943dd5a
commit
dbc4fad577
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user