aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-09-05 18:32:13 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-09-05 18:32:13 +0000
commitbabc0fab197bdf4981601071d4d77bdc48aac83a (patch)
treeb949412e96e9c99b5bc80bc5d8228fa75e81cd9f /lib/Target
parent537a8779989645705c60c9577c913bb7d00b0239 (diff)
downloadexternal_llvm-babc0fab197bdf4981601071d4d77bdc48aac83a.zip
external_llvm-babc0fab197bdf4981601071d4d77bdc48aac83a.tar.gz
external_llvm-babc0fab197bdf4981601071d4d77bdc48aac83a.tar.bz2
-- Use size of pointer element type instead of pointer type in array offsets!
-- A few bug fixes in casting between floats and ints. -- Use SRL reg, 0 instead of AND reg, 0xffffffff to clear high 32 bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3579 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp73
1 files changed, 46 insertions, 27 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index a68331b..368afbb 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -319,6 +319,20 @@ CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal)
// CreateCodeToConvertFloatToInt: 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.
+//
+// Since fdtoi converts to signed integers, any FP value V between MAXINT+1
+// and MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly
+// *only* when converting to an unsigned int. (Unsigned byte, short or long
+// don't have this problem.)
+// For unsigned int, we therefore have to generate the code sequence:
+//
+// if (V > (float) MAXINT) {
+// unsigned result = (unsigned) (V - (float) MAXINT);
+// result = result + (unsigned) MAXINT;
+// }
+// else
+// result = (unsigned int) V;
+//
static void
CreateCodeToConvertFloatToInt(const TargetMachine& target,
Value* opVal,
@@ -331,9 +345,9 @@ CreateCodeToConvertFloatToInt(const TargetMachine& target,
// 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);
+ size_t destSize = target.DataLayout.getTypeSize(destI->getType());
+ const Type* destTypeToUse = (destSize > 4)? Type::DoubleTy : Type::FloatTy;
+ TmpInstruction* destForCast = new TmpInstruction(destTypeToUse, opVal);
mcfi.addTemp(destForCast);
// Create the fp-to-int conversion code
@@ -344,7 +358,7 @@ CreateCodeToConvertFloatToInt(const TargetMachine& target,
// Create the fpreg-to-intreg copy code
target.getInstrInfo().
CreateCodeToCopyFloatToInt(target, destI->getParent()->getParent(),
- (TmpInstruction*)destForCast, destI, mvec, mcfi);
+ destForCast, destI, mvec, mcfi);
}
@@ -990,28 +1004,34 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
// offset. (An extra leading zero offset, if any, can be ignored.)
// Generate code sequence to compute address from index.
//
- assert(idxVec.size() == 1U + IsZero(idxVec[0])
+ bool firstIdxIsZero = IsZero(idxVec[0]);
+ assert(idxVec.size() == 1U + firstIdxIsZero
&& "Array refs must be lowered before Instruction Selection");
- Value* idxVal = idxVec[IsZero(idxVec[0])];
+ Value* idxVal = idxVec[firstIdxIsZero];
assert(! isa<Constant>(idxVal) && "Need to sign-extend uint to 64b!");
vector<MachineInstr*> mulVec;
Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
MachineCodeForInstruction::get(memInst).addTemp(addr);
+ // Get the array type indexed by idxVal, and compute its element size.
// The call to getTypeSize() will fail if size is not constant.
- unsigned int eltSize =
- target.DataLayout.getTypeSize(ptrType->getElementType());
- assert(eltSize > 0 && "Invalid or non-const array element size");
- ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
+ const Type* vecType = (firstIdxIsZero
+ ? GetElementPtrInst::getIndexedType(ptrType,
+ std::vector<Value*>(1U, idxVec[0]),
+ /*AllowCompositeLeaf*/ true)
+ : ptrType);
+ const Type* eltType = cast<SequentialType>(vecType)->getElementType();
+ ConstantUInt* eltSizeVal = ConstantUInt::get(Type::UIntTy,
+ target.DataLayout.getTypeSize(eltType));
// CreateMulInstruction() folds constants intelligently enough.
CreateMulInstruction(target,
memInst->getParent()->getParent(),
- idxVal, /* lval, not likely const */
- eltVal, /* rval, likely constant */
- addr, /* result*/
+ idxVal, /* lval, not likely to be const*/
+ eltSizeVal, /* rval, likely to be constant */
+ addr, /* result */
mulVec,
MachineCodeForInstruction::get(memInst),
INVALID_MACHINE_OPCODE);
@@ -1531,11 +1551,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
-
+
case 31: // reg: ToFloatTy(reg):
case 32: // reg: ToDoubleTy(reg):
case 232: // reg: ToDoubleTy(Constant):
-
+
// If this instruction has a parent (a user) in the tree
// and the user is translated as an FsMULd instruction,
// then the cast is unnecessary. So check that first.
@@ -1572,18 +1592,18 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// register used: single-prec for a 32-bit int or smaller,
// double-prec for a 64-bit int.
//
- const Type* srcTypeToUse =
- (leftVal->getType() == Type::LongTy)? Type::DoubleTy
- : Type::FloatTy;
-
- srcForCast = new TmpInstruction(srcTypeToUse, dest);
+ uint64_t srcSize =
+ target.DataLayout.getTypeSize(leftVal->getType());
+ Type* tmpTypeToUse =
+ (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
+ srcForCast = new TmpInstruction(tmpTypeToUse, dest);
MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest);
destMCFI.addTemp(srcForCast);
-
+
target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
dest->getParent()->getParent(),
- leftVal, (TmpInstruction*) srcForCast,
+ leftVal, cast<Instruction>(srcForCast),
mvec, destMCFI);
}
else
@@ -2150,7 +2170,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
if (dest->getType()->isUnsigned())
{
unsigned destSize = target.DataLayout.getTypeSize(dest->getType());
- if (destSize < target.DataLayout.getIntegerRegize())
+ if (destSize <= 4)
{ // Mask high bits. Use a TmpInstruction to represent the
// intermediate result before masking. Since those instructions
// have already been generated, go back and substitute tmpI
@@ -2162,12 +2182,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
for (unsigned i=0, N=mvec.size(); i < N; ++i)
mvec[i]->substituteValue(dest, tmpI);
- M = Create3OperandInstr(AND, tmpI,
- ConstantUInt::get(Type::ULongTy,
- ((uint64_t) 1 << 8*destSize) - 1),
- dest);
+ M = Create3OperandInstr_UImmed(SRL, tmpI, 4-destSize, dest);
mvec.push_back(M);
}
+ else if (destSize < target.DataLayout.getIntegerRegize())
+ assert(0 && "Unsupported type size: 32 < size < 64 bits");
}
}
}