blob: d8a6af0179c1d7bf60c3376d6b5aaef0bab29fe3 [file] [log] [blame]
Chris Lattner05950c32001-10-13 06:47:01 +00001//===- ReadInst.cpp - Code to read an instruction from bytecode -----------===//
Chris Lattner00950542001-06-06 20:29:01 +00002//
3// This file defines the mechanism to read an instruction from a bytecode
4// stream.
5//
6// Note that this library should be as fast as possible, reentrant, and
7// threadsafe!!
8//
9// TODO: Change from getValue(Raw.Arg1) etc, to getArg(Raw, 1)
10// Make it check type, so that casts are checked.
11//
Chris Lattner05950c32001-10-13 06:47:01 +000012//===----------------------------------------------------------------------===//
Chris Lattner00950542001-06-06 20:29:01 +000013
Chris Lattner7061dc52001-12-03 18:02:31 +000014#include "ReaderInternals.h"
Chris Lattner00950542001-06-06 20:29:01 +000015#include "llvm/iTerminators.h"
16#include "llvm/iMemory.h"
Chris Lattner7061dc52001-12-03 18:02:31 +000017#include "llvm/iPHINode.h"
18#include "llvm/iOther.h"
Chris Lattner00950542001-06-06 20:29:01 +000019
Misha Brukmand554ebf2003-09-23 16:17:50 +000020std::auto_ptr<RawInst>
21BytecodeParser::ParseRawInst(const unsigned char *&Buf,
22 const unsigned char *EndBuf) {
Chris Lattner00950542001-06-06 20:29:01 +000023 unsigned Op, Typ;
Misha Brukmand554ebf2003-09-23 16:17:50 +000024 std::auto_ptr<RawInst> Result = std::auto_ptr<RawInst>(new RawInst());
25 if (read(Buf, EndBuf, Op))
26 throw std::string("Error reading from buffer.");
Chris Lattner00950542001-06-06 20:29:01 +000027
Chris Lattner2b9f6002001-10-23 03:21:10 +000028 // bits Instruction format: Common to all formats
29 // --------------------------
30 // 01-00: Opcode type, fixed to 1.
31 // 07-02: Opcode
Misha Brukmand554ebf2003-09-23 16:17:50 +000032 Result->NumOperands = (Op >> 0) & 03;
33 Result->Opcode = (Op >> 2) & 63;
Chris Lattner00950542001-06-06 20:29:01 +000034
Misha Brukmand554ebf2003-09-23 16:17:50 +000035 switch (Result->NumOperands) {
Chris Lattner00950542001-06-06 20:29:01 +000036 case 1:
Chris Lattner2b9f6002001-10-23 03:21:10 +000037 // bits Instruction format:
38 // --------------------------
39 // 19-08: Resulting type plane
40 // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
41 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000042 Result->Ty = getType((Op >> 8) & 4095);
43 Result->Arg1 = (Op >> 20) & 4095;
44 if (Result->Arg1 == 4095) // Handle special encoding for 0 operands...
45 Result->NumOperands = 0;
Chris Lattner00950542001-06-06 20:29:01 +000046 break;
47 case 2:
Chris Lattner2b9f6002001-10-23 03:21:10 +000048 // bits Instruction format:
49 // --------------------------
50 // 15-08: Resulting type plane
51 // 23-16: Operand #1
52 // 31-24: Operand #2
53 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000054 Result->Ty = getType((Op >> 8) & 255);
55 Result->Arg1 = (Op >> 16) & 255;
56 Result->Arg2 = (Op >> 24) & 255;
Chris Lattner00950542001-06-06 20:29:01 +000057 break;
58 case 3:
Chris Lattner2b9f6002001-10-23 03:21:10 +000059 // bits Instruction format:
60 // --------------------------
61 // 13-08: Resulting type plane
62 // 19-14: Operand #1
63 // 25-20: Operand #2
64 // 31-26: Operand #3
65 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000066 Result->Ty = getType((Op >> 8) & 63);
67 Result->Arg1 = (Op >> 14) & 63;
68 Result->Arg2 = (Op >> 20) & 63;
69 Result->Arg3 = (Op >> 26) & 63;
Chris Lattner00950542001-06-06 20:29:01 +000070 break;
71 case 0:
72 Buf -= 4; // Hrm, try this again...
Misha Brukmand554ebf2003-09-23 16:17:50 +000073 if (read_vbr(Buf, EndBuf, Result->Opcode))
74 throw std::string("Error reading from buffer.");
75 Result->Opcode >>= 2;
76 if (read_vbr(Buf, EndBuf, Typ))
77 throw std::string("Error reading from buffer.");
78 Result->Ty = getType(Typ);
79 if (Result->Ty == 0)
80 throw std::string("Invalid type read in instruction.");
81 if (read_vbr(Buf, EndBuf, Result->NumOperands))
82 throw std::string("Error reading from buffer.");
Chris Lattner00950542001-06-06 20:29:01 +000083
Misha Brukmand554ebf2003-09-23 16:17:50 +000084 switch (Result->NumOperands) {
Chris Lattner00950542001-06-06 20:29:01 +000085 case 0:
Misha Brukmand554ebf2003-09-23 16:17:50 +000086 throw std::string("Zero-argument instruction found; this is invalid.");
Chris Lattner00950542001-06-06 20:29:01 +000087 case 1:
Misha Brukmand554ebf2003-09-23 16:17:50 +000088 if (read_vbr(Buf, EndBuf, Result->Arg1))
89 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +000090 break;
91 case 2:
Misha Brukmand554ebf2003-09-23 16:17:50 +000092 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
93 read_vbr(Buf, EndBuf, Result->Arg2))
94 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +000095 break;
96 case 3:
Misha Brukmand554ebf2003-09-23 16:17:50 +000097 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
98 read_vbr(Buf, EndBuf, Result->Arg2) ||
99 read_vbr(Buf, EndBuf, Result->Arg3))
100 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +0000101 break;
102 default:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000103 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
104 read_vbr(Buf, EndBuf, Result->Arg2))
105 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +0000106
107 // Allocate a vector to hold arguments 3, 4, 5, 6 ...
Misha Brukmand554ebf2003-09-23 16:17:50 +0000108 Result->VarArgs = new std::vector<unsigned>(Result->NumOperands-2);
109 for (unsigned a = 0; a < Result->NumOperands-2; a++)
110 if (read_vbr(Buf, EndBuf, (*Result->VarArgs)[a]))
111 throw std::string("Error reading from buffer");
112
Chris Lattner00950542001-06-06 20:29:01 +0000113 break;
114 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000115 if (align32(Buf, EndBuf))
116 throw std::string("Unaligned bytecode buffer.");
Chris Lattner00950542001-06-06 20:29:01 +0000117 break;
118 }
119
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000120#if 0
Misha Brukmand554ebf2003-09-23 16:17:50 +0000121 std::cerr << "NO: " << Result->NumOperands << " opcode: " << Result->Opcode
122 << " Ty: "<< Result->Ty->getDescription()<< " arg1: "<< Result->Arg1
123 << " arg2: " << Result->Arg2 << " arg3: " << Result->Arg3 << "\n";
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000124#endif
Misha Brukmand554ebf2003-09-23 16:17:50 +0000125 return Result;
Chris Lattner00950542001-06-06 20:29:01 +0000126}
127
128
Chris Lattner12e64652003-05-22 18:08:30 +0000129bool BytecodeParser::ParseInstruction(const unsigned char *&Buf,
130 const unsigned char *EndBuf,
Chris Lattner09bd0252003-09-08 18:04:16 +0000131 Instruction *&Res) {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000132 std::auto_ptr<RawInst> Raw = ParseRawInst(Buf, EndBuf);
Chris Lattner00950542001-06-06 20:29:01 +0000133
Misha Brukmand554ebf2003-09-23 16:17:50 +0000134 if (Raw->Opcode >= Instruction::BinaryOpsBegin &&
135 Raw->Opcode < Instruction::BinaryOpsEnd && Raw->NumOperands == 2) {
136 Res = BinaryOperator::create((Instruction::BinaryOps)Raw->Opcode,
137 getValue(Raw->Ty, Raw->Arg1),
138 getValue(Raw->Ty, Raw->Arg2));
Chris Lattner00950542001-06-06 20:29:01 +0000139 return false;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000140 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000141
142 Value *V;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000143 switch (Raw->Opcode) {
Chris Lattner8f77dae2003-05-08 02:44:12 +0000144 case Instruction::VarArg:
Chris Lattner5ab1f872001-10-21 00:14:44 +0000145 case Instruction::Cast: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000146 V = getValue(Raw->Ty, Raw->Arg1);
147 const Type *Ty = getType(Raw->Arg2);
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000148 if (V == 0 || Ty == 0) { std::cerr << "Invalid cast!\n"; return true; }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000149 if (Raw->Opcode == Instruction::Cast)
Chris Lattner8f77dae2003-05-08 02:44:12 +0000150 Res = new CastInst(V, Ty);
151 else
152 Res = new VarArgInst(V, Ty);
Chris Lattner09083092001-07-08 04:57:15 +0000153 return false;
Chris Lattner5ab1f872001-10-21 00:14:44 +0000154 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000155 case Instruction::PHINode: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000156 PHINode *PN = new PHINode(Raw->Ty);
157 switch (Raw->NumOperands) {
Chris Lattneree976f32001-06-11 15:04:40 +0000158 case 0:
159 case 1:
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000160 case 3: std::cerr << "Invalid phi node encountered!\n";
Chris Lattner00950542001-06-06 20:29:01 +0000161 delete PN;
Chris Lattner74734132002-08-17 22:01:27 +0000162 return true;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000163 case 2: PN->addIncoming(getValue(Raw->Ty, Raw->Arg1),
Chris Lattner36392bc2003-10-08 21:18:57 +0000164 cast<BasicBlock>(getValue(Type::LabelTyID,
Misha Brukmand554ebf2003-09-23 16:17:50 +0000165 Raw->Arg2)));
Chris Lattneree976f32001-06-11 15:04:40 +0000166 break;
Chris Lattner00950542001-06-06 20:29:01 +0000167 default:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000168 PN->addIncoming(getValue(Raw->Ty, Raw->Arg1),
Chris Lattner36392bc2003-10-08 21:18:57 +0000169 cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg2)));
Misha Brukmand554ebf2003-09-23 16:17:50 +0000170 if (Raw->VarArgs->size() & 1) {
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000171 std::cerr << "PHI Node with ODD number of arguments!\n";
Chris Lattneree976f32001-06-11 15:04:40 +0000172 delete PN;
Chris Lattner74734132002-08-17 22:01:27 +0000173 return true;
Chris Lattneree976f32001-06-11 15:04:40 +0000174 } else {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000175 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattneree976f32001-06-11 15:04:40 +0000176 for (unsigned i = 0; i < args.size(); i+=2)
Misha Brukmand554ebf2003-09-23 16:17:50 +0000177 PN->addIncoming(getValue(Raw->Ty, args[i]),
Chris Lattner36392bc2003-10-08 21:18:57 +0000178 cast<BasicBlock>(getValue(Type::LabelTyID, args[i+1])));
Chris Lattner00950542001-06-06 20:29:01 +0000179 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000180 delete Raw->VarArgs;
Chris Lattneree976f32001-06-11 15:04:40 +0000181 break;
Chris Lattner00950542001-06-06 20:29:01 +0000182 }
183 Res = PN;
184 return false;
Chris Lattner027dcc52001-07-08 21:10:27 +0000185 }
186
187 case Instruction::Shl:
188 case Instruction::Shr:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000189 Res = new ShiftInst((Instruction::OtherOps)Raw->Opcode,
190 getValue(Raw->Ty, Raw->Arg1),
Chris Lattner36392bc2003-10-08 21:18:57 +0000191 getValue(Type::UByteTyID, Raw->Arg2));
Chris Lattner027dcc52001-07-08 21:10:27 +0000192 return false;
193 case Instruction::Ret:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000194 if (Raw->NumOperands == 0) {
Chris Lattner00950542001-06-06 20:29:01 +0000195 Res = new ReturnInst(); return false;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000196 } else if (Raw->NumOperands == 1) {
197 Res = new ReturnInst(getValue(Raw->Ty, Raw->Arg1)); return false;
Chris Lattner00950542001-06-06 20:29:01 +0000198 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000199 break;
200
201 case Instruction::Br:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000202 if (Raw->NumOperands == 1) {
Chris Lattner36392bc2003-10-08 21:18:57 +0000203 Res = new BranchInst(cast<BasicBlock>(getValue(Type::LabelTyID,Raw->Arg1)));
Chris Lattner00950542001-06-06 20:29:01 +0000204 return false;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000205 } else if (Raw->NumOperands == 3) {
Chris Lattner36392bc2003-10-08 21:18:57 +0000206 Res = new BranchInst(cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg1)),
207 cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg2)),
208 getValue(Type::BoolTyID , Raw->Arg3));
Chris Lattner00950542001-06-06 20:29:01 +0000209 return false;
210 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000211 break;
212
213 case Instruction::Switch: {
Chris Lattner00950542001-06-06 20:29:01 +0000214 SwitchInst *I =
Misha Brukmand554ebf2003-09-23 16:17:50 +0000215 new SwitchInst(getValue(Raw->Ty, Raw->Arg1),
Chris Lattner36392bc2003-10-08 21:18:57 +0000216 cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg2)));
Chris Lattner00950542001-06-06 20:29:01 +0000217 Res = I;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000218 if (Raw->NumOperands < 3) return false; // No destinations? Weird.
Chris Lattner00950542001-06-06 20:29:01 +0000219
Misha Brukmand554ebf2003-09-23 16:17:50 +0000220 if (Raw->NumOperands == 3 || Raw->VarArgs->size() & 1) {
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000221 std::cerr << "Switch statement with odd number of arguments!\n";
Chris Lattner00950542001-06-06 20:29:01 +0000222 delete I;
Chris Lattner74734132002-08-17 22:01:27 +0000223 return true;
Chris Lattner00950542001-06-06 20:29:01 +0000224 }
225
Misha Brukmand554ebf2003-09-23 16:17:50 +0000226 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner00950542001-06-06 20:29:01 +0000227 for (unsigned i = 0; i < args.size(); i += 2)
Misha Brukmand554ebf2003-09-23 16:17:50 +0000228 I->addCase(cast<Constant>(getValue(Raw->Ty, args[i])),
Chris Lattner36392bc2003-10-08 21:18:57 +0000229 cast<BasicBlock>(getValue(Type::LabelTyID, args[i+1])));
Chris Lattner00950542001-06-06 20:29:01 +0000230
Misha Brukmand554ebf2003-09-23 16:17:50 +0000231 delete Raw->VarArgs;
Chris Lattner00950542001-06-06 20:29:01 +0000232 return false;
Chris Lattner027dcc52001-07-08 21:10:27 +0000233 }
234
235 case Instruction::Call: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000236 Value *F = getValue(Raw->Ty, Raw->Arg1);
Chris Lattner5bea4112003-09-05 18:25:29 +0000237 if (F == 0) return true;
Chris Lattner00950542001-06-06 20:29:01 +0000238
Chris Lattner05950c32001-10-13 06:47:01 +0000239 // Check to make sure we have a pointer to method type
Chris Lattner5bea4112003-09-05 18:25:29 +0000240 const PointerType *PTy = dyn_cast<PointerType>(F->getType());
Chris Lattner74734132002-08-17 22:01:27 +0000241 if (PTy == 0) return true;
Chris Lattner5bea4112003-09-05 18:25:29 +0000242 const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
243 if (FTy == 0) return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000244
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000245 std::vector<Value *> Params;
Chris Lattner5bea4112003-09-05 18:25:29 +0000246 const FunctionType::ParamTypes &PL = FTy->getParamTypes();
Chris Lattner05950c32001-10-13 06:47:01 +0000247
Chris Lattner5bea4112003-09-05 18:25:29 +0000248 if (!FTy->isVarArg()) {
Chris Lattner2aac6bf2002-04-04 22:19:18 +0000249 FunctionType::ParamTypes::const_iterator It = PL.begin();
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000250
Misha Brukmand554ebf2003-09-23 16:17:50 +0000251 switch (Raw->NumOperands) {
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000252 case 0: std::cerr << "Invalid call instruction encountered!\n";
Chris Lattner74734132002-08-17 22:01:27 +0000253 return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000254 case 1: break;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000255 case 2: Params.push_back(getValue(*It++, Raw->Arg2)); break;
256 case 3: Params.push_back(getValue(*It++, Raw->Arg2));
Chris Lattner74734132002-08-17 22:01:27 +0000257 if (It == PL.end()) return true;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000258 Params.push_back(getValue(*It++, Raw->Arg3)); break;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000259 default:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000260 Params.push_back(getValue(*It++, Raw->Arg2));
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000261 {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000262 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000263 for (unsigned i = 0; i < args.size(); i++) {
Chris Lattner74734132002-08-17 22:01:27 +0000264 if (It == PL.end()) return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000265 Params.push_back(getValue(*It++, args[i]));
Chris Lattner5bea4112003-09-05 18:25:29 +0000266 if (Params.back() == 0) return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000267 }
Chris Lattner00950542001-06-06 20:29:01 +0000268 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000269 delete Raw->VarArgs;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000270 }
Chris Lattner74734132002-08-17 22:01:27 +0000271 if (It != PL.end()) return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000272 } else {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000273 if (Raw->NumOperands > 2) {
274 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner74734132002-08-17 22:01:27 +0000275 if (args.size() < 1) return true;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000276
Chris Lattner05950c32001-10-13 06:47:01 +0000277 if ((args.size() & 1) != 0)
Chris Lattner74734132002-08-17 22:01:27 +0000278 return true; // Must be pairs of type/value
Chris Lattner05950c32001-10-13 06:47:01 +0000279 for (unsigned i = 0; i < args.size(); i+=2) {
280 const Type *Ty = getType(args[i]);
281 if (Ty == 0)
Chris Lattner74734132002-08-17 22:01:27 +0000282 return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000283
284 Value *V = getValue(Ty, args[i+1]);
Chris Lattner74734132002-08-17 22:01:27 +0000285 if (V == 0) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000286 Params.push_back(V);
287 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000288 delete Raw->VarArgs;
Chris Lattner00950542001-06-06 20:29:01 +0000289 }
Chris Lattner00950542001-06-06 20:29:01 +0000290 }
Chris Lattner00950542001-06-06 20:29:01 +0000291
Chris Lattner5bea4112003-09-05 18:25:29 +0000292 Res = new CallInst(F, Params);
Chris Lattner00950542001-06-06 20:29:01 +0000293 return false;
Chris Lattner027dcc52001-07-08 21:10:27 +0000294 }
Chris Lattner05950c32001-10-13 06:47:01 +0000295 case Instruction::Invoke: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000296 Value *F = getValue(Raw->Ty, Raw->Arg1);
Chris Lattner5bea4112003-09-05 18:25:29 +0000297 if (F == 0) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000298
299 // Check to make sure we have a pointer to method type
Chris Lattner5bea4112003-09-05 18:25:29 +0000300 const PointerType *PTy = dyn_cast<PointerType>(F->getType());
Chris Lattner74734132002-08-17 22:01:27 +0000301 if (PTy == 0) return true;
Chris Lattner5bea4112003-09-05 18:25:29 +0000302 const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
303 if (FTy == 0) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000304
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000305 std::vector<Value *> Params;
Chris Lattner5bea4112003-09-05 18:25:29 +0000306 const FunctionType::ParamTypes &PL = FTy->getParamTypes();
Misha Brukmand554ebf2003-09-23 16:17:50 +0000307 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner05950c32001-10-13 06:47:01 +0000308
309 BasicBlock *Normal, *Except;
310
Chris Lattner5bea4112003-09-05 18:25:29 +0000311 if (!FTy->isVarArg()) {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000312 if (Raw->NumOperands < 3) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000313
Chris Lattner36392bc2003-10-08 21:18:57 +0000314 Normal = cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg2));
Misha Brukmand554ebf2003-09-23 16:17:50 +0000315 if (Raw->NumOperands == 3)
Chris Lattner36392bc2003-10-08 21:18:57 +0000316 Except = cast<BasicBlock>(getValue(Type::LabelTyID, Raw->Arg3));
Chris Lattnereaeaad62003-06-17 13:31:10 +0000317 else {
Chris Lattner36392bc2003-10-08 21:18:57 +0000318 Except = cast<BasicBlock>(getValue(Type::LabelTyID, args[0]));
Chris Lattner05950c32001-10-13 06:47:01 +0000319
Chris Lattnereaeaad62003-06-17 13:31:10 +0000320 FunctionType::ParamTypes::const_iterator It = PL.begin();
321 for (unsigned i = 1; i < args.size(); i++) {
322 if (It == PL.end()) return true;
Chris Lattnereaeaad62003-06-17 13:31:10 +0000323 Params.push_back(getValue(*It++, args[i]));
Chris Lattner5bea4112003-09-05 18:25:29 +0000324 if (Params.back() == 0) return true;
Chris Lattnereaeaad62003-06-17 13:31:10 +0000325 }
326 if (It != PL.end()) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000327 }
Chris Lattner05950c32001-10-13 06:47:01 +0000328 } else {
Chris Lattner74734132002-08-17 22:01:27 +0000329 if (args.size() < 4) return true;
Chris Lattner5bea4112003-09-05 18:25:29 +0000330 if (getType(args[0]) != Type::LabelTy ||
331 getType(args[2]) != Type::LabelTy) return true;
Chris Lattner36392bc2003-10-08 21:18:57 +0000332 Normal = cast<BasicBlock>(getValue(Type::LabelTyID, args[1]));
333 Except = cast<BasicBlock>(getValue(Type::LabelTyID, args[3]));
Chris Lattner05950c32001-10-13 06:47:01 +0000334
335 if ((args.size() & 1) != 0)
Chris Lattner74734132002-08-17 22:01:27 +0000336 return true; // Must be pairs of type/value
Chris Lattner05950c32001-10-13 06:47:01 +0000337 for (unsigned i = 4; i < args.size(); i+=2) {
Chris Lattner36392bc2003-10-08 21:18:57 +0000338 Params.push_back(getValue(args[i], args[i+1]));
Chris Lattner5bea4112003-09-05 18:25:29 +0000339 if (Params.back() == 0) return true;
Chris Lattner05950c32001-10-13 06:47:01 +0000340 }
341 }
342
Misha Brukmand554ebf2003-09-23 16:17:50 +0000343 if (Raw->NumOperands > 3)
344 delete Raw->VarArgs;
Chris Lattner5bea4112003-09-05 18:25:29 +0000345 Res = new InvokeInst(F, Normal, Except, Params);
Chris Lattner05950c32001-10-13 06:47:01 +0000346 return false;
347 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000348 case Instruction::Malloc:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000349 if (Raw->NumOperands > 2) return true;
Chris Lattner36392bc2003-10-08 21:18:57 +0000350 V = Raw->NumOperands ? getValue(Type::UIntTyID, Raw->Arg1) : 0;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000351 if (const PointerType *PTy = dyn_cast<PointerType>(Raw->Ty))
Chris Lattnere87e1c92002-09-13 22:28:50 +0000352 Res = new MallocInst(PTy->getElementType(), V);
353 else
354 return true;
Chris Lattner00950542001-06-06 20:29:01 +0000355 return false;
Chris Lattner027dcc52001-07-08 21:10:27 +0000356
357 case Instruction::Alloca:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000358 if (Raw->NumOperands > 2) return true;
Chris Lattner36392bc2003-10-08 21:18:57 +0000359 V = Raw->NumOperands ? getValue(Type::UIntTyID, Raw->Arg1) : 0;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000360 if (const PointerType *PTy = dyn_cast<PointerType>(Raw->Ty))
Chris Lattnere87e1c92002-09-13 22:28:50 +0000361 Res = new AllocaInst(PTy->getElementType(), V);
362 else
363 return true;
Chris Lattner00950542001-06-06 20:29:01 +0000364 return false;
Chris Lattner027dcc52001-07-08 21:10:27 +0000365
366 case Instruction::Free:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000367 V = getValue(Raw->Ty, Raw->Arg1);
Chris Lattner74734132002-08-17 22:01:27 +0000368 if (!isa<PointerType>(V->getType())) return true;
Chris Lattner027dcc52001-07-08 21:10:27 +0000369 Res = new FreeInst(V);
370 return false;
371
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000372 case Instruction::GetElementPtr: {
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000373 std::vector<Value*> Idx;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000374 if (!isa<PointerType>(Raw->Ty)) return true;
375 const CompositeType *TopTy = dyn_cast<CompositeType>(Raw->Ty);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000376
Misha Brukmand554ebf2003-09-23 16:17:50 +0000377 switch (Raw->NumOperands) {
Chris Lattner09bd0252003-09-08 18:04:16 +0000378 case 0: std::cerr << "Invalid getelementptr encountered!\n"; return true;
Chris Lattner027dcc52001-07-08 21:10:27 +0000379 case 1: break;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000380 case 2:
Chris Lattner74734132002-08-17 22:01:27 +0000381 if (!TopTy) return true;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000382 Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattner74734132002-08-17 22:01:27 +0000383 if (!V) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000384 break;
385 case 3: {
Chris Lattner74734132002-08-17 22:01:27 +0000386 if (!TopTy) return true;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000387 Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattner74734132002-08-17 22:01:27 +0000388 if (!V) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000389
Chris Lattnercc63f1c2002-08-22 23:37:20 +0000390 const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000391 const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
Chris Lattner74734132002-08-17 22:01:27 +0000392 if (!ElTy) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000393
Misha Brukmand554ebf2003-09-23 16:17:50 +0000394 Idx.push_back(V = getValue(ElTy->getIndexType(), Raw->Arg3));
Chris Lattner74734132002-08-17 22:01:27 +0000395 if (!V) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000396 break;
397 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000398 default:
Chris Lattner74734132002-08-17 22:01:27 +0000399 if (!TopTy) return true;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000400 Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattner74734132002-08-17 22:01:27 +0000401 if (!V) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000402
Misha Brukmand554ebf2003-09-23 16:17:50 +0000403 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner027dcc52001-07-08 21:10:27 +0000404 for (unsigned i = 0, E = args.size(); i != E; ++i) {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000405 const Type *ETy = GetElementPtrInst::getIndexedType(Raw->Ty, Idx, true);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000406 const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
Chris Lattner74734132002-08-17 22:01:27 +0000407 if (!ElTy) return true;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000408 Idx.push_back(V = getValue(ElTy->getIndexType(), args[i]));
Chris Lattner74734132002-08-17 22:01:27 +0000409 if (!V) return true;
Chris Lattner027dcc52001-07-08 21:10:27 +0000410 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000411 delete Raw->VarArgs;
Chris Lattner027dcc52001-07-08 21:10:27 +0000412 break;
413 }
Chris Lattner77a316a2001-11-12 21:48:38 +0000414
Misha Brukmand554ebf2003-09-23 16:17:50 +0000415 Res = new GetElementPtrInst(getValue(Raw->Ty, Raw->Arg1), Idx);
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000416 return false;
417 }
Chris Lattner09bd0252003-09-08 18:04:16 +0000418
Chris Lattnerdba2b222003-09-08 18:20:14 +0000419 case 62: // volatile load
Chris Lattner09bd0252003-09-08 18:04:16 +0000420 case Instruction::Load:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000421 if (Raw->NumOperands != 1) return true;
422 if (!isa<PointerType>(Raw->Ty)) return true;
423 Res = new LoadInst(getValue(Raw->Ty, Raw->Arg1), "", Raw->Opcode == 62);
Chris Lattner09bd0252003-09-08 18:04:16 +0000424 return false;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000425
Chris Lattnerdba2b222003-09-08 18:20:14 +0000426 case 63: // volatile store
Chris Lattner09bd0252003-09-08 18:04:16 +0000427 case Instruction::Store: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000428 if (!isa<PointerType>(Raw->Ty) || Raw->NumOperands != 2) return true;
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000429
Misha Brukmand554ebf2003-09-23 16:17:50 +0000430 Value *Ptr = getValue(Raw->Ty, Raw->Arg2);
Chris Lattner352eef72002-08-21 22:55:27 +0000431 const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
Misha Brukmand554ebf2003-09-23 16:17:50 +0000432 Res = new StoreInst(getValue(ValTy, Raw->Arg1), Ptr, Raw->Opcode == 63);
Chris Lattner00950542001-06-06 20:29:01 +0000433 return false;
434 }
Chris Lattner36143fc2003-09-08 18:54:55 +0000435 case Instruction::Unwind:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000436 if (Raw->NumOperands != 0) return true;
Chris Lattnerda73bea2003-09-08 19:43:46 +0000437 Res = new UnwindInst();
438 return false;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000439 } // end switch(Raw->Opcode)
Chris Lattner00950542001-06-06 20:29:01 +0000440
Misha Brukmand554ebf2003-09-23 16:17:50 +0000441 std::cerr << "Unrecognized instruction! " << Raw->Opcode
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000442 << " ADDR = 0x" << (void*)Buf << "\n";
Chris Lattner74734132002-08-17 22:01:27 +0000443 return true;
Chris Lattner00950542001-06-06 20:29:01 +0000444}