mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +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
|
static inline MachineOpCode
|
||||||
ChooseConvertToFloatInstr(const InstructionNode* instrNode,
|
ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
|
||||||
const Type* opType)
|
|
||||||
{
|
{
|
||||||
MachineOpCode opCode = INVALID_OPCODE;
|
MachineOpCode opCode = INVALID_OPCODE;
|
||||||
|
|
||||||
switch(instrNode->getOpLabel())
|
switch(vopCode)
|
||||||
{
|
{
|
||||||
case ToFloatTy:
|
case ToFloatTy:
|
||||||
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
|
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
|
||||||
@ -285,14 +284,11 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline MachineOpCode
|
static inline MachineOpCode
|
||||||
ChooseConvertToIntInstr(const InstructionNode* instrNode,
|
ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
|
||||||
const Type* opType)
|
|
||||||
{
|
{
|
||||||
MachineOpCode opCode = INVALID_OPCODE;;
|
MachineOpCode opCode = INVALID_OPCODE;;
|
||||||
|
|
||||||
int instrType = (int) instrNode->getOpLabel();
|
if (vopCode == ToSByteTy || vopCode == ToShortTy || vopCode == ToIntTy)
|
||||||
|
|
||||||
if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
|
|
||||||
{
|
{
|
||||||
switch (opType->getPrimitiveID())
|
switch (opType->getPrimitiveID())
|
||||||
{
|
{
|
||||||
@ -303,7 +299,7 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (instrType == ToLongTy)
|
else if (vopCode == ToLongTy)
|
||||||
{
|
{
|
||||||
switch (opType->getPrimitiveID())
|
switch (opType->getPrimitiveID())
|
||||||
{
|
{
|
||||||
@ -320,6 +316,17 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
|
|||||||
return opCode;
|
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
|
static inline MachineOpCode
|
||||||
ChooseAddInstructionByType(const Type* resultType)
|
ChooseAddInstructionByType(const Type* resultType)
|
||||||
@ -1565,9 +1572,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
(dest->getType() == Type::LongTy)? Type::DoubleTy
|
(dest->getType() == Type::LongTy)? Type::DoubleTy
|
||||||
: Type::FloatTy;
|
: Type::FloatTy;
|
||||||
destForCast = new TmpInstruction(destTypeToUse, leftVal);
|
destForCast = new TmpInstruction(destTypeToUse, leftVal);
|
||||||
MachineCodeForInstruction &MCFI =
|
MachineCodeForInstruction &destMCFI =
|
||||||
MachineCodeForInstruction::get(dest);
|
MachineCodeForInstruction::get(dest);
|
||||||
MCFI.addTemp(destForCast);
|
destMCFI.addTemp(destForCast);
|
||||||
|
|
||||||
vector<TmpInstruction*> tempVec;
|
vector<TmpInstruction*> tempVec;
|
||||||
target.getInstrInfo().CreateCodeToCopyFloatToInt(
|
target.getInstrInfo().CreateCodeToCopyFloatToInt(
|
||||||
@ -1576,21 +1583,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
minstrVec, tempVec, target);
|
minstrVec, tempVec, target);
|
||||||
|
|
||||||
for (unsigned i=0; i < tempVec.size(); ++i)
|
for (unsigned i=0; i < tempVec.size(); ++i)
|
||||||
MCFI.addTemp(tempVec[i]);
|
destMCFI.addTemp(tempVec[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
destForCast = leftVal;
|
destForCast = leftVal;
|
||||||
|
|
||||||
MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType);
|
M = CreateConvertToIntInstr(subtreeRoot->getOpLabel(),
|
||||||
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
|
leftVal, destForCast);
|
||||||
|
|
||||||
M = new MachineInstr(opCode);
|
|
||||||
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
|
|
||||||
leftVal);
|
|
||||||
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
|
|
||||||
destForCast);
|
|
||||||
mvec.push_back(M);
|
mvec.push_back(M);
|
||||||
|
|
||||||
// Append the copy code, if any, after the conversion instr.
|
// Append the copy code, if any, after the conversion instr.
|
||||||
mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
|
mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
|
||||||
}
|
}
|
||||||
@ -1616,7 +1617,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
{
|
{
|
||||||
Value* leftVal = subtreeRoot->leftChild()->getValue();
|
Value* leftVal = subtreeRoot->leftChild()->getValue();
|
||||||
const Type* opType = leftVal->getType();
|
const Type* opType = leftVal->getType();
|
||||||
MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
|
MachineOpCode opCode=ChooseConvertToFloatInstr(
|
||||||
|
subtreeRoot->getOpLabel(), opType);
|
||||||
if (opCode == INVALID_OPCODE) // no conversion needed
|
if (opCode == INVALID_OPCODE) // no conversion needed
|
||||||
{
|
{
|
||||||
forwardOperandNum = 0; // forward first operand to user
|
forwardOperandNum = 0; // forward first operand to user
|
||||||
@ -1641,9 +1643,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
: Type::FloatTy;
|
: Type::FloatTy;
|
||||||
|
|
||||||
srcForCast = new TmpInstruction(srcTypeToUse, dest);
|
srcForCast = new TmpInstruction(srcTypeToUse, dest);
|
||||||
MachineCodeForInstruction &DestMCFI =
|
MachineCodeForInstruction &destMCFI =
|
||||||
MachineCodeForInstruction::get(dest);
|
MachineCodeForInstruction::get(dest);
|
||||||
DestMCFI.addTemp(srcForCast);
|
destMCFI.addTemp(srcForCast);
|
||||||
|
|
||||||
vector<MachineInstr*> minstrVec;
|
vector<MachineInstr*> minstrVec;
|
||||||
vector<TmpInstruction*> tempVec;
|
vector<TmpInstruction*> tempVec;
|
||||||
@ -1655,7 +1657,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
|
mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
|
||||||
|
|
||||||
for (unsigned i=0; i < tempVec.size(); ++i)
|
for (unsigned i=0; i < tempVec.size(); ++i)
|
||||||
DestMCFI.addTemp(tempVec[i]);
|
destMCFI.addTemp(tempVec[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
srcForCast = leftVal;
|
srcForCast = leftVal;
|
||||||
@ -2003,14 +2005,16 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 61: // reg: Call
|
case 61: // reg: Call
|
||||||
{ // Generate a call-indirect (i.e., jmpl) for now to expose
|
{ // Generate a direct (CALL) or indirect (JMPL). depending
|
||||||
// the potential need for registers. If an absolute address
|
// Mark the return-address register and the indirection
|
||||||
// is available, replace this with a CALL instruction.
|
// register (if any) as hidden virtual registers.
|
||||||
// Mark both the indirection register and the return-address
|
|
||||||
// register as hidden virtual registers.
|
|
||||||
// Also, mark the operands of the Call and return value (if
|
// Also, mark the operands of the Call and return value (if
|
||||||
// any) as implicit operands of the CALL machine instruction.
|
// 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());
|
CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
|
||||||
Value *callee = callInstr->getCalledValue();
|
Value *callee = callInstr->getCalledValue();
|
||||||
|
|
||||||
@ -2048,9 +2052,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
// in register allocation.
|
// in register allocation.
|
||||||
//
|
//
|
||||||
// Add the call operands and return value as implicit refs
|
// 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)
|
for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
|
||||||
if (callInstr->getOperand(i) != callee)
|
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)
|
if (callInstr->getType() != Type::VoidTy)
|
||||||
mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
|
mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
|
||||||
|
Loading…
Reference in New Issue
Block a user