| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1 | //===-- Execution.cpp - Implement code to simulate the program ------------===// | 
 | 2 | //  | 
 | 3 | //  This file contains the actual instruction interpreter. | 
 | 4 | // | 
 | 5 | //===----------------------------------------------------------------------===// | 
 | 6 |  | 
 | 7 | #include "Interpreter.h" | 
 | 8 | #include "ExecutionAnnotations.h" | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 9 | #include "llvm/GlobalVariable.h" | 
 | 10 | #include "llvm/Function.h" | 
| Chris Lattner | 7061dc5 | 2001-12-03 18:02:31 +0000 | [diff] [blame] | 11 | #include "llvm/iPHINode.h" | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 12 | #include "llvm/iOther.h" | 
 | 13 | #include "llvm/iTerminators.h" | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 14 | #include "llvm/iMemory.h" | 
| Chris Lattner | e2cbbce | 2002-04-29 18:56:45 +0000 | [diff] [blame] | 15 | #include "llvm/DerivedTypes.h" | 
| Chris Lattner | 31bcdb8 | 2002-04-28 19:55:58 +0000 | [diff] [blame] | 16 | #include "llvm/Constants.h" | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 17 | #include "llvm/Assembly/Writer.h" | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 18 | #include "Support/CommandLine.h" | 
| Chris Lattner | bbdabce | 2002-12-08 05:51:08 +0000 | [diff] [blame] | 19 | #include "Support/Statistic.h" | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 20 | #include <math.h>  // For fmod | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 21 | #include <signal.h> | 
 | 22 | #include <setjmp.h> | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 23 | using std::vector; | 
 | 24 | using std::cout; | 
 | 25 | using std::cerr; | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 26 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 27 | Interpreter *TheEE = 0; | 
 | 28 |  | 
| Chris Lattner | bbdabce | 2002-12-08 05:51:08 +0000 | [diff] [blame] | 29 | namespace { | 
 | 30 |   Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); | 
| Chris Lattner | 138b0cd | 2002-12-08 06:01:34 +0000 | [diff] [blame] | 31 |  | 
 | 32 |   cl::opt<bool> | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 33 |   QuietMode("quiet", cl::desc("Do not emit any non-program output"), | 
 | 34 | 	    cl::init(true)); | 
| Chris Lattner | 138b0cd | 2002-12-08 06:01:34 +0000 | [diff] [blame] | 35 |  | 
 | 36 |   cl::alias  | 
 | 37 |   QuietModeA("q", cl::desc("Alias for -quiet"), cl::aliasopt(QuietMode)); | 
 | 38 |  | 
 | 39 |   cl::opt<bool> | 
 | 40 |   ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks")); | 
 | 41 |  | 
 | 42 |   cl::opt<bool> | 
 | 43 |   AbortOnExceptions("abort-on-exception", | 
 | 44 |                     cl::desc("Halt execution on a machine exception")); | 
| Chris Lattner | bbdabce | 2002-12-08 05:51:08 +0000 | [diff] [blame] | 45 | } | 
 | 46 |  | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 47 | // Create a TargetData structure to handle memory addressing and size/alignment | 
 | 48 | // computations | 
 | 49 | // | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 50 | CachedWriter CW;     // Object to accelerate printing of LLVM | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 51 |  | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 52 | #ifdef PROFILE_STRUCTURE_FIELDS | 
| Chris Lattner | 5ff62e9 | 2002-07-22 02:10:13 +0000 | [diff] [blame] | 53 | static cl::opt<bool> | 
 | 54 | ProfileStructureFields("profilestructfields",  | 
 | 55 |                        cl::desc("Profile Structure Field Accesses")); | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 56 | #include <map> | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 57 | static std::map<const StructType *, vector<unsigned> > FieldAccessCounts; | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 58 | #endif | 
 | 59 |  | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 60 | sigjmp_buf SignalRecoverBuffer; | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 61 | static bool InInstruction = false; | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 62 |  | 
 | 63 | extern "C" { | 
 | 64 | static void SigHandler(int Signal) { | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 65 |   if (InInstruction) | 
 | 66 |     siglongjmp(SignalRecoverBuffer, Signal); | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 67 | } | 
 | 68 | } | 
 | 69 |  | 
 | 70 | static void initializeSignalHandlers() { | 
 | 71 |   struct sigaction Action; | 
 | 72 |   Action.sa_handler = SigHandler; | 
 | 73 |   Action.sa_flags   = SA_SIGINFO; | 
 | 74 |   sigemptyset(&Action.sa_mask); | 
 | 75 |   sigaction(SIGSEGV, &Action, 0); | 
 | 76 |   sigaction(SIGBUS, &Action, 0); | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 77 |   sigaction(SIGINT, &Action, 0); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 78 |   sigaction(SIGFPE, &Action, 0); | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 79 | } | 
 | 80 |  | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 81 |  | 
 | 82 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 83 | //                     Value Manipulation code | 
 | 84 | //===----------------------------------------------------------------------===// | 
 | 85 |  | 
 | 86 | static unsigned getOperandSlot(Value *V) { | 
 | 87 |   SlotNumber *SN = (SlotNumber*)V->getAnnotation(SlotNumberAID); | 
 | 88 |   assert(SN && "Operand does not have a slot number annotation!"); | 
 | 89 |   return SN->SlotNum; | 
 | 90 | } | 
 | 91 |  | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 92 | // Operations used by constant expr implementations... | 
 | 93 | static GenericValue executeCastOperation(Value *Src, const Type *DestTy, | 
 | 94 |                                          ExecutionContext &SF); | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 95 | static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,  | 
 | 96 | 				   const Type *Ty, ExecutionContext &SF); | 
 | 97 |  | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 98 |  | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 99 | static GenericValue getOperandValue(Value *V, ExecutionContext &SF) { | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 100 |   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { | 
 | 101 |     switch (CE->getOpcode()) { | 
 | 102 |     case Instruction::Cast: | 
 | 103 |       return executeCastOperation(CE->getOperand(0), CE->getType(), SF); | 
 | 104 |     case Instruction::GetElementPtr: | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 105 |       return TheEE->executeGEPOperation(CE->getOperand(0), CE->op_begin()+1, | 
 | 106 | 					CE->op_end(), SF); | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 107 |     case Instruction::Add: | 
 | 108 |       return executeAddInst(getOperandValue(CE->getOperand(0), SF), | 
 | 109 |                             getOperandValue(CE->getOperand(1), SF), | 
 | 110 |                             CE->getType(), SF); | 
 | 111 |     default: | 
 | 112 |       cerr << "Unhandled ConstantExpr: " << CE << "\n"; | 
 | 113 |       abort(); | 
| Chris Lattner | 04e2ad7 | 2003-04-21 22:43:32 +0000 | [diff] [blame] | 114 |       return GenericValue(); | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 115 |     } | 
 | 116 |   } else if (Constant *CPV = dyn_cast<Constant>(V)) { | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 117 |     return TheEE->getConstantValue(CPV); | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 118 |   } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) { | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 119 |     return PTOGV(TheEE->getPointerToGlobal(GV)); | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 120 |   } else { | 
 | 121 |     unsigned TyP = V->getType()->getUniqueID();   // TypePlane for value | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 122 |     unsigned OpSlot = getOperandSlot(V); | 
 | 123 |     assert(TyP < SF.Values.size() &&  | 
 | 124 |            OpSlot < SF.Values[TyP].size() && "Value out of range!"); | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 125 |     return SF.Values[TyP][getOperandSlot(V)]; | 
 | 126 |   } | 
 | 127 | } | 
 | 128 |  | 
 | 129 | static void printOperandInfo(Value *V, ExecutionContext &SF) { | 
| Chris Lattner | e9bb2df | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 130 |   if (isa<Constant>(V)) { | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 131 |     cout << "Constant Pool Value\n"; | 
 | 132 |   } else if (isa<GlobalValue>(V)) { | 
 | 133 |     cout << "Global Value\n"; | 
 | 134 |   } else { | 
 | 135 |     unsigned TyP  = V->getType()->getUniqueID();   // TypePlane for value | 
 | 136 |     unsigned Slot = getOperandSlot(V); | 
 | 137 |     cout << "Value=" << (void*)V << " TypeID=" << TyP << " Slot=" << Slot | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 138 |          << " Addr=" << &SF.Values[TyP][Slot] << " SF=" << &SF | 
 | 139 |          << " Contents=0x"; | 
 | 140 |  | 
 | 141 |     const unsigned char *Buf = (const unsigned char*)&SF.Values[TyP][Slot]; | 
 | 142 |     for (unsigned i = 0; i < sizeof(GenericValue); ++i) { | 
 | 143 |       unsigned char Cur = Buf[i]; | 
 | 144 |       cout << ( Cur     >= 160? char((Cur>>4)+'A'-10) : char((Cur>>4) + '0')) | 
 | 145 |            << ((Cur&15) >=  10? char((Cur&15)+'A'-10) : char((Cur&15) + '0')); | 
 | 146 |     } | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 147 |     cout << "\n"; | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 148 |   } | 
 | 149 | } | 
 | 150 |  | 
 | 151 |  | 
 | 152 |  | 
 | 153 | static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) { | 
 | 154 |   unsigned TyP = V->getType()->getUniqueID();   // TypePlane for value | 
 | 155 |  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 156 |   //cout << "Setting value: " << &SF.Values[TyP][getOperandSlot(V)] << "\n"; | 
| Chris Lattner | 39bb5b4 | 2001-10-15 13:25:40 +0000 | [diff] [blame] | 157 |   SF.Values[TyP][getOperandSlot(V)] = Val; | 
 | 158 | } | 
 | 159 |  | 
 | 160 |  | 
 | 161 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 162 | //                    Annotation Wrangling code | 
 | 163 | //===----------------------------------------------------------------------===// | 
 | 164 |  | 
 | 165 | void Interpreter::initializeExecutionEngine() { | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 166 |   TheEE = this; | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 167 |   AnnotationManager::registerAnnotationFactory(MethodInfoAID, | 
 | 168 |                                                &MethodInfo::Create); | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 169 |   initializeSignalHandlers(); | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 170 | } | 
 | 171 |  | 
