mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
Add a missing case: converting float/double to unsigned integer types.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3188 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8633a487c7
commit
1e60669d3b
@ -286,11 +286,12 @@ ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline MachineOpCode
|
static inline MachineOpCode
|
||||||
ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
|
ChooseConvertToIntInstr(Type::PrimitiveID tid, const Type* opType)
|
||||||
{
|
{
|
||||||
MachineOpCode opCode = INVALID_OPCODE;;
|
MachineOpCode opCode = INVALID_OPCODE;;
|
||||||
|
|
||||||
if (vopCode == ToSByteTy || vopCode == ToShortTy || vopCode == ToIntTy)
|
if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID ||
|
||||||
|
tid==Type::UByteTyID || tid==Type::UShortTyID || tid==Type::UIntTyID)
|
||||||
{
|
{
|
||||||
switch (opType->getPrimitiveID())
|
switch (opType->getPrimitiveID())
|
||||||
{
|
{
|
||||||
@ -301,7 +302,7 @@ ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vopCode == ToLongTy)
|
else if (tid==Type::LongTyID || tid==Type::ULongTyID)
|
||||||
{
|
{
|
||||||
switch (opType->getPrimitiveID())
|
switch (opType->getPrimitiveID())
|
||||||
{
|
{
|
||||||
@ -319,9 +320,9 @@ ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr*
|
MachineInstr*
|
||||||
CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal)
|
CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal)
|
||||||
{
|
{
|
||||||
MachineOpCode opCode = ChooseConvertToIntInstr(vopCode, srcVal->getType());
|
MachineOpCode opCode = ChooseConvertToIntInstr(destTID, srcVal->getType());
|
||||||
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
|
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
|
||||||
|
|
||||||
MachineInstr* M = new MachineInstr(opCode);
|
MachineInstr* M = new MachineInstr(opCode);
|
||||||
@ -330,6 +331,38 @@ CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal)
|
|||||||
return M;
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateCodeToConvertIntToFloat: Convert FP value to signed or unsigned integer
|
||||||
|
// The FP value must be converted to the dest type in an FP register,
|
||||||
|
// and the result is then copied from FP to int register via memory.
|
||||||
|
static void
|
||||||
|
CreateCodeToConvertIntToFloat (const TargetMachine& target,
|
||||||
|
Value* opVal,
|
||||||
|
Instruction* destI,
|
||||||
|
std::vector<MachineInstr*>& mvec,
|
||||||
|
MachineCodeForInstruction& mcfi)
|
||||||
|
{
|
||||||
|
// Create a temporary to represent the FP register into which the
|
||||||
|
// int value will placed after conversion. The type of this temporary
|
||||||
|
// depends on the type of FP register to use: single-prec for a 32-bit
|
||||||
|
// int or smaller; double-prec for a 64-bit int.
|
||||||
|
//
|
||||||
|
const Type* destTypeToUse = (destI->getType() == Type::LongTy)? Type::DoubleTy
|
||||||
|
: Type::FloatTy;
|
||||||
|
Value* destForCast = new TmpInstruction(destTypeToUse, opVal);
|
||||||
|
mcfi.addTemp(destForCast);
|
||||||
|
|
||||||
|
// Create the fp-to-int conversion code
|
||||||
|
MachineInstr* M = CreateConvertToIntInstr(destI->getType()->getPrimitiveID(),
|
||||||
|
opVal, destForCast);
|
||||||
|
mvec.push_back(M);
|
||||||
|
|
||||||
|
// Create the fpreg-to-intreg copy code
|
||||||
|
target.getInstrInfo().
|
||||||
|
CreateCodeToCopyFloatToInt(target, destI->getParent()->getParent(),
|
||||||
|
(TmpInstruction*)destForCast, destI, mvec, mcfi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline MachineOpCode
|
static inline MachineOpCode
|
||||||
ChooseAddInstruction(const InstructionNode* instrNode)
|
ChooseAddInstruction(const InstructionNode* instrNode)
|
||||||
{
|
{
|
||||||
@ -1494,30 +1527,34 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
Instruction* destI = subtreeRoot->getInstruction();
|
Instruction* destI = subtreeRoot->getInstruction();
|
||||||
Value* opVal = subtreeRoot->leftChild()->getValue();
|
Value* opVal = subtreeRoot->leftChild()->getValue();
|
||||||
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
|
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
|
||||||
assert(opType->isIntegral() ||
|
if (opType->isIntegral()
|
||||||
isa<PointerType>(opType) ||
|
|| isa<PointerType>(opType)
|
||||||
opType == Type::BoolTy && "Cast is illegal for other types");
|
|| opType == Type::BoolTy)
|
||||||
|
{
|
||||||
unsigned opSize = target.DataLayout.getTypeSize(opType);
|
unsigned opSize = target.DataLayout.getTypeSize(opType);
|
||||||
unsigned destSize = target.DataLayout.getTypeSize(destI->getType());
|
unsigned destSize = target.DataLayout.getTypeSize(destI->getType());
|
||||||
|
if (opSize > destSize ||
|
||||||
if (opSize > destSize ||
|
(opType->isSigned()
|
||||||
(opType->isSigned()
|
&& destSize < target.DataLayout.getIntegerRegize()))
|
||||||
&& destSize < target.DataLayout.getIntegerRegize()))
|
{ // operand is larger than dest,
|
||||||
{ // operand is larger than dest,
|
// OR both are equal but smaller than the full register size
|
||||||
// OR both are equal but smaller than the full register size
|
// AND operand is signed, so it may have extra sign bits:
|
||||||
// AND operand is signed, so it may have extra sign bits:
|
// mask high bits using AND
|
||||||
// mask high bits using AND
|
M = Create3OperandInstr(AND, opVal,
|
||||||
//
|
ConstantUInt::get(Type::ULongTy,
|
||||||
M = Create3OperandInstr(AND, opVal,
|
((uint64_t) 1 << 8*destSize) - 1),
|
||||||
ConstantUInt::get(Type::ULongTy,
|
destI);
|
||||||
((uint64_t) 1 << 8*destSize) - 1),
|
mvec.push_back(M);
|
||||||
destI);
|
}
|
||||||
mvec.push_back(M);
|
else
|
||||||
|
forwardOperandNum = 0; // forward first operand to user
|
||||||
}
|
}
|
||||||
|
else if (opType->isFloatingPoint())
|
||||||
|
CreateCodeToConvertIntToFloat(target, opVal, destI, mvec,
|
||||||
|
MachineCodeForInstruction::get(destI));
|
||||||
else
|
else
|
||||||
forwardOperandNum = 0; // forward first operand to user
|
assert(0 && "Unrecognized operand type for convert-to-unsigned");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1526,11 +1563,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
case 28: // reg: ToIntTy(reg)
|
case 28: // reg: ToIntTy(reg)
|
||||||
case 30: // reg: ToLongTy(reg)
|
case 30: // reg: ToLongTy(reg)
|
||||||
{
|
{
|
||||||
unsigned int oldMvecSize = mvec.size(); // to check if it grew
|
|
||||||
Instruction* destI = subtreeRoot->getInstruction();
|
Instruction* destI = subtreeRoot->getInstruction();
|
||||||
Value* opVal = subtreeRoot->leftChild()->getValue();
|
Value* opVal = subtreeRoot->leftChild()->getValue();
|
||||||
MachineCodeForInstruction& mcfi =MachineCodeForInstruction::get(destI);
|
MachineCodeForInstruction& mcfi =MachineCodeForInstruction::get(destI);
|
||||||
|
|
||||||
const Type* opType = opVal->getType();
|
const Type* opType = opVal->getType();
|
||||||
if (opType->isIntegral()
|
if (opType->isIntegral()
|
||||||
|| isa<PointerType>(opType)
|
|| isa<PointerType>(opType)
|
||||||
@ -1542,11 +1578,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
const Type* destType = destI->getType();
|
const Type* destType = destI->getType();
|
||||||
unsigned opSize = target.DataLayout.getTypeSize(opType);
|
unsigned opSize = target.DataLayout.getTypeSize(opType);
|
||||||
unsigned destSize = target.DataLayout.getTypeSize(destType);
|
unsigned destSize = target.DataLayout.getTypeSize(destType);
|
||||||
if (opSize <= destSize && !opType->isSigned())
|
if (opSize < destSize && !opType->isSigned())
|
||||||
{ // operand is smaller than or same size as dest:
|
{ // operand is unsigned and smaller than dest: sign-extend
|
||||||
// -- if operand is signed (checked above), nothing to do
|
|
||||||
// -- if operand is unsigned, sign-extend the value:
|
|
||||||
//
|
|
||||||
target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), opVal, 8*opSize, destI, mvec, mcfi);
|
target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), opVal, 8*opSize, destI, mvec, mcfi);
|
||||||
}
|
}
|
||||||
else if (opSize > destSize)
|
else if (opSize > destSize)
|
||||||
@ -1564,51 +1597,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
|
|
||||||
target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), tmpI, 8*destSize, destI, mvec, mcfi);
|
target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), tmpI, 8*destSize, destI, mvec, mcfi);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the source operand is an FP type, the int result must be
|
|
||||||
// copied from float to int register via memory!
|
|
||||||
Value* leftVal = subtreeRoot->leftChild()->getValue();
|
|
||||||
Value* destForCast;
|
|
||||||
vector<MachineInstr*> minstrVec;
|
|
||||||
|
|
||||||
if (opType->isFloatingPoint())
|
|
||||||
{
|
|
||||||
// Create a temporary to represent the INT register
|
|
||||||
// into which the FP value will be copied via memory.
|
|
||||||
// The type of this temporary will determine the FP
|
|
||||||
// register used: single-prec for a 32-bit int or smaller,
|
|
||||||
// double-prec for a 64-bit int.
|
|
||||||
//
|
|
||||||
const Type* destTypeToUse =
|
|
||||||
(destI->getType() == Type::LongTy)? Type::DoubleTy
|
|
||||||
: Type::FloatTy;
|
|
||||||
destForCast = new TmpInstruction(destTypeToUse, leftVal);
|
|
||||||
MachineCodeForInstruction &destMCFI =
|
|
||||||
MachineCodeForInstruction::get(destI);
|
|
||||||
destMCFI.addTemp(destForCast);
|
|
||||||
|
|
||||||
target.getInstrInfo().
|
|
||||||
CreateCodeToCopyFloatToInt(target,
|
|
||||||
destI->getParent()->getParent(),
|
|
||||||
(TmpInstruction*) destForCast,
|
|
||||||
destI, minstrVec, destMCFI);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
destForCast = leftVal;
|
forwardOperandNum = 0; // forward first operand to user
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
else if (opType->isFloatingPoint())
|
||||||
if (oldMvecSize == mvec.size()) // no instruction was generated
|
CreateCodeToConvertIntToFloat(target, opVal, destI, mvec, mcfi);
|
||||||
forwardOperandNum = 0; // forward first operand to user
|
else
|
||||||
|
assert(0 && "Unrecognized operand type for convert-to-signed");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user