+CastInst *CastInst::createPointerCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ assert(isa<PointerType>(S->getType()) && "Invalid cast");
+ assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ "Invalid cast");
+
+ if (Ty->isInteger())
+ return create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
+ return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+}
+
+/// @brief Create a BitCast or a PtrToInt cast instruction
+CastInst *CastInst::createPointerCast(Value *S, const Type *Ty,
+ const std::string &Name,
+ Instruction *InsertBefore) {
+ assert(isa<PointerType>(S->getType()) && "Invalid cast");
+ assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
+ "Invalid cast");
+
+ if (Ty->isInteger())
+ return create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
+ return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createIntegerCast(Value *C, const Type *Ty,
+ bool isSigned, const std::string &Name,
+ Instruction *InsertBefore) {
+ assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
+ unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
+ unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ Instruction::CastOps opcode =
+ (SrcBits == DstBits ? Instruction::BitCast :
+ (SrcBits > DstBits ? Instruction::Trunc :
+ (isSigned ? Instruction::SExt : Instruction::ZExt)));
+ return create(opcode, C, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createIntegerCast(Value *C, const Type *Ty,
+ bool isSigned, const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
+ unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
+ unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ Instruction::CastOps opcode =
+ (SrcBits == DstBits ? Instruction::BitCast :
+ (SrcBits > DstBits ? Instruction::Trunc :
+ (isSigned ? Instruction::SExt : Instruction::ZExt)));
+ return create(opcode, C, Ty, Name, InsertAtEnd);
+}
+
+CastInst *CastInst::createFPCast(Value *C, const Type *Ty,
+ const std::string &Name,
+ Instruction *InsertBefore) {
+ assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ "Invalid cast");
+ unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
+ unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ Instruction::CastOps opcode =
+ (SrcBits == DstBits ? Instruction::BitCast :
+ (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
+ return create(opcode, C, Ty, Name, InsertBefore);
+}
+
+CastInst *CastInst::createFPCast(Value *C, const Type *Ty,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ "Invalid cast");
+ unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
+ unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ Instruction::CastOps opcode =
+ (SrcBits == DstBits ? Instruction::BitCast :
+ (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
+ return create(opcode, C, Ty, Name, InsertAtEnd);
+}
+
+// Check whether it is valid to call getCastOpcode for these types.
+// This routine must be kept in sync with getCastOpcode.
+bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
+ if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType())
+ return false;
+
+ if (SrcTy == DestTy)
+ return true;
+
+ // Get the bit sizes, we'll need these
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+
+ // Run through the possibilities ...
+ if (DestTy->isInteger()) { // Casting to integral
+ if (SrcTy->isInteger()) { // Casting from integral
+ return true;
+ } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ return true;
+ } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
+ // Casting from vector
+ return DestBits == PTy->getBitWidth();
+ } else { // Casting from something else
+ return isa<PointerType>(SrcTy);
+ }
+ } else if (DestTy->isFloatingPoint()) { // Casting to floating pt
+ if (SrcTy->isInteger()) { // Casting from integral
+ return true;
+ } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
+ return true;
+ } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
+ // Casting from vector
+ return DestBits == PTy->getBitWidth();
+ } else { // Casting from something else
+ return false;
+ }
+ } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
+ // Casting to vector
+ if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
+ // Casting from vector
+ return DestPTy->getBitWidth() == SrcPTy->getBitWidth();
+ } else { // Casting from something else
+ return DestPTy->getBitWidth() == SrcBits;
+ }
+ } else if (isa<PointerType>(DestTy)) { // Casting to pointer
+ if (isa<PointerType>(SrcTy)) { // Casting from pointer
+ return true;
+ } else if (SrcTy->isInteger()) { // Casting from integral
+ return true;
+ } else { // Casting from something else
+ return false;
+ }
+ } else { // Casting to something else
+ return false;
+ }
+}
+