[llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp
Vikram Adve
vadve at cs.uiuc.edu
Tue Jul 29 14:59:01 PDT 2003
Changes in directory llvm/lib/Target/Sparc:
SparcInstrInfo.cpp updated: 1.50 -> 1.51
---
Log message:
Unify all constant evaluations that depend on register size
in ConvertConstantToIntType.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.50 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.51
--- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.50 Wed Jul 23 10:22:19 2003
+++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Tue Jul 29 14:58:42 2003
@@ -20,47 +20,97 @@
//---------------------------------------------------------------------------
-// Function GetConstantValueAsUnsignedInt
-// Function GetConstantValueAsSignedInt
+// Function ConvertConstantToIntType
//
-// Convenience functions to get the value of an integral constant, for an
-// appropriate integer or non-integer type that can be held in a signed
-// or unsigned integer respectively. The type of the argument must be
-// the following:
-// Signed or unsigned integer
-// Boolean
-// Pointer
+// Function to get the value of an integral constant in the form
+// that must be put into the machine register. The specified constant is
+// interpreted as (i.e., converted if necessary to) the specified destination
+// type. The result is always returned as an uint64_t, since the representation
+// of int64_t and uint64_t are identical. The argument can be any known const.
//
// isValidConstant is set to true if a valid constant was found.
//---------------------------------------------------------------------------
-static uint64_t
-GetConstantValueAsUnsignedInt(const Value *V,
- bool &isValidConstant)
-{
- isValidConstant = true;
-
- if (isa<Constant>(V))
- if (const ConstantBool *CB = dyn_cast<ConstantBool>(V))
- return (int64_t)CB->getValue();
- else if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return CI->getRawValue();
-
+uint64_t
+UltraSparcInstrInfo::ConvertConstantToIntType(const TargetMachine &target,
+ const Value *V,
+ const Type *destType,
+ bool &isValidConstant) const
+{
isValidConstant = false;
- return 0;
-}
+ uint64_t C = 0;
-int64_t
-GetConstantValueAsSignedInt(const Value *V, bool &isValidConstant)
-{
- uint64_t C = GetConstantValueAsUnsignedInt(V, isValidConstant);
+ if (! destType->isIntegral() && ! isa<PointerType>(destType))
+ return C;
+
+ if (! isa<Constant>(V))
+ return C;
+
+ // ConstantPointerRef: no conversions needed: get value and return it
+ if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(V)) {
+ // A ConstantPointerRef is just a reference to GlobalValue.
+ isValidConstant = true; // may be overwritten by recursive call
+ return (CPR->isNullValue()? 0
+ : ConvertConstantToIntType(target, CPR->getValue(), destType,
+ isValidConstant));
+ }
+
+ // ConstantBool: no conversions needed: get value and return it
+ if (const ConstantBool *CB = dyn_cast<ConstantBool>(V)) {
+ isValidConstant = true;
+ return (uint64_t) CB->getValue();
+ }
+
+ // For other types of constants, some conversion may be needed.
+ // First, extract the constant operand according to its own type
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ switch(CE->getOpcode()) {
+ case Instruction::Cast: // recursively get the value as cast
+ C = ConvertConstantToIntType(target, CE->getOperand(0), CE->getType(),
+ isValidConstant);
+ break;
+ default: // not simplifying other ConstantExprs
+ break;
+ }
+ else if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ isValidConstant = true;
+ C = CI->getRawValue();
+ }
+ else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
+ isValidConstant = true;
+ double fC = CFP->getValue();
+ C = (destType->isSigned()? (uint64_t) (int64_t) fC
+ : (uint64_t) fC);
+ }
+
+ // Now if a valid value was found, convert it to destType.
if (isValidConstant) {
- if (V->getType()->isSigned() || C < INT64_MAX) // safe to cast to signed
- return (int64_t) C;
- else
- isValidConstant = false;
+ unsigned opSize = target.getTargetData().getTypeSize(V->getType());
+ unsigned destSize = target.getTargetData().getTypeSize(destType);
+ uint64_t maskHi = (destSize < 8)? (1U << 8*destSize) - 1 : ~0;
+ assert(opSize <= 8 && destSize <= 8 && ">8-byte int type unexpected");
+
+ if (destType->isSigned()) {
+ if (opSize > destSize) // operand is larger than dest:
+ C = C & maskHi; // mask high bits
+
+ if (opSize > destSize ||
+ (opSize == destSize && ! V->getType()->isSigned()))
+ if (C & (1U << (8*destSize - 1)))
+ C = C | ~maskHi; // sign-extend from destSize to 64 bits
+ }
+ else {
+ if (opSize > destSize || (V->getType()->isSigned() && destSize < 8)) {
+ // operand is larger than dest,
+ // OR both are equal but smaller than the full register size
+ // AND operand is signed, so it may have extra sign bits:
+ // mask high bits
+ C = C & maskHi;
+ }
+ }
}
- return 0;
+
+ return C;
}
@@ -410,49 +460,25 @@
//
const Type* valType = val->getType();
- // Unfortunate special case: a ConstantPointerRef is just a
- // reference to GlobalValue.
- if (isa<ConstantPointerRef>(val))
+ // A ConstantPointerRef is just a reference to GlobalValue.
+ while (isa<ConstantPointerRef>(val))
val = cast<ConstantPointerRef>(val)->getValue();
if (isa<GlobalValue>(val)) {
TmpInstruction* tmpReg =
new TmpInstruction(mcfi, PointerType::get(val->getType()), val);
CreateSETXLabel(target, val, tmpReg, dest, mvec);
- } else if (valType->isIntegral()) {
- bool isValidConstant;
- unsigned opSize = target.getTargetData().getTypeSize(val->getType());
- unsigned destSize = target.getTargetData().getTypeSize(dest->getType());
-
- if (! dest->getType()->isSigned()) {
- uint64_t C = GetConstantValueAsUnsignedInt(val, isValidConstant);
- assert(isValidConstant && "Unrecognized constant");
+ return;
+ }
- if (opSize > destSize || (val->getType()->isSigned() && destSize < 8)) {
- // operand is larger than dest,
- // OR both are equal but smaller than the full register size
- // AND operand is signed, so it may have extra sign bits:
- // mask high bits
- C = C & ((1U << 8*destSize) - 1);
- }
+ bool isValid;
+ uint64_t C = ConvertConstantToIntType(target, val, dest->getType(), isValid);
+ if (isValid) {
+ if (dest->getType()->isSigned())
CreateUIntSetInstruction(target, C, dest, mvec, mcfi);
- } else {
- int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
- assert(isValidConstant && "Unrecognized constant");
-
- if (opSize > destSize)
- // operand is larger than dest: mask high bits
- C = C & ((1U << 8*destSize) - 1);
+ else
+ CreateIntSetInstruction(target, (int64_t) C, dest, mvec, mcfi);
- if (opSize > destSize ||
- (opSize == destSize && !val->getType()->isSigned()))
- // sign-extend from destSize to 64 bits
- C = ((C & (1U << (8*destSize - 1)))
- ? C | ~((1U << 8*destSize) - 1)
- : C);
-
- CreateIntSetInstruction(target, C, dest, mvec, mcfi);
- }
} else {
// Make an instruction sequence to load the constant, viz:
// SETX <addr-of-constant>, tmpReg, addrReg
@@ -465,10 +491,10 @@
// Create another TmpInstruction for the address register
TmpInstruction* addrReg =
new TmpInstruction(mcfi, PointerType::get(val->getType()), val);
-
+
// Put the address (a symbolic name) into a register
CreateSETXLabel(target, val, tmpReg, addrReg, mvec);
-
+
// Generate the load instruction
int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
unsigned Opcode = ChooseLoadInstruction(val->getType());
More information about the llvm-commits
mailing list