| Chris Lattner | 2adcd83 | 2002-05-03 19:52:30 +0000 | [diff] [blame] | 172 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 173 | //                    Binary Instruction Implementations | 
 | 174 | //===----------------------------------------------------------------------===// | 
 | 175 |  | 
 | 176 | #define IMPLEMENT_BINARY_OPERATOR(OP, TY) \ | 
 | 177 |    case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; break | 
 | 178 |  | 
 | 179 | static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,  | 
 | 180 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 181 |   GenericValue Dest; | 
 | 182 |   switch (Ty->getPrimitiveID()) { | 
 | 183 |     IMPLEMENT_BINARY_OPERATOR(+, UByte); | 
 | 184 |     IMPLEMENT_BINARY_OPERATOR(+, SByte); | 
 | 185 |     IMPLEMENT_BINARY_OPERATOR(+, UShort); | 
 | 186 |     IMPLEMENT_BINARY_OPERATOR(+, Short); | 
 | 187 |     IMPLEMENT_BINARY_OPERATOR(+, UInt); | 
 | 188 |     IMPLEMENT_BINARY_OPERATOR(+, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 189 |     IMPLEMENT_BINARY_OPERATOR(+, ULong); | 
 | 190 |     IMPLEMENT_BINARY_OPERATOR(+, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 191 |     IMPLEMENT_BINARY_OPERATOR(+, Float); | 
 | 192 |     IMPLEMENT_BINARY_OPERATOR(+, Double); | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 193 |     IMPLEMENT_BINARY_OPERATOR(+, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 194 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 195 |     cout << "Unhandled type for Add instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 196 |   } | 
 | 197 |   return Dest; | 
 | 198 | } | 
 | 199 |  | 
 | 200 | static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,  | 
 | 201 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 202 |   GenericValue Dest; | 
 | 203 |   switch (Ty->getPrimitiveID()) { | 
 | 204 |     IMPLEMENT_BINARY_OPERATOR(-, UByte); | 
 | 205 |     IMPLEMENT_BINARY_OPERATOR(-, SByte); | 
 | 206 |     IMPLEMENT_BINARY_OPERATOR(-, UShort); | 
 | 207 |     IMPLEMENT_BINARY_OPERATOR(-, Short); | 
 | 208 |     IMPLEMENT_BINARY_OPERATOR(-, UInt); | 
 | 209 |     IMPLEMENT_BINARY_OPERATOR(-, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 210 |     IMPLEMENT_BINARY_OPERATOR(-, ULong); | 
 | 211 |     IMPLEMENT_BINARY_OPERATOR(-, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 212 |     IMPLEMENT_BINARY_OPERATOR(-, Float); | 
 | 213 |     IMPLEMENT_BINARY_OPERATOR(-, Double); | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 214 |     IMPLEMENT_BINARY_OPERATOR(-, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 215 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 216 |     cout << "Unhandled type for Sub instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 217 |   } | 
 | 218 |   return Dest; | 
 | 219 | } | 
 | 220 |  | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 221 | static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,  | 
 | 222 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 223 |   GenericValue Dest; | 
 | 224 |   switch (Ty->getPrimitiveID()) { | 
 | 225 |     IMPLEMENT_BINARY_OPERATOR(*, UByte); | 
 | 226 |     IMPLEMENT_BINARY_OPERATOR(*, SByte); | 
 | 227 |     IMPLEMENT_BINARY_OPERATOR(*, UShort); | 
 | 228 |     IMPLEMENT_BINARY_OPERATOR(*, Short); | 
 | 229 |     IMPLEMENT_BINARY_OPERATOR(*, UInt); | 
 | 230 |     IMPLEMENT_BINARY_OPERATOR(*, Int); | 
 | 231 |     IMPLEMENT_BINARY_OPERATOR(*, ULong); | 
 | 232 |     IMPLEMENT_BINARY_OPERATOR(*, Long); | 
 | 233 |     IMPLEMENT_BINARY_OPERATOR(*, Float); | 
 | 234 |     IMPLEMENT_BINARY_OPERATOR(*, Double); | 
 | 235 |     IMPLEMENT_BINARY_OPERATOR(*, Pointer); | 
 | 236 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 237 |     cout << "Unhandled type for Mul instruction: " << Ty << "\n"; | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 238 |   } | 
 | 239 |   return Dest; | 
 | 240 | } | 
 | 241 |  | 
 | 242 | static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2,  | 
 | 243 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 244 |   GenericValue Dest; | 
 | 245 |   switch (Ty->getPrimitiveID()) { | 
 | 246 |     IMPLEMENT_BINARY_OPERATOR(/, UByte); | 
 | 247 |     IMPLEMENT_BINARY_OPERATOR(/, SByte); | 
 | 248 |     IMPLEMENT_BINARY_OPERATOR(/, UShort); | 
 | 249 |     IMPLEMENT_BINARY_OPERATOR(/, Short); | 
 | 250 |     IMPLEMENT_BINARY_OPERATOR(/, UInt); | 
 | 251 |     IMPLEMENT_BINARY_OPERATOR(/, Int); | 
 | 252 |     IMPLEMENT_BINARY_OPERATOR(/, ULong); | 
 | 253 |     IMPLEMENT_BINARY_OPERATOR(/, Long); | 
 | 254 |     IMPLEMENT_BINARY_OPERATOR(/, Float); | 
 | 255 |     IMPLEMENT_BINARY_OPERATOR(/, Double); | 
 | 256 |     IMPLEMENT_BINARY_OPERATOR(/, Pointer); | 
 | 257 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 258 |     cout << "Unhandled type for Div instruction: " << Ty << "\n"; | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 259 |   } | 
 | 260 |   return Dest; | 
 | 261 | } | 
 | 262 |  | 
 | 263 | static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2,  | 
 | 264 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 265 |   GenericValue Dest; | 
 | 266 |   switch (Ty->getPrimitiveID()) { | 
 | 267 |     IMPLEMENT_BINARY_OPERATOR(%, UByte); | 
 | 268 |     IMPLEMENT_BINARY_OPERATOR(%, SByte); | 
 | 269 |     IMPLEMENT_BINARY_OPERATOR(%, UShort); | 
 | 270 |     IMPLEMENT_BINARY_OPERATOR(%, Short); | 
 | 271 |     IMPLEMENT_BINARY_OPERATOR(%, UInt); | 
 | 272 |     IMPLEMENT_BINARY_OPERATOR(%, Int); | 
 | 273 |     IMPLEMENT_BINARY_OPERATOR(%, ULong); | 
 | 274 |     IMPLEMENT_BINARY_OPERATOR(%, Long); | 
 | 275 |     IMPLEMENT_BINARY_OPERATOR(%, Pointer); | 
 | 276 |   case Type::FloatTyID: | 
 | 277 |     Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal); | 
 | 278 |     break; | 
 | 279 |   case Type::DoubleTyID: | 
 | 280 |     Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal); | 
 | 281 |     break; | 
 | 282 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 283 |     cout << "Unhandled type for Rem instruction: " << Ty << "\n"; | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 284 |   } | 
 | 285 |   return Dest; | 
 | 286 | } | 
 | 287 |  | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 288 | static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2,  | 
| Chris Lattner | 4d0e1f9 | 2001-10-30 20:54:36 +0000 | [diff] [blame] | 289 | 				   const Type *Ty, ExecutionContext &SF) { | 
 | 290 |   GenericValue Dest; | 
 | 291 |   switch (Ty->getPrimitiveID()) { | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 292 |     IMPLEMENT_BINARY_OPERATOR(&, UByte); | 
 | 293 |     IMPLEMENT_BINARY_OPERATOR(&, SByte); | 
 | 294 |     IMPLEMENT_BINARY_OPERATOR(&, UShort); | 
 | 295 |     IMPLEMENT_BINARY_OPERATOR(&, Short); | 
 | 296 |     IMPLEMENT_BINARY_OPERATOR(&, UInt); | 
 | 297 |     IMPLEMENT_BINARY_OPERATOR(&, Int); | 
 | 298 |     IMPLEMENT_BINARY_OPERATOR(&, ULong); | 
 | 299 |     IMPLEMENT_BINARY_OPERATOR(&, Long); | 
 | 300 |     IMPLEMENT_BINARY_OPERATOR(&, Pointer); | 
 | 301 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 302 |     cout << "Unhandled type for And instruction: " << Ty << "\n"; | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 303 |   } | 
 | 304 |   return Dest; | 
 | 305 | } | 
 | 306 |  | 
 | 307 |  | 
 | 308 | static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2,  | 
 | 309 |                                   const Type *Ty, ExecutionContext &SF) { | 
 | 310 |   GenericValue Dest; | 
 | 311 |   switch (Ty->getPrimitiveID()) { | 
 | 312 |     IMPLEMENT_BINARY_OPERATOR(|, UByte); | 
 | 313 |     IMPLEMENT_BINARY_OPERATOR(|, SByte); | 
 | 314 |     IMPLEMENT_BINARY_OPERATOR(|, UShort); | 
 | 315 |     IMPLEMENT_BINARY_OPERATOR(|, Short); | 
 | 316 |     IMPLEMENT_BINARY_OPERATOR(|, UInt); | 
 | 317 |     IMPLEMENT_BINARY_OPERATOR(|, Int); | 
 | 318 |     IMPLEMENT_BINARY_OPERATOR(|, ULong); | 
 | 319 |     IMPLEMENT_BINARY_OPERATOR(|, Long); | 
 | 320 |     IMPLEMENT_BINARY_OPERATOR(|, Pointer); | 
 | 321 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 322 |     cout << "Unhandled type for Or instruction: " << Ty << "\n"; | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 323 |   } | 
 | 324 |   return Dest; | 
 | 325 | } | 
 | 326 |  | 
 | 327 |  | 
 | 328 | static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2,  | 
 | 329 |                                    const Type *Ty, ExecutionContext &SF) { | 
 | 330 |   GenericValue Dest; | 
 | 331 |   switch (Ty->getPrimitiveID()) { | 
| Chris Lattner | 4d0e1f9 | 2001-10-30 20:54:36 +0000 | [diff] [blame] | 332 |     IMPLEMENT_BINARY_OPERATOR(^, UByte); | 
 | 333 |     IMPLEMENT_BINARY_OPERATOR(^, SByte); | 
 | 334 |     IMPLEMENT_BINARY_OPERATOR(^, UShort); | 
 | 335 |     IMPLEMENT_BINARY_OPERATOR(^, Short); | 
 | 336 |     IMPLEMENT_BINARY_OPERATOR(^, UInt); | 
 | 337 |     IMPLEMENT_BINARY_OPERATOR(^, Int); | 
 | 338 |     IMPLEMENT_BINARY_OPERATOR(^, ULong); | 
 | 339 |     IMPLEMENT_BINARY_OPERATOR(^, Long); | 
 | 340 |     IMPLEMENT_BINARY_OPERATOR(^, Pointer); | 
 | 341 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 342 |     cout << "Unhandled type for Xor instruction: " << Ty << "\n"; | 
| Chris Lattner | 4d0e1f9 | 2001-10-30 20:54:36 +0000 | [diff] [blame] | 343 |   } | 
 | 344 |   return Dest; | 
 | 345 | } | 
 | 346 |  | 
 | 347 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 348 | #define IMPLEMENT_SETCC(OP, TY) \ | 
 | 349 |    case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break | 
 | 350 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 351 | static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2,  | 
 | 352 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 353 |   GenericValue Dest; | 
 | 354 |   switch (Ty->getPrimitiveID()) { | 
 | 355 |     IMPLEMENT_SETCC(==, UByte); | 
 | 356 |     IMPLEMENT_SETCC(==, SByte); | 
 | 357 |     IMPLEMENT_SETCC(==, UShort); | 
 | 358 |     IMPLEMENT_SETCC(==, Short); | 
 | 359 |     IMPLEMENT_SETCC(==, UInt); | 
 | 360 |     IMPLEMENT_SETCC(==, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 361 |     IMPLEMENT_SETCC(==, ULong); | 
 | 362 |     IMPLEMENT_SETCC(==, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 363 |     IMPLEMENT_SETCC(==, Float); | 
 | 364 |     IMPLEMENT_SETCC(==, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 365 |     IMPLEMENT_SETCC(==, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 366 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 367 |     cout << "Unhandled type for SetEQ instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 368 |   } | 
 | 369 |   return Dest; | 
 | 370 | } | 
 | 371 |  | 
 | 372 | static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2,  | 
 | 373 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 374 |   GenericValue Dest; | 
 | 375 |   switch (Ty->getPrimitiveID()) { | 
 | 376 |     IMPLEMENT_SETCC(!=, UByte); | 
 | 377 |     IMPLEMENT_SETCC(!=, SByte); | 
 | 378 |     IMPLEMENT_SETCC(!=, UShort); | 
 | 379 |     IMPLEMENT_SETCC(!=, Short); | 
 | 380 |     IMPLEMENT_SETCC(!=, UInt); | 
 | 381 |     IMPLEMENT_SETCC(!=, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 382 |     IMPLEMENT_SETCC(!=, ULong); | 
 | 383 |     IMPLEMENT_SETCC(!=, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 384 |     IMPLEMENT_SETCC(!=, Float); | 
 | 385 |     IMPLEMENT_SETCC(!=, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 386 |     IMPLEMENT_SETCC(!=, Pointer); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 387 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 388 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 389 |     cout << "Unhandled type for SetNE instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 390 |   } | 
 | 391 |   return Dest; | 
 | 392 | } | 
 | 393 |  | 
 | 394 | static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,  | 
 | 395 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 396 |   GenericValue Dest; | 
 | 397 |   switch (Ty->getPrimitiveID()) { | 
 | 398 |     IMPLEMENT_SETCC(<=, UByte); | 
 | 399 |     IMPLEMENT_SETCC(<=, SByte); | 
 | 400 |     IMPLEMENT_SETCC(<=, UShort); | 
 | 401 |     IMPLEMENT_SETCC(<=, Short); | 
 | 402 |     IMPLEMENT_SETCC(<=, UInt); | 
 | 403 |     IMPLEMENT_SETCC(<=, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 404 |     IMPLEMENT_SETCC(<=, ULong); | 
 | 405 |     IMPLEMENT_SETCC(<=, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 406 |     IMPLEMENT_SETCC(<=, Float); | 
 | 407 |     IMPLEMENT_SETCC(<=, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 408 |     IMPLEMENT_SETCC(<=, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 409 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 410 |     cout << "Unhandled type for SetLE instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 411 |   } | 
 | 412 |   return Dest; | 
 | 413 | } | 
 | 414 |  | 
 | 415 | static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,  | 
 | 416 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 417 |   GenericValue Dest; | 
 | 418 |   switch (Ty->getPrimitiveID()) { | 
 | 419 |     IMPLEMENT_SETCC(>=, UByte); | 
 | 420 |     IMPLEMENT_SETCC(>=, SByte); | 
 | 421 |     IMPLEMENT_SETCC(>=, UShort); | 
 | 422 |     IMPLEMENT_SETCC(>=, Short); | 
 | 423 |     IMPLEMENT_SETCC(>=, UInt); | 
 | 424 |     IMPLEMENT_SETCC(>=, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 425 |     IMPLEMENT_SETCC(>=, ULong); | 
 | 426 |     IMPLEMENT_SETCC(>=, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 427 |     IMPLEMENT_SETCC(>=, Float); | 
 | 428 |     IMPLEMENT_SETCC(>=, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 429 |     IMPLEMENT_SETCC(>=, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 430 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 431 |     cout << "Unhandled type for SetGE instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 432 |   } | 
 | 433 |   return Dest; | 
 | 434 | } | 
 | 435 |  | 
 | 436 | static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2,  | 
 | 437 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 438 |   GenericValue Dest; | 
 | 439 |   switch (Ty->getPrimitiveID()) { | 
 | 440 |     IMPLEMENT_SETCC(<, UByte); | 
 | 441 |     IMPLEMENT_SETCC(<, SByte); | 
 | 442 |     IMPLEMENT_SETCC(<, UShort); | 
 | 443 |     IMPLEMENT_SETCC(<, Short); | 
 | 444 |     IMPLEMENT_SETCC(<, UInt); | 
 | 445 |     IMPLEMENT_SETCC(<, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 446 |     IMPLEMENT_SETCC(<, ULong); | 
 | 447 |     IMPLEMENT_SETCC(<, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 448 |     IMPLEMENT_SETCC(<, Float); | 
 | 449 |     IMPLEMENT_SETCC(<, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 450 |     IMPLEMENT_SETCC(<, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 451 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 452 |     cout << "Unhandled type for SetLT instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 453 |   } | 
 | 454 |   return Dest; | 
 | 455 | } | 
 | 456 |  | 
 | 457 | static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2,  | 
 | 458 | 				     const Type *Ty, ExecutionContext &SF) { | 
 | 459 |   GenericValue Dest; | 
 | 460 |   switch (Ty->getPrimitiveID()) { | 
 | 461 |     IMPLEMENT_SETCC(>, UByte); | 
 | 462 |     IMPLEMENT_SETCC(>, SByte); | 
 | 463 |     IMPLEMENT_SETCC(>, UShort); | 
 | 464 |     IMPLEMENT_SETCC(>, Short); | 
 | 465 |     IMPLEMENT_SETCC(>, UInt); | 
 | 466 |     IMPLEMENT_SETCC(>, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 467 |     IMPLEMENT_SETCC(>, ULong); | 
 | 468 |     IMPLEMENT_SETCC(>, Long); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 469 |     IMPLEMENT_SETCC(>, Float); | 
 | 470 |     IMPLEMENT_SETCC(>, Double); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 471 |     IMPLEMENT_SETCC(>, Pointer); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 472 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 473 |     cout << "Unhandled type for SetGT instruction: " << Ty << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 474 |   } | 
 | 475 |   return Dest; | 
 | 476 | } | 
 | 477 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 478 | static void executeBinaryInst(BinaryOperator &I, ExecutionContext &SF) { | 
 | 479 |   const Type *Ty    = I.getOperand(0)->getType(); | 
 | 480 |   GenericValue Src1 = getOperandValue(I.getOperand(0), SF); | 
 | 481 |   GenericValue Src2 = getOperandValue(I.getOperand(1), SF); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 482 |   GenericValue R;   // Result | 
 | 483 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 484 |   switch (I.getOpcode()) { | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 485 |   case Instruction::Add:   R = executeAddInst  (Src1, Src2, Ty, SF); break; | 
 | 486 |   case Instruction::Sub:   R = executeSubInst  (Src1, Src2, Ty, SF); break; | 
 | 487 |   case Instruction::Mul:   R = executeMulInst  (Src1, Src2, Ty, SF); break; | 
 | 488 |   case Instruction::Div:   R = executeDivInst  (Src1, Src2, Ty, SF); break; | 
 | 489 |   case Instruction::Rem:   R = executeRemInst  (Src1, Src2, Ty, SF); break; | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 490 |   case Instruction::And:   R = executeAndInst  (Src1, Src2, Ty, SF); break; | 
 | 491 |   case Instruction::Or:    R = executeOrInst   (Src1, Src2, Ty, SF); break; | 
| Chris Lattner | 4d0e1f9 | 2001-10-30 20:54:36 +0000 | [diff] [blame] | 492 |   case Instruction::Xor:   R = executeXorInst  (Src1, Src2, Ty, SF); break; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 493 |   case Instruction::SetEQ: R = executeSetEQInst(Src1, Src2, Ty, SF); break; | 
 | 494 |   case Instruction::SetNE: R = executeSetNEInst(Src1, Src2, Ty, SF); break; | 
 | 495 |   case Instruction::SetLE: R = executeSetLEInst(Src1, Src2, Ty, SF); break; | 
 | 496 |   case Instruction::SetGE: R = executeSetGEInst(Src1, Src2, Ty, SF); break; | 
 | 497 |   case Instruction::SetLT: R = executeSetLTInst(Src1, Src2, Ty, SF); break; | 
 | 498 |   case Instruction::SetGT: R = executeSetGTInst(Src1, Src2, Ty, SF); break; | 
 | 499 |   default: | 
 | 500 |     cout << "Don't know how to handle this binary operator!\n-->" << I; | 
| Chris Lattner | 4d0e1f9 | 2001-10-30 20:54:36 +0000 | [diff] [blame] | 501 |     R = Src1; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 502 |   } | 
 | 503 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 504 |   SetValue(&I, R, SF); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 505 | } | 
 | 506 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 507 | //===----------------------------------------------------------------------===// | 
 | 508 | //                     Terminator Instruction Implementations | 
 | 509 | //===----------------------------------------------------------------------===// | 
 | 510 |  | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 511 | static void PerformExitStuff() { | 
 | 512 | #ifdef PROFILE_STRUCTURE_FIELDS | 
 | 513 |   // Print out structure field accounting information... | 
 | 514 |   if (!FieldAccessCounts.empty()) { | 
| Chris Lattner | 84efe09 | 2001-11-12 20:13:14 +0000 | [diff] [blame] | 515 |     CW << "Profile Field Access Counts:\n"; | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 516 |     std::map<const StructType *, vector<unsigned> >::iterator  | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 517 |       I = FieldAccessCounts.begin(), E = FieldAccessCounts.end(); | 
 | 518 |     for (; I != E; ++I) { | 
 | 519 |       vector<unsigned> &OfC = I->second; | 
 | 520 |       CW << "  '" << (Value*)I->first << "'\t- Sum="; | 
 | 521 |        | 
 | 522 |       unsigned Sum = 0; | 
 | 523 |       for (unsigned i = 0; i < OfC.size(); ++i) | 
 | 524 |         Sum += OfC[i]; | 
 | 525 |       CW << Sum << " - "; | 
 | 526 |        | 
 | 527 |       for (unsigned i = 0; i < OfC.size(); ++i) { | 
 | 528 |         if (i) CW << ", "; | 
 | 529 |         CW << OfC[i]; | 
 | 530 |       } | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 531 |       CW << "\n"; | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 532 |     } | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 533 |     CW << "\n"; | 
| Chris Lattner | 84efe09 | 2001-11-12 20:13:14 +0000 | [diff] [blame] | 534 |  | 
 | 535 |     CW << "Profile Field Access Percentages:\n"; | 
 | 536 |     cout.precision(3); | 
 | 537 |     for (I = FieldAccessCounts.begin(); I != E; ++I) { | 
 | 538 |       vector<unsigned> &OfC = I->second; | 
 | 539 |       unsigned Sum = 0; | 
 | 540 |       for (unsigned i = 0; i < OfC.size(); ++i) | 
 | 541 |         Sum += OfC[i]; | 
 | 542 |        | 
 | 543 |       CW << "  '" << (Value*)I->first << "'\t- "; | 
 | 544 |       for (unsigned i = 0; i < OfC.size(); ++i) { | 
 | 545 |         if (i) CW << ", "; | 
 | 546 |         CW << double(OfC[i])/Sum; | 
 | 547 |       } | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 548 |       CW << "\n"; | 
| Chris Lattner | 84efe09 | 2001-11-12 20:13:14 +0000 | [diff] [blame] | 549 |     } | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 550 |     CW << "\n"; | 
| Chris Lattner | 84efe09 | 2001-11-12 20:13:14 +0000 | [diff] [blame] | 551 |  | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 552 |     FieldAccessCounts.clear(); | 
 | 553 |   } | 
 | 554 | #endif | 
 | 555 | } | 
 | 556 |  | 
| Chris Lattner | e43db88 | 2001-10-27 04:15:57 +0000 | [diff] [blame] | 557 | void Interpreter::exitCalled(GenericValue GV) { | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 558 |   if (!QuietMode) { | 
 | 559 |     cout << "Program returned "; | 
 | 560 |     print(Type::IntTy, GV); | 
 | 561 |     cout << " via 'void exit(int)'\n"; | 
 | 562 |   } | 
| Chris Lattner | e43db88 | 2001-10-27 04:15:57 +0000 | [diff] [blame] | 563 |  | 
 | 564 |   ExitCode = GV.SByteVal; | 
 | 565 |   ECStack.clear(); | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 566 |   PerformExitStuff(); | 
| Chris Lattner | e43db88 | 2001-10-27 04:15:57 +0000 | [diff] [blame] | 567 | } | 
 | 568 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 569 | void Interpreter::executeRetInst(ReturnInst &I, ExecutionContext &SF) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 570 |   const Type *RetTy = 0; | 
 | 571 |   GenericValue Result; | 
 | 572 |  | 
 | 573 |   // Save away the return value... (if we are not 'ret void') | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 574 |   if (I.getNumOperands()) { | 
 | 575 |     RetTy  = I.getReturnValue()->getType(); | 
 | 576 |     Result = getOperandValue(I.getReturnValue(), SF); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 577 |   } | 
 | 578 |  | 
 | 579 |   // Save previously executing meth | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 580 |   const Function *M = ECStack.back().CurMethod; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 581 |  | 
 | 582 |   // Pop the current stack frame... this invalidates SF | 
 | 583 |   ECStack.pop_back(); | 
 | 584 |  | 
 | 585 |   if (ECStack.empty()) {  // Finished main.  Put result into exit code... | 
 | 586 |     if (RetTy) {          // Nonvoid return type? | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 587 |       if (!QuietMode) { | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 588 |         CW << "Function " << M->getType() << " \"" << M->getName() | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 589 |            << "\" returned "; | 
 | 590 |         print(RetTy, Result); | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 591 |         cout << "\n"; | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 592 |       } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 593 |  | 
 | 594 |       if (RetTy->isIntegral()) | 
| Chris Lattner | f4dca80 | 2002-05-02 19:28:45 +0000 | [diff] [blame] | 595 | 	ExitCode = Result.IntVal;   // Capture the exit code of the program | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 596 |     } else { | 
 | 597 |       ExitCode = 0; | 
 | 598 |     } | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 599 |  | 
| Chris Lattner | a95c699 | 2001-11-12 16:28:48 +0000 | [diff] [blame] | 600 |     PerformExitStuff(); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 601 |     return; | 
 | 602 |   } | 
 | 603 |  | 
 | 604 |   // If we have a previous stack frame, and we have a previous call, fill in | 
 | 605 |   // the return value... | 
 | 606 |   // | 
 | 607 |   ExecutionContext &NewSF = ECStack.back(); | 
 | 608 |   if (NewSF.Caller) { | 
 | 609 |     if (NewSF.Caller->getType() != Type::VoidTy)             // Save result... | 
 | 610 |       SetValue(NewSF.Caller, Result, NewSF); | 
 | 611 |  | 
 | 612 |     NewSF.Caller = 0;          // We returned from the call... | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 613 |   } else if (!QuietMode) { | 
| Chris Lattner | 365a76e | 2001-09-10 04:49:44 +0000 | [diff] [blame] | 614 |     // This must be a function that is executing because of a user 'call' | 
 | 615 |     // instruction. | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 616 |     CW << "Function " << M->getType() << " \"" << M->getName() | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 617 |        << "\" returned "; | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 618 |     print(RetTy, Result); | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 619 |     cout << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 620 |   } | 
 | 621 | } | 
 | 622 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 623 | void Interpreter::executeBrInst(BranchInst &I, ExecutionContext &SF) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 624 |   SF.PrevBB = SF.CurBB;               // Update PrevBB so that PHI nodes work... | 
 | 625 |   BasicBlock *Dest; | 
 | 626 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 627 |   Dest = I.getSuccessor(0);          // Uncond branches have a fixed dest... | 
 | 628 |   if (!I.isUnconditional()) { | 
 | 629 |     Value *Cond = I.getCondition(); | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 630 |     GenericValue CondVal = getOperandValue(Cond, SF); | 
 | 631 |     if (CondVal.BoolVal == 0) // If false cond... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 632 |       Dest = I.getSuccessor(1);     | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 633 |   } | 
 | 634 |   SF.CurBB   = Dest;                  // Update CurBB to branch destination | 
 | 635 |   SF.CurInst = SF.CurBB->begin();     // Update new instruction ptr... | 
 | 636 | } | 
 | 637 |  | 
 | 638 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 639 | //                     Memory Instruction Implementations | 
 | 640 | //===----------------------------------------------------------------------===// | 
 | 641 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 642 | void Interpreter::executeAllocInst(AllocationInst &I, ExecutionContext &SF) { | 
 | 643 |   const Type *Ty = I.getType()->getElementType();  // Type to be allocated | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 644 |  | 
| Chris Lattner | cc82cc1 | 2002-04-28 21:57:33 +0000 | [diff] [blame] | 645 |   // Get the number of elements being allocated by the array... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 646 |   unsigned NumElements = getOperandValue(I.getOperand(0), SF).UIntVal; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 647 |  | 
 | 648 |   // Allocate enough memory to hold the type... | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 649 |   // FIXME: Don't use CALLOC, use a tainted malloc. | 
| Chris Lattner | 9bffa73 | 2002-02-19 18:50:09 +0000 | [diff] [blame] | 650 |   void *Memory = calloc(NumElements, TD.getTypeSize(Ty)); | 
 | 651 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 652 |   GenericValue Result = PTOGV(Memory); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 653 |   assert(Result.PointerVal != 0 && "Null pointer returned by malloc!"); | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 654 |   SetValue(&I, Result, SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 655 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 656 |   if (I.getOpcode() == Instruction::Alloca) | 
| Chris Lattner | 9bffa73 | 2002-02-19 18:50:09 +0000 | [diff] [blame] | 657 |     ECStack.back().Allocas.add(Memory); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 658 | } | 
 | 659 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 660 | static void executeFreeInst(FreeInst &I, ExecutionContext &SF) { | 
 | 661 |   assert(isa<PointerType>(I.getOperand(0)->getType()) && "Freeing nonptr?"); | 
 | 662 |   GenericValue Value = getOperandValue(I.getOperand(0), SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 663 |   // TODO: Check to make sure memory is allocated | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 664 |   free(GVTOP(Value));   // Free memory | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 665 | } | 
 | 666 |  | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 667 |  | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 668 | // getElementOffset - The workhorse for getelementptr. | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 669 | // | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 670 | GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I, | 
 | 671 | 					      User::op_iterator E, | 
 | 672 | 					      ExecutionContext &SF) { | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 673 |   assert(isa<PointerType>(Ptr->getType()) && | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 674 |          "Cannot getElementOffset of a nonpointer type!"); | 
 | 675 |  | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 676 |   PointerTy Total = 0; | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 677 |   const Type *Ty = Ptr->getType(); | 
 | 678 |  | 
 | 679 |   for (; I != E; ++I) { | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 680 |     if (const StructType *STy = dyn_cast<StructType>(Ty)) { | 
 | 681 |       const StructLayout *SLO = TD.getStructLayout(STy); | 
 | 682 |        | 
 | 683 |       // Indicies must be ubyte constants... | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 684 |       const ConstantUInt *CPU = cast<ConstantUInt>(*I); | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 685 |       assert(CPU->getType() == Type::UByteTy); | 
 | 686 |       unsigned Index = CPU->getValue(); | 
 | 687 |        | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 688 | #ifdef PROFILE_STRUCTURE_FIELDS | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 689 |       if (ProfileStructureFields) { | 
 | 690 |         // Do accounting for this field... | 
 | 691 |         vector<unsigned> &OfC = FieldAccessCounts[STy]; | 
 | 692 |         if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size()); | 
 | 693 |         OfC[Index]++; | 
 | 694 |       } | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 695 | #endif | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 696 |        | 
 | 697 |       Total += SLO->MemberOffsets[Index]; | 
 | 698 |       Ty = STy->getElementTypes()[Index]; | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 699 |     } else if (const SequentialType *ST = cast<SequentialType>(Ty)) { | 
| Chris Lattner | e240906 | 2001-11-12 16:19:45 +0000 | [diff] [blame] | 700 |  | 
| Chris Lattner | 006a4a5 | 2003-02-25 21:14:59 +0000 | [diff] [blame] | 701 |       // Get the index number for the array... which must be long type... | 
| Chris Lattner | 0374b8d | 2002-09-11 01:21:35 +0000 | [diff] [blame] | 702 |       assert((*I)->getType() == Type::LongTy); | 
| Chris Lattner | e8b3e9b | 2002-09-13 23:30:42 +0000 | [diff] [blame] | 703 |       unsigned Idx = getOperandValue(*I, SF).LongVal; | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 704 |       if (const ArrayType *AT = dyn_cast<ArrayType>(ST)) | 
| Chris Lattner | c0fbd57 | 2002-02-11 20:19:16 +0000 | [diff] [blame] | 705 |         if (Idx >= AT->getNumElements() && ArrayChecksEnabled) { | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 706 |           cerr << "Out of range memory access to element #" << Idx | 
 | 707 |                << " of a " << AT->getNumElements() << " element array." | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 708 |                << " Subscript #" << *I << "\n"; | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 709 |           // Get outta here!!! | 
| Chris Lattner | 7403025 | 2002-02-12 15:47:23 +0000 | [diff] [blame] | 710 |           siglongjmp(SignalRecoverBuffer, SIGTRAP); | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 711 |         } | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 712 |  | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 713 |       Ty = ST->getElementType(); | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 714 |       unsigned Size = TD.getTypeSize(Ty); | 
 | 715 |       Total += Size*Idx; | 
 | 716 |     }   | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 717 |   } | 
 | 718 |  | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 719 |   GenericValue Result; | 
 | 720 |   Result.PointerVal = getOperandValue(Ptr, SF).PointerVal + Total; | 
 | 721 |   return Result; | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 722 | } | 
 | 723 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 724 | static void executeGEPInst(GetElementPtrInst &I, ExecutionContext &SF) { | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 725 |   SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(), | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 726 |                                    I.idx_begin(), I.idx_end(), SF), SF); | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 727 | } | 
 | 728 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 729 | void Interpreter::executeLoadInst(LoadInst &I, ExecutionContext &SF) { | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 730 |   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF); | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 731 |   GenericValue *Ptr = (GenericValue*)GVTOP(SRC); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 732 |   GenericValue Result; | 
 | 733 |  | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 734 |   if (TD.isLittleEndian()) { | 
 | 735 |     switch (I.getType()->getPrimitiveID()) { | 
 | 736 |     case Type::BoolTyID: | 
 | 737 |     case Type::UByteTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 738 |     case Type::SByteTyID:   Result.UByteVal = Ptr->Untyped[0]; break; | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 739 |     case Type::UShortTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 740 |     case Type::ShortTyID:   Result.UShortVal = (unsigned)Ptr->Untyped[0] | | 
 | 741 |                                               ((unsigned)Ptr->Untyped[1] << 8); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 742 |                             break; | 
 | 743 |     case Type::FloatTyID: | 
 | 744 |     case Type::UIntTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 745 |     case Type::IntTyID:     Result.UIntVal = (unsigned)Ptr->Untyped[0] | | 
 | 746 |                                             ((unsigned)Ptr->Untyped[1] <<  8) | | 
 | 747 |                                             ((unsigned)Ptr->Untyped[2] << 16) | | 
 | 748 |                                             ((unsigned)Ptr->Untyped[3] << 24); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 749 |                             break; | 
 | 750 |     case Type::DoubleTyID: | 
 | 751 |     case Type::ULongTyID: | 
 | 752 |     case Type::LongTyID:     | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 753 |     case Type::PointerTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] | | 
 | 754 |                                              ((uint64_t)Ptr->Untyped[1] <<  8) | | 
 | 755 |                                              ((uint64_t)Ptr->Untyped[2] << 16) | | 
 | 756 |                                              ((uint64_t)Ptr->Untyped[3] << 24) | | 
 | 757 |                                              ((uint64_t)Ptr->Untyped[4] << 32) | | 
 | 758 |                                              ((uint64_t)Ptr->Untyped[5] << 40) | | 
 | 759 |                                              ((uint64_t)Ptr->Untyped[6] << 48) | | 
 | 760 |                                              ((uint64_t)Ptr->Untyped[7] << 56); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 761 |                             break; | 
 | 762 |     default: | 
 | 763 |       cout << "Cannot load value of type " << I.getType() << "!\n"; | 
 | 764 |     } | 
 | 765 |   } else { | 
 | 766 |     switch (I.getType()->getPrimitiveID()) { | 
 | 767 |     case Type::BoolTyID: | 
 | 768 |     case Type::UByteTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 769 |     case Type::SByteTyID:   Result.UByteVal = Ptr->Untyped[0]; break; | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 770 |     case Type::UShortTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 771 |     case Type::ShortTyID:   Result.UShortVal = (unsigned)Ptr->Untyped[1] | | 
 | 772 |                                               ((unsigned)Ptr->Untyped[0] << 8); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 773 |                             break; | 
 | 774 |     case Type::FloatTyID: | 
 | 775 |     case Type::UIntTyID: | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 776 |     case Type::IntTyID:     Result.UIntVal = (unsigned)Ptr->Untyped[3] | | 
 | 777 |                                             ((unsigned)Ptr->Untyped[2] <<  8) | | 
 | 778 |                                             ((unsigned)Ptr->Untyped[1] << 16) | | 
 | 779 |                                             ((unsigned)Ptr->Untyped[0] << 24); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 780 |                             break; | 
 | 781 |     case Type::DoubleTyID: | 
 | 782 |     case Type::ULongTyID: | 
 | 783 |     case Type::LongTyID:     | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 784 |     case Type::PointerTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] | | 
 | 785 |                                              ((uint64_t)Ptr->Untyped[6] <<  8) | | 
 | 786 |                                              ((uint64_t)Ptr->Untyped[5] << 16) | | 
 | 787 |                                              ((uint64_t)Ptr->Untyped[4] << 24) | | 
 | 788 |                                              ((uint64_t)Ptr->Untyped[3] << 32) | | 
 | 789 |                                              ((uint64_t)Ptr->Untyped[2] << 40) | | 
 | 790 |                                              ((uint64_t)Ptr->Untyped[1] << 48) | | 
 | 791 |                                              ((uint64_t)Ptr->Untyped[0] << 56); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 792 |                             break; | 
 | 793 |     default: | 
 | 794 |       cout << "Cannot load value of type " << I.getType() << "!\n"; | 
 | 795 |     } | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 796 |   } | 
 | 797 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 798 |   SetValue(&I, Result, SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 799 | } | 
 | 800 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 801 | void Interpreter::executeStoreInst(StoreInst &I, ExecutionContext &SF) { | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 802 |   GenericValue Val = getOperandValue(I.getOperand(0), SF); | 
 | 803 |   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF); | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 804 |   StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC), | 
| Chris Lattner | 683d5da9 | 2002-10-26 01:57:15 +0000 | [diff] [blame] | 805 |                      I.getOperand(0)->getType()); | 
| Chris Lattner | fddc755 | 2002-10-15 20:34:05 +0000 | [diff] [blame] | 806 | } | 
 | 807 |  | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 808 |  | 
| Chris Lattner | ab2dea5 | 2002-11-07 19:29:31 +0000 | [diff] [blame] | 809 |  | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 810 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 811 | //                 Miscellaneous Instruction Implementations | 
 | 812 | //===----------------------------------------------------------------------===// | 
 | 813 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 814 | void Interpreter::executeCallInst(CallInst &I, ExecutionContext &SF) { | 
 | 815 |   ECStack.back().Caller = &I; | 
| Chris Lattner | 365a76e | 2001-09-10 04:49:44 +0000 | [diff] [blame] | 816 |   vector<GenericValue> ArgVals; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 817 |   ArgVals.reserve(I.getNumOperands()-1); | 
| Chris Lattner | 9378013 | 2003-01-13 00:58:52 +0000 | [diff] [blame] | 818 |   for (unsigned i = 1; i < I.getNumOperands(); ++i) { | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 819 |     ArgVals.push_back(getOperandValue(I.getOperand(i), SF)); | 
| Chris Lattner | 9378013 | 2003-01-13 00:58:52 +0000 | [diff] [blame] | 820 |     // Promote all integral types whose size is < sizeof(int) into ints.  We do | 
 | 821 |     // this by zero or sign extending the value as appropriate according to the | 
 | 822 |     // source type. | 
 | 823 |     if (I.getOperand(i)->getType()->isIntegral() && | 
 | 824 | 	I.getOperand(i)->getType()->getPrimitiveSize() < 4) { | 
 | 825 |       const Type *Ty = I.getOperand(i)->getType(); | 
 | 826 |       if (Ty == Type::ShortTy) | 
 | 827 | 	ArgVals.back().IntVal = ArgVals.back().ShortVal; | 
 | 828 |       else if (Ty == Type::UShortTy) | 
 | 829 | 	ArgVals.back().UIntVal = ArgVals.back().UShortVal; | 
 | 830 |       else if (Ty == Type::SByteTy) | 
 | 831 | 	ArgVals.back().IntVal = ArgVals.back().SByteVal; | 
 | 832 |       else if (Ty == Type::UByteTy) | 
 | 833 | 	ArgVals.back().UIntVal = ArgVals.back().UByteVal; | 
 | 834 |       else if (Ty == Type::BoolTy) | 
 | 835 | 	ArgVals.back().UIntVal = ArgVals.back().BoolVal; | 
 | 836 |       else | 
 | 837 | 	assert(0 && "Unknown type!"); | 
 | 838 |     } | 
 | 839 |   } | 
| Chris Lattner | 365a76e | 2001-09-10 04:49:44 +0000 | [diff] [blame] | 840 |  | 
| Chris Lattner | 070cf5e | 2001-11-07 20:12:30 +0000 | [diff] [blame] | 841 |   // To handle indirect calls, we must get the pointer value from the argument  | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 842 |   // and treat it as a function pointer. | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 843 |   GenericValue SRC = getOperandValue(I.getCalledValue(), SF); | 
| Chris Lattner | 070cf5e | 2001-11-07 20:12:30 +0000 | [diff] [blame] | 844 |    | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 845 |   callMethod((Function*)GVTOP(SRC), ArgVals); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 846 | } | 
 | 847 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 848 | static void executePHINode(PHINode &I, ExecutionContext &SF) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 849 |   BasicBlock *PrevBB = SF.PrevBB; | 
 | 850 |   Value *IncomingValue = 0; | 
 | 851 |  | 
 | 852 |   // Search for the value corresponding to this previous bb... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 853 |   for (unsigned i = I.getNumIncomingValues(); i > 0;) { | 
 | 854 |     if (I.getIncomingBlock(--i) == PrevBB) { | 
 | 855 |       IncomingValue = I.getIncomingValue(i); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 856 |       break; | 
 | 857 |     } | 
 | 858 |   } | 
 | 859 |   assert(IncomingValue && "No PHI node predecessor for current PrevBB!"); | 
 | 860 |  | 
 | 861 |   // Found the value, set as the result... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 862 |   SetValue(&I, getOperandValue(IncomingValue, SF), SF); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 863 | } | 
 | 864 |  | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 865 | #define IMPLEMENT_SHIFT(OP, TY) \ | 
 | 866 |    case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.UByteVal; break | 
 | 867 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 868 | static void executeShlInst(ShiftInst &I, ExecutionContext &SF) { | 
 | 869 |   const Type *Ty    = I.getOperand(0)->getType(); | 
 | 870 |   GenericValue Src1 = getOperandValue(I.getOperand(0), SF); | 
 | 871 |   GenericValue Src2 = getOperandValue(I.getOperand(1), SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 872 |   GenericValue Dest; | 
 | 873 |  | 
 | 874 |   switch (Ty->getPrimitiveID()) { | 
 | 875 |     IMPLEMENT_SHIFT(<<, UByte); | 
 | 876 |     IMPLEMENT_SHIFT(<<, SByte); | 
 | 877 |     IMPLEMENT_SHIFT(<<, UShort); | 
 | 878 |     IMPLEMENT_SHIFT(<<, Short); | 
 | 879 |     IMPLEMENT_SHIFT(<<, UInt); | 
 | 880 |     IMPLEMENT_SHIFT(<<, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 881 |     IMPLEMENT_SHIFT(<<, ULong); | 
 | 882 |     IMPLEMENT_SHIFT(<<, Long); | 
| Chris Lattner | 743cd3e | 2002-07-09 18:42:36 +0000 | [diff] [blame] | 883 |     IMPLEMENT_SHIFT(<<, Pointer); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 884 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 885 |     cout << "Unhandled type for Shl instruction: " << Ty << "\n"; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 886 |   } | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 887 |   SetValue(&I, Dest, SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 888 | } | 
 | 889 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 890 | static void executeShrInst(ShiftInst &I, ExecutionContext &SF) { | 
 | 891 |   const Type *Ty    = I.getOperand(0)->getType(); | 
 | 892 |   GenericValue Src1 = getOperandValue(I.getOperand(0), SF); | 
 | 893 |   GenericValue Src2 = getOperandValue(I.getOperand(1), SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 894 |   GenericValue Dest; | 
 | 895 |  | 
 | 896 |   switch (Ty->getPrimitiveID()) { | 
 | 897 |     IMPLEMENT_SHIFT(>>, UByte); | 
 | 898 |     IMPLEMENT_SHIFT(>>, SByte); | 
 | 899 |     IMPLEMENT_SHIFT(>>, UShort); | 
 | 900 |     IMPLEMENT_SHIFT(>>, Short); | 
 | 901 |     IMPLEMENT_SHIFT(>>, UInt); | 
 | 902 |     IMPLEMENT_SHIFT(>>, Int); | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 903 |     IMPLEMENT_SHIFT(>>, ULong); | 
 | 904 |     IMPLEMENT_SHIFT(>>, Long); | 
| Chris Lattner | 743cd3e | 2002-07-09 18:42:36 +0000 | [diff] [blame] | 905 |     IMPLEMENT_SHIFT(>>, Pointer); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 906 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 907 |     cout << "Unhandled type for Shr instruction: " << Ty << "\n"; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 908 |   } | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 909 |   SetValue(&I, Dest, SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 910 | } | 
 | 911 |  | 
 | 912 | #define IMPLEMENT_CAST(DTY, DCTY, STY) \ | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 913 |    case Type::STY##TyID: Dest.DTY##Val = DCTY Src.STY##Val; break; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 914 |  | 
 | 915 | #define IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY)    \ | 
 | 916 |   case Type::DESTTY##TyID:                      \ | 
 | 917 |     switch (SrcTy->getPrimitiveID()) {          \ | 
| Chris Lattner | f4dca80 | 2002-05-02 19:28:45 +0000 | [diff] [blame] | 918 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Bool);    \ | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 919 |       IMPLEMENT_CAST(DESTTY, DESTCTY, UByte);   \ | 
 | 920 |       IMPLEMENT_CAST(DESTTY, DESTCTY, SByte);   \ | 
 | 921 |       IMPLEMENT_CAST(DESTTY, DESTCTY, UShort);  \ | 
 | 922 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Short);   \ | 
 | 923 |       IMPLEMENT_CAST(DESTTY, DESTCTY, UInt);    \ | 
| Chris Lattner | 7b851ab | 2001-10-15 19:18:26 +0000 | [diff] [blame] | 924 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Int);     \ | 
 | 925 |       IMPLEMENT_CAST(DESTTY, DESTCTY, ULong);   \ | 
| Chris Lattner | c259316 | 2001-10-27 08:28:11 +0000 | [diff] [blame] | 926 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Long);    \ | 
 | 927 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 928 |  | 
 | 929 | #define IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY) \ | 
 | 930 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Float);   \ | 
 | 931 |       IMPLEMENT_CAST(DESTTY, DESTCTY, Double) | 
 | 932 |  | 
 | 933 | #define IMPLEMENT_CAST_CASE_END()    \ | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 934 |     default: cout << "Unhandled cast: " << SrcTy << " to " << Ty << "\n";  \ | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 935 |       break;                                    \ | 
 | 936 |     }                                           \ | 
 | 937 |     break | 
 | 938 |  | 
 | 939 | #define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \ | 
 | 940 |    IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY);   \ | 
 | 941 |    IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY); \ | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 942 |    IMPLEMENT_CAST_CASE_END() | 
 | 943 |  | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 944 | static GenericValue executeCastOperation(Value *SrcVal, const Type *Ty, | 
 | 945 |                                          ExecutionContext &SF) { | 
 | 946 |   const Type *SrcTy = SrcVal->getType(); | 
 | 947 |   GenericValue Dest, Src = getOperandValue(SrcVal, SF); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 948 |  | 
 | 949 |   switch (Ty->getPrimitiveID()) { | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 950 |     IMPLEMENT_CAST_CASE(UByte  , (unsigned char)); | 
 | 951 |     IMPLEMENT_CAST_CASE(SByte  , (  signed char)); | 
 | 952 |     IMPLEMENT_CAST_CASE(UShort , (unsigned short)); | 
| Chris Lattner | 1bbd361 | 2002-08-02 22:06:04 +0000 | [diff] [blame] | 953 |     IMPLEMENT_CAST_CASE(Short  , (  signed short)); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 954 |     IMPLEMENT_CAST_CASE(UInt   , (unsigned int )); | 
 | 955 |     IMPLEMENT_CAST_CASE(Int    , (  signed int )); | 
 | 956 |     IMPLEMENT_CAST_CASE(ULong  , (uint64_t)); | 
 | 957 |     IMPLEMENT_CAST_CASE(Long   , ( int64_t)); | 
| Chris Lattner | 2fdaddf | 2002-10-30 21:47:57 +0000 | [diff] [blame] | 958 |     IMPLEMENT_CAST_CASE(Pointer, (PointerTy)); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 959 |     IMPLEMENT_CAST_CASE(Float  , (float)); | 
 | 960 |     IMPLEMENT_CAST_CASE(Double , (double)); | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 961 |   default: | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 962 |     cout << "Unhandled dest type for cast instruction: " << Ty << "\n"; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 963 |   } | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 964 |  | 
 | 965 |   return Dest; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 966 | } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 967 |  | 
 | 968 |  | 
| Chris Lattner | a34c568 | 2002-08-27 22:33:45 +0000 | [diff] [blame] | 969 | static void executeCastInst(CastInst &I, ExecutionContext &SF) { | 
 | 970 |   SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); | 
 | 971 | } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 972 |  | 
 | 973 |  | 
 | 974 | //===----------------------------------------------------------------------===// | 
 | 975 | //                        Dispatch and Execution Code | 
 | 976 | //===----------------------------------------------------------------------===// | 
 | 977 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 978 | MethodInfo::MethodInfo(Function *F) : Annotation(MethodInfoAID) { | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 979 |   // Assign slot numbers to the function arguments... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 980 |   for (Function::const_aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI) | 
 | 981 |     AI->addAnnotation(new SlotNumber(getValueSlot(AI))); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 982 |  | 
 | 983 |   // Iterate over all of the instructions... | 
 | 984 |   unsigned InstNum = 0; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 985 |   for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB) | 
 | 986 |     for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) | 
 | 987 |       // For each instruction... Add Annote | 
 | 988 |       II->addAnnotation(new InstNumber(++InstNum, getValueSlot(II))); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 989 | } | 
 | 990 |  | 
 | 991 | unsigned MethodInfo::getValueSlot(const Value *V) { | 
 | 992 |   unsigned Plane = V->getType()->getUniqueID(); | 
 | 993 |   if (Plane >= NumPlaneElements.size()) | 
 | 994 |     NumPlaneElements.resize(Plane+1, 0); | 
 | 995 |   return NumPlaneElements[Plane]++; | 
 | 996 | } | 
 | 997 |  | 
 | 998 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 999 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1000 | // callMethod - Execute the specified function... | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1001 | // | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1002 | void Interpreter::callMethod(Function *M, const vector<GenericValue> &ArgVals) { | 
| Chris Lattner | 365a76e | 2001-09-10 04:49:44 +0000 | [diff] [blame] | 1003 |   assert((ECStack.empty() || ECStack.back().Caller == 0 ||  | 
 | 1004 | 	  ECStack.back().Caller->getNumOperands()-1 == ArgVals.size()) && | 
 | 1005 | 	 "Incorrect number of arguments passed into function call!"); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1006 |   if (M->isExternal()) { | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1007 |     GenericValue Result = callExternalMethod(M, ArgVals); | 
 | 1008 |     const Type *RetTy = M->getReturnType(); | 
 | 1009 |  | 
 | 1010 |     // Copy the result back into the result variable if we are not returning | 
 | 1011 |     // void. | 
 | 1012 |     if (RetTy != Type::VoidTy) { | 
 | 1013 |       if (!ECStack.empty() && ECStack.back().Caller) { | 
 | 1014 |         ExecutionContext &SF = ECStack.back(); | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1015 |         SetValue(SF.Caller, Result, SF); | 
 | 1016 |        | 
 | 1017 |         SF.Caller = 0;          // We returned from the call... | 
| Chris Lattner | f23eb85 | 2001-12-14 16:49:29 +0000 | [diff] [blame] | 1018 |       } else if (!QuietMode) { | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1019 |         // print it. | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1020 |         CW << "Function " << M->getType() << " \"" << M->getName() | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 1021 |            << "\" returned "; | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1022 |         print(RetTy, Result);  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1023 |         cout << "\n"; | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1024 |          | 
 | 1025 |         if (RetTy->isIntegral()) | 
| Chris Lattner | 0c4e886 | 2002-09-03 01:08:28 +0000 | [diff] [blame] | 1026 |           ExitCode = Result.IntVal;   // Capture the exit code of the program | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1027 |       } | 
 | 1028 |     } | 
 | 1029 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1030 |     return; | 
 | 1031 |   } | 
 | 1032 |  | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1033 |   // Process the function, assigning instruction numbers to the instructions in | 
 | 1034 |   // the function.  Also calculate the number of values for each type slot | 
 | 1035 |   // active. | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1036 |   // | 
 | 1037 |   MethodInfo *MethInfo = (MethodInfo*)M->getOrCreateAnnotation(MethodInfoAID); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1038 |   ECStack.push_back(ExecutionContext());         // Make a new stack frame... | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1039 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1040 |   ExecutionContext &StackFrame = ECStack.back(); // Fill it in... | 
 | 1041 |   StackFrame.CurMethod = M; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1042 |   StackFrame.CurBB     = M->begin(); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1043 |   StackFrame.CurInst   = StackFrame.CurBB->begin(); | 
 | 1044 |   StackFrame.MethInfo  = MethInfo; | 
 | 1045 |  | 
 | 1046 |   // Initialize the values to nothing... | 
 | 1047 |   StackFrame.Values.resize(MethInfo->NumPlaneElements.size()); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 1048 |   for (unsigned i = 0; i < MethInfo->NumPlaneElements.size(); ++i) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1049 |     StackFrame.Values[i].resize(MethInfo->NumPlaneElements[i]); | 
 | 1050 |  | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 1051 |     // Taint the initial values of stuff | 
 | 1052 |     memset(&StackFrame.Values[i][0], 42, | 
 | 1053 |            MethInfo->NumPlaneElements[i]*sizeof(GenericValue)); | 
 | 1054 |   } | 
 | 1055 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1056 |   StackFrame.PrevBB = 0;  // No previous BB for PHI nodes... | 
 | 1057 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1058 |  | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1059 |   // Run through the function arguments and initialize their values... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1060 |   assert(ArgVals.size() == M->asize() && | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1061 |          "Invalid number of values passed to function invocation!"); | 
| Chris Lattner | 365a76e | 2001-09-10 04:49:44 +0000 | [diff] [blame] | 1062 |   unsigned i = 0; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1063 |   for (Function::aiterator AI = M->abegin(), E = M->aend(); AI != E; ++AI, ++i) | 
 | 1064 |     SetValue(AI, ArgVals[i], StackFrame); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1065 | } | 
 | 1066 |  | 
 | 1067 | // executeInstruction - Interpret a single instruction, increment the "PC", and | 
 | 1068 | // return true if the next instruction is a breakpoint... | 
 | 1069 | // | 
 | 1070 | bool Interpreter::executeInstruction() { | 
 | 1071 |   assert(!ECStack.empty() && "No program running, cannot execute inst!"); | 
 | 1072 |  | 
 | 1073 |   ExecutionContext &SF = ECStack.back();  // Current stack frame | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1074 |   Instruction &I = *SF.CurInst++;         // Increment before execute | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1075 |  | 
| Chris Lattner | 43e3f7c | 2001-10-27 08:43:52 +0000 | [diff] [blame] | 1076 |   if (Trace) | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 1077 |     CW << "Run:" << I; | 
 | 1078 |  | 
| Chris Lattner | bbdabce | 2002-12-08 05:51:08 +0000 | [diff] [blame] | 1079 |   // Track the number of dynamic instructions executed. | 
 | 1080 |   ++NumDynamicInsts; | 
 | 1081 |  | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 1082 |   // Set a sigsetjmp buffer so that we can recover if an error happens during | 
 | 1083 |   // instruction execution... | 
 | 1084 |   // | 
 | 1085 |   if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) { | 
 | 1086 |     --SF.CurInst;   // Back up to erroring instruction | 
| Chris Lattner | 7403025 | 2002-02-12 15:47:23 +0000 | [diff] [blame] | 1087 |     if (SigNo != SIGINT) { | 
| Chris Lattner | 8b77be2 | 2002-09-13 14:41:38 +0000 | [diff] [blame] | 1088 |       cout << "EXCEPTION OCCURRED [" << strsignal(SigNo) << "]:\n"; | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1089 |       printStackTrace(); | 
| Chris Lattner | 7403025 | 2002-02-12 15:47:23 +0000 | [diff] [blame] | 1090 |       // If -abort-on-exception was specified, terminate LLI instead of trying | 
 | 1091 |       // to debug it. | 
 | 1092 |       // | 
 | 1093 |       if (AbortOnExceptions) exit(1); | 
| Chris Lattner | 782b939 | 2001-11-26 18:18:18 +0000 | [diff] [blame] | 1094 |     } else if (SigNo == SIGINT) { | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1095 |       cout << "CTRL-C Detected, execution halted.\n"; | 
 | 1096 |     } | 
 | 1097 |     InInstruction = false; | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 1098 |     return true; | 
 | 1099 |   } | 
| Chris Lattner | 43e3f7c | 2001-10-27 08:43:52 +0000 | [diff] [blame] | 1100 |  | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1101 |   InInstruction = true; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1102 |   if (I.isBinaryOp()) { | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1103 |     executeBinaryInst(cast<BinaryOperator>(I), SF); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1104 |   } else { | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1105 |     switch (I.getOpcode()) { | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1106 |       // Terminators | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1107 |     case Instruction::Ret:     executeRetInst  (cast<ReturnInst>(I), SF); break; | 
 | 1108 |     case Instruction::Br:      executeBrInst   (cast<BranchInst>(I), SF); break; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1109 |       // Memory Instructions | 
 | 1110 |     case Instruction::Alloca: | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1111 |     case Instruction::Malloc:  executeAllocInst((AllocationInst&)I, SF); break; | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1112 |     case Instruction::Free:    executeFreeInst (cast<FreeInst> (I), SF); break; | 
 | 1113 |     case Instruction::Load:    executeLoadInst (cast<LoadInst> (I), SF); break; | 
 | 1114 |     case Instruction::Store:   executeStoreInst(cast<StoreInst>(I), SF); break; | 
| Chris Lattner | 95c3af5 | 2001-10-29 19:32:19 +0000 | [diff] [blame] | 1115 |     case Instruction::GetElementPtr: | 
 | 1116 |                           executeGEPInst(cast<GetElementPtrInst>(I), SF); break; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1117 |  | 
 | 1118 |       // Miscellaneous Instructions | 
| Chris Lattner | bb76f02 | 2001-10-30 20:27:31 +0000 | [diff] [blame] | 1119 |     case Instruction::Call:    executeCallInst (cast<CallInst> (I), SF); break; | 
 | 1120 |     case Instruction::PHINode: executePHINode  (cast<PHINode>  (I), SF); break; | 
 | 1121 |     case Instruction::Shl:     executeShlInst  (cast<ShiftInst>(I), SF); break; | 
 | 1122 |     case Instruction::Shr:     executeShrInst  (cast<ShiftInst>(I), SF); break; | 
 | 1123 |     case Instruction::Cast:    executeCastInst (cast<CastInst> (I), SF); break; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1124 |     default: | 
 | 1125 |       cout << "Don't know how to execute this instruction!\n-->" << I; | 
 | 1126 |     } | 
 | 1127 |   } | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1128 |   InInstruction = false; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1129 |    | 
 | 1130 |   // Reset the current frame location to the top of stack | 
 | 1131 |   CurFrame = ECStack.size()-1; | 
 | 1132 |  | 
 | 1133 |   if (CurFrame == -1) return false;  // No breakpoint if no code | 
 | 1134 |  | 
 | 1135 |   // Return true if there is a breakpoint annotation on the instruction... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1136 |   return ECStack[CurFrame].CurInst->getAnnotation(BreakpointAID) != 0; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1137 | } | 
 | 1138 |  | 
 | 1139 | void Interpreter::stepInstruction() {  // Do the 'step' command | 
 | 1140 |   if (ECStack.empty()) { | 
 | 1141 |     cout << "Error: no program running, cannot step!\n"; | 
 | 1142 |     return; | 
 | 1143 |   } | 
 | 1144 |  | 
 | 1145 |   // Run an instruction... | 
 | 1146 |   executeInstruction(); | 
 | 1147 |  | 
 | 1148 |   // Print the next instruction to execute... | 
 | 1149 |   printCurrentInstruction(); | 
 | 1150 | } | 
 | 1151 |  | 
 | 1152 | // --- UI Stuff... | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1153 | void Interpreter::nextInstruction() {  // Do the 'next' command | 
 | 1154 |   if (ECStack.empty()) { | 
 | 1155 |     cout << "Error: no program running, cannot 'next'!\n"; | 
 | 1156 |     return; | 
 | 1157 |   } | 
 | 1158 |  | 
 | 1159 |   // If this is a call instruction, step over the call instruction... | 
 | 1160 |   // TODO: ICALL, CALL WITH, ... | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1161 |   if (ECStack.back().CurInst->getOpcode() == Instruction::Call) { | 
| Chris Lattner | a74a6b5 | 2001-10-29 14:08:33 +0000 | [diff] [blame] | 1162 |     unsigned StackSize = ECStack.size(); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1163 |     // Step into the function... | 
 | 1164 |     if (executeInstruction()) { | 
 | 1165 |       // Hit a breakpoint, print current instruction, then return to user... | 
 | 1166 |       cout << "Breakpoint hit!\n"; | 
 | 1167 |       printCurrentInstruction(); | 
 | 1168 |       return; | 
 | 1169 |     } | 
 | 1170 |  | 
| Chris Lattner | a74a6b5 | 2001-10-29 14:08:33 +0000 | [diff] [blame] | 1171 |     // If we we able to step into the function, finish it now.  We might not be | 
 | 1172 |     // able the step into a function, if it's external for example. | 
 | 1173 |     if (ECStack.size() != StackSize) | 
 | 1174 |       finish(); // Finish executing the function... | 
| Chris Lattner | 069aa25 | 2001-10-29 16:05:19 +0000 | [diff] [blame] | 1175 |     else | 
 | 1176 |       printCurrentInstruction(); | 
| Chris Lattner | a74a6b5 | 2001-10-29 14:08:33 +0000 | [diff] [blame] | 1177 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1178 |   } else { | 
 | 1179 |     // Normal instruction, just step... | 
 | 1180 |     stepInstruction(); | 
 | 1181 |   } | 
 | 1182 | } | 
 | 1183 |  | 
 | 1184 | void Interpreter::run() { | 
 | 1185 |   if (ECStack.empty()) { | 
 | 1186 |     cout << "Error: no program running, cannot run!\n"; | 
 | 1187 |     return; | 
 | 1188 |   } | 
 | 1189 |  | 
 | 1190 |   bool HitBreakpoint = false; | 
 | 1191 |   while (!ECStack.empty() && !HitBreakpoint) { | 
 | 1192 |     // Run an instruction... | 
 | 1193 |     HitBreakpoint = executeInstruction(); | 
 | 1194 |   } | 
 | 1195 |  | 
 | 1196 |   if (HitBreakpoint) { | 
 | 1197 |     cout << "Breakpoint hit!\n"; | 
 | 1198 |   } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1199 |   // Print the next instruction to execute... | 
 | 1200 |   printCurrentInstruction(); | 
 | 1201 | } | 
 | 1202 |  | 
 | 1203 | void Interpreter::finish() { | 
 | 1204 |   if (ECStack.empty()) { | 
 | 1205 |     cout << "Error: no program running, cannot run!\n"; | 
 | 1206 |     return; | 
 | 1207 |   } | 
 | 1208 |  | 
 | 1209 |   unsigned StackSize = ECStack.size(); | 
 | 1210 |   bool HitBreakpoint = false; | 
 | 1211 |   while (ECStack.size() >= StackSize && !HitBreakpoint) { | 
 | 1212 |     // Run an instruction... | 
 | 1213 |     HitBreakpoint = executeInstruction(); | 
 | 1214 |   } | 
 | 1215 |  | 
 | 1216 |   if (HitBreakpoint) { | 
 | 1217 |     cout << "Breakpoint hit!\n"; | 
 | 1218 |   } | 
 | 1219 |  | 
 | 1220 |   // Print the next instruction to execute... | 
 | 1221 |   printCurrentInstruction(); | 
 | 1222 | } | 
 | 1223 |  | 
 | 1224 |  | 
 | 1225 |  | 
 | 1226 | // printCurrentInstruction - Print out the instruction that the virtual PC is | 
 | 1227 | // at, or fail silently if no program is running. | 
 | 1228 | // | 
 | 1229 | void Interpreter::printCurrentInstruction() { | 
 | 1230 |   if (!ECStack.empty()) { | 
| Chris Lattner | f5b2ec1 | 2001-10-29 20:44:34 +0000 | [diff] [blame] | 1231 |     if (ECStack.back().CurBB->begin() == ECStack.back().CurInst)  // print label | 
 | 1232 |       WriteAsOperand(cout, ECStack.back().CurBB) << ":\n"; | 
 | 1233 |  | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1234 |     Instruction &I = *ECStack.back().CurInst; | 
 | 1235 |     InstNumber *IN = (InstNumber*)I.getAnnotation(SlotNumberAID); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1236 |     assert(IN && "Instruction has no numbering annotation!"); | 
 | 1237 |     cout << "#" << IN->InstNum << I; | 
 | 1238 |   } | 
 | 1239 | } | 
 | 1240 |  | 
 | 1241 | void Interpreter::printValue(const Type *Ty, GenericValue V) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1242 |   switch (Ty->getPrimitiveID()) { | 
 | 1243 |   case Type::BoolTyID:   cout << (V.BoolVal?"true":"false"); break; | 
| Chris Lattner | 65629d5 | 2002-08-13 20:45:11 +0000 | [diff] [blame] | 1244 |   case Type::SByteTyID: | 
 | 1245 |     cout << (int)V.SByteVal << " '" << V.SByteVal << "'";  break; | 
 | 1246 |   case Type::UByteTyID: | 
 | 1247 |     cout << (unsigned)V.UByteVal << " '" << V.UByteVal << "'";  break; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1248 |   case Type::ShortTyID:  cout << V.ShortVal;  break; | 
 | 1249 |   case Type::UShortTyID: cout << V.UShortVal; break; | 
 | 1250 |   case Type::IntTyID:    cout << V.IntVal;    break; | 
 | 1251 |   case Type::UIntTyID:   cout << V.UIntVal;   break; | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1252 |   case Type::LongTyID:   cout << (long)V.LongVal;   break; | 
 | 1253 |   case Type::ULongTyID:  cout << (unsigned long)V.ULongVal;  break; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1254 |   case Type::FloatTyID:  cout << V.FloatVal;  break; | 
 | 1255 |   case Type::DoubleTyID: cout << V.DoubleVal; break; | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 1256 |   case Type::PointerTyID:cout << (void*)GVTOP(V); break; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1257 |   default: | 
 | 1258 |     cout << "- Don't know how to print value of this type!"; | 
 | 1259 |     break; | 
 | 1260 |   } | 
 | 1261 | } | 
 | 1262 |  | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 1263 | void Interpreter::print(const Type *Ty, GenericValue V) { | 
| Chris Lattner | 5af0c48 | 2001-11-07 04:23:00 +0000 | [diff] [blame] | 1264 |   CW << Ty << " "; | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 1265 |   printValue(Ty, V); | 
 | 1266 | } | 
 | 1267 |  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1268 | void Interpreter::print(const std::string &Name) { | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1269 |   Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name)); | 
 | 1270 |   if (!PickedVal) return; | 
 | 1271 |  | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1272 |   if (const Function *F = dyn_cast<const Function>(PickedVal)) { | 
 | 1273 |     CW << F;  // Print the function | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 1274 |   } else if (const Type *Ty = dyn_cast<const Type>(PickedVal)) { | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1275 |     CW << "type %" << Name << " = " << Ty->getDescription() << "\n"; | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 1276 |   } else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(PickedVal)) { | 
 | 1277 |     CW << BB;   // Print the basic block | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1278 |   } else {      // Otherwise there should be an annotation for the slot# | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 1279 |     print(PickedVal->getType(),  | 
 | 1280 |           getOperandValue(PickedVal, ECStack[CurFrame])); | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1281 |     cout << "\n"; | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1282 |   } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1283 | } | 
 | 1284 |  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1285 | void Interpreter::infoValue(const std::string &Name) { | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1286 |   Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name)); | 
 | 1287 |   if (!PickedVal) return; | 
 | 1288 |  | 
 | 1289 |   cout << "Value: "; | 
