[llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Interpreter.h
Reid Spencer
reid at x10sys.com
Sun Nov 26 17:06:23 PST 2006
Changes in directory llvm/lib/ExecutionEngine/Interpreter:
Execution.cpp updated: 1.147 -> 1.148
Interpreter.h updated: 1.76 -> 1.77
---
Log message:
For PR950: http://llvm.org/PR950 :
The long awaited CAST patch. This introduces 12 new instructions into LLVM
to replace the cast instruction. Corresponding changes throughout LLVM are
provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the
exception of 175.vpr which fails only on a slight floating point output
difference.
---
Diffs of the changes: (+182 -37)
Execution.cpp | 215 ++++++++++++++++++++++++++++++++++++++++++++++++----------
Interpreter.h | 4 -
2 files changed, 182 insertions(+), 37 deletions(-)
Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp
diff -u llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.147 llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.148
--- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.147 Wed Nov 8 13:16:44 2006
+++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Sun Nov 26 19:05:10 2006
@@ -81,8 +81,20 @@
GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
ExecutionContext &SF) {
switch (CE->getOpcode()) {
- case Instruction::Cast:
- return executeCastOperation(CE->getOperand(0), CE->getType(), SF);
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::PtrToInt:
+ case Instruction::IntToPtr:
+ case Instruction::BitCast:
+ return executeCastOperation(Instruction::CastOps(CE->getOpcode()),
+ CE->getOperand(0), CE->getType(), SF);
case Instruction::GetElementPtr:
return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
gep_type_end(CE), SF);
@@ -1030,12 +1042,15 @@
SetValue(&I, Dest, SF);
}
+#define IMPLEMENT_CAST_START \
+ switch (DstTy->getTypeID()) {
+
#define IMPLEMENT_CAST(DTY, DCTY, STY) \
- case Type::STY##TyID: Dest.DTY##Val = DCTY Src.STY##Val; break;
+ case Type::STY##TyID: Dest.DTY##Val = DCTY Src.STY##Val; break;
-#define IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY) \
+#define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \
case Type::DESTTY##TyID: \
- switch (SrcTy->getTypeID()) { \
+ switch (SrcTy->getTypeID()) { \
IMPLEMENT_CAST(DESTTY, DESTCTY, Bool); \
IMPLEMENT_CAST(DESTTY, DESTCTY, UByte); \
IMPLEMENT_CAST(DESTTY, DESTCTY, SByte); \
@@ -1045,52 +1060,182 @@
IMPLEMENT_CAST(DESTTY, DESTCTY, Int); \
IMPLEMENT_CAST(DESTTY, DESTCTY, ULong); \
IMPLEMENT_CAST(DESTTY, DESTCTY, Long); \
- IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer);
-
-#define IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY) \
+ IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer); \
IMPLEMENT_CAST(DESTTY, DESTCTY, Float); \
- IMPLEMENT_CAST(DESTTY, DESTCTY, Double)
-
-#define IMPLEMENT_CAST_CASE_END() \
- default: std::cout << "Unhandled cast: " << *SrcTy << " to " << *Ty << "\n"; \
+ IMPLEMENT_CAST(DESTTY, DESTCTY, Double) \
+ default: \
+ std::cout << "Unhandled cast: " \
+ << *SrcTy << " to " << *DstTy << "\n"; \
abort(); \
} \
break
-#define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \
- IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY); \
- IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY); \
- IMPLEMENT_CAST_CASE_END()
+#define IMPLEMENT_CAST_END \
+ default: std::cout \
+ << "Unhandled dest type for cast instruction: " \
+ << *DstTy << "\n"; \
+ abort(); \
+ }
-GenericValue Interpreter::executeCastOperation(Value *SrcVal, const Type *Ty,
+GenericValue Interpreter::executeCastOperation(Instruction::CastOps opcode,
+ Value *SrcVal, const Type *DstTy,
ExecutionContext &SF) {
const Type *SrcTy = SrcVal->getType();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
- switch (Ty->getTypeID()) {
- IMPLEMENT_CAST_CASE(UByte , (unsigned char));
- IMPLEMENT_CAST_CASE(SByte , ( signed char));
- IMPLEMENT_CAST_CASE(UShort , (unsigned short));
- IMPLEMENT_CAST_CASE(Short , ( signed short));
- IMPLEMENT_CAST_CASE(UInt , (unsigned int ));
- IMPLEMENT_CAST_CASE(Int , ( signed int ));
- IMPLEMENT_CAST_CASE(ULong , (uint64_t));
- IMPLEMENT_CAST_CASE(Long , ( int64_t));
- IMPLEMENT_CAST_CASE(Pointer, (PointerTy));
- IMPLEMENT_CAST_CASE(Float , (float));
- IMPLEMENT_CAST_CASE(Double , (double));
- IMPLEMENT_CAST_CASE(Bool , (bool));
- default:
- std::cout << "Unhandled dest type for cast instruction: " << *Ty << "\n";
- abort();
+ if (opcode == Instruction::Trunc && DstTy->getTypeID() == Type::BoolTyID) {
+ // For truncations to bool, we must clear the high order bits of the source
+ switch (SrcTy->getTypeID()) {
+ case Type::BoolTyID: Src.BoolVal &= 1; break;
+ case Type::SByteTyID: Src.SByteVal &= 1; break;
+ case Type::UByteTyID: Src.UByteVal &= 1; break;
+ case Type::ShortTyID: Src.ShortVal &= 1; break;
+ case Type::UShortTyID: Src.UShortVal &= 1; break;
+ case Type::IntTyID: Src.IntVal &= 1; break;
+ case Type::UIntTyID: Src.UIntVal &= 1; break;
+ case Type::LongTyID: Src.LongVal &= 1; break;
+ case Type::ULongTyID: Src.ULongVal &= 1; break;
+ default:
+ assert(0 && "Can't trunc a non-integer!");
+ break;
+ }
+ } else if (opcode == Instruction::SExt &&
+ SrcTy->getTypeID() == Type::BoolTyID) {
+ // For sign extension from bool, we must extend the source bits.
+ SrcTy = Type::LongTy;
+ Src.LongVal = 0 - Src.BoolVal;
+ }
+
+ switch (opcode) {
+ case Instruction::Trunc: // src integer, dest integral (can't be long)
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Bool , (bool));
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char));
+ IMPLEMENT_CAST_CASE(SByte , ( signed char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short));
+ IMPLEMENT_CAST_CASE(Short , ( signed short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int ));
+ IMPLEMENT_CAST_CASE(Int , ( signed int ));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::ZExt: // src integral (can't be long), dest integer
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char));
+ IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short));
+ IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int ));
+ IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int ));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t));
+ IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::SExt: // src integral (can't be long), dest integer
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char)(signed char));
+ IMPLEMENT_CAST_CASE(SByte , (signed char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short)(signed short));
+ IMPLEMENT_CAST_CASE(Short , (signed short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int )(signed int));
+ IMPLEMENT_CAST_CASE(Int , (signed int));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t)(int64_t));
+ IMPLEMENT_CAST_CASE(Long , (int64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::FPTrunc: // src double, dest float
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Float , (float));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::FPExt: // src float, dest double
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Double , (double));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::UIToFP: // src integral, dest floating
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Float , (float)(uint64_t));
+ IMPLEMENT_CAST_CASE(Double , (double)(uint64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::SIToFP: // src integeral, dest floating
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Float , (float)(int64_t));
+ IMPLEMENT_CAST_CASE(Double , (double)(int64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::FPToUI: // src floating, dest integral
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Bool , (bool));
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char));
+ IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short));
+ IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int ));
+ IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int ));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t));
+ IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::FPToSI: // src floating, dest integral
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Bool , (bool));
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char)(signed char));
+ IMPLEMENT_CAST_CASE(SByte , (signed char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short)(signed short));
+ IMPLEMENT_CAST_CASE(Short , (signed short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int )(signed int));
+ IMPLEMENT_CAST_CASE(Int , (signed int));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t)(int64_t));
+ IMPLEMENT_CAST_CASE(Long , (int64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::PtrToInt: // src pointer, dest integral
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Bool , (bool));
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char));
+ IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short));
+ IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int));
+ IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t));
+ IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::IntToPtr: // src integral, dest pointer
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Pointer, (PointerTy));
+ IMPLEMENT_CAST_END
+ break;
+ case Instruction::BitCast: // src any, dest any (same size)
+ IMPLEMENT_CAST_START
+ IMPLEMENT_CAST_CASE(Bool , (bool));
+ IMPLEMENT_CAST_CASE(UByte , (unsigned char));
+ IMPLEMENT_CAST_CASE(SByte , ( signed char));
+ IMPLEMENT_CAST_CASE(UShort , (unsigned short));
+ IMPLEMENT_CAST_CASE(Short , ( signed short));
+ IMPLEMENT_CAST_CASE(UInt , (unsigned int));
+ IMPLEMENT_CAST_CASE(Int , ( signed int));
+ IMPLEMENT_CAST_CASE(ULong , (uint64_t));
+ IMPLEMENT_CAST_CASE(Long , ( int64_t));
+ IMPLEMENT_CAST_CASE(Pointer, (PointerTy));
+ IMPLEMENT_CAST_CASE(Float , (float));
+ IMPLEMENT_CAST_CASE(Double , (double));
+ IMPLEMENT_CAST_END
+ break;
+ default:
+ std::cout
+ << "Invalid cast opcode for cast instruction: " << opcode << "\n";
+ abort();
}
-
return Dest;
}
void Interpreter::visitCastInst(CastInst &I) {
ExecutionContext &SF = ECStack.back();
- SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF);
+ SetValue(&I, executeCastOperation(I.getOpcode(), I.getOperand(0),
+ I.getType(), SF), SF);
}
#define IMPLEMENT_VAARG(TY) \
Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.76 llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.77
--- llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.76 Wed Nov 8 00:47:33 2006
+++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.h Sun Nov 26 19:05:10 2006
@@ -192,8 +192,8 @@
void initializeExternalFunctions();
GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF);
GenericValue getOperandValue(Value *V, ExecutionContext &SF);
- GenericValue executeCastOperation(Value *SrcVal, const Type *Ty,
- ExecutionContext &SF);
+ GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal,
+ const Type *Ty, ExecutionContext &SF);
void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result);
};
More information about the llvm-commits
mailing list