+ //======================================================================
+ // Rules for integer conversions:
+ //
+ //--------
+ // From ISO 1998 C++ Standard, Sec. 4.7:
+ //
+ // 2. If the destination type is unsigned, the resulting value is
+ // the least unsigned integer congruent to the source integer
+ // (modulo 2n where n is the number of bits used to represent the
+ // unsigned type). [Note: In a two s complement representation,
+ // this conversion is conceptual and there is no change in the
+ // bit pattern (if there is no truncation). ]
+ //
+ // 3. If the destination type is signed, the value is unchanged if
+ // it can be represented in the destination type (and bitfield width);
+ // otherwise, the value is implementation-defined.
+ //--------
+ //
+ // Since we assume 2s complement representations, this implies:
+ //
+ // -- if operand is smaller than destination, zero-extend or sign-extend
+ // according to the signedness of the *operand*: source decides.
+ // ==> we have to do nothing here!
+ //
+ // -- if operand is same size as or larger than destination, and the
+ // destination is *unsigned*, zero-extend the operand: dest. decides
+ //
+ // -- if operand is same size as or larger than destination, and the
+ // destination is *signed*, the choice is implementation defined:
+ // we sign-extend the operand: i.e., again dest. decides.
+ // Note: this matches both Sun's cc and gcc3.2.
+ //======================================================================
+
+ Instruction* destI = subtreeRoot->getInstruction();
+ Value* opVal = subtreeRoot->leftChild()->getValue();
+ const Type* opType = opVal->getType();
+ if (opType->isIntegral() || isa<PointerType>(opType))
+ {
+ unsigned opSize = target.DataLayout.getTypeSize(opType);
+ unsigned destSize = target.DataLayout.getTypeSize(destI->getType());
+ if (opSize >= destSize)
+ { // Operand is same size as or larger than dest:
+ // zero- or sign-extend, according to the signeddness of
+ // the destination (see above).
+ if (destI->getType()->isSigned())
+ target.getInstrInfo().CreateSignExtensionInstructions(target,
+ destI->getParent()->getParent(), opVal, destI, 8*destSize,
+ mvec, MachineCodeForInstruction::get(destI));
+ else
+ target.getInstrInfo().CreateZeroExtensionInstructions(target,
+ destI->getParent()->getParent(), opVal, destI, 8*destSize,
+ mvec, MachineCodeForInstruction::get(destI));
+ }
+ else
+ forwardOperandNum = 0; // forward first operand to user
+ }
+ else if (opType->isFloatingPoint())
+ {
+ CreateCodeToConvertFloatToInt(target, opVal, destI, mvec,
+ MachineCodeForInstruction::get(destI));
+ if (destI->getType()->isUnsigned())
+ maskUnsignedResult = true; // not handled by fp->int code
+ }
+ else
+ assert(0 && "Unrecognized operand type for convert-to-unsigned");
+