| Chris Lattner | 2e42d3a | 2001-10-15 05:51:48 +0000 | [diff] [blame] | 1290 |   print(PickedVal->getType(),  | 
 | 1291 |         getOperandValue(PickedVal, ECStack[CurFrame])); | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1292 |   cout << "\n"; | 
| Chris Lattner | 8666098 | 2001-08-27 05:16:50 +0000 | [diff] [blame] | 1293 |   printOperandInfo(PickedVal, ECStack[CurFrame]); | 
 | 1294 | } | 
 | 1295 |  | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1296 | // printStackFrame - Print information about the specified stack frame, or -1 | 
 | 1297 | // for the default one. | 
 | 1298 | // | 
| Chris Lattner | 601d715 | 2002-07-25 17:37:05 +0000 | [diff] [blame] | 1299 | void Interpreter::printStackFrame(int FrameNo) { | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1300 |   if (FrameNo == -1) FrameNo = CurFrame; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1301 |   Function *F = ECStack[FrameNo].CurMethod; | 
 | 1302 |   const Type *RetTy = F->getReturnType(); | 
| Chris Lattner | ea38c0e | 2001-11-07 19:46:27 +0000 | [diff] [blame] | 1303 |  | 
 | 1304 |   CW << ((FrameNo == CurFrame) ? '>' : '-') << "#" << FrameNo << ". " | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1305 |      << (Value*)RetTy << " \"" << F->getName() << "\"("; | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1306 |    | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1307 |   unsigned i = 0; | 
 | 1308 |   for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I, ++i) { | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1309 |     if (i != 0) cout << ", "; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1310 |     CW << *I << "="; | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1311 |      | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1312 |     printValue(I->getType(), getOperandValue(I, ECStack[FrameNo])); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1313 |   } | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1314 |  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 1315 |   cout << ")\n"; | 
| Chris Lattner | 0b12b5f | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 1316 |  | 
 | 1317 |   if (FrameNo != int(ECStack.size()-1)) { | 
 | 1318 |     BasicBlock::iterator I = ECStack[FrameNo].CurInst; | 
 | 1319 |     CW << --I; | 
 | 1320 |   } else { | 
 | 1321 |     CW << *ECStack[FrameNo].CurInst; | 
 | 1322 |   } | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 1323 | } | 
| Chris Lattner | 461f02f | 2001-11-07 05:31:27 +0000 | [diff] [blame] | 1324 |